Skip to content

Commit

Permalink
test(api): add e2e tests for secret (#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
rajdip-b authored Feb 19, 2024
1 parent 349014c commit 3960581
Show file tree
Hide file tree
Showing 13 changed files with 1,186 additions and 197 deletions.
4 changes: 3 additions & 1 deletion apps/api/src/common/get-collective-project-authorities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default async function getCollectiveProjectAuthorities(
}
}
},
include: {
select: {
role: {
select: {
authorities: true
Expand All @@ -48,5 +48,7 @@ export default async function getCollectiveProjectAuthorities(
})
})

// console.log('authorities: ', authorities)

return authorities
}
30 changes: 21 additions & 9 deletions apps/api/src/common/get-environment-with-authority.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { NotFoundException, UnauthorizedException } from '@nestjs/common'
import { Authority, Environment, PrismaClient, User } from '@prisma/client'
import {
Authority,
Environment,
PrismaClient,
Project,
User
} from '@prisma/client'
import getCollectiveProjectAuthorities from './get-collective-project-authorities'

export default async function getEnvironmentWithAuthority(
Expand All @@ -9,14 +15,20 @@ export default async function getEnvironmentWithAuthority(
prisma: PrismaClient
): Promise<Environment> {
// Fetch the environment
const environment = await prisma.environment.findUnique({
where: {
id: environmentId
},
include: {
project: true
}
})
let environment: Environment & { project: Project }

try {
environment = await prisma.environment.findUnique({
where: {
id: environmentId
},
include: {
project: true
}
})
} catch (e) {
/* empty */
}

if (!environment) {
throw new NotFoundException(
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/common/get-project-with-authority.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default async function getProjectWithAuthority(
!permittedAuthorities.has(Authority.WORKSPACE_ADMIN)
) {
throw new UnauthorizedException(
`User with id ${userId} does not have the authority ${authority} in the project with id ${projectId}`
`User with id ${userId} does not have the authority in the project with id ${projectId}`
)
}

Expand Down
39 changes: 20 additions & 19 deletions apps/api/src/common/get-secret-with-authority.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Authority, PrismaClient, Secret, User } from '@prisma/client'
import { SecretWithProjectAndVersion } from '../secret/secret.types'
import getCollectiveProjectAuthorities from './get-collective-project-authorities'
import { ConflictException, NotFoundException } from '@nestjs/common'
import { NotFoundException, UnauthorizedException } from '@nestjs/common'

export default async function getSecretWithAuthority(
userId: User['id'],
Expand All @@ -10,23 +10,27 @@ export default async function getSecretWithAuthority(
prisma: PrismaClient
): Promise<SecretWithProjectAndVersion> {
// Fetch the secret
const secret = await prisma.secret.findUnique({
where: {
id: secretId
},
include: {
versions: true,
project: {
include: {
workspace: {
include: {
members: true
}
let secret: SecretWithProjectAndVersion

try {
secret = await prisma.secret.findUnique({
where: {
id: secretId
},
include: {
versions: true,
project: true,
environment: {
select: {
id: true,
name: true
}
}
}
}
})
})
} catch (error) {
/* empty */
}

if (!secret) {
throw new NotFoundException(`Secret with id ${secretId} not found`)
Expand All @@ -44,13 +48,10 @@ export default async function getSecretWithAuthority(
!permittedAuthorities.has(authority) &&
!permittedAuthorities.has(Authority.WORKSPACE_ADMIN)
) {
throw new ConflictException(
throw new UnauthorizedException(
`User ${userId} does not have the required authorities`
)
}

// Remove the workspace from the secret
secret.project.workspace = undefined

return secret
}
15 changes: 3 additions & 12 deletions apps/api/src/environment/environment.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
import { PrismaService } from '../prisma/prisma.service'
import cleanUp from '../common/cleanup'
import {
Authority,
Environment,
EventSeverity,
EventSource,
Expand All @@ -26,11 +25,7 @@ import { ProjectModule } from '../project/project.module'
import { WorkspaceService } from '../workspace/service/workspace.service'
import { ProjectService } from '../project/service/project.service'
import { EventModule } from '../event/event.module'
import { UserModule } from '../user/user.module'
import { WorkspaceModule } from '../workspace/workspace.module'
import { WorkspaceRoleModule } from '../workspace-role/workspace-role.module'
import { SecretModule } from '../secret/secret.module'
import { ApiKeyModule } from '../api-key/api-key.module'

describe('Environment Controller Tests', () => {
let app: NestFastifyApplication
Expand All @@ -48,13 +43,9 @@ describe('Environment Controller Tests', () => {
imports: [
AppModule,
EventModule,
UserModule,
WorkspaceModule,
WorkspaceRoleModule,
SecretModule,
ProjectModule,
EnvironmentModule,
ApiKeyModule
EnvironmentModule
]
})
.overrideProvider(MAIL_SERVICE)
Expand Down Expand Up @@ -186,7 +177,7 @@ describe('Environment Controller Tests', () => {

expect(response.statusCode).toBe(401)
expect(response.json().message).toBe(
`User with id ${user2.id} does not have the authority ${Authority.CREATE_ENVIRONMENT} in the project with id ${project1.id}`
`User with id ${user2.id} does not have the authority in the project with id ${project1.id}`
)
})

Expand Down Expand Up @@ -487,7 +478,7 @@ describe('Environment Controller Tests', () => {

expect(response.statusCode).toBe(401)
expect(response.json().message).toBe(
`User with id ${user2.id} does not have the authority ${Authority.READ_ENVIRONMENT} in the project with id ${project1.id}`
`User with id ${user2.id} does not have the authority in the project with id ${project1.id}`
)
})

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Warnings:
- A unique constraint covering the columns `[projectId,environmentId,name]` on the table `Secret` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[secretId,version]` on the table `SecretVersion` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX "Secret_projectId_environmentId_name_key" ON "Secret"("projectId", "environmentId", "name");

-- CreateIndex
CREATE UNIQUE INDEX "SecretVersion_secretId_version_key" ON "SecretVersion"("secretId", "version");
4 changes: 4 additions & 0 deletions apps/api/src/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ model SecretVersion {
createdOn DateTime @default(now())
createdBy User? @relation(fields: [createdById], references: [id], onUpdate: Cascade, onDelete: SetNull)
createdById String?
@@unique([secretId, version])
}

model Secret {
Expand All @@ -311,6 +313,8 @@ model Secret {
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade, onUpdate: Cascade)
events Event[]
@@unique([projectId, environmentId, name])
}

model ApiKey {
Expand Down
6 changes: 3 additions & 3 deletions apps/api/src/project/project.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ describe('Project Controller Tests', () => {
expect(response.json()).toEqual({
statusCode: 401,
error: 'Unauthorized',
message: `User with id ${user2.id} does not have the authority UPDATE_PROJECT in the project with id ${project1.id}`
message: `User with id ${user2.id} does not have the authority in the project with id ${project1.id}`
})
})

Expand Down Expand Up @@ -462,7 +462,7 @@ describe('Project Controller Tests', () => {
expect(response.json()).toEqual({
statusCode: 401,
error: 'Unauthorized',
message: `User with id ${user2.id} does not have the authority READ_PROJECT in the project with id ${project1.id}`
message: `User with id ${user2.id} does not have the authority in the project with id ${project1.id}`
})
})

Expand Down Expand Up @@ -700,7 +700,7 @@ describe('Project Controller Tests', () => {
expect(response.json()).toEqual({
statusCode: 401,
error: 'Unauthorized',
message: `User with id ${user1.id} does not have the authority DELETE_PROJECT in the project with id ${otherProject.id}`
message: `User with id ${user1.id} does not have the authority in the project with id ${otherProject.id}`
})
})

Expand Down
49 changes: 19 additions & 30 deletions apps/api/src/secret/controller/secret.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import {
Param,
Post,
Put,
Query,
UseGuards
Query
} from '@nestjs/common'
import { SecretService } from '../service/secret.service'
import { CurrentUser } from '../../decorators/user.decorator'
import { Authority, User } from '@prisma/client'
import { CreateSecret } from '../dto/create.secret/create.secret'
import { UpdateSecret } from '../dto/update.secret/update.secret'
import { AdminGuard } from '../../auth/guard/admin/admin.guard'
import { ApiTags } from '@nestjs/swagger'
import { RequiredApiKeyAuthorities } from '../../decorators/required-api-key-authorities.decorator'

Expand Down Expand Up @@ -93,21 +91,12 @@ export class SecretController {
return await this.secretService.getSecretById(user, secretId, decryptValue)
}

@Get(':secretId/versions')
@RequiredApiKeyAuthorities(Authority.READ_SECRET)
async getAllVersionsOfSecret(
@CurrentUser() user: User,
@Param('secretId') secretId: string
) {
return await this.secretService.getAllVersionsOfSecret(user, secretId)
}

@Get('/all/:projectId')
@RequiredApiKeyAuthorities(Authority.READ_SECRET)
async getAllSecretsOfProject(
@CurrentUser() user: User,
@Param('projectId') projectId: string,
@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 @@ -126,21 +115,21 @@ export class SecretController {
)
}

@UseGuards(AdminGuard)
@Get()
async getAllSecrets(
@Query('page') page: number = 1,
@Query('limit') limit: number = 10,
@Query('sort') sort: string = 'name',
@Query('order') order: string = 'asc',
@Query('search') search: string = ''
) {
return await this.secretService.getAllSecrets(
page,
limit,
sort,
order,
search
)
}
// @UseGuards(AdminGuard)
// @Get()
// async getAllSecrets(
// @Query('page') page: number = 1,
// @Query('limit') limit: number = 10,
// @Query('sort') sort: string = 'name',
// @Query('order') order: string = 'asc',
// @Query('search') search: string = ''
// ) {
// return await this.secretService.getAllSecrets(
// page,
// limit,
// sort,
// order,
// search
// )
// }
}
Loading

0 comments on commit 3960581

Please sign in to comment.