getjerry / nest-casl

Casl integration for NestJS
MIT License
225 stars 29 forks source link

Id checking doesn't work properly. It allows patch any user instead of himself #810

Closed rtatarinov closed 10 months ago

rtatarinov commented 10 months ago

Hi, I just use very simple example from documentation I have the following code

export enum Roles {
  Admin = "admin",
  Teacher = "teacher",
  Guest = "guest"
}

Register nest-casl in module

CaslModule.forRoot<Roles, EmployeeResponse, ExpressRequest>({
      superuserRole: Roles.Admin,
      getUserFromRequest: request => request.employee,
})      

Entity is

@Entity({ name: "employees" })
export class EmployeeEntity {
  @PrimaryGeneratedColumn("uuid")
  id: string;

  @Column({
    type: "enum",
    enum: Roles,
    default: Roles.Guest
  })
  roles: Roles[];
}

The permisiion file is

export const permissions: Permissions<Roles, Subjects, Actions> = {
  [Roles.Teacher]({ user, can }) {
    can(Actions.read, EmployeeEntity, { id: user.id });
    can(Actions.update, EmployeeEntity, { id: user.id });
  }
};

And my controller is

  @Patch(":id")
  @UseGuards(AuthGuard, AccessGuard)
  @UseAbility(Actions.update, EmployeeEntity)
  @UsePipes(new ValidationPipe())
  async update(
    @Param("id") id: string,
    @Body() updateEmployeeDto: UpdateEmployeeDto
  ): Promise<EmployeeResponse> {
    const employee = await this.employeeService.update(id, updateEmployeeDto);

    return this.employeeService.buildEmployeeResponse(employee);
  }

And the problem is user with Guest role can update the user with Teacher role. Also it's about @Get(:id). Also any of this user can update Admin. How can fix it?

And the second problem is can(Actions.read, EmployeeEntity, { id: user.id }); also works for findAll method. But I wanna allow read user only himself

liquidautumn commented 10 months ago

@rtatarinov I see you marked it completed, assuming you had some misconfiguration happened. Could you outline what was wrong real quick and what could be done to prevent it in the future? Maybe add some bit of info to README