Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2744 - Accès au pilotage de convention depuis le pilotage entreprise si j'ai les droits sur l'entreprise qui a le même SIRET qu'une convention #2956

Merged
merged 4 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,8 @@ describe("convention e2e", () => {
status: 404,
body: {
status: 404,
message:
"No convention found with id add5c20e-6dd2-45af-affe-927358005251",
message: errors.convention.notFound({ conventionId: unknownId })
.message,
},
});
});
Expand Down
148 changes: 65 additions & 83 deletions back/src/domains/convention/use-cases/GetConvention.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import {
AgencyWithUsersRights,
ConventionDomainPayload,
ConventionId,
ConventionReadDto,
ConventionRelatedJwtPayload,
ForbiddenError,
InclusionConnectJwtPayload,
NotFoundError,
EmailHash,
Role,
UserId,
WithConventionId,
errors,
getIcUserRoleForAccessingConvention,
Expand All @@ -33,59 +31,44 @@ export class GetConvention extends TransactionalUseCase<
uow: UnitOfWork,
authPayload?: ConventionRelatedJwtPayload,
): Promise<ConventionReadDto> {
if (!authPayload) {
throw new ForbiddenError("No auth payload provided");
}
if (!authPayload) throw errors.user.noJwtProvided();

const convention =
await uow.conventionQueries.getConventionById(conventionId);
if (!convention)
throw new NotFoundError(`No convention found with id ${conventionId}`);

const isConventionDomainPayload = "emailHash" in authPayload;
const isInclusionConnectPayload = this.#isInclusionConnectPayload(
authPayload,
conventionId,
);

const agency = await uow.agencyRepository.getById(convention.agencyId);
if (!agency) {
throw new NotFoundError(`Agency ${convention.agencyId} not found`);
}
if (!convention) throw errors.convention.notFound({ conventionId });

if (isConventionDomainPayload) {
return this.#onConventionDomainPayload({
authPayload,
uow,
convention,
agency,
});
}

if (isInclusionConnectPayload) {
return this.#onInclusionConnectPayload({
authPayload,
uow,
convention,
});
}

throw new ForbiddenError("Incorrect jwt");
return "emailHash" in authPayload
? this.#onConventionDomainPayload({
emailHash: authPayload.emailHash,
role: authPayload.role,
uow,
convention,
})
: this.#onInclusionConnectPayload({
userId: authPayload.userId,
uow,
convention,
});
}

async #onConventionDomainPayload({
authPayload,
role,
emailHash,
convention,
agency,
uow,
}: {
authPayload: ConventionDomainPayload;
role: Role;
emailHash: EmailHash;
convention: ConventionReadDto;
agency: AgencyWithUsersRights;
uow: UnitOfWork;
}): Promise<ConventionReadDto> {
const agency = await uow.agencyRepository.getById(convention.agencyId);
if (!agency)
throw errors.agency.notFound({ agencyId: convention.agencyId });

const isMatchingEmailHash = await this.#isEmailHashMatch({
authPayload,
emailHash,
role,
convention,
agency,
uow,
Expand All @@ -100,70 +83,69 @@ export class GetConvention extends TransactionalUseCase<
}

async #onInclusionConnectPayload({
authPayload,
userId,
convention,
uow,
}: {
authPayload: InclusionConnectJwtPayload;
userId: UserId;
convention: ConventionReadDto;
uow: UnitOfWork;
}): Promise<ConventionReadDto> {
const roles = getIcUserRoleForAccessingConvention(
convention,
await getIcUserByUserId(uow, authPayload.userId),
);
const user = await getIcUserByUserId(uow, userId);

if (!roles.length)
throw new ForbiddenError(
`User with id '${authPayload.userId}' is not allowed to access convention with id '${convention.id}'`,
);
const roles = getIcUserRoleForAccessingConvention(convention, user);
if (roles.length) return convention;

return convention;
}
const establishment =
await uow.establishmentAggregateRepository.getEstablishmentAggregateBySiret(
convention.siret,
);

#isInclusionConnectPayload(
authPayload: ConventionRelatedJwtPayload,
conventionId: ConventionId,
): authPayload is InclusionConnectJwtPayload {
if (!("role" in authPayload)) return true;
if (authPayload.role === "back-office") return false;
if (authPayload.applicationId === conventionId) return false;
throw new ForbiddenError(
`This token is not allowed to access convention with id ${conventionId}. Role was '${authPayload.role}'`,
const hasSomeEstablishmentRights = establishment?.userRights.some(
(userRight) => userRight.userId === user.id,
);

if (hasSomeEstablishmentRights) return convention;

throw errors.convention.forbiddenMissingRights({
conventionId: convention.id,
userId: user.id,
});
}

async #isEmailHashMatch({
authPayload,
emailHash,
role,
convention,
agency,
uow,
}: {
authPayload: ConventionDomainPayload;
emailHash: EmailHash;
role: Role;
convention: ConventionReadDto;
agency: AgencyWithUsersRights;
uow: UnitOfWork;
}): Promise<boolean> {
const isMatchingConventionEmails = await isHashMatchConventionEmails({
const isEmailMatchingPeAdvisor = isHashMatchPeAdvisorEmail({
convention,
emailHash,
});
if (isEmailMatchingPeAdvisor) return true;

const isMatchingConventionEmails = await isHashMatchConventionEmails({
uow,
role,
emailHash,
convention,
agency,
authPayload,
});
const isEmailMatchingIcUserEmails =
await isHashMatchNotNotifiedCounsellorOrValidator({
authPayload,
agency,
uow,
});
const isEmailMatchingPeAdvisor = isHashMatchPeAdvisorEmail({
convention,
authPayload,
if (isMatchingConventionEmails) return true;

return await isHashMatchNotNotifiedCounsellorOrValidator({
uow,
emailHash,
agency,
role,
});
return (
isMatchingConventionEmails ||
isEmailMatchingIcUserEmails ||
isEmailMatchingPeAdvisor
);
}
}
Loading
Loading