providers/ldap: improve mapping of LDAP filters to authentik queries
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
6f9002eb01
commit
107f2745c8
|
@ -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}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Reference in New Issue