Skip to content

Commit

Permalink
first working casl
Browse files Browse the repository at this point in the history
  • Loading branch information
wermarter committed Dec 29, 2023
1 parent 22a245e commit daa28cd
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const AuthAction = {
BioProduct: extractSecondHalf(
Object.values(BioProductAction),
) as `${BioProductAction}`[],

TestCategory: extractSecondHalf(
Object.values(TestCategoryAction),
) as `${TestCategoryAction}`[],
Expand Down
16 changes: 11 additions & 5 deletions apps/levansy-access-service/src/domain/entity/auth/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MongoAbility } from '@casl/ability'
import { MongoAbility, subject } from '@casl/ability'
import { RecordTypes } from '@casl/mongoose'

import { AuthAction } from './action'
Expand All @@ -11,9 +11,13 @@ export function checkPermission<TSubject extends keyof RecordTypes>(
action: (typeof AuthAction)[TSubject][number],
object?: AuthSubjectType[TSubject],
) {
const subject = AuthSubject[subjectType]
// object type injection
return ability.can(action, subject)
const subjectName = AuthSubject[subjectType]

if (object !== undefined) {
return ability.can(action, subject(subjectName, object))
}

return ability.can(action, subjectName)
}

export function assertPermission<TSubject extends keyof RecordTypes>(
Expand All @@ -24,7 +28,9 @@ export function assertPermission<TSubject extends keyof RecordTypes>(
) {
if (!checkPermission(ability, subjectType, action, object)) {
throw new EAuthzPermissionDeny(
`subject=${AuthSubject[subjectType]} action=${action} object=${object}`,
`subject=${
AuthSubject[subjectType]
} action=${action} object=${JSON.stringify(object)}`,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import '@casl/mongoose'
export enum BioProductAction {
Manage = 'manage',
Read = 'read',
Delete = 'delete',
Update = 'update',
}

declare module '@casl/mongoose' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ export class AuthPopulateContextUseCase {
// create from user role and direct ability
const ability = createMongoAbility([
{
action: BioProductAction.Delete,
action: BioProductAction.Read,
subject: AuthSubject.BioProduct,
},
{
action: BioProductAction.Update,
subject: AuthSubject.BioProduct,
conditions: {
index: 2,
},
},
])

return { user, ability }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class BioProductSearchUseCase {
execute(input: SearchOptions<BioProduct>) {
const { ability } = this.authContext.getData()

assertPermission(ability, 'BioProduct', BioProductAction.Manage)
assertPermission(ability, 'BioProduct', BioProductAction.Read)

return this.bioProductRepository.search(input)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
import { Inject, Injectable } from '@nestjs/common'

import { BioProductAction, assertPermission } from 'src/domain/entity'
import {
AuthContextToken,
BioProductRepositoryToken,
IAuthContext,
IBioProductRepository,
} from 'src/domain/interface'
import { BioProductFindOneUseCase } from './find-one'

@Injectable()
export class BioProductUpdateUseCase {
constructor(
@Inject(BioProductRepositoryToken)
private readonly bioProductRepository: IBioProductRepository,
@Inject(AuthContextToken) private readonly authContext: IAuthContext,
private readonly bioProductFindOneUseCase: BioProductFindOneUseCase,
) {}

execute(...input: Parameters<IBioProductRepository['update']>) {
async execute(...input: Parameters<IBioProductRepository['update']>) {
const { ability } = this.authContext.getData()

const target = await this.bioProductFindOneUseCase.execute({
filter: input[0],
})

if (target === null) {
throw new Error('not found')
}

assertPermission(ability, 'BioProduct', BioProductAction.Update, target)

return this.bioProductRepository.update(...input)
}
}

0 comments on commit daa28cd

Please sign in to comment.