Skip to content

Commit

Permalink
Adds get_users method to provide an interface for
Browse files Browse the repository at this point in the history
listing all available users in the ldap directory
based on the filter defined in LDAP_USERS_OBJECT_FILTER

The get_users method has two arguments fields and dn_only
to customize the result. i.e. get_users(fields=['uid'])
provide a list of dict with uid included. if only
get_users(dn_only=True) is provided, a list of available
users dn is returned. If no users in directory, an empty
list is returned.
  • Loading branch information
jm66 committed May 12, 2020
1 parent 7dcddf2 commit 481a763
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions examples/basic_auth/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
1 change: 1 addition & 0 deletions examples/basic_auth/app_oldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
45 changes: 42 additions & 3 deletions flask_simpleldap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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.
Expand All @@ -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:
Expand Down Expand Up @@ -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']))
Expand Down

0 comments on commit 481a763

Please sign in to comment.