Skip to content

Commit

Permalink
fix: permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
sbenfares committed Oct 12, 2023
1 parent a1c476a commit 8808a81
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 23 deletions.
53 changes: 52 additions & 1 deletion server/src/common/actions/helpers/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ObjectId } from "mongodb";
import { getOrganismeById } from "@/common/actions/organismes/organismes.actions";
import logger from "@/common/logger";
import { Organisme } from "@/common/model/@types/Organisme";
import { organismesDb } from "@/common/model/collections";
import { effectifsDb, organismesDb } from "@/common/model/collections";
import { AuthContext } from "@/common/model/internal/AuthContext";
import { OrganisationOrganismeFormation } from "@/common/model/organisations.model";

Expand Down Expand Up @@ -290,6 +290,57 @@ export function findOrganismeFormateursIds(organisme: Organisme): ObjectId[] {
.map((organisme) => organisme._id as ObjectId);
}

/**
* Fonction qui vérifie si on peut supprimer un effectif (en doublon)
* Si c'est un effectif de notre organisme -> OK
* Si c'est un effectif d'un de nos organismes formateur -> OK
* Si on est administrateur -> OK
* Sinon -> KO
* @param ctx
* @param effectifId
* @returns
*/
export const canDeleteEffectifDuplicate = async (ctx: AuthContext, effectifId: ObjectId) => {
// On récupère l'organisme rattaché à l'effectif
const effectifToDelete = await effectifsDb().findOne({ _id: new ObjectId(effectifId) });

if (!effectifToDelete) {
logger.error(effectifId, "effectif non trouvé");
throw new Error("effectif non trouvé");
}

const organisation = ctx.organisation;
switch (organisation.type) {
case "ORGANISME_FORMATION": {
const ofContext = ctx as AuthContext<OrganisationOrganismeFormation>;

const organismeIdForEffectif = effectifToDelete.organisme_id;

// On compare l'organisme de l'effectif à l'organisme du user ou l'un de ses responsables
const organisation = ofContext.organisation;
const userOrganisme = await organismesDb().findOne({
siret: organisation.siret,
uai: organisation.uai as string,
});
if (!userOrganisme) {
logger.error({ siret: organisation.siret, uai: organisation.uai }, "organisme de l'organisation non trouvé");
throw new Error("organisme de l'organisation non trouvé");
}

const organismesResponsablesIdsOfOrganisme = findOrganismeFormateursIds(userOrganisme);

return (
organismeIdForEffectif.equals(userOrganisme._id) ||
organismesResponsablesIdsOfOrganisme.includes(organismeIdForEffectif)
);
}
case "ADMINISTRATEUR":
return true;
}

return false;
};

export async function canAccessOrganismeIndicateurs(ctx: AuthContext, organismeId: ObjectId): Promise<boolean> {
const organisme = await getOrganismeById(organismeId);
const organisation = ctx.organisation;
Expand Down
28 changes: 10 additions & 18 deletions server/src/http/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
fullEffectifsFiltersSchema,
organismesFiltersSchema,
} from "@/common/actions/helpers/filters";
import { canDeleteEffectifDuplicate } from "@/common/actions/helpers/permissions";
import { hasOrganismePermission } from "@/common/actions/helpers/permissions-organisme";
import {
getIndicateursNational,
Expand Down Expand Up @@ -367,6 +368,15 @@ function setupRoutes(app: Application) {
returnResult(async (req) => {
await updateUserProfile(req.user, { has_accept_cgu_version: req.params.version });
})
)
.delete(
"/api/v1/effectif-duplicate/:effectifId",
returnResult(async (req) => {
if (!(await canDeleteEffectifDuplicate(req.user, req.params.effectifId)))
throw Boom.forbidden("Permissions invalides");

await effectifsDb().deleteOne({ _id: new ObjectId(req.params.effectifId) });
})
);

/********************************
Expand Down Expand Up @@ -456,24 +466,6 @@ function setupRoutes(app: Application) {
return await getDuplicatesEffectifsForOrganismeId(res.locals.organismeId);
})
)
.delete(
"/duplicate/:effectifId",
requireOrganismePermission("manageEffectifs"),
async (req, res, next) => {
res.locals.duplicateId = new ObjectId((req.params as any).effectifId);

const isEffectifLinkedToOrganisme = (
await effectifsDb().findOne({ _id: res.locals.duplicateId })
)?.organisme_id.equals(res.locals.organismeId);

if (!isEffectifLinkedToOrganisme) throw Boom.forbidden("Permissions invalides");

next();
},
returnResult(async (req, res) => {
await effectifsDb().deleteOne({ _id: new ObjectId(res.locals.duplicateId) });
})
)
.get(
"/sifa-export",
requireOrganismePermission("manageEffectifs"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import {
} from "@chakra-ui/react";
import { useQueryClient } from "@tanstack/react-query";
import React from "react";
import { useRecoilValue } from "recoil";

import { _delete } from "@/common/httpClient";
import Ribbons from "@/components/Ribbons/Ribbons";
import { organismeAtom } from "@/hooks/organismeAtoms";

import { DuplicateEffectifDetail } from "./models/DuplicateEffectifDetail";

Expand All @@ -32,7 +30,6 @@ const EffectifDoublonDeleteAlertDialog = ({
apprenantNomPrenom: string;
}) => {
const queryClient = useQueryClient();
const organisme = useRecoilValue<any>(organismeAtom);

return (
<AlertDialog isOpen={isOpen} leastDestructiveRef={cancelRef} onClose={onClose} size={"4xl"}>
Expand Down Expand Up @@ -62,7 +59,7 @@ const EffectifDoublonDeleteAlertDialog = ({
<Button
colorScheme="red"
onClick={async () => {
await _delete(`/api/v1/organismes/${organisme?._id}/duplicate/${duplicateDetail?.id}`);
await _delete(`/api/v1/effectif-duplicate/${duplicateDetail?.id}`);
queryClient.invalidateQueries(["duplicates-effectifs"]);
onClose();
}}
Expand Down

0 comments on commit 8808a81

Please sign in to comment.