14
14
* limitations under the License.
15
15
*/
16
16
17
- import { errorHandler , loggerToWinstonLogger } from '@backstage/backend-common' ;
17
+ import {
18
+ createLegacyAuthAdapters ,
19
+ errorHandler ,
20
+ loggerToWinstonLogger ,
21
+ PluginEndpointDiscovery ,
22
+ } from '@backstage/backend-common' ;
18
23
import {
19
24
coreServices ,
20
25
createBackendPlugin ,
26
+ HttpAuthService ,
27
+ PermissionsService ,
21
28
} from '@backstage/backend-plugin-api' ;
22
29
import { Config } from '@backstage/config' ;
30
+ import { NotAllowedError } from '@backstage/errors' ;
31
+ import {
32
+ AuthorizeResult ,
33
+ BasicPermission ,
34
+ } from '@backstage/plugin-permission-common' ;
35
+ import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node' ;
23
36
24
37
import express from 'express' ;
25
38
import Router from 'express-promise-router' ;
39
+ import { Request } from 'express-serve-static-core' ;
26
40
import { Logger } from 'winston' ;
27
41
28
42
import {
29
43
Cluster ,
30
44
ClusterOverview ,
45
+ ocmClusterReadPermission ,
46
+ ocmEntityPermissions ,
47
+ ocmEntityReadPermission ,
31
48
} from '@janus-idp/backstage-plugin-ocm-common' ;
32
49
33
50
import { readOcmConfigs } from '../helpers/config' ;
@@ -52,11 +69,25 @@ import { ManagedClusterInfo } from '../types';
52
69
export interface RouterOptions {
53
70
logger : Logger ;
54
71
config : Config ;
72
+ discovery : PluginEndpointDiscovery ;
73
+ permissions : PermissionsService ;
74
+ httpAuth ?: HttpAuthService ;
55
75
}
56
76
57
- const buildRouter = ( config : Config , logger : Logger ) => {
77
+ const buildRouter = (
78
+ config : Config ,
79
+ logger : Logger ,
80
+ httpAuth : HttpAuthService ,
81
+ permissions : PermissionsService ,
82
+ ) => {
58
83
const router = Router ( ) ;
84
+
85
+ const permissionsIntegrationRouter = createPermissionIntegrationRouter ( {
86
+ permissions : ocmEntityPermissions ,
87
+ } ) ;
88
+
59
89
router . use ( express . json ( ) ) ;
90
+ router . use ( permissionsIntegrationRouter ) ;
60
91
61
92
const clients = Object . fromEntries (
62
93
readOcmConfigs ( config ) . map ( provider => [
@@ -68,43 +99,63 @@ const buildRouter = (config: Config, logger: Logger) => {
68
99
] ) ,
69
100
) ;
70
101
71
- router . get (
72
- '/status/:providerId/:clusterName' ,
73
- async ( { params : { clusterName, providerId } } , response ) => {
74
- logger . debug (
75
- `Incoming status request for ${ clusterName } cluster on ${ providerId } hub` ,
76
- ) ;
77
-
78
- if ( ! clients . hasOwnProperty ( providerId ) ) {
79
- throw Object . assign ( new Error ( 'Hub not found' ) , {
80
- statusCode : 404 ,
81
- name : 'HubNotFound' ,
82
- } ) ;
83
- }
84
-
85
- const normalizedClusterName = translateResourceToOCM (
86
- clusterName ,
87
- clients [ providerId ] . hubResourceName ,
88
- ) ;
89
-
90
- const mc = await getManagedCluster (
91
- clients [ providerId ] . client ,
92
- normalizedClusterName ,
93
- ) ;
94
- const mci = await getManagedClusterInfo (
95
- clients [ providerId ] . client ,
96
- normalizedClusterName ,
97
- ) ;
98
-
99
- response . send ( {
100
- name : clusterName ,
101
- ...parseManagedCluster ( mc ) ,
102
- ...parseUpdateInfo ( mci ) ,
103
- } as Cluster ) ;
104
- } ,
105
- ) ;
102
+ const authorize = async ( request : Request , permission : BasicPermission ) => {
103
+ const decision = (
104
+ await permissions . authorize ( [ { permission : permission } ] , {
105
+ credentials : await httpAuth . credentials ( request ) ,
106
+ } )
107
+ ) [ 0 ] ;
108
+
109
+ return decision ;
110
+ } ;
111
+
112
+ router . get ( '/status/:providerId/:clusterName' , async ( request , response ) => {
113
+ const decision = await authorize ( request , ocmEntityReadPermission ) ;
114
+
115
+ if ( decision . result === AuthorizeResult . DENY ) {
116
+ throw new NotAllowedError ( 'Unauthorized' ) ;
117
+ }
118
+
119
+ const { clusterName, providerId } = request . params ;
120
+ logger . debug (
121
+ `Incoming status request for ${ clusterName } cluster on ${ providerId } hub` ,
122
+ ) ;
123
+
124
+ if ( ! clients . hasOwnProperty ( providerId ) ) {
125
+ throw Object . assign ( new Error ( 'Hub not found' ) , {
126
+ statusCode : 404 ,
127
+ name : 'HubNotFound' ,
128
+ } ) ;
129
+ }
130
+
131
+ const normalizedClusterName = translateResourceToOCM (
132
+ clusterName ,
133
+ clients [ providerId ] . hubResourceName ,
134
+ ) ;
135
+
136
+ const mc = await getManagedCluster (
137
+ clients [ providerId ] . client ,
138
+ normalizedClusterName ,
139
+ ) ;
140
+ const mci = await getManagedClusterInfo (
141
+ clients [ providerId ] . client ,
142
+ normalizedClusterName ,
143
+ ) ;
144
+
145
+ response . send ( {
146
+ name : clusterName ,
147
+ ...parseManagedCluster ( mc ) ,
148
+ ...parseUpdateInfo ( mci ) ,
149
+ } as Cluster ) ;
150
+ } ) ;
151
+
152
+ router . get ( '/status' , async ( request , response ) => {
153
+ const decision = await authorize ( request , ocmClusterReadPermission ) ;
154
+
155
+ if ( decision . result === AuthorizeResult . DENY ) {
156
+ throw new NotAllowedError ( 'Unauthorized' ) ;
157
+ }
106
158
107
- router . get ( '/status' , async ( _ , response ) => {
108
159
logger . debug ( `Incoming status request for all clusters` ) ;
109
160
110
161
const allClusters = await Promise . all (
@@ -144,8 +195,11 @@ export async function createRouter(
144
195
) : Promise < express . Router > {
145
196
const { logger } = options ;
146
197
const { config } = options ;
198
+ const { permissions } = options ;
199
+
200
+ const { httpAuth } = createLegacyAuthAdapters ( options ) ;
147
201
148
- return buildRouter ( config , logger ) ;
202
+ return buildRouter ( config , logger , httpAuth , permissions ) ;
149
203
}
150
204
151
205
export const ocmPlugin = createBackendPlugin ( {
@@ -156,9 +210,18 @@ export const ocmPlugin = createBackendPlugin({
156
210
logger : coreServices . logger ,
157
211
config : coreServices . rootConfig ,
158
212
http : coreServices . httpRouter ,
213
+ httpAuth : coreServices . httpAuth ,
214
+ permissions : coreServices . permissions ,
159
215
} ,
160
- async init ( { config, logger, http } ) {
161
- http . use ( buildRouter ( config , loggerToWinstonLogger ( logger ) ) ) ;
216
+ async init ( { config, logger, http, httpAuth, permissions } ) {
217
+ http . use (
218
+ buildRouter (
219
+ config ,
220
+ loggerToWinstonLogger ( logger ) ,
221
+ httpAuth ,
222
+ permissions ,
223
+ ) ,
224
+ ) ;
162
225
} ,
163
226
} ) ;
164
227
} ,
0 commit comments