enhance: permission handling

This commit is contained in:
Julian Krauser 2025-05-07 09:05:25 +02:00
parent c17355fcd1
commit b4fdd5fc60
3 changed files with 46 additions and 24 deletions

View file

@ -18,22 +18,22 @@
<div class="flex flex-row border border-white rounded-md overflow-hidden"> <div class="flex flex-row border border-white rounded-md overflow-hidden">
<EyeIcon <EyeIcon
class="w-5 h-5 p-1 box-content cursor-pointer" class="w-5 h-5 p-1 box-content cursor-pointer"
:class="_can(permissionUpdate, 'read', section) ? 'bg-success' : ''" :class="_canSection(permissionUpdate, 'read', section) ? 'bg-success' : ''"
@click="togglePermission('read', section)" @click="togglePermission('read', section)"
/> />
<PlusIcon <PlusIcon
class="w-5 h-5 p-1 box-content cursor-pointer" class="w-5 h-5 p-1 box-content cursor-pointer"
:class="_can(permissionUpdate, 'create', section) ? 'bg-success' : ''" :class="_canSection(permissionUpdate, 'create', section) ? 'bg-success' : ''"
@click="togglePermission('create', section)" @click="togglePermission('create', section)"
/> />
<PencilIcon <PencilIcon
class="w-5 h-5 p-1 box-content cursor-pointer" class="w-5 h-5 p-1 box-content cursor-pointer"
:class="_can(permissionUpdate, 'update', section) ? 'bg-success' : ''" :class="_canSection(permissionUpdate, 'update', section) ? 'bg-success' : ''"
@click="togglePermission('update', section)" @click="togglePermission('update', section)"
/> />
<TrashIcon <TrashIcon
class="w-5 h-5 p-1 box-content cursor-pointer" class="w-5 h-5 p-1 box-content cursor-pointer"
:class="_can(permissionUpdate, 'delete', section) ? 'bg-success' : ''" :class="_canSection(permissionUpdate, 'delete', section) ? 'bg-success' : ''"
@click="togglePermission('delete', section)" @click="togglePermission('delete', section)"
/> />
</div> </div>
@ -132,7 +132,7 @@ export default defineComponent({
}; };
}, },
computed: { computed: {
...mapState(useAbilityStore, ["_can"]), ...mapState(useAbilityStore, ["_can", "_canSection"]),
canSaveOrReset(): boolean { canSaveOrReset(): boolean {
return isEqual(this.permissions, this.permissionUpdate); return isEqual(this.permissions, this.permissionUpdate);
}, },

View file

@ -11,21 +11,18 @@ export const useAbilityStore = defineStore("ability", {
getters: { getters: {
can: can:
(state) => (state) =>
(type: PermissionType | "admin", section: PermissionSection, module?: PermissionModule): boolean => { (type: PermissionType | "admin", section: PermissionSection, module: PermissionModule): boolean => {
const permissions = state.permissions; const permissions = state.permissions;
if (state.isOwner) return true; if (state.isOwner) return true;
if (type == "admin") return permissions?.admin ?? false; if (type == "admin") return permissions?.admin ?? permissions?.adminByOwner ?? false;
if (permissions?.admin) return true; if (permissions?.admin || permissions?.adminByOwner) return true;
if ( if (
(!module &&
permissions[section] != undefined &&
(permissions[section]?.all == "*" || permissions[section]?.all?.includes(type))) ||
permissions[section]?.all == "*" || permissions[section]?.all == "*" ||
permissions[section]?.all?.includes(type) permissions[section]?.all?.includes(type) ||
permissions[section]?.[module] == "*" ||
permissions[section]?.[module]?.includes(type)
) )
return true; return true;
if (module && (permissions[section]?.[module] == "*" || permissions[section]?.[module]?.includes(type)))
return true;
return false; return false;
}, },
canSection: canSection:
@ -33,8 +30,8 @@ export const useAbilityStore = defineStore("ability", {
(type: PermissionType | "admin", section: PermissionSection): boolean => { (type: PermissionType | "admin", section: PermissionSection): boolean => {
const permissions = state.permissions; const permissions = state.permissions;
if (state.isOwner) return true; if (state.isOwner) return true;
if (type == "admin") return permissions?.admin ?? false; if (type == "admin") return permissions?.admin ?? permissions?.adminByOwner ?? false;
if (permissions?.admin) return true; if (permissions?.admin || permissions?.adminByOwner) return true;
if ( if (
permissions[section]?.all == "*" || permissions[section]?.all == "*" ||
permissions[section]?.all?.includes(type) || permissions[section]?.all?.includes(type) ||
@ -54,20 +51,31 @@ export const useAbilityStore = defineStore("ability", {
permissions: PermissionObject, permissions: PermissionObject,
type: PermissionType | "admin", type: PermissionType | "admin",
section: PermissionSection, section: PermissionSection,
module?: PermissionModule module: PermissionModule
): boolean => { ): boolean => {
// ignores ownership // ignores ownership
if (type == "admin") return permissions?.admin ?? false; if (type == "admin") return permissions?.admin ?? permissions?.adminByOwner ?? false;
if (permissions?.admin) return true; if (permissions?.admin || permissions?.adminByOwner) return true;
if ( if (
(!module &&
permissions[section] != undefined &&
(permissions[section]?.all == "*" || permissions[section]?.all?.includes(type))) ||
permissions[section]?.all == "*" || permissions[section]?.all == "*" ||
permissions[section]?.all?.includes(type) permissions[section]?.all?.includes(type) ||
permissions[section]?.[module] == "*" ||
permissions[section]?.[module]?.includes(type)
) )
return true; return true;
if (module && (permissions[section]?.[module] == "*" || permissions[section]?.[module]?.includes(type))) return false;
},
_canSection:
() =>
(permissions: PermissionObject, type: PermissionType | "admin", section: PermissionSection): boolean => {
// ignores ownership
if (type == "admin") return permissions?.admin ?? permissions?.adminByOwner ?? false;
if (permissions?.admin || permissions?.adminByOwner) return true;
if (
permissions[section]?.all == "*" ||
permissions[section]?.all?.includes(type) ||
permissions[section] != undefined
)
return true; return true;
return false; return false;
}, },

View file

@ -31,6 +31,7 @@ export type PermissionString =
| `${PermissionSection}.${PermissionModule}.*` // für alle Berechtigungen in einem Modul | `${PermissionSection}.${PermissionModule}.*` // für alle Berechtigungen in einem Modul
| `${PermissionSection}.${PermissionType}` // für spezifische Berechtigungen in einem Abschnitt | `${PermissionSection}.${PermissionType}` // für spezifische Berechtigungen in einem Abschnitt
| `${PermissionSection}.*` // für alle Berechtigungen in einem Abschnitt | `${PermissionSection}.*` // für alle Berechtigungen in einem Abschnitt
| `additional.${string}.${string}` // additional
| "*"; // für Admin | "*"; // für Admin
export type PermissionObject = { export type PermissionObject = {
@ -39,10 +40,20 @@ export type PermissionObject = {
} & { all?: Array<PermissionType> | "*" }; } & { all?: Array<PermissionType> | "*" };
} & { } & {
admin?: boolean; admin?: boolean;
adminByOwner?: boolean;
} & {
additional?: { [key: string]: string };
}; };
export type SectionsAndModulesObject = { export type SectionsAndModulesObject = {
[section in PermissionSection]: Array<PermissionModule>; [section in PermissionSection]: Array<PermissionModule>;
} & {
additional?: Array<{
key: string;
name: string;
type: "number" | "string";
emptyIfAdmin: boolean;
}>;
}; };
export const permissionSections: Array<PermissionSection> = ["club", "configuration", "management"]; export const permissionSections: Array<PermissionSection> = ["club", "configuration", "management"];
@ -87,4 +98,7 @@ export const sectionsAndModules: SectionsAndModulesObject = {
"newsletter_config", "newsletter_config",
], ],
management: ["user", "role", "webapi", "backup", "setting"], management: ["user", "role", "webapi", "backup", "setting"],
additional: [
//{ key: "val", name: "name", type: "number", emptyIfAdmin: true },
],
}; };