From c6b61a5f14bc18423ab627bc7a329cb0dcf4b1c7 Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop Date: Thu, 12 Sep 2024 11:16:59 +0000 Subject: [PATCH] Bug 38010: Add permissions This patch adds a permissions store and utility methods for implementing permissions checks in a Vue app --- acqui/booksellers.pl | 12 +---- .../prog/js/vue/components/Vendors/Main.vue | 51 ++++++++++++++++++- .../components/Vendors/VendorContracts.vue | 32 ++++++++++-- .../Vendors/VendorSubscriptions.vue | 16 ++++-- .../prog/js/vue/modules/vendors.ts | 3 ++ .../prog/js/vue/routes/vendors.js | 6 +-- .../prog/js/vue/stores/permissions.js | 21 ++++++++ 7 files changed, 119 insertions(+), 22 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/stores/permissions.js diff --git a/acqui/booksellers.pl b/acqui/booksellers.pl index e2784430329..520b977f78f 100755 --- a/acqui/booksellers.pl +++ b/acqui/booksellers.pl @@ -52,7 +52,7 @@ The id of the supplier whose baskets we will display =cut use Modern::Perl; -use C4::Auth qw( get_template_and_user ); +use C4::Auth qw( get_template_and_user haspermission ); use C4::Budgets qw( GetBudgetHierarchy GetBudget CanUserUseBudget ); use C4::Output qw( output_html_with_http_headers ); use CGI qw ( -utf8 ); @@ -172,14 +172,4 @@ $template->param( ); $template->{VARS}->{'allbaskets'} = $allbaskets; - - -$template->param( - loop_suppliers => $loop_suppliers, - supplier => ( $booksellerid || $supplier ), - count => $supplier_count, - has_budgets => $has_budgets, -); -$template->{VARS}->{'allbaskets'} = $allbaskets; - output_html_with_http_headers $query, $cookie, $template->output; diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue index b6cb622e039..ddb24f11414 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/Main.vue @@ -14,7 +14,7 @@
- +
@@ -44,12 +44,16 @@ export default { const { loading, loaded, setError } = mainStore + const permissionsStore = inject("permissionsStore") + const { userPermissions } = storeToRefs(permissionsStore) + return { vendorStore, AVStore, setError, loading, loaded, + userPermissions, AVStore, } }, @@ -90,6 +94,50 @@ export default { return Promise.all(promises) } + fetchConfig().then(() => { + this.loaded() + this.initialized = true + }) + }, + beforeCreate() { + this.loading() + + const fetchConfig = () => { + let promises = [] + + const av_client = APIClient.authorised_values + const authorised_values = { + vendor_types: "VENDOR_TYPE", + vendor_interface_types: "VENDOR_INTERFACE_TYPE", + vendor_payment_methods: "VENDOR_PAYMENT_METHOD", + lang: "LANG", + } + + let av_cat_array = Object.keys(authorised_values).map(function ( + av_cat + ) { + return '"' + authorised_values[av_cat] + '"' + }) + + promises.push( + av_client.values + .getCategoriesWithValues(av_cat_array) + .then(av_categories => { + Object.entries(authorised_values).forEach( + ([av_var, av_cat]) => { + const av_match = av_categories.find( + element => element.category_name == av_cat + ) + this.AVStore[av_var] = + av_match.authorised_values + } + ) + }) + ) + + return Promise.all(promises) + } + fetchConfig().then(() => { this.vendorStore.currencies = currencies this.vendorStore.gstValues = gstValues.map(gv => { @@ -103,6 +151,7 @@ export default { }) }, data() { + this.userPermissions = userPermissions return { initialized: true, } diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContracts.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContracts.vue index 068d7a549c8..cb991ec9687 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContracts.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorContracts.vue @@ -8,8 +8,15 @@ {{ $__("Description") }} {{ $__("Start date") }} {{ $__("End date") }} - - + {{ $__("Actions") }} @@ -29,8 +36,14 @@ {{ contract.contractenddate }} - - + diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorSubscriptions.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorSubscriptions.vue index a0b7650ea33..419f5adeda3 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorSubscriptions.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Vendors/VendorSubscriptions.vue @@ -3,24 +3,34 @@

{{ $__("Subscription details") }}

-

{{ $__("Number of subscriptions") }}: {{ vendor.subscriptions.length }} - {{ vendor.subscriptions.length }} + {{ vendor.subscriptions.length }}

diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts index 26e61adf75f..9424ae0b00c 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/modules/vendors.ts @@ -23,6 +23,7 @@ import { useMainStore } from "../stores/main"; import { useVendorStore } from "../stores/vendors"; import { useAVStore } from "../stores/authorised-values"; import { useNavigationStore } from "../stores/navigation"; +import { usePermissionsStore } from "../stores/permissions"; import i18n from "../i18n"; const pinia = createPinia(); @@ -30,6 +31,7 @@ const pinia = createPinia(); const mainStore = useMainStore(pinia); const AVStore = useAVStore(pinia); const navigationStore = useNavigationStore(pinia); +const permissionsStore = usePermissionsStore(pinia); const routes = navigationStore.setRoutes(routesDef); const router = createRouter({ @@ -52,6 +54,7 @@ app.provide("vendorStore", useVendorStore(pinia)); app.provide("mainStore", mainStore); app.provide("AVStore", AVStore); app.provide("navigationStore", navigationStore); +app.provide("permissionsStore", permissionsStore); app.mount("#__vendors"); diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js index 8a2908e57cb..bfaffca3fdc 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/routes/vendors.js @@ -11,7 +11,7 @@ export const routes = [ path: "/cgi-bin/koha/acqui/booksellers.pl", is_default: true, is_base: true, - title: $__("Vendors"), + title: $__("Vendor management"), children: [ { path: "", @@ -21,8 +21,8 @@ export const routes = [ }, { path: "/cgi-bin/koha/vendors", - title: $__("Vendor list"), - icon: "fa fa-check-circle", + title: $__("Vendors"), + icon: "fa fa-shopping-cart", is_end_node: true, children: [ { diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/stores/permissions.js b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/permissions.js new file mode 100644 index 00000000000..1dfc1af7cf2 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/stores/permissions.js @@ -0,0 +1,21 @@ +import { defineStore } from "pinia"; + +export const usePermissionsStore = defineStore("permissions", { + state: () => ({ + userPermissions: null, + }), + actions: { + isUserPermitted(operation, permissions) { + const userPermissions = permissions + ? permissions + : this.userPermissions; + if (!operation) return true; + if (!userPermissions) return false; + + return ( + userPermissions.hasOwnProperty(operation) && + userPermissions[operation] + ); + }, + }, +}); -- 2.39.3 (Apple Git-146)