You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

126 lines
3.9 KiB

  1. package controller
  2. import (
  3. "net/http"
  4. "strconv"
  5. "strings"
  6. "github.com/QuantumNous/new-api/model"
  7. user_migration "github.com/QuantumNous/new-api/service/user_migration"
  8. "github.com/gin-gonic/gin"
  9. )
  10. func ListMigrationUsers(c *gin.Context) {
  11. page, _ := strconv.Atoi(c.DefaultQuery("page", "0"))
  12. pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "50"))
  13. if pageSize <= 0 || pageSize > 200 {
  14. pageSize = 50
  15. }
  16. users, total, err := model.ListLocalUsersForMigration(page, pageSize)
  17. if err != nil {
  18. c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "database error"})
  19. return
  20. }
  21. snapshots := make([]user_migration.RemoteUserSnapshot, 0, len(users))
  22. for _, user := range users {
  23. bindings, _ := model.GetUserOAuthBindingsByUserId(user.Id)
  24. snapshots = append(snapshots, buildRemoteUserSnapshot(user, bindings))
  25. }
  26. c.JSON(http.StatusOK, gin.H{"success": true, "data": snapshots, "total": total})
  27. }
  28. func GetMigrationUser(c *gin.Context) {
  29. userId, err := strconv.Atoi(c.Param("id"))
  30. if err != nil {
  31. c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "invalid user id"})
  32. return
  33. }
  34. user, err := model.GetUserById(userId, true)
  35. if err != nil || user == nil {
  36. c.JSON(http.StatusNotFound, gin.H{"success": false, "error": "user not found"})
  37. return
  38. }
  39. bindings, _ := model.GetUserOAuthBindingsByUserId(userId)
  40. c.JSON(http.StatusOK, gin.H{"success": true, "data": buildRemoteUserSnapshot(user, bindings)})
  41. }
  42. func ConvertMigrationUserToSynced(c *gin.Context) {
  43. userId, err := strconv.Atoi(c.Param("id"))
  44. if err != nil {
  45. c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "invalid user id"})
  46. return
  47. }
  48. var req user_migration.ConvertRemoteUserRequest
  49. if err := c.ShouldBindJSON(&req); err != nil || req.RemoteUserId == 0 {
  50. c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "invalid request body"})
  51. return
  52. }
  53. if err := model.ConvertUserToSynced(userId, req.RemoteUserId, req.SyncedQuota); err != nil {
  54. if strings.Contains(err.Error(), "already synced") || strings.Contains(err.Error(), "cannot change") {
  55. c.JSON(http.StatusConflict, gin.H{"success": false, "error": err.Error()})
  56. return
  57. }
  58. c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()})
  59. return
  60. }
  61. c.JSON(http.StatusOK, gin.H{"success": true})
  62. }
  63. func CheckSyncedCopy(c *gin.Context) {
  64. cnUserId, err := strconv.Atoi(c.Query("cn_user_id"))
  65. if err != nil {
  66. c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "invalid cn_user_id"})
  67. return
  68. }
  69. hasCopy, err := model.HasOVSyncedCopyByRemoteId(cnUserId)
  70. if err != nil {
  71. c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()})
  72. return
  73. }
  74. c.JSON(http.StatusOK, gin.H{"success": true, "has_copy": hasCopy})
  75. }
  76. func buildRemoteUserSnapshot(user *model.User, bindings []*model.UserOAuthBinding) user_migration.RemoteUserSnapshot {
  77. snapshot := user_migration.RemoteUserSnapshot{
  78. Id: user.Id,
  79. Username: user.Username,
  80. Password: user.Password,
  81. Email: user.Email,
  82. DisplayName: user.DisplayName,
  83. Status: user.Status,
  84. Role: user.Role,
  85. Group: user.Group,
  86. Quota: user.Quota,
  87. AffCode: user.AffCode,
  88. CreatedAt: user.CreatedAt,
  89. Setting: user.Setting,
  90. GitHubId: user.GitHubId,
  91. DiscordId: user.DiscordId,
  92. OidcId: user.OidcId,
  93. WeChatId: user.WeChatId,
  94. TelegramId: user.TelegramId,
  95. LinuxDOId: user.LinuxDOId,
  96. Source: user.Source,
  97. RemoteUserId: user.RemoteUserId,
  98. SyncedQuota: user.SyncedQuota,
  99. }
  100. for _, binding := range bindings {
  101. provider, err := model.GetCustomOAuthProviderById(binding.ProviderId)
  102. if err != nil {
  103. continue
  104. }
  105. snapshot.OAuthBindings = append(snapshot.OAuthBindings, user_migration.RemoteOAuthBinding{
  106. ProviderSlug: provider.Slug,
  107. ProviderUserId: binding.ProviderUserId,
  108. })
  109. }
  110. return snapshot
  111. }