user.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. package controller
  2. import (
  3. "encoding/json"
  4. "github.com/gin-contrib/sessions"
  5. "github.com/gin-gonic/gin"
  6. "github.com/google/uuid"
  7. "message-pusher/common"
  8. "message-pusher/model"
  9. "net/http"
  10. "strconv"
  11. "strings"
  12. )
  13. type LoginRequest struct {
  14. Username string `json:"username"`
  15. Password string `json:"password"`
  16. }
  17. func Login(c *gin.Context) {
  18. if !common.PasswordLoginEnabled {
  19. c.JSON(http.StatusOK, gin.H{
  20. "message": "管理员关闭了密码登录",
  21. "success": false,
  22. })
  23. return
  24. }
  25. var loginRequest LoginRequest
  26. err := json.NewDecoder(c.Request.Body).Decode(&loginRequest)
  27. if err != nil {
  28. c.JSON(http.StatusOK, gin.H{
  29. "message": "无效的参数",
  30. "success": false,
  31. })
  32. return
  33. }
  34. username := loginRequest.Username
  35. password := loginRequest.Password
  36. if username == "" || password == "" {
  37. c.JSON(http.StatusOK, gin.H{
  38. "message": "无效的参数",
  39. "success": false,
  40. })
  41. return
  42. }
  43. user := model.User{
  44. Username: username,
  45. Password: password,
  46. }
  47. err = user.ValidateAndFill()
  48. if err != nil {
  49. c.JSON(http.StatusOK, gin.H{
  50. "message": err.Error(),
  51. "success": false,
  52. })
  53. return
  54. }
  55. setupLogin(&user, c)
  56. }
  57. // setup session & cookies and then return user info
  58. func setupLogin(user *model.User, c *gin.Context) {
  59. session := sessions.Default(c)
  60. session.Set("id", user.Id)
  61. session.Set("username", user.Username)
  62. session.Set("role", user.Role)
  63. session.Set("status", user.Status)
  64. err := session.Save()
  65. if err != nil {
  66. c.JSON(http.StatusOK, gin.H{
  67. "message": "无法保存会话信息,请重试",
  68. "success": false,
  69. })
  70. return
  71. }
  72. user.Password = ""
  73. user.Token = ""
  74. c.JSON(http.StatusOK, gin.H{
  75. "message": "",
  76. "success": true,
  77. "data": user,
  78. })
  79. }
  80. func Logout(c *gin.Context) {
  81. session := sessions.Default(c)
  82. session.Clear()
  83. err := session.Save()
  84. if err != nil {
  85. c.JSON(http.StatusOK, gin.H{
  86. "message": err.Error(),
  87. "success": false,
  88. })
  89. return
  90. }
  91. c.JSON(http.StatusOK, gin.H{
  92. "message": "",
  93. "success": true,
  94. })
  95. }
  96. func Register(c *gin.Context) {
  97. if !common.PasswordRegisterEnabled {
  98. c.JSON(http.StatusOK, gin.H{
  99. "message": "管理员关闭了新用户注册",
  100. "success": false,
  101. })
  102. return
  103. }
  104. var user model.User
  105. err := json.NewDecoder(c.Request.Body).Decode(&user)
  106. if err != nil {
  107. c.JSON(http.StatusOK, gin.H{
  108. "success": false,
  109. "message": "无效的参数",
  110. })
  111. return
  112. }
  113. if err := common.Validate.Struct(&user); err != nil {
  114. c.JSON(http.StatusOK, gin.H{
  115. "success": false,
  116. "message": "输入不合法 " + err.Error(),
  117. })
  118. return
  119. }
  120. if common.EmailVerificationEnabled {
  121. if user.Email == "" || user.VerificationCode == "" {
  122. c.JSON(http.StatusOK, gin.H{
  123. "success": false,
  124. "message": "管理员开启了邮箱验证,请输入邮箱地址和验证码",
  125. })
  126. return
  127. }
  128. if !common.VerifyCodeWithKey(user.Email, user.VerificationCode, common.EmailVerificationPurpose) {
  129. c.JSON(http.StatusOK, gin.H{
  130. "success": false,
  131. "message": "验证码错误!",
  132. })
  133. return
  134. }
  135. }
  136. cleanUser := model.User{
  137. Username: user.Username,
  138. Password: user.Password,
  139. DisplayName: user.Username,
  140. }
  141. if common.EmailVerificationEnabled {
  142. cleanUser.Email = user.Email
  143. }
  144. if err := cleanUser.Insert(); err != nil {
  145. c.JSON(http.StatusOK, gin.H{
  146. "success": false,
  147. "message": err.Error(),
  148. })
  149. return
  150. }
  151. c.JSON(http.StatusOK, gin.H{
  152. "success": true,
  153. "message": "",
  154. })
  155. return
  156. }
  157. func GetAllUsers(c *gin.Context) {
  158. users, err := model.GetAllUsers()
  159. if err != nil {
  160. c.JSON(http.StatusOK, gin.H{
  161. "success": false,
  162. "message": err.Error(),
  163. })
  164. return
  165. }
  166. c.JSON(http.StatusOK, gin.H{
  167. "success": true,
  168. "message": "",
  169. "data": users,
  170. })
  171. return
  172. }
  173. func SearchUsers(c *gin.Context) {
  174. keyword := c.Query("keyword")
  175. users, err := model.SearchUsers(keyword)
  176. if err != nil {
  177. c.JSON(http.StatusOK, gin.H{
  178. "success": false,
  179. "message": err.Error(),
  180. })
  181. return
  182. }
  183. c.JSON(http.StatusOK, gin.H{
  184. "success": true,
  185. "message": "",
  186. "data": users,
  187. })
  188. return
  189. }
  190. func GetUser(c *gin.Context) {
  191. id, err := strconv.Atoi(c.Param("id"))
  192. if err != nil {
  193. c.JSON(http.StatusOK, gin.H{
  194. "success": false,
  195. "message": err.Error(),
  196. })
  197. return
  198. }
  199. user, err := model.GetUserById(id, false)
  200. if err != nil {
  201. c.JSON(http.StatusOK, gin.H{
  202. "success": false,
  203. "message": err.Error(),
  204. })
  205. return
  206. }
  207. myRole := c.GetInt("role")
  208. if myRole <= user.Role {
  209. c.JSON(http.StatusOK, gin.H{
  210. "success": false,
  211. "message": "无权获取同级或更高等级用户的信息",
  212. })
  213. return
  214. }
  215. c.JSON(http.StatusOK, gin.H{
  216. "success": true,
  217. "message": "",
  218. "data": user,
  219. })
  220. return
  221. }
  222. func GenerateToken(c *gin.Context) {
  223. id := c.GetInt("id")
  224. user, err := model.GetUserById(id, true)
  225. if err != nil {
  226. c.JSON(http.StatusOK, gin.H{
  227. "success": false,
  228. "message": err.Error(),
  229. })
  230. return
  231. }
  232. user.Token = uuid.New().String()
  233. user.Token = strings.Replace(user.Token, "-", "", -1)
  234. if model.DB.Where("token = ?", user.Token).First(user).RowsAffected != 0 {
  235. c.JSON(http.StatusOK, gin.H{
  236. "success": false,
  237. "message": "请重试,系统生成的 UUID 竟然重复了!",
  238. })
  239. return
  240. }
  241. if err := user.Update(false); err != nil {
  242. c.JSON(http.StatusOK, gin.H{
  243. "success": false,
  244. "message": err.Error(),
  245. })
  246. return
  247. }
  248. c.JSON(http.StatusOK, gin.H{
  249. "success": true,
  250. "message": "",
  251. "data": user.Token,
  252. })
  253. return
  254. }
  255. func GetSelf(c *gin.Context) {
  256. id := c.GetInt("id")
  257. user, err := model.GetUserById(id, false)
  258. if err != nil {
  259. c.JSON(http.StatusOK, gin.H{
  260. "success": false,
  261. "message": err.Error(),
  262. })
  263. return
  264. }
  265. c.JSON(http.StatusOK, gin.H{
  266. "success": true,
  267. "message": "",
  268. "data": user,
  269. })
  270. return
  271. }
  272. func UpdateUser(c *gin.Context) {
  273. var updatedUser model.User
  274. err := json.NewDecoder(c.Request.Body).Decode(&updatedUser)
  275. if err != nil || updatedUser.Id == 0 {
  276. c.JSON(http.StatusOK, gin.H{
  277. "success": false,
  278. "message": "无效的参数",
  279. })
  280. return
  281. }
  282. if err := common.Validate.Struct(&updatedUser); err != nil {
  283. c.JSON(http.StatusOK, gin.H{
  284. "success": false,
  285. "message": "输入不合法 " + err.Error(),
  286. })
  287. return
  288. }
  289. originUser, err := model.GetUserById(updatedUser.Id, false)
  290. if err != nil {
  291. c.JSON(http.StatusOK, gin.H{
  292. "success": false,
  293. "message": err.Error(),
  294. })
  295. return
  296. }
  297. myRole := c.GetInt("role")
  298. if myRole <= originUser.Role {
  299. c.JSON(http.StatusOK, gin.H{
  300. "success": false,
  301. "message": "无权更新同权限等级或更高权限等级的用户信息",
  302. })
  303. return
  304. }
  305. if myRole <= updatedUser.Role {
  306. c.JSON(http.StatusOK, gin.H{
  307. "success": false,
  308. "message": "无权将其他用户权限等级提升到大于等于自己的权限等级",
  309. })
  310. return
  311. }
  312. updatePassword := updatedUser.Password != ""
  313. if err := updatedUser.Update(updatePassword); err != nil {
  314. c.JSON(http.StatusOK, gin.H{
  315. "success": false,
  316. "message": err.Error(),
  317. })
  318. return
  319. }
  320. c.JSON(http.StatusOK, gin.H{
  321. "success": true,
  322. "message": "",
  323. })
  324. return
  325. }
  326. func UpdateSelf(c *gin.Context) {
  327. var user model.User
  328. err := json.NewDecoder(c.Request.Body).Decode(&user)
  329. if err != nil {
  330. c.JSON(http.StatusOK, gin.H{
  331. "success": false,
  332. "message": "无效的参数",
  333. })
  334. return
  335. }
  336. if user.Password == "" {
  337. user.Password = "$I_LOVE_U" // make Validator happy :)
  338. }
  339. if err := common.Validate.Struct(&user); err != nil {
  340. c.JSON(http.StatusOK, gin.H{
  341. "success": false,
  342. "message": "输入不合法 " + err.Error(),
  343. })
  344. return
  345. }
  346. cleanUser := model.User{
  347. Id: c.GetInt("id"),
  348. Username: user.Username,
  349. Password: user.Password,
  350. DisplayName: user.DisplayName,
  351. Token: user.Token,
  352. }
  353. if cleanUser.Token == "" {
  354. cleanUser.Token = " " // this is because gorm will ignore zero value
  355. }
  356. if user.Password == "$I_LOVE_U" {
  357. user.Password = "" // rollback to what it should be
  358. cleanUser.Password = ""
  359. }
  360. updatePassword := user.Password != ""
  361. if err := cleanUser.Update(updatePassword); err != nil {
  362. c.JSON(http.StatusOK, gin.H{
  363. "success": false,
  364. "message": err.Error(),
  365. })
  366. return
  367. }
  368. c.JSON(http.StatusOK, gin.H{
  369. "success": true,
  370. "message": "",
  371. })
  372. return
  373. }
  374. func DeleteUser(c *gin.Context) {
  375. id, err := strconv.Atoi(c.Param("id"))
  376. if err != nil {
  377. c.JSON(http.StatusOK, gin.H{
  378. "success": false,
  379. "message": err.Error(),
  380. })
  381. return
  382. }
  383. originUser, err := model.GetUserById(id, false)
  384. if err != nil {
  385. c.JSON(http.StatusOK, gin.H{
  386. "success": false,
  387. "message": err.Error(),
  388. })
  389. return
  390. }
  391. myRole := c.GetInt("role")
  392. if myRole <= originUser.Role {
  393. c.JSON(http.StatusOK, gin.H{
  394. "success": false,
  395. "message": "无权删除同权限等级或更高权限等级的用户",
  396. })
  397. return
  398. }
  399. err = model.DeleteUserById(id)
  400. if err != nil {
  401. c.JSON(http.StatusOK, gin.H{
  402. "success": true,
  403. "message": "",
  404. })
  405. return
  406. }
  407. }
  408. func DeleteSelf(c *gin.Context) {
  409. id := c.GetInt("id")
  410. err := model.DeleteUserById(id)
  411. if err != nil {
  412. c.JSON(http.StatusOK, gin.H{
  413. "success": false,
  414. "message": err.Error(),
  415. })
  416. return
  417. }
  418. c.JSON(http.StatusOK, gin.H{
  419. "success": true,
  420. "message": "",
  421. })
  422. return
  423. }
  424. // CreateUser Only admin user can call this, so we can trust it
  425. func CreateUser(c *gin.Context) {
  426. var user model.User
  427. err := json.NewDecoder(c.Request.Body).Decode(&user)
  428. if err != nil || user.Username == "" || user.Password == "" {
  429. c.JSON(http.StatusOK, gin.H{
  430. "success": false,
  431. "message": "无效的参数",
  432. })
  433. return
  434. }
  435. if user.DisplayName == "" {
  436. user.DisplayName = user.Username
  437. }
  438. myRole := c.GetInt("role")
  439. if user.Role >= myRole {
  440. c.JSON(http.StatusOK, gin.H{
  441. "success": false,
  442. "message": "无法创建权限大于等于自己的用户",
  443. })
  444. return
  445. }
  446. if err := user.Insert(); err != nil {
  447. c.JSON(http.StatusOK, gin.H{
  448. "success": false,
  449. "message": err.Error(),
  450. })
  451. return
  452. }
  453. c.JSON(http.StatusOK, gin.H{
  454. "success": true,
  455. "message": "",
  456. })
  457. return
  458. }
  459. type ManageRequest struct {
  460. Username string `json:"username"`
  461. Action string `json:"action"`
  462. }
  463. // ManageUser Only admin user can do this
  464. func ManageUser(c *gin.Context) {
  465. var req ManageRequest
  466. err := json.NewDecoder(c.Request.Body).Decode(&req)
  467. if err != nil {
  468. c.JSON(http.StatusOK, gin.H{
  469. "success": false,
  470. "message": "无效的参数",
  471. })
  472. return
  473. }
  474. user := model.User{
  475. Username: req.Username,
  476. }
  477. // Fill attributes
  478. model.DB.Where(&user).First(&user)
  479. if user.Id == 0 {
  480. c.JSON(http.StatusOK, gin.H{
  481. "success": false,
  482. "message": "用户不存在",
  483. })
  484. return
  485. }
  486. myRole := c.GetInt("role")
  487. if myRole <= user.Role {
  488. c.JSON(http.StatusOK, gin.H{
  489. "success": false,
  490. "message": "无权更新同权限等级或更高权限等级的用户信息",
  491. })
  492. return
  493. }
  494. switch req.Action {
  495. case "disable":
  496. user.Status = common.UserStatusDisabled
  497. case "enable":
  498. user.Status = common.UserStatusEnabled
  499. case "delete":
  500. if err := user.Delete(); err != nil {
  501. c.JSON(http.StatusOK, gin.H{
  502. "success": false,
  503. "message": err.Error(),
  504. })
  505. return
  506. }
  507. case "promote":
  508. if myRole != common.RoleRootUser {
  509. c.JSON(http.StatusOK, gin.H{
  510. "success": false,
  511. "message": "普通管理员用户无法提升其他用户为管理员",
  512. })
  513. return
  514. }
  515. user.Role = common.RoleAdminUser
  516. case "demote":
  517. user.Role = common.RoleCommonUser
  518. }
  519. if err := user.Update(false); err != nil {
  520. c.JSON(http.StatusOK, gin.H{
  521. "success": false,
  522. "message": err.Error(),
  523. })
  524. return
  525. }
  526. c.JSON(http.StatusOK, gin.H{
  527. "success": true,
  528. "message": "",
  529. })
  530. return
  531. }
  532. func EmailBind(c *gin.Context) {
  533. email := c.Query("email")
  534. code := c.Query("code")
  535. if !common.VerifyCodeWithKey(email, code, common.EmailVerificationPurpose) {
  536. c.JSON(http.StatusOK, gin.H{
  537. "success": false,
  538. "message": "验证码错误!",
  539. })
  540. return
  541. }
  542. id := c.GetInt("id")
  543. user := model.User{
  544. Id: id,
  545. }
  546. user.FillUserById()
  547. user.Email = email
  548. // no need to check if this email already taken, because we have used verification code to check it
  549. err := user.Update(false)
  550. if err != nil {
  551. c.JSON(http.StatusOK, gin.H{
  552. "success": false,
  553. "message": err.Error(),
  554. })
  555. return
  556. }
  557. c.JSON(http.StatusOK, gin.H{
  558. "success": true,
  559. "message": "",
  560. })
  561. return
  562. }