Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

132 строки
4.0 KiB

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