LDAP auth login method enhancements
1/
Allow user to pass a group mapping in manage_groups=True mode.
A group mapping is a structure like:
{
"ldap_grp1": ["web2py_grp1", "web2py_grp2"],
"ldap_grp2": ["ldap_grp2", "web2py_grp3"],
}
After fetching the ldap user's ldap groups, the list entries are
translated, before janitoring the auth_group and auth_membership
tables.
2/
Allow to define a callback to execute if the auth_group or
auth_membership tables are changed.
Typical use-case are cache flushing and app-driven replication.
This commit is contained in:
@@ -36,11 +36,13 @@ def ldap_auth(server='ldap',
|
|||||||
user_lastname_attrib='cn:2',
|
user_lastname_attrib='cn:2',
|
||||||
user_mail_attrib='mail',
|
user_mail_attrib='mail',
|
||||||
manage_groups=False,
|
manage_groups=False,
|
||||||
|
manage_groups_callback=[],
|
||||||
db=None,
|
db=None,
|
||||||
group_dn=None,
|
group_dn=None,
|
||||||
group_name_attrib='cn',
|
group_name_attrib='cn',
|
||||||
group_member_attrib='memberUid',
|
group_member_attrib='memberUid',
|
||||||
group_filterstr='objectClass=*',
|
group_filterstr='objectClass=*',
|
||||||
|
group_mapping={},
|
||||||
tls=False,
|
tls=False,
|
||||||
logging_level='error'):
|
logging_level='error'):
|
||||||
|
|
||||||
@@ -207,6 +209,7 @@ def ldap_auth(server='ldap',
|
|||||||
user_mail_attrib=user_mail_attrib,
|
user_mail_attrib=user_mail_attrib,
|
||||||
manage_groups=manage_groups,
|
manage_groups=manage_groups,
|
||||||
allowed_groups=allowed_groups,
|
allowed_groups=allowed_groups,
|
||||||
|
group_mapping=group_mapping,
|
||||||
db=db):
|
db=db):
|
||||||
if password == '': # http://tools.ietf.org/html/rfc4513#section-5.1.2
|
if password == '': # http://tools.ietf.org/html/rfc4513#section-5.1.2
|
||||||
logger.warning('blank password not allowed')
|
logger.warning('blank password not allowed')
|
||||||
@@ -262,6 +265,7 @@ def ldap_auth(server='ldap',
|
|||||||
requested_attrs = ['sAMAccountName']
|
requested_attrs = ['sAMAccountName']
|
||||||
if manage_user:
|
if manage_user:
|
||||||
requested_attrs.extend([user_firstname_attrib, user_lastname_attrib, user_mail_attrib])
|
requested_attrs.extend([user_firstname_attrib, user_lastname_attrib, user_mail_attrib])
|
||||||
|
|
||||||
result = con.search_ext_s(
|
result = con.search_ext_s(
|
||||||
ldap_basedn, ldap.SCOPE_SUBTREE,
|
ldap_basedn, ldap.SCOPE_SUBTREE,
|
||||||
"(&(sAMAccountName=%s)(%s))" % (ldap.filter.escape_filter_chars(username_bare), filterstr),
|
"(&(sAMAccountName=%s)(%s))" % (ldap.filter.escape_filter_chars(username_bare), filterstr),
|
||||||
@@ -444,7 +448,7 @@ def ldap_auth(server='ldap',
|
|||||||
con.unbind()
|
con.unbind()
|
||||||
|
|
||||||
if manage_groups:
|
if manage_groups:
|
||||||
if not do_manage_groups(username, password):
|
if not do_manage_groups(username, password, group_mapping):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
except ldap.INVALID_CREDENTIALS, e:
|
except ldap.INVALID_CREDENTIALS, e:
|
||||||
@@ -482,7 +486,7 @@ def ldap_auth(server='ldap',
|
|||||||
# No match
|
# No match
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def do_manage_groups(username, password=None, db=db):
|
def do_manage_groups(username, password=None, group_mapping={}, db=db):
|
||||||
"""
|
"""
|
||||||
Manage user groups
|
Manage user groups
|
||||||
|
|
||||||
@@ -498,6 +502,14 @@ def ldap_auth(server='ldap',
|
|||||||
ldap_groups_of_the_user = get_user_groups_from_ldap(
|
ldap_groups_of_the_user = get_user_groups_from_ldap(
|
||||||
username, password)
|
username, password)
|
||||||
|
|
||||||
|
if group_mapping != {}:
|
||||||
|
l = []
|
||||||
|
for group in ldap_groups_of_the_user:
|
||||||
|
if group in group_mapping:
|
||||||
|
l += group_mapping[group]
|
||||||
|
ldap_groups_of_the_user = l
|
||||||
|
logging.info("User groups after remapping: %s" % str(l))
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get all group name where the user is in actually in local db
|
# Get all group name where the user is in actually in local db
|
||||||
# #############################################################
|
# #############################################################
|
||||||
@@ -540,6 +552,7 @@ def ldap_auth(server='ldap',
|
|||||||
db_groups_of_the_user.append(group.role)
|
db_groups_of_the_user.append(group.role)
|
||||||
logging.debug('db groups of user %s: %s' % (username, str(db_groups_of_the_user)))
|
logging.debug('db groups of user %s: %s' % (username, str(db_groups_of_the_user)))
|
||||||
|
|
||||||
|
auth_membership_changed = False
|
||||||
#
|
#
|
||||||
# Delete user membership from groups where user is not anymore
|
# Delete user membership from groups where user is not anymore
|
||||||
# #############################################################
|
# #############################################################
|
||||||
@@ -547,6 +560,7 @@ def ldap_auth(server='ldap',
|
|||||||
if ldap_groups_of_the_user.count(group_to_del) == 0:
|
if ldap_groups_of_the_user.count(group_to_del) == 0:
|
||||||
db((db.auth_membership.user_id == db_user_id) &
|
db((db.auth_membership.user_id == db_user_id) &
|
||||||
(db.auth_membership.group_id == db_group_id[group_to_del])).delete()
|
(db.auth_membership.group_id == db_group_id[group_to_del])).delete()
|
||||||
|
auth_membership_changed = True
|
||||||
|
|
||||||
#
|
#
|
||||||
# Create user membership in groups where user is not in already
|
# Create user membership in groups where user is not in already
|
||||||
@@ -558,6 +572,12 @@ def ldap_auth(server='ldap',
|
|||||||
else:
|
else:
|
||||||
gid = db(db.auth_group.role == group_to_add).select(db.auth_group.id).first().id
|
gid = db(db.auth_group.role == group_to_add).select(db.auth_group.id).first().id
|
||||||
db.auth_membership.insert(user_id=db_user_id, group_id=gid)
|
db.auth_membership.insert(user_id=db_user_id, group_id=gid)
|
||||||
|
auth_membership_changed = True
|
||||||
|
|
||||||
|
if auth_membership_changed:
|
||||||
|
for callback in manage_groups_callback:
|
||||||
|
callback()
|
||||||
|
|
||||||
except:
|
except:
|
||||||
logger.warning("[%s] Groups are not managed successfully!" % str(username))
|
logger.warning("[%s] Groups are not managed successfully!" % str(username))
|
||||||
import traceback
|
import traceback
|
||||||
|
|||||||
Reference in New Issue
Block a user