From a44f79765c5c83eeeea064d2cb272b95eeddcee6 Mon Sep 17 00:00:00 2001 From: Raffael Meyer <14891507+barredterra@users.noreply.github.com> Date: Fri, 10 Jan 2025 17:03:20 +0100 Subject: [PATCH] feat: new report LANDA Power Users (#270) --- docs/permissions.md | 6 ++ .../report/landa_power_users/__init__.py | 0 .../landa_power_users/landa_power_users.js | 9 +++ .../landa_power_users/landa_power_users.json | 30 ++++++++ .../landa_power_users/landa_power_users.py | 73 +++++++++++++++++++ landa/translations/de.csv | 2 + 6 files changed, 120 insertions(+) create mode 100644 landa/organization_management/report/landa_power_users/__init__.py create mode 100644 landa/organization_management/report/landa_power_users/landa_power_users.js create mode 100644 landa/organization_management/report/landa_power_users/landa_power_users.json create mode 100644 landa/organization_management/report/landa_power_users/landa_power_users.py diff --git a/docs/permissions.md b/docs/permissions.md index ab37fbe6..27b7d063 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -46,3 +46,9 @@ The default way to achieve this would be adding a link field from **Tag** to **O To prevent this, we added a table named **Tag Organization** to the **Tag** doctype. When a new tag is created, the creator's organization is added to this table. We also added a custom permission query which checks if the user's organization is in this table. This way users can only see tags created by people in the same organization. See https://github.com/alyf-de/landa/pull/254 for details. + +### Monitoring + +Usually, most users should be restricted to seeing data of their own organization only. However, some users are allowed to see data of other organizations. + +For monitoring users with high permissions, we created a report named **LANDA Power Users**. It shows all users with high permissions, and which organizations they are allowed to see. Excluded are the default users **Administrator** and **Guest**. Also, users who are members of a regional organization (e.g. AVL-000) and have permissions for that regional organization (e.g. AVL) are excluded. diff --git a/landa/organization_management/report/landa_power_users/__init__.py b/landa/organization_management/report/landa_power_users/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/landa/organization_management/report/landa_power_users/landa_power_users.js b/landa/organization_management/report/landa_power_users/landa_power_users.js new file mode 100644 index 00000000..57c04abb --- /dev/null +++ b/landa/organization_management/report/landa_power_users/landa_power_users.js @@ -0,0 +1,9 @@ +// Copyright (c) 2025, ALYF GmbH and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["LANDA Power Users"] = { + "filters": [ + + ] +}; diff --git a/landa/organization_management/report/landa_power_users/landa_power_users.json b/landa/organization_management/report/landa_power_users/landa_power_users.json new file mode 100644 index 00000000..63eba988 --- /dev/null +++ b/landa/organization_management/report/landa_power_users/landa_power_users.json @@ -0,0 +1,30 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2025-01-10 16:06:59.329435", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "letter_head": "Extended Information in Footer", + "modified": "2025-01-10 16:06:59.329435", + "modified_by": "Administrator", + "module": "Organization Management", + "name": "LANDA Power Users", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "User", + "report_name": "LANDA Power Users", + "report_type": "Script Report", + "roles": [ + { + "role": "System Manager" + }, + { + "role": "LANDA State Organization Employee" + } + ] +} \ No newline at end of file diff --git a/landa/organization_management/report/landa_power_users/landa_power_users.py b/landa/organization_management/report/landa_power_users/landa_power_users.py new file mode 100644 index 00000000..96e98ab7 --- /dev/null +++ b/landa/organization_management/report/landa_power_users/landa_power_users.py @@ -0,0 +1,73 @@ +# Copyright (c) 2025, ALYF GmbH and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ +from frappe.query_builder.functions import Substring +from pypika.functions import Coalesce +from pypika.terms import Not + + +def execute(filters=None): + return get_columns(), get_data() + + +def get_data(): + User = frappe.qb.DocType("User") + UserPermission = frappe.qb.DocType("User Permission") + + org_permissions = ( + frappe.qb.from_(UserPermission) + .select(UserPermission.user, UserPermission.for_value) + .where(UserPermission.allow == "Organization") + .where(UserPermission.apply_to_all_doctypes == 1) + ) + + query = ( + frappe.qb.from_(User) + .left_join(org_permissions) + .on(User.name == org_permissions.user) + .select( + User.name, + User.organization, + Coalesce(org_permissions.for_value, "All Organizations").as_("permissions_for"), + ) + .where(User.name.notin(["Administrator", "Guest"])) + .where(User.enabled == 1) + .where( + (Substring(org_permissions.for_value, 1, 7) != Substring(User.organization, 1, 7)) + | (org_permissions.for_value.isnull()) + ) + .where( + # Exclude lines like "Member of AVL-000. Permissions for AVL" (regional org management) + Not( + (Substring(User.organization, 5, 7) == "000") + & (Substring(User.organization, 1, 3) == org_permissions.for_value) + ) + ) + .orderby(User.name) + ) + + return query.run() + + +def get_columns(): + return [ + { + "fieldname": "user", + "label": _("User"), + "fieldtype": "Link", + "options": "User", + }, + { + "fieldname": "member_of", + "label": _("Member of"), + "fieldtype": "Link", + "options": "Organization", + }, + { + "fieldname": "permissions_for", + "label": _("Permissions for"), + "fieldtype": "Data", + }, + ] diff --git a/landa/translations/de.csv b/landa/translations/de.csv index f9f6f171..f1a1341d 100644 --- a/landa/translations/de.csv +++ b/landa/translations/de.csv @@ -107,3 +107,5 @@ Statement of Fees and Payments,Beitragsabrechnung, This Statement of Fees and Payments already exists: {0},Diese Beitragsabrechnung existiert bereits: {0}, This Statement of Fees and Payments must be linked to an Organization,Diese Beitragsabrechnung muss mit einem Verein verknüpft sein, Group By Fish Species,Nach Fischart gruppieren, +Member of,Mitglied von, +Permissions for,Berechtigungen für,