Bug 10190: fix permissions
- add a config API endpoint to Circulations Triggers so permissions can be fetched - update the permissions in the Vue App so that manage_circ_rules is required - update the permissions in the Circulation Rules API so that manage_circ_rules is required for PUT operations - update the circulation-rules store to so that it is compatible with recently intorduced compostables - implement a redirect into the route so that permission requirements are honoured Signed-off-by: Michaela <michaela.sieber@kit.edu> Signed-off-by: Nick Clemens <nick@bywatersolutions.com> Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
839bc81e80
commit
cf8230cdda
|
|
@ -316,4 +316,25 @@ sub _all_kinds {
|
|||
return \@all_valid_kinds;
|
||||
}
|
||||
|
||||
=head3 config
|
||||
|
||||
Return the configuration options needed for the Circulations Triggers Vue app
|
||||
|
||||
=cut
|
||||
|
||||
sub config {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $patron = $c->stash('koha.user');
|
||||
my $userflags = C4::Auth::haspermission( $patron->userid );
|
||||
my $permissions = Koha::Auth::Permissions->get_authz_from_flags( { flags => $userflags } );
|
||||
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => {
|
||||
permissions => $permissions,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
type: object
|
||||
properties:
|
||||
permissions:
|
||||
type: object
|
||||
description: List of permissions for the user
|
||||
additionalProperties: false
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
/circulation_rules/config:
|
||||
get:
|
||||
x-mojo-to: CirculationRules#config
|
||||
operationId: getCirculationRulesConfig
|
||||
description: This resource returns a list of options needed for the Circulation Triggers Vue app
|
||||
summary: get the CirculationRules config
|
||||
tags:
|
||||
- circulation_rules_config
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
200:
|
||||
description: The Circulation Rules config
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/circulation_rules_config"
|
||||
400:
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
403:
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
500:
|
||||
description: |
|
||||
Internal server error. Possible `error_code` attribute values:
|
||||
|
||||
* `internal_server_error`
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
503:
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
- acquisition: '*'
|
||||
- erm: 1
|
||||
|
|
@ -18,6 +18,8 @@ definitions:
|
|||
$ref: ./definitions/authorised_value_category.yaml
|
||||
circulation_rules:
|
||||
$ref: ./definitions/circulation_rules.yaml
|
||||
circulation_rules_config:
|
||||
$ref: ./definitions/circulation_rules_config.yaml
|
||||
identity_provider:
|
||||
$ref: ./definitions/identity_provider.yaml
|
||||
identity_provider_domain:
|
||||
|
|
@ -355,6 +357,8 @@ paths:
|
|||
$ref: ./paths/circulation_rules.yaml#/~1circulation_rules
|
||||
/circulation_rules/kinds:
|
||||
$ref: ./paths/circulation_rules.yaml#/~1circulation_rules~1kinds
|
||||
/circulation_rules/config:
|
||||
$ref: ./paths/circulation_rules_config.yaml#/~1circulation_rules~1config
|
||||
/cities:
|
||||
$ref: ./paths/cities.yaml#/~1cities
|
||||
"/cities/{city_id}":
|
||||
|
|
@ -1340,6 +1344,9 @@ tags:
|
|||
- description: "Manage circulation rules\n"
|
||||
name: circulation_rules
|
||||
x-displayName: Circulation rules
|
||||
- description: "Retrieve configuration relevant to circulation rules\n"
|
||||
name: circulation_rules_config
|
||||
x-displayName: Circulation rules config
|
||||
- description: "Manage cities\n"
|
||||
name: cities
|
||||
x-displayName: Cities
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@
|
|||
<dt><a href="/cgi-bin/koha/admin/smart-rules.pl">Circulation and fine rules</a></dt>
|
||||
<dd>Define circulation and fine rules for combinations of libraries, patron categories, and item types</dd>
|
||||
[% END %]
|
||||
[% IF ( CAN_user_tools_edit_notice_status_triggers ) %]
|
||||
[% IF ( CAN_user_parameters_manage_circ_rules ) %]
|
||||
<dt><a href="/cgi-bin/koha/admin/circulation_triggers">Circulation triggers</a></dt>
|
||||
<dd>Define triggers for circulation notices</dd>
|
||||
[% END %]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,15 @@ export class CircRuleAPIClient {
|
|||
});
|
||||
}
|
||||
|
||||
get config() {
|
||||
return {
|
||||
getAll: () =>
|
||||
this.httpClient.get({
|
||||
endpoint: "/config",
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
get circ_rules() {
|
||||
return {
|
||||
getAll: (query, params, headers) =>
|
||||
|
|
|
|||
|
|
@ -288,7 +288,6 @@ import { storeToRefs } from "pinia";
|
|||
export default {
|
||||
setup() {
|
||||
const circRulesStore = inject("circRulesStore");
|
||||
circRulesStore.init();
|
||||
const {
|
||||
updateTriggerCount,
|
||||
setAllRawRuleSets,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import { inject } from "vue";
|
|||
export default {
|
||||
setup() {
|
||||
const circRulesStore = inject("circRulesStore");
|
||||
circRulesStore.init();
|
||||
letters.unshift({
|
||||
name: "No letter",
|
||||
code: "",
|
||||
|
|
|
|||
|
|
@ -51,7 +51,31 @@ app.provide("navigationStore", navigationStore);
|
|||
app.provide("circRulesStore", circRulesStore);
|
||||
app.mount("#__app");
|
||||
|
||||
router.beforeEach(to => {
|
||||
navigationStore.$patch({ current: to.matched, params: to.params || {} });
|
||||
removeMessages(); // This will actually flag the messages as displayed already
|
||||
router.beforeEach((to, from, next) => {
|
||||
circRulesStore
|
||||
.loadUserPermissions()
|
||||
.then(() => {
|
||||
if (
|
||||
!circRulesStore.isUserPermitted(
|
||||
"CAN_user_parameters_manage_circ_rules"
|
||||
)
|
||||
) {
|
||||
navigationStore.$patch({
|
||||
navigationBlocked: true,
|
||||
currentPermission: null,
|
||||
});
|
||||
removeMessages(); // This will actually flag the messages as displayed already
|
||||
window.location.href = "/cgi-bin/koha/mainpage.pl";
|
||||
return;
|
||||
}
|
||||
navigationStore.$patch({
|
||||
current: to.matched,
|
||||
params: to.params || {},
|
||||
});
|
||||
removeMessages(); // This will actually flag the messages as displayed already
|
||||
next();
|
||||
})
|
||||
.catch(() => {
|
||||
window.location.href = "/cgi-bin/koha/mainpage.pl";
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,16 +2,19 @@ import { defineStore } from "pinia";
|
|||
import { $__ } from "../i18n";
|
||||
import { APIClient } from "../fetch/api-client.js";
|
||||
import { isEqual } from "lodash";
|
||||
import { permissionsActions } from "../composables/permissions";
|
||||
import { reactive, toRefs } from "vue";
|
||||
|
||||
export const useCircRulesStore = defineStore("circRules", {
|
||||
// NOTES ON RULE SETS TYPES
|
||||
// exhaustive: includes 'pure fallback' rules sets for contexts that no rules match.
|
||||
// Format: [{overdue_X_<rule_name>: {value: mixed: isFallback: bool}}]
|
||||
// effective: includes sets only for contexts for which one or more rule exists in the db. These sets will include fallbacks.
|
||||
// Format: [{overdue_X_<rule_name>: <value>}}
|
||||
// raw: includes only the exact sets as they are found in the db
|
||||
// Format: [{overdue_X_<rule_name>: <value>}}]
|
||||
state: () => ({
|
||||
// NOTES ON RULE SETS TYPES
|
||||
// exhaustive: includes 'pure fallback' rules sets for contexts that no rules match.
|
||||
// Format: [{overdue_X_<rule_name>: {value: mixed: isFallback: bool}}]
|
||||
// effective: includes sets only for contexts for which one or more rule exists in the db. These sets will include fallbacks.
|
||||
// Format: [{overdue_X_<rule_name>: <value>}}
|
||||
// raw: includes only the exact sets as they are found in the db
|
||||
// Format: [{overdue_X_<rule_name>: <value>}}]
|
||||
|
||||
export const useCircRulesStore = defineStore("circRules", () => {
|
||||
const store = reactive({
|
||||
// context
|
||||
currentLibraryId: "*",
|
||||
currentPatronCategoryId: null,
|
||||
|
|
@ -21,6 +24,7 @@ export const useCircRulesStore = defineStore("circRules", {
|
|||
itemTypes: [],
|
||||
libraries: [],
|
||||
patronCategories: [],
|
||||
userPermissions: null,
|
||||
letters: [],
|
||||
ruleSuffixes: ["delay", "notice", "mtt", "restrict", "has_rules"],
|
||||
transportTypes: [
|
||||
|
|
@ -36,14 +40,21 @@ export const useCircRulesStore = defineStore("circRules", {
|
|||
allExhaustiveEffectiveRuleSets: [], // main data set for display all applied rules for current library
|
||||
currentAndDefaultRawRuleSets: [], // data set to identify effective rules from (combines allDefaultLibraryRawRuleSets and allCurrentLibraryRawRuleSets)
|
||||
storeInitialized: false,
|
||||
}),
|
||||
actions: {
|
||||
});
|
||||
|
||||
const actions = {
|
||||
// controllers
|
||||
async init() {
|
||||
await this.getItemTypes();
|
||||
await this.getLibraries();
|
||||
await this.getPatronCategories();
|
||||
},
|
||||
async loadUserPermissions() {
|
||||
if (this.userPermissions !== null) {
|
||||
return;
|
||||
}
|
||||
await this.getConfigurationOptions();
|
||||
},
|
||||
// utilities
|
||||
formatTriggerSpecificRuleSetForDisplay(
|
||||
context,
|
||||
|
|
@ -403,6 +414,11 @@ export const useCircRulesStore = defineStore("circRules", {
|
|||
throw e;
|
||||
}
|
||||
},
|
||||
async getConfigurationOptions() {
|
||||
const client = APIClient.circRule;
|
||||
const { permissions } = await client.config.getAll();
|
||||
this.userPermissions = permissions;
|
||||
},
|
||||
async getItemTypes() {
|
||||
const client = APIClient.item;
|
||||
let itemTypes = [];
|
||||
|
|
@ -485,5 +501,11 @@ export const useCircRulesStore = defineStore("circRules", {
|
|||
//TODO: handle e
|
||||
}
|
||||
},
|
||||
},
|
||||
...permissionsActions(store),
|
||||
};
|
||||
|
||||
return {
|
||||
...toRefs(store),
|
||||
...actions,
|
||||
};
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue