From f33ca3a74009e4022462ba2e17dc544438ac0c1a Mon Sep 17 00:00:00 2001 From: stae1102 Date: Thu, 14 Mar 2024 23:45:03 +0900 Subject: [PATCH 1/2] feat: create admin guard --- src/test/is-admin.guard.ts | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/is-admin.guard.ts diff --git a/src/test/is-admin.guard.ts b/src/test/is-admin.guard.ts new file mode 100644 index 0000000..2d58cac --- /dev/null +++ b/src/test/is-admin.guard.ts @@ -0,0 +1,43 @@ +import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; + +@Injectable() +export class IsAdminGuard implements CanActivate { + constructor(private readonly configService: ConfigService) {} + + canActivate(context: ExecutionContext) { + const request = context.switchToHttp().getRequest(); + const authorization = request.headers.authorization; + if (!authorization) { + return false; + } + + if (this.validateAuthorizationHeader(authorization)) { + return false; + } + + const [username, password] = this.decodeAuthorization(authorization); + + if ( + username === this.configService.get('ADMIN_USERNAME') && + password === this.configService.get('ADMIN_PASSWORD') + ) { + return true; + } + + return false; + } + + private validateAuthorizationHeader(authorization: string) { + const [bearer, token] = authorization.split(' '); + if (bearer !== 'Basic' || !token) { + return false; + } + } + + private decodeAuthorization(authorization: string) { + const [_, token] = authorization.split(' '); + const basicAuth = Buffer.from(token, 'base64').toString('utf-8'); + return basicAuth.split(':'); + } +} From f2470a2a7c9ecc35eb61758d36492349230c6952 Mon Sep 17 00:00:00 2001 From: stae1102 Date: Thu, 14 Mar 2024 23:45:46 +0900 Subject: [PATCH 2/2] feat: create tester generating api --- src/app.module.ts | 2 ++ src/categories/category.module.ts | 2 +- src/test/test.controller.ts | 15 ++++++++++++++- src/test/test.module.ts | 7 +++++++ src/test/test.service.ts | 28 ++++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/test/test.service.ts diff --git a/src/app.module.ts b/src/app.module.ts index e95e8e9..ed9afe7 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -16,6 +16,7 @@ import { OpenaiModule } from './openai/openai.module'; import { AppController } from './app.controller'; import { AopModule } from './common/aop/aop.module'; import { InfraModule } from './infra/infra.module'; +import { TestModule } from './test/test.module'; @Module({ imports: [ @@ -109,6 +110,7 @@ import { InfraModule } from './infra/infra.module'; OpenaiModule, AopModule, InfraModule, + TestModule, ], controllers: [AppController], providers: [], diff --git a/src/categories/category.module.ts b/src/categories/category.module.ts index be433a9..2417fda 100644 --- a/src/categories/category.module.ts +++ b/src/categories/category.module.ts @@ -18,6 +18,6 @@ import { CategoryRepository } from './category.repository'; ], controllers: [CategoryController], providers: [CategoryService, ContentRepository, CategoryRepository], - exports: [CategoryRepository], + exports: [CategoryRepository, CategoryService], }) export class CategoryModule {} diff --git a/src/test/test.controller.ts b/src/test/test.controller.ts index fef8537..58ea416 100644 --- a/src/test/test.controller.ts +++ b/src/test/test.controller.ts @@ -1,9 +1,10 @@ -import { Controller, Post, Body } from '@nestjs/common'; +import { Controller, Post, Body, UseGuards } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiOkResponse, ApiBadRequestResponse, + ApiExcludeEndpoint, } from '@nestjs/swagger'; import { ErrorOutput } from '../common/dtos/output.dto'; import { ContentsService } from '../contents/contents.service'; @@ -16,13 +17,17 @@ import { SummarizeContentBodyDto, } from '../contents/dtos/content.dto'; import { CategoryService } from '../categories/category.service'; +import { TestService } from './test.service'; +import { IsAdminGuard } from './is-admin.guard'; @Controller('test') @ApiTags('Test') +@UseGuards(IsAdminGuard) export class TestController { constructor( private readonly contentsService: ContentsService, private readonly categoryService: CategoryService, + private readonly testService: TestService, ) {} @ApiOperation({ @@ -54,4 +59,12 @@ export class TestController { ): Promise { return this.categoryService.autoCategorizeForTest(autoCategorizeBody); } + + @ApiExcludeEndpoint() + @Post('user') + async createTester( + @Body() { email, password }: { email: string; password: string }, + ) { + return this.testService.createTester({ email, password }); + } } diff --git a/src/test/test.module.ts b/src/test/test.module.ts index f973592..b873ff4 100644 --- a/src/test/test.module.ts +++ b/src/test/test.module.ts @@ -1,8 +1,15 @@ import { Module } from '@nestjs/common'; import { CategoryModule } from '../categories/category.module'; import { ContentsModule } from '../contents/contents.module'; +import { TestService } from './test.service'; +import { UserRepository } from '../users/repository/user.repository'; +import { CategoryRepository } from '../categories/category.repository'; +import { IsAdminGuard } from './is-admin.guard'; +import { TestController } from './test.controller'; @Module({ imports: [CategoryModule, ContentsModule], + controllers: [TestController], + providers: [TestService, UserRepository, CategoryRepository, IsAdminGuard], }) export class TestModule {} diff --git a/src/test/test.service.ts b/src/test/test.service.ts new file mode 100644 index 0000000..bb83c41 --- /dev/null +++ b/src/test/test.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@nestjs/common'; +import { UserRepository } from '../users/repository/user.repository'; +import { CategoryRepository } from '../categories/category.repository'; +import { User } from '../users/entities/user.entity'; + +@Injectable() +export class TestService { + constructor( + private readonly userRepository: UserRepository, + private readonly categoryRepository: CategoryRepository, + ) {} + + async createTester({ + email, + password, + }: { + email: string; + password: string; + }): Promise { + const user = new User(); + user.email = email; + user.password = password; + user.name = email.split('@')[0]; + + await this.userRepository.createOne(user); + await this.categoryRepository.createDefaultCategories(user); + } +}