Files
cdle 55c0895161 x
2023-06-04 14:30:54 +08:00

242 lines
5.6 KiB
Go

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{}
var password = ""
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
})
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 {
if new == "" {
return &storage.Final{
Now: new,
}
}
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) {
if password == "" {
return
}
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
}