多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.3 KiB

import { OrgUserRoles, ProjectRoles, SourceRestriction } from 'nocodb-sdk'
const roleScopes = {
org: [OrgUserRoles.VIEWER, OrgUserRoles.CREATOR],
10 months ago
base: [
ProjectRoles.NO_ACCESS,
ProjectRoles.VIEWER,
ProjectRoles.COMMENTER,
ProjectRoles.EDITOR,
ProjectRoles.CREATOR,
ProjectRoles.OWNER,
],
}
interface Perm {
include?: Record<string, boolean>
}
/**
* Each permission value means the following
* `*` - which is wildcard, means all permissions are allowed
* `include` - which is an object, means only the permissions listed in the object are allowed
* `undefined` or `{}` - which is the default value, means no permissions are allowed
* */
const rolePermissions = {
// org level role permissions
[OrgUserRoles.SUPER_ADMIN]: '*',
[OrgUserRoles.CREATOR]: {
include: {
workspaceSettings: true,
superAdminUserManagement: true,
baseCreate: true,
baseMove: true,
baseDelete: true,
baseDuplicate: true,
newUser: true,
tableRename: true,
tableDelete: true,
viewCreateOrEdit: true,
baseReorder: true,
Nc feat/user management (#8369) * fix: source filter Signed-off-by: mertmit <mertmit99@gmail.com> * feat: sso cloud apis - WIP * feat: admin panel menu option * feat: UI integration - WIP * feat: UI integration - SSO * feat: domain verification * feat: workspace upgrade and sso page - WIP * feat: domain adding and verification - WIP * feat: domain adding and verification * fix: domain validation corrections * chore: lint * feat(nc-gui): organization settings page * feat(nc-gui): organization members page * fix(nc-gui): some more changes * fix(nc-gui): refactor collaborators ui * feat(nc-gui): dashboard ui * feat(nc-gui): bases page * feat(nocodb): wired up ui and apis. wip * fix(nc-gui): some more fixes * fix(nc-gui): move ws to org immediately after creation * fix(nc-gui): some more bug fixes * feat(nocodb): transfer workspace ownership * fix(nc-gui): load roles if baseId is provided in prop * fix(nc-gui): show only org workspaces * fix(nc-gui): some more fixes * fix(nc-gui): rename base * fix(nc-gui): invite fixes * feat: restrict access to org level user(SSO login) * fix: include org and client info in token * fix: include org and client info in refresh token * refactor: minor ui corrections * refactor: add a generic component for copying * refactor: ui correction and cleanup * fix: refresh token update * fix: ui corrections * fix: if user signin using unverified domain show error in sso page rather than showing the json with error * fix: for all sso related exceptions redirect to sso ui page with error * chore: lint * fix: show admin panel option only for user who have permission * fix: redirect to sso login page on logout based on current user info * test: sso - playwright test * fix: duplicate attribute * test: playwright * fix: missing import * test: playwright - WIP * test: playwright - Cloud sso login flow * fix: error handling * test: playwright - sso auth flow tests * fix: show upgrade option only for workspace owner * test: user invite tests corrections * test: user invite tests corrections * test: user management correction * test: playwright - use regex for path match * fix: delete existing provider if any * test: combine sso tests to run serially * test: playwright - title name correction * test: playwright - reset sso client from sso tests only * test: playwright - page navigation correction * refactor: by default navigate to org settings page on org creation and disable org image upload * refactor: reverify domain after 7 days and update role names to avoid confusion between org and cloud org roles * fix: corrections * fix: show org level roles in members section * refactor: disable org update by default * test: unit tests for org admin apis * chore: lint * fix: review comments * chore: lint and cleanup --------- Signed-off-by: mertmit <mertmit99@gmail.com> Co-authored-by: mertmit <mertmit99@gmail.com> Co-authored-by: DarkPhoenix2704 <anbarasun123@gmail.com>
8 months ago
orgAdminPanel: true,
workspaceAuditList: true,
},
},
[OrgUserRoles.VIEWER]: {
include: {
importRequest: true,
},
},
// Base role permissions
[ProjectRoles.OWNER]: {
include: {
baseDelete: true,
},
},
[ProjectRoles.CREATOR]: {
include: {
baseCreate: true,
fieldUpdate: true,
hookList: true,
tableCreate: true,
tableRename: true,
tableDelete: true,
tableDuplicate: true,
tableSort: true,
layoutRename: true,
layoutDelete: true,
airtableImport: true,
jsonImport: true,
excelImport: true,
settingsPage: true,
newUser: true,
webhook: true,
fieldEdit: true,
fieldAlter: true,
fieldDelete: true,
fieldAdd: true,
tableIconEdit: true,
viewCreateOrEdit: true,
viewShare: true,
baseShare: true,
baseMiscSettings: true,
csvImport: true,
baseRename: true,
baseDuplicate: true,
sourceCreate: true,
baseAuditList: true,
},
},
[ProjectRoles.EDITOR]: {
include: {
dataInsert: true,
dataEdit: true,
sortSync: true,
filterSync: true,
filterChildrenRead: true,
viewFieldEdit: true,
csvTableImport: true,
excelTableImport: true,
},
},
[ProjectRoles.COMMENTER]: {
include: {
commentDelete: true,
commentResolve: true,
commentEdit: true,
commentList: true,
commentCount: true,
},
},
[ProjectRoles.VIEWER]: {
include: {
baseSettings: true,
expandedForm: true,
apiDocs: true,
},
},
[ProjectRoles.NO_ACCESS]: {
include: {},
},
} as Record<OrgUserRoles | ProjectRoles, Perm | '*'>
// excluded/restricted permissions at source level based on source restriction
// `true` means permission is restricted and `false`/missing means permission is allowed
export const sourceRestrictions = {
[SourceRestriction.DATA_READONLY]: {
dataInsert: true,
dataEdit: true,
dataDelete: true,
airtableImport: true,
csvImport: true,
jsonImport: true,
excelImport: true,
duplicateColumn: true,
duplicateModel: true,
tableDuplicate: true,
},
[SourceRestriction.SCHEMA_READONLY]: {
tableCreate: true,
tableRename: true,
tableDelete: true,
tableDuplicate: true,
airtableImport: true,
csvImport: true,
jsonImport: true,
excelImport: true,
duplicateColumn: true,
duplicateModel: true,
},
}
/*
We inherit include permissions from previous roles in the same scope (role order)
To determine role order, we use `roleScopes` object
So for example ProjectRoles.COMMENTER has `commentEdit` permission,
which means ProjectRoles.EDITOR, ProjectRoles.CREATOR, ProjectRoles.OWNER will also have `commentEdit` permission
where as ProjectRoles.VIEWER, ProjectRoles.NO_ACCESS will not have `commentEdit` permission.
This is why we are validating that there are no duplicate permissions within the same scope
even though it is not required for the code to work. It is to keep the code clean and easy to understand.
*/
// validate no duplicate permissions within same scope
Object.values(roleScopes).forEach((roles) => {
const scopePermissions: Record<string, boolean> = {}
const duplicates: string[] = []
roles.forEach((role) => {
const perms = (rolePermissions[role] as Perm).include || {}
Object.keys(perms).forEach((perm) => {
if (scopePermissions[perm]) {
duplicates.push(perm)
}
scopePermissions[perm] = true
})
})
if (duplicates.length) {
throw new Error(
`Duplicate permissions found in roles ${roles.join(', ')}. Please remove duplicate permissions: ${duplicates.join(', ')}`,
)
}
})
// inherit include permissions within scope (role order)
Object.values(roleScopes).forEach((roles) => {
let roleIndex = 0
for (const role of roles) {
if (roleIndex === 0) {
roleIndex++
continue
}
if (rolePermissions[role] === '*') continue
if ((rolePermissions[role] as Perm).include && (rolePermissions[roles[roleIndex - 1]] as Perm).include) {
Object.assign((rolePermissions[role] as Perm).include!, (rolePermissions[roles[roleIndex - 1]] as Perm).include)
}
roleIndex++
}
})
export { rolePermissions }