Allow to specify right away what groups to allow for a permission when creating it

This commit is contained in:
Alexandre Aubin 2019-10-09 22:55:06 +02:00
parent c315df9269
commit e7d1cc5f94
6 changed files with 44 additions and 18 deletions

View file

@ -232,11 +232,12 @@ ynh_webpath_register () {
# Create a new permission for the app # Create a new permission for the app
# #
# example: ynh_permission_create --permission admin --url /admin # example: ynh_permission_create --permission admin --url /admin --allowed alice bob
# #
# usage: ynh_permission_create --permission "permission" [--url "url"] # usage: ynh_permission_create --permission "permission" [--url "url"] [--allowed group1 group2]
# | arg: permission - the name for the permission (by default a permission named "main" already exist) # | arg: permission - the name for the permission (by default a permission named "main" already exist)
# | arg: url - (optional) URL for which access will be allowed/forbidden # | arg: url - (optional) URL for which access will be allowed/forbidden
# | arg: allowed - (optional) A list of group/user to allow for the permission
# #
# If provided, 'url' is assumed to be relative to the app domain/path if they # If provided, 'url' is assumed to be relative to the app domain/path if they
# start with '/'. For example: # start with '/'. For example:
@ -250,9 +251,10 @@ ynh_webpath_register () {
# re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ # re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
# #
ynh_permission_create() { ynh_permission_create() {
declare -Ar args_array=( [p]=permission= [u]=url= ) declare -Ar args_array=( [p]=permission= [u]=url= [a]=allowed= )
local permission local permission
local urls local url
local allowed
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
if [[ -n ${url:-} ]]; then if [[ -n ${url:-} ]]; then
@ -261,7 +263,11 @@ ynh_permission_create() {
url="None" url="None"
fi fi
yunohost tools shell -c "from yunohost.permission import permission_create; permission_create('$app.$permission', url=$url, sync_perm=False)" if [[ -n ${allowed:-} ]]; then
allowed=",allowed=['${allowed//';'/"','"}']"
fi
yunohost tools shell -c "from yunohost.permission import permission_create; permission_create('$app.$permission', url=$url ${allowed:-} , sync_perm=False)"
} }
# Remove a permission for the app (note that when the app is removed all permission is automatically removed) # Remove a permission for the app (note that when the app is removed all permission is automatically removed)

View file

@ -981,7 +981,7 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
# Initialize the main permission for the app # Initialize the main permission for the app
# After the install, if apps don't have a domain and path defined, the default url '/' is removed from the permission # After the install, if apps don't have a domain and path defined, the default url '/' is removed from the permission
permission_create(app_instance_name+".main", url="/") permission_create(app_instance_name+".main", url="/", allowed=["all_users"])
# Execute the app install script # Execute the app install script
install_retcode = 1 install_retcode = 1

View file

@ -1251,8 +1251,7 @@ class RestoreManager():
for permission_name, permission_infos in old_apps_permission.items(): for permission_name, permission_infos in old_apps_permission.items():
app_name = permission_name.split(".")[0] app_name = permission_name.split(".")[0]
if _is_installed(app_name): if _is_installed(app_name):
permission_create(permission_name, url=permission_infos["url"], sync_perm=False) permission_create(permission_name, url=permission_infos["url"], allowed=permission_infos["allowed"], sync_perm=False)
user_permission_update(permission_name, remove="all_users", add=permission_infos["allowed"], sync_perm=False)
permission_sync_to_user() permission_sync_to_user()
@ -1365,15 +1364,13 @@ class RestoreManager():
for permission_name, permission_infos in permissions.items(): for permission_name, permission_infos in permissions.items():
permission_create(permission_name, url=permission_infos.get("url", None), sync_perm=False)
if "allowed" not in permission_infos: if "allowed" not in permission_infos:
logger.warning("'allowed' key corresponding to allowed groups for permission %s not found when restoring app %s … You might have to reconfigure permissions yourself." % (permission_name, app_instance_name)) logger.warning("'allowed' key corresponding to allowed groups for permission %s not found when restoring app %s … You might have to reconfigure permissions yourself." % (permission_name, app_instance_name))
should_be_allowed = ["all_users"]
else: else:
should_be_allowed = [g for g in permission_infos["allowed"] if g in existing_groups] should_be_allowed = [g for g in permission_infos["allowed"] if g in existing_groups]
current_allowed = user_permission_list()["permissions"][permission_name]["allowed"]
if should_be_allowed != current_allowed: permission_create(permission_name, url=permission_infos.get("url", None), allowed=should_be_allowed, sync_perm=False)
user_permission_update(permission_name, remove=current_allowed, add=should_be_allowed, sync_perm=False)
permission_sync_to_user() permission_sync_to_user()

View file

@ -108,10 +108,12 @@ class MyMigration(Migration):
domain = app_setting(app, 'domain') domain = app_setting(app, 'domain')
url = "/" if domain and path else None url = "/" if domain and path else None
permission_create(app+".main", url=url, sync_perm=False)
if permission: if permission:
allowed_group = permission.split(',') allowed_groups = permission.split(',')
user_permission_update(app+".main", remove="all_users", add=allowed_group, sync_perm=False) else:
allowed_groups = ["all_users"]
permission_create(app+".main", url=url, allowed=allowed_groups, sync_perm=False)
app_setting(app, 'allowed_users', delete=True) app_setting(app, 'allowed_users', delete=True)
# Migrate classic public app still using the legacy unprotected_uris # Migrate classic public app still using the legacy unprotected_uris

View file

@ -266,13 +266,14 @@ def user_permission_reset(operation_logger, permission, sync_perm=True):
@is_unit_operation() @is_unit_operation()
def permission_create(operation_logger, permission, url=None, sync_perm=True): def permission_create(operation_logger, permission, url=None, allowed=None, sync_perm=True):
""" """
Create a new permission for a specific application Create a new permission for a specific application
Keyword argument: Keyword argument:
permission -- Name of the permission (e.g. mail or nextcloud or wordpress.editors) permission -- Name of the permission (e.g. mail or nextcloud or wordpress.editors)
url -- (optional) URL for which access will be allowed/forbidden url -- (optional) URL for which access will be allowed/forbidden
allowed -- (optional) A list of group/user to allow for the permission
If provided, 'url' is assumed to be relative to the app domain/path if they If provided, 'url' is assumed to be relative to the app domain/path if they
start with '/'. For example: start with '/'. For example:
@ -286,6 +287,7 @@ def permission_create(operation_logger, permission, url=None, sync_perm=True):
re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
""" """
from yunohost.user import user_group_list
from yunohost.utils.ldap import _get_ldap_interface from yunohost.utils.ldap import _get_ldap_interface
ldap = _get_ldap_interface() ldap = _get_ldap_interface()
@ -312,8 +314,18 @@ def permission_create(operation_logger, permission, url=None, sync_perm=True):
'gidNumber': gid, 'gidNumber': gid,
} }
# If who should be allowed is explicitly provided, use this info
if allowed:
if not isinstance(allowed, list):
allowed = [allowed]
# (though first we validate that the targets actually exist)
all_existing_groups = user_group_list()['groups'].keys()
for g in allowed:
if g not in all_existing_groups:
raise YunohostError('group_unknown', group=g)
attr_dict['groupPermission'] = ['cn=%s,ou=groups,dc=yunohost,dc=org' % g for g in allowed]
# For main permission, we add all users by default # For main permission, we add all users by default
if permission.endswith(".main"): elif permission.endswith(".main"):
attr_dict['groupPermission'] = ['cn=all_users,ou=groups,dc=yunohost,dc=org'] attr_dict['groupPermission'] = ['cn=all_users,ou=groups,dc=yunohost,dc=org']
if url: if url:

View file

@ -226,6 +226,15 @@ def test_permission_create_extra():
assert "all_users" not in res['site.test']['allowed'] assert "all_users" not in res['site.test']['allowed']
assert res['site.test']['corresponding_users'] == [] assert res['site.test']['corresponding_users'] == []
def test_permission_create_with_allowed():
permission_create("site.test", allowed=["alice"])
res = user_permission_list(full=True)['permissions']
assert "site.test" in res
assert res['site.test']['allowed'] == ["alice"]
def test_permission_delete(): def test_permission_delete():
permission_delete("wiki.main", force=True) permission_delete("wiki.main", force=True)