From e3bcaa9ded029cc466efc0d82e2b3c86cb7f3d4e Mon Sep 17 00:00:00 2001 From: "Yassine R." Date: Tue, 5 Nov 2024 00:04:02 +0100 Subject: [PATCH] fix(backend): fix unit test for security --- .../db/dumps/domifa_test.postgres.custom.gz | Bin 104482 -> 104171 bytes ...domifa_test.postgres.restore-data-only.sql | 1 - ...st.postgres.truncate-restore-data-only.sql | 1 - .../auth/guards/usager-doc-access.guard.ts | 10 ++++---- .../usager-docs.controller.security-tests.ts | 23 +++++++++++++----- .../structure-stats.component.html | 3 +++ .../structure-stats.component.ts | 2 +- .../edit-usager-doc.component.html | 2 +- packages/frontend/src/assets/files/news.json | 20 +++++++++++++++ .../src/assets/files/news.json | 13 ++++++++++ 10 files changed, 60 insertions(+), 15 deletions(-) diff --git a/_scripts/db/dumps/domifa_test.postgres.custom.gz b/_scripts/db/dumps/domifa_test.postgres.custom.gz index c3dbdd74dd5cb3174cb772323d6cefff6a06a37e..2c2fc547cf6d91db7429f0d5b646d5fa03d3c4ff 100644 GIT binary patch delta 2678 zcmZ9Oe{faB6~}XKLIO_$M3O-A!XsL01%=$b_wL?%MFI$n1;t4%X0$4p1~e$fq%;*_ zj7EZC$QZ(0!kf}!El@i6V^TQEQi5oxKWIe|$Df!sq*XH1)PP##M;zSU^U%@!@#eGV z*Pi|E-ZR)1jO>xbqI99cM0nG9OF;3!~{Rh0*Tv;h0-7+L)XG zS><(FIPQeFY+DA5M)wFm=DUvi^HeR=cl zA8t@xURCub5<-PMT) z%Pp(0GMc`;NL$qIzg&JbSPfNC>k4i0lnOgmltApsD$s8*Ep0}0sv-A#_jTFBGa%M+ z(LYoBb*8$$ruqvI6ZfSuXI=ED+uZ(WDOlCZq7w~f7te`mr{!buW7(D!E{{qYja9w9 zvc@%FW!FbttBge*JdUGrP3tH5e}BD!Wx z(GRaU`bEpwXv3NhtVh;GHO)FfU-r7@l@M!+Qq7j7npGDb`A_s(FvQj*Sv`ia-&TV961bNfQK}x<>W%lAAoZo4`Q0*5 zdUDTC<59)j0&Ly1jC>(x|KV2#)lD`&l|mQK|M70Ja=d#B#d1HnZU&6R(_0sjE5y6D zH5n8P`~G}Cp^Njk*AsH=d3pt*j}^~uAPjNfxg`dDmaHBJaa`SAXBzjDH3e!}v|}l` zdGfGO>-L>=MBm5p&o`1Q#GNltvjM~Lvej4v7x(RMAmli652XcuvbF#U@q><3LKyWt zor{$(-en>~HFDIlYhNWT-Kf89ELOg}mX;j9>LeXQAMg2FHCe-CPATN$$yZD}LQR{8 zUNbKBz_IUjBaqUYqL%zUZ={+iIi$%iKsy13#kUp;SI zFfT2kzKp2m?F1e@Qb=x&XWw=S1+sTi=;Pvd1F{CV?LCh$#P0X6Go>7xN*((!fwMo1 z8@I!7@lj6b;Fgal$#Jo(%OfZid24iRe;lhm&NNwWs+W@E3Ec3>7_u>{G`}~2A05v!m0SmVdqYAOe|&-w zdU*SPsa5rTtpAjnas|H8mkRI^KD(N#22}NEe*$mmA3`>2Dk?sez{gJ}Oij#)iRXTMlEVk$xa$8I6yagZX*HzOSv^i$HJnM{*{_C@TVU+0PX$OR zB}MY7QuVwSpUb0=09T%;(|9579k|L^)qv{zdV;CTQ^Is!NMPv&5{5f3%mHebyRrpf z5@mU^(*i-vni{L_rgTOO=@bCJlnFVp#mI*nO5Xfh;poBP--GhOY7q%P|gDJ)? zm|SoPP>aHmYli|iJql7MSvw38vM(EkP_!q{4O81{bp)xC>>i;a%11ypMF?4y1J_f8 zpO&ZIdb0mg$diXIg<^^b zz~s$wc!^lZ{4psGnH~=bc_slJ#u*B^yBIn(`!>_lKyJDm4$@jkHL*iS4rOn`h@ z>cS4QR{tIC+nq0C9A2iikZM3uH-aVACWZ3N0RC#6LdfQ8V5ecFi<)t={94#WYa!LH zhYTxSKAx(MtB(;}JjScjQ@w{ws-aKkP{Q0fi-ZYmre||PPQRXH3~Z59edo!-+0d@* W21=eob3lwvZk-FG<db;?$(}r=GlH){&=77nVB!c}~0Ta3Igp$s~9M4M9Seq93{?&Gc?EH{ zRa4-6m(LjLGL*kCl%XNQF~8}aG(h7e7!VM_P!J(0u%4kPf=@`aolFxoP(%CM+cZ%( zn{vaUF#HR)lr$LUSkB^Q1y1$yWL8Cj3w{3LWyjMx3I_gzSvAe%oneqSBnp>0Y>MfP zXh4JTg!88Hy6zEbc9ciJb-9)K3>D65)tzZBUEpEW@SC<(7YxW55zxs-Q8SZ^!l5#; z%q~Nx6~&HiW$lx`517Gj$WUI8I}q%EDntB^lC z4pD>pITI0ecyV45q5(59US&w{_i5%R8&xXXliza;Y5P1EjAuyOH+f+#zAV%}MN&-T-9wJb^DxJk3kgtsDW z3q5_-TZ0K#muWheG7D9qW@!xZ`6iRtuh7F|l-aQ&@P8WC>+Mm*=k9ZVqV2bH(f$<| zJ|jL07r1whc6;o0RxOVs+=m5b%L@Ax+Ep`WL@-3Xg<@urb#vx~2*@gqC!Dz6tX{*cw9RMMWDu^t)Eu@p;{RK0{f-^%Z7RDGOz7f5i21!SD@|{X7jS zeqLFgEv_NR&{qCuL=~Jaw^aw9KczFP$h!jKNHDC~G#}R@Ja{jkP(ck*_E5~U38CP8 zKOcQ6_{@`RyR!O{a9C4~mr!_DPACb3h?-pHS47uomHMk|-F_Jc zd|HGq6>4{5wTcb{EGM(7JRGQ7fha=aKHR3tnD$aVZctUTX?q}~?|&U5>DZymD+f?M zjW^rMdqVo54a}>FaK8bC)MS|Vc^2`cLb|%ekq~GeccToM-{@#nVA};5QH5(4M`9`sQ(eF8fN__@(XB&fqk?F_mT&D%2G8?wB#>4rpl#MYjUp-y6iwcB{-iE^(@P{ct#B-0;F( z?pk7+9Z>N@B-(V$lzP(v-!^+=CIfEXG#Juv_RB2-q5!}95lf}tkFr}>lpw+JR(F65 z2vLC2dvr+AyNV(nwc>#T9^Usww*)>9HB5j?Q7K%TTl zQu~vm%xma-29hsr6nM!xF^HT+#v%_6!6F60%-Ph#s*EA~m|M`TGyw}1M5$sR3AW-S zQp0@oAEX0y!IqCg4zV?DC!LS17D3Wo^oTI)q)zrSrz}||!$>VM8*x_3ugD%-7(roY zM#qsl=BC2jh^P0Z_Yl>bi9*iKrpV66sG~e&g-3{aJ^3|K;=U25!7K>qhRZO8#7x=l02Y^J7EOKOXc+ zpJ!3Mj(B$XMi$ic8<065XzuMZw|{uLHf--I&%@>-4v&|D2MxZ!#BqdjGA30XBYF*8P8voU7zr^=evKey42l-un&9e$nU0ULC*gUiI#R z#@;7it1Wc~6fXbqh%$4vmvct^(>;wl`z&63sbo#z_rp?#$G2WozkBV|X?#Z3kRQ&R^6Woyn z4au=(=TaM+hpzuuyz}7Vs15HWP0XJXeSTSSZgYOmk=aY8f1JEyb#sB~S diff --git a/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql b/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql index d7a27342f4..145d8e7ec0 100644 --- a/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql +++ b/_scripts/db/dumps/domifa_test.postgres.restore-data-only.sql @@ -187,7 +187,6 @@ cc452c79-3669-4dc6-85fa-564631a3d48b 2024-06-10 23:41:59.530897+02 2024-10-29 23 -- COPY public.public_stats_cache (uuid, "createdAt", "updatedAt", version, key, stats) FROM stdin; -127f1519-0037-4715-96b6-2c9e9235474e 2024-10-30 22:33:21.504391+01 2024-10-30 22:33:21.504391+01 1 public-stats {"actifs": 11, "usersCount": 10, "usagersCount": 20, "courrierInCount": 5, "structuresCount": 5, "courrierOutCount": 2, "usagersCountByMonth": [{"name": "oct.", "value": 0}, {"name": "nov.", "value": 0}, {"name": "déc.", "value": 0}, {"name": "janv.", "value": 0}, {"name": "févr.", "value": 0}, {"name": "mars", "value": 0}, {"name": "avr.", "value": 0}, {"name": "mai", "value": 0}, {"name": "juin", "value": 0}, {"name": "juil.", "value": 0}, {"name": "août", "value": 0}, {"name": "sept.", "value": 0}], "structuresCountByRegion": [{"count": 2, "region": "52"}, {"count": 1, "region": "03"}, {"count": 1, "region": "11"}, {"count": 1, "region": "75"}], "interactionsCountByMonth": [{"name": "oct.", "value": 0}, {"name": "nov.", "value": 0}, {"name": "déc.", "value": 0}, {"name": "janv.", "value": 0}, {"name": "févr.", "value": 0}, {"name": "mars", "value": 0}, {"name": "avr.", "value": 0}, {"name": "mai", "value": 0}, {"name": "juin", "value": 0}, {"name": "juil.", "value": 0}, {"name": "août", "value": 0}, {"name": "sept.", "value": 0}], "structuresCountByTypeMap": {"asso": 2, "ccas": 1, "cias": 2}} \. diff --git a/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql b/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql index f3c8defe4a..a97bee2d84 100644 --- a/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql +++ b/_scripts/db/dumps/domifa_test.postgres.truncate-restore-data-only.sql @@ -227,7 +227,6 @@ cc452c79-3669-4dc6-85fa-564631a3d48b 2024-06-10 23:41:59.530897+02 2024-10-29 23 -- COPY public.public_stats_cache (uuid, "createdAt", "updatedAt", version, key, stats) FROM stdin; -127f1519-0037-4715-96b6-2c9e9235474e 2024-10-30 22:33:21.504391+01 2024-10-30 22:33:21.504391+01 1 public-stats {"actifs": 11, "usersCount": 10, "usagersCount": 20, "courrierInCount": 5, "structuresCount": 5, "courrierOutCount": 2, "usagersCountByMonth": [{"name": "oct.", "value": 0}, {"name": "nov.", "value": 0}, {"name": "déc.", "value": 0}, {"name": "janv.", "value": 0}, {"name": "févr.", "value": 0}, {"name": "mars", "value": 0}, {"name": "avr.", "value": 0}, {"name": "mai", "value": 0}, {"name": "juin", "value": 0}, {"name": "juil.", "value": 0}, {"name": "août", "value": 0}, {"name": "sept.", "value": 0}], "structuresCountByRegion": [{"count": 2, "region": "52"}, {"count": 1, "region": "03"}, {"count": 1, "region": "11"}, {"count": 1, "region": "75"}], "interactionsCountByMonth": [{"name": "oct.", "value": 0}, {"name": "nov.", "value": 0}, {"name": "déc.", "value": 0}, {"name": "janv.", "value": 0}, {"name": "févr.", "value": 0}, {"name": "mars", "value": 0}, {"name": "avr.", "value": 0}, {"name": "mai", "value": 0}, {"name": "juin", "value": 0}, {"name": "juil.", "value": 0}, {"name": "août", "value": 0}, {"name": "sept.", "value": 0}], "structuresCountByTypeMap": {"asso": 2, "ccas": 1, "cias": 2}} \. diff --git a/packages/backend/src/auth/guards/usager-doc-access.guard.ts b/packages/backend/src/auth/guards/usager-doc-access.guard.ts index 41201614f7..6a06815394 100644 --- a/packages/backend/src/auth/guards/usager-doc-access.guard.ts +++ b/packages/backend/src/auth/guards/usager-doc-access.guard.ts @@ -17,11 +17,7 @@ export class UsagerDocAccessGuard implements CanActivate { const request = context.switchToHttp().getRequest(); const user = request?.user as UserStructureAuthenticated; - if ( - user?.role === "facteur" || - !isUUID(request.params.docUuid) || - !isNumber(user?.structureId) - ) { + if (!isUUID(request.params.docUuid) || !isNumber(user?.structureId)) { appLogger.error("[UsagerDocAccessGuard] invalid docUuid or structureId", { sentry: true, context: { @@ -34,6 +30,10 @@ export class UsagerDocAccessGuard implements CanActivate { throw new HttpException("USAGER_DOC_NOT_FOUND", HttpStatus.BAD_REQUEST); } + if (user?.role === "facteur") { + throw new HttpException("CANNOT_GET_DOC", HttpStatus.UNAUTHORIZED); + } + const docUuid = request.params.docUuid; try { diff --git a/packages/backend/src/usagers/controllers/security-tests/usager-docs.controller.security-tests.ts b/packages/backend/src/usagers/controllers/security-tests/usager-docs.controller.security-tests.ts index c48bbc3be8..32c3ecea97 100644 --- a/packages/backend/src/usagers/controllers/security-tests/usager-docs.controller.security-tests.ts +++ b/packages/backend/src/usagers/controllers/security-tests/usager-docs.controller.security-tests.ts @@ -43,13 +43,14 @@ export const UsagerDocsControllerSecurityTests: AppTestHttpClientSecurityTestDef context.user, { roles: ["simple", "responsable", "admin"], + validStructureIds: [1], validExpectedResponseStatus: HttpStatus.OK, // filesystem document does not exists in tests } ), }), }, { - label: `${CONTROLLER}.patchDocument`, + label: `${CONTROLLER}.patchDocument (wrong payload)`, query: async (context: AppTestContext) => ({ response: await AppTestHttpClient.patch( "/docs/7/542a0da1-ea1c-48ab-8026-67a4248b1c47", @@ -66,12 +67,16 @@ export const UsagerDocsControllerSecurityTests: AppTestHttpClientSecurityTestDef { roles: ["simple", "responsable", "admin"], validExpectedResponseStatus: HttpStatus.BAD_REQUEST, + invalidStructureIdExpectedResponseStatus: HttpStatus.BAD_REQUEST, + + allowSuperAdminDomifa: false, + validStructureIds: [1], } ), }), }, { - label: `${CONTROLLER}.patchDocument`, + label: `${CONTROLLER}.patchDocument (Good payload)`, query: async (context: AppTestContext) => ({ response: await AppTestHttpClient.patch( "/docs/7/542a0da1-ea1c-48ab-8026-67a4248b1c47", @@ -87,16 +92,19 @@ export const UsagerDocsControllerSecurityTests: AppTestHttpClientSecurityTestDef context.user, { roles: ["simple", "responsable", "admin"], - validExpectedResponseStatus: HttpStatus.BAD_REQUEST, + validExpectedResponseStatus: HttpStatus.OK, + invalidStructureIdExpectedResponseStatus: HttpStatus.BAD_REQUEST, + allowSuperAdminDomifa: false, + validStructureIds: [1], } ), }), }, { - label: `${CONTROLLER}.patchDocument`, + label: `${CONTROLLER}.patchDocument (wrong id)`, query: async (context: AppTestContext) => ({ response: await AppTestHttpClient.patch( - "/docs/7/542a0da1-ea1c-48ab-8026-67a4248b1c47", + "/docs/xxxxxxx/542a0da1-ea1c-48ab-8026-67a4248b1c47", { context, body: { @@ -106,10 +114,13 @@ export const UsagerDocsControllerSecurityTests: AppTestHttpClientSecurityTestDef } ), expectedStatus: expectedResponseStatusBuilder.allowStructureOnly( - { ...context.user, structureRole: "facteur" }, + context.user, { + allowSuperAdminDomifa: false, roles: ["simple", "responsable", "admin"], validExpectedResponseStatus: HttpStatus.BAD_REQUEST, + invalidStructureIdExpectedResponseStatus: HttpStatus.BAD_REQUEST, + validStructureIds: [1], } ), }), diff --git a/packages/frontend/src/app/modules/structure-stats/components/structure-stats/structure-stats.component.html b/packages/frontend/src/app/modules/structure-stats/components/structure-stats/structure-stats.component.html index 64b324388c..9e74339dc4 100644 --- a/packages/frontend/src/app/modules/structure-stats/components/structure-stats/structure-stats.component.html +++ b/packages/frontend/src/app/modules/structure-stats/components/structure-stats/structure-stats.component.html @@ -4,6 +4,9 @@ class="px-0 py-2 mx-0 d-md-flex justify-content-between align-items-center" >

Rapport d'activité et statistiques

+
+ {{ me?.structure.nom }} +