forked from forgejo/forgejo
LDAP user synchronization (#1478)
This commit is contained in:
parent
fd76f090a2
commit
524885dd65
15 changed files with 356 additions and 52 deletions
127
models/user.go
127
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue