3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 12:25:02 +00:00

More work on API permissions

This commit is contained in:
Dragory 2019-11-08 00:04:24 +02:00
parent 79b0adf81a
commit c9a21c64bf
14 changed files with 318 additions and 85 deletions

View file

@ -4,5 +4,36 @@
<p>
<img class="inline-block w-16 mr-4" style="vertical-align: -20px" src="../../img/squint.png"> Or here
</p>
<permission-tree :tree="tree" :granted-permissions="grantedPermissions" :on-change="onChange" />
</div>
</template>
<script lang="ts">
import { ApiPermissions, permissionHierarchy } from "@shared/apiPermissions";
import PermissionTree from "./PermissionTree.vue";
import { applyStateToPermissionHierarchy } from "./permissionTreeUtils";
export default {
components: {PermissionTree},
data() {
return {
tree: [],
grantedPermissions: new Set([ApiPermissions.EditConfig]),
managerPermissions: new Set([ApiPermissions.ManageAccess])
};
},
beforeMount() {
this.tree = applyStateToPermissionHierarchy(permissionHierarchy, this.grantedPermissions, this.managerPermissions);
},
methods: {
updateTreeState() {
this.tree = applyStateToPermissionHierarchy(permissionHierarchy, this.grantedPermissions, this.managerPermissions);
},
onChange() {
console.log('changed!', this.grantedPermissions);
this.updateTreeState();
}
}
}
</script>

View file

@ -0,0 +1,62 @@
<template>
<ul class="nostyles">
<li v-for="[permission, treeState, subTree] in tree" :class="{locked: treeState.locked}">
<label>
<input type="checkbox"
:checked="grantedPermissions.has(permission) || treeState.redundant"
v-on:input="togglePermission(permission)"
:disabled="treeState.locked || treeState.redundant">
<span>{{ permissionNames[permission] }}</span>
</label>
<permission-tree v-if="subTree && subTree.length"
:tree="subTree"
:granted-permissions="grantedPermissions"
:on-change="onChange" />
</li>
</ul>
</template>
<style scoped>
ul {
list-style: none;
& ul {
padding-left: 16px;
}
}
.locked > label {
opacity: 0.5;
}
</style>
<script lang="ts">
import { ApiPermissions, permissionNames } from "@shared/apiPermissions";
import { PropType } from "vue";
import { TPermissionHierarchyWithState } from "./permissionTreeUtils";
export default {
name: 'permission-tree',
props: {
tree: Array as PropType<TPermissionHierarchyWithState>,
grantedPermissions: Set as PropType<Set<ApiPermissions>>,
onChange: Function
},
data() {
return { permissionNames };
},
methods: {
togglePermission(permission) {
if (this.grantedPermissions.has(permission)) {
this.grantedPermissions.delete(permission);
} else {
this.grantedPermissions.add(permission);
}
if (this.onChange) {
this.onChange();
}
},
},
}
</script>

View file

@ -0,0 +1,43 @@
import { ApiPermissions, hasPermission, TPermissionHierarchy } from "@shared/apiPermissions";
export type TPermissionHierarchyState = {
locked: boolean;
redundant: boolean;
};
export type TApiPermissionWithState = [ApiPermissions, TPermissionHierarchyState, TPermissionHierarchyWithState?];
export type TPermissionHierarchyWithState = TApiPermissionWithState[];
/**
* @param tree
* @param grantedPermissions Permissions granted to the user being edited
* @param managerPermissions Permissions granted to the user who's editing the other user's permissions
* @param entireTreeIsGranted
*/
export function applyStateToPermissionHierarchy(
tree: TPermissionHierarchy,
grantedPermissions: Set<ApiPermissions>,
managerPermissions: Set<ApiPermissions> = new Set(),
entireTreeIsGranted = false,
): TPermissionHierarchyWithState {
const result: TPermissionHierarchyWithState = [];
for (const item of tree) {
const [perm, nested] = Array.isArray(item) ? item : [item];
// Can't edit permissions you don't have yourself
const locked = !hasPermission(managerPermissions, perm);
const permissionWithState: TApiPermissionWithState = [perm, { locked, redundant: entireTreeIsGranted }];
if (nested) {
const subTreeGranted = entireTreeIsGranted || grantedPermissions.has(perm);
permissionWithState.push(
applyStateToPermissionHierarchy(nested, grantedPermissions, managerPermissions, subTreeGranted),
);
}
result.push(permissionWithState);
}
return result;
}