Merge pull request #2975 from Budibase/no-access-role
No access role / public by default
This commit is contained in:
commit
a94becac9c
|
@ -34,6 +34,12 @@
|
|||
const publishedAppsOnly = app => app.status === AppStatus.DEPLOYED
|
||||
|
||||
$: publishedApps = $apps.filter(publishedAppsOnly)
|
||||
|
||||
$: userApps = $auth.user?.builder?.global
|
||||
? publishedApps
|
||||
: publishedApps.filter(app =>
|
||||
Object.keys($auth.user?.roles).includes(app.prodId)
|
||||
)
|
||||
</script>
|
||||
|
||||
{#if $auth.user && loaded}
|
||||
|
@ -82,11 +88,11 @@
|
|||
</Body>
|
||||
</Layout>
|
||||
<Divider />
|
||||
{#if publishedApps.length}
|
||||
{#if userApps.length}
|
||||
<Heading>Apps</Heading>
|
||||
<div class="group">
|
||||
<Layout gap="S" noPadding>
|
||||
{#each publishedApps as app, idx (app.appId)}
|
||||
{#each userApps as app, idx (app.appId)}
|
||||
<a class="app" target="_blank" href={`/${app.prodId}`}>
|
||||
<div class="preview" use:gradient={{ seed: app.name }} />
|
||||
<div class="app-info">
|
||||
|
|
|
@ -34,9 +34,13 @@
|
|||
role: {},
|
||||
}
|
||||
|
||||
$: defaultRoleId = $userFetch?.data?.builder?.global ? "ADMIN" : "BASIC"
|
||||
const noRoleSchema = {
|
||||
name: { displayName: "App" },
|
||||
}
|
||||
|
||||
$: defaultRoleId = $userFetch?.data?.builder?.global ? "ADMIN" : ""
|
||||
// Merge the Apps list and the roles response to get something that makes sense for the table
|
||||
$: appList = Object.keys($apps?.data).map(id => {
|
||||
$: allAppList = Object.keys($apps?.data).map(id => {
|
||||
const roleId = $userFetch?.data?.roles?.[id] || defaultRoleId
|
||||
const role = $apps?.data?.[id].roles.find(role => role._id === roleId)
|
||||
return {
|
||||
|
@ -45,6 +49,15 @@
|
|||
role: [role],
|
||||
}
|
||||
})
|
||||
|
||||
$: appList = allAppList.filter(app => !!app.role[0])
|
||||
$: noRoleAppList = allAppList
|
||||
.filter(app => !app.role[0])
|
||||
.map(app => {
|
||||
delete app.role
|
||||
return app
|
||||
})
|
||||
|
||||
let selectedApp
|
||||
|
||||
const userFetch = fetchData(`/api/global/users/${userId}`)
|
||||
|
@ -173,6 +186,7 @@
|
|||
<Divider size="S" />
|
||||
<Layout gap="S" noPadding>
|
||||
<Heading size="S">Configure roles</Heading>
|
||||
<Body>Specify a role to grant access to an app.</Body>
|
||||
<Table
|
||||
on:click={openUpdateRolesModal}
|
||||
schema={roleSchema}
|
||||
|
@ -183,6 +197,21 @@
|
|||
customRenderers={[{ column: "role", component: TagsRenderer }]}
|
||||
/>
|
||||
</Layout>
|
||||
<Layout gap="S" noPadding>
|
||||
<Heading size="XS">No Access</Heading>
|
||||
<Body
|
||||
>Apps do not appear in the users portal. Public pages may still be viewed
|
||||
if visited directly.</Body
|
||||
>
|
||||
<Table
|
||||
on:click={openUpdateRolesModal}
|
||||
schema={noRoleSchema}
|
||||
data={noRoleAppList}
|
||||
allowEditColumns={false}
|
||||
allowEditRows={false}
|
||||
allowSelectRows={false}
|
||||
/>
|
||||
</Layout>
|
||||
<Divider size="S" />
|
||||
<Layout gap="XS" noPadding>
|
||||
<Heading size="S">Delete user</Heading>
|
||||
|
|
|
@ -6,22 +6,38 @@
|
|||
export let app
|
||||
export let user
|
||||
|
||||
const NO_ACCESS = "NO_ACCESS"
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const roles = app.roles
|
||||
let options = roles
|
||||
.filter(role => role._id !== "PUBLIC")
|
||||
.map(role => ({ value: role._id, label: role.name }))
|
||||
let options = roles.map(role => ({ value: role._id, label: role.name }))
|
||||
options.push({ value: NO_ACCESS, label: "No Access" })
|
||||
let selectedRole = user?.roles?.[app?._id]
|
||||
|
||||
async function updateUserRoles() {
|
||||
const res = await users.save({
|
||||
let res
|
||||
if (selectedRole === NO_ACCESS) {
|
||||
// remove the user role
|
||||
const filteredRoles = { ...user.roles }
|
||||
delete filteredRoles[app?._id]
|
||||
res = await users.save({
|
||||
...user,
|
||||
roles: {
|
||||
...filteredRoles,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
// add the user role
|
||||
res = await users.save({
|
||||
...user,
|
||||
roles: {
|
||||
...user.roles,
|
||||
[app._id]: selectedRole,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if (res.status === 400) {
|
||||
notifications.error("Failed to update role")
|
||||
} else {
|
||||
|
|
|
@ -45,7 +45,7 @@ module.exports = async (ctx, next) => {
|
|||
const globalUser = await getCachedSelf(ctx, requestAppId)
|
||||
appId = requestAppId
|
||||
// retrieving global user gets the right role
|
||||
roleId = globalUser.roleId || BUILTIN_ROLE_IDS.BASIC
|
||||
roleId = globalUser.roleId || roleId
|
||||
}
|
||||
|
||||
// nothing more to do
|
||||
|
|
|
@ -127,8 +127,8 @@ describe("Current app middleware", () => {
|
|||
} else {
|
||||
expect(cookieFn).not.toHaveBeenCalled()
|
||||
}
|
||||
expect(config.ctx.roleId).toEqual("BASIC")
|
||||
expect(config.ctx.user.role._id).toEqual("BASIC")
|
||||
expect(config.ctx.roleId).toEqual("PUBLIC")
|
||||
expect(config.ctx.user.role._id).toEqual("PUBLIC")
|
||||
expect(config.ctx.appId).toEqual("app_test")
|
||||
expect(config.next).toHaveBeenCalled()
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ describe("Current app middleware", () => {
|
|||
return "app_test"
|
||||
},
|
||||
setCookie: jest.fn(),
|
||||
getCookie: () => ({appId: "app_test", roleId: "BASIC"}),
|
||||
getCookie: () => ({appId: "app_test", roleId: "PUBLIC"}),
|
||||
},
|
||||
constants: { Cookies: {} },
|
||||
}))
|
||||
|
|
|
@ -26,7 +26,7 @@ exports.updateAppRole = (appId, user) => {
|
|||
if (!user.roleId && user.builder && user.builder.global) {
|
||||
user.roleId = BUILTIN_ROLE_IDS.ADMIN
|
||||
} else if (!user.roleId) {
|
||||
user.roleId = BUILTIN_ROLE_IDS.BASIC
|
||||
user.roleId = BUILTIN_ROLE_IDS.PUBLIC
|
||||
}
|
||||
delete user.roles
|
||||
return user
|
||||
|
|
Loading…
Reference in New Issue