diff options
author | Magnus Lindvall <magnus@dnmgns.com> | 2018-05-24 06:59:02 +0200 |
---|---|---|
committer | Lauris BH <lauris@nix.lv> | 2018-05-24 07:59:02 +0300 |
commit | cdb9478774e6c5cebf5a75ff35bfa6d8a37bdbdb (patch) | |
tree | a3f8a487c45d43b15a9aaf7518e0b342880b3361 /modules | |
parent | b908ac9fab141b72f38db3d40a9f6054bb701982 (diff) | |
download | gitea-cdb9478774e6c5cebf5a75ff35bfa6d8a37bdbdb.tar.gz gitea-cdb9478774e6c5cebf5a75ff35bfa6d8a37bdbdb.zip |
LDAP Public SSH Keys synchronization (#1844)
* Add LDAP Key Synchronization feature
Signed-off-by: Magnus Lindvall <magnus@dnmgns.com>
* Add migration: add login source id column for public_key table
* Only update keys if needed
* Add function to only list pubkey synchronized from ldap
* Only list pub ssh keys synchronized from ldap. Do not sort strings as ExistsInSlice does it.
* Only get keys belonging to current login source id
* Set default login source id to 0
* Some minor cleanup. Add integration tests (updete dep testify)
Diffstat (limited to 'modules')
-rw-r--r-- | modules/auth/auth_form.go | 1 | ||||
-rw-r--r-- | modules/auth/ldap/ldap.go | 63 | ||||
-rw-r--r-- | modules/util/compare.go | 29 |
3 files changed, 63 insertions, 30 deletions
diff --git a/modules/auth/auth_form.go b/modules/auth/auth_form.go index 8fe07d0737..e44ef58f8e 100644 --- a/modules/auth/auth_form.go +++ b/modules/auth/auth_form.go @@ -24,6 +24,7 @@ type AuthenticationForm struct { AttributeName string AttributeSurname string AttributeMail string + AttributeSSHPublicKey string AttributesInBind bool UsePagedSearch bool SearchPageSize int diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go index 2e2db004f6..8a5a6cf4d0 100644 --- a/modules/auth/ldap/ldap.go +++ b/modules/auth/ldap/ldap.go @@ -28,33 +28,35 @@ const ( // Source Basic LDAP authentication service type Source struct { - Name string // canonical name (ie. corporate.ad) - Host string // LDAP host - Port int // port number - SecurityProtocol SecurityProtocol - SkipVerify bool - BindDN string // DN to bind with - BindPassword string // Bind DN password - UserBase string // Base search path for users - UserDN string // Template for the DN of the user for simple auth - AttributeUsername string // Username attribute - AttributeName string // First name attribute - AttributeSurname string // Surname attribute - AttributeMail string // E-mail attribute - AttributesInBind bool // fetch attributes in bind context (not user) - SearchPageSize uint32 // Search with paging page size - Filter string // Query filter to validate entry - AdminFilter string // Query filter to check if user is admin - Enabled bool // if this source is disabled + Name string // canonical name (ie. corporate.ad) + Host string // LDAP host + Port int // port number + SecurityProtocol SecurityProtocol + SkipVerify bool + BindDN string // DN to bind with + BindPassword string // Bind DN password + UserBase string // Base search path for users + UserDN string // Template for the DN of the user for simple auth + AttributeUsername string // Username attribute + AttributeName string // First name attribute + AttributeSurname string // Surname attribute + AttributeMail string // E-mail attribute + AttributesInBind bool // fetch attributes in bind context (not user) + AttributeSSHPublicKey string // LDAP SSH Public Key attribute + SearchPageSize uint32 // Search with paging page size + Filter string // Query filter to validate entry + AdminFilter string // Query filter to check if user is admin + Enabled bool // if this source is disabled } // SearchResult : user data type SearchResult struct { - Username string // Username - Name string // Name - Surname string // Surname - Mail string // E-mail address - IsAdmin bool // if user is administrator + Username string // Username + Name string // Name + Surname string // Surname + Mail string // E-mail address + SSHPublicKey []string // SSH Public Key + IsAdmin bool // if user is administrator } func (ls *Source) sanitizedUserQuery(username string) (string, bool) { @@ -298,10 +300,10 @@ func (ls *Source) SearchEntries() []*SearchResult { userFilter := fmt.Sprintf(ls.Filter, "*") - log.Trace("Fetching attributes '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, userFilter, ls.UserBase) + 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) search := ldap.NewSearchRequest( ls.UserBase, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter, - []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail}, + []string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey}, nil) var sr *ldap.SearchResult @@ -319,11 +321,12 @@ func (ls *Source) SearchEntries() []*SearchResult { for i, v := range sr.Entries { result[i] = &SearchResult{ - Username: v.GetAttributeValue(ls.AttributeUsername), - Name: v.GetAttributeValue(ls.AttributeName), - Surname: v.GetAttributeValue(ls.AttributeSurname), - Mail: v.GetAttributeValue(ls.AttributeMail), - IsAdmin: checkAdmin(l, ls, v.DN), + Username: v.GetAttributeValue(ls.AttributeUsername), + Name: v.GetAttributeValue(ls.AttributeName), + Surname: v.GetAttributeValue(ls.AttributeSurname), + Mail: v.GetAttributeValue(ls.AttributeMail), + SSHPublicKey: v.GetAttributeValues(ls.AttributeSSHPublicKey), + IsAdmin: checkAdmin(l, ls, v.DN), } } diff --git a/modules/util/compare.go b/modules/util/compare.go index c03a823d85..c61e7965ae 100644 --- a/modules/util/compare.go +++ b/modules/util/compare.go @@ -27,3 +27,32 @@ func IsSliceInt64Eq(a, b []int64) bool { } return true } + +// ExistsInSlice returns true if string exists in slice. +func ExistsInSlice(target string, slice []string) bool { + i := sort.Search(len(slice), + func(i int) bool { return slice[i] == target }) + return i < len(slice) +} + +// IsEqualSlice returns true if slices are equal. +func IsEqualSlice(target []string, source []string) bool { + if len(target) != len(source) { + return false + } + + if (target == nil) != (source == nil) { + return false + } + + sort.Strings(target) + sort.Strings(source) + + for i, v := range target { + if v != source[i] { + return false + } + } + + return true +} |