Merge pull request #11609 from Budibase/BUDI-7393/dont-allow-frontend
Guard frontend view permissions
This commit is contained in:
commit
8269dc98cd
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
export let resourceId
|
export let resourceId
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
|
export let requiresLicence
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
let resourcePermissions
|
let resourcePermissions
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={modal}>
|
||||||
<ManageAccessModal
|
<ManageAccessModal
|
||||||
{resourceId}
|
{resourceId}
|
||||||
|
{requiresLicence}
|
||||||
levels={$permissions}
|
levels={$permissions}
|
||||||
permissions={resourcePermissions}
|
permissions={resourcePermissions}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { licensing, admin } from "stores/portal"
|
||||||
import ManageAccessButton from "../ManageAccessButton.svelte"
|
import ManageAccessButton from "../ManageAccessButton.svelte"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
|
|
||||||
|
@ -12,6 +13,17 @@
|
||||||
}
|
}
|
||||||
return datasource.type === "table" ? datasource.tableId : datasource.id
|
return datasource.type === "table" ? datasource.tableId : datasource.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var requiresLicence
|
||||||
|
$: {
|
||||||
|
if ($datasource.type === "viewV2" && !$licensing.isViewPermissionsEnabled) {
|
||||||
|
const requiredLicense = $admin?.cloud ? "Premium" : "Business"
|
||||||
|
requiresLicence = {
|
||||||
|
tier: requiredLicense,
|
||||||
|
message: `A ${requiredLicense} subscription is required to specify access level roles for this view.`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ManageAccessButton {resourceId} />
|
<ManageAccessButton {resourceId} {requiresLicence} />
|
||||||
|
|
|
@ -7,11 +7,14 @@
|
||||||
notifications,
|
notifications,
|
||||||
Body,
|
Body,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
|
Tags,
|
||||||
|
Tag,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { capitalise } from "helpers"
|
import { capitalise } from "helpers"
|
||||||
|
|
||||||
export let resourceId
|
export let resourceId
|
||||||
export let permissions
|
export let permissions
|
||||||
|
export let requiresLicence
|
||||||
|
|
||||||
async function changePermission(level, role) {
|
async function changePermission(level, role) {
|
||||||
try {
|
try {
|
||||||
|
@ -30,22 +33,36 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModalContent title="Manage Access" showCancelButton={false} confirmText="Done">
|
<ModalContent showCancelButton={false} confirmText="Done">
|
||||||
<Body size="S">Specify the minimum access level role for this data.</Body>
|
<span slot="header">
|
||||||
<div class="row">
|
Manage Access
|
||||||
<Label extraSmall grey>Level</Label>
|
{#if requiresLicence}
|
||||||
<Label extraSmall grey>Role</Label>
|
<span class="lock-tag">
|
||||||
{#each Object.keys(permissions) as level}
|
<Tags>
|
||||||
<Input value={capitalise(level)} disabled />
|
<Tag icon="LockClosed">{requiresLicence.tier}</Tag>
|
||||||
<Select
|
</Tags>
|
||||||
value={permissions[level]}
|
</span>
|
||||||
on:change={e => changePermission(level, e.detail)}
|
{/if}
|
||||||
options={$roles}
|
</span>
|
||||||
getOptionLabel={x => x.name}
|
{#if requiresLicence}
|
||||||
getOptionValue={x => x._id}
|
<Body size="S">{requiresLicence.message}</Body>
|
||||||
/>
|
{:else}
|
||||||
{/each}
|
<Body size="S">Specify the minimum access level role for this data.</Body>
|
||||||
</div>
|
<div class="row">
|
||||||
|
<Label extraSmall grey>Level</Label>
|
||||||
|
<Label extraSmall grey>Role</Label>
|
||||||
|
{#each Object.keys(permissions) as level}
|
||||||
|
<Input value={capitalise(level)} disabled />
|
||||||
|
<Select
|
||||||
|
value={permissions[level]}
|
||||||
|
on:change={e => changePermission(level, e.detail)}
|
||||||
|
options={$roles}
|
||||||
|
getOptionLabel={x => x.name}
|
||||||
|
getOptionValue={x => x._id}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -54,4 +71,8 @@
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
grid-gap: var(--spacing-s);
|
grid-gap: var(--spacing-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lock-tag {
|
||||||
|
padding-left: var(--spacing-s);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -125,6 +125,9 @@ export const createLicensingStore = () => {
|
||||||
const syncAutomationsEnabled = license.features.includes(
|
const syncAutomationsEnabled = license.features.includes(
|
||||||
Constants.Features.SYNC_AUTOMATIONS
|
Constants.Features.SYNC_AUTOMATIONS
|
||||||
)
|
)
|
||||||
|
const isViewPermissionsEnabled = license.features.includes(
|
||||||
|
Constants.Features.VIEW_PERMISSIONS
|
||||||
|
)
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -140,6 +143,7 @@ export const createLicensingStore = () => {
|
||||||
auditLogsEnabled,
|
auditLogsEnabled,
|
||||||
enforceableSSO,
|
enforceableSSO,
|
||||||
syncAutomationsEnabled,
|
syncAutomationsEnabled,
|
||||||
|
isViewPermissionsEnabled,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* Operator options for lucene queries
|
* Operator options for lucene queries
|
||||||
*/
|
*/
|
||||||
export { OperatorOptions, SqlNumberTypeRangeMap } from "@budibase/shared-core"
|
export { OperatorOptions, SqlNumberTypeRangeMap } from "@budibase/shared-core"
|
||||||
|
export { Feature as Features } from "@budibase/types"
|
||||||
|
|
||||||
// Cookie names
|
// Cookie names
|
||||||
export const Cookies = {
|
export const Cookies = {
|
||||||
|
@ -62,17 +63,6 @@ export const PlanType = {
|
||||||
*/
|
*/
|
||||||
export const ApiVersion = "1"
|
export const ApiVersion = "1"
|
||||||
|
|
||||||
export const Features = {
|
|
||||||
USER_GROUPS: "userGroups",
|
|
||||||
BACKUPS: "appBackups",
|
|
||||||
ENVIRONMENT_VARIABLES: "environmentVariables",
|
|
||||||
AUDIT_LOGS: "auditLogs",
|
|
||||||
ENFORCEABLE_SSO: "enforceableSSO",
|
|
||||||
BRANDING: "branding",
|
|
||||||
SCIM: "scim",
|
|
||||||
SYNC_AUTOMATIONS: "syncAutomations",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Role IDs
|
// Role IDs
|
||||||
export const Roles = {
|
export const Roles = {
|
||||||
ADMIN: "ADMIN",
|
ADMIN: "ADMIN",
|
||||||
|
|
|
@ -12,7 +12,7 @@ export enum Feature {
|
||||||
APP_BUILDERS = "appBuilders",
|
APP_BUILDERS = "appBuilders",
|
||||||
OFFLINE = "offline",
|
OFFLINE = "offline",
|
||||||
USER_ROLE_PUBLIC_API = "userRolePublicApi",
|
USER_ROLE_PUBLIC_API = "userRolePublicApi",
|
||||||
VIEW_PERMISSIONS = "viewPermission",
|
VIEW_PERMISSIONS = "viewPermissions",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PlanFeatures = { [key in PlanType]: Feature[] | undefined }
|
export type PlanFeatures = { [key in PlanType]: Feature[] | undefined }
|
||||||
|
|
Loading…
Reference in New Issue