Skip to content

Commit 0909adc

Browse files
role verification 50%
1 parent 2578aeb commit 0909adc

File tree

7 files changed

+62
-18
lines changed

7 files changed

+62
-18
lines changed

src/controllers/projects/projects.controller.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,32 @@ import {AuthGuard} from '@nestjs/passport'
77
import { JoiValidationPipe } from '../../pipe/joi-validation.pipe'
88
import { ProjectService } from './../../services/project/project.service';
99
import { projectSchema } from './../../schemas/project.schema';
10-
import { JwtAuthGuard, Public } from '../../modules/auth/guards/jwt-auth.guard'
11-
12-
13-
@UseGuards(JwtAuthGuard)
10+
import { JwtAuthGuard } from '../../modules/auth/guards/jwt-auth.guard'
11+
import { RolesGuard } from '../../modules/auth/guards/roles.guard'
12+
import { Public } from '../../modules/auth/decorators/public.decorator'
13+
import { Roles } from '../../modules/auth/decorators/roles.decorator'
14+
import { Role } from '../../entities/user.entity'
15+
@UseGuards(JwtAuthGuard, RolesGuard)
1416
@Controller('project')
1517
export class ProjectsController {
1618
constructor(private projectService: ProjectService) { }
1719
@Public()
20+
@Roles(Role.DEFAULT)
1821
@Get(":projectID")
1922
@HttpCode(HttpStatus.FOUND)
2023
async get(@Param("projectID", ParseIntPipe) projectID: number): Promise<object> {
2124
return { data: await this.projectService.getProject(projectID) }//AppService.getProject(projectID);
2225
}
2326
@Public()
27+
@Roles(Role.DEFAULT)
2428
@Get()
2529
@HttpCode(HttpStatus.FOUND)
2630
async list(@Query() params: any): Promise<object> {
2731
return { data: await this.projectService.getProjects(params) }
2832
}
33+
2934
@Post()
35+
@Roles(Role.DEFAULT)
3036
@HttpCode(HttpStatus.CREATED)
3137
@UsePipes(new JoiValidationPipe(projectSchema))
3238
async create(@Body() payload: any): Promise<object> {
@@ -35,6 +41,8 @@ export class ProjectsController {
3541

3642
return { msg: "created", data: newProduct };
3743
}
44+
45+
@Roles(Role.DEFAULT)
3846
@Put(":projectID")
3947
@HttpCode(HttpStatus.ACCEPTED)
4048
async update(@Param("projectID", ParseIntPipe) projectID: number, @Body(new JoiValidationPipe(projectSchema)) payload: any): Promise<object> {

src/entities/user.entity.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ import {
99
import { Project } from './project.entity'
1010

1111

12-
export enum UserRole {
12+
export enum Role {
1313
ADMIN = "admin",
14-
EDITOR = "editor",
1514
DEFAULT = "default"
1615
}
1716
@Entity()
@@ -27,10 +26,10 @@ export class User {
2726

2827
@Column({
2928
type: "enum",
30-
enum: UserRole,
31-
default: UserRole.DEFAULT
29+
enum: Role,
30+
default: Role.DEFAULT
3231
})
33-
role: UserRole;
32+
role: Role;
3433

3534
@OneToMany(() => Project, photo => photo.owner, { nullable: true })
3635
projects: Project
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { SetMetadata } from '@nestjs/common';
2+
3+
export const IS_PUBLIC_KEY = 'isPublic';
4+
5+
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { SetMetadata } from '@nestjs/common';
2+
3+
import { Role } from '../../../entities/user.entity'
4+
5+
export const ROLE_KEY = 'roles';
6+
7+
export const Roles = (...roles: Role[]) => SetMetadata(ROLE_KEY, roles.concat(Role.ADMIN));

src/modules/auth/guards/jwt-auth.guard.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,19 @@ import { Reflector } from '@nestjs/core';
33

44
import { AuthGuard } from '@nestjs/passport'
55

6-
import { SetMetadata } from '@nestjs/common';
7-
8-
export const IS_PUBLIC = 'isPublic';
9-
10-
export const Public = () => SetMetadata(IS_PUBLIC, true);
11-
6+
import { IS_PUBLIC_KEY } from '../decorators/public.decorator'
127

138
@Injectable()
149
export class JwtAuthGuard extends AuthGuard('jwt'){
1510
constructor(private reflector: Reflector) {
1611
super()
1712
}
18-
canActivate(ctx: ExecutionContext){
19-
const isPublic = this.reflector.get(IS_PUBLIC, ctx.getHandler())
13+
canActivate(context: ExecutionContext){
14+
const isPublic = this.reflector.get(IS_PUBLIC_KEY, context.getHandler())
2015

2116
if(isPublic){
2217
return true
2318
}
24-
return super.canActivate(ctx)
19+
return super.canActivate(context)
2520
}
2621
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { RolesGuard } from './roles.guard';
2+
3+
describe('RolesGuard', () => {
4+
it('should be defined', () => {
5+
expect(new RolesGuard()).toBeDefined();
6+
});
7+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { CanActivate, ExecutionContext, Injectable, ForbiddenException} from '@nestjs/common';
2+
import { Observable } from 'rxjs';
3+
import { Reflector } from '@nestjs/core';
4+
import { ROLE_KEY } from '../decorators/roles.decorator'
5+
import { Role } from '../../../entities/user.entity'
6+
import { UsersService } from '../../users/services/users/users.service'
7+
@Injectable()
8+
export class RolesGuard implements CanActivate {
9+
constructor(private userService: UsersService, private reflector: Reflector) {
10+
}
11+
12+
async canActivate(
13+
context: ExecutionContext,
14+
): boolean | Promise<boolean> | Observable<boolean> {
15+
const roles = this.reflector.get(ROLE_KEY, context.getHandler())
16+
const request = context.switchToHttp().getRequest();
17+
const userId = request.id
18+
const user = await this.userService.get(userId)
19+
if(user.role == Role.ADMIN) return true
20+
if(roles.some(item => item === user.role)) return true
21+
throw new ForbiddenException('not enough privilages')
22+
}
23+
}

0 commit comments

Comments
 (0)