api_auth.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package core
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "math"
  7. "sync"
  8. "time"
  9. "github.com/cdle/sillyplus/core/storage"
  10. "github.com/cdle/sillyplus/utils"
  11. "github.com/gin-gonic/gin"
  12. )
  13. var authBucket = MakeBucket("auths")
  14. var auths = []*Auth{}
  15. var password = ""
  16. func init() {
  17. storage.Watch(sillyGirl, "name", func(old, new, key string) *storage.Final {
  18. if old == new {
  19. return &storage.Final{
  20. Error: errors.New("unchanged"),
  21. }
  22. }
  23. return nil
  24. })
  25. authBucket.Foreach(func(b1, b2 []byte) error {
  26. auth := &Auth{}
  27. if json.Unmarshal(b2, auth) == nil {
  28. if math.Abs(float64(int(time.Now().Unix())-auth.CreatedAt)) < 86400 {
  29. auths = append(auths, auth)
  30. }
  31. }
  32. return nil
  33. })
  34. password = sillyGirl.GetString("password")
  35. var name = sillyGirl.GetString("name", "傻妞")
  36. // if password == "" {
  37. // password = utils.GenUUID()
  38. // console.Info("可视化面板临时账号密码:%s %s", name, password)
  39. // }
  40. storage.Watch(sillyGirl, "password", func(old, new, key string) *storage.Final {
  41. if new == "" {
  42. return &storage.Final{
  43. Now: new,
  44. }
  45. }
  46. password, _ = EncryptByAes([]byte(new))
  47. return &storage.Final{
  48. Now: password,
  49. }
  50. })
  51. storage.Watch(sillyGirl, "name", func(old, new, key string) *storage.Final {
  52. name = new
  53. return nil
  54. })
  55. ///可视化部分
  56. GinApi(POST, "/api/login/account", func(ctx *gin.Context) {
  57. var auth = struct {
  58. Password string `json:"password"`
  59. Username string `json:"username"`
  60. }{}
  61. json.NewDecoder(ctx.Request.Body).Decode(&auth)
  62. epassword, _ := EncryptByAes([]byte(auth.Password))
  63. if (auth.Password == password || epassword == password) && auth.Username == name {
  64. token := utils.GenUUID()
  65. auth := &Auth{
  66. IP: ctx.ClientIP(),
  67. UserAgent: ctx.Request.UserAgent(),
  68. Token: token,
  69. CreatedAt: int(time.Now().Unix()),
  70. }
  71. authBucket.Create(auth)
  72. auths = append(auths, auth)
  73. console.Log("登录成功,当前有效令牌数%d,总数%d", len(ValidAuths()), len(auths))
  74. ctx.SetCookie("token", token, 86400, "/", "", false, true)
  75. ctx.JSON(200, map[string]interface{}{
  76. "status": "ok",
  77. "type": "account",
  78. "currentAuthority": "admin",
  79. })
  80. } else {
  81. ctx.JSON(200, map[string]interface{}{
  82. "status": "error",
  83. "type": "account",
  84. "currentAuthority": "guest",
  85. })
  86. }
  87. })
  88. GinApi(POST, "/api/login/outLogin", DestroyAuth, func(ctx *gin.Context) {
  89. sillyGirl.Set("web_token", "")
  90. ctx.JSON(200, map[string]interface{}{
  91. "success": true,
  92. })
  93. })
  94. pluginNextUuid := sillyGirl.GetString("pluginNextUuid")
  95. if pluginNextUuid == "" {
  96. pluginNextUuid = utils.GenUUID()
  97. sillyGirl.Set("pluginNextUuid", pluginNextUuid)
  98. }
  99. GinApi(GET, "/api/currentUser", RequireAuth, func(ctx *gin.Context) {
  100. rs := []Route{}
  101. for _, f := range Functions {
  102. if f.UUID == pluginNextUuid {
  103. pluginNextUuid = utils.GenUUID()
  104. sillyGirl.Set("pluginNextUuid", pluginNextUuid)
  105. }
  106. if f.UUID != "" {
  107. name := f.Title
  108. if name == "" {
  109. name = "无名脚本"
  110. }
  111. if f.Module {
  112. name = name + " 🔧"
  113. }
  114. if f.OnStart {
  115. name = name + " 💫"
  116. }
  117. if f.Encrypt {
  118. name = name + " 🔒"
  119. }
  120. if f.Public {
  121. name = name + " 👑"
  122. }
  123. rs = append(rs, Route{
  124. Path: fmt.Sprintf(`/script/%s`, f.UUID),
  125. Name: name,
  126. Component: "./Script",
  127. CreateAt: f.CreateAt,
  128. })
  129. }
  130. }
  131. rrs := rs
  132. n := len(rrs)
  133. flag := true
  134. for i := 0; i < n && flag; i++ {
  135. flag = false
  136. for j := 0; j < n-i-1; j++ {
  137. if rrs[j].CreateAt < rrs[j+1].CreateAt {
  138. rrs[j], rrs[j+1] = rrs[j+1], rrs[j]
  139. flag = true
  140. }
  141. }
  142. }
  143. rrs = append(rrs, Route{
  144. Path: fmt.Sprintf(`/script/%s`, pluginNextUuid),
  145. Name: "+新增脚本",
  146. Component: "./Script",
  147. })
  148. ctx.JSON(200, map[string]interface{}{
  149. "success": true,
  150. "data": map[string]interface{}{
  151. "name": sillyGirl.GetString("name"),
  152. "avatar": "https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png",
  153. "plugins": rrs,
  154. },
  155. })
  156. })
  157. }
  158. func DestroyAuth(c *gin.Context) {
  159. token, _ := c.Cookie("token")
  160. auth, _ := CheckAuth(token)
  161. if auth != nil {
  162. auth.ExpiredAt = int(time.Now().Unix())
  163. authBucket.Create(auth)
  164. }
  165. }
  166. var tempAuth sync.Map
  167. func getTempAuth() string {
  168. uuid := utils.GenUUID()
  169. tempAuth.Store(uuid, time.Now().Unix())
  170. return uuid
  171. }
  172. func checkTempAuth(uuid string) bool {
  173. unix, ok := tempAuth.LoadAndDelete(uuid)
  174. if !ok {
  175. return false
  176. }
  177. if time.Now().Unix()-unix.(int64) > 1 {
  178. return false
  179. }
  180. return true
  181. }
  182. func RequireAuth(c *gin.Context) {
  183. if password == "" {
  184. return
  185. }
  186. token, _ := c.Cookie("token")
  187. _, err := CheckAuth(token)
  188. if err != nil && !checkTempAuth(token) {
  189. c.JSON(401, map[string]interface{}{
  190. "data": map[string]interface{}{
  191. "isLogin": false,
  192. },
  193. "errorCode": "401",
  194. "errorMessage": err.Error(),
  195. "success": true,
  196. "showType": 9,
  197. })
  198. panic(err)
  199. }
  200. }
  201. func CheckAuth(token string) (*Auth, error) {
  202. var errorMessage = "请先登录!"
  203. if token != "" {
  204. auths := auths
  205. for i := range auths {
  206. if auths[i].Token == token && auths[i].ExpiredAt == 0 {
  207. if math.Abs(float64(int(time.Now().Unix())-auths[i].CreatedAt)) > 86400 {
  208. auths[i].ExpiredAt = int(time.Now().Unix())
  209. authBucket.Create(auths[i])
  210. errorMessage = "授权已过期!"
  211. } else {
  212. return auths[i], nil
  213. }
  214. } else {
  215. errorMessage = "非法访问!"
  216. }
  217. }
  218. }
  219. return nil, errors.New(errorMessage)
  220. }
  221. func ValidAuths() []*Auth {
  222. tmp := []*Auth{}
  223. for _, auth := range auths {
  224. if auth.ExpiredAt == 0 {
  225. tmp = append(tmp, auth)
  226. }
  227. }
  228. return tmp
  229. }