package core import ( "encoding/json" "errors" "fmt" "math" "sync" "time" "github.com/cdle/sillyplus/core/storage" "github.com/cdle/sillyplus/utils" "github.com/gin-gonic/gin" ) var authBucket = MakeBucket("auths") var auths = []*Auth{} func init() { storage.Watch(sillyGirl, "name", func(old, new, key string) *storage.Final { if old == new { return &storage.Final{ Error: errors.New("unchanged"), } } return nil }) authBucket.Foreach(func(b1, b2 []byte) error { auth := &Auth{} if json.Unmarshal(b2, auth) == nil { if math.Abs(float64(int(time.Now().Unix())-auth.CreatedAt)) < 86400 { auths = append(auths, auth) } } return nil }) var password = sillyGirl.GetString("password") var name = sillyGirl.GetString("name", "傻妞") if password == "" { password = utils.GenUUID() console.Info("可视化面板临时账号密码:%s %s", name, password) } storage.Watch(sillyGirl, "password", func(old, new, key string) *storage.Final { password, _ = EncryptByAes([]byte(new)) return &storage.Final{ Now: password, } }) storage.Watch(sillyGirl, "name", func(old, new, key string) *storage.Final { name = new return nil }) ///可视化部分 GinApi(POST, "/api/login/account", func(ctx *gin.Context) { var auth = struct { Password string `json:"password"` Username string `json:"username"` }{} json.NewDecoder(ctx.Request.Body).Decode(&auth) epassword, _ := EncryptByAes([]byte(auth.Password)) if (auth.Password == password || epassword == password) && auth.Username == name { token := utils.GenUUID() auth := &Auth{ IP: ctx.ClientIP(), UserAgent: ctx.Request.UserAgent(), Token: token, CreatedAt: int(time.Now().Unix()), } authBucket.Create(auth) auths = append(auths, auth) console.Log("登录成功,当前有效令牌数%d,总数%d", len(ValidAuths()), len(auths)) ctx.SetCookie("token", token, 86400, "/", "", false, true) ctx.JSON(200, map[string]interface{}{ "status": "ok", "type": "account", "currentAuthority": "admin", }) } else { ctx.JSON(200, map[string]interface{}{ "status": "error", "type": "account", "currentAuthority": "guest", }) } }) GinApi(POST, "/api/login/outLogin", DestroyAuth, func(ctx *gin.Context) { sillyGirl.Set("web_token", "") ctx.JSON(200, map[string]interface{}{ "success": true, }) }) pluginNextUuid := sillyGirl.GetString("pluginNextUuid") if pluginNextUuid == "" { pluginNextUuid = utils.GenUUID() sillyGirl.Set("pluginNextUuid", pluginNextUuid) } GinApi(GET, "/api/currentUser", RequireAuth, func(ctx *gin.Context) { rs := []Route{} for _, f := range Functions { if f.UUID == pluginNextUuid { pluginNextUuid = utils.GenUUID() sillyGirl.Set("pluginNextUuid", pluginNextUuid) } if f.UUID != "" { name := f.Title if name == "" { name = "无名脚本" } if f.Module { name = name + " 🔧" } if f.OnStart { name = name + " 💫" } if f.Encrypt { name = name + " 🔒" } if f.Public { name = name + " 👑" } rs = append(rs, Route{ Path: fmt.Sprintf(`/script/%s`, f.UUID), Name: name, Component: "./Script", CreateAt: f.CreateAt, }) } } rrs := rs n := len(rrs) flag := true for i := 0; i < n && flag; i++ { flag = false for j := 0; j < n-i-1; j++ { if rrs[j].CreateAt < rrs[j+1].CreateAt { rrs[j], rrs[j+1] = rrs[j+1], rrs[j] flag = true } } } rrs = append(rrs, Route{ Path: fmt.Sprintf(`/script/%s`, pluginNextUuid), Name: "+新增脚本", Component: "./Script", }) ctx.JSON(200, map[string]interface{}{ "success": true, "data": map[string]interface{}{ "name": sillyGirl.GetString("name"), "avatar": "https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png", "plugins": rrs, }, }) }) } func DestroyAuth(c *gin.Context) { token, _ := c.Cookie("token") auth, _ := CheckAuth(token) if auth != nil { auth.ExpiredAt = int(time.Now().Unix()) authBucket.Create(auth) } } var tempAuth sync.Map func getTempAuth() string { uuid := utils.GenUUID() tempAuth.Store(uuid, time.Now().Unix()) return uuid } func checkTempAuth(uuid string) bool { unix, ok := tempAuth.LoadAndDelete(uuid) if !ok { return false } if time.Now().Unix()-unix.(int64) > 1 { return false } return true } func RequireAuth(c *gin.Context) { token, _ := c.Cookie("token") _, err := CheckAuth(token) if err != nil && !checkTempAuth(token) { c.JSON(401, map[string]interface{}{ "data": map[string]interface{}{ "isLogin": false, }, "errorCode": "401", "errorMessage": err.Error(), "success": true, "showType": 9, }) panic(err) } } func CheckAuth(token string) (*Auth, error) { var errorMessage = "请先登录!" if token != "" { auths := auths for i := range auths { if auths[i].Token == token && auths[i].ExpiredAt == 0 { if math.Abs(float64(int(time.Now().Unix())-auths[i].CreatedAt)) > 86400 { auths[i].ExpiredAt = int(time.Now().Unix()) authBucket.Create(auths[i]) errorMessage = "授权已过期!" } else { return auths[i], nil } } else { errorMessage = "非法访问!" } } } return nil, errors.New(errorMessage) } func ValidAuths() []*Auth { tmp := []*Auth{} for _, auth := range auths { if auth.ExpiredAt == 0 { tmp = append(tmp, auth) } } return tmp }