Skip to content
Snippets Groups Projects
Commit cbe60a98 authored by Hangzhi Yu's avatar Hangzhi Yu
Browse files

Add permission checking system detached from menu generation

parent 6161df20
No related branches found
No related tags found
1 merge request!1249Resolve "Search bar in sidenav is sometimes mistakenly shown"
Pipeline #129186 canceled
......@@ -9,6 +9,11 @@ and this project adheres to `Semantic Versioning`_.
Unreleased
----------
Fixed
~~~~~
* The search bar in the sidenav menu is shown even though the user has no permission to see it.
`3.0`_ - 2022-05-11
-------------------
......
......@@ -10,7 +10,7 @@
<brand-logo :site-preferences="systemProperties.sitePreferences" />
</a>
</v-list-item>
<v-list-item class="search">
<v-list-item v-if="checkPermission('core.search_rule')" class="search">
<sidenav-search />
</v-list-item>
<v-list-item-group :value="$route.name" v-if="sideNavMenu">
......@@ -94,6 +94,8 @@ import BrandLogo from "./BrandLogo.vue";
import LanguageForm from "./LanguageForm.vue";
import SidenavSearch from "./SidenavSearch.vue";
import permissionsMixin from "../../mixins/permissions.js";
export default {
name: "SideNav",
components: {
......@@ -106,6 +108,10 @@ export default {
systemProperties: { type: Object, required: true },
value: { type: Boolean, required: true },
},
mixins: [permissionsMixin],
mounted() {
this.fetchPermissions(["core.search_rule"]);
},
};
</script>
......
query gqlPermissions($permissions: [String]!) {
whoAmI {
permissions: globalPermissionsByName(permissions: $permissions) {
name
result
}
}
}
query ($permissions: [String]!) {
query whoAmI {
whoAmI {
username
isAuthenticated
......@@ -12,9 +12,5 @@ query ($permissions: [String]!) {
avatarUrl
isDummy
}
permissions: globalPermissionsByName(permissions: $permissions) {
name
result
}
}
}
......@@ -70,6 +70,7 @@ const app = new Vue({
backgroundActive: true,
invalidation: false,
snackbarItems: [],
permissions: [],
}),
computed: {
matchedComponents() {
......
import gqlCustomMenu from "../components/app/customMenu.graphql";
import permissionsMixin from "./permissions.js";
/**
* Vue mixin containing menu generation code.
*
* Only used by main App component, but factored out for readability.
*/
const menusMixin = {
mixins: [permissionsMixin],
data() {
return {
footerMenu: null,
permissionNames: [],
sideNavMenu: null,
accountMenu: null,
};
......@@ -35,8 +37,7 @@ const menusMixin = {
}
}
this.permissionNames = permArray;
this.$apollo.queries.whoAmI.refetch();
this.fetchPermissions(permArray);
},
buildMenu(routes, menuKey) {
let menu = {};
......@@ -99,14 +100,6 @@ const menusMixin = {
return Object.values(menu);
},
checkPermission(permissionName) {
return (
this.whoAmI &&
this.whoAmI.permissions &&
this.whoAmI.permissions.find((p) => p.name === permissionName) &&
this.whoAmI.permissions.find((p) => p.name === permissionName).result
);
},
checkValidators(validators) {
for (const validator of validators) {
if (!validator(this.whoAmI)) {
......@@ -118,14 +111,9 @@ const menusMixin = {
buildMenus() {
this.accountMenu = this.buildMenu(
this.$router.getRoutes(),
"inAccountMenu",
this.whoAmI ? this.whoAmI.permissions : []
);
this.sideNavMenu = this.buildMenu(
this.$router.getRoutes(),
"inMenu",
this.whoAmI ? this.whoAmI.permissions : []
"inAccountMenu"
);
this.sideNavMenu = this.buildMenu(this.$router.getRoutes(), "inMenu");
},
},
apollo: {
......
import gqlPermissions from "../components/app/permissions.graphql";
/**
* Vue mixin containing permission checking code.
*/
const permissionsMixin = {
apollo: {
permissions: {
query: gqlPermissions,
update(data) {
this.$root.permissions = data.whoAmI.permissions;
},
variables: {
permissions: [],
},
},
},
methods: {
checkPermission(permissionName) {
return (
this.$root.permissions &&
this.$root.permissions.find((p) => p.name === permissionName) &&
this.$root.permissions.find((p) => p.name === permissionName).result
);
},
fetchPermissions(permissionNames) {
this.$apollo.queries.permissions.fetchMore({
variables: {
permissions: permissionNames,
},
updateQuery: (previousResult, { fetchMoreResult }) => {
const oldPermissions = previousResult.whoAmI.permissions;
const newPermissions = fetchMoreResult.whoAmI.permissions;
const keepPermissions = oldPermissions.filter(
(oldPermission) =>
!newPermissions.find(
(newPermission) => newPermission.name === oldPermission.name
)
);
return {
whoAmI: {
__typename: previousResult.whoAmI.__typename,
permissions: [...keepPermissions, ...newPermissions],
},
};
},
});
},
},
};
export default permissionsMixin;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment