Skip to content

Commit

Permalink
introspect ldap group types for param validation
Browse files Browse the repository at this point in the history
* Instead of keeping a hard-coded mapping of valid args for each ldap
group type; introspect the subclass to determine valid/invalid fields
  • Loading branch information
chrismeyersfsu committed Mar 26, 2018
1 parent cb7e178 commit b9b8502
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 32 deletions.
51 changes: 22 additions & 29 deletions awx/sso/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from django_auth_ldap.config import (
LDAPSearch,
LDAPSearchUnion,
LDAPGroupType,
)

# This must be imported so get_subclasses picks it up
Expand All @@ -32,6 +31,18 @@ def get_subclasses(cls):
yield subclass


def find_class_in_modules(class_name):
'''
Used to find ldap subclasses by string
'''
module_search_space = [django_auth_ldap.config, awx.sso.ldap_group_types]
for m in module_search_space:
cls = getattr(m, class_name, None)
if cls:
return cls
return None


class DependsOnMixin():
def get_depends_on(self):
"""
Expand Down Expand Up @@ -349,14 +360,6 @@ def to_internal_value(self, data):
return data


VALID_GROUP_TYPE_PARAMS_MAP = {
'LDAPGroupType': ['name_attr'],
'MemberDNGroupType': ['name_attr', 'member_attr'],
'PosixUIDGroupType': ['name_attr', 'ldap_group_user_attr'],
}



class LDAPGroupTypeField(fields.ChoiceField, DependsOnMixin):

default_error_messages = {
Expand All @@ -376,14 +379,6 @@ def to_representation(self, value):
return value.__class__.__name__

def to_internal_value(self, data):
def find_class_in_modules(class_name):
module_search_space = [django_auth_ldap.config, awx.sso.ldap_group_types]
for m in module_search_space:
cls = getattr(m, class_name, None)
if cls:
return cls
return None

data = super(LDAPGroupTypeField, self).to_internal_value(data)
if not data:
return None
Expand All @@ -399,17 +394,9 @@ def find_class_in_modules(class_name):
# MemberDNGroupType was the only group type, of the underlying lib, that
# took a parameter.
params_sanitized = dict()
if isinstance(cls, LDAPGroupType):
for k in VALID_GROUP_TYPE_PARAMS_MAP['LDAPGroupType']:
if k in params:
params_sanitized['name_attr'] = params['name_attr']

if data.endswith('MemberDNGroupType'):
params.setdefault('member_attr', 'member')
params_sanitized['member_attr'] = params['member_attr']
elif data.endswith('PosixUIDGroupType'):
params.setdefault('ldap_group_user_attr', 'uid')
params_sanitized['ldap_group_user_attr'] = params['ldap_group_user_attr']
for attr in inspect.getargspec(cls.__init__).args[1:]:
if attr in params:
params_sanitized[attr] = params[attr]

return cls(**params_sanitized)

Expand All @@ -425,7 +412,13 @@ def to_internal_value(self, value):
return value
group_type_str = self.get_depends_on()
group_type_str = group_type_str or ''
invalid_keys = (set(value.keys()) - set(VALID_GROUP_TYPE_PARAMS_MAP.get(group_type_str, 'LDAPGroupType')))

group_type_cls = find_class_in_modules(group_type_str)
if not group_type_cls:
# Fail safe
return {}

invalid_keys = set(value.keys()) - set(inspect.getargspec(group_type_cls.__init__).args[1:])
if invalid_keys:
keys_display = json.dumps(list(invalid_keys)).lstrip('[').rstrip(']')
self.fail('invalid_keys', invalid_keys=keys_display)
Expand Down
5 changes: 2 additions & 3 deletions awx/sso/ldap_group_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@

class PosixUIDGroupType(LDAPGroupType):

def __init__(self, ldap_group_user_attr, *args, **kwargs):
super(PosixUIDGroupType, self).__init__(*args, **kwargs)

def __init__(self, name_attr='cn', ldap_group_user_attr='uid'):
self.ldap_group_user_attr = ldap_group_user_attr
super(PosixUIDGroupType, self).__init__(name_attr)

"""
An LDAPGroupType subclass that handles non-standard DS.
Expand Down

0 comments on commit b9b8502

Please sign in to comment.