diff --git a/.vscode/launch.json b/.vscode/launch.json index ec5331d..94770e3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,4 +19,4 @@ "console": "integratedTerminal" } ] -} \ No newline at end of file +} diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index e664c96..41462f3 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -21,9 +21,12 @@ import { AuthVerifyTotpMfaRequest, } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; +import { PERMISSIONS } from 'src/authentication/permissions.enum'; +import { RequireAllPermissions } from 'src/authentication/authentication.decorator'; import { AuthClientService } from './auth.service'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { GrpcToHttpExceptionFilter } from '../../error/grpc-to-http-exception.filter'; +import { RequestUser, User } from 'src/authentication/user.decorator'; @ApiTags('Auth') @UseFilters(new GrpcToHttpExceptionFilter()) @@ -39,6 +42,21 @@ export class AuthController { this.logger = dadosferaLogger.logger; } + @Post('/sso/snowflake') + @RequireAllPermissions(PERMISSIONS.SNOWFLAKE.permissions.OPEN) + @HttpCode(HttpStatus.OK) + async snowflakeSignIn( + @User() user: RequestUser, + @Body('RelayState') relayState: string, + ) { + this.logger.info('/auth - snowflakeSignIn'); + + return this.authClient.snowflakeSignIn({ + userId: user.user_id, + relayState, + }); + } + @Post('sign-in') @HttpCode(HttpStatus.OK) async signIn(@Body() { username, password, totp }: AuthSignInRequest) { diff --git a/src/modules/auth/auth.service.ts b/src/modules/auth/auth.service.ts index 3dfcec7..9723401 100644 --- a/src/modules/auth/auth.service.ts +++ b/src/modules/auth/auth.service.ts @@ -6,6 +6,7 @@ import { lastValueFrom } from 'rxjs'; import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc'; import { AuthProtoService as AuthServiceInterface } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service'; import { + AuthSnowflakeSignInRequest, AuthSignInRequest, AuthRefreshAccessTokenRequest, AuthEnableTotpMfaRequest, @@ -44,6 +45,12 @@ export class AuthClientService implements OnModuleInit { return lastValueFrom(this.authService.AuthGetPublicKeys({})); } + async snowflakeSignIn(input: AuthSnowflakeSignInRequest) { + this.logger.info('snowflakeSignIn'); + + return lastValueFrom(this.authService.AuthSnowflakeSignIn(input)); + } + async signIn({ username, password, totp }: AuthSignInRequest) { this.logger.info('SignIn'); diff --git a/src/modules/roles/dto/entities.ts b/src/modules/roles/dto/entities.ts index 5652684..18b60a3 100644 --- a/src/modules/roles/dto/entities.ts +++ b/src/modules/roles/dto/entities.ts @@ -23,6 +23,8 @@ export class RoleDto { isPublic: boolean; @ApiProperty({ type: () => Customer }) customer?: Customer; + @ApiProperty() + usage: string; } export class CustomerRole extends OmitType(RoleDto, ['customer']) {} diff --git a/src/modules/roles/roles.service.ts b/src/modules/roles/roles.service.ts index f3f3dcf..b2ecdad 100644 --- a/src/modules/roles/roles.service.ts +++ b/src/modules/roles/roles.service.ts @@ -29,6 +29,7 @@ interface GetRolesPermissionsName { isPublic?: boolean; createdAt: string; updatedAt: string; + usage: string; } @Injectable() export class RolesService { diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts index 3177269..089febf 100644 --- a/src/modules/users/users.controller.ts +++ b/src/modules/users/users.controller.ts @@ -11,7 +11,7 @@ import { Patch, Post, Put, - Req, + Query, UseFilters, } from '@nestjs/common'; import { @@ -172,6 +172,18 @@ export class UsersController { return this.userService.resendInvite({ id }); } + @Delete('role') + @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) + async unassignRoleToUser( + @User() user: RequestUser, + @Query() request: UnassignRoleToUserReq, + @Headers('dadosfera-lang') language, + ) { + this.logger.info('unassignRoleToUser', { user }); + this.userService.setLanguage(language); + return await this.userService.unassignRoleFromUser(request); + } + @Delete(':id') @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) @ApiOkResponse({ type: DeleteUserRes }) @@ -210,18 +222,6 @@ export class UsersController { return await this.userService.assignRoleToUser(body); } - @Delete('role') - @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) - async unassignRoleToUser( - @User() user: RequestUser, - @Req() request: UnassignRoleToUserReq, - @Headers('dadosfera-lang') language, - ) { - this.logger.info('unassignRoleToUser', { user }); - this.userService.setLanguage(language); - return await this.userService.unassignRoleToUser(request); - } - @Patch(':id') @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) @ApiOkResponse({ type: UpdateUserRes }) diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts index f42e152..466b231 100644 --- a/src/modules/users/users.service.ts +++ b/src/modules/users/users.service.ts @@ -162,7 +162,7 @@ export class UsersService implements OnModuleInit { return lastValueFrom(this.usersClientService.AssignRoleToUser(body)); } - async unassignRoleToUser(body: UnassignRoleFromUserRequest) { + async unassignRoleFromUser(body: UnassignRoleFromUserRequest) { return lastValueFrom(this.usersClientService.UnassignRoleFromUser(body)); } diff --git a/src/utils/ErrorBuilder.ts b/src/utils/ErrorBuilder.ts index 3180542..747d726 100644 --- a/src/utils/ErrorBuilder.ts +++ b/src/utils/ErrorBuilder.ts @@ -128,13 +128,46 @@ export function EnrichErrorCode(code: string) { code, }; - case ErrorCodes.ROLE.ALREADY_EXIST: + case ErrorCodes.ROLE.ALREADY_EXISTS: return { statusCode: HttpStatus.BAD_REQUEST, error: 'Grupo já existe', message: 'Não é possível criar um grupo com esse nome', code, }; + + case ErrorCodes.ROLE.ALREADY_EXISTS_PUBLIC: + return { + statusCode: HttpStatus.BAD_REQUEST, + error: 'Grupo já existe', + message: 'Nome conflita com grupo público da Dadosfera', + code, + }; + + case ErrorCodes.ROLE.PERMISSION_ALREADY_GRANTED: + return { + statusCode: HttpStatus.BAD_REQUEST, + error: 'Permissão já inclusa', + message: 'Permissão já consta nesse grupo', + code, + }; + + case ErrorCodes.ROLE.PERMISSION_NOT_GRANTED: + return { + statusCode: HttpStatus.BAD_REQUEST, + error: 'Permissão não inclusa', + message: 'Permissão já consta nesse grupo', + code, + }; + + case ErrorCodes.ROLE.PRIVATE: + return { + statusCode: HttpStatus.FORBIDDEN, + error: 'Não é possivel fazer alterações', + message: 'Você não tem permissão para alterar esse grupo', + code, + }; + case ErrorCodes.ROLE.NOT_FOUND: case ErrorCodes.ROLE.FROM_ANOTHER_CUSTOMER: return { @@ -143,6 +176,7 @@ export function EnrichErrorCode(code: string) { message: 'Grupo solicitado não encontrado', code: ErrorCodes.ROLE.NOT_FOUND, }; + case ErrorCodes.ROLE.CANNOT_EDIT_PUBLIC_ROLE: return { statusCode: HttpStatus.FORBIDDEN, @@ -150,6 +184,7 @@ export function EnrichErrorCode(code: string) { message: 'Você não tem permissão para editar esse grupo', code, }; + case ErrorCodes.USER.NOT_FOUND: return { statusCode: HttpStatus.NOT_FOUND, diff --git a/src/utils/errorCodes.ts b/src/utils/errorCodes.ts index 3a7808d..8a44ae8 100644 --- a/src/utils/errorCodes.ts +++ b/src/utils/errorCodes.ts @@ -14,10 +14,15 @@ export const AUTH = { WEAK_NEW_PASSWORD: 'AUTH.WEAK_NEW_PASSWORD', }; export const ROLE = { - ALREADY_EXIST: 'ROLE.ALREADY_EXISTS', + INVALID_ID: 'ROLE.INVALID_ID', NOT_FOUND: 'ROLE.NOT_FOUND', + ALREADY_EXISTS: 'ROLE.ALREADY_EXISTS', + ALREADY_EXISTS_PUBLIC: 'ROLE.ALREADY_EXISTS_PUBLIC', + PERMISSION_ALREADY_GRANTED: 'ROLE.PERMISSION_ALREADY_GRANTED', + PERMISSION_NOT_GRANTED: 'ROLE.PERMISSION_NOT_GRANTED', FROM_ANOTHER_CUSTOMER: 'ROLE.FROM_ANOTHER_CUSTOMER', CANNOT_EDIT_PUBLIC_ROLE: 'ROLE.CANNOT_EDIT_PUBLIC_ROLE', + PRIVATE: 'ROLE.PRIVATE', }; export const USER = {