From e6ff4c14607dd3bfa4b437299967398e993cef2a Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Mon, 13 Sep 2021 23:06:42 +0200 Subject: [PATCH] =?UTF-8?q?cr=C3=A9ation=20roles=20en=20cli?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scodoc/sco_permissions.py | 4 +-- app/views/users.py | 23 +++++++++---- scodoc.py | 64 +++++++++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/app/scodoc/sco_permissions.py b/app/scodoc/sco_permissions.py index 4529e767..a1a06aba 100644 --- a/app/scodoc/sco_permissions.py +++ b/app/scodoc/sco_permissions.py @@ -57,8 +57,8 @@ class Permission(object): @staticmethod def get_by_name(permission_name: str) -> int: - """Return permission mode (integer bit field). May raise keyError.""" - return Permission.permission_by_name[permission_name] + """Return permission mode (integer bit field), or None if it doesn't exist.""" + return Permission.permission_by_name.get(permission_name) Permission.init_permissions() diff --git a/app/views/users.py b/app/views/users.py index c246d500..17e9987f 100644 --- a/app/views/users.py +++ b/app/views/users.py @@ -97,11 +97,12 @@ def user_info(user_name, format="json", REQUEST=None): @scodoc @permission_required(Permission.ScoUsersAdmin) @scodoc7func -def create_user_form(REQUEST, user_name=None, edit=0): - "form. creation ou edit utilisateur" +def create_user_form(REQUEST, user_name=None, edit=0, all_roles=1): + "form. création ou edition utilisateur" auth_dept = current_user.dept initvalues = {} edit = int(edit) + all_roles = int(all_roles) H = [html_sco_header.sco_header(bodyOnLoad="init_tf_form('')")] F = html_sco_header.sco_footer() if edit: @@ -120,11 +121,19 @@ def create_user_form(REQUEST, user_name=None, edit=0): H.append("""

Vous êtes super administrateur !

""") is_super_admin = True - # Les rôles standards créés à l'initialisation de ScoDoc: - standard_roles = [ - Role.get_named_role(r) for r in ("Ens", "Secr", "Admin", "RespPe") - ] - # Rôles pouvant etre attribués aux utilisateurs via ce dialogue: + if all_roles: + # tous sauf SuperAdmin + standard_roles = [ + r + for r in Role.query.all() + if r.permissions != Permission.ALL_PERMISSIONS[0] + ] + else: + # Les rôles standards créés à l'initialisation de ScoDoc: + standard_roles = [ + Role.get_named_role(r) for r in ("Ens", "Secr", "Admin", "RespPe") + ] + # Départements auxquels ont peut associer des rôles via ce dialogue: # si SuperAdmin, tous les rôles standards dans tous les départements # sinon, les départements dans lesquels l'utilisateur a le droit if is_super_admin: diff --git a/scodoc.py b/scodoc.py index 87cc9677..b5176c25 100755 --- a/scodoc.py +++ b/scodoc.py @@ -6,9 +6,8 @@ """ - -import os from pprint import pprint as pp +import re import sys import click @@ -151,6 +150,39 @@ def user_password(username, password=None): # user-password click.echo(f"changed password for user {u}") +@app.cli.command() +@click.argument("rolename") +@click.argument("permissions", nargs=-1) +def create_role(rolename, permissions): # create-role + """Create a new role""" + # Check rolename + if not re.match(r"^[a-zA-Z0-9]+$", rolename): + sys.stderr.write(f"create_role: invalid rolename {rolename}\n") + return 1 + # Check permissions + permission_list = [] + for permission_name in permissions: + perm = Permission.get_by_name(permission_name) + if not perm: + sys.stderr.write(f"create_role: invalid permission name {perm}\n") + sys.stderr.write( + f"\tavailable permissions: {', '.join([ name for name in Permission.permission_by_name])}.\n" + ) + return 1 + permission_list.append(perm) + + role = Role.query.filter_by(name=rolename).first() + if role: + sys.stderr.write(f"create_role: role {rolename} already exists\n") + return 1 + + role = Role(name=rolename) + for perm in permission_list: + role.add_permission(perm) + db.session.add(role) + db.session.commit() + + @app.cli.command() @click.argument("rolename") @click.option("-a", "--add", "addpermissionname") @@ -163,9 +195,8 @@ def edit_role(rolename, addpermissionname=None, removepermissionname=None): # e Example: `flask edit-role -a ScoEditApo Ens` """ if addpermissionname: - try: - perm_to_add = Permission.get_by_name(addpermissionname) - except KeyError: + perm_to_add = Permission.get_by_name(addpermissionname) + if not perm_to_add: sys.stderr.write( f"edit_role: permission {addpermissionname} does not exists\n" ) @@ -173,9 +204,8 @@ def edit_role(rolename, addpermissionname=None, removepermissionname=None): # e else: perm_to_add = None if removepermissionname: - try: - perm_to_remove = Permission.get_by_name(removepermissionname) - except KeyError: + perm_to_remove = Permission.get_by_name(removepermissionname) + if not perm_to_remove: sys.stderr.write( f"edit_role: permission {removepermissionname} does not exists\n" ) @@ -237,7 +267,7 @@ def create_dept(dept): # create-dept @app.cli.command() @with_appcontext def import_scodoc7_users(): # import-scodoc7-users - """Import used defined in ScoDoc7 postgresql database into ScoDoc 9 + """Import users defined in ScoDoc7 postgresql database into ScoDoc 9 The old database SCOUSERS must be alive and readable by the current user. This script is typically run as unix user "scodoc". The original SCOUSERS database is left unmodified. @@ -263,7 +293,21 @@ def import_scodoc7_dept(dept: str, dept_db_name: str): # import-scodoc7-dept def clear_cache(): # clear-cache """Clear ScoDoc cache This cache (currently Redis) is persistent between invocation - and it may be necessary to clear it during developement or tests. + and it may be necessary to clear it during development or tests. """ clear_scodoc_cache() click.echo("Redis caches flushed.") + + +def recursive_help(cmd, parent=None): + ctx = click.core.Context(cmd, info_name=cmd.name, parent=parent) + print(cmd.get_help(ctx)) + print() + commands = getattr(cmd, "commands", {}) + for sub in commands.values(): + recursive_help(sub, ctx) + + +@app.cli.command() +def dumphelp(): + recursive_help(app.cli)