Allow LDAP Sources to provide Avatars (#16851)
* Allow LDAP Sources to provide Avatars Add setting to LDAP source to allow it to provide an Avatar. Currently this is required to point to the image bytes. Fix #4144 Signed-off-by: Andrew Thornton <art27@cantab.net> * Rename as Avatar Attribute (drop JPEG) Signed-off-by: Andrew Thornton <art27@cantab.net> * Always synchronize avatar if there is change Signed-off-by: Andrew Thornton <art27@cantab.net> * Actually get the avatar from the ldap Signed-off-by: Andrew Thornton <art27@cantab.net> * clean-up Signed-off-by: Andrew Thornton <art27@cantab.net> * use len()>0 rather than != "" Signed-off-by: Andrew Thornton <art27@cantab.net> * slight shortcut in IsUploadAvatarChanged Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
parent
7e98cd58dd
commit
123f0aea00
13 changed files with 80 additions and 6 deletions
|
@ -42,6 +42,7 @@ type Source struct {
|
|||
AttributeMail string // E-mail attribute
|
||||
AttributesInBind bool // fetch attributes in bind context (not user)
|
||||
AttributeSSHPublicKey string // LDAP SSH Public Key attribute
|
||||
AttributeAvatar string
|
||||
SearchPageSize uint32 // Search with paging page size
|
||||
Filter string // Query filter to validate entry
|
||||
AdminFilter string // Query filter to check if user is admin
|
||||
|
|
|
@ -96,6 +96,10 @@ func (source *Source) Authenticate(user *models.User, userName, password string)
|
|||
err = models.RewriteAllPublicKeys()
|
||||
}
|
||||
|
||||
if err == nil && len(source.AttributeAvatar) > 0 {
|
||||
_ = user.UploadAvatar(sr.Avatar)
|
||||
}
|
||||
|
||||
return user, err
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ type SearchResult struct {
|
|||
IsAdmin bool // if user is administrator
|
||||
IsRestricted bool // if user is restricted
|
||||
LowerName string // Lowername
|
||||
Avatar []byte
|
||||
}
|
||||
|
||||
func (ls *Source) sanitizedUserQuery(username string) (string, bool) {
|
||||
|
@ -266,7 +267,8 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
|
|||
return nil
|
||||
}
|
||||
|
||||
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(ls.AttributeSSHPublicKey)) > 0
|
||||
isAttributeSSHPublicKeySet := len(strings.TrimSpace(ls.AttributeSSHPublicKey)) > 0
|
||||
isAtributeAvatarSet := len(strings.TrimSpace(ls.AttributeAvatar)) > 0
|
||||
|
||||
attribs := []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail}
|
||||
if len(strings.TrimSpace(ls.UserUID)) > 0 {
|
||||
|
@ -275,8 +277,11 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
|
|||
if isAttributeSSHPublicKeySet {
|
||||
attribs = append(attribs, ls.AttributeSSHPublicKey)
|
||||
}
|
||||
if isAtributeAvatarSet {
|
||||
attribs = append(attribs, ls.AttributeAvatar)
|
||||
}
|
||||
|
||||
log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v', '%v' with filter '%s' and base '%s'", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, ls.UserUID, userFilter, userDN)
|
||||
log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v', '%v', '%v' with filter '%s' and base '%s'", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, ls.AttributeAvatar, ls.UserUID, userFilter, userDN)
|
||||
search := ldap.NewSearchRequest(
|
||||
userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
|
||||
attribs, nil)
|
||||
|
@ -296,6 +301,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
|
|||
}
|
||||
|
||||
var sshPublicKey []string
|
||||
var Avatar []byte
|
||||
|
||||
username := sr.Entries[0].GetAttributeValue(ls.AttributeUsername)
|
||||
firstname := sr.Entries[0].GetAttributeValue(ls.AttributeName)
|
||||
|
@ -363,6 +369,10 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
|
|||
}
|
||||
}
|
||||
|
||||
if isAtributeAvatarSet {
|
||||
Avatar = sr.Entries[0].GetRawAttributeValue(ls.AttributeAvatar)
|
||||
}
|
||||
|
||||
return &SearchResult{
|
||||
LowerName: strings.ToLower(username),
|
||||
Username: username,
|
||||
|
@ -372,6 +382,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul
|
|||
SSHPublicKey: sshPublicKey,
|
||||
IsAdmin: isAdmin,
|
||||
IsRestricted: isRestricted,
|
||||
Avatar: Avatar,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,14 +414,18 @@ func (ls *Source) SearchEntries() ([]*SearchResult, error) {
|
|||
|
||||
userFilter := fmt.Sprintf(ls.Filter, "*")
|
||||
|
||||
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(ls.AttributeSSHPublicKey)) > 0
|
||||
isAttributeSSHPublicKeySet := len(strings.TrimSpace(ls.AttributeSSHPublicKey)) > 0
|
||||
isAtributeAvatarSet := len(strings.TrimSpace(ls.AttributeAvatar)) > 0
|
||||
|
||||
attribs := []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail}
|
||||
if isAttributeSSHPublicKeySet {
|
||||
attribs = append(attribs, ls.AttributeSSHPublicKey)
|
||||
}
|
||||
if isAtributeAvatarSet {
|
||||
attribs = append(attribs, ls.AttributeAvatar)
|
||||
}
|
||||
|
||||
log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, userFilter, ls.UserBase)
|
||||
log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, ls.AttributeAvatar, userFilter, ls.UserBase)
|
||||
search := ldap.NewSearchRequest(
|
||||
ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter,
|
||||
attribs, nil)
|
||||
|
@ -442,8 +457,10 @@ func (ls *Source) SearchEntries() ([]*SearchResult, error) {
|
|||
if isAttributeSSHPublicKeySet {
|
||||
result[i].SSHPublicKey = v.GetAttributeValues(ls.AttributeSSHPublicKey)
|
||||
}
|
||||
if isAtributeAvatarSet {
|
||||
result[i].Avatar = v.GetRawAttributeValue(ls.AttributeAvatar)
|
||||
}
|
||||
result[i].LowerName = strings.ToLower(result[i].Username)
|
||||
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
|
|
@ -112,12 +112,18 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
|
|||
|
||||
if err != nil {
|
||||
log.Error("SyncExternalUsers[%s]: Error creating user %s: %v", source.loginSource.Name, su.Username, err)
|
||||
} else if isAttributeSSHPublicKeySet {
|
||||
}
|
||||
|
||||
if err == nil && isAttributeSSHPublicKeySet {
|
||||
log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", source.loginSource.Name, usr.Name)
|
||||
if models.AddPublicKeysBySource(usr, source.loginSource, su.SSHPublicKey) {
|
||||
sshKeysNeedUpdate = true
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil && len(source.AttributeAvatar) > 0 {
|
||||
_ = usr.UploadAvatar(su.Avatar)
|
||||
}
|
||||
} else if updateExisting {
|
||||
// Synchronize SSH Public Key if that attribute is set
|
||||
if isAttributeSSHPublicKeySet && models.SynchronizePublicKeys(usr, source.loginSource, su.SSHPublicKey) {
|
||||
|
@ -150,6 +156,13 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error {
|
|||
log.Error("SyncExternalUsers[%s]: Error updating user %s: %v", source.loginSource.Name, usr.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if usr.IsUploadAvatarChanged(su.Avatar) {
|
||||
if err == nil && len(source.AttributeAvatar) > 0 {
|
||||
_ = usr.UploadAvatar(su.Avatar)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ type AuthenticationForm struct {
|
|||
AttributeSurname string
|
||||
AttributeMail string
|
||||
AttributeSSHPublicKey string
|
||||
AttributeAvatar string
|
||||
AttributesInBind bool
|
||||
UsePagedSearch bool
|
||||
SearchPageSize int
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue