control RBAC from data section
This commit is contained in:
parent
1958143500
commit
37c00f24bd
|
@ -328,6 +328,30 @@ export const getBackendUiStore = () => {
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
permissions: {
|
||||||
|
fetch: async () => {
|
||||||
|
const response = await api.get("/api/permission")
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
},
|
||||||
|
fetchLevels: async () => {
|
||||||
|
const response = await api.get("/api/permission/levels")
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
},
|
||||||
|
forResource: async resourceId => {
|
||||||
|
const response = await api.get(`/api/permission/${resourceId}`)
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
},
|
||||||
|
save: async ({ role, resource, level }) => {
|
||||||
|
const response = await api.post(
|
||||||
|
`/api/permission/${role}/${resource}/${level}`
|
||||||
|
)
|
||||||
|
const json = await response.json()
|
||||||
|
return json
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return store
|
return store
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import CreateViewButton from "./buttons/CreateViewButton.svelte"
|
import CreateViewButton from "./buttons/CreateViewButton.svelte"
|
||||||
import ExportButton from "./buttons/ExportButton.svelte"
|
import ExportButton from "./buttons/ExportButton.svelte"
|
||||||
import EditRolesButton from "./buttons/EditRolesButton.svelte"
|
import EditRolesButton from "./buttons/EditRolesButton.svelte"
|
||||||
|
import ManageAccessButton from "./buttons/ManageAccessButton.svelte"
|
||||||
import * as api from "./api"
|
import * as api from "./api"
|
||||||
import Table from "./Table.svelte"
|
import Table from "./Table.svelte"
|
||||||
import { TableNames } from "constants"
|
import { TableNames } from "constants"
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
modalContentComponent={isUsersTable ? CreateEditUser : CreateEditRow} />
|
modalContentComponent={isUsersTable ? CreateEditUser : CreateEditRow} />
|
||||||
<CreateViewButton />
|
<CreateViewButton />
|
||||||
<ExportButton view={tableView} />
|
<ExportButton view={tableView} />
|
||||||
|
<ManageAccessButton resourceId={$backendUiStore.selectedTable?._id} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if isUsersTable}
|
{#if isUsersTable}
|
||||||
<EditRolesButton />
|
<EditRolesButton />
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import GroupByButton from "./buttons/GroupByButton.svelte"
|
import GroupByButton from "./buttons/GroupByButton.svelte"
|
||||||
import FilterButton from "./buttons/FilterButton.svelte"
|
import FilterButton from "./buttons/FilterButton.svelte"
|
||||||
import ExportButton from "./buttons/ExportButton.svelte"
|
import ExportButton from "./buttons/ExportButton.svelte"
|
||||||
|
import ManageAccessButton from "./buttons/ManageAccessButton.svelte"
|
||||||
|
|
||||||
export let view = {}
|
export let view = {}
|
||||||
|
|
||||||
|
@ -54,4 +55,5 @@
|
||||||
<GroupByButton {view} />
|
<GroupByButton {view} />
|
||||||
{/if}
|
{/if}
|
||||||
<ExportButton {view} />
|
<ExportButton {view} />
|
||||||
|
<ManageAccessButton resourceId={decodeURI(name)} />
|
||||||
</Table>
|
</Table>
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script>
|
||||||
|
import { TextButton, Icon, Popover } from "@budibase/bbui"
|
||||||
|
import api from "builderStore/api"
|
||||||
|
import ManageAccessPopover from "../popovers/ManageAccessPopover.svelte"
|
||||||
|
|
||||||
|
export let resourceId
|
||||||
|
|
||||||
|
let anchor
|
||||||
|
let dropdown
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={anchor}>
|
||||||
|
<TextButton text small on:click={dropdown.show}>
|
||||||
|
<i class="ri-lock-line" />
|
||||||
|
Manage Access
|
||||||
|
</TextButton>
|
||||||
|
</div>
|
||||||
|
<Popover bind:this={dropdown} {anchor} align="left">
|
||||||
|
<ManageAccessPopover {resourceId} onClosed={dropdown.hide} />
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
i {
|
||||||
|
margin-right: var(--spacing-xs);
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,83 @@
|
||||||
|
<script>
|
||||||
|
import { onMount } from "svelte"
|
||||||
|
import { backendUiStore } from "builderStore"
|
||||||
|
import api from "builderStore/api"
|
||||||
|
import { notifier } from "builderStore/store/notifications"
|
||||||
|
import { Button, Select } from "@budibase/bbui"
|
||||||
|
|
||||||
|
const FORMATS = [
|
||||||
|
{
|
||||||
|
name: "CSV",
|
||||||
|
key: "csv",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "JSON",
|
||||||
|
key: "json",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export let resourceId
|
||||||
|
export let onClosed
|
||||||
|
|
||||||
|
let permissions = {}
|
||||||
|
let levels = []
|
||||||
|
|
||||||
|
async function exportView() {
|
||||||
|
onClosed()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function changePermission(level, role) {
|
||||||
|
console.log({ role, resourceId, level })
|
||||||
|
await backendUiStore.actions.permissions.save({
|
||||||
|
role,
|
||||||
|
resource: resourceId,
|
||||||
|
level,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
// TODO: possibly cleaner
|
||||||
|
permissions = await backendUiStore.actions.permissions.forResource(
|
||||||
|
resourceId
|
||||||
|
)
|
||||||
|
levels = await backendUiStore.actions.permissions.fetchLevels()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="popover">
|
||||||
|
<h5>Manage Access</h5>
|
||||||
|
{#each levels as level}
|
||||||
|
<Select
|
||||||
|
label={level}
|
||||||
|
secondary
|
||||||
|
thin
|
||||||
|
value={permissions[level]}
|
||||||
|
on:change={e => changePermission(level, e.target.value)}>
|
||||||
|
{#each $backendUiStore.roles as role}
|
||||||
|
<option value={role._id}>{role.name}</option>
|
||||||
|
{/each}
|
||||||
|
</Select>
|
||||||
|
{/each}
|
||||||
|
<div class="footer">
|
||||||
|
<Button secondary on:click={onClosed}>Cancel</Button>
|
||||||
|
<!-- <Button primary on:click={}>Save</Button> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.popover {
|
||||||
|
display: grid;
|
||||||
|
grid-gap: var(--spacing-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: var(--spacing-m);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -2,6 +2,7 @@ const Router = require("@koa/router")
|
||||||
const viewController = require("../controllers/view")
|
const viewController = require("../controllers/view")
|
||||||
const rowController = require("../controllers/row")
|
const rowController = require("../controllers/row")
|
||||||
const authorized = require("../../middleware/authorized")
|
const authorized = require("../../middleware/authorized")
|
||||||
|
const { paramResource } = require("../../middleware/resourceId")
|
||||||
const {
|
const {
|
||||||
BUILDER,
|
BUILDER,
|
||||||
PermissionTypes,
|
PermissionTypes,
|
||||||
|
@ -15,12 +16,14 @@ router
|
||||||
.get("/api/views/export", authorized(BUILDER), viewController.exportView)
|
.get("/api/views/export", authorized(BUILDER), viewController.exportView)
|
||||||
.get(
|
.get(
|
||||||
"/api/views/:viewName",
|
"/api/views/:viewName",
|
||||||
|
paramResource("viewName"),
|
||||||
authorized(PermissionTypes.VIEW, PermissionLevels.READ),
|
authorized(PermissionTypes.VIEW, PermissionLevels.READ),
|
||||||
rowController.fetchView
|
rowController.fetchView
|
||||||
)
|
)
|
||||||
.get("/api/views", authorized(BUILDER), viewController.fetch)
|
.get("/api/views", authorized(BUILDER), viewController.fetch)
|
||||||
.delete(
|
.delete(
|
||||||
"/api/views/:viewName",
|
"/api/views/:viewName",
|
||||||
|
paramResource("viewName"),
|
||||||
authorized(BUILDER),
|
authorized(BUILDER),
|
||||||
usage,
|
usage,
|
||||||
viewController.destroy
|
viewController.destroy
|
||||||
|
|
Loading…
Reference in New Issue