Sync permission only at end of each operation

This commit is contained in:
Josué Tille 2018-12-07 15:26:04 +01:00
parent c52ae32631
commit 9ac60be564
No known key found for this signature in database
GPG key ID: D5E068C6DFA8681D
5 changed files with 62 additions and 58 deletions

View file

@ -61,7 +61,7 @@ ynh_permission_remove() {
local permission local permission
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
yunohost tools shell -c "from yunohost.permission import permission_remove; permission_remove(auth, '$app', '$permission')" yunohost tools shell -c "from yunohost.permission import permission_remove; permission_remove(auth, '$app', '$permission', sync_perm=False)"
} }
# Add a path managed by the SSO # Add a path managed by the SSO
@ -77,7 +77,7 @@ ynh_permission_add_path() {
local url local url
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
yunohost tools shell -c "from yunohost.permission import permission_update; permission_update(auth, '$app', '$permission', add_url=['${url//';'/"','"}'])" yunohost tools shell -c "from yunohost.permission import permission_update; permission_update(auth, '$app', '$permission', add_url=['${url//';'/"','"}'], sync_perm=False)"
} }
# Remove a path managed by the SSO # Remove a path managed by the SSO
@ -93,5 +93,5 @@ ynh_permission_del_path() {
local url local url
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
yunohost tools shell -c "from yunohost.permission import permission_update; permission_update(auth, '$app', '$permission', remove_url=['${url//';'/"','"}'])" yunohost tools shell -c "from yunohost.permission import permission_update; permission_update(auth, '$app', '$permission', remove_url=['${url//';'/"','"}'], sync_perm=False)"
} }

View file

@ -403,6 +403,7 @@
"permission_not_found": "Permission '{permission:s}' not found for application {app:s}", "permission_not_found": "Permission '{permission:s}' not found for application {app:s}",
"permission_name_not_valid": "Permission name '{permission:s}' not valid", "permission_name_not_valid": "Permission name '{permission:s}' not valid",
"permission_update_failed": "Permission update failed", "permission_update_failed": "Permission update failed",
"permission_generated": "Permission updated",
"permission_updated": "Permission '{permission:s}' for app {app:s} updated", "permission_updated": "Permission '{permission:s}' for app {app:s} updated",
"permission_update_nothing_to_do": "Permission update nothing to do", "permission_update_nothing_to_do": "Permission update nothing to do",
"port_already_closed": "Port {port:d} is already closed for {ip_version:s} connections", "port_already_closed": "Port {port:d} is already closed for {ip_version:s} connections",

View file

@ -536,9 +536,7 @@ def app_change_url(operation_logger, auth, app, domain, path):
app_setting(app, 'domain', value=domain) app_setting(app, 'domain', value=domain)
app_setting(app, 'path', value=path) app_setting(app, 'path', value=path)
permission_update(auth, app, permission="main", add_url=[domain+path], remove_url=[old_domain+old_path]) permission_update(auth, app, permission="main", add_url=[domain+path], remove_url=[old_domain+old_path], sync_perm=True)
app_ssowatconf(auth)
# avoid common mistakes # avoid common mistakes
if _run_service_command("reload", "nginx") == False: if _run_service_command("reload", "nginx") == False:
@ -568,6 +566,7 @@ def app_upgrade(auth, app=[], url=None, file=None):
""" """
from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback
from yunohost.permission import permission_sync_to_user
# Retrieve interface # Retrieve interface
is_api = msettings.get('interface') == 'api' is_api = msettings.get('interface') == 'api'
@ -687,7 +686,7 @@ def app_upgrade(auth, app=[], url=None, file=None):
if not upgraded_apps: if not upgraded_apps:
raise YunohostError('app_no_upgrade') raise YunohostError('app_no_upgrade')
app_ssowatconf(auth) permission_sync_to_user(auth)
logger.success(m18n.n('upgrade_complete')) logger.success(m18n.n('upgrade_complete'))
@ -710,7 +709,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
""" """
from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback
from yunohost.log import OperationLogger from yunohost.log import OperationLogger
from yunohost.permission import permission_add, permission_update, permission_remove from yunohost.permission import permission_add, permission_update, permission_remove, permission_sync_to_user
# Fetch or extract sources # Fetch or extract sources
try: try:
@ -915,9 +914,9 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
domain = app_settings['domain'] domain = app_settings['domain']
path = app_settings.get('path', '/') path = app_settings.get('path', '/')
if domain and path: if domain and path:
permission_update(auth, app_instance_name, permission="main", add_url=[domain+path]) permission_update(auth, app_instance_name, permission="main", add_url=[domain+path], sync_perm=False)
app_ssowatconf(auth) permission_sync_to_user(auth)
logger.success(m18n.n('installation_complete')) logger.success(m18n.n('installation_complete'))
@ -934,7 +933,7 @@ def app_remove(operation_logger, auth, app):
""" """
from yunohost.hook import hook_exec, hook_remove, hook_callback from yunohost.hook import hook_exec, hook_remove, hook_callback
from yunohost.permission import permission_remove from yunohost.permission import permission_remove, permission_sync_to_user
if not _is_installed(app): if not _is_installed(app):
raise YunohostError('app_not_installed', app=app) raise YunohostError('app_not_installed', app=app)
@ -982,9 +981,9 @@ def app_remove(operation_logger, auth, app):
filter='(&(objectclass=permissionYnh)(cn=*.%s))' % app, attrs=['cn']) filter='(&(objectclass=permissionYnh)(cn=*.%s))' % app, attrs=['cn'])
permission_list = [p['cn'][0] for p in result] permission_list = [p['cn'][0] for p in result]
for l in permission_list: for l in permission_list:
permission_remove(auth, app, l.split('.')[0], force=True) permission_remove(auth, app, l.split('.')[0], force=True, sync_perm=False)
app_ssowatconf(auth) permission_sync_to_user(auth)
@is_unit_operation(['permission','app']) @is_unit_operation(['permission','app'])
def app_addaccess(operation_logger, auth, apps, users=[]): def app_addaccess(operation_logger, auth, apps, users=[]):
@ -1037,6 +1036,9 @@ def app_clearaccess(operation_logger, auth, apps):
user_permission_clear(operation_logger, auth, app=apps, permission="main") user_permission_clear(operation_logger, auth, app=apps, permission="main")
result = {p : v['main']['allowed_users'] for p, v in permission['permissions'].items()}
return {'allowed_users': result}
def app_debug(app): def app_debug(app):
""" """

View file

@ -32,7 +32,6 @@ from moulinette import m18n
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette.utils.log import getActionLogger from moulinette.utils.log import getActionLogger
from yunohost.user import user_list, user_group_list from yunohost.user import user_list, user_group_list
from yunohost.app import app_ssowatconf
from yunohost.log import is_unit_operation from yunohost.log import is_unit_operation
logger = getActionLogger('yunohost.user') logger = getActionLogger('yunohost.user')
@ -232,7 +231,7 @@ def user_permission_update(operation_logger, auth, app=[], permission=None, add_
else: else:
raise MoulinetteError(169, m18n.n('permission_update_failed')) raise MoulinetteError(169, m18n.n('permission_update_failed'))
_permission_sync_to_user(auth) permission_sync_to_user(auth)
for a in app: for a in app:
allowed_users = set() allowed_users = set()
@ -253,11 +252,10 @@ def user_permission_update(operation_logger, auth, app=[], permission=None, add_
if del_group: if del_group:
hook_callback('post_app_removeaccess', args=[app, disallowed_users]) hook_callback('post_app_removeaccess', args=[app, disallowed_users])
app_ssowatconf(auth)
return user_permission_list(auth, app, permission) return user_permission_list(auth, app, permission)
def user_permission_clear(operation_logger, auth, app=[], permission=None): def user_permission_clear(operation_logger, auth, app=[], permission=None, sync_perm=True):
""" """
Reset the permission for a specific application Reset the permission for a specific application
@ -300,7 +298,7 @@ def user_permission_clear(operation_logger, auth, app=[], permission=None):
else: else:
raise MoulinetteError(169, m18n.n('permission_update_failed')) raise MoulinetteError(169, m18n.n('permission_update_failed'))
_permission_sync_to_user(auth) permission_sync_to_user(auth)
for a in app: for a in app:
permission_name = 'main.' + a permission_name = 'main.' + a
@ -311,12 +309,11 @@ def user_permission_clear(operation_logger, auth, app=[], permission=None):
new_user_list = ','.join(allowed_users) new_user_list = ','.join(allowed_users)
hook_callback('post_app_removeaccess', args=[app, new_user_list]) hook_callback('post_app_removeaccess', args=[app, new_user_list])
app_ssowatconf(auth)
return user_permission_list(auth, app, permission) return user_permission_list(auth, app, permission)
@is_unit_operation(['permission','app']) @is_unit_operation(['permission','app'])
def permission_add(operation_logger, auth, app, permission, url=None, default_allow=True): def permission_add(operation_logger, auth, app, permission, url=None, default_allow=True, sync_perm=True):
""" """
Create a new permission for a specific application Create a new permission for a specific application
@ -362,7 +359,8 @@ def permission_add(operation_logger, auth, app, permission, url=None, default_al
operation_logger.start() operation_logger.start()
if auth.add('cn=%s,ou=permission' % permission_name, attr_dict): if auth.add('cn=%s,ou=permission' % permission_name, attr_dict):
_permission_sync_to_user(auth) if sync_perm:
permission_sync_to_user(auth)
logger.success(m18n.n('permission_created', permission=permission, app=app)) logger.success(m18n.n('permission_created', permission=permission, app=app))
return user_permission_list(auth, app, permission) return user_permission_list(auth, app, permission)
@ -370,7 +368,7 @@ def permission_add(operation_logger, auth, app, permission, url=None, default_al
@is_unit_operation(['permission','app']) @is_unit_operation(['permission','app'])
def permission_update(operation_logger, auth, app, permission, add_url=None, remove_url=None): def permission_update(operation_logger, auth, app, permission, add_url=None, remove_url=None, sync_perm=True):
""" """
Update a permission for a specific application Update a permission for a specific application
@ -416,7 +414,8 @@ def permission_update(operation_logger, auth, app, permission, add_url=None, rem
operation_logger.start() operation_logger.start()
if auth.update('cn=%s,ou=permission' % permission_name, {'cn':permission_name, 'URL': url}): if auth.update('cn=%s,ou=permission' % permission_name, {'cn':permission_name, 'URL': url}):
_permission_sync_to_user(auth) if sync_perm:
permission_sync_to_user(auth)
logger.success(m18n.n('permission_updated', permission=permission, app=app)) logger.success(m18n.n('permission_updated', permission=permission, app=app))
return user_permission_list(auth, app, permission) return user_permission_list(auth, app, permission)
@ -424,7 +423,7 @@ def permission_update(operation_logger, auth, app, permission, add_url=None, rem
@is_unit_operation(['permission','app']) @is_unit_operation(['permission','app'])
def permission_remove(operation_logger, auth, app, permission, force=False): def permission_remove(operation_logger, auth, app, permission, force=False, sync_perm=True):
""" """
Remove a permission for a specific application Remove a permission for a specific application
@ -440,15 +439,17 @@ def permission_remove(operation_logger, auth, app, permission, force=False):
operation_logger.start() operation_logger.start()
if not auth.remove('cn=%s,ou=permission' % str(permission + '.' + app)): if not auth.remove('cn=%s,ou=permission' % str(permission + '.' + app)):
raise MoulinetteError(169, m18n.n('permission_deletion_failed', permission=permission, app=app)) raise MoulinetteError(169, m18n.n('permission_deletion_failed', permission=permission, app=app))
_permission_sync_to_user(auth) if sync_perm:
permission_sync_to_user(auth)
logger.success(m18n.n('permission_deleted', permission=permission, app=app)) logger.success(m18n.n('permission_deleted', permission=permission, app=app))
def _permission_sync_to_user(auth): def permission_sync_to_user(auth):
""" """
Sychronise the inheritPermission attribut in the permission object from the user<->group link and the group<->permission link Sychronise the inheritPermission attribut in the permission object from the user<->group link and the group<->permission link
""" """
import os import os
from yunohost.app import app_ssowatconf
permission_attrs = [ permission_attrs = [
'cn', 'cn',
@ -486,6 +487,9 @@ def _permission_sync_to_user(auth):
inheritPermission = {'inheritPermission': val, 'memberUid': uid_val} inheritPermission = {'inheritPermission': val, 'memberUid': uid_val}
if not auth.update('cn=%s,ou=permission' % per['cn'][0], inheritPermission): if not auth.update('cn=%s,ou=permission' % per['cn'][0], inheritPermission):
raise MoulinetteError(169, m18n.n('permission_update_failed')) raise MoulinetteError(169, m18n.n('permission_update_failed'))
logger.success(m18n.n('permission_generated'))
app_ssowatconf(auth)
# Reload unscd because if not the group is not updated in the system from LDAP # Reload unscd because if not the group is not updated in the system from LDAP
os.system('systemctl restart unscd') os.system('systemctl restart unscd')

View file

@ -115,7 +115,6 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
""" """
from yunohost.domain import domain_list, _get_maindomain from yunohost.domain import domain_list, _get_maindomain
from yunohost.hook import hook_callback from yunohost.hook import hook_callback
from yunohost.app import app_ssowatconf
from yunohost.utils.password import assert_password_is_strong_enough from yunohost.utils.password import assert_password_is_strong_enough
# Ensure sufficiently complex password # Ensure sufficiently complex password
@ -211,13 +210,14 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
if not os.path.isdir('/home/{0}'.format(username)): if not os.path.isdir('/home/{0}'.format(username)):
logger.warning(m18n.n('user_home_creation_failed'), logger.warning(m18n.n('user_home_creation_failed'),
exc_info=1) exc_info=1)
app_ssowatconf(auth)
# Create group for user and add to group 'all_users'
user_group_add(auth, groupname=username, gid=uid, sync_perm=False)
user_group_update(auth, groupname=username, add_user=username, force=True, sync_perm=False)
user_group_update(auth, 'all_users', add_user=username, force=True, sync_perm=True)
# TODO: Send a welcome mail to user # TODO: Send a welcome mail to user
logger.success(m18n.n('user_created')) logger.success(m18n.n('user_created'))
# Create group for user and add to group 'all_users'
user_group_add(auth, groupname=username, gid=uid)
user_group_update(auth, groupname=username, add_user=username, force=True)
user_group_update(auth, 'all_users', add_user=username, force=True)
hook_callback('post_user_create', hook_callback('post_user_create',
args=[username, mail, password, firstname, lastname]) args=[username, mail, password, firstname, lastname])
@ -237,7 +237,6 @@ def user_delete(operation_logger, auth, username, purge=False):
purge purge
""" """
from yunohost.app import app_ssowatconf
from yunohost.hook import hook_callback from yunohost.hook import hook_callback
operation_logger.start() operation_logger.start()
@ -250,7 +249,7 @@ def user_delete(operation_logger, auth, username, purge=False):
else: else:
raise YunohostError('user_deletion_failed') raise YunohostError('user_deletion_failed')
user_group_delete(auth, username, force=True) user_group_delete(auth, username, force=True, sync_perm=True)
group_list = auth.search('ou=groups,dc=yunohost,dc=org', group_list = auth.search('ou=groups,dc=yunohost,dc=org',
'(&(objectclass=groupOfNamesYnh)(memberUid=%s))' '(&(objectclass=groupOfNamesYnh)(memberUid=%s))'
@ -263,8 +262,6 @@ def user_delete(operation_logger, auth, username, purge=False):
if not auth.update('cn=%s,ou=groups' % group['cn'][0], user_list): if not auth.update('cn=%s,ou=groups' % group['cn'][0], user_list):
raise YunohostError('group_update_failed') raise YunohostError('group_update_failed')
app_ssowatconf(auth)
hook_callback('post_user_delete', args=[username, purge]) hook_callback('post_user_delete', args=[username, purge])
logger.success(m18n.n('user_deleted')) logger.success(m18n.n('user_deleted'))
@ -537,7 +534,7 @@ def user_group_list(auth, fields=None):
@is_unit_operation([('groupname', 'user')]) @is_unit_operation([('groupname', 'user')])
def user_group_add(operation_logger, auth, groupname,gid=None): def user_group_add(operation_logger, auth, groupname,gid=None, sync_perm=True):
""" """
Create group Create group
@ -545,8 +542,7 @@ def user_group_add(operation_logger, auth, groupname,gid=None):
groupname -- Must be unique groupname -- Must be unique
""" """
from yunohost.app import app_ssowatconf from yunohost.permission import permission_sync_to_user
from yunohost.permission import _permission_sync_to_user
operation_logger.start() operation_logger.start()
@ -578,16 +574,16 @@ def user_group_add(operation_logger, auth, groupname,gid=None):
} }
if auth.add('cn=%s,ou=groups' % groupname, attr_dict): if auth.add('cn=%s,ou=groups' % groupname, attr_dict):
_permission_sync_to_user(auth)
app_ssowatconf(auth)
logger.success(m18n.n('group_created')) logger.success(m18n.n('group_created'))
if sync_perm:
permission_sync_to_user(auth)
return {'name': groupname} return {'name': groupname}
raise MoulinetteError(169, m18n.n('group_creation_failed')) raise MoulinetteError(169, m18n.n('group_creation_failed'))
@is_unit_operation([('groupname', 'user')]) @is_unit_operation([('groupname', 'user')])
def user_group_delete(operation_logger, auth, groupname, force=False): def user_group_delete(operation_logger, auth, groupname, force=False, sync_perm=True):
""" """
Delete user Delete user
@ -595,8 +591,7 @@ def user_group_delete(operation_logger, auth, groupname, force=False):
groupname -- Groupname to delete groupname -- Groupname to delete
""" """
from yunohost.app import app_ssowatconf from yunohost.permission import permission_sync_to_user
from yunohost.permission import _permission_sync_to_user
if not force and (groupname == 'all_users' or groupname == 'admins' or groupname in user_list(auth, ['uid'])['users']): if not force and (groupname == 'all_users' or groupname == 'admins' or groupname in user_list(auth, ['uid'])['users']):
raise MoulinetteError(errno.EPERM, m18n.n('group_deletion_not_allowed', user=groupname)) raise MoulinetteError(errno.EPERM, m18n.n('group_deletion_not_allowed', user=groupname))
@ -605,13 +600,13 @@ def user_group_delete(operation_logger, auth, groupname, force=False):
if not auth.remove('cn=%s,ou=groups' % groupname): if not auth.remove('cn=%s,ou=groups' % groupname):
raise MoulinetteError(169, m18n.n('group_deletion_failed')) raise MoulinetteError(169, m18n.n('group_deletion_failed'))
_permission_sync_to_user(auth)
app_ssowatconf(auth)
logger.success(m18n.n('group_deleted')) logger.success(m18n.n('group_deleted'))
if sync_perm:
permission_sync_to_user(auth)
@is_unit_operation([('groupname', 'user')]) @is_unit_operation([('groupname', 'user')])
def user_group_update(operation_logger, auth, groupname, add_user=None, remove_user=None, force=False): def user_group_update(operation_logger, auth, groupname, add_user=None, remove_user=None, force=False, sync_perm=True):
""" """
Update user informations Update user informations
@ -622,8 +617,7 @@ def user_group_update(operation_logger, auth, groupname, add_user=None, remove_u
""" """
from yunohost.app import app_ssowatconf from yunohost.permission import permission_sync_to_user
from yunohost.permission import _permission_sync_to_user
attrs_to_fetch = ['member'] attrs_to_fetch = ['member']
@ -685,9 +679,9 @@ def user_group_update(operation_logger, auth, groupname, add_user=None, remove_u
if not auth.update('cn=%s,ou=groups' % groupname, new_group_list): if not auth.update('cn=%s,ou=groups' % groupname, new_group_list):
raise MoulinetteError(169, m18n.n('group_update_failed')) raise MoulinetteError(169, m18n.n('group_update_failed'))
_permission_sync_to_user(auth)
logger.success(m18n.n('group_updated')) logger.success(m18n.n('group_updated'))
app_ssowatconf(auth) if sync_perm:
permission_sync_to_user(auth)
return user_group_info(auth, groupname) return user_group_info(auth, groupname)
@ -723,24 +717,27 @@ def user_group_info(auth, groupname):
# #
import yunohost.permission import yunohost.permission
def user_permission_list(auth, app=None, permission=None, username=None, group=None): def user_permission_list(auth, app=None, permission=None, username=None, group=None, sync_perm=True):
return yunohost.permission.user_permission_list(auth, app, permission, username, group) return yunohost.permission.user_permission_list(auth, app, permission, username, group)
@is_unit_operation([('app', 'user')]) @is_unit_operation([('app', 'user')])
def user_permission_add(operation_logger, auth, app, permission="main", username=None, group=None): def user_permission_add(operation_logger, auth, app, permission="main", username=None, group=None, sync_perm=True):
return yunohost.permission.user_permission_update(operation_logger, auth, app, permission=permission, return yunohost.permission.user_permission_update(operation_logger, auth, app, permission=permission,
add_username=username, add_group=group, add_username=username, add_group=group,
del_username=None, del_group=None) del_username=None, del_group=None,
sync_perm=sync_perm)
@is_unit_operation([('app', 'user')]) @is_unit_operation([('app', 'user')])
def user_permission_remove(operation_logger, auth, app, permission="main", username=None, group=None): def user_permission_remove(operation_logger, auth, app, permission="main", username=None, group=None, sync_perm=True):
return yunohost.permission.user_permission_update(operation_logger, auth, app, permission=permission, return yunohost.permission.user_permission_update(operation_logger, auth, app, permission=permission,
add_username=None, add_group=None, add_username=None, add_group=None,
del_username=username, del_group=group) del_username=username, del_group=group,
sync_perm=sync_perm)
@is_unit_operation([('app', 'user')]) @is_unit_operation([('app', 'user')])
def user_permission_clear(operation_logger, auth, app, permission=None): def user_permission_clear(operation_logger, auth, app, permission=None, sync_perm=True):
return yunohost.permission.user_permission_clear(operation_logger, auth, app, permission) return yunohost.permission.user_permission_clear(operation_logger, auth, app, permission,
sync_perm=sync_perm)
# #
# SSH subcategory # SSH subcategory