Skip to content

Commit

Permalink
add route to remove user from agency
Browse files Browse the repository at this point in the history
  • Loading branch information
celineung committed Sep 24, 2024
1 parent dc912c5 commit 97caee0
Show file tree
Hide file tree
Showing 10 changed files with 464 additions and 39 deletions.
25 changes: 24 additions & 1 deletion back/src/adapters/primary/routers/admin/createAdminRouter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Router } from "express";
import { GetDashboardParams, adminRoutes, agencyRoutes, errors } from "shared";
import {
GetDashboardParams,
RemoveAgencyUserParams,
adminRoutes,
agencyRoutes,
errors,
} from "shared";
import { BadRequestError } from "shared";
import { createExpressSharedRouter } from "shared-routes/express";
import type { AppDependencies } from "../../../../config/bootstrap/createAppDependencies";
Expand Down Expand Up @@ -95,6 +101,23 @@ export const createAdminRouter = (deps: AppDependencies): Router => {
}),
);

sharedAdminRouter.removeUserFromAgency(
deps.inclusionConnectAuthMiddleware,
(req, res) =>
sendHttpResponse(req, res, async () => {
const currentUser = req.payloads?.currentUser;
if (!currentUser) throw errors.user.unauthorized();
const userWithAgency: RemoveAgencyUserParams = {
agencyId: req.params.agencyId,
userId: req.params.userId,
};
return await deps.useCases.removeUserFromAgency.execute(
userWithAgency,
currentUser,
);
}),
);

sharedAdminRouter.rejectIcUserForAgency(
deps.inclusionConnectAuthMiddleware,
(req, res) =>
Expand Down
5 changes: 5 additions & 0 deletions back/src/config/bootstrap/createUseCases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ import { GetInclusionConnectedUser } from "../../domains/inclusion-connected-use
import { GetInclusionConnectedUsers } from "../../domains/inclusion-connected-users/use-cases/GetInclusionConnectedUsers";
import { LinkFranceTravailUsersToTheirAgencies } from "../../domains/inclusion-connected-users/use-cases/LinkFranceTravailUsersToTheirAgencies";
import { RejectIcUserForAgency } from "../../domains/inclusion-connected-users/use-cases/RejectIcUserForAgency";
import { makeRemoveUserFromAgency } from "../../domains/inclusion-connected-users/use-cases/RemoveUserFromAgency";
import { UpdateUserForAgency } from "../../domains/inclusion-connected-users/use-cases/UpdateUserForAgency";
import { makeUpdateMarketingEstablishmentContactList } from "../../domains/marketing/use-cases/UpdateMarketingEstablishmentContactsList";
import { AppConfig } from "./appConfig";
Expand Down Expand Up @@ -639,6 +640,10 @@ export const createUseCases = (
createNewEvent,
},
}),
removeUserFromAgency: makeRemoveUserFromAgency({
uowPerformer,
deps: { createNewEvent },
}),
broadcastConventionAgain: makeBroadcastConventionAgain({
uowPerformer,
deps: { createNewEvent, timeGateway: gateways.timeGateway },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { AgencyDto, UserId, errors } from "shared";
import { UnitOfWork } from "../../core/unit-of-work/ports/UnitOfWork";

export const throwIfAgencyDontHaveOtherValidatorsReceivingNotifications =
async (uow: UnitOfWork, agency: AgencyDto, userId: UserId) => {
if (agency.refersToAgencyId !== null) return;

const agencyUsers = await uow.userRepository.getWithFilter({
agencyId: agency.id,
});

const agencyHasOtherValidator = agencyUsers.some(
(agencyUser) =>
agencyUser.id !== userId &&
agencyUser.agencyRights.some(
(right) =>
right.isNotifiedByEmail && right.roles.includes("validator"),
),
);

if (!agencyHasOtherValidator)
throw errors.agency.notEnoughValidators({ agencyId: agency.id });
};

export const throwIfAgencyDontHaveOtherCounsellorsReceivingNotifications =
async (uow: UnitOfWork, agency: AgencyDto, userId: UserId) => {
if (!agency.refersToAgencyId) return;

const agencyUsers = await uow.userRepository.getWithFilter({
agencyId: agency.id,
});

const agencyHasOtherCounsellor = agencyUsers.some(
(agencyUser) =>
agencyUser.id !== userId &&
agencyUser.agencyRights.some(
(right) =>
right.isNotifiedByEmail && right.roles.includes("counsellor"),
),
);

if (!agencyHasOtherCounsellor)
throw errors.agency.notEnoughCounsellors({ agencyId: agency.id });
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {
AgencyDto,
AgencyId,
InclusionConnectedUser,
RemoveAgencyUserParams,
UserId,
errors,
removeAgencyUserParamsSchema,
} from "shared";
import { createTransactionalUseCase } from "../../core/UseCase";
import { UserRepository } from "../../core/authentication/inclusion-connect/port/UserRepository";
import { CreateNewEvent } from "../../core/events/ports/EventBus";
import {
throwIfAgencyDontHaveOtherCounsellorsReceivingNotifications,
throwIfAgencyDontHaveOtherValidatorsReceivingNotifications,
} from "../helpers/throwIfAgencyWontHaveEnoughCounsellorsOrValidators";
import { throwIfNotAdmin } from "../helpers/throwIfIcUserNotBackofficeAdmin";

export type RemoveUserFromAgency = ReturnType<typeof makeRemoveUserFromAgency>;

const getUserAndThrowIfNotFound = async (
userRepository: UserRepository,
userId: UserId,
): Promise<InclusionConnectedUser> => {
const requestedUser = await userRepository.getById(userId);
if (!requestedUser) throw errors.user.notFound({ userId });
return requestedUser;
};

const getAgencyAndThrowIfUserHasNoAgencyRight = (
user: InclusionConnectedUser,
agencyId: AgencyId,
): AgencyDto => {
const userRight = user.agencyRights.find(
(agencyRight) => agencyRight.agency.id === agencyId,
);

if (!userRight)
throw errors.user.expectedRightsOnAgency({
agencyId,
userId: user.id,
});

return userRight.agency;
};

export const makeRemoveUserFromAgency = createTransactionalUseCase<
RemoveAgencyUserParams,
void,
InclusionConnectedUser,
{ createNewEvent: CreateNewEvent }
>(
{ name: "RemoveUserFromAgency", inputSchema: removeAgencyUserParamsSchema },
async ({ currentUser, uow, inputParams }) => {
throwIfNotAdmin(currentUser);
const requestedUser = await getUserAndThrowIfNotFound(
uow.userRepository,
inputParams.userId,
);
const agency = getAgencyAndThrowIfUserHasNoAgencyRight(
requestedUser,
inputParams.agencyId,
);
await throwIfAgencyDontHaveOtherValidatorsReceivingNotifications(
uow,
agency,
inputParams.userId,
);
await throwIfAgencyDontHaveOtherCounsellorsReceivingNotifications(
uow,
agency,
inputParams.userId,
);

const filteredAgencyRights = requestedUser.agencyRights.filter(
(agencyRight) => agencyRight.agency.id !== inputParams.agencyId,
);

await uow.userRepository.updateAgencyRights({
userId: inputParams.userId,
agencyRights: filteredAgencyRights,
});
},
);
Loading

0 comments on commit 97caee0

Please sign in to comment.