diff --git a/docs/index.rst b/docs/index.rst index ab72749..79815eb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -78,6 +78,8 @@ directives: object details. Default: ``list`` (all). ``LDAP_USER_OBJECT_FILTER`` The filter to use when searching for a user object. Default: '(&(objectclass=Person)(userPrincipalName=%s))' +``LDAP_USERS_OBJECT_FILTER`` The filter to use when searching for users objects. + Default: 'objectclass=Person' ``LDAP_USER_GROUPS_FIELD`` The field to return when searching for a user's groups. Default: 'memberOf'. ``LDAP_GROUP_FIELDS`` ``list`` of fields to return when searching for a group's diff --git a/examples/basic_auth/app.py b/examples/basic_auth/app.py index e9e745f..9f8536e 100644 --- a/examples/basic_auth/app.py +++ b/examples/basic_auth/app.py @@ -6,6 +6,9 @@ app.config['LDAP_BASE_DN'] = 'OU=users,dc=example,dc=org' app.config['LDAP_USERNAME'] = 'CN=user,OU=Users,DC=example,DC=org' app.config['LDAP_PASSWORD'] = 'password' +app.config['LDAP_USER_OBJECT_FILTER'] = '(&(objectclass=inetOrgPerson)(uid=%s))' +app.config['LDAP_USERS_OBJECT_FILTER'] = 'objectclass=inetOrgPerson' +app.config['LDAP_USER_FIELDS'] = ['cn', 'uid'] ldap = LDAP(app) diff --git a/examples/basic_auth/app_oldap.py b/examples/basic_auth/app_oldap.py index 4155130..02adb3f 100644 --- a/examples/basic_auth/app_oldap.py +++ b/examples/basic_auth/app_oldap.py @@ -14,6 +14,7 @@ app.config['LDAP_OPENLDAP'] = True app.config['LDAP_OBJECTS_DN'] = 'dn' app.config['LDAP_USER_OBJECT_FILTER'] = '(&(objectclass=inetOrgPerson)(uid=%s))' +app.config['LDAP_USERS_OBJECT_FILTER'] = 'objectclass=inetOrgPerson' # Groups app.config['LDAP_GROUP_MEMBERS_FIELD'] = "uniquemember" diff --git a/flask_simpleldap/__init__.py b/flask_simpleldap/__init__.py index 73ab24c..525ebf1 100644 --- a/flask_simpleldap/__init__.py +++ b/flask_simpleldap/__init__.py @@ -45,6 +45,8 @@ def init_app(app): app.config.setdefault('LDAP_BASE_DN', None) app.config.setdefault('LDAP_OBJECTS_DN', 'distinguishedName') app.config.setdefault('LDAP_USER_FIELDS', []) + app.config.setdefault('LDAP_USERS_OBJECT_FILTER', + 'objectclass=Person') app.config.setdefault('LDAP_USER_OBJECT_FILTER', '(&(objectclass=Person)(userPrincipalName=%s))') app.config.setdefault('LDAP_USER_GROUPS_FIELD', 'memberOf') @@ -154,6 +156,43 @@ def bind_user(self, username, password): except ldap.LDAPError: return + def get_users(self, fields=None, dn_only=False): + """Returns a ``list`` with the users in base dn + or empty ``list`` if unsuccessful. + + LDAP query setting is ``LDAP_USERS_OBJECT_FILTER`` + + :param fields: list of user fields to retrieve. + if ``None`` or empty, default user fields + ``LDAP_USER_FIELDS`` is used + :param bool dn_only: If we should only retrieve the object's + distinguished name or not. Default: ``False``. + :type fields: list + """ + conn = self.bind + try: + fields = fields or current_app.config['LDAP_USER_FIELDS'] + if current_app.config['LDAP_OPENLDAP']: + records = conn.search_s( + current_app.config['LDAP_BASE_DN'], ldap.SCOPE_SUBTREE, + current_app.config['LDAP_USERS_OBJECT_FILTER'], + fields) + else: + records = conn.search_s( + current_app.config['LDAP_BASE_DN'], ldap.SCOPE_SUBTREE, + current_app.config['LDAP_USERS_OBJECT_FILTER'], + fields) + conn.unbind_s() + if records: + if dn_only: + return [r[0] for r in records] + else: + return [r[1] for r in records] + else: + return [] + except ldap.LDAPError as e: + raise LDAPException(self.error(e.args)) + def get_object_details(self, user=None, group=None, query_filter=None, dn_only=False): """Returns a ``dict`` with the object's (user or group) details. @@ -170,13 +209,13 @@ def get_object_details(self, user=None, group=None, query_filter=None, if not dn_only: fields = current_app.config['LDAP_USER_FIELDS'] query_filter = query_filter or \ - current_app.config['LDAP_USER_OBJECT_FILTER'] + current_app.config['LDAP_USER_OBJECT_FILTER'] query = ldap_filter.filter_format(query_filter, (user,)) elif group is not None: if not dn_only: fields = current_app.config['LDAP_GROUP_FIELDS'] query_filter = query_filter or \ - current_app.config['LDAP_GROUP_OBJECT_FILTER'] + current_app.config['LDAP_GROUP_OBJECT_FILTER'] query = ldap_filter.filter_format(query_filter, (group,)) conn = self.bind try: @@ -296,7 +335,7 @@ def login_required(func): @wraps(func) def wrapped(*args, **kwargs): if g.user is None: - next_path=request.full_path or request.path + next_path = request.full_path or request.path if next_path == '/?': return redirect( url_for(current_app.config['LDAP_LOGIN_VIEW']))