这里对于casl装饰器有点疑问
来源:12-17 权限控制:与casl集成并完成策略权限控制(作业与奖励)

宝慕林4472258
2023-01-20
这是log实体
import {
Column,
Entity,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { User } from '../../users/entities/users.entity';
import { BaseEntity } from '../../../common/entities/base.entity';
@Entity()
export class Log extends BaseEntity {
@Column()
path: string;
@Column()
method: string;
@Column()
result: number;
@Column()
data: string;
@ManyToOne(() => User, (user) => user.logs, {
onDelete: 'CASCADE',
})
@JoinColumn()
user: User;
}
controller
import { Controller, Delete, Get, UseGuards } from '@nestjs/common';
import { LogsService } from './logs.service';
import { Can, CheckPolicies } from '../../decorators/casl.decorator';
import { ActionEnum } from '../../common/enum/action.enum';
import { CaslGuard } from '../../guards/casl.guard';
import { JwtGuard } from '../../guards/jwt.guard';
import { Log } from './entities/logs.entity';
@Controller('logs')
@UseGuards(JwtGuard, CaslGuard)
export class LogsController {
constructor(private readonly logsService: LogsService) {}
@Delete()
@CheckPolicies((ability) => ability.can(ActionEnum.READ, Log))
getHello() {
return this.logsService.findAll();
}
}
casl.service
import { Injectable } from '@nestjs/common';
import { AbilityBuilder, createMongoAbility } from '@casl/ability';
import { ActionEnum } from '../../common/enum/action.enum';
import { Log } from '../logs/entities/logs.entity';
import { UsersService } from '../users/users.service';
import { User } from '../users/entities/users.entity';
import { Menu } from '../menu/entities/menu.entity';
import { Role } from '../roles/entities/roles.entity';
@Injectable()
export class CaslService {
constructor(private readonly userService: UsersService) {}
async forRoot(id: number) {
const { build, can, cannot } = new AbilityBuilder(createMongoAbility);
const permission = await this.userService.findUserPermissions(id);
permission.forEach((item) => {
const { action, controller } = item;
const entity = this.getEntity(controller);
if (entity) {
can(action as ActionEnum, entity);
}
});
return build({
detectSubjectType: (object) => object.constructor,
});
}
getEntity(key: string) {
const map = {
user: User,
menu: Menu,
role: Role,
log: Log,
};
if (map[key]) {
return map[key];
}
return null;
}
}
例如我想在这里指定用户能够查询method为get的日志,或者进让用户修改自己日志的method字段,实际应用中condition参数提示我需要是一个字符串,有点不理解
写回答
1回答
-
Brian
2023-01-23
我没有看到你定义的casl的装饰器,应该是这样定义的:
export const Can = ( action: Action, subject: InferSubjects<any>, conditions?: any, // 这里可以定义成any )
然后再来说说你的逻辑:
1. 指定用户能够查询method为get的日志——@Can(Action.Read, User, { methed: 'get' })
2. 进让用户修改自己日志的method字段 ——这个可以参考AdminGuard
PS: 这里我有点搞不懂,日志模块在业务上原则上只允许管理员进行管理->一般是删除操作,其他用户可以分配查询权限。
00
相似问题