@@ -7,6 +7,7 @@ package ldap
77import (
88 "context"
99 "fmt"
10+ "sort"
1011 "strings"
1112
1213 "code.gitea.io/gitea/models"
@@ -17,7 +18,7 @@ import (
1718func (source * Source ) Sync (ctx context.Context , updateExisting bool ) error {
1819 log .Trace ("Doing: SyncExternalUsers[%s]" , source .loginSource .Name )
1920
20- var existingUsers []int64
21+ var existingUsers []int
2122 isAttributeSSHPublicKeySet := len (strings .TrimSpace (source .AttributeSSHPublicKey )) > 0
2223 var sshKeysNeedUpdate bool
2324
@@ -34,6 +35,10 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
3435 default :
3536 }
3637
38+ sort .Slice (users , func (i , j int ) bool {
39+ return users [i ].LowerName < users [j ].LowerName
40+ })
41+
3742 sr , err := source .SearchEntries ()
3843 if err != nil {
3944 log .Error ("SyncExternalUsers LDAP source failure [%s], skipped" , source .loginSource .Name )
@@ -48,6 +53,12 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
4853 log .Warn ("LDAP search found no entries but did not report an error. All users will be deactivated as per settings" )
4954 }
5055
56+ sort .Slice (sr , func (i , j int ) bool {
57+ return sr [i ].LowerName < sr [j ].LowerName
58+ })
59+
60+ userPos := 0
61+
5162 for _ , su := range sr {
5263 select {
5364 case <- ctx .Done ():
@@ -71,12 +82,12 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
7182 }
7283
7384 var usr * models.User
74- // Search for existing user
75- for _ , du := range users {
76- if du . LowerName == strings . ToLower ( su . Username ) {
77- usr = du
78- break
79- }
85+ for userPos < len ( users ) && users [ userPos ]. LowerName < su . LowerName {
86+ userPos ++
87+ }
88+ if userPos < len ( users ) && users [ userPos ]. LowerName == su . LowerName {
89+ usr = users [ userPos ]
90+ existingUsers = append ( existingUsers , userPos )
8091 }
8192
8293 fullName := composeFullName (su .Name , su .Surname , su .Username )
@@ -85,7 +96,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
8596 log .Trace ("SyncExternalUsers[%s]: Creating user %s" , source .loginSource .Name , su .Username )
8697
8798 usr = & models.User {
88- LowerName : strings . ToLower ( su .Username ) ,
99+ LowerName : su .LowerName ,
89100 Name : su .Username ,
90101 FullName : fullName ,
91102 LoginType : source .loginSource .Type ,
@@ -108,8 +119,6 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
108119 }
109120 }
110121 } else if updateExisting {
111- existingUsers = append (existingUsers , usr .ID )
112-
113122 // Synchronize SSH Public Key if that attribute is set
114123 if isAttributeSSHPublicKeySet && models .SynchronizePublicKeys (usr , source .loginSource , su .SSHPublicKey ) {
115124 sshKeysNeedUpdate = true
@@ -161,15 +170,12 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
161170
162171 // Deactivate users not present in LDAP
163172 if updateExisting {
164- for _ , usr := range users {
165- found := false
166- for _ , uid := range existingUsers {
167- if usr .ID == uid {
168- found = true
169- break
170- }
173+ existPos := 0
174+ for i , usr := range users {
175+ for existPos < len (existingUsers ) && i > existingUsers [existPos ] {
176+ existPos ++
171177 }
172- if ! found {
178+ if usr . IsActive && ( existPos >= len ( existingUsers ) || i < existingUsers [ existPos ]) {
173179 log .Trace ("SyncExternalUsers[%s]: Deactivating user %s" , source .loginSource .Name , usr .Name )
174180
175181 usr .IsActive = false
0 commit comments