control RBAC from data section

This commit is contained in:
Martin McKeaveney 2021-02-10 18:18:31 +00:00
parent 1958143500
commit 37c00f24bd
6 changed files with 141 additions and 0 deletions

View File

@ -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

View File

@ -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 />

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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