242 lines
5.6 KiB
Go
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
|
|
}
|