providers/ldap: improve mapping of LDAP filters to authentik queries

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-12-12 18:30:52 +00:00
parent 6f9002eb01
commit 107f2745c8
4 changed files with 55 additions and 60 deletions

View File

@ -9,7 +9,7 @@ import (
ldapConstants "goauthentik.io/internal/outpost/ldap/constants"
)
func ldapResolveTypeSingle(in interface{}) *string {
func stringify(in interface{}) *string {
switch t := in.(type) {
case string:
return &t
@ -51,13 +51,13 @@ func AKAttrsToLDAP(attrs map[string]interface{}) []*ldap.EntryAttribute {
case []interface{}:
entry.Values = make([]string, len(t))
for idx, v := range t {
v := ldapResolveTypeSingle(v)
v := stringify(v)
if v != nil {
entry.Values[idx] = *v
}
}
default:
v := ldapResolveTypeSingle(t)
v := stringify(t)
if v != nil {
entry.Values = []string{*v}
}

View File

@ -40,32 +40,30 @@ func parseFilterForGroupSingle(req api.ApiCoreGroupsListRequest, f *ber.Packet)
if v == nil {
return req, false
}
// Switch on type of the value, then check the key
switch vv := v.(type) {
case string:
switch strings.ToLower(k.(string)) {
case "cn":
return req.Name(vv), false
case "member":
fallthrough
case "memberOf":
userDN, err := goldap.ParseDN(vv)
if err != nil {
return req.MembersByUsername([]string{vv}), false
}
username := userDN.RDNs[0].Attributes[0].Value
// If the DN's first ou is virtual-groups, ignore this filter
if len(userDN.RDNs) > 1 {
if strings.EqualFold(userDN.RDNs[1].Attributes[0].Value, constants.OUVirtualGroups) || strings.EqualFold(userDN.RDNs[1].Attributes[0].Value, constants.OUGroups) {
// Since we know we're not filtering anything, skip this request
return req, true
}
}
return req.MembersByUsername([]string{username}), false
}
//TODO: Support int
default:
val := stringify(v)
if val == nil {
return req, false
}
// Check key
switch strings.ToLower(k.(string)) {
case "cn":
return req.Name(*val), false
case "member":
fallthrough
case "memberOf":
userDN, err := goldap.ParseDN(*val)
if err != nil {
return req.MembersByUsername([]string{*val}), false
}
username := userDN.RDNs[0].Attributes[0].Value
// If the DN's first ou is virtual-groups, ignore this filter
if len(userDN.RDNs) > 1 {
if strings.EqualFold(userDN.RDNs[1].Attributes[0].Value, constants.OUVirtualGroups) || strings.EqualFold(userDN.RDNs[1].Attributes[0].Value, constants.OUGroups) {
// Since we know we're not filtering anything, skip this request
return req, true
}
}
return req.MembersByUsername([]string{username}), false
}
return req, false
}

View File

@ -7,9 +7,9 @@ import (
"goauthentik.io/api/v3"
)
func Test_ldapResolveTypeSingle_nil(t *testing.T) {
func Test_stringify_nil(t *testing.T) {
var ex *string
assert.Equal(t, ex, ldapResolveTypeSingle(nil))
assert.Equal(t, ex, stringify(nil))
}
func TestAKAttrsToLDAP_String(t *testing.T) {

View File

@ -38,37 +38,34 @@ func parseFilterForUserSingle(req api.ApiCoreUsersListRequest, f *ber.Packet) (a
if v == nil {
return req, false
}
// Switch on type of the value, then check the key
switch vv := v.(type) {
case string:
switch k {
case "cn":
return req.Username(vv), false
case "name":
case "displayName":
return req.Name(vv), false
case "mail":
return req.Email(vv), false
case "member":
fallthrough
case "memberOf":
groupDN, err := goldap.ParseDN(vv)
if err != nil {
return req.GroupsByName([]string{vv}), false
}
name := groupDN.RDNs[0].Attributes[0].Value
// If the DN's first ou is virtual-groups, ignore this filter
if len(groupDN.RDNs) > 1 {
if groupDN.RDNs[1].Attributes[0].Value == constants.OUUsers || groupDN.RDNs[1].Attributes[0].Value == constants.OUVirtualGroups {
// Since we know we're not filtering anything, skip this request
return req, true
}
}
return req.GroupsByName([]string{name}), false
}
//TODO: Support int
default:
val := stringify(v)
if val == nil {
return req, false
}
switch k {
case "cn":
return req.Username(*val), false
case "name":
case "displayName":
return req.Name(*val), false
case "mail":
return req.Email(*val), false
case "member":
fallthrough
case "memberOf":
groupDN, err := goldap.ParseDN(*val)
if err != nil {
return req.GroupsByName([]string{*val}), false
}
name := groupDN.RDNs[0].Attributes[0].Value
// If the DN's first ou is virtual-groups, ignore this filter
if len(groupDN.RDNs) > 1 {
if groupDN.RDNs[1].Attributes[0].Value == constants.OUUsers || groupDN.RDNs[1].Attributes[0].Value == constants.OUVirtualGroups {
// Since we know we're not filtering anything, skip this request
return req, true
}
}
return req.GroupsByName([]string{name}), false
}
return req, false
}