feat: teamEnvironment module added

This commit is contained in:
Mir Arif Hasan
2023-02-08 15:18:46 +06:00
parent 9bee62ada9
commit c5d8a446ae
15 changed files with 1012 additions and 21 deletions

View File

@@ -0,0 +1,83 @@
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import * as TE from 'fp-ts/TaskEither';
import * as O from 'fp-ts/Option';
import * as S from 'fp-ts/string';
import { pipe } from 'fp-ts/function';
import {
getAnnotatedRequiredRoles,
getGqlArg,
getUserFromGQLContext,
namedTrace,
throwErr,
} from 'src/utils';
import { TeamEnvironmentsService } from './team-environments.service';
import {
BUG_AUTH_NO_USER_CTX,
BUG_TEAM_ENV_GUARD_NO_ENV_ID,
BUG_TEAM_ENV_GUARD_NO_REQUIRE_ROLES,
TEAM_ENVIRONMENT_NOT_TEAM_MEMBER,
TEAM_ENVIRONMENT_NOT_FOUND,
} from 'src/errors';
import { TeamService } from 'src/team/team.service';
/**
* A guard which checks whether the caller of a GQL Operation
* is in the team which owns the environment.
* This guard also requires the RequireRole decorator for access control
*/
@Injectable()
export class GqlTeamEnvTeamGuard implements CanActivate {
constructor(
private readonly reflector: Reflector,
private readonly teamEnvironmentService: TeamEnvironmentsService,
private readonly teamService: TeamService,
) {}
canActivate(context: ExecutionContext): Promise<boolean> {
return pipe(
TE.Do,
TE.bindW('requiredRoles', () =>
pipe(
getAnnotatedRequiredRoles(this.reflector, context),
TE.fromOption(() => BUG_TEAM_ENV_GUARD_NO_REQUIRE_ROLES),
),
),
TE.bindW('user', () =>
pipe(
getUserFromGQLContext(context),
TE.fromOption(() => BUG_AUTH_NO_USER_CTX),
),
),
TE.bindW('envID', () =>
pipe(
getGqlArg('id', context),
O.fromPredicate(S.isString),
TE.fromOption(() => BUG_TEAM_ENV_GUARD_NO_ENV_ID),
),
),
TE.bindW('membership', ({ envID, user }) =>
pipe(
this.teamEnvironmentService.getTeamEnvironment(envID),
TE.fromTaskOption(() => TEAM_ENVIRONMENT_NOT_FOUND),
TE.chainW((env) =>
pipe(
this.teamService.getTeamMemberTE(env.teamID, user.uid),
TE.mapLeft(() => TEAM_ENVIRONMENT_NOT_TEAM_MEMBER),
),
),
),
),
TE.map(({ membership, requiredRoles }) =>
requiredRoles.includes(membership.role),
),
TE.getOrElse(throwErr),
)();
}
}