Skip to content

Commit

Permalink
Merge branch 'main' into chore/fix-typo
Browse files Browse the repository at this point in the history
  • Loading branch information
abuaboud committed Mar 3, 2024
2 parents 761adb6 + 6c46673 commit 49b53db
Show file tree
Hide file tree
Showing 56 changed files with 386 additions and 322 deletions.
Expand Up @@ -2,15 +2,24 @@
{{title}}
</ap-dialog-title-template>

<mat-dialog-content>
<form [formGroup]="form" class="ap-max-w-[34.375rem] ap-min-w-[31.25rem]">
<mat-dialog-content class="thin-scrollbars">
<form [formGroup]="form" class="ap-max-w-[34.375rem] ap-flex ap-flex-col ap-gap-2 ap-min-w-[31.25rem] ">
<ap-markdown [fullWidth]="true" [data]="shareTemplateMarkdown" class="ap-mb-2"></ap-markdown>
<mat-form-field class="ap-w-full ap-mb-1" appearance="outline">
<mat-label i18n>Name</mat-label>
<input [formControl]="form.controls.name" matInput type="text" />
<mat-error *ngIf="form.controls.name.invalid" i18n>Name is required</mat-error>
</mat-form-field>

<mat-form-field class="ap-w-full ap-mb-1" appearance="outline">
<mat-label i18n>Description</mat-label>
<textarea [formControl]="form.controls.description" matInput type="text" rows="4" > </textarea>
<mat-error *ngIf="form.controls.description.invalid" i18n>Description is required</mat-error>
<mat-hint>
Description can be in markdown format
</mat-hint>
</mat-form-field>

<mat-form-field class="ap-w-full ap-mb-1">
<mat-label i18n>Flow template</mat-label>
<ap-file-upload #flowInput [formControl]="form.controls.file" [required]="true"></ap-file-upload>
Expand Down
Expand Up @@ -38,7 +38,7 @@ export class CreateOrUpdateTemplateDialogueComponent {
form: FormGroup<{
file: FormControl<File | null>;
name: FormControl<string>;

description: FormControl<string>;
blogUrl: FormControl<string>;
tags: FormControl<string[]>;
}>;
Expand All @@ -55,7 +55,10 @@ export class CreateOrUpdateTemplateDialogueComponent {
file: new FormControl<File | null>(null, {
validators: Validators.required,
}),

description: new FormControl('', {
nonNullable: true,
validators: Validators.required,
}),
name: new FormControl('', {
nonNullable: true,
validators: Validators.required,
Expand All @@ -66,6 +69,7 @@ export class CreateOrUpdateTemplateDialogueComponent {
if (data?.template) {
this.form.patchValue({
name: data.template.name,
description: data.template.description,
blogUrl: data.template.blogUrl,
tags: data.template.tags,
});
Expand Down Expand Up @@ -94,6 +98,7 @@ export class CreateOrUpdateTemplateDialogueComponent {
this.createTemplate$ = this.templateService
.create({
...template,
description: this.form.value.description,
type: TemplateType.PLATFORM,
blogUrl: this.form.value.blogUrl,
tags: this.form.value.tags,
Expand Down
Expand Up @@ -3,6 +3,7 @@ import {
AppConnection,
AppConnectionWithoutSensitiveData,
ListAppConnectionsRequestQuery,
Permission,
PrincipalType,
SERVICE_KEY_SECURITY_OPENAPI,
SeekPage,
Expand Down Expand Up @@ -96,6 +97,7 @@ const removeSensitiveData = (
const UpsertAppConnectionRequest = {
config: {
allowedPrincipals: [PrincipalType.USER, PrincipalType.SERVICE],
permission: Permission.WRITE_APP_CONNECTION,
},
schema: {
tags: ['app-connections'],
Expand All @@ -111,6 +113,7 @@ const UpsertAppConnectionRequest = {
const ListAppConnectionsRequest = {
config: {
allowedPrincipals: [PrincipalType.USER, PrincipalType.SERVICE],
permission: Permission.READ_APP_CONNECTION,
},
schema: {
tags: ['app-connections'],
Expand All @@ -126,6 +129,7 @@ const ListAppConnectionsRequest = {
const DeleteAppConnectionRequest = {
config: {
allowedPrincipals: [PrincipalType.USER, PrincipalType.SERVICE],
permission: Permission.WRITE_APP_CONNECTION,
},
schema: {
tags: ['app-connections'],
Expand Down
@@ -1,5 +1,5 @@
import { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox'
import { PrincipalType } from '@activepieces/shared'
import { Permission, PrincipalType } from '@activepieces/shared'
import { activityService } from './activity-service'
import { ListActivityParams } from '@activepieces/ee-shared'

Expand All @@ -18,6 +18,7 @@ const ListActivitiesRequest = {
allowedPrincipals: [
PrincipalType.USER,
],
permission: Permission.READ_ACTIVITY,
},
schema: {
querystring: ListActivityParams,
Expand Down
@@ -1,15 +1,4 @@
import { ProjectMemberRole } from '@activepieces/shared'
import { ResourceAction, ResourceName } from './resources'

export enum Permission {
READ_ACTIVITY = 'READ_ACTIVITY',
READ_APP_CONNECTION = 'READ_APP_CONNECTION',
WRITE_APP_CONNECTION = 'WRITE_APP_CONNECTION',
READ_FLOW = 'READ_FLOW',
WRITE_FLOW = 'WRITE_FLOW',
READ_PROJECT_MEMBER = 'READ_PROJECT_MEMBER',
WRITE_PROJECT_MEMBER = 'WRITE_PROJECT_MEMBER',
}
import { Permission, ProjectMemberRole } from '@activepieces/shared'

export const rolePermissions: Record<ProjectMemberRole, Permission[]> = {
[ProjectMemberRole.ADMIN]: [
Expand Down Expand Up @@ -41,39 +30,3 @@ export const rolePermissions: Record<ProjectMemberRole, Permission[]> = {
Permission.WRITE_APP_CONNECTION,
],
}

export const accessControlList: Record<Permission, AccessControl> = {
[Permission.READ_ACTIVITY]: {
resource: 'activities',
actions: ['GET'],
},
[Permission.READ_APP_CONNECTION]: {
resource: 'app-connections',
actions: ['GET'],
},
[Permission.WRITE_APP_CONNECTION]: {
resource: 'app-connections',
actions: ['POST', 'DELETE'],
},
[Permission.READ_FLOW]: {
resource: 'flows',
actions: ['GET'],
},
[Permission.WRITE_FLOW]: {
resource: 'flows',
actions: ['POST', 'DELETE'],
},
[Permission.READ_PROJECT_MEMBER]: {
resource: 'project-members',
actions: ['GET'],
},
[Permission.WRITE_PROJECT_MEMBER]: {
resource: 'project-members',
actions: ['POST', 'DELETE'],
},
}

type AccessControl = {
resource: ResourceName
actions: ResourceAction[]
}
Expand Up @@ -3,16 +3,15 @@ import {
ActivepiecesError,
ApEdition,
ErrorCode,
Permission,
Principal,
PrincipalType,
ProjectId,
ProjectMemberRole,
isNil,
} from '@activepieces/shared'
import { projectMemberService } from '../../project-members/project-member.service'
import { getEdition } from '../../../helper/secret-helper'
import { extractResourceName } from '../../../authentication/authorization'
import { ResourceAction, ResourceName, accessControlledResourceNames } from './resources'
import { accessControlList, rolePermissions } from './access-control-list'
import { rolePermissions } from './access-control-list'

const EDITION_IS_COMMUNITY = getEdition() === ApEdition.COMMUNITY

Expand All @@ -21,41 +20,18 @@ export const rbacMiddleware = async (req: FastifyRequest): Promise<void> => {
return
}

const resourceName = extractResourceNameOrThrow(req)
const resourceAction = extractResourceAction(req)
const projectId = req.principal.projectId

const role = await getRoleOrThrow({
projectId,
userId: req.principal.id,
resourceName,
resourceAction,
})
const principalRole = await getPrincipalRoleOrThrow(req.principal)

const access = grantAccess({
role,
resourceName,
resourceAction,
principalRole,
routePermission: req.routeConfig.permission,
})

if (!access) {
throwPermissionDenied({
projectId,
resourceName,
resourceAction,
})
throwPermissionDenied(req.principal)
}
}

const grantAccess = ({ role, resourceName, resourceAction }: GrantAccessArgs): boolean => {
const permissions = rolePermissions[role]

return permissions.some(permission => {
const { resource, actions } = accessControlList[permission]
return resource === resourceName && actions.includes(resourceAction)
})
}

const ignoreRequest = (req: FastifyRequest): boolean => {
if (EDITION_IS_COMMUNITY) {
return true
Expand All @@ -70,13 +46,11 @@ const ignoreRequest = (req: FastifyRequest): boolean => {
return true
}

const resourceName = extractResourceNameOrThrow(req)

return !accessControlledResourceNames.includes(resourceName)
return req.routeConfig.permission === undefined
}

const getRoleOrThrow = async (params: GetRoleOrThrowArgs): Promise<ProjectMemberRole> => {
const { projectId, userId } = params
const getPrincipalRoleOrThrow = async (principal: Principal): Promise<ProjectMemberRole> => {
const { id: userId, projectId } = principal

const role = await projectMemberService.getRole({
projectId,
Expand All @@ -98,51 +72,26 @@ const getRoleOrThrow = async (params: GetRoleOrThrowArgs): Promise<ProjectMember

}

const extractResourceNameOrThrow = (req: FastifyRequest): ResourceName => {
const resourceName = extractResourceName(req.url) as ResourceName | undefined

if (isNil(resourceName)) {
throw new ActivepiecesError({
code: ErrorCode.AUTHORIZATION,
params: {
message: 'Invalid resource',
},
})
const grantAccess = ({ principalRole, routePermission }: GrantAccessArgs): boolean => {
if (isNil(routePermission)) {
return true
}

return resourceName
const principalPermissions = rolePermissions[principalRole]
return principalPermissions.includes(routePermission)
}

const extractResourceAction = (req: FastifyRequest): ResourceAction => {
return req.method as ResourceAction
}

const throwPermissionDenied = ({ projectId, resourceName, resourceAction }: ThrowPermissionDeniedArgs): never => {
const throwPermissionDenied = (principal: Principal): never => {
throw new ActivepiecesError({
code: ErrorCode.PERMISSION_DENIED,
params: {
projectId,
resource: resourceName,
action: resourceAction,
userId: principal.id,
projectId: principal.projectId,
},
})
}

type GrantAccessArgs = {
role: ProjectMemberRole
resourceName: ResourceName
resourceAction: ResourceAction
}

type ThrowPermissionDeniedArgs = {
projectId: ProjectId
resourceName: ResourceName
resourceAction: ResourceAction
}

type GetRoleOrThrowArgs = {
projectId: ProjectId
userId: string
resourceName: ResourceName
resourceAction: ResourceAction
principalRole: ProjectMemberRole
routePermission: Permission | undefined
}
13 changes: 0 additions & 13 deletions packages/server/api/src/app/ee/authentication/rbac/resources.ts

This file was deleted.

Expand Up @@ -9,6 +9,7 @@ import {
ALL_PRINCIPAL_TYPES,
ActivepiecesError,
ErrorCode,
Permission,
PrincipalType,
SERVICE_KEY_SECURITY_OPENAPI,
assertNotNullOrUndefined,
Expand Down Expand Up @@ -101,6 +102,7 @@ async function assertFeatureIsEnabled(
const ListProjectMembersRequestQueryOptions = {
config: {
allowedPrincipals: [PrincipalType.USER, PrincipalType.SERVICE],
permission: Permission.READ_PROJECT_MEMBER,
},
schema: {
tags: ['project-members'],
Expand All @@ -112,6 +114,7 @@ const ListProjectMembersRequestQueryOptions = {
const AddProjectMemberRequest = {
config: {
allowedPrincipals: [PrincipalType.USER, PrincipalType.SERVICE],
permission: Permission.WRITE_PROJECT_MEMBER,
},
schema: {
tags: ['project-members'],
Expand Down Expand Up @@ -140,6 +143,7 @@ const AcceptProjectMemberRequest = {
const DeleteProjectMemberRequest = {
config: {
allowedPrincipals: [PrincipalType.USER, PrincipalType.SERVICE],
permission: Permission.WRITE_PROJECT_MEMBER,
},
schema: {
tags: ['project-members'],
Expand Down

0 comments on commit 49b53db

Please sign in to comment.