Bug 38010: Add permissions

This patch adds a permissions store and utility methods for implementing permissions checks in a Vue app

Signed-off-by: Michaela Sieber <michaela.sieber@kit.edu>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Matt Blenkinsop 2024-09-12 11:16:59 +00:00 committed by Katrin Fischer
parent 0cc42d91d6
commit 28f772b1e3
No known key found for this signature in database
GPG Key ID: 0EF6E2C03357A834
6 changed files with 98 additions and 12 deletions

View File

@ -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 );

View File

@ -14,7 +14,7 @@
</div>
<div class="col-md-2 order-sm-2 order-md-1">
<LeftMenu :title="$__('Vendors')"></LeftMenu>
<LeftMenu :title="$__('Vendor management')"></LeftMenu>
</div>
</div>
</div>
@ -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,
};

View File

@ -8,8 +8,15 @@
<th scope="col">{{ $__("Description") }}</th>
<th scope="col">{{ $__("Start date") }}</th>
<th scope="col">{{ $__("End date") }}</th>
<!-- PERMISSION CAN_user_acquisition_contracts_manage -->
<th v-if="false" scope="col" class="NoSort noExport">
<th
v-if="
isUserPermitted(
'CAN_user_acquisition_contracts_manage'
)
"
scope="col"
class="NoSort noExport"
>
{{ $__("Actions") }}
</th>
</tr>
@ -29,8 +36,14 @@
<td :data-order="contract.contractenddate">
{{ contract.contractenddate }}
</td>
<!-- PERMISSION CAN_user_acquisition_contracts_manage -->
<td class="actions" v-if="false">
<td
class="actions"
v-if="
isUserPermitted(
'CAN_user_acquisition_contracts_manage'
)
"
>
<a
class="btn btn-default btn-xs"
:href="`/cgi-bin/koha/admin/aqcontract.pl?op=add_form&contractnumber=${contract.contractnumber}&booksellerid=${contract.booksellerid}`"
@ -54,10 +67,21 @@
</template>
<script>
import { inject } from "vue";
export default {
props: {
vendor: Object,
},
setup() {
const permissionsStore = inject("permissionsStore");
const { isUserPermitted } = permissionsStore;
return {
isUserPermitted,
};
},
};
</script>

View File

@ -3,24 +3,34 @@
<h2>
{{ $__("Subscription details") }}
</h2>
<!-- PERMISSION -->
<p>
<strong>{{ $__("Number of subscriptions") }}: </strong>
<a
v-if="false"
v-if="isUserPermitted('CAN_user_serials')"
:href="`/cgi-bin/koha/serials/serials-search.pl?bookseller_filter=${vendor.name}&searched=1`"
>{{ vendor.subscriptions.length }}</a
>
<span v-if="true">{{ vendor.subscriptions.length }}</span>
<span v-else>{{ vendor.subscriptions.length }}</span>
</p>
</fieldset>
</template>
<script>
import { inject } from "vue";
export default {
props: {
vendor: Object,
},
setup() {
const permissionsStore = inject("permissionsStore");
const { isUserPermitted } = permissionsStore;
return {
isUserPermitted,
};
},
};
</script>

View File

@ -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");

View File

@ -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: [
{