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 %} +
+ {%- endfor %} +{% 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",