def test_populate_without_auth(self): self._init_settings( USER_DN_TEMPLATE='uid=%(user)s,ou=people,o=test', ALWAYS_UPDATE_USER=False, USER_ATTR_MAP={'first_name': 'givenName', 'last_name': 'sn'}, GROUP_SEARCH=LDAPSearch('ou=groups,o=test', ldap.SCOPE_SUBTREE), GROUP_TYPE=GroupOfNamesType(), USER_FLAGS_BY_GROUP={ 'is_active': "cn=active_gon,ou=groups,o=test", 'is_staff': "cn=staff_gon,ou=groups,o=test", 'is_superuser': "******" } ) User.objects.create(username='******') User.objects.create(username='******') alice = self.backend.populate_user('alice') bob = self.backend.populate_user('bob') self.assertTrue(alice is not None) self.assertEqual(alice.first_name, u"Alice") self.assertEqual(alice.last_name, u"Adams") self.assertTrue(alice.is_active) self.assertTrue(alice.is_staff) self.assertTrue(alice.is_superuser) self.assertTrue(bob is not None) self.assertEqual(bob.first_name, u"Robert") self.assertEqual(bob.last_name, u"Barker") self.assertTrue(not bob.is_active) self.assertTrue(not bob.is_staff) self.assertTrue(not bob.is_superuser)
def to_django_settings(self): """Apply LDAP related parameters to Django settings. Doing so, we can use the django_auth_ldap module. """ try: import ldap from django_auth_ldap.config import ( LDAPSearch, PosixGroupType, GroupOfNamesType) ldap_available = True except ImportError: ldap_available = False values = dict(param_tools.get_global_parameters("core")) if not ldap_available or values["authentication_type"] != "ldap": return if not hasattr(settings, "AUTH_LDAP_USER_ATTR_MAP"): setattr(settings, "AUTH_LDAP_USER_ATTR_MAP", { "first_name": "givenName", "email": "mail", "last_name": "sn" }) ldap_uri = "ldaps://" if values["ldap_secured"] else "ldap://" ldap_uri += "%s:%s" % ( values["ldap_server_address"], values["ldap_server_port"]) setattr(settings, "AUTH_LDAP_SERVER_URI", ldap_uri) if values["ldap_group_type"] == "groupofnames": setattr(settings, "AUTH_LDAP_GROUP_TYPE", GroupOfNamesType()) searchfilter = "(objectClass=groupOfNames)" else: setattr(settings, "AUTH_LDAP_GROUP_TYPE", PosixGroupType()) searchfilter = "(objectClass=posixGroup)" setattr(settings, "AUTH_LDAP_GROUP_SEARCH", LDAPSearch( values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE, searchfilter )) if values["ldap_auth_method"] == "searchbind": setattr(settings, "AUTH_LDAP_BIND_DN", values["ldap_bind_dn"]) setattr( settings, "AUTH_LDAP_BIND_PASSWORD", values["ldap_bind_password"] ) search = LDAPSearch( values["ldap_search_base"], ldap.SCOPE_SUBTREE, values["ldap_search_filter"] ) setattr(settings, "AUTH_LDAP_USER_SEARCH", search) else: setattr( settings, "AUTH_LDAP_USER_DN_TEMPLATE", values["ldap_user_dn_template"] ) if values["ldap_is_active_directory"]: if not hasattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS"): setattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS", { ldap.OPT_REFERRALS: False }) else: settings.AUTH_LDAP_GLOBAL_OPTIONS[ldap.OPT_REFERRALS] = False
def _apply_ldap_settings(self, values, backend): """Apply configuration for given backend.""" import ldap from django_auth_ldap.config import (LDAPSearch, PosixGroupType, GroupOfNamesType, ActiveDirectoryGroupType) if not hasattr(settings, backend.setting_fullname("USER_ATTR_MAP")): setattr(settings, backend.setting_fullname("USER_ATTR_MAP"), { "first_name": "givenName", "email": "mail", "last_name": "sn" }) ldap_uri = "ldaps://" if values["ldap_secured"] == "ssl" else "ldap://" ldap_uri += "%s:%s" % (values[backend.srv_address_setting_name], values[backend.srv_port_setting_name]) setattr(settings, backend.setting_fullname("SERVER_URI"), ldap_uri) if values["ldap_secured"] == "starttls": setattr(settings, backend.setting_fullname("START_TLS"), True) if values["ldap_is_active_directory"]: setattr(settings, backend.setting_fullname("GROUP_TYPE"), ActiveDirectoryGroupType()) searchfilter = "(objectClass=group)" elif values["ldap_group_type"] == "groupofnames": setattr(settings, backend.setting_fullname("GROUP_TYPE"), GroupOfNamesType()) searchfilter = "(objectClass=groupOfNames)" else: setattr(settings, backend.setting_fullname("GROUP_TYPE"), PosixGroupType()) searchfilter = "(objectClass=posixGroup)" setattr( settings, backend.setting_fullname("GROUP_SEARCH"), LDAPSearch(values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE, searchfilter)) if values["ldap_auth_method"] == "searchbind": setattr(settings, backend.setting_fullname("BIND_DN"), values["ldap_bind_dn"]) setattr(settings, backend.setting_fullname("BIND_PASSWORD"), values["ldap_bind_password"]) search = LDAPSearch(values["ldap_search_base"], ldap.SCOPE_SUBTREE, values["ldap_search_filter"]) setattr(settings, backend.setting_fullname("USER_SEARCH"), search) else: setattr(settings, backend.setting_fullname("USER_DN_TEMPLATE"), values["ldap_user_dn_template"]) setattr(settings, backend.setting_fullname("BIND_AS_AUTHENTICATING_USER"), True) if values["ldap_is_active_directory"]: setting = backend.setting_fullname("GLOBAL_OPTIONS") if not hasattr(settings, setting): setattr(settings, setting, {ldap.OPT_REFERRALS: False}) else: getattr(settings, setting)[ldap.OPT_REFERRALS] = False
'LDAPURI') #example : LDAPURI=ldap://contosoOpenLdap AUTH_LDAP_BIND_DN = os.environ.get( 'LDAPBIND') # example : 'cn=ldap-ro,dc=contoso,dc=com' AUTH_LDAP_BIND_PASSWORD = os.environ.get( 'LDAPPASSWRD') # example : 'P@ss1W0Rd!' AUTH_LDAP_USER_SEARCH = LDAPSearch( os.environ.get('LDAPUSERS'), ldap.SCOPE_SUBTREE, '(uid=%(user)s)', ) AUTH_LDAP_GROUP_SEARCH = LDAPSearch( os.environ.get('LDAPGROUPS'), ldap.SCOPE_SUBTREE, '(objectClass=groupOfNames)', ) # general ldap variables AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', 'django_auth_ldap.backend.LDAPBackend', ) AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr='cn') AUTH_LDAP_USER_ATTR_MAP = { 'first_name': 'givenName', 'last_name': 'sn', 'email': 'mail', } AUTH_LDAP_ALWAYS_UPDATE_USER = True AUTH_LDAP_FIND_GROUP_PERMS = True AUTH_LDAP_CACHE_TIMEOUT = 3600
# If a user's DN is producible from their username, we don't need to search. # AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=users,dc=lab,dc=example,dc=com" AUTH_LDAP_USER_DN_TEMPLATE = "None" # You can map user attributes to Django attributes as so. AUTH_LDAP_USER_ATTR_MAP = { "first_name": "givenName", "last_name": "sn", "email": "mail" } # This search ought to return all groups to which the user belongs. # django_auth_ldap uses this to determine group heirarchy. AUTH_LDAP_GROUP_SEARCH = LDAPSearch("dc=lab,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(objectClass=group)") AUTH_LDAP_GROUP_TYPE = GroupOfNamesType() # Define a group required to login. AUTH_LDAP_REQUIRE_GROUP = "cn=Netbox Users,dc=lab,dc=example,DC=com" # Define special user types using groups. Exercise great caution when assigning # superuser status. AUTH_LDAP_USER_FLAGS_BY_GROUP = { "is_active": "cn=active,ou=groups,dc=lab,dc=example,dc=com", } # This should only be done once AUTH_LDAP_ALWAYS_UPDATE_USER = False # For more granular permissions, we can map LDAP groups to Django groups. AUTH_LDAP_FIND_GROUP_PERMS = True
'django.contrib.auth.backends.ModelBackend', ] AUTH_LDAP_SERVER_URI = os.environ['LDAP_SERVER_URI'] AUTH_LDAP_BIND_DN = os.environ.get('LDAP_ADMIN_USER_NAME', '') AUTH_LDAP_BIND_PASSWORD = os.environ.get('LDAP_ADMIN_USER_PASSWORD', '') # AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=people,ou=fs_wiai,ou=fachschaften,dc=stuve,dc=de" AUTH_LDAP_USER_SEARCH = LDAPSearch(os.environ['LDAP_USER_ENTRY'], ldap.SCOPE_SUBTREE, os.environ['LDAP_USER_SELECTOR']) AUTH_LDAP_GROUP_SEARCH = LDAPSearch( os.environ['LDAP_GROUP_ENTRY'], ldap.SCOPE_SUBTREE, os.environ['LDAP_GROUP_SELECTOR'], ) AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr=os.environ['LDAP_GROUP_NAME_ATTR']) AUTH_LDAP_MIRROR_GROUPS = True AUTH_LDAP_USER_ATTR_MAP = { 'first_name': 'cn', 'last_name': 'sn', 'email': 'mail', } AUTH_PROFILE_MODULE = 'account_manager.UserProfile' ######################################################################################################################## # EMAIL Config # ######################################################################################################################## if 'file' in os.environ['EMAIL_BACKEND']: EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend' EMAIL_FILE_PATH = os.path.join(BASE_DIR, "sent_emails")
def _get_default_setting(self): """ Get default settings from ldap database """ defaults = { 'ALWAYS_UPDATE_USER': True, 'AUTHORIZE_ALL_USERS': False, 'BIND_AS_AUTHENTICATING_USER': False, 'BIND_DN': '', 'BIND_PASSWORD': '', 'CACHE_GROUPS': False, 'CONNECTION_OPTIONS': {}, 'DENY_GROUP': None, 'FIND_GROUP_PERMS': False, 'GROUP_CACHE_TIMEOUT': None, 'GROUP_SEARCH': None, 'GROUP_TYPE': None, 'MIRROR_GROUPS': None, 'MIRROR_GROUPS_EXCEPT': None, 'PERMIT_EMPTY_PASSWORD': False, 'PROFILE_ATTR_MAP': {}, 'PROFILE_FLAGS_BY_GROUP': {}, 'REQUIRE_GROUP': None, 'SERVER_URI': 'ldap://localhost', 'START_TLS': False, 'USER_ATTRLIST': None, 'USER_ATTR_MAP': {}, 'USER_DN_TEMPLATE': None, 'USER_FLAGS_BY_GROUP': {}, 'USER_SEARCH': None, } db_map = { 'SERVER_URI': 'provider_url', 'BIND_DN': 'admin', 'BIND_PASSWORD': '******', 'USER_DN_TEMPLATE': 'user_template', } db_info = None try: db_info = self.config_table_serializer( self.config_table.objects.get(type=self.cfg_type)).data except Exception as ex: print ex if not db_info: return defaults db_defaults = {} for k, v in db_map.items(): if v in db_info.keys(): db_defaults[k] = db_info[v] if not (db_defaults['BIND_DN'] and db_defaults['BIND_PASSWORD']): db_defaults['BIND_DN'] = '' db_defaults['BIND_PASSWORD'] = '' return dict(defaults, **db_defaults) db_defaults['USER_DN_TEMPLATE'] = None rdn = "(cn=%(user)s)" if db_info[ 'filter_attr'] == "cn" else "(uid=%(user)s)" db_defaults['USER_SEARCH'] = LDAPSearch(db_info['search_dn'], ldap.SCOPE_SUBTREE, rdn) db_defaults['USER_ATTR_MAP'] = { "first_name": "givenName", "last_name": "sn", "email": "mail" } # db_defaults['GROUP_SEARCH'] = LDAPSearch(db_info['search_dn'], ldap.SCOPE_SUBTREE, "(objectClass=group)") db_defaults['GROUP_SEARCH'] = LDAPSearch(db_info['search_dn'], ldap.SCOPE_SUBTREE, "(objectClass=*)") db_defaults['GROUP_TYPE'] = GroupOfNamesType() db_defaults['REQUIRE_GROUP'] = db_info['require_group'] if db_info[ 'require_group'] else None db_defaults['USER_FLAGS_BY_GROUP'] = {} if db_info['super_group']: db_defaults['USER_FLAGS_BY_GROUP']['is_superuser'] = db_info[ 'super_group'] return dict(defaults, **db_defaults)
AUTH_LDAP_USER_ATTR_MAP = { "username": "******", 'email': 'mail', "first_name": "givenName", "last_name": "sn", } AUTH_LDAP_USER_SEARCH = LDAPSearch( LADP_BASE_DN, ldap.SCOPE_SUBTREE, '(sAMAccountName=%(user)s)', ) AUTH_LDAP_GROUP_SEARCH = LDAPSearch(LADP_BASE_DN, ldap.SCOPE_SUBTREE, "(objectClass=group)") #搜索某个OU下组信息 AUTH_LDAP_GROUP_TYPE = GroupOfNamesType( name_attr="cn") #返回的组的类型,并用来判断用户与组的从属关系 # AUTH_LDAP_MIRROR_GROUPS = True #导入用户的组信息,在用户登录的时候把用户的域组关系同步过来。每次用户登录时,都会把用户的组关系删除,重新从ldap中进行同步(解决办法参考后面) AUTH_LDAP_ALWAYS_UPDATE_USER = True #是否同步LDAP修改 # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
def _parse_config_item(key, value): """Generate the settings related to a specific configuration item. Arguments: key (str): the configuration name. value (mixed): the configuration value to parse. Returns: dict: with the additional settings to create based on the config. """ if key == 'GROUP_SEARCH': return { 'AUTH_LDAP_GROUP_SEARCH': LDAPSearch(value, ldap.SCOPE_SUBTREE, '(objectClass=groupOfNames)'), 'AUTH_LDAP_GROUP_TYPE': GroupOfNamesType() } if key == 'USER_SEARCH': return { 'AUTH_LDAP_USER_SEARCH': LDAPSearch( value['SEARCH'], ldap.SCOPE_ONELEVEL, '({user_field}=%(user)s)'.format( user_field=value['USER_FIELD'])) } if key == 'GLOBAL_OPTIONS': # Options for ldap.set_option(). Keys are ldap.OPT_* constants. return { 'AUTH_LDAP_GLOBAL_OPTIONS': { getattr(ldap, opt_name): opt_value for opt_name, opt_value in value.items() } } if key == 'USER_FLAGS_BY_GROUP': flag_settings = value.copy() for flag, groups in value.items(): if isinstance(groups, str): continue parsed_groups = _get_ldap_group_query(groups) if parsed_groups is None: del flag_settings[flag] else: flag_settings[flag] = parsed_groups return {'AUTH_LDAP_USER_FLAGS_BY_GROUP': flag_settings} if key == 'REQUIRE_GROUP': if isinstance(value, str): require_settings = value else: require_settings = _get_ldap_group_query(value) if require_settings is not None: return {'AUTH_LDAP_REQUIRE_GROUP': require_settings} else: return {} return {'AUTH_LDAP_' + key: value}
f"({RDRF_AUTH_LDAP_USER_SEARCH_ATTR}=%(user)s)") # Matching LDAP user group to user settings (superuser / active) AUTH_LDAP_USER_FLAGS_BY_GROUP = {} if RDRF_AUTH_LDAP_ALLOW_SUPERUSER: AUTH_LDAP_USER_FLAGS_BY_GROUP['is_superuser'] = RDRF_AUTH_LDAP_IS_SUPERUSER_GROUP if not RDRF_AUTH_LDAP_FORCE_ISACTIVE: AUTH_LDAP_USER_FLAGS_BY_GROUP['is_active'] = RDRF_AUTH_LDAP_IS_ACTIVE_GROUP # LDAP Group Search settings. AUTH_LDAP_GROUP_SEARCH = LDAPSearch(RDRF_AUTH_LDAP_BIND_GROUP, ldap.SCOPE_SUBTREE, f"({RDRF_AUTH_LDAP_GROUP_SEARCH_FIELD}={RDRF_AUTH_LDAP_GROUP_SEARCH_FIELD_VALUE})") if RDRF_AUTH_LDAP_GROUP_SEARCH_TYPE == "posix": AUTH_LDAP_GROUP_TYPE = PosixGroupType(name_attr=RDRF_AUTH_LDAP_GROUP_TYPE_ATTR) elif RDRF_AUTH_LDAP_GROUP_SEARCH_TYPE == "groupofnames": AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr=RDRF_AUTH_LDAP_GROUP_TYPE_ATTR) elif RDRF_AUTH_LDAP_GROUP_SEARCH_TYPE == "activedirectory": AUTH_LDAP_GROUP_TYPE = ActiveDirectoryGroupType(name_attr=RDRF_AUTH_LDAP_GROUP_TYPE_ATTR) AUTH_LDAP_FIND_GROUP_PERMS = env.get("auth_ldap_find_group_perms", DEV_LDAP_GROUP_PERMS) AUTH_LDAP_CACHE_GROUPS = env.get("auth_ldap_cache_groups", DEV_LDAP_CACHE_GROUPS) AUTH_LDAP_GROUP_CACHE_TIMEOUT = env.get("auth_ldap_group_cache_timeout", DEV_LDAP_CACHE_TIMEOUT) # Security: set required LDAP group (user must be in this LDAP group to login in RDRF) AUTH_LDAP_REQUIRE_GROUP = env.get("auth_ldap_require_group", "") # these determine which authentication method to use # apps use modelbackend by default, but can be overridden here # see: https://docs.djangoproject.com/en/dev/ref/settings/#authentication-backends AUTHENTICATION_BACKENDS = [ 'useraudit.password_expiry.AccountExpiryBackend',
def _dict_to_configs(self, new_configs): """ Turn given dictionary into self.configs. Clears all previous settings. :param new_configs: dictionary of new configs; values should be booleans or strings :return: """ self.configs = {} for k, v in new_configs.items(): k = k.upper() if v == "": continue if k == 'AUTH_LDAP_ENABLED': self.enabled = bool(v) # Also treat AUTH_LDAP_USER_FLAGS_BY_GROUP_IS_STAFF or _IS_SUPERUSER differently elif k == 'AUTH_LDAP_USER_FLAGS_BY_GROUP_IS_STAFF': group_flags = self.configs.get('AUTH_LDAP_USER_FLAGS_BY_GROUP', {}) group_flags['is_staff'] = v self.configs['AUTH_LDAP_USER_FLAGS_BY_GROUP'] = group_flags elif k == 'AUTH_LDAP_USER_FLAGS_BY_GROUP_IS_SUPERUSER': group_flags = self.configs.get('AUTH_LDAP_USER_FLAGS_BY_GROUP', {}) group_flags['is_superuser'] = v self.configs['AUTH_LDAP_USER_FLAGS_BY_GROUP'] = group_flags # AUTH_LDAP_GROUP_MAPPING and AUTH_LDAP_USER_ATTR_MAP should be imported as json elif k in LDAPSettings.JSON_FIELDS: try: self.configs[k] = json.loads(v) except json.JSONDecodeError: self.errors[k] = 'This field is not in json form' else: self.configs[k] = v if LDAPSettings.LDAP_IMPORT_SUCCESS: # Import AUTH_LDAP_USER_SEARCH as LDAPSearchUnion if "AUTH_LDAP_USER_SEARCH" in self.configs: temp = self.configs["AUTH_LDAP_USER_SEARCH"] ldap_searches = [] for el in temp: ldap_searches.append( LDAPSearch(el["search"], ldap.SCOPE_SUBTREE, el["filter"])) self.configs["AUTH_LDAP_USER_SEARCH"] = LDAPSearchUnion( *ldap_searches) # Import AUTH_LDAP_GROUP_SEARCH as LDAPSearch temp = new_configs.get('AUTH_LDAP_GROUP_TYPE', '').lower() group_type = None if temp == 'groupofnames': group_type = 'groupOfNames' elif temp == 'posixgroup': group_type = 'posixGroup' group_search_dn = new_configs.get('AUTH_LDAP_GROUP_SEARCH', None) if group_search_dn and group_type: self.configs['AUTH_LDAP_GROUP_SEARCH'] = LDAPSearch( group_search_dn, ldap.SCOPE_SUBTREE, "(objectClass={})".format(group_type)) # import AUTH_LDAP_GROUP_TYPE and AUTH_LDAP_GROUP_TYPE_NAME_ATTR as object name_attr = new_configs.get('AUTH_LDAP_GROUP_TYPE_NAME_ATTR', None) if group_type == 'groupOfNames': self.configs['AUTH_LDAP_GROUP_TYPE'] = GroupOfNamesType() \ if name_attr is None else GroupOfNamesType(name_attr=name_attr) elif group_type == 'posixGroup': self.configs['AUTH_LDAP_GROUP_TYPE'] = PosixGroupType() \ if name_attr is None else PosixGroupType(name_attr=name_attr) else: if 'AUTH_LDAP_GROUP_TYPE' in self.configs: del self.configs['AUTH_LDAP_GROUP_TYPE']