[auth_ldap] delete unused roles in ldap

This commit is contained in:
Tim Gröger 2020-11-14 13:16:30 +01:00
parent f9a873d303
commit 89257a7d37
1 changed files with 64 additions and 27 deletions

View File

@ -35,7 +35,7 @@ class AuthLDAP(AuthPlugin):
app.config["LDAP_SECRET"] = (config["secret"],) app.config["LDAP_SECRET"] = (config["secret"],)
self.ldap = LDAPConn(app) self.ldap = LDAPConn(app)
self.dn = config["base_dn"] self.dn = config["base_dn"]
self.default_gid = config['default_gid'] self.default_gid = config["default_gid"]
# TODO: might not be set if modify is called # TODO: might not be set if modify is called
if "admin_dn" in config: if "admin_dn" in config:
self.admin_dn = config["admin_dn"] self.admin_dn = config["admin_dn"]
@ -74,22 +74,33 @@ class AuthLDAP(AuthPlugin):
try: try:
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret) ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret)
self.ldap.connection.search( self.ldap.connection.search(
"ou=user,{}".format(self.dn), "(uidNumber=*)", SUBTREE, attributes=["uidNumber"] "ou=user,{}".format(self.dn),
"(uidNumber=*)",
SUBTREE,
attributes=["uidNumber"],
) )
uidNumbers = sorted(self.ldap.response(), key = lambda i: i['attributes']['uidNumber'], reverse=True) uidNumbers = sorted(
uidNumber = uidNumbers[0]['attributes']['uidNumber'] + 1 self.ldap.response(),
dn = f'cn={user.firstname} {user.lastname},ou=user,{self.dn}' key=lambda i: i["attributes"]["uidNumber"],
object_class = ['inetOrgPerson', 'posixAccount', 'person', 'organizationalPerson'] reverse=True,
)
uidNumber = uidNumbers[0]["attributes"]["uidNumber"] + 1
dn = f"cn={user.firstname} {user.lastname},ou=user,{self.dn}"
object_class = [
"inetOrgPerson",
"posixAccount",
"person",
"organizationalPerson",
]
attributes = { attributes = {
'sn': user.firstname, "sn": user.firstname,
'givenName': user.lastname, "givenName": user.lastname,
'gidNumber': self.default_gid, "gidNumber": self.default_gid,
'homeDirectory': f'/home/{user.userid}', "homeDirectory": f"/home/{user.userid}",
'loginShell': '/bin/bash', "loginShell": "/bin/bash",
'uid': user.userid, "uid": user.userid,
'userPassword': hashed(HASHED_SALTED_MD5, password), "userPassword": hashed(HASHED_SALTED_MD5, password),
'uidNumber': uidNumber "uidNumber": uidNumber,
} }
ldap_conn.add(dn, object_class, attributes) ldap_conn.add(dn, object_class, attributes)
self._set_roles(user) self._set_roles(user)
@ -99,37 +110,63 @@ class AuthLDAP(AuthPlugin):
def _get_groups(self, uid): def _get_groups(self, uid):
groups = [] groups = []
self.ldap.connection.search( self.ldap.connection.search(
"ou=group,{}".format(self.dn), "(memberUID={})".format(uid), SUBTREE, attributes=["cn"] "ou=group,{}".format(self.dn),
"(memberUID={})".format(uid),
SUBTREE,
attributes=["cn"],
) )
groups_data = self.ldap.connection.response groups_data = self.ldap.connection.response
for data in groups_data: for data in groups_data:
groups.append(data["attributes"]["cn"][0]) groups.append(data["attributes"]["cn"][0])
return groups return groups
def _get_all_roles(self, ldap_conn):
self.ldap.connection.search(
f"ou=group,{self.dn}",
"(cn=*)",
SUBTREE,
attributes=["cn", "gidNumber", "memberUid"],
)
return self.ldap.response()
def _delete_unsed_roles(self):
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret)
ldap_roles = self._get_all_roles(ldap_conn)
for role in ldap_roles:
if len(role["attributes"]["memberUid"]) == 0:
ldap_conn.delete(role["dn"])
def _set_roles(self, user: User): def _set_roles(self, user: User):
try: try:
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret) ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret)
self.ldap.connection.search(f"ou=group,{self.dn}", "(cn=*)", SUBTREE, attributes=["cn", "gidNumber"])
ldap_roles = self.ldap.response()
gid_numbers = sorted(ldap_roles, key=lambda i: i['attributes']['gidNumber'], reverse=True) ldap_roles = self._get_all_roles(ldap_conn)
gid_number = gid_numbers[0]['attributes']['gidNumber'] + 1
gid_numbers = sorted(
ldap_roles, key=lambda i: i["attributes"]["gidNumber"], reverse=True
)
gid_number = gid_numbers[0]["attributes"]["gidNumber"] + 1
for user_role in user.roles: for user_role in user.roles:
if user_role not in [role["attributes"]["cn"][0] for role in ldap_roles]: if user_role not in [
ldap_conn.add(f"cn={user_role},ou=group,{self.dn}", ["posixGroup"], attributes={"gidNumber": gid_number}) role["attributes"]["cn"][0] for role in ldap_roles
]:
ldap_conn.add(
f"cn={user_role},ou=group,{self.dn}",
["posixGroup"],
attributes={"gidNumber": gid_number},
)
ldap_conn = self.ldap.connect(self.admin_dn, self.admin_secret) ldap_roles = self._get_all_roles(ldap_conn)
self.ldap.connection.search(f"ou=group,{self.dn}", "(cn=*)", SUBTREE, attributes=["cn", "gidNumber"])
ldap_roles = self.ldap.response()
for ldap_role in ldap_roles: for ldap_role in ldap_roles:
if ldap_role["attributes"]["cn"][0] in user.roles: if ldap_role["attributes"]["cn"][0] in user.roles:
modify = {'memberUid': [(MODIFY_ADD, [user.userid])]} modify = {"memberUid": [(MODIFY_ADD, [user.userid])]}
else: else:
modify = {'memberUid': [(MODIFY_DELETE, [user.userid])]} modify = {"memberUid": [(MODIFY_DELETE, [user.userid])]}
ldap_conn.modify(ldap_role["dn"], modify) ldap_conn.modify(ldap_role["dn"], modify)
self._delete_unsed_roles()
except (LDAPPasswordIsMandatoryError, LDAPBindError): except (LDAPPasswordIsMandatoryError, LDAPBindError):
raise BadRequest raise BadRequest