@ -6,7 +6,6 @@ package ldap
import (
import (
"context"
"context"
"fmt"
"fmt"
"sort"
"strings"
"strings"
asymkey_model "code.gitea.io/gitea/models/asymkey"
asymkey_model "code.gitea.io/gitea/models/asymkey"
@ -24,7 +23,6 @@ import (
func ( source * Source ) Sync ( ctx context . Context , updateExisting bool ) error {
func ( source * Source ) Sync ( ctx context . Context , updateExisting bool ) error {
log . Trace ( "Doing: SyncExternalUsers[%s]" , source . authSource . Name )
log . Trace ( "Doing: SyncExternalUsers[%s]" , source . authSource . Name )
var existingUsers [ ] int
isAttributeSSHPublicKeySet := len ( strings . TrimSpace ( source . AttributeSSHPublicKey ) ) > 0
isAttributeSSHPublicKeySet := len ( strings . TrimSpace ( source . AttributeSSHPublicKey ) ) > 0
var sshKeysNeedUpdate bool
var sshKeysNeedUpdate bool
@ -41,9 +39,14 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
default :
default :
}
}
sort . Slice ( users , func ( i , j int ) bool {
usernameUsers := make ( map [ string ] * user_model . User , len ( users ) )
return users [ i ] . LowerName < users [ j ] . LowerName
mailUsers := make ( map [ string ] * user_model . User , len ( users ) )
} )
keepActiveUsers := make ( map [ int64 ] struct { } )
for _ , u := range users {
usernameUsers [ u . LowerName ] = u
mailUsers [ strings . ToLower ( u . Email ) ] = u
}
sr , err := source . SearchEntries ( )
sr , err := source . SearchEntries ( )
if err != nil {
if err != nil {
@ -59,11 +62,6 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
log . Warn ( "LDAP search found no entries but did not report an error. All users will be deactivated as per settings" )
log . Warn ( "LDAP search found no entries but did not report an error. All users will be deactivated as per settings" )
}
}
sort . Slice ( sr , func ( i , j int ) bool {
return sr [ i ] . LowerName < sr [ j ] . LowerName
} )
userPos := 0
orgCache := make ( map [ string ] * organization . Organization )
orgCache := make ( map [ string ] * organization . Organization )
teamCache := make ( map [ string ] * organization . Team )
teamCache := make ( map [ string ] * organization . Team )
@ -86,21 +84,27 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
return db . ErrCancelledf ( "During update of %s before completed update of users" , source . authSource . Name )
return db . ErrCancelledf ( "During update of %s before completed update of users" , source . authSource . Name )
default :
default :
}
}
if len ( su . Username ) == 0 {
if len ( su . Username ) == 0 && len ( su . Mail ) == 0 {
continue
continue
}
}
if len ( su . Mail ) == 0 {
var usr * user_model . User
su . Mail = fmt . Sprintf ( "%s@localhost" , su . Username )
if len ( su . Username ) > 0 {
usr = usernameUsers [ su . LowerName ]
}
if usr == nil && len ( su . Mail ) > 0 {
usr = mailUsers [ strings . ToLower ( su . Mail ) ]
}
}
var usr * user_model . User
if usr != nil {
for userPos < len ( users ) && users [ userPos ] . LowerName < su . LowerName {
keepActiveUsers [ usr . ID ] = struct { } { }
userPos ++
} else if len ( su . Username ) == 0 {
// we cannot create the user if su.Username is empty
continue
}
}
if userPos < len ( users ) && users [ userPos ] . LowerName == su . LowerName {
usr = users [ userPos ]
if len ( su . Mail ) == 0 {
existingUsers = append ( existingUsers , userPos )
su . Mail = fmt . Sprintf ( "%s@localhost" , su . Username )
}
}
fullName := composeFullName ( su . Name , su . Surname , su . Username )
fullName := composeFullName ( su . Name , su . Surname , su . Username )
@ -203,19 +207,17 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
// Deactivate users not present in LDAP
// Deactivate users not present in LDAP
if updateExisting {
if updateExisting {
existPos := 0
for _ , usr := range users {
for i , usr := range users {
if _ , ok := keepActiveUsers [ usr . ID ] ; ok {
for existPos < len ( existingUsers ) && i > existingUsers [ existPos ] {
continue
existPos ++
}
}
if usr . IsActive && ( existPos >= len ( existingUsers ) || i < existingUsers [ existPos ] ) {
log . Trace ( "SyncExternalUsers[%s]: Deactivating user %s" , source . authSource . Name , usr . Name )
usr . IsActive = false
log . Trace ( "SyncExternalUsers[%s]: Deactivating user %s" , source . authSource . Name , usr . Name )
err = user_model . UpdateUserCols ( ctx , usr , "is_active" )
if err != nil {
usr . IsActive = false
log . Error ( "SyncExternalUsers[%s]: Error deactivating user %s: %v" , source . authSource . Name , usr . Name , err )
err = user_model . UpdateUserCols ( ctx , usr , "is_active" )
}
if err != nil {
log . Error ( "SyncExternalUsers[%s]: Error deactivating user %s: %v" , source . authSource . Name , usr . Name , err )
}
}
}
}
}
}