aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorMagnus Lindvall <magnus@dnmgns.com>2018-05-24 06:59:02 +0200
committerLauris BH <lauris@nix.lv>2018-05-24 07:59:02 +0300
commitcdb9478774e6c5cebf5a75ff35bfa6d8a37bdbdb (patch)
treea3f8a487c45d43b15a9aaf7518e0b342880b3361 /modules
parentb908ac9fab141b72f38db3d40a9f6054bb701982 (diff)
downloadgitea-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.go1
-rw-r--r--modules/auth/ldap/ldap.go63
-rw-r--r--modules/util/compare.go29
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
+}