diff --git a/app/auth/models.py b/app/auth/models.py index ad56c5063f..3750ea3f88 100644 --- a/app/auth/models.py +++ b/app/auth/models.py @@ -279,7 +279,7 @@ class User(UserMixin, db.Model): return False # Role management - def add_role(self, role, dept): + def add_role(self, role: "Role", dept: str): """Add a role to this user. :param role: Role to add. """ @@ -287,7 +287,7 @@ class User(UserMixin, db.Model): raise ScoValueError("add_role: rĂ´le invalide") self.user_roles.append(UserRole(user=self, role=role, dept=dept)) - def add_roles(self, roles, dept): + def add_roles(self, roles: "list[Role]", dept: str): """Add roles to this user. :param roles: Roles to add. """ @@ -410,6 +410,9 @@ class Role(db.Model): w=Permission.NBITS, ) + def __str__(self): + return f"{self.name}: perm={', '.join(Permission.permissions_names(self.permissions))}" + def add_permission(self, perm): self.permissions |= perm diff --git a/app/scodoc/sco_permissions.py b/app/scodoc/sco_permissions.py index 2a68b1a46a..53dfcf97be 100644 --- a/app/scodoc/sco_permissions.py +++ b/app/scodoc/sco_permissions.py @@ -57,12 +57,13 @@ _SCO_PERMISSIONS = ( ) -class Permission(object): +class Permission: "Permissions for ScoDoc" NBITS = 1 # maximum bits used (for formatting) ALL_PERMISSIONS = [-1] description = {} # { symbol : blah blah } permission_by_name = {} # { symbol : int } + permission_by_value = {} # { int : symbol } @staticmethod def init_permissions(): @@ -70,6 +71,7 @@ class Permission(object): setattr(Permission, symbol, perm) Permission.description[symbol] = description Permission.permission_by_name[symbol] = perm + Permission.permission_by_value[perm] = symbol max_perm = max(p[0] for p in _SCO_PERMISSIONS) Permission.NBITS = max_perm.bit_length() @@ -78,5 +80,23 @@ class Permission(object): """Return permission mode (integer bit field), or None if it doesn't exist.""" return Permission.permission_by_name.get(permission_name) + @staticmethod + def get_name(permission: int) -> str: + """Return permission name, or None if it doesn't exist.""" + return Permission.permission_by_value.get(permission) + + @staticmethod + def permissions_names(permissions: int) -> list[str]: + """From a bit field, return list of permission names""" + names = [] + mask = 1 << (permissions.bit_length() - 1) + while mask > 0: + if mask & permissions: + name = Permission.get_name(mask) + if name is not None: + names.append(name) + mask = mask >> 1 + return names + Permission.init_permissions() diff --git a/scodoc.py b/scodoc.py index 0b7f353139..66c0a175a7 100755 --- a/scodoc.py +++ b/scodoc.py @@ -227,6 +227,13 @@ def create_role(rolename, permissions): # create-role db.session.commit() +@app.cli.command() +def list_roles(): # list-roles + """List all defined roles""" + for role in Role.query: + print(role) + + @app.cli.command() @click.argument("rolename") @click.option("-a", "--add", "addpermissionname") @@ -290,7 +297,7 @@ def delete_role(rolename): @click.option("-r", "--remove", "remove_role_name") def user_role(username, dept_acronym=None, add_role_name=None, remove_role_name=None): """Add or remove a role to the given user in the given dept""" - user = User.query.filter_by(user_name=username).first() + user: User = User.query.filter_by(user_name=username).first() if not user: sys.stderr.write(f"user_role: user {username} does not exists\n") return 1 @@ -302,9 +309,15 @@ def user_role(username, dept_acronym=None, add_role_name=None, remove_role_name= if add_role_name: role = Role.query.filter_by(name=add_role_name).first() + if role is None: + sys.stderr.write(f"user_role: role {add_role_name} does not exists\n") + return 2 user.add_role(role, dept_acronym) if remove_role_name: role = Role.query.filter_by(name=remove_role_name).first() + if role is None: + sys.stderr.write(f"user_role: role {remove_role_name} does not exists\n") + return 2 user_role = UserRole.query.filter( UserRole.role == role, UserRole.user == user, UserRole.dept == dept_acronym ).first() @@ -355,7 +368,7 @@ def create_dept(dept): # create-dept @app.cli.command() @click.argument("depts", nargs=-1) -def list_depts(depts=""): # list-dept +def list_depts(depts=""): # list-depts """If dept exists, print it, else nothing. Called without arguments, list all depts along with their ids. """