From 97ad14187beb00aa2f9c7a2c20d2d3613bf4b272 Mon Sep 17 00:00:00 2001 From: pcong Date: Wed, 15 Jan 2025 11:58:37 +0800 Subject: [PATCH] add: user lock screen --- godo/cmd/main.go | 7 +++ godo/user/user.go | 142 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 godo/user/user.go diff --git a/godo/cmd/main.go b/godo/cmd/main.go index c55d042..b727854 100644 --- a/godo/cmd/main.go +++ b/godo/cmd/main.go @@ -31,6 +31,7 @@ import ( "godo/proxy" "godo/store" "godo/sys" + "godo/user" "godo/webdav" "io/fs" "log" @@ -184,6 +185,12 @@ func OsStart() { proxyRouter.HandleFunc("/frpc/restart", proxy.RestartFrpcHandler).Methods(http.MethodGet) // 重启frpc服务 proxyRouter.HandleFunc("/frpc/status", proxy.StatusFrpcHandler).Methods(http.MethodGet) + userRouter := router.PathPrefix("/user").Subrouter() + userRouter.HandleFunc("/register", user.RegisterSysUserHandler).Methods(http.MethodPost) + userRouter.HandleFunc("/screen/lock", user.LockedScreenHandler).Methods(http.MethodPost) + userRouter.HandleFunc("/screen/unlock", user.UnLockScreenHandler).Methods(http.MethodPost) + userRouter.HandleFunc("/screen/status", user.CheckLockedScreenHandler).Methods(http.MethodGet) + // 注册根路径的处理函数 distFS, _ := fs.Sub(deps.Frontendassets, "dist") fileServer := http.FileServer(http.FS(distFS)) diff --git a/godo/user/user.go b/godo/user/user.go new file mode 100644 index 0000000..4d421c0 --- /dev/null +++ b/godo/user/user.go @@ -0,0 +1,142 @@ +package user + +import ( + "encoding/json" + "godo/libs" + "godo/model" + "net/http" + "strconv" + "sync" +) + +// 全局变量,用于存储锁屏状态 +var userLockedScreen map[uint]bool +var mu sync.Mutex // 用于保护锁屏状态的并发安全 + +// 注册系统用户 +func RegisterSysUserHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + libs.ErrorMsg(w, "invalid request method") + return + } + + var user model.SysUser + if err := json.NewDecoder(r.Body).Decode(&user); err != nil { + libs.ErrorMsg(w, "invalid input") + return + } + if user.Username == "" || user.Password == "" { + libs.ErrorMsg(w, "username or password is empty") + return + } + + if err := model.Db.Create(&user).Error; err != nil { + libs.ErrorMsg(w, "failed to create user") + return + } + + libs.SuccessMsg(w, user.ID, "") +} + +// 系统用户登录(锁屏) +func LockedScreenHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + libs.ErrorMsg(w, "invalid request method") + return + } + + var req model.SysUser + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + libs.ErrorMsg(w, "invalid input") + return + } + + var user model.SysUser + if err := model.Db.Where("username = ? and password = ?", req.Username, req.Password).First(&user).Error; err != nil { + libs.ErrorMsg(w, "invalid username or password") + return + } + + userEncodeStr, err := libs.EncodeFile("godoos", strconv.Itoa(int(user.ID))) + if err != nil { + libs.ErrorMsg(w, "failed to encode user") + return + } + + w.Header().Set("sysuser", userEncodeStr) + + // 登录成功,锁屏状态设置为 true + mu.Lock() + if userLockedScreen == nil { + userLockedScreen = make(map[uint]bool) + } + userLockedScreen[user.ID] = true + mu.Unlock() + + libs.SuccessMsg(w, nil, "system locked") +} + +// 系统用户登录(解锁) +func UnLockScreenHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + libs.ErrorMsg(w, "invalid request method") + return + } + + var req model.SysUser + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + libs.ErrorMsg(w, "invalid input") + return + } + + var user model.SysUser + if err := model.Db.Where("username = ? and password = ?", req.Username, req.Password).First(&user).Error; err != nil { + libs.ErrorMsg(w, "invalid username or password") + return + } + + // 登录成功,锁屏状态设置为 false + mu.Lock() + if userLockedScreen == nil { + userLockedScreen = make(map[uint]bool) + } + userLockedScreen[user.ID] = false + mu.Unlock() + + libs.SuccessMsg(w, nil, "system unlock") +} + +// 检查锁屏状态 +func CheckLockedScreenHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + libs.ErrorMsg(w, "invalid request method") + return + } + + decoderUid := r.Header.Get("sysuser") + if decoderUid == "" { + libs.ErrorMsg(w, "invalid uid") + return + } + uidStr, err := libs.DecodeFile("godoos", decoderUid) + if err != nil { + libs.ErrorMsg(w, "invalid uid") + return + } + uid, err := strconv.Atoi(uidStr) + if err != nil { + libs.ErrorMsg(w, "parse uid fail") + return + } + + mu.Lock() + defer mu.Unlock() + status, ok := userLockedScreen[uint(uid)] + if !ok { + libs.ErrorMsg(w, "user not found") + return + } + + //获取锁屏状态 + libs.SuccessMsg(w, status, "") +}