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
api: GET /users/groups
arguments:
--fields:
help: fields to fetch
nargs: "+"
-n:
full: --names-only
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()
create:

View file

@ -1374,7 +1374,7 @@ class RestoreManager():
filtred_entries = ['entryUUID', 'creatorsName', 'createTimestamp', 'entryCSN', 'structuralObjectClass',
'modifiersName', 'modifyTimestamp', 'inheritPermission', 'memberUid']
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:
# Remove the group which has been removed
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
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)
for u in add_username:
if u not in user_list(['uid'])['users']:
raise YunohostError('user_unknown', user=u)
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)
for u in del_username:
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:
allowed_users = set()
disallowed_users = set()
group_list = user_group_list(['member'])['groups']
group_list = user_group_list()['groups']
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:
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)
disallowed_users = ','.join(disallowed_users)

View file

@ -489,66 +489,44 @@ def user_info(username):
#
# Group subcategory
#
def user_group_list(fields=None):
def user_group_list(names_only=False, full=False):
"""
List users
Keyword argument:
filter -- LDAP filter used to search
offset -- Starting number for user fetching
limit -- Maximum number of user fetched
fields -- fields to fetch
names-only -- Only list the name of the groups without any additional info
full -- List all the info available for each groups
"""
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()
group_attr = {
'cn': 'groupname',
'member': 'members',
'permission': 'permission'
}
attrs = ['cn']
groups = {}
if fields:
keys = group_attr.keys()
for attr in fields:
if attr in keys:
attrs.append(attr)
else:
raise YunohostError('field_invalid', attr)
if names_only:
fields_to_fetch = ["cn"]
elif full:
fields_to_fetch = ["cn", "member", "permission"]
else:
attrs = ['cn', 'member']
fields_to_fetch = ["cn", "member"]
result = ldap.search('ou=groups,dc=yunohost,dc=org',
'(objectclass=groupOfNamesYnh)',
attrs)
groups_infos = ldap.search('ou=groups,dc=yunohost,dc=org',
'(objectclass=groupOfNamesYnh)',
fields_to_fetch)
for group in result:
# 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]
# Parse / organize information to be outputed
groupname = entry[group_attr['cn']]
groups[groupname] = entry
groups = {}
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}

View file

@ -40,6 +40,20 @@ def _get_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
# when Python exits ...
# Otherwise there's a risk that some funky error appears at the very end