mirror of
https://github.com/project-zot/zot.git
synced 2025-03-18 02:22:53 -05:00
feat(ldap): allow to customize user filter (#2927)
feat(ldap): allow to customize user filter (#2927) Signed-off-by: Vladimir Ermakov <vooon341@gmail.com>
This commit is contained in:
parent
05823cd74f
commit
4fcd1079f7
5 changed files with 57 additions and 18 deletions
|
@ -19,6 +19,7 @@
|
|||
"startTLS": false,
|
||||
"baseDN":"ou=Users,dc=example,dc=org",
|
||||
"userAttribute": "uid",
|
||||
"userFilter": "(!(nsaccountlock=TRUE))",
|
||||
"userGroupAttribute": "memberOf",
|
||||
"skipVerify": true,
|
||||
"subtreeSearch": true
|
||||
|
@ -69,4 +70,4 @@
|
|||
"output": "/tmp/zot.log",
|
||||
"audit": "/tmp/zot-audit.log"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -272,7 +272,8 @@ func (amw *AuthnMiddleware) tryAuthnHandlers(ctlr *Controller) mux.MiddlewareFun
|
|||
BindDN: ldapConfig.BindDN(),
|
||||
BindPassword: ldapConfig.BindPassword(),
|
||||
UserGroupAttribute: ldapConfig.UserGroupAttribute, // from config
|
||||
UserFilter: fmt.Sprintf("(%s=%%s)", ldapConfig.UserAttribute),
|
||||
UserAttribute: ldapConfig.UserAttribute,
|
||||
UserFilter: ldapConfig.UserFilter,
|
||||
InsecureSkipVerify: ldapConfig.SkipVerify,
|
||||
ServerName: ldapConfig.Address,
|
||||
Log: ctlr.Log,
|
||||
|
|
|
@ -175,6 +175,7 @@ type LDAPConfig struct {
|
|||
UserGroupAttribute string
|
||||
BaseDN string
|
||||
UserAttribute string
|
||||
UserFilter string
|
||||
CACert string
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ var (
|
|||
LDAPBaseDN = "ou=" + username //nolint: gochecknoglobals
|
||||
LDAPBindDN = "cn=reader," + LDAPBaseDN //nolint: gochecknoglobals
|
||||
LDAPBindPassword = "ldappass" //nolint: gochecknoglobals
|
||||
LDAPUserAttr = "uid" //nolint: gochecknoglobals
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
|
@ -2974,6 +2975,13 @@ func (l *testLDAPServer) Search(boundDN string, req vldap.SearchRequest,
|
|||
}, nil
|
||||
}
|
||||
|
||||
if req.Filter == "(&(uid=locked-user)((!(nsaccountlock=TRUE))))" {
|
||||
return vldap.ServerSearchResult{
|
||||
Entries: []*vldap.Entry{},
|
||||
ResultCode: vldap.LDAPResultSuccess,
|
||||
}, nil
|
||||
}
|
||||
|
||||
check := fmt.Sprintf("(uid=%s)", username)
|
||||
|
||||
if check == req.Filter {
|
||||
|
@ -3769,13 +3777,14 @@ func TestLDAPClient(t *testing.T) {
|
|||
|
||||
// bad user credentials with anonymous authentication
|
||||
lClient = &api.LDAPClient{
|
||||
Host: LDAPAddress,
|
||||
Port: ldapPort,
|
||||
BindDN: LDAPBindDN,
|
||||
BindPassword: LDAPBindPassword,
|
||||
Base: LDAPBaseDN,
|
||||
UserFilter: "(uid=%s)",
|
||||
SkipTLS: true,
|
||||
Host: LDAPAddress,
|
||||
Port: ldapPort,
|
||||
BindDN: LDAPBindDN,
|
||||
BindPassword: LDAPBindPassword,
|
||||
Base: LDAPBaseDN,
|
||||
UserAttribute: LDAPUserAttr,
|
||||
UserFilter: "",
|
||||
SkipTLS: true,
|
||||
}
|
||||
|
||||
_, _, _, err = lClient.Authenticate("fail-user-bind", "")
|
||||
|
@ -3783,17 +3792,33 @@ func TestLDAPClient(t *testing.T) {
|
|||
|
||||
// bad user credentials with anonymous authentication
|
||||
lClient = &api.LDAPClient{
|
||||
Host: LDAPAddress,
|
||||
Port: ldapPort,
|
||||
BindDN: LDAPBindDN,
|
||||
BindPassword: LDAPBindPassword,
|
||||
Base: LDAPBaseDN,
|
||||
UserFilter: "(uid=%s)",
|
||||
SkipTLS: true,
|
||||
Host: LDAPAddress,
|
||||
Port: ldapPort,
|
||||
BindDN: LDAPBindDN,
|
||||
BindPassword: LDAPBindPassword,
|
||||
Base: LDAPBaseDN,
|
||||
UserAttribute: LDAPUserAttr,
|
||||
UserFilter: "",
|
||||
SkipTLS: true,
|
||||
}
|
||||
|
||||
_, _, _, err = lClient.Authenticate("fail-user-bind", "pass")
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// user filtered by additional filter (disabled account in FreeIPA)
|
||||
lClient = &api.LDAPClient{
|
||||
Host: LDAPAddress,
|
||||
Port: ldapPort,
|
||||
BindDN: LDAPBindDN,
|
||||
BindPassword: LDAPBindPassword,
|
||||
Base: LDAPBaseDN,
|
||||
UserAttribute: LDAPUserAttr,
|
||||
UserFilter: "(!(nsaccountlock=TRUE))",
|
||||
SkipTLS: true,
|
||||
}
|
||||
|
||||
_, _, _, err = lClient.Authenticate("locked-user", "pass")
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ type LDAPClient struct {
|
|||
UserGroupAttribute string // e.g. "memberOf"
|
||||
Host string
|
||||
ServerName string
|
||||
UserFilter string // e.g. "(uid=%s)"
|
||||
UserFilter string // e.g. "(!(nsaccountlock=TRUE))"
|
||||
UserAttribute string // e.g. "uid"
|
||||
Conn *ldap.Conn
|
||||
ClientCertificates []tls.Certificate // Adding client certificates
|
||||
ClientCAs *x509.CertPool
|
||||
|
@ -187,7 +188,7 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
|||
searchRequest := ldap.NewSearchRequest(
|
||||
lc.Base,
|
||||
searchScope, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf(lc.UserFilter, username),
|
||||
lc.userFilter(username),
|
||||
attributes,
|
||||
nil,
|
||||
)
|
||||
|
@ -242,3 +243,13 @@ func (lc *LDAPClient) Authenticate(username, password string) (bool, map[string]
|
|||
|
||||
return true, user, userGroups, nil
|
||||
}
|
||||
|
||||
func (lc *LDAPClient) userFilter(username string) string {
|
||||
filter := fmt.Sprintf("(%s=%s)", lc.UserAttribute, ldap.EscapeFilter(username))
|
||||
|
||||
if lc.UserFilter != "" {
|
||||
filter = fmt.Sprintf("(&(%s)(%s))", filter, lc.UserFilter)
|
||||
}
|
||||
|
||||
return filter
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue