Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New RBAC UI #14577

Merged
merged 121 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
4fd74c3
Add new access selection UI for tables and views
aptkingston Sep 9, 2024
608bc97
Update access button
aptkingston Sep 10, 2024
eb20686
Remove licensing restriction for configuring access on views
aptkingston Sep 10, 2024
9da84b1
Add scaffolding for new role editor modal
aptkingston Sep 10, 2024
3c158c5
Add initial version of new RBAC editor
aptkingston Sep 10, 2024
dd98364
Improve RBAC flow chart
aptkingston Sep 10, 2024
d8dc874
Add ability to update roles
aptkingston Sep 10, 2024
3295d90
Update mapping of roles to new flow structure
aptkingston Sep 11, 2024
f1aca4c
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 11, 2024
9f0c160
Add deleted permissions file, update auto layout
aptkingston Sep 11, 2024
a5520a9
Use display names and allow descriptions to be edited
aptkingston Sep 11, 2024
a81d9c6
Add display name, color and descriptions to roles. Allow row CRUD via…
aptkingston Sep 11, 2024
de7604f
Fix role CRUD
aptkingston Sep 11, 2024
0fd3892
Remove log
aptkingston Sep 11, 2024
e47d25c
Fix role updating and add custom role type to grid
aptkingston Sep 11, 2024
7e6f140
Ensure roles always have new metadta and update access popover
aptkingston Sep 11, 2024
aa75fca
Update user side panel to account for new role metadata
aptkingston Sep 11, 2024
dc0f93e
Update design section to use new role metadata
aptkingston Sep 11, 2024
6419829
Update other usages of roles to use new metadata
aptkingston Sep 11, 2024
8a7af78
Remove legacy stuff
aptkingston Sep 11, 2024
f6852d5
Update some other portal components to use new role metadata
aptkingston Sep 11, 2024
bc03f1e
Fixing some role typing issues, as well as fixing an issue with the v…
mike12345567 Sep 11, 2024
0a627e6
Add validation to editing roles
aptkingston Sep 11, 2024
35bdc99
Fix roles store update
aptkingston Sep 12, 2024
6f91751
Add custom RBAC edges with inline deletion icon
aptkingston Sep 12, 2024
d80d381
Update styles of handles and edges
aptkingston Sep 12, 2024
d4451a4
Increase max auto zoom and add more constants
aptkingston Sep 12, 2024
87206b1
Update node spacing
aptkingston Sep 12, 2024
dded09c
Update RBAC editor to use a grid and make all dimensions consistent w…
aptkingston Sep 12, 2024
63dd73f
Update RBAC editor edges to explain what action the delete icon will …
aptkingston Sep 12, 2024
46c8335
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 13, 2024
0404050
Reset server changes to master
aptkingston Sep 13, 2024
2849a7a
Add uiMetdata prefix to roles everywhere
aptkingston Sep 13, 2024
b323130
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 13, 2024
bf10b4c
Lint
aptkingston Sep 16, 2024
a120a9c
Add multi user sync for roles
aptkingston Sep 16, 2024
0a10916
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 16, 2024
c634cfd
Simplify and rewrite some flow logic
aptkingston Sep 16, 2024
d23d415
Lint
aptkingston Sep 16, 2024
d61594d
Refactor RBAC flow and use selected states more
aptkingston Sep 16, 2024
e7916c5
Some style updates
aptkingston Sep 16, 2024
518f290
Fix edge issue
aptkingston Sep 16, 2024
1eee556
Fix issues with multi selectioni
aptkingston Sep 16, 2024
c9c6d41
Wait for server changes before updating state
aptkingston Sep 16, 2024
3e2fdee
Remove logs
aptkingston Sep 16, 2024
7406812
Lint
aptkingston Sep 16, 2024
93751f3
Lint
aptkingston Sep 16, 2024
57e34e3
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 16, 2024
a90cf51
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 18, 2024
e621cfc
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 20, 2024
376ac1c
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 23, 2024
de34217
Increase spacing to M in list items
aptkingston Sep 23, 2024
b2b6cc2
Reorder grid buttons and remove export button for users table
aptkingston Sep 23, 2024
c4d4e44
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 24, 2024
bb7102b
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 25, 2024
6f054c3
Update role nodes to always show icons
aptkingston Sep 25, 2024
3fc3edf
Allow hovering over edges to make them active as well as supporting s…
aptkingston Sep 25, 2024
bf91266
Select nodes after creation
aptkingston Sep 25, 2024
f3c219a
Increase spacing between RBAC editor controls
aptkingston Sep 25, 2024
f08e449
Lint
aptkingston Sep 26, 2024
adfe467
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 30, 2024
2e5f07d
Merge branch 'feature/role-multi-inheritance' of github.com:Budibase/…
aptkingston Sep 30, 2024
46feabe
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Sep 30, 2024
2099ee8
Fix duplicates
aptkingston Sep 30, 2024
354b504
Update handling of basic and admin edges
aptkingston Oct 1, 2024
d2b59fe
Refactor node management to automatically position basic and admin at…
aptkingston Oct 1, 2024
3f520f0
Add bounding brackets to role editor
aptkingston Oct 1, 2024
66f6e91
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 2, 2024
4de91d4
Add animated curly brackets
aptkingston Oct 3, 2024
f430de5
Add more edge validation
aptkingston Oct 3, 2024
fbdbefd
Fix resizing issue with brackes
aptkingston Oct 3, 2024
f7318b1
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 3, 2024
72f1db8
Update spacing
aptkingston Oct 3, 2024
303f400
Prevent selection of basic and admin roles
aptkingston Oct 3, 2024
a342aa3
Add empty state node to role editor
aptkingston Oct 3, 2024
a4aac8a
Deal with power users
aptkingston Oct 3, 2024
8187322
Add auto layout and fit when doing any role operation other than upda…
aptkingston Oct 3, 2024
303bb94
Fix top nav being off-center
aptkingston Oct 3, 2024
c51c7cd
Make role editor full screen
aptkingston Oct 3, 2024
aa3da2b
Fix z-index
aptkingston Oct 3, 2024
e4900e2
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 3, 2024
bcaff95
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 3, 2024
f2b4ef2
Lint
aptkingston Oct 4, 2024
b9a1069
Improve RBAC edutor UI for small flows
aptkingston Oct 7, 2024
f4e149f
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 9, 2024
72dd3a1
Fix resolution of builderSocket
aptkingston Oct 9, 2024
06413fd
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 15, 2024
f7f300b
Merge branch 'feature/role-multi-inheritance' of github.com:Budibase/…
aptkingston Oct 15, 2024
fa8d01b
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 16, 2024
54a0e33
Merge branch 'feature/role-multi-inheritance' of github.com:Budibase/…
aptkingston Oct 16, 2024
477bdf2
Fixing some issues with finding roles.
mike12345567 Oct 16, 2024
edf6d95
Role save API returns role ID in correct format.
mike12345567 Oct 16, 2024
02d4c2d
fixing rbac
mike12345567 Oct 16, 2024
d1fc12d
Merge branch 'feature/role-multi-inheritance' of github.com:Budibase/…
aptkingston Oct 16, 2024
cbd84ae
Handle role errors and reset state as required
aptkingston Oct 17, 2024
d50e1cf
Fix detection of custom roles
aptkingston Oct 17, 2024
ac46e27
Lint
aptkingston Oct 17, 2024
609bc3f
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 18, 2024
761c9d3
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 18, 2024
3d1b786
Remove frontend role prefixing hacks and fix 409s on role deletion
aptkingston Oct 18, 2024
73999e4
Remove old code
aptkingston Oct 18, 2024
69969e8
Merge branch 'v3-ui' of github.com:Budibase/budibase into new-rbac-ui
aptkingston Oct 22, 2024
00fe28e
Simplifying retrieval of role hierarchy for accessible endpoint.
mike12345567 Oct 22, 2024
86620b9
Remove permissionId when creating roles and ensure all roles inherit …
aptkingston Oct 22, 2024
f3d54f1
Adding test cases.
mike12345567 Oct 22, 2024
cf3ef64
Clean up role header implementation in currentapp.ts
mike12345567 Oct 22, 2024
ebc440a
Another test case.
mike12345567 Oct 22, 2024
fe35ef7
final test case.
mike12345567 Oct 22, 2024
eb349b5
Linting.
mike12345567 Oct 22, 2024
3ae5ce9
Use role display names for picking preview roles
aptkingston Oct 22, 2024
1e4f105
Fix labels and add colours to access level selctor for queries
aptkingston Oct 22, 2024
62d87da
Fix role colours in user app list portal page
aptkingston Oct 22, 2024
80e532f
Fix app count in groups list
aptkingston Oct 22, 2024
4129169
Lint
aptkingston Oct 22, 2024
7487066
Addressing PR comments.
mike12345567 Oct 22, 2024
99d867f
Updating test case.
mike12345567 Oct 22, 2024
f91e039
Adding test with invalid role IDs.#
mike12345567 Oct 22, 2024
0b2ac57
linting.
mike12345567 Oct 22, 2024
9575095
Merge pull request #14844 from Budibase/fix/multi-inheritance-preview…
mike12345567 Oct 22, 2024
07312b9
Revert testing stuff
aptkingston Oct 23, 2024
0a14075
Merge branch 'new-rbac-ui' of github.com:Budibase/budibase into new-r…
aptkingston Oct 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions packages/backend-core/src/security/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,22 @@ export function getBuiltinRole(roleId: string): Role | undefined {
return cloneDeep(role)
}

export function validInherits(
allRoles: RoleDoc[],
inherits?: string | string[]
): boolean {
if (!inherits) {
return false
}
const find = (id: string) => allRoles.find(r => roleIDsAreEqual(r._id!, id))
if (Array.isArray(inherits)) {
const filtered = inherits.filter(roleId => find(roleId))
return inherits.length !== 0 && filtered.length === inherits.length
} else {
return !!find(inherits)
}
}

/**
* Works through the inheritance ranks to see how far up the builtin stack this ID is.
*/
Expand Down Expand Up @@ -290,7 +306,7 @@ export function lowerBuiltinRoleID(roleId1?: string, roleId2?: string): string {
: roleId1
}

export function compareRoleIds(roleId1: string, roleId2: string) {
export function roleIDsAreEqual(roleId1: string, roleId2: string) {
// make sure both role IDs are prefixed correctly
return prefixRoleID(roleId1) === prefixRoleID(roleId2)
}
Expand Down Expand Up @@ -323,7 +339,7 @@ export function findRole(
roleId = prefixRoleID(roleId)
}
const dbRole = roles.find(
role => role._id && compareRoleIds(role._id, roleId)
role => role._id && roleIDsAreEqual(role._id, roleId)
)
if (!dbRole && !isBuiltin(roleId) && opts?.defaultPublic) {
return cloneDeep(BUILTIN_ROLES.PUBLIC)
Expand Down Expand Up @@ -557,7 +573,7 @@ export class AccessController {
}

return (
roleIds?.find(roleId => compareRoleIds(roleId, tryingRoleId)) !==
roleIds?.find(roleId => roleIDsAreEqual(roleId, tryingRoleId)) !==
undefined
)
}
Expand Down
1 change: 1 addition & 0 deletions packages/bbui/src/InlineAlert/InlineAlert.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
export let onConfirm = undefined
export let buttonText = ""
export let cta = false

$: icon = selectIcon(type)
// if newlines used, convert them to different elements
$: split = message.split("\n")
Expand Down
16 changes: 13 additions & 3 deletions packages/bbui/src/List/ListItem.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script>
import Icon from "../Icon/Icon.svelte"
import StatusLight from "../StatusLight/StatusLight.svelte"

export let icon = null
export let iconColor = null
Expand All @@ -8,16 +9,20 @@
export let url = null
export let hoverable = false
export let showArrow = false
export let selected = false
</script>

<a
href={url}
class="list-item"
class:hoverable={hoverable || url != null}
on:click
class:selected
>
<div class="left">
{#if icon}
{#if icon === "StatusLight"}
<StatusLight square size="L" color={iconColor} />
{:else if icon}
<Icon name={icon} color={iconColor} />
{/if}
<div class="list-item__text">
Expand All @@ -43,7 +48,7 @@

<style>
.list-item {
padding: var(--spacing-m);
padding: var(--spacing-m) var(--spacing-l);
background: var(--spectrum-global-color-gray-75);
display: flex;
flex-direction: row;
Expand All @@ -66,15 +71,20 @@
}
.hoverable:hover {
cursor: pointer;
}
.hoverable:not(.selected):hover {
background: var(--spectrum-global-color-gray-200);
}
.selected {
background: var(--spectrum-global-color-blue-100);
}

.left,
.right {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--spacing-s);
gap: var(--spacing-m);
}
.left {
width: 0;
Expand Down
1 change: 1 addition & 0 deletions packages/bbui/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export { default as EnvDropdown } from "./Form/EnvDropdown.svelte"
export { default as Multiselect } from "./Form/Multiselect.svelte"
export { default as Search } from "./Form/Search.svelte"
export { default as RichTextField } from "./Form/RichTextField.svelte"
export { default as FieldLabel } from "./Form/FieldLabel.svelte"
export { default as Slider } from "./Form/Slider.svelte"
export { default as File } from "./Form/File.svelte"

Expand Down
2 changes: 2 additions & 0 deletions packages/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@
"@codemirror/state": "^6.2.0",
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.11.2",
"@dagrejs/dagre": "1.1.4",
"@fontsource/source-sans-pro": "^5.0.3",
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2",
"@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1",
"@xyflow/svelte": "^0.1.18",
"@zerodevx/svelte-json-view": "^1.0.7",
"codemirror": "^5.65.16",
"cron-parser": "^4.9.0",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,31 +1,195 @@
<script>
import { ActionButton } from "@budibase/bbui"
import { permissions } from "stores/builder"
import ManageAccessModal from "../modals/ManageAccessModal.svelte"
import {
ActionButton,
Input,
Select,
Label,
List,
ListItem,
notifications,
} from "@budibase/bbui"
import { permissions as permissionsStore, roles } from "stores/builder"
import DetailPopover from "components/common/DetailPopover.svelte"
import EditRolesButton from "./EditRolesButton.svelte"
import { PermissionSource } from "@budibase/types"
import { capitalise } from "helpers"
import InfoDisplay from "pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/InfoDisplay.svelte"
import { Roles } from "constants/backend"

export let resourceId

let resourcePermissions
const inheritedRoleId = "inherited"
const builtins = [Roles.ADMIN, Roles.POWER, Roles.BASIC, Roles.PUBLIC]

let permissions
let showPopover = true
let dependantsInfoMessage

$: fetchPermissions(resourceId)
$: loadDependantInfo(resourceId)
$: roleMismatch = checkRoleMismatch(permissions)
$: selectedRole = roleMismatch ? null : permissions?.[0]?.value
$: readableRole = selectedRole
? $roles.find(x => x._id === selectedRole)?.uiMetadata.displayName
: null
$: buttonLabel = readableRole ? `Access: ${readableRole}` : "Access"
$: highlight = roleMismatch || selectedRole === Roles.PUBLIC

$: builtInRoles = builtins.map(roleId => $roles.find(x => x._id === roleId))
$: customRoles = $roles
.filter(x => !builtins.includes(x._id))
.slice()
.toSorted((a, b) => {
const aName = a.uiMetadata.displayName || a.name
const bName = b.uiMetadata.displayName || b.name
return aName < bName ? -1 : 1
})

const fetchPermissions = async id => {
resourcePermissions = await permissions.forResourceDetailed(id)
const res = await permissionsStore.forResourceDetailed(id)
permissions = Object.entries(res?.permissions || {}).map(([perm, info]) => {
let enriched = {
permission: perm,
value:
info.permissionType === PermissionSource.INHERITED
? inheritedRoleId
: info.role,
options: [...$roles],
}
if (info.inheritablePermission) {
enriched.options.unshift({
_id: inheritedRoleId,
name: `Inherit (${
$roles.find(x => x._id === info.inheritablePermission).name
})`,
})
}
return enriched
})
}

const checkRoleMismatch = permissions => {
if (!permissions || permissions.length < 2) {
return false
}
return (
permissions[0].value !== permissions[1].value ||
permissions[0].value === inheritedRoleId
)
}

const loadDependantInfo = async resourceId => {
const dependantsInfo = await permissionsStore.getDependantsInfo(resourceId)
const resourceByType = dependantsInfo?.resourceByType
if (resourceByType) {
const total = Object.values(resourceByType).reduce((p, c) => p + c, 0)
let resourceDisplay =
Object.keys(resourceByType).length === 1 && resourceByType.view
? "view"
: "resource"

if (total === 1) {
dependantsInfoMessage = `1 ${resourceDisplay} is inheriting this access`
} else if (total > 1) {
dependantsInfoMessage = `${total} ${resourceDisplay}s are inheriting this access`
} else {
dependantsInfoMessage = null
}
} else {
dependantsInfoMessage = null
}
}

const changePermission = async role => {
try {
await permissionsStore.save({
level: "read",
role,
resource: resourceId,
})
await permissionsStore.save({
level: "write",
role,
resource: resourceId,
})
await fetchPermissions(resourceId)
notifications.success("Updated permissions")
} catch (error) {
console.error(error)
notifications.error("Error updating permissions")
}
}
</script>

<DetailPopover title="Manage access" {showPopover}>
<DetailPopover title="Select access role" {showPopover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton icon="LockClosed" selected={open} quiet>Access</ActionButton>
<ActionButton
icon="LockClosed"
selected={open || highlight}
quiet
accentColor={highlight ? "#ff0000" : null}
>
{buttonLabel}
</ActionButton>
</svelte:fragment>
{#if resourcePermissions}
<ManageAccessModal {resourceId} permissions={resourcePermissions} />

{#if roleMismatch}
<div class="row">
<Label extraSmall grey>Level</Label>
<Label extraSmall grey>Role</Label>
{#each permissions as permission}
<Input value={capitalise(permission.permission)} disabled />
<Select
placeholder={false}
value={permission.value}
on:change={e => changePermission(e.detail)}
disabled
options={permission.options}
getOptionLabel={x => x.name}
getOptionValue={x => x._id}
/>
{/each}
</div>
<InfoDisplay
error
icon="Alert"
body="Your previous configuration is shown above.<br/> Please choose a single role for read and write access."
/>
{/if}

<List>
{#each builtInRoles as role}
<ListItem
title={role.uiMetadata.displayName}
subtitle={role.uiMetadata.description}
hoverable
selected={selectedRole === role._id}
icon="StatusLight"
iconColor={role.uiMetadata.color}
on:click={() => changePermission(role._id)}
/>
{/each}
{#each customRoles as role}
<ListItem
title={role.uiMetadata.displayName}
subtitle={role.uiMetadata.description}
hoverable
selected={selectedRole === role._id}
icon="StatusLight"
iconColor={role.uiMetadata.color}
on:click={() => changePermission(role._id)}
/>
{/each}
</List>

{#if dependantsInfoMessage}
<InfoDisplay info body={dependantsInfoMessage} />
{/if}
<EditRolesButton
on:show={() => (showPopover = false)}
on:hide={() => (showPopover = true)}
/>
</DetailPopover>

<style>
.row {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: var(--spacing-s);
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

const generateAutomation = () => {
popover?.hide()
dispatch("request-generate")
dispatch("generate")
}
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@

<DetailPopover title="Generate" bind:this={popover}>
<svelte:fragment slot="anchor" let:open>
<ActionButton selected={open}>
<ActionButton quiet selected={open}>
<div class="center">
<img height={16} alt="magic wand" src={MagicWand} />
Generate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

const generateScreen = () => {
popover?.hide()
dispatch("request-generate")
dispatch("generate")
}
</script>

Expand Down
Loading
Loading