diff --git a/backend/helpers/kratos_user.py b/backend/helpers/kratos_user.py index 894332f1e87fc387ebf2106ad021dc1d231c06a3..e1540368bdb0a44d0754331a7acbe1a0df31265d 100644 --- a/backend/helpers/kratos_user.py +++ b/backend/helpers/kratos_user.py @@ -352,9 +352,6 @@ class KratosUser(): return False raise BackendError("Unable to set password by submitting form") - # Pylint complains about app not used. That is correct, but we will use that - # in the future. Ignore this error - # pylint: disable=unused-argument def get_claims(self, app, roles, mapping=None) -> Dict[str, Dict[str, str]]: """Create openID Connect token Use the userdata stored in the user object to create an OpenID Connect token. @@ -364,7 +361,7 @@ class KratosUser(): Example: getClaims('nextcloud', mapping=[("name", "username"),("roles", "groups")]) Attributes: - appname - Name or ID of app to connect to + appname - client_id of app to connect to roles - List of roles to add to the `stackspin_roles` claim mapping - Mapping of the fields @@ -392,6 +389,34 @@ class KratosUser(): "stackspin_roles": roles, } + if app == "wekan": + # This is a non-standard extension to OIDC. It's used in this form + # by Wekan. We don't really have user groups in Stackspin, just an + # admin flag. However as far as I can see, the only way to make + # some users admin in Wekan via OIDC is to have a group for them. + # + # We include a default "stackspin_users" group, because Wekan doesn't + # process group information if the `groups` list is empty, so we + # would not be able to remove a user from the admin group + # otherwise. + # + # Actually Wekan doesn't remove users from groups based on this + # list apparently, but it still implements a correct `isAdmin` + # check based on this group data, which is the part we care about. + groups = [{ + "displayName": "Stackspin users", + "isAdmin": False, + "forceCreate": True, + "isActive": True, + }] + if "admin" in roles: + groups.append({ + "displayName": "Stackspin admins", + "isAdmin": True, + "forceCreate": True, + "isActive": True, + }) + token["groups"] = groups # Relabel field names if mapping: diff --git a/backend/web/login/login.py b/backend/web/login/login.py index 2abbcc01e3bb35fea3b599c7ae08c4e5c27d3bb6..572253717af5926a14e1023b9790e4c5f71e7743 100644 --- a/backend/web/login/login.py +++ b/backend/web/login/login.py @@ -382,7 +382,7 @@ def consent(): current_app.logger.info(f"Providing consent to {client_id} for {kratos_id}") current_app.logger.info(f"{kratos_id} was granted admin access to {client_id}") # Get claims for this user, provided the current app - claims = user.get_claims(None, ['admin']) + claims = user.get_claims(client_id, ['admin']) current_app.logger.info(f"claims: {claims}") return redirect( hydra_admin_api.accept_consent_request( @@ -443,7 +443,8 @@ def consent(): current_app.logger.info(f"Using '{roles}' when applying consent for {kratos_id}") # Get claims for this user, provided the current app - claims = user.get_claims(None, roles) + claims = user.get_claims(client_id, roles) + current_app.logger.info(f"claims: {claims}") # pylint: disable=fixme # TODO: Need to implement checking claims here, once the backend for that is