Skip to content

Commit

Permalink
fix(api): update role based access
Browse files Browse the repository at this point in the history
  • Loading branch information
rajdip-b committed Feb 2, 2024
1 parent 325880e commit 5e3456c
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 46 deletions.
4 changes: 3 additions & 1 deletion apps/api/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { UserModule } from '../user/user.module'
import { ProjectModule } from '../project/project.module'
import { EnvironmentModule } from '../environment/environment.module'
import { ApiKeyModule } from '../api-key/api-key.module'
import { WorkspaceModule } from '../workspace/workspace.module'

@Module({
controllers: [AppController],
Expand All @@ -29,7 +30,8 @@ import { ApiKeyModule } from '../api-key/api-key.module'
ApiKeyModule,
UserModule,
ProjectModule,
EnvironmentModule
EnvironmentModule,
WorkspaceModule
],
providers: [
{
Expand Down
12 changes: 12 additions & 0 deletions apps/api/src/auth/service/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
MAIL_SERVICE
} from '../../mail/services/interface.service'
import { PrismaService } from '../../prisma/prisma.service'
import { WorkspaceRole } from '@prisma/client'

@Injectable()
export class AuthService {
Expand Down Expand Up @@ -179,6 +180,17 @@ export class AuthService {
connect: {
id: user.id
}
},
members: {
create: {
role: WorkspaceRole.OWNER,
invitationAccepted: true,
user: {
connect: {
id: user.id
}
}
}
}
}
})
Expand Down
18 changes: 18 additions & 0 deletions apps/api/src/common/get-permitted.roles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { WorkspaceRole } from '@prisma/client'

const permittedRoles = (role: WorkspaceRole) => {
switch (role) {
case WorkspaceRole.OWNER:
return [
WorkspaceRole.OWNER,
WorkspaceRole.MAINTAINER,
WorkspaceRole.VIEWER
]
case WorkspaceRole.MAINTAINER:
return [WorkspaceRole.MAINTAINER, WorkspaceRole.VIEWER]
case WorkspaceRole.VIEWER:
return [WorkspaceRole.VIEWER]
}
}

export default permittedRoles
2 changes: 1 addition & 1 deletion apps/api/src/project/controller/project.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class ProjectController {
@Post(':workspaceId')
async createProject(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param('workspaceId') workspaceId: Workspace['id'],
@Body() dto: CreateProject
) {
return await this.service.createProject(user, workspaceId, dto)
Expand Down
4 changes: 3 additions & 1 deletion apps/api/src/project/service/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { PrismaService } from '../../prisma/prisma.service'
import { decrypt } from '../../common/decrypt'
import { encrypt } from '../../common/encrypt'
import { WorkspacePermission } from '../../workspace/misc/workspace.permission'
import permittedRoles from '../../common/get-permitted.roles'

@Injectable()
export class ProjectService {
Expand Down Expand Up @@ -412,7 +413,8 @@ export class ProjectService {
// Check for the required membership role
if (
!project.workspace.members.some(
(member) => member.userId === userId && member.role === role
(member) =>
member.userId === userId && permittedRoles(role).includes(role)
)
)
throw new UnauthorizedException(
Expand Down
7 changes: 5 additions & 2 deletions apps/api/src/secret/service/secret.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { SecretWithProjectAndVersion, SecretWithVersion } from '../secret.types'
import { PrismaService } from '../../prisma/prisma.service'
import { addHoursToDate } from '../../common/add-hours-to-date'
import { encrypt } from '../../common/encrypt'
import permittedRoles from '../../common/get-permitted.roles'

@Injectable()
export class SecretService {
Expand Down Expand Up @@ -501,7 +502,8 @@ export class SecretService {
// Check for the required membership role
if (
!secret.project.workspace.members.some(
(member) => member.userId === userId && member.role === role
(member) =>
member.userId === userId && permittedRoles(role).includes(role)
)
)
throw new UnauthorizedException(
Expand Down Expand Up @@ -540,7 +542,8 @@ export class SecretService {
// Check for the required membership role
if (
!project.workspace.members.some(
(member) => member.userId === userId && member.role === role
(member) =>
member.userId === userId && permittedRoles(role).includes(role)
)
)
throw new UnauthorizedException(
Expand Down
13 changes: 12 additions & 1 deletion apps/api/src/user/service/user.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ConflictException, Inject, Injectable, Logger } from '@nestjs/common'
import { UpdateUserDto } from '../dto/update.user/update.user'
import { User } from '@prisma/client'
import { User, WorkspaceRole } from '@prisma/client'
import { excludeFields } from '../../common/exclude-fields'
import { PrismaService } from '../../prisma/prisma.service'
import { CreateUserDto } from '../dto/create.user/create.user'
Expand Down Expand Up @@ -165,6 +165,17 @@ export class UserService {
connect: {
id: newUser.id
}
},
members: {
create: {
role: WorkspaceRole.OWNER,
invitationAccepted: true,
user: {
connect: {
id: newUser.id
}
}
}
}
}
})
Expand Down
38 changes: 19 additions & 19 deletions apps/api/src/workspace/controller/workspace.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class WorkspaceController {
@Put(':workspaceId')
async update(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param('workspaceId') workspaceId: Workspace['id'],
@Body() dto: UpdateWorkspace
) {
return this.workspaceService.updateWorkspace(user, workspaceId, dto)
Expand All @@ -40,24 +40,24 @@ export class WorkspaceController {
@Put(':workspaceId/transfer-ownership/:userId')
async transferOwnership(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param() userId: User['id']
@Param('workspaceId') workspaceId: Workspace['id'],
@Param('userId') userId: User['id']
) {
return this.workspaceService.transferOwnership(user, workspaceId, userId)
}

@Delete(':workspaceId')
async delete(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id']
@Param('workspaceId') workspaceId: Workspace['id']
) {
return this.workspaceService.deleteWorkspace(user, workspaceId)
}

@Post(':workspaceId/add-users')
async addUsers(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param('workspaceId') workspaceId: Workspace['id'],
@Body() members: WorkspaceMemberDTO[]
) {
return this.workspaceService.addUsersToWorkspace(user, workspaceId, members)
Expand All @@ -66,7 +66,7 @@ export class WorkspaceController {
@Delete(':workspaceId/remove-users')
async removeUsers(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param('workspaceId') workspaceId: Workspace['id'],
@Body() userIds: User['id'][]
) {
return this.workspaceService.removeUsersFromWorkspace(
Expand All @@ -79,9 +79,9 @@ export class WorkspaceController {
@Put(':workspaceId/update-member-role/:userId')
async updateMemberRole(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param() userId: User['id'],
@Query() role: WorkspaceRole
@Param('workspaceId') workspaceId: Workspace['id'],
@Param('userId') userId: User['id'],
@Query('role') role: WorkspaceRole
) {
return this.workspaceService.updateMemberRole(
user,
Expand All @@ -94,41 +94,41 @@ export class WorkspaceController {
@Post(':workspaceId/accept-invitation')
async acceptInvitation(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id']
@Param('workspaceId') workspaceId: Workspace['id']
) {
return this.workspaceService.acceptInvitation(user, workspaceId)
}

@Delete(':workspaceId/decline-invitation')
async declineInvitation(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id']
@Param('workspaceId') workspaceId: Workspace['id']
) {
return this.workspaceService.declineInvitation(user, workspaceId)
}

@Delete(':workspaceId/cancel-invitation/:userId')
async cancelInvitation(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param() userId: User['id']
@Param('workspaceId') workspaceId: Workspace['id'],
@Param('userId') userId: User['id']
) {
return this.workspaceService.cancelInvitation(user, workspaceId, userId)
}

@Delete(':workspaceId/leave')
async leave(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id']
@Param('workspaceId') workspaceId: Workspace['id']
) {
return this.workspaceService.leaveWorkspace(user, workspaceId)
}

@Get(':workspaceId/is-member/:userId')
async isMember(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id'],
@Param() userId: User['id']
@Param('workspaceId') workspaceId: Workspace['id'],
@Param('userId') userId: User['id']
) {
return this.workspaceService.isUserMemberOfWorkspace(
user,
Expand All @@ -140,15 +140,15 @@ export class WorkspaceController {
@Get(':workspaceId')
async getWorkspace(
@CurrentUser() user: User,
@Param() workspaceId: Workspace['id']
@Param('workspaceId') workspaceId: Workspace['id']
) {
return this.workspaceService.getWorkspaceById(user, workspaceId)
}

@Get()
async getAllWorkspacesOfUser(
@CurrentUser() user: User,
@Query('page') page: number = 1,
@Query('page') page: number = 0,
@Query('limit') limit: number = 10,
@Query('sort') sort: string = 'name',
@Query('order') order: string = 'asc',
Expand All @@ -167,7 +167,7 @@ export class WorkspaceController {
@UseGuards(AdminGuard)
@Get()
async getAllWorkspaces(
@Query('page') page: number = 1,
@Query('page') page: number = 0,
@Query('limit') limit: number = 10,
@Query('sort') sort: string = 'name',
@Query('order') order: string = 'asc',
Expand Down
19 changes: 3 additions & 16 deletions apps/api/src/workspace/service/workspace.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '../../mail/services/interface.service'
import { JwtService } from '@nestjs/jwt'
import { UpdateWorkspace } from '../dto/update.workspace/update.workspace'
import permittedRoles from '../../common/get-permitted.roles'

@Injectable()
export class WorkspaceService {
Expand Down Expand Up @@ -731,21 +732,6 @@ export class WorkspaceService {
}
})

const permittedRoles = () => {
switch (role) {
case WorkspaceRole.OWNER:
return [
WorkspaceRole.OWNER,
WorkspaceRole.MAINTAINER,
WorkspaceRole.VIEWER
]
case WorkspaceRole.MAINTAINER:
return [WorkspaceRole.MAINTAINER, WorkspaceRole.VIEWER]
case WorkspaceRole.VIEWER:
return [WorkspaceRole.VIEWER]
}
}

// Check if the workspace exists or not
if (!workspace) {
throw new NotFoundException(`Workspace with id ${workspaceId} not found`)
Expand All @@ -754,7 +740,8 @@ export class WorkspaceService {
// Check if the user is a member of the workspace
if (
!workspace.members.some(
(member) => member.userId === userId && permittedRoles().includes(role)
(member) =>
member.userId === userId && permittedRoles(role).includes(role)
)
) {
throw new UnauthorizedException(
Expand Down
5 changes: 0 additions & 5 deletions apps/web/vercel.json

This file was deleted.

0 comments on commit 5e3456c

Please sign in to comment.