Simplify group list interface and code

This commit is contained in:
Alexandre Aubin 2019-09-11 02:08:46 +02:00
parent a6d68c76c4
commit 0f7b8c3515
5 changed files with 55 additions and 60 deletions

View file

@ -208,9 +208,14 @@ user:
action_help: List group action_help: List group
api: GET /users/groups api: GET /users/groups
arguments: arguments:
--fields: -n:
help: fields to fetch full: --names-only
nargs: "+" help: Only list the name of the groups without any additional info
action: store_true
-f:
full: --full
help: List all the info available for each groups
action: store_true
### user_group_create() ### user_group_create()
create: create:

View file

@ -1374,7 +1374,7 @@ class RestoreManager():
filtred_entries = ['entryUUID', 'creatorsName', 'createTimestamp', 'entryCSN', 'structuralObjectClass', filtred_entries = ['entryUUID', 'creatorsName', 'createTimestamp', 'entryCSN', 'structuralObjectClass',
'modifiersName', 'modifyTimestamp', 'inheritPermission', 'memberUid'] 'modifiersName', 'modifyTimestamp', 'inheritPermission', 'memberUid']
entries = read_ldif('%s/permission.ldif' % app_settings_in_archive, filtred_entries) entries = read_ldif('%s/permission.ldif' % app_settings_in_archive, filtred_entries)
group_list = user_group_list(['cn'])['groups'] group_list = user_group_list()['groups']
for dn, entry in entries: for dn, entry in entries:
# Remove the group which has been removed # Remove the group which has been removed
for group in entry['groupPermission']: for group in entry['groupPermission']:

View file

@ -169,13 +169,13 @@ def user_permission_update(operation_logger, app=[], permission=None, add_userna
# Validate that the group exist # Validate that the group exist
for g in add_group: for g in add_group:
if g not in user_group_list(['cn'])['groups']: if g not in user_group_list()['groups']:
raise YunohostError('group_unknown', group=g) raise YunohostError('group_unknown', group=g)
for u in add_username: for u in add_username:
if u not in user_list(['uid'])['users']: if u not in user_list(['uid'])['users']:
raise YunohostError('user_unknown', user=u) raise YunohostError('user_unknown', user=u)
for g in del_group: for g in del_group:
if g not in user_group_list(['cn'])['groups']: if g not in user_group_list()['groups']:
raise YunohostError('group_unknown', group=g) raise YunohostError('group_unknown', group=g)
for u in del_username: for u in del_username:
if u not in user_list(['uid'])['users']: if u not in user_list(['uid'])['users']:
@ -244,14 +244,12 @@ def user_permission_update(operation_logger, app=[], permission=None, add_userna
for a in app: for a in app:
allowed_users = set() allowed_users = set()
disallowed_users = set() disallowed_users = set()
group_list = user_group_list(['member'])['groups'] group_list = user_group_list()['groups']
for g in add_group: for g in add_group:
if 'members' in group_list[g]: allowed_users.union(group_list[g]['members'])
allowed_users.union(group_list[g]['members'])
for g in del_group: for g in del_group:
if 'members' in group_list[g]: disallowed_users.union(group_list[g]['members'])
disallowed_users.union(group_list[g]['members'])
allowed_users = ','.join(allowed_users) allowed_users = ','.join(allowed_users)
disallowed_users = ','.join(disallowed_users) disallowed_users = ','.join(disallowed_users)

View file

@ -489,66 +489,44 @@ def user_info(username):
# #
# Group subcategory # Group subcategory
# #
def user_group_list(fields=None): def user_group_list(names_only=False, full=False):
""" """
List users List users
Keyword argument: Keyword argument:
filter -- LDAP filter used to search names-only -- Only list the name of the groups without any additional info
offset -- Starting number for user fetching full -- List all the info available for each groups
limit -- Maximum number of user fetched
fields -- fields to fetch
""" """
from yunohost.utils.ldap import _get_ldap_interface
# Fetch relevant informations
from yunohost.utils.ldap import _get_ldap_interface, _ldap_path_extract
ldap = _get_ldap_interface() ldap = _get_ldap_interface()
group_attr = {
'cn': 'groupname',
'member': 'members',
'permission': 'permission'
}
attrs = ['cn']
groups = {}
if fields: if names_only:
keys = group_attr.keys() fields_to_fetch = ["cn"]
for attr in fields: elif full:
if attr in keys: fields_to_fetch = ["cn", "member", "permission"]
attrs.append(attr)
else:
raise YunohostError('field_invalid', attr)
else: else:
attrs = ['cn', 'member'] fields_to_fetch = ["cn", "member"]
result = ldap.search('ou=groups,dc=yunohost,dc=org', groups_infos = ldap.search('ou=groups,dc=yunohost,dc=org',
'(objectclass=groupOfNamesYnh)', '(objectclass=groupOfNamesYnh)',
attrs) fields_to_fetch)
for group in result: # Parse / organize information to be outputed
# The group "admins" should be hidden for the user
if group_attr['cn'] == "admins":
continue
entry = {}
for attr, values in group.items():
if values:
if attr == "member":
entry[group_attr[attr]] = []
for v in values:
entry[group_attr[attr]].append(v.split("=")[1].split(",")[0])
elif attr == "permission":
entry[group_attr[attr]] = {}
for v in values:
permission = v.split("=")[1].split(",")[0].split(".")[1]
pType = v.split("=")[1].split(",")[0].split(".")[0]
if permission in entry[group_attr[attr]]:
entry[group_attr[attr]][permission].append(pType)
else:
entry[group_attr[attr]][permission] = [pType]
else:
entry[group_attr[attr]] = values[0]
groupname = entry[group_attr['cn']] groups = {}
groups[groupname] = entry for infos in groups_infos:
name = infos["cn"][0]
groups[name] = {}
if "member" in fields_to_fetch:
groups[name]["members"] = [_ldap_path_extract(p, "uid") for p in infos.get("member", [])]
if "permission" in fields_to_fetch:
groups[name]["permissions"] = [_ldap_path_extract(p, "cn") for p in infos.get("permission", [])]
if names_only:
groups = groups.keys()
return {'groups': groups} return {'groups': groups}

View file

@ -40,6 +40,20 @@ def _get_ldap_interface():
return _ldap_interface return _ldap_interface
# We regularly want to extract stuff like 'bar' in ldap path like
# foo=bar,dn=users.example.org,ou=example.org,dc=org so this small helper allow
# to do this without relying of dozens of mysterious string.split()[0]
#
# e.g. using _ldap_path_extract(path, "foo") on the previous example will
# return bar
def _ldap_path_extract(path, info):
for element in path.split(","):
if element.startswith(info + "="):
return element[len(info + "="):]
# Add this to properly close / delete the ldap interface / authenticator # Add this to properly close / delete the ldap interface / authenticator
# when Python exits ... # when Python exits ...
# Otherwise there's a risk that some funky error appears at the very end # Otherwise there's a risk that some funky error appears at the very end