@@ -18,17 +18,29 @@ import {
1818 BackstageCredentials ,
1919 BackstageUserPrincipal ,
2020 LoggerService ,
21+ PermissionsService ,
2122} from '@backstage/backend-plugin-api' ;
2223import { RELATION_MEMBER_OF } from '@backstage/catalog-model' ;
2324import { CatalogService } from '@backstage/plugin-catalog-node' ;
25+ import {
26+ createPermission ,
27+ PolicyDecision ,
28+ QueryPermissionRequest ,
29+ } from '@backstage/plugin-permission-common' ;
30+ import { homepageDefaultWidgetsReadPermission } from '@red-hat-developer-hub/backstage-plugin-homepage-common' ;
31+ import { UserContext } from './types' ;
2432
2533export async function buildUserContext ( opts : {
2634 credentials : BackstageCredentials < BackstageUserPrincipal > ;
2735 catalog : CatalogService ;
36+ permissions : PermissionsService ;
37+ referencedPermissions : Set < string > ;
2838 logger : LoggerService ;
29- } ) : Promise < { userEntityRef : string ; groupEntityRefs : Set < string > } > {
30- const { credentials, catalog, logger } = opts ;
39+ } ) : Promise < UserContext > {
40+ const { credentials, catalog, permissions, referencedPermissions, logger } =
41+ opts ;
3142
43+ // user ref
3244 const userEntityRef = credentials . principal . userEntityRef ;
3345 const userEntity = await catalog . getEntityByRef ( userEntityRef , {
3446 credentials,
@@ -39,11 +51,45 @@ export async function buildUserContext(opts: {
3951 `User entity '${ userEntityRef } ' not found in catalog; group-based visibility will fail closed` ,
4052 ) ;
4153 }
54+
55+ // group refs
4256 const groupEntityRefs = new Set < string > (
4357 ( userEntity ?. relations ?? [ ] )
4458 . filter ( relation => relation . type === RELATION_MEMBER_OF )
4559 . map ( relation => relation . targetRef ) ,
4660 ) ;
4761
48- return { userEntityRef, groupEntityRefs } ;
62+ // permissions
63+ const names = [ ...referencedPermissions ] ;
64+ const conditionalPermissionRequests = [
65+ // This default permission will be "removed" below and added as a dedicated
66+ // `defaultWidgetsReadDecision` to the user context.
67+ {
68+ permission : homepageDefaultWidgetsReadPermission ,
69+ } ,
70+ ...names . map < QueryPermissionRequest > ( name => ( {
71+ permission : createPermission ( {
72+ name,
73+ attributes : { action : 'read' } ,
74+ resourceType : 'homepage-default-widget' ,
75+ } ) ,
76+ } ) ) ,
77+ ] ;
78+
79+ const [ defaultWidgetsReadDecision , ...otherConditionalDecisions ] =
80+ await permissions . authorizeConditional ( conditionalPermissionRequests , {
81+ credentials,
82+ } ) ;
83+
84+ const otherPolicyDecisions = new Map < string , PolicyDecision > ( ) ;
85+ otherConditionalDecisions . forEach ( ( decision , index ) => {
86+ otherPolicyDecisions . set ( names [ index ] , decision ) ;
87+ } ) ;
88+
89+ return {
90+ userEntityRef,
91+ groupEntityRefs,
92+ defaultWidgetsReadDecision,
93+ otherPolicyDecisions,
94+ } ;
4995}
0 commit comments