From 9040da01726d5e2e94f29fe416d754aef40cb4e7 Mon Sep 17 00:00:00 2001 From: Cian Hughes Date: Thu, 13 Aug 2026 13:22:50 +0100 Subject: [PATCH] Added admin panel access with Role Assignment --- .../administration/__init__.py | 9 ++ invenio_theme_iform/administration/views.py | 78 ++++++++++++ .../accounts/header_login.html | 7 + .../administration/roles.html | 120 ++++++++++++++++++ pyproject.toml | 4 + 5 files changed, 218 insertions(+) create mode 100644 invenio_theme_iform/administration/__init__.py create mode 100644 invenio_theme_iform/administration/views.py create mode 100644 invenio_theme_iform/templates/invenio_theme_iform/administration/roles.html diff --git a/invenio_theme_iform/administration/__init__.py b/invenio_theme_iform/administration/__init__.py new file mode 100644 index 0000000..ebe97b8 --- /dev/null +++ b/invenio_theme_iform/administration/__init__.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 I-Form. +# +# invenio-theme-iform is free software; you can redistribute it and/or +# modify it under the terms of the MIT License; see LICENSE file for more +# details. + +"""Administration views.""" diff --git a/invenio_theme_iform/administration/views.py b/invenio_theme_iform/administration/views.py new file mode 100644 index 0000000..f13eca6 --- /dev/null +++ b/invenio_theme_iform/administration/views.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 I-Form. +# +# invenio-theme-iform is free software; you can redistribute it and/or +# modify it under the terms of the MIT License; see LICENSE file for more +# details. + +"""I-Form role management administration views.""" + +from flask import flash, redirect, request, url_for +from invenio_accounts.models import Role, User +from invenio_accounts.proxies import current_accounts +from invenio_administration.views.base import AdminView +from invenio_db import db +from invenio_i18n import lazy_gettext as _ + + +class RoleManagementView(AdminView): + """Admin view for managing user roles.""" + + name = "roles" + category = "User management" + template = "invenio_theme_iform/administration/roles.html" + url = "/roles" + menu_label = _("Role Assignment") + icon = "users" + + def get(self): + """Render the role management template.""" + roles = Role.query.order_by(Role.name).all() + selected_role_id = request.args.get("role_id") + + users = [] + selected_role = None + if selected_role_id: + selected_role = Role.query.get(selected_role_id) + if selected_role: + users = User.query.order_by(User.email).all() + + return self.render( + roles=roles, + selected_role=selected_role, + users=users, + ) + + def post(self): + """Handle role assignment/revocation.""" + user_id = request.form.get("user_id") + role_id = request.form.get("role_id") + action = request.form.get("action") + + if not (user_id and role_id and action): + flash(_("Missing required fields."), "error") + return redirect(url_for("administration.roles", role_id=role_id)) + + try: + user = User.query.get(int(user_id)) + except ValueError: + user = None + + role = Role.query.get(role_id) + + if not user or not role: + flash(_("User or role not found."), "error") + return redirect(url_for("administration.roles", role_id=role_id)) + + if action == "enable": + if role not in user.roles: + current_accounts.datastore.add_role_to_user(user, role) + flash(_("Role {role} enabled for {email}.").format(role=role.name, email=user.email), "success") + elif action == "disable": + if role in user.roles: + current_accounts.datastore.remove_role_from_user(user, role) + flash(_("Role {role} disabled for {email}.").format(role=role.name, email=user.email), "success") + + db.session.commit() + return redirect(url_for("administration.roles", role_id=role_id)) diff --git a/invenio_theme_iform/templates/invenio_theme_iform/accounts/header_login.html b/invenio_theme_iform/templates/invenio_theme_iform/accounts/header_login.html index 59be9db..62eb2bb 100644 --- a/invenio_theme_iform/templates/invenio_theme_iform/accounts/header_login.html +++ b/invenio_theme_iform/templates/invenio_theme_iform/accounts/header_login.html @@ -22,6 +22,13 @@ {{ current_user.email }} + {%- for item in current_menu.submenu('profile-admin').children if item.visible %} +
+ + {{ item.text|safe }} + +
+ {%- endfor %}
{{ _("Sign out") }} +
+
+

+ +
+ {{ _("Role Assignment") }} +
{{ _("Select a role and enable or disable it for users.") }}
+
+

+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
+ {{ message }} +
+ {% endfor %} + {% endif %} + {% endwith %} + +
+
+
+ +
+ + +
+
+
+
+ + {% if selected_role %} +
+

+ {{ _("Users assigned to:") }} {{ selected_role.name }} + {% if selected_role.description %} +
+ {{ selected_role.description }} +
+ {% endif %} +

+ + + + + + + + + + + {% for user in users %} + + + + + {% set has_role = selected_role in user.roles %} + + + + + {% else %} + + + + {% endfor %} + +
{{ _("Email") }}{{ _("Active") }}{{ _("Has Role?") }}{{ _("Actions") }}
{{ user.email }} + {% if user.active %} +
{{ _("Active") }}
+ {% else %} +
{{ _("Inactive") }}
+ {% endif %} +
+ {% if has_role %} + + {% else %} + + {% endif %} + +
+ + + {% if has_role %} + + + {% else %} + + + {% endif %} +
+
{{ _("No users found.") }}
+
+ {% endif %} +
+
+
+{% endblock %} diff --git a/pyproject.toml b/pyproject.toml index 8e1c347..773353b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,10 @@ invenio_theme_iform = "invenio_theme_iform.config" [project.entry-points."invenio_base.finalize_app"] invenio_theme_iform = "invenio_theme_iform.ext:finalize_app" +[project.entry-points."invenio_administration.views"] +invenio_theme_iform_roles = "invenio_theme_iform.administration.views:RoleManagementView" + + [dependency-groups] dev = [ "hatch>=1.14.1",