UI: Add permission checks for people #98
This commit is contained in:
parent
39063d892d
commit
2f11587174
9 changed files with 54 additions and 13 deletions
|
@ -117,7 +117,7 @@ Vue.mixin({
|
||||||
hasPermission(resource, ...actions) {
|
hasPermission(resource, ...actions) {
|
||||||
if (this.$config.values.public) return true;
|
if (this.$config.values.public) return true;
|
||||||
const role = this.$session.getUser().getRole();
|
const role = this.$session.getUser().getRole();
|
||||||
return this.acl.accessAllowedAny(role, resource, actions);
|
return this.acl.accessAllowedAny(role, resource, ...actions);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -95,6 +95,8 @@ export default class Acl {
|
||||||
return act;
|
return act;
|
||||||
}
|
}
|
||||||
accessAllowedAny(role, resource, ...actions) {
|
accessAllowedAny(role, resource, ...actions) {
|
||||||
return actions.some((action) => this.accessAllowed(role, resource, action));
|
return actions.some((action) => {
|
||||||
|
return this.accessAllowed(role, resource, action);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,7 @@
|
||||||
</v-list-tile-content>
|
</v-list-tile-content>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
|
|
||||||
<v-list-tile v-show="$config.feature('people')" :to="{ name: 'people' }" class="nav-people" @click.stop="">
|
<v-list-tile v-show="$config.feature('people') && hasPermission(aclResources.ResourceSubjects, aclActions.ActionSearch, aclActions.ActionRead)" :to="{ name: 'people' }" class="nav-people" @click.stop="">
|
||||||
<v-list-tile-action :title="$gettext('People')">
|
<v-list-tile-action :title="$gettext('People')">
|
||||||
<v-icon>person</v-icon>
|
<v-icon>person</v-icon>
|
||||||
</v-list-tile-action>
|
</v-list-tile-action>
|
||||||
|
@ -273,7 +273,7 @@
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
</v-list-group>
|
</v-list-group>
|
||||||
|
|
||||||
<v-list-tile v-show="$config.feature('labels')" to="/labels" class="nav-labels" @click.stop="">
|
<v-list-tile v-show="$config.feature('labels') && hasPermission(aclResources.ResourceLabels, aclActions.ActionRead, aclActions.ActionSearch)" to="/labels" class="nav-labels" @click.stop="">
|
||||||
<v-list-tile-action :title="$gettext('Labels')">
|
<v-list-tile-action :title="$gettext('Labels')">
|
||||||
<v-icon>label</v-icon>
|
<v-icon>label</v-icon>
|
||||||
</v-list-tile-action>
|
</v-list-tile-action>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
:transition="false"
|
:transition="false"
|
||||||
aspect-ratio="1"
|
aspect-ratio="1"
|
||||||
class="accent lighten-2">
|
class="accent lighten-2">
|
||||||
<v-btn v-if="!marker.SubjUID && !marker.Invalid" :ripple="false" :depressed="false" class="input-reject"
|
<v-btn v-if="!marker.SubjUID && !marker.Invalid && hasPermission(aclResources.ResourceFiles, aclActions.ActionUpdate)" :ripple="false" :depressed="false" class="input-reject"
|
||||||
icon flat small absolute :title="$gettext('Remove')"
|
icon flat small absolute :title="$gettext('Remove')"
|
||||||
@click.stop.prevent="onReject(marker)">
|
@click.stop.prevent="onReject(marker)">
|
||||||
<v-icon color="white" class="action-reject">clear</v-icon>
|
<v-icon color="white" class="action-reject">clear</v-icon>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model="marker.Name"
|
v-model="marker.Name"
|
||||||
:rules="[textRule]"
|
:rules="[textRule]"
|
||||||
:disabled="busy"
|
:disabled="busy || !hasPermission(aclResources.ResourceFiles, aclActions.ActionUpdate)"
|
||||||
:readonly="true"
|
:readonly="true"
|
||||||
browser-autocomplete="off"
|
browser-autocomplete="off"
|
||||||
class="input-name pa-0 ma-0"
|
class="input-name pa-0 ma-0"
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
:items="$config.values.people"
|
:items="$config.values.people"
|
||||||
item-value="Name"
|
item-value="Name"
|
||||||
item-text="Name"
|
item-text="Name"
|
||||||
:disabled="busy"
|
:disabled="busy || !hasPermission(aclResources.ResourceFiles, aclActions.ActionUpdate)"
|
||||||
:return-object="false"
|
:return-object="false"
|
||||||
:menu-props="menuProps"
|
:menu-props="menuProps"
|
||||||
:allow-overflow="false"
|
:allow-overflow="false"
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
slider-color="secondary-dark"
|
slider-color="secondary-dark"
|
||||||
:height="$vuetify.breakpoint.smAndDown ? 48 : 64"
|
:height="$vuetify.breakpoint.smAndDown ? 48 : 64"
|
||||||
>
|
>
|
||||||
<v-tab v-for="(item, index) in tabs" :id="'tab-' + item.name" :key="index" :class="item.class"
|
<v-tab v-for="(item, index) in permittedTabs" :id="'tab-' + item.name" :key="index" :class="item.class"
|
||||||
ripple @click.stop.prevent="changePath(item.path)">
|
ripple @click.stop.prevent="changePath(item.path)">
|
||||||
<v-icon v-if="$vuetify.breakpoint.smAndDown" :title="item.label">{{ item.icon }}</v-icon>
|
<v-icon v-if="$vuetify.breakpoint.smAndDown" :title="item.label">{{ item.icon }}</v-icon>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
</v-tab>
|
</v-tab>
|
||||||
|
|
||||||
<v-tabs-items touchless>
|
<v-tabs-items touchless>
|
||||||
<v-tab-item v-for="(item, index) in tabs" :key="index" lazy>
|
<v-tab-item v-for="(item, index) in permittedTabs" :key="index" lazy>
|
||||||
<component :is="item.component" :static-filter="item.filter" :active="active === index"
|
<component :is="item.component" :static-filter="item.filter" :active="active === index"
|
||||||
@updateFaceCount="onUpdateFaceCount"></component>
|
@updateFaceCount="onUpdateFaceCount"></component>
|
||||||
</v-tab-item>
|
</v-tab-item>
|
||||||
|
@ -53,6 +53,9 @@ export default {
|
||||||
'class': '',
|
'class': '',
|
||||||
'path': '/people',
|
'path': '/people',
|
||||||
'icon': 'people_alt',
|
'icon': 'people_alt',
|
||||||
|
'permission': () => {
|
||||||
|
return this.hasPermission(this.aclResources.ResourceSubjects, this.aclActions.ActionRead, this.aclActions.ActionSearch);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'people_faces',
|
'name': 'people_faces',
|
||||||
|
@ -63,6 +66,9 @@ export default {
|
||||||
'path': '/people/new',
|
'path': '/people/new',
|
||||||
'icon': 'person_add',
|
'icon': 'person_add',
|
||||||
'count': 0,
|
'count': 0,
|
||||||
|
'permission': () => {
|
||||||
|
return this.hasPermission(this.aclResources.ResourceSubjects, this.aclActions.ActionUpdate);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -76,6 +82,14 @@ export default {
|
||||||
rtl: this.$rtl,
|
rtl: this.$rtl,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
permittedTabs() {
|
||||||
|
if (!this.tabs) return this.tabs;
|
||||||
|
return this.tabs.filter(tab => {
|
||||||
|
return tab.permission();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route'() {
|
'$route'() {
|
||||||
this.openTab();
|
this.openTab();
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
<v-layout v-if="model.SubjUID" row wrap align-center>
|
<v-layout v-if="model.SubjUID" row wrap align-center>
|
||||||
<v-flex xs12 class="text-xs-left pa-0">
|
<v-flex xs12 class="text-xs-left pa-0">
|
||||||
<v-text-field
|
<v-text-field
|
||||||
|
v-if="hasPermission(aclResources.ResourceSubjects, aclActions.ActionUpdate)"
|
||||||
v-model="model.Name"
|
v-model="model.Name"
|
||||||
:rules="[textRule]"
|
:rules="[textRule]"
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
|
|
|
@ -129,7 +129,7 @@
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<v-icon>edit</v-icon>
|
<v-icon>edit</v-icon>
|
||||||
</span>
|
</span>
|
||||||
<template #input>
|
<template v-if="hasPermission(aclResources.ResourceSubjects, aclActions.ActionUpdate)" #input>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model="model.Name"
|
v-model="model.Name"
|
||||||
:rules="[titleRule]"
|
:rules="[titleRule]"
|
||||||
|
|
|
@ -61,7 +61,7 @@ const hasPermission = (resource, ...actions) => {
|
||||||
// const acl = new Acl(window.__CONFIG__.acl);
|
// const acl = new Acl(window.__CONFIG__.acl);
|
||||||
const acl = new Acl(config.values.acl);
|
const acl = new Acl(config.values.acl);
|
||||||
const role = session.getUser().getRole();
|
const role = session.getUser().getRole();
|
||||||
return acl.accessAllowedAny(role, resource, actions);
|
return acl.accessAllowedAny(role, resource, ...actions);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
|
@ -328,15 +328,28 @@ export default [
|
||||||
component: People,
|
component: People,
|
||||||
meta: { title: $gettext("People"), auth: true, background: "application-light" },
|
meta: { title: $gettext("People"), auth: true, background: "application-light" },
|
||||||
beforeEnter: (to, from, next) => {
|
beforeEnter: (to, from, next) => {
|
||||||
|
const nextGuarded = () => {
|
||||||
|
if (
|
||||||
|
hasPermission(
|
||||||
|
aclResources.ResourceSubjects,
|
||||||
|
aclActions.ActionRead,
|
||||||
|
aclActions.ActionSearch
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
next({ name: "home" });
|
||||||
|
}
|
||||||
|
};
|
||||||
if (!config || !from || !from.name || from.name.startsWith("people")) {
|
if (!config || !from || !from.name || from.name.startsWith("people")) {
|
||||||
next();
|
nextGuarded();
|
||||||
} else {
|
} else {
|
||||||
config.load().finally(() => {
|
config.load().finally(() => {
|
||||||
// Open new faces tab when there are no people.
|
// Open new faces tab when there are no people.
|
||||||
if (config.values.count.people === 0) {
|
if (config.values.count.people === 0) {
|
||||||
next({ name: "people_faces" });
|
next({ name: "people_faces" });
|
||||||
} else {
|
} else {
|
||||||
next();
|
nextGuarded();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -347,6 +360,13 @@ export default [
|
||||||
path: "/people/new",
|
path: "/people/new",
|
||||||
component: People,
|
component: People,
|
||||||
meta: { title: $gettext("People"), auth: true, background: "application-light" },
|
meta: { title: $gettext("People"), auth: true, background: "application-light" },
|
||||||
|
beforeEnter: (to, from, next) => {
|
||||||
|
if (hasPermission(aclResources.ResourceSubjects, aclActions.ActionUpdate)) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
next({ name: "people" });
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "library",
|
name: "library",
|
||||||
|
|
|
@ -51,4 +51,8 @@ var Permissions = ACL{
|
||||||
RoleAdmin: Actions{ActionDefault: true},
|
RoleAdmin: Actions{ActionDefault: true},
|
||||||
RoleMember: Actions{ActionSearch: true, ActionRead: true},
|
RoleMember: Actions{ActionSearch: true, ActionRead: true},
|
||||||
},
|
},
|
||||||
|
ResourceFiles: Roles{
|
||||||
|
RoleAdmin: Actions{ActionDefault: true},
|
||||||
|
RoleMember: Actions{ActionSearch: true, ActionRead: true},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue