gitea源码

source_group_sync.go 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package source
  4. import (
  5. "context"
  6. "fmt"
  7. "code.gitea.io/gitea/models/organization"
  8. user_model "code.gitea.io/gitea/models/user"
  9. "code.gitea.io/gitea/modules/container"
  10. "code.gitea.io/gitea/modules/log"
  11. org_service "code.gitea.io/gitea/services/org"
  12. )
  13. type syncType int
  14. const (
  15. syncAdd syncType = iota
  16. syncRemove
  17. )
  18. // SyncGroupsToTeams maps authentication source groups to organization and team memberships
  19. func SyncGroupsToTeams(ctx context.Context, user *user_model.User, sourceUserGroups container.Set[string], sourceGroupTeamMapping map[string]map[string][]string, performRemoval bool) error {
  20. orgCache := make(map[string]*organization.Organization)
  21. teamCache := make(map[string]*organization.Team)
  22. return SyncGroupsToTeamsCached(ctx, user, sourceUserGroups, sourceGroupTeamMapping, performRemoval, orgCache, teamCache)
  23. }
  24. // SyncGroupsToTeamsCached maps authentication source groups to organization and team memberships
  25. func SyncGroupsToTeamsCached(ctx context.Context, user *user_model.User, sourceUserGroups container.Set[string], sourceGroupTeamMapping map[string]map[string][]string, performRemoval bool, orgCache map[string]*organization.Organization, teamCache map[string]*organization.Team) error {
  26. membershipsToAdd, membershipsToRemove := resolveMappedMemberships(sourceUserGroups, sourceGroupTeamMapping)
  27. if performRemoval {
  28. if err := syncGroupsToTeamsCached(ctx, user, membershipsToRemove, syncRemove, orgCache, teamCache); err != nil {
  29. return fmt.Errorf("could not sync[remove] user groups: %w", err)
  30. }
  31. }
  32. if err := syncGroupsToTeamsCached(ctx, user, membershipsToAdd, syncAdd, orgCache, teamCache); err != nil {
  33. return fmt.Errorf("could not sync[add] user groups: %w", err)
  34. }
  35. return nil
  36. }
  37. func resolveMappedMemberships(sourceUserGroups container.Set[string], sourceGroupTeamMapping map[string]map[string][]string) (map[string][]string, map[string][]string) {
  38. membershipsToAdd := map[string][]string{}
  39. membershipsToRemove := map[string][]string{}
  40. for group, memberships := range sourceGroupTeamMapping {
  41. isUserInGroup := sourceUserGroups.Contains(group)
  42. if isUserInGroup {
  43. for org, teams := range memberships {
  44. membershipsToAdd[org] = append(membershipsToAdd[org], teams...)
  45. }
  46. } else {
  47. for org, teams := range memberships {
  48. membershipsToRemove[org] = append(membershipsToRemove[org], teams...)
  49. }
  50. }
  51. }
  52. return membershipsToAdd, membershipsToRemove
  53. }
  54. func syncGroupsToTeamsCached(ctx context.Context, user *user_model.User, orgTeamMap map[string][]string, action syncType, orgCache map[string]*organization.Organization, teamCache map[string]*organization.Team) error {
  55. for orgName, teamNames := range orgTeamMap {
  56. var err error
  57. org, ok := orgCache[orgName]
  58. if !ok {
  59. org, err = organization.GetOrgByName(ctx, orgName)
  60. if err != nil {
  61. if organization.IsErrOrgNotExist(err) {
  62. // organization must be created before group sync
  63. log.Warn("group sync: Could not find organisation %s: %v", orgName, err)
  64. continue
  65. }
  66. return err
  67. }
  68. orgCache[orgName] = org
  69. }
  70. for _, teamName := range teamNames {
  71. team, ok := teamCache[orgName+teamName]
  72. if !ok {
  73. team, err = org.GetTeam(ctx, teamName)
  74. if err != nil {
  75. if organization.IsErrTeamNotExist(err) {
  76. // team must be created before group sync
  77. log.Warn("group sync: Could not find team %s: %v", teamName, err)
  78. continue
  79. }
  80. return err
  81. }
  82. teamCache[orgName+teamName] = team
  83. }
  84. isMember, err := organization.IsTeamMember(ctx, org.ID, team.ID, user.ID)
  85. if err != nil {
  86. return err
  87. }
  88. if action == syncAdd && !isMember {
  89. if err := org_service.AddTeamMember(ctx, team, user); err != nil {
  90. log.Error("group sync: Could not add user to team: %v", err)
  91. return err
  92. }
  93. } else if action == syncRemove && isMember {
  94. if err := org_service.RemoveTeamMember(ctx, team, user); err != nil {
  95. log.Error("group sync: Could not remove user from team: %v", err)
  96. return err
  97. }
  98. }
  99. }
  100. }
  101. return nil
  102. }