diff options
author | Lauris BH <lauris@nix.lv> | 2017-05-10 16:10:18 +0300 |
---|---|---|
committer | Kim "BKC" Carlbäcker <kim.carlbacker@gmail.com> | 2017-05-10 15:10:18 +0200 |
commit | 524885dd6502570dddf5c83f171ee74890dba5c4 (patch) | |
tree | 6256ab65739e8b2b9f4d9b498e10526341c2493c /models/user.go | |
parent | fd76f090a29b229b9e8e089e225f7ca012809090 (diff) | |
download | gitea-524885dd6502570dddf5c83f171ee74890dba5c4.tar.gz gitea-524885dd6502570dddf5c83f171ee74890dba5c4.zip |
LDAP user synchronization (#1478)
Diffstat (limited to 'models/user.go')
-rw-r--r-- | models/user.go | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/models/user.go b/models/user.go index e95bf5cd44..7e6bbd5dc3 100644 --- a/models/user.go +++ b/models/user.go @@ -50,6 +50,8 @@ const ( UserTypeOrganization ) +const syncExternalUsers = "sync_external_users" + var ( // ErrUserNotKeyOwner user does not own this key error ErrUserNotKeyOwner = errors.New("User does not own this public key") @@ -1322,3 +1324,128 @@ func GetWatchedRepos(userID int64, private bool) ([]*Repository, error) { } return repos, nil } + +// SyncExternalUsers is used to synchronize users with external authorization source +func SyncExternalUsers() { + if taskStatusTable.IsRunning(syncExternalUsers) { + return + } + taskStatusTable.Start(syncExternalUsers) + defer taskStatusTable.Stop(syncExternalUsers) + + log.Trace("Doing: SyncExternalUsers") + + ls, err := LoginSources() + if err != nil { + log.Error(4, "SyncExternalUsers: %v", err) + return + } + + updateExisting := setting.Cron.SyncExternalUsers.UpdateExisting + + for _, s := range ls { + if !s.IsActived || !s.IsSyncEnabled { + continue + } + if s.IsLDAP() { + log.Trace("Doing: SyncExternalUsers[%s]", s.Name) + + var existingUsers []int64 + + // Find all users with this login type + var users []User + x.Where("login_type = ?", LoginLDAP). + And("login_source = ?", s.ID). + Find(&users) + + sr := s.LDAP().SearchEntries() + + for _, su := range sr { + if len(su.Username) == 0 { + continue + } + + if len(su.Mail) == 0 { + su.Mail = fmt.Sprintf("%s@localhost", su.Username) + } + + var usr *User + // Search for existing user + for _, du := range users { + if du.LowerName == strings.ToLower(su.Username) { + usr = &du + break + } + } + + fullName := composeFullName(su.Name, su.Surname, su.Username) + // If no existing user found, create one + if usr == nil { + log.Trace("SyncExternalUsers[%s]: Creating user %s", s.Name, su.Username) + + usr = &User{ + LowerName: strings.ToLower(su.Username), + Name: su.Username, + FullName: fullName, + LoginType: s.Type, + LoginSource: s.ID, + LoginName: su.Username, + Email: su.Mail, + IsAdmin: su.IsAdmin, + IsActive: true, + } + + err = CreateUser(usr) + if err != nil { + log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err) + } + } else if updateExisting { + existingUsers = append(existingUsers, usr.ID) + // Check if user data has changed + if (len(s.LDAP().AdminFilter) > 0 && usr.IsAdmin != su.IsAdmin) || + strings.ToLower(usr.Email) != strings.ToLower(su.Mail) || + usr.FullName != fullName || + !usr.IsActive { + + log.Trace("SyncExternalUsers[%s]: Updating user %s", s.Name, usr.Name) + + usr.FullName = fullName + usr.Email = su.Mail + // Change existing admin flag only if AdminFilter option is set + if len(s.LDAP().AdminFilter) > 0 { + usr.IsAdmin = su.IsAdmin + } + usr.IsActive = true + + err = UpdateUser(usr) + if err != nil { + log.Error(4, "SyncExternalUsers[%s]: Error updating user %s: %v", s.Name, usr.Name, err) + } + } + } + } + + // Deactivate users not present in LDAP + if updateExisting { + for _, usr := range users { + found := false + for _, uid := range existingUsers { + if usr.ID == uid { + found = true + break + } + } + if !found { + log.Trace("SyncExternalUsers[%s]: Deactivating user %s", s.Name, usr.Name) + + usr.IsActive = false + err = UpdateUser(&usr) + if err != nil { + log.Error(4, "SyncExternalUsers[%s]: Error deactivating user %s: %v", s.Name, usr.Name, err) + } + } + } + } + } + } +} |