1616
1717import express , { Request } from 'express' ;
1818import Router from 'express-promise-router' ;
19-
19+ import { NotAllowedError } from '@backstage/errors' ;
2020import {
2121 HttpAuthService ,
2222 PermissionsService ,
@@ -31,12 +31,12 @@ import {
3131import {
3232 decodeGetEntitiesRequest ,
3333 decodeGetEntityFacetsRequest ,
34- extensionPluginCreatePermission ,
35- extensionPluginReadPermission ,
34+ extensionsPluginWritePermission ,
35+ extensionsPluginReadPermission ,
3636 MarketplaceApi ,
3737 MarketplacePlugin ,
38- RESOURCE_TYPE_EXTENSION_PLUGIN ,
39- extensionPermissions ,
38+ RESOURCE_TYPE_EXTENSIONS_PLUGIN ,
39+ extensionsPermissions ,
4040} from '@red-hat-developer-hub/backstage-plugin-marketplace-common' ;
4141import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node' ;
4242import { createSearchParams } from './utils/createSearchParams' ;
@@ -55,8 +55,8 @@ export async function createRouter({
5555} ) : Promise < express . Router > {
5656 const router = Router ( ) ;
5757 const permissionsIntegrationRouter = createPermissionIntegrationRouter ( {
58- resourceType : RESOURCE_TYPE_EXTENSION_PLUGIN ,
59- permissions : extensionPermissions ,
58+ resourceType : RESOURCE_TYPE_EXTENSIONS_PLUGIN ,
59+ permissions : extensionsPermissions ,
6060 rules : Object . values ( extensionRules ) ,
6161 } ) ;
6262 router . use ( express . json ( ) ) ;
@@ -65,7 +65,7 @@ export async function createRouter({
6565 const authorizeConditional = async (
6666 request : Request ,
6767 permission :
68- | ResourcePermission < 'extension -plugin' | 'extension -package' >
68+ | ResourcePermission < 'extensions -plugin' | 'extensions -package' >
6969 | BasicPermission ,
7070 ) => {
7171 const credentials = await httpAuth . credentials ( request ) ;
@@ -163,18 +163,18 @@ export async function createRouter({
163163 '/plugin/:namespace/:name/configuration/authorize' ,
164164 async ( req , res ) => {
165165 const [ readDecision , installDecision ] = await Promise . all ( [
166- authorizeConditional ( req , extensionPluginReadPermission ) ,
167- authorizeConditional ( req , extensionPluginCreatePermission ) ,
166+ authorizeConditional ( req , extensionsPluginReadPermission ) ,
167+ authorizeConditional ( req , extensionsPluginWritePermission ) ,
168168 ] ) ;
169169 if (
170170 readDecision . result === AuthorizeResult . DENY &&
171171 installDecision . result === AuthorizeResult . DENY
172172 ) {
173- res . status ( 403 ) ;
173+ res . status ( 200 ) . json ( { read : 'DENY' , write : 'DENY' } ) ;
174174 return ;
175175 }
176176
177- const authorizedActions : string [ ] = [ ] ;
177+ let authorizedActions = { } ;
178178 let plugin : MarketplacePlugin ;
179179
180180 const evaluateConditional = async (
@@ -189,34 +189,35 @@ export async function createRouter({
189189 ) ;
190190 }
191191 if ( matches ( plugin , decision . conditions ) ) {
192- authorizedActions . push ( action ) ;
192+ authorizedActions = { ... authorizedActions , [ action ] : 'ALLOW' } ;
193193 }
194194 } else if ( decision . result === AuthorizeResult . ALLOW ) {
195- authorizedActions . push ( action ) ;
195+ authorizedActions = { ... authorizedActions , [ action ] : 'ALLOW' } ;
196196 }
197197 } ;
198198
199199 await Promise . all ( [
200200 evaluateConditional ( readDecision , 'read' ) ,
201- evaluateConditional ( installDecision , 'create ' ) ,
201+ evaluateConditional ( installDecision , 'write ' ) ,
202202 ] ) ;
203203
204- if ( authorizedActions . length === 0 ) {
205- res . status ( 403 ) ;
206- return ;
204+ if ( Object . keys ( authorizedActions ) . length === 0 ) {
205+ res . status ( 200 ) . json ( { read : 'DENY' , write : 'DENY' } ) ;
206+ } else {
207+ res . status ( 200 ) . json ( authorizedActions ) ;
207208 }
208- res . status ( 200 ) . json ( { authorizedActions } ) ;
209209 } ,
210210 ) ;
211211
212212 router . get ( '/plugin/:namespace/:name/configuration' , async ( req , res ) => {
213213 const readDecision = await authorizeConditional (
214214 req ,
215- extensionPluginReadPermission ,
215+ extensionsPluginReadPermission ,
216216 ) ;
217217 if ( readDecision . result === AuthorizeResult . DENY ) {
218- res . status ( 403 ) . json ( { error : 'Forbidden' } ) ;
219- return ;
218+ throw new NotAllowedError (
219+ `Not allowed to read the configuration of ${ req . params . namespace } :${ req . params . name } ` ,
220+ ) ;
220221 }
221222
222223 const plugin = await marketplaceApi . getPluginByName (
@@ -229,8 +230,9 @@ export async function createRouter({
229230 ( readDecision . result === AuthorizeResult . CONDITIONAL &&
230231 matches ( plugin , readDecision . conditions ) ) ;
231232 if ( ! hasReadAccess ) {
232- res . status ( 403 ) . json ( { error : 'Forbidden' } ) ;
233- return ;
233+ throw new NotAllowedError (
234+ `Not allowed to read the configuration of ${ req . params . namespace } :${ req . params . name } ` ,
235+ ) ;
234236 }
235237
236238 res . status ( 200 ) . json ( { } ) ; // This should return the configuration in YAML string
@@ -240,11 +242,12 @@ export async function createRouter({
240242 // installs the plugin
241243 const installDecision = await authorizeConditional (
242244 req ,
243- extensionPluginCreatePermission ,
245+ extensionsPluginWritePermission ,
244246 ) ;
245247 if ( installDecision . result === AuthorizeResult . DENY ) {
246- res . status ( 403 ) . json ( { error : 'Forbidden' } ) ;
247- return ;
248+ throw new NotAllowedError (
249+ `Not allowed to configure ${ req . params . namespace } :${ req . params . name } ` ,
250+ ) ;
248251 }
249252
250253 const plugin = await marketplaceApi . getPluginByName (
@@ -258,8 +261,9 @@ export async function createRouter({
258261 matches ( plugin , installDecision . conditions ) ) ;
259262
260263 if ( ! hasInstallAccess ) {
261- res . status ( 403 ) . json ( { error : 'Forbidden' } ) ;
262- return ;
264+ throw new NotAllowedError (
265+ `Not allowed to configure ${ req . params . namespace } :${ req . params . name } ` ,
266+ ) ;
263267 }
264268
265269 res . status ( 200 ) . json ( { } ) ;
0 commit comments