11import  {  assertNonNullish  }  from  'testkit/utils' ; 
2+ import  {  PersonalAccessTokensCache  }  from  '../../../packages/services/api/src/modules/organization/providers/personal-access-tokens-cache' ; 
23import  {  graphql  }  from  '../../testkit/gql' ; 
34import  *  as  GraphQLSchema  from  '../../testkit/gql/graphql' ; 
45import  {  execute  }  from  '../../testkit/graphql' ; 
@@ -299,7 +300,8 @@ test.concurrent('query GraphQL API on resources with access', async ({ expect })
299300    authToken : ownerToken , 
300301  } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
301302  expect ( result . createPersonalAccessToken . error ) . toEqual ( null ) ; 
302-   const  organizationAccessToken  =  result . createPersonalAccessToken . ok ! . privateAccessKey ; 
303+   assertNonNullish ( result . createPersonalAccessToken . ok ) ; 
304+   const  personalAccessToken  =  result . createPersonalAccessToken . ok . privateAccessKey ; 
303305
304306  const  projectQuery  =  await  execute ( { 
305307    document : OrganizationProjectTargetQuery1 , 
@@ -308,7 +310,7 @@ test.concurrent('query GraphQL API on resources with access', async ({ expect })
308310      projectSlug : project . project . slug , 
309311      targetSlug : project . target . slug , 
310312    } , 
311-     authToken : organizationAccessToken , 
313+     authToken : personalAccessToken , 
312314  } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
313315  expect ( projectQuery ) . toEqual ( { 
314316    organization : { 
@@ -376,3 +378,204 @@ test.concurrent('query GraphQL API on resources without access', async ({ expect
376378    } , 
377379  } ) ; 
378380} ) ; 
381+ 
382+ test . concurrent ( 
383+   'query GraphQL API after membership resources have been downgraded' , 
384+   async  ( {  expect } )  =>  { 
385+     const  seed  =  await  initSeed ( ) ; 
386+     const  {  createOrg }  =  await  seed . createOwner ( ) ; 
387+     const  org  =  await  createOrg ( ) ; 
388+     const  project  =  await  org . createProject ( GraphQLSchema . ProjectType . Federation ) ; 
389+ 
390+     const  {  member,  memberToken,  assignMemberRole,  createMemberRole }  = 
391+       await  org . inviteAndJoinMember ( ) ; 
392+ 
393+     const  newRole  =  await  createMemberRole ( [ 
394+       'organization:describe' , 
395+       'project:describe' , 
396+       'personalAccessToken:modify' , 
397+     ] ) ; 
398+ 
399+     // make user also an admin 
400+     await  assignMemberRole ( { 
401+       userId : member . id , 
402+       roleId : newRole . id , 
403+     } ) ; 
404+ 
405+     const  result  =  await  execute ( { 
406+       document : CreatePersonalAccessTokenMutation , 
407+       variables : { 
408+         input : { 
409+           organization : { 
410+             byId : org . organization . id , 
411+           } , 
412+           title : 'a access token' , 
413+           description : 'a description' , 
414+           resources : {  mode : GraphQLSchema . ResourceAssignmentModeType . All  } , 
415+           permissions : [ 'organization:describe' ,  'project:describe' ] , 
416+         } , 
417+       } , 
418+       authToken : memberToken , 
419+     } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
420+ 
421+     expect ( result . createPersonalAccessToken . error ) . toEqual ( null ) ; 
422+     assertNonNullish ( result . createPersonalAccessToken . ok ) ; 
423+ 
424+     const  personalAccessToken  =  result . createPersonalAccessToken . ok . privateAccessKey ; 
425+ 
426+     let  projectQuery  =  await  execute ( { 
427+       document : OrganizationProjectTargetQuery1 , 
428+       variables : { 
429+         organizationSlug : org . organization . slug , 
430+         projectSlug : project . project . slug , 
431+         targetSlug : project . target . slug , 
432+       } , 
433+       authToken : personalAccessToken , 
434+     } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
435+ 
436+     expect ( projectQuery ) . toEqual ( { 
437+       organization : { 
438+         id : org . organization . id , 
439+         project : { 
440+           id : project . project . id , 
441+           slug : project . project . slug , 
442+           targetBySlug : { 
443+             id : project . target . id , 
444+             slug : project . target . slug , 
445+           } , 
446+         } , 
447+         slug : org . organization . slug , 
448+       } , 
449+     } ) ; 
450+ 
451+     // Update member role assignment so it looses access to describe project/target on the resources 
452+     await  assignMemberRole ( { 
453+       userId : member . id , 
454+       roleId : newRole . id , 
455+       resources : { 
456+         mode : GraphQLSchema . ResourceAssignmentModeType . Granular , 
457+         projects : [ ] , 
458+       } , 
459+     } ) ; 
460+ 
461+     // simulate 5 minutes passing by... 
462+     await  seed . purgePersonalAccessTokenById ( 
463+       result . createPersonalAccessToken . ok . createdPersonalAccessToken . id , 
464+     ) ; 
465+ 
466+     projectQuery  =  await  execute ( { 
467+       document : OrganizationProjectTargetQuery1 , 
468+       variables : { 
469+         organizationSlug : org . organization . slug , 
470+         projectSlug : project . project . slug , 
471+         targetSlug : project . target . slug , 
472+       } , 
473+       authToken : personalAccessToken , 
474+     } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
475+ 
476+     expect ( projectQuery ) . toEqual ( { 
477+       organization : { 
478+         id : org . organization . id , 
479+         project : null , 
480+         slug : org . organization . slug , 
481+       } , 
482+     } ) ; 
483+   } , 
484+ ) ; 
485+ 
486+ test . concurrent ( 
487+   'query GraphQL API after membership permissions have been downgraded' , 
488+   async  ( {  expect } )  =>  { 
489+     const  seed  =  await  initSeed ( ) ; 
490+     const  {  createOrg }  =  await  seed . createOwner ( ) ; 
491+     const  org  =  await  createOrg ( ) ; 
492+     const  project  =  await  org . createProject ( GraphQLSchema . ProjectType . Federation ) ; 
493+ 
494+     const  {  member,  memberToken,  assignMemberRole,  createMemberRole,  updateMemberRole }  = 
495+       await  org . inviteAndJoinMember ( ) ; 
496+ 
497+     const  newRole  =  await  createMemberRole ( [ 
498+       'organization:describe' , 
499+       'project:describe' , 
500+       'personalAccessToken:modify' , 
501+     ] ) ; 
502+ 
503+     // make user also an admin 
504+     await  assignMemberRole ( { 
505+       userId : member . id , 
506+       roleId : newRole . id , 
507+     } ) ; 
508+ 
509+     const  result  =  await  execute ( { 
510+       document : CreatePersonalAccessTokenMutation , 
511+       variables : { 
512+         input : { 
513+           organization : { 
514+             byId : org . organization . id , 
515+           } , 
516+           title : 'a access token' , 
517+           description : 'a description' , 
518+           resources : {  mode : GraphQLSchema . ResourceAssignmentModeType . All  } , 
519+           permissions : [ 'organization:describe' ,  'project:describe' ] , 
520+         } , 
521+       } , 
522+       authToken : memberToken , 
523+     } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
524+ 
525+     expect ( result . createPersonalAccessToken . error ) . toEqual ( null ) ; 
526+     assertNonNullish ( result . createPersonalAccessToken . ok ) ; 
527+ 
528+     const  personalAccessToken  =  result . createPersonalAccessToken . ok . privateAccessKey ; 
529+ 
530+     let  projectQuery  =  await  execute ( { 
531+       document : OrganizationProjectTargetQuery1 , 
532+       variables : { 
533+         organizationSlug : org . organization . slug , 
534+         projectSlug : project . project . slug , 
535+         targetSlug : project . target . slug , 
536+       } , 
537+       authToken : personalAccessToken , 
538+     } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
539+ 
540+     expect ( projectQuery ) . toEqual ( { 
541+       organization : { 
542+         id : org . organization . id , 
543+         project : { 
544+           id : project . project . id , 
545+           slug : project . project . slug , 
546+           targetBySlug : { 
547+             id : project . target . id , 
548+             slug : project . target . slug , 
549+           } , 
550+         } , 
551+         slug : org . organization . slug , 
552+       } , 
553+     } ) ; 
554+ 
555+     // Update member role to no longer allow describing projects 
556+     await  updateMemberRole ( newRole ,  [ 'organization:describe' ] ) ; 
557+ 
558+     // simulate 5 minutes passing by... 
559+     await  seed . purgePersonalAccessTokenById ( 
560+       result . createPersonalAccessToken . ok . createdPersonalAccessToken . id , 
561+     ) ; 
562+ 
563+     projectQuery  =  await  execute ( { 
564+       document : OrganizationProjectTargetQuery1 , 
565+       variables : { 
566+         organizationSlug : org . organization . slug , 
567+         projectSlug : project . project . slug , 
568+         targetSlug : project . target . slug , 
569+       } , 
570+       authToken : personalAccessToken , 
571+     } ) . then ( e  =>  e . expectNoGraphQLErrors ( ) ) ; 
572+ 
573+     expect ( projectQuery ) . toEqual ( { 
574+       organization : { 
575+         id : org . organization . id , 
576+         project : null , 
577+         slug : org . organization . slug , 
578+       } , 
579+     } ) ; 
580+   } , 
581+ ) ; 
0 commit comments