diff --git a/backend/src/api/guilds.ts b/backend/src/api/guilds.ts index c902943c..bb1f5c4a 100644 --- a/backend/src/api/guilds.ts +++ b/backend/src/api/guilds.ts @@ -7,6 +7,9 @@ import yaml, { YAMLException } from "js-yaml"; import { apiTokenAuthHandlers } from "./auth"; import { ApiPermissions } from "@shared/apiPermissions"; import { hasGuildPermission, requireGuildPermission } from "./permissions"; +import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; + +const apiPermissionAssignments = new ApiPermissionAssignments(); export function initGuildsAPI(app: express.Express) { const allowedGuilds = new AllowedGuilds(); @@ -82,5 +85,14 @@ export function initGuildsAPI(app: express.Express) { ok(res); }); + guildRouter.get( + "/:guildId/permissions", + requireGuildPermission(ApiPermissions.ManageAccess), + async (req: Request, res: Response) => { + const permissions = await apiPermissionAssignments.getByGuildId(req.params.guildId); + res.json(permissions); + }, + ); + app.use("/guilds", guildRouter); } diff --git a/backend/src/data/ApiPermissionAssignments.ts b/backend/src/data/ApiPermissionAssignments.ts index 05e5d1ba..3699ee06 100644 --- a/backend/src/data/ApiPermissionAssignments.ts +++ b/backend/src/data/ApiPermissionAssignments.ts @@ -15,6 +15,14 @@ export class ApiPermissionAssignments extends BaseRepository { this.apiPermissions = getRepository(ApiPermissionAssignment); } + getByGuildId(guildId) { + return this.apiPermissions.find({ + where: { + guild_id: guildId, + }, + }); + } + getByUserId(userId) { return this.apiPermissions.find({ where: { diff --git a/dashboard/src/components/dashboard/GuildAccess.vue b/dashboard/src/components/dashboard/GuildAccess.vue index 72e5bbe7..8ea9b3da 100644 --- a/dashboard/src/components/dashboard/GuildAccess.vue +++ b/dashboard/src/components/dashboard/GuildAccess.vue @@ -4,7 +4,10 @@

Or here

- +
+ {{ permAssignment.type }} {{ permAssignment.target_id }} + +
@@ -12,27 +15,65 @@ import { ApiPermissions, permissionHierarchy } from "@shared/apiPermissions"; import PermissionTree from "./PermissionTree.vue"; import { applyStateToPermissionHierarchy } from "./permissionTreeUtils"; + import { mapState } from "vuex"; + import { GuildState } from "../../store/types"; export default { components: {PermissionTree}, data() { return { - tree: [], - grantedPermissions: new Set([ApiPermissions.EditConfig]), - managerPermissions: new Set([ApiPermissions.ManageAccess]) + managerPermissions: new Set([ApiPermissions.ManageAccess]), }; }, - beforeMount() { - this.tree = applyStateToPermissionHierarchy(permissionHierarchy, this.grantedPermissions, this.managerPermissions); + computed: { + ...mapState("guilds", { + canManage(guilds) { + return guilds.myPermissions[this.$route.params.guildId]?.[ApiPermissions.ManageAccess]; + }, + + permissionAssignments(guilds) { + return (guilds.guildPermissionAssignments[this.$route.params.guildId] || []).map(permAssignment => { + return { + ...permAssignment, + _permissionTree: applyStateToPermissionHierarchy(permissionHierarchy, permAssignment.permissions, this.managerPermissions), + }; + }); + }, + }), + }, + // beforeMount() { + // this.tree = applyStateToPermissionHierarchy(permissionHierarchy, this.grantedPermissions, this.managerPermissions); + // }, + async mounted() { + await this.$store.dispatch("guilds/checkPermission", { + guildId: this.$route.params.guildId, + permission: ApiPermissions.ManageAccess, + }); + + if (! this.canManage) { + this.$router.push('/dashboard'); + return; + } + + await this.$store.dispatch("guilds/loadGuildPermissionAssignments", this.$route.params.guildId); }, methods: { - updateTreeState() { - this.tree = applyStateToPermissionHierarchy(permissionHierarchy, this.grantedPermissions, this.managerPermissions); - }, + // updateTreeState() { + // this.tree = applyStateToPermissionHierarchy(permissionHierarchy, this.grantedPermissions, this.managerPermissions); + // }, + // + // onChange() { + // this.updateTreeState(); + // } - onChange() { - console.log('changed!', this.grantedPermissions); - this.updateTreeState(); + onTreeUpdate(targetPermissions) { + console.log('hi'); + this.$store.dispatch("guilds/setTargetPermissions", { + guildId: this.$route.params.guildId, + targetId: targetPermissions.target_id, + type: targetPermissions.type, + permissions: targetPermissions.permissions, + }); } } } diff --git a/dashboard/src/components/dashboard/GuildConfigEditor.vue b/dashboard/src/components/dashboard/GuildConfigEditor.vue index 596b7e81..69b35058 100644 --- a/dashboard/src/components/dashboard/GuildConfigEditor.vue +++ b/dashboard/src/components/dashboard/GuildConfigEditor.vue @@ -74,12 +74,12 @@ }; }, computed: { - ...mapState('guilds', { - guild() { - return this.$store.state.guilds.available.get(this.$route.params.guildId); + ...mapState("guilds", { + guild(guilds) { + return guilds.available.get(this.$route.params.guildId); }, - config() { - return this.$store.state.guilds.configs[this.$route.params.guildId]; + config(guilds) { + return guilds.configs[this.$route.params.guildId]; }, }), }, diff --git a/dashboard/src/store/guilds.ts b/dashboard/src/store/guilds.ts index 62e7ff62..ce9306dc 100644 --- a/dashboard/src/store/guilds.ts +++ b/dashboard/src/store/guilds.ts @@ -1,6 +1,8 @@ import { get, post } from "../api"; import { Module } from "vuex"; import { GuildState, LoadStatus, RootState } from "./types"; +import { ApiPermissions } from "@shared/apiPermissions"; +import Vue from "vue"; export const GuildStore: Module = { namespaced: true, @@ -9,6 +11,8 @@ export const GuildStore: Module = { availableGuildsLoadStatus: LoadStatus.None, available: new Map(), configs: {}, + myPermissions: {}, + guildPermissionAssignments: {}, }, actions: { @@ -43,6 +47,20 @@ export const GuildStore: Module = { async saveConfig({ commit }, { guildId, config }) { await post(`guilds/${guildId}/config`, { config }); }, + + async checkPermission({ commit }, { guildId, permission }) { + const result = await post(`guilds/${guildId}/check-permission`, { permission }); + commit("setMyPermission", { guildId, permission, value: result.result }); + }, + + async loadGuildPermissionAssignments({ commit }, guildId) { + const permissionAssignments = await get(`guilds/${guildId}/permissions`); + commit("setGuildPermissionAssignments", { guildId, permissionAssignments }); + }, + + async setTargetPermissions({ commit }, { guildId, targetId, type, permissions }) { + commit("setTargetPermissions", { guildId, targetId, type, permissions }); + }, }, mutations: { @@ -52,10 +70,36 @@ export const GuildStore: Module = { addGuild(state: GuildState, guild) { state.available.set(guild.id, guild); + state.available = state.available; }, setConfig(state: GuildState, { guildId, config }) { - state.configs[guildId] = config; + Vue.set(state.configs, guildId, config); + }, + + setMyPermission(state: GuildState, { guildId, permission, value }) { + Vue.set(state.myPermissions, guildId, state.myPermissions[guildId] || {}); + Vue.set(state.myPermissions[guildId], permission, value); + }, + + setGuildPermissionAssignments(state: GuildState, { guildId, permissionAssignments }) { + Vue.set( + state.guildPermissionAssignments, + guildId, + permissionAssignments.map(p => ({ + ...p, + permissions: new Set(p.permissions), + })), + ); + }, + + setTargetPermissions(state: GuildState, { guildId, targetId, type, permissions }) { + const guildPermissionAssignments = state.guildPermissionAssignments[guildId] || []; + const itemToEdit = guildPermissionAssignments.find(p => p.target_id === targetId && p.type === type); + if (!itemToEdit) return; + + itemToEdit.permissions = permissions; + state.guildPermissionAssignments = { ...state.guildPermissionAssignments }; }, }, }; diff --git a/dashboard/src/store/types.ts b/dashboard/src/store/types.ts index 26ad52cc..3cab32bc 100644 --- a/dashboard/src/store/types.ts +++ b/dashboard/src/store/types.ts @@ -1,3 +1,6 @@ +import { ApiPermissions } from "@shared/apiPermissions"; +import { ApiPermissionTypes } from "../../../backend/src/data/ApiPermissionAssignments"; + export enum LoadStatus { None = 1, Loading, @@ -22,6 +25,18 @@ export interface GuildState { configs: { [key: string]: string; }; + myPermissions: { + [guildId: string]: { + [K in ApiPermissions]?: boolean; + }; + }; + guildPermissionAssignments: { + [guildId: string]: Array<{ + target_id: string; + type: ApiPermissionTypes; + permissions: Set; + }>; + }; } export interface StaffState {