@red-hat-developer-hub/backstage-plugin-bulk-import-backend 5.3.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,6 @@
2
2
 
3
3
  var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
4
4
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
5
- var backstagePluginAuditLogNode = require('@janus-idp/backstage-plugin-audit-log-node');
6
5
  var formats = require('ajv-formats/dist/formats');
7
6
  var express = require('express');
8
7
  var openapiBackend = require('openapi-backend');
@@ -17,7 +16,7 @@ require('luxon');
17
16
  var githubApiService = require('../github/githubApiService.cjs.js');
18
17
  var auth = require('../helpers/auth.cjs.js');
19
18
  require('@backstage/errors');
20
- var auditLogUtils = require('../helpers/auditLogUtils.cjs.js');
19
+ var auditorUtils = require('../helpers/auditorUtils.cjs.js');
21
20
  var bulkImports = require('./handlers/import/bulkImports.cjs.js');
22
21
  var organizations = require('./handlers/organization/organizations.cjs.js');
23
22
  var ping = require('./handlers/ping/ping.cjs.js');
@@ -27,6 +26,17 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
27
26
 
28
27
  var express__default = /*#__PURE__*/_interopDefaultCompat(express);
29
28
 
29
+ var Operations;
30
+ ((Operations2) => {
31
+ Operations2.PING = "ping";
32
+ Operations2.FIND_ALL_ORGANIZATIONS = "findAllOrganizations";
33
+ Operations2.FIND_ALL_REPOSITORIES = "findAllRepositories";
34
+ Operations2.FIND_REPOSITORIES_BY_ORGANIZATION = "findRepositoriesByOrganization";
35
+ Operations2.FIND_ALL_IMPORTS = "findAllImports";
36
+ Operations2.CREATE_IMPORT_JOBS = "createImportJobs";
37
+ Operations2.FIND_IMPORT_STATUS_BY_REPO = "findImportStatusByRepo";
38
+ Operations2.DELETE_IMPORT_BY_REPO = "deleteImportByRepo";
39
+ })(Operations || (Operations = {}));
30
40
  async function createRouter(options) {
31
41
  const {
32
42
  logger,
@@ -36,13 +46,9 @@ async function createRouter(options) {
36
46
  config,
37
47
  cache,
38
48
  discovery,
39
- catalogApi
49
+ catalogApi,
50
+ auditor
40
51
  } = options;
41
- const auditLogger = new backstagePluginAuditLogNode.DefaultAuditLogger({
42
- logger,
43
- authService: auth$1,
44
- httpAuthService: httpAuth
45
- });
46
52
  const githubApiService$1 = new githubApiService.GithubApiService(logger, config, cache);
47
53
  const catalogHttpClient$1 = new catalogHttpClient.CatalogHttpClient({
48
54
  logger,
@@ -70,12 +76,15 @@ async function createRouter(options) {
70
76
  }
71
77
  });
72
78
  await api.init();
73
- api.register("ping", async (_c, _req, res) => {
74
- const result = await ping.ping(logger);
75
- return res.status(result.statusCode).json(result.responseBody);
76
- });
77
79
  api.register(
78
- "findAllOrganizations",
80
+ Operations.PING,
81
+ async (_c, _req, res) => {
82
+ const result = await ping.ping(logger);
83
+ return res.status(result.statusCode).json(result.responseBody);
84
+ }
85
+ );
86
+ api.register(
87
+ Operations.FIND_ALL_ORGANIZATIONS,
79
88
  async (c, _req, res) => {
80
89
  const q = {
81
90
  ...c.request.query
@@ -99,7 +108,7 @@ async function createRouter(options) {
99
108
  }
100
109
  );
101
110
  api.register(
102
- "findAllRepositories",
111
+ Operations.FIND_ALL_REPOSITORIES,
103
112
  async (c, _req, res) => {
104
113
  const q = {
105
114
  ...c.request.query
@@ -132,7 +141,7 @@ async function createRouter(options) {
132
141
  }
133
142
  );
134
143
  api.register(
135
- "findRepositoriesByOrganization",
144
+ Operations.FIND_REPOSITORIES_BY_ORGANIZATION,
136
145
  async (c, _req, res) => {
137
146
  const q = {
138
147
  ...c.request.query
@@ -164,7 +173,7 @@ async function createRouter(options) {
164
173
  }
165
174
  );
166
175
  api.register(
167
- "findAllImports",
176
+ Operations.FIND_ALL_IMPORTS,
168
177
  async (c, _req, res) => {
169
178
  const h = {
170
179
  ...c.request.headers
@@ -204,7 +213,7 @@ async function createRouter(options) {
204
213
  }
205
214
  );
206
215
  api.register(
207
- "createImportJobs",
216
+ Operations.CREATE_IMPORT_JOBS,
208
217
  async (c, _req, res) => {
209
218
  const q = {
210
219
  ...c.request.query
@@ -229,7 +238,7 @@ async function createRouter(options) {
229
238
  }
230
239
  );
231
240
  api.register(
232
- "findImportStatusByRepo",
241
+ Operations.FIND_IMPORT_STATUS_BY_REPO,
233
242
  async (c, _req, res) => {
234
243
  const q = {
235
244
  ...c.request.query
@@ -252,7 +261,7 @@ async function createRouter(options) {
252
261
  }
253
262
  );
254
263
  api.register(
255
- "deleteImportByRepo",
264
+ Operations.DELETE_IMPORT_BY_REPO,
256
265
  async (c, _req, res) => {
257
266
  const q = {
258
267
  ...c.request.query
@@ -282,7 +291,7 @@ async function createRouter(options) {
282
291
  router.use(async (req, _res, next) => {
283
292
  if (req.path !== "/ping") {
284
293
  await auth.permissionCheck(
285
- auditLogger,
294
+ auditor,
286
295
  api.matchOperation(req)?.operationId,
287
296
  permissions,
288
297
  httpAuth,
@@ -294,17 +303,17 @@ async function createRouter(options) {
294
303
  router.use(async (req, res, next) => {
295
304
  const reqCast = req;
296
305
  const operationId = api.matchOperation(reqCast)?.operationId;
306
+ const auditorEvent = await createAuditorEventByOperationId(
307
+ operationId,
308
+ req,
309
+ auditor
310
+ );
297
311
  try {
298
312
  const response = await api.handleRequest(reqCast, req, res);
299
- auditLogUtils.auditLogRequestSuccess(
300
- auditLogger,
301
- operationId,
302
- req,
303
- response.statusCode
304
- );
313
+ auditorEvent?.success({ meta: { responseStatus: response.statusCode } });
305
314
  next();
306
315
  } catch (err) {
307
- auditLogUtils.auditLogRequestError(auditLogger, operationId, req, err);
316
+ auditorEvent?.fail({ error: err, meta: { responseStatus: 500 } });
308
317
  next(err);
309
318
  }
310
319
  });
@@ -312,6 +321,64 @@ async function createRouter(options) {
312
321
  router.use(middleware.error());
313
322
  return router;
314
323
  }
324
+ async function createAuditorEventByOperationId(operationId, req, auditor) {
325
+ let auditorEvent;
326
+ switch (operationId) {
327
+ case Operations.PING:
328
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, "ping", req);
329
+ break;
330
+ case Operations.FIND_ALL_ORGANIZATIONS:
331
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, "org-read", req, {
332
+ queryType: req.query.search ? "by-query" : "all",
333
+ search: req.query?.search
334
+ });
335
+ break;
336
+ case Operations.FIND_ALL_REPOSITORIES:
337
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, "repo-read", req, {
338
+ queryType: req.query.search ? "by-query" : "all",
339
+ search: req.query.search
340
+ });
341
+ break;
342
+ case Operations.FIND_REPOSITORIES_BY_ORGANIZATION: {
343
+ const organizationName = req.params.organizationName?.toString();
344
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, "repo-read", req, {
345
+ queryType: "by-org",
346
+ organizationName
347
+ });
348
+ break;
349
+ }
350
+ case Operations.FIND_ALL_IMPORTS:
351
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, "import-read", req, {
352
+ queryType: req.query.search ? "by-query" : "all",
353
+ search: req.query.search
354
+ });
355
+ break;
356
+ case Operations.CREATE_IMPORT_JOBS:
357
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, "import-write", req, {
358
+ actionType: "create",
359
+ dryRun: req.query.dryRun
360
+ });
361
+ break;
362
+ case Operations.FIND_IMPORT_STATUS_BY_REPO:
363
+ auditorEvent = await auditorUtils.auditCreateEvent(
364
+ auditor,
365
+ "import-status-read",
366
+ req,
367
+ { queryType: "by-query", repo: req.query.repo }
368
+ );
369
+ break;
370
+ case Operations.DELETE_IMPORT_BY_REPO:
371
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, "import-write", req, {
372
+ actionType: "delete",
373
+ repository: req.query.repo
374
+ });
375
+ break;
376
+ case undefined:
377
+ auditorEvent = await auditorUtils.auditCreateEvent(auditor, operationId, req);
378
+ break;
379
+ }
380
+ return auditorEvent;
381
+ }
315
382
  function stringToNumber(s) {
316
383
  return s ? Number.parseInt(s.toString(), 10) : undefined;
317
384
  }
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport type {\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport type { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\n\nimport {\n DefaultAuditLogger,\n type AuditLogger,\n} from '@janus-idp/backstage-plugin-audit-log-node';\nimport { fullFormats } from 'ajv-formats/dist/formats';\nimport express, { Router, type Request, type Response } from 'express';\nimport {\n OpenAPIBackend,\n type Context,\n type Request as OpenAPIRequest,\n} from 'openapi-backend';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { CatalogHttpClient } from '../catalog/catalogHttpClient';\nimport { CatalogInfoGenerator } from '../catalog/catalogInfoGenerator';\nimport type { Components, Paths } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { permissionCheck } from '../helpers';\nimport {\n auditLogRequestError,\n auditLogRequestSuccess,\n} from '../helpers/auditLogUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n findAllImports,\n findImportStatusByRepo,\n} from './handlers/import';\nimport { findAllOrganizations } from './handlers/organization';\nimport { ping } from './handlers/ping';\nimport {\n findAllRepositories,\n findRepositoriesByOrganization,\n} from './handlers/repository';\n\n/**\n * Router Options\n * @public\n */\nexport interface RouterOptions {\n logger: LoggerService;\n permissions: PermissionEvaluator;\n config: Config;\n cache: CacheService;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n auth: AuthService;\n catalogApi: CatalogApi;\n}\n\n/**\n * Router\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n logger,\n httpAuth,\n auth,\n permissions,\n config,\n cache,\n discovery,\n catalogApi,\n } = options;\n\n const auditLogger: AuditLogger = new DefaultAuditLogger({\n logger: logger,\n authService: auth,\n httpAuthService: httpAuth,\n });\n\n const githubApiService = new GithubApiService(logger, config, cache);\n const catalogHttpClient = new CatalogHttpClient({\n logger,\n config,\n discovery,\n auth,\n catalogApi,\n });\n const catalogInfoGenerator = new CatalogInfoGenerator(\n logger,\n catalogHttpClient,\n );\n\n // create openapi requests handler\n const api = new OpenAPIBackend({\n ajvOpts: {\n verbose: true,\n formats: fullFormats, // open issue: https://github.com/openapistack/openapi-backend/issues/280\n },\n validate: true,\n definition: openApiDocument,\n handlers: {\n validationFail: async (c, _req: Request, res: Response) =>\n res.status(400).json({ err: c.validation.errors }),\n notFound: async (_c, req: Request, res: Response) =>\n res.status(404).json({ err: `'${req.method} ${req.path}' not found` }),\n notImplemented: async (_c, req: Request, res: Response) =>\n res\n .status(500)\n .json({ err: `'${req.method} ${req.path}' not implemented` }),\n },\n });\n\n await api.init();\n\n api.register('ping', async (_c: Context, _req: Request, res: Response) => {\n const result = await ping(logger);\n return res.status(result.statusCode).json(result.responseBody);\n });\n\n api.register(\n 'findAllOrganizations',\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllOrganizations.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n const response = await findAllOrganizations(\n logger,\n githubApiService,\n q.search,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n organizations: response.responseBody?.organizations,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: response.responseBody?.pagePerIntegration,\n sizePerIntegration: response.responseBody?.sizePerIntegration,\n } as Components.Schemas.OrganizationList);\n },\n );\n\n api.register(\n 'findAllRepositories',\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllRepositories.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n const response = await findAllRepositories(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n },\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n 'findRepositoriesByOrganization',\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindRepositoriesByOrganization.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n const response = await findRepositoriesByOrganization(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n c.request.params.organizationName?.toString(),\n q.search,\n q.checkImportStatus,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n 'findAllImports',\n async (c: Context, _req: Request, res: Response) => {\n const h: Paths.FindAllImports.HeaderParameters = {\n ...c.request.headers,\n };\n const apiVersion = h['api-version'];\n const q: Paths.FindAllImports.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n let page: number | undefined;\n let size: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n page = stringToNumber(q.page || q.pagePerIntegration);\n size = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n page = stringToNumber(q.page);\n size = stringToNumber(q.size);\n }\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search: q.search,\n pageNumber: page,\n pageSize: size,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n 'createImportJobs',\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n const q: Paths.CreateImportJobs.QueryParameters = {\n ...c.request.query,\n };\n q.dryRun = stringToBoolean(q.dryRun);\n const response = await createImportJobs(\n {\n logger,\n config,\n auth,\n catalogApi,\n githubApiService,\n catalogInfoGenerator,\n catalogHttpClient,\n },\n {\n importRequests: c.request.requestBody,\n dryRun: q.dryRun,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n 'findImportStatusByRepo',\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n true,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n 'deleteImportByRepo',\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteImportByRepo(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n const router = Router();\n router.use(express.json());\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n permissions: [bulkImportPermission],\n });\n router.use(permissionIntegrationRouter);\n\n router.use(async (req, _res, next) => {\n if (req.path !== '/ping') {\n await permissionCheck(\n auditLogger,\n api.matchOperation(req as OpenAPIRequest)?.operationId,\n permissions,\n httpAuth,\n req,\n ).catch(next);\n }\n next();\n });\n\n router.use(async (req, res, next) => {\n const reqCast = req as OpenAPIRequest;\n const operationId = api.matchOperation(reqCast)?.operationId;\n try {\n const response = (await api.handleRequest(reqCast, req, res)) as Response;\n auditLogRequestSuccess(\n auditLogger,\n operationId,\n req,\n response.statusCode,\n );\n next();\n } catch (err: any) {\n auditLogRequestError(auditLogger, operationId, req, err);\n next(err);\n }\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n router.use(middleware.error());\n\n return router;\n}\n\nfunction stringToNumber(s: number | undefined): number | undefined {\n return s ? Number.parseInt(s.toString(), 10) : undefined;\n}\n\nfunction stringToBoolean(s: boolean | undefined): boolean | undefined {\n if (!s) {\n return undefined;\n }\n return s.toString() === 'true';\n}\n"],"names":["auth","DefaultAuditLogger","githubApiService","GithubApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","ping","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","createImportJobs","findImportStatusByRepo","deleteImportByRepo","Router","express","createPermissionIntegrationRouter","bulkImportPermission","permissionCheck","auditLogRequestSuccess","auditLogRequestError","MiddlewareFactory"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqFA,eAAsB,aACpB,OACyB,EAAA;AACzB,EAAM,MAAA;AAAA,IACJ,MAAA;AAAA,IACA,QAAA;AAAA,UACAA,MAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACE,GAAA,OAAA;AAEJ,EAAM,MAAA,WAAA,GAA2B,IAAIC,8CAAmB,CAAA;AAAA,IACtD,MAAA;AAAA,IACA,WAAa,EAAAD,MAAA;AAAA,IACb,eAAiB,EAAA;AAAA,GAClB,CAAA;AAED,EAAA,MAAME,kBAAmB,GAAA,IAAIC,iCAAiB,CAAA,MAAA,EAAQ,QAAQ,KAAK,CAAA;AACnE,EAAM,MAAAC,mBAAA,GAAoB,IAAIC,mCAAkB,CAAA;AAAA,IAC9C,MAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,UACAL,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AACD,EAAA,MAAMM,yBAAuB,IAAIC,yCAAA;AAAA,IAC/B,MAAA;AAAA,IACAH;AAAA,GACF;AAGA,EAAM,MAAA,GAAA,GAAM,IAAII,6BAAe,CAAA;AAAA,IAC7B,OAAS,EAAA;AAAA,MACP,OAAS,EAAA,IAAA;AAAA,MACT,OAAS,EAAAC;AAAA;AAAA,KACX;AAAA,IACA,QAAU,EAAA,IAAA;AAAA,IACV,UAAY,EAAAC,+BAAA;AAAA,IACZ,QAAU,EAAA;AAAA,MACR,cAAgB,EAAA,OAAO,CAAG,EAAA,IAAA,EAAe,QACvC,GAAI,CAAA,MAAA,CAAO,GAAG,CAAA,CAAE,KAAK,EAAE,GAAA,EAAK,CAAE,CAAA,UAAA,CAAW,QAAQ,CAAA;AAAA,MACnD,UAAU,OAAO,EAAA,EAAI,KAAc,GACjC,KAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,GAAA,EAAK,IAAI,GAAI,CAAA,MAAM,IAAI,GAAI,CAAA,IAAI,eAAe,CAAA;AAAA,MACvE,gBAAgB,OAAO,EAAA,EAAI,KAAc,GACvC,KAAA,GAAA,CACG,OAAO,GAAG,CAAA,CACV,KAAK,EAAE,GAAA,EAAK,IAAI,GAAI,CAAA,MAAM,IAAI,GAAI,CAAA,IAAI,qBAAqB;AAAA;AAClE,GACD,CAAA;AAED,EAAA,MAAM,IAAI,IAAK,EAAA;AAEf,EAAA,GAAA,CAAI,QAAS,CAAA,MAAA,EAAQ,OAAO,EAAA,EAAa,MAAe,GAAkB,KAAA;AACxE,IAAM,MAAA,MAAA,GAAS,MAAMC,SAAA,CAAK,MAAM,CAAA;AAChC,IAAA,OAAO,IAAI,MAAO,CAAA,MAAA,CAAO,UAAU,CAAE,CAAA,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,GAC9D,CAAA;AAED,EAAI,GAAA,CAAA,QAAA;AAAA,IACF,sBAAA;AAAA,IACA,OAAO,CAAY,EAAA,IAAA,EAAe,GAAkB,KAAA;AAClD,MAAA,MAAM,CAAgD,GAAA;AAAA,QACpD,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AAEA,MAAE,CAAA,CAAA,kBAAA,GAAqB,cAAe,CAAA,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAE,CAAA,CAAA,kBAAA,GAAqB,cAAe,CAAA,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAA,MAAM,WAAW,MAAMC,kCAAA;AAAA,QACrB,MAAA;AAAA,QACAV,kBAAA;AAAA,QACA,CAAE,CAAA,MAAA;AAAA,QACF,CAAE,CAAA,kBAAA;AAAA,QACF,CAAE,CAAA;AAAA,OACJ;AACA,MAAA,OAAO,GAAI,CAAA,MAAA,CAAO,QAAS,CAAA,UAAU,EAAE,IAAK,CAAA;AAAA,QAC1C,MAAA,EAAQ,SAAS,YAAc,EAAA,MAAA;AAAA,QAC/B,aAAA,EAAe,SAAS,YAAc,EAAA,aAAA;AAAA,QACtC,UAAA,EAAY,SAAS,YAAc,EAAA,UAAA;AAAA,QACnC,kBAAA,EAAoB,SAAS,YAAc,EAAA,kBAAA;AAAA,QAC3C,kBAAA,EAAoB,SAAS,YAAc,EAAA;AAAA,OACL,CAAA;AAAA;AAC1C,GACF;AAEA,EAAI,GAAA,CAAA,QAAA;AAAA,IACF,qBAAA;AAAA,IACA,OAAO,CAAY,EAAA,IAAA,EAAe,GAAkB,KAAA;AAClD,MAAA,MAAM,CAA+C,GAAA;AAAA,QACnD,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AAEA,MAAE,CAAA,CAAA,kBAAA,GAAqB,cAAe,CAAA,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAE,CAAA,CAAA,kBAAA,GAAqB,cAAe,CAAA,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAE,CAAA,CAAA,iBAAA,GAAoB,eAAgB,CAAA,CAAA,CAAE,iBAAiB,CAAA;AACzD,MAAA,MAAM,WAAW,MAAMW,gCAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,4BACAX,kBAAA;AAAA,6BACAE;AAAA,SACF;AAAA,QACA;AAAA,UACE,QAAQ,CAAE,CAAA,MAAA;AAAA,UACV,aAAa,CAAE,CAAA,iBAAA;AAAA,UACf,YAAY,CAAE,CAAA,kBAAA;AAAA,UACd,UAAU,CAAE,CAAA;AAAA;AACd,OACF;AACA,MAAM,MAAA,KAAA,GAAQ,SAAS,YAAc,EAAA,YAAA;AACrC,MAAA,OAAO,GAAI,CAAA,MAAA,CAAO,QAAS,CAAA,UAAU,EAAE,IAAK,CAAA;AAAA,QAC1C,MAAA,EAAQ,SAAS,YAAc,EAAA,MAAA;AAAA,QAC/B,YAAc,EAAA,KAAA;AAAA,QACd,UAAA,EAAY,SAAS,YAAc,EAAA,UAAA;AAAA,QACnC,oBAAoB,CAAE,CAAA,kBAAA;AAAA,QACtB,oBAAoB,CAAE,CAAA;AAAA,OACc,CAAA;AAAA;AACxC,GACF;AAEA,EAAI,GAAA,CAAA,QAAA;AAAA,IACF,gCAAA;AAAA,IACA,OAAO,CAAY,EAAA,IAAA,EAAe,GAAkB,KAAA;AAClD,MAAA,MAAM,CAA0D,GAAA;AAAA,QAC9D,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AAEA,MAAE,CAAA,CAAA,kBAAA,GAAqB,cAAe,CAAA,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAE,CAAA,CAAA,kBAAA,GAAqB,cAAe,CAAA,CAAA,CAAE,kBAAkB,CAAA;AAC1D,MAAE,CAAA,CAAA,iBAAA,GAAoB,eAAgB,CAAA,CAAA,CAAE,iBAAiB,CAAA;AACzD,MAAA,MAAM,WAAW,MAAMU,2CAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,4BACAZ,kBAAA;AAAA,6BACAE;AAAA,SACF;AAAA,QACA,CAAE,CAAA,OAAA,CAAQ,MAAO,CAAA,gBAAA,EAAkB,QAAS,EAAA;AAAA,QAC5C,CAAE,CAAA,MAAA;AAAA,QACF,CAAE,CAAA,iBAAA;AAAA,QACF,CAAE,CAAA,kBAAA;AAAA,QACF,CAAE,CAAA;AAAA,OACJ;AACA,MAAM,MAAA,KAAA,GAAQ,SAAS,YAAc,EAAA,YAAA;AACrC,MAAA,OAAO,GAAI,CAAA,MAAA,CAAO,QAAS,CAAA,UAAU,EAAE,IAAK,CAAA;AAAA,QAC1C,MAAA,EAAQ,SAAS,YAAc,EAAA,MAAA;AAAA,QAC/B,YAAc,EAAA,KAAA;AAAA,QACd,UAAA,EAAY,SAAS,YAAc,EAAA,UAAA;AAAA,QACnC,oBAAoB,CAAE,CAAA,kBAAA;AAAA,QACtB,oBAAoB,CAAE,CAAA;AAAA,OACc,CAAA;AAAA;AACxC,GACF;AAEA,EAAI,GAAA,CAAA,QAAA;AAAA,IACF,gBAAA;AAAA,IACA,OAAO,CAAY,EAAA,IAAA,EAAe,GAAkB,KAAA;AAClD,MAAA,MAAM,CAA2C,GAAA;AAAA,QAC/C,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AACA,MAAM,MAAA,UAAA,GAAa,EAAE,aAAa,CAAA;AAClC,MAAA,MAAM,CAA0C,GAAA;AAAA,QAC9C,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AAEA,MAAI,IAAA,IAAA;AACJ,MAAI,IAAA,IAAA;AACJ,MAAI,IAAA,UAAA,KAAe,SAAa,IAAA,UAAA,KAAe,IAAM,EAAA;AAEnD,QAAA,IAAA,GAAO,cAAe,CAAA,CAAA,CAAE,IAAQ,IAAA,CAAA,CAAE,kBAAkB,CAAA;AACpD,QAAA,IAAA,GAAO,cAAe,CAAA,CAAA,CAAE,IAAQ,IAAA,CAAA,CAAE,kBAAkB,CAAA;AAAA,OAC/C,MAAA;AAEL,QAAO,IAAA,GAAA,cAAA,CAAe,EAAE,IAAI,CAAA;AAC5B,QAAO,IAAA,GAAA,cAAA,CAAe,EAAE,IAAI,CAAA;AAAA;AAE9B,MAAA,MAAM,WAAW,MAAMW,0BAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,4BACAb,kBAAA;AAAA,6BACAE;AAAA,SACF;AAAA,QACA;AAAA,UACE;AAAA,SACF;AAAA,QACA;AAAA,UACE,QAAQ,CAAE,CAAA,MAAA;AAAA,UACV,UAAY,EAAA,IAAA;AAAA,UACZ,QAAU,EAAA,IAAA;AAAA,UACV,YAAY,CAAE,CAAA,UAAA;AAAA,UACd,WAAW,CAAE,CAAA;AAAA;AACf,OACF;AACA,MAAA,OAAO,IAAI,MAAO,CAAA,QAAA,CAAS,UAAU,CAAE,CAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA;AACnE,GACF;AAEA,EAAI,GAAA,CAAA,QAAA;AAAA,IACF,kBAAA;AAAA,IACA,OACE,CACA,EAAA,IAAA,EACA,GACG,KAAA;AACH,MAAA,MAAM,CAA4C,GAAA;AAAA,QAChD,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AACA,MAAE,CAAA,CAAA,MAAA,GAAS,eAAgB,CAAA,CAAA,CAAE,MAAM,CAAA;AACnC,MAAA,MAAM,WAAW,MAAMY,4BAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,gBACAhB,MAAA;AAAA,UACA,UAAA;AAAA,4BACAE,kBAAA;AAAA,gCACAI,sBAAA;AAAA,6BACAF;AAAA,SACF;AAAA,QACA;AAAA,UACE,cAAA,EAAgB,EAAE,OAAQ,CAAA,WAAA;AAAA,UAC1B,QAAQ,CAAE,CAAA;AAAA;AACZ,OACF;AACA,MAAA,OAAO,IAAI,MAAO,CAAA,QAAA,CAAS,UAAU,CAAE,CAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA;AACnE,GACF;AAEA,EAAI,GAAA,CAAA,QAAA;AAAA,IACF,wBAAA;AAAA,IACA,OAAO,CAAY,EAAA,IAAA,EAAe,GAAkB,KAAA;AAClD,MAAA,MAAM,CAAkD,GAAA;AAAA,QACtD,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAM,EAAA,IAAA,EAAQ,EAAA;AACnB,QAAM,MAAA,IAAI,MAAM,4BAA4B,CAAA;AAAA;AAE9C,MAAA,MAAM,WAAW,MAAMa,kCAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,4BACAf,kBAAA;AAAA,6BACAE;AAAA,SACF;AAAA,QACA,CAAE,CAAA,IAAA;AAAA,QACF,CAAE,CAAA,aAAA;AAAA,QACF;AAAA,OACF;AACA,MAAA,OAAO,IAAI,MAAO,CAAA,QAAA,CAAS,UAAU,CAAE,CAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA;AACnE,GACF;AAEA,EAAI,GAAA,CAAA,QAAA;AAAA,IACF,oBAAA;AAAA,IACA,OAAO,CAAY,EAAA,IAAA,EAAe,GAAkB,KAAA;AAClD,MAAA,MAAM,CAA8C,GAAA;AAAA,QAClD,GAAG,EAAE,OAAQ,CAAA;AAAA,OACf;AACA,MAAA,IAAI,CAAC,CAAA,CAAE,IAAM,EAAA,IAAA,EAAQ,EAAA;AACnB,QAAM,MAAA,IAAI,MAAM,mCAAmC,CAAA;AAAA;AAErD,MAAA,MAAM,WAAW,MAAMc,8BAAA;AAAA,QACrB;AAAA,UACE,MAAA;AAAA,UACA,MAAA;AAAA,4BACAhB,kBAAA;AAAA,6BACAE;AAAA,SACF;AAAA,QACA,CAAE,CAAA,IAAA;AAAA,QACF,CAAE,CAAA;AAAA,OACJ;AACA,MAAA,OAAO,IAAI,MAAO,CAAA,QAAA,CAAS,UAAU,CAAE,CAAA,IAAA,CAAK,SAAS,YAAY,CAAA;AAAA;AACnE,GACF;AAEA,EAAA,MAAM,SAASe,cAAO,EAAA;AACtB,EAAO,MAAA,CAAA,GAAA,CAAIC,wBAAQ,CAAA,IAAA,EAAM,CAAA;AAEzB,EAAA,MAAM,8BAA8BC,sDAAkC,CAAA;AAAA,IACpE,WAAA,EAAa,CAACC,oDAAoB;AAAA,GACnC,CAAA;AACD,EAAA,MAAA,CAAO,IAAI,2BAA2B,CAAA;AAEtC,EAAA,MAAA,CAAO,GAAI,CAAA,OAAO,GAAK,EAAA,IAAA,EAAM,IAAS,KAAA;AACpC,IAAI,IAAA,GAAA,CAAI,SAAS,OAAS,EAAA;AACxB,MAAM,MAAAC,oBAAA;AAAA,QACJ,WAAA;AAAA,QACA,GAAA,CAAI,cAAe,CAAA,GAAqB,CAAG,EAAA,WAAA;AAAA,QAC3C,WAAA;AAAA,QACA,QAAA;AAAA,QACA;AAAA,OACF,CAAE,MAAM,IAAI,CAAA;AAAA;AAEd,IAAK,IAAA,EAAA;AAAA,GACN,CAAA;AAED,EAAA,MAAA,CAAO,GAAI,CAAA,OAAO,GAAK,EAAA,GAAA,EAAK,IAAS,KAAA;AACnC,IAAA,MAAM,OAAU,GAAA,GAAA;AAChB,IAAA,MAAM,WAAc,GAAA,GAAA,CAAI,cAAe,CAAA,OAAO,CAAG,EAAA,WAAA;AACjD,IAAI,IAAA;AACF,MAAA,MAAM,WAAY,MAAM,GAAA,CAAI,aAAc,CAAA,OAAA,EAAS,KAAK,GAAG,CAAA;AAC3D,MAAAC,oCAAA;AAAA,QACE,WAAA;AAAA,QACA,WAAA;AAAA,QACA,GAAA;AAAA,QACA,QAAS,CAAA;AAAA,OACX;AACA,MAAK,IAAA,EAAA;AAAA,aACE,GAAU,EAAA;AACjB,MAAqBC,kCAAA,CAAA,WAAA,EAAa,WAAa,EAAA,GAAA,EAAK,GAAG,CAAA;AACvD,MAAA,IAAA,CAAK,GAAG,CAAA;AAAA;AACV,GACD,CAAA;AAED,EAAA,MAAM,aAAaC,gCAAkB,CAAA,MAAA,CAAO,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAC9D,EAAO,MAAA,CAAA,GAAA,CAAI,UAAW,CAAA,KAAA,EAAO,CAAA;AAE7B,EAAO,OAAA,MAAA;AACT;AAEA,SAAS,eAAe,CAA2C,EAAA;AACjE,EAAA,OAAO,IAAI,MAAO,CAAA,QAAA,CAAS,EAAE,QAAS,EAAA,EAAG,EAAE,CAAI,GAAA,SAAA;AACjD;AAEA,SAAS,gBAAgB,CAA6C,EAAA;AACpE,EAAA,IAAI,CAAC,CAAG,EAAA;AACN,IAAO,OAAA,SAAA;AAAA;AAET,EAAO,OAAA,CAAA,CAAE,UAAe,KAAA,MAAA;AAC1B;;;;"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport type {\n AuditorService,\n AuditorServiceEvent,\n AuthService,\n CacheService,\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { Config } from '@backstage/config';\nimport type { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\n\nimport { fullFormats } from 'ajv-formats/dist/formats';\nimport express, { Router, type Request, type Response } from 'express';\nimport {\n OpenAPIBackend,\n type Context,\n type Request as OpenAPIRequest,\n} from 'openapi-backend';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { CatalogHttpClient } from '../catalog/catalogHttpClient';\nimport { CatalogInfoGenerator } from '../catalog/catalogInfoGenerator';\nimport type { Components, Paths } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { permissionCheck } from '../helpers';\nimport { auditCreateEvent } from '../helpers/auditorUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n findAllImports,\n findImportStatusByRepo,\n} from './handlers/import';\nimport { findAllOrganizations } from './handlers/organization';\nimport { ping } from './handlers/ping';\nimport {\n findAllRepositories,\n findRepositoriesByOrganization,\n} from './handlers/repository';\n\n/**\n * Router Options\n * @public\n */\nexport interface RouterOptions {\n logger: LoggerService;\n permissions: PermissionEvaluator;\n config: Config;\n cache: CacheService;\n discovery: DiscoveryService;\n httpAuth: HttpAuthService;\n auth: AuthService;\n catalogApi: CatalogApi;\n auditor: AuditorService;\n}\n\nnamespace Operations {\n export const PING = 'ping';\n export const FIND_ALL_ORGANIZATIONS = 'findAllOrganizations';\n export const FIND_ALL_REPOSITORIES = 'findAllRepositories';\n export const FIND_REPOSITORIES_BY_ORGANIZATION =\n 'findRepositoriesByOrganization';\n export const FIND_ALL_IMPORTS = 'findAllImports';\n export const CREATE_IMPORT_JOBS = 'createImportJobs';\n export const FIND_IMPORT_STATUS_BY_REPO = 'findImportStatusByRepo';\n export const DELETE_IMPORT_BY_REPO = 'deleteImportByRepo';\n}\n\n/**\n * Router\n * @public\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const {\n logger,\n httpAuth,\n auth,\n permissions,\n config,\n cache,\n discovery,\n catalogApi,\n auditor: auditor,\n } = options;\n\n const githubApiService = new GithubApiService(logger, config, cache);\n const catalogHttpClient = new CatalogHttpClient({\n logger,\n config,\n discovery,\n auth,\n catalogApi,\n });\n const catalogInfoGenerator = new CatalogInfoGenerator(\n logger,\n catalogHttpClient,\n );\n\n // create openapi requests handler\n const api = new OpenAPIBackend({\n ajvOpts: {\n verbose: true,\n formats: fullFormats, // open issue: https://github.com/openapistack/openapi-backend/issues/280\n },\n validate: true,\n definition: openApiDocument,\n handlers: {\n validationFail: async (c, _req: Request, res: Response) =>\n res.status(400).json({ err: c.validation.errors }),\n notFound: async (_c, req: Request, res: Response) =>\n res.status(404).json({ err: `'${req.method} ${req.path}' not found` }),\n notImplemented: async (_c, req: Request, res: Response) =>\n res\n .status(500)\n .json({ err: `'${req.method} ${req.path}' not implemented` }),\n },\n });\n\n await api.init();\n\n api.register(\n Operations.PING,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await ping(logger);\n return res.status(result.statusCode).json(result.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORGANIZATIONS,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllOrganizations.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n const response = await findAllOrganizations(\n logger,\n githubApiService,\n q.search,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n organizations: response.responseBody?.organizations,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: response.responseBody?.pagePerIntegration,\n sizePerIntegration: response.responseBody?.sizePerIntegration,\n } as Components.Schemas.OrganizationList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_REPOSITORIES,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindAllRepositories.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n const response = await findAllRepositories(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n },\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_REPOSITORIES_BY_ORGANIZATION,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindRepositoriesByOrganization.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n q.pagePerIntegration = stringToNumber(q.pagePerIntegration);\n q.sizePerIntegration = stringToNumber(q.sizePerIntegration);\n q.checkImportStatus = stringToBoolean(q.checkImportStatus);\n const response = await findRepositoriesByOrganization(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n c.request.params.organizationName?.toString(),\n q.search,\n q.checkImportStatus,\n q.pagePerIntegration,\n q.sizePerIntegration,\n );\n const repos = response.responseBody?.repositories;\n return res.status(response.statusCode).json({\n errors: response.responseBody?.errors,\n repositories: repos,\n totalCount: response.responseBody?.totalCount,\n pagePerIntegration: q.pagePerIntegration,\n sizePerIntegration: q.sizePerIntegration,\n } as Components.Schemas.RepositoryList);\n },\n );\n\n api.register(\n Operations.FIND_ALL_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const h: Paths.FindAllImports.HeaderParameters = {\n ...c.request.headers,\n };\n const apiVersion = h['api-version'];\n const q: Paths.FindAllImports.QueryParameters = {\n ...c.request.query,\n };\n // we need to convert strings to real types due to open PR https://github.com/openapistack/openapi-backend/pull/571\n let page: number | undefined;\n let size: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n page = stringToNumber(q.page || q.pagePerIntegration);\n size = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n page = stringToNumber(q.page);\n size = stringToNumber(q.size);\n }\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search: q.search,\n pageNumber: page,\n pageSize: size,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n const q: Paths.CreateImportJobs.QueryParameters = {\n ...c.request.query,\n };\n q.dryRun = stringToBoolean(q.dryRun);\n const response = await createImportJobs(\n {\n logger,\n config,\n auth,\n catalogApi,\n githubApiService,\n catalogInfoGenerator,\n catalogHttpClient,\n },\n {\n importRequests: c.request.requestBody,\n dryRun: q.dryRun,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_IMPORT_STATUS_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.FindImportStatusByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank parameter');\n }\n const response = await findImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n true,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_IMPORT_BY_REPO,\n async (c: Context, _req: Request, res: Response) => {\n const q: Paths.DeleteImportByRepo.QueryParameters = {\n ...c.request.query,\n };\n if (!q.repo?.trim()) {\n throw new Error('missing or blank \"repo\" parameter');\n }\n const response = await deleteImportByRepo(\n {\n logger,\n config,\n githubApiService,\n catalogHttpClient,\n },\n q.repo,\n q.defaultBranch,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n const router = Router();\n router.use(express.json());\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n permissions: [bulkImportPermission],\n });\n router.use(permissionIntegrationRouter);\n\n router.use(async (req, _res, next) => {\n if (req.path !== '/ping') {\n await permissionCheck(\n auditor,\n api.matchOperation(req as OpenAPIRequest)?.operationId,\n permissions,\n httpAuth,\n req,\n ).catch(next);\n }\n next();\n });\n\n router.use(async (req, res, next) => {\n const reqCast = req as OpenAPIRequest;\n const operationId = api.matchOperation(reqCast)?.operationId;\n\n const auditorEvent = await createAuditorEventByOperationId(\n operationId,\n req,\n auditor,\n );\n try {\n const response = (await api.handleRequest(reqCast, req, res)) as Response;\n auditorEvent?.success({ meta: { responseStatus: response.statusCode } });\n next();\n } catch (err: any) {\n auditorEvent?.fail({ error: err, meta: { responseStatus: 500 } });\n next(err);\n }\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n router.use(middleware.error());\n\n return router;\n}\n\nasync function createAuditorEventByOperationId(\n operationId: string | undefined,\n req: Request,\n auditor: AuditorService,\n): Promise<AuditorServiceEvent | undefined> {\n let auditorEvent;\n switch (operationId) {\n case Operations.PING:\n auditorEvent = await auditCreateEvent(auditor, 'ping', req);\n break;\n case Operations.FIND_ALL_ORGANIZATIONS:\n auditorEvent = await auditCreateEvent(auditor, 'org-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query?.search,\n });\n break;\n case Operations.FIND_ALL_REPOSITORIES:\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.FIND_REPOSITORIES_BY_ORGANIZATION: {\n const organizationName = req.params.organizationName?.toString();\n auditorEvent = await auditCreateEvent(auditor, 'repo-read', req, {\n queryType: 'by-org',\n organizationName,\n });\n break;\n }\n case Operations.FIND_ALL_IMPORTS:\n auditorEvent = await auditCreateEvent(auditor, 'import-read', req, {\n queryType: req.query.search ? 'by-query' : 'all',\n search: req.query.search,\n });\n break;\n case Operations.CREATE_IMPORT_JOBS:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'create',\n dryRun: req.query.dryRun,\n });\n break;\n case Operations.FIND_IMPORT_STATUS_BY_REPO:\n auditorEvent = await auditCreateEvent(\n auditor,\n 'import-status-read',\n req,\n { queryType: 'by-query', repo: req.query.repo },\n );\n break;\n case Operations.DELETE_IMPORT_BY_REPO:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'delete',\n repository: req.query.repo,\n });\n break;\n case undefined:\n auditorEvent = await auditCreateEvent(auditor, operationId, req);\n break;\n default:\n // do nothing\n break;\n }\n return auditorEvent;\n}\n\nfunction stringToNumber(s: number | undefined): number | undefined {\n return s ? Number.parseInt(s.toString(), 10) : undefined;\n}\n\nfunction stringToBoolean(s: boolean | undefined): boolean | undefined {\n if (!s) {\n return undefined;\n }\n return s.toString() === 'true';\n}\n"],"names":["Operations","auth","githubApiService","GithubApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","ping","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","createImportJobs","findImportStatusByRepo","deleteImportByRepo","Router","express","createPermissionIntegrationRouter","bulkImportPermission","permissionCheck","MiddlewareFactory","auditCreateEvent"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-bulk-import-backend",
3
- "version": "5.3.0",
3
+ "version": "6.0.0",
4
4
  "main": "./dist/index.cjs.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -15,7 +15,10 @@
15
15
  "@red-hat-developer-hub/backstage-plugin-bulk-import",
16
16
  "@red-hat-developer-hub/backstage-plugin-bulk-import-backend",
17
17
  "@red-hat-developer-hub/backstage-plugin-bulk-import-common"
18
- ]
18
+ ],
19
+ "features": {
20
+ ".": "@backstage/BackendFeature"
21
+ }
19
22
  },
20
23
  "exports": {
21
24
  ".": {
@@ -48,32 +51,33 @@
48
51
  "openapi": "./scripts/openapi.sh"
49
52
  },
50
53
  "dependencies": {
51
- "@backstage/backend-defaults": "^0.7.0",
52
- "@backstage/backend-plugin-api": "^1.1.1",
54
+ "@backstage/backend-defaults": "^0.8.1",
55
+ "@backstage/backend-plugin-api": "^1.2.0",
53
56
  "@backstage/errors": "^1.2.7",
54
57
  "@backstage/integration": "^1.16.1",
55
- "@backstage/plugin-catalog-node": "^1.15.1",
58
+ "@backstage/plugin-catalog-node": "^1.16.0",
56
59
  "@backstage/plugin-permission-common": "^0.8.4",
57
- "@backstage/plugin-permission-node": "^0.8.7",
60
+ "@backstage/plugin-permission-node": "^0.8.8",
58
61
  "@octokit/auth-app": "^6.0.3",
59
62
  "@octokit/rest": "^20.0.2",
60
- "@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^1.5.0",
63
+ "@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^1.6.0",
61
64
  "ajv-formats": "^3.0.1",
62
65
  "express": "^4.17.1",
63
66
  "git-url-parse": "^14.0.0",
64
67
  "js-yaml": "^4.1.0",
68
+ "just-kebab-case": "4.2.0",
65
69
  "luxon": "^3.4.4",
66
70
  "node-fetch": "^2.6.7",
67
71
  "openapi-backend": "^5.10.6"
68
72
  },
69
73
  "devDependencies": {
70
- "@backstage/backend-test-utils": "^1.2.1",
74
+ "@backstage/backend-test-utils": "^1.3.0",
71
75
  "@backstage/catalog-client": "^1.9.1",
72
76
  "@backstage/catalog-model": "^1.7.3",
73
- "@backstage/cli": "^0.29.5",
77
+ "@backstage/cli": "^0.30.0",
74
78
  "@backstage/config": "^1.3.2",
75
- "@backstage/plugin-catalog-backend": "^1.30.0",
76
- "@janus-idp/backstage-plugin-audit-log-node": "^1.7.1",
79
+ "@backstage/plugin-catalog-backend": "^1.31.0",
80
+ "@backstage/types": "^1.2.1",
77
81
  "@openapitools/openapi-generator-cli": "2.16.3",
78
82
  "@spotify/prettier-config": "^15.0.0",
79
83
  "@types/express": "4.17.21",
@@ -1,112 +0,0 @@
1
- 'use strict';
2
-
3
- var errors = require('@backstage/errors');
4
-
5
- const EVENT_PREFIX = "BulkImport";
6
- const UNKNOWN_ENDPOINT_EVENT = `${EVENT_PREFIX}UnknownEndpoint`;
7
- async function auditLogRequestSuccess(auditLogger, openApiOperationId, req, responseStatus) {
8
- if (!openApiOperationId) {
9
- auditLogUnknownEndpoint(auditLogger, req);
10
- return;
11
- }
12
- auditLogger.auditLog({
13
- eventName: operationIdToEventName(openApiOperationId),
14
- stage: "completion",
15
- status: "succeeded",
16
- level: "info",
17
- request: req,
18
- response: {
19
- status: responseStatus
20
- },
21
- message: `'${req.method} ${req.path}' endpoint hit by ${await auditLogger.getActorId(req)}`
22
- });
23
- }
24
- async function auditLogRequestError(auditLogger, openApiOperationId, req, error) {
25
- if (!openApiOperationId) {
26
- auditLogUnknownEndpoint(auditLogger, req);
27
- return;
28
- }
29
- auditLogger.auditLog({
30
- eventName: operationIdToEventName(openApiOperationId),
31
- stage: "completion",
32
- status: "failed",
33
- level: "error",
34
- request: req,
35
- response: {
36
- status: 500,
37
- body: {
38
- errors: [
39
- {
40
- name: error.name,
41
- message: error.message || "internal server error"
42
- }
43
- ]
44
- }
45
- },
46
- errors: [error],
47
- message: `Error while requesting the '${req.method} ${req.path}' endpoint (request from ${await auditLogger.getActorId(req)})`
48
- });
49
- }
50
- async function auditLogUnknownEndpoint(auditLogger, req) {
51
- const error = new errors.NotFoundError(`'${req.method} ${req.path}' not found`);
52
- auditLogger.auditLog({
53
- eventName: UNKNOWN_ENDPOINT_EVENT,
54
- stage: "initiation",
55
- status: "failed",
56
- level: "info",
57
- request: req,
58
- response: {
59
- status: 404,
60
- body: {
61
- errors: [
62
- {
63
- name: error.name,
64
- message: error.message
65
- }
66
- ]
67
- }
68
- },
69
- errors: [error],
70
- message: `${await auditLogger.getActorId(req)} requested the unknown '${req.method} ${req.path}' endpoint`
71
- });
72
- }
73
- async function auditLogAuthError(auditLogger, openApiOperationId, req, error) {
74
- if (!openApiOperationId) {
75
- auditLogUnknownEndpoint(auditLogger, req);
76
- return;
77
- }
78
- auditLogger.auditLog({
79
- eventName: operationIdToEventName(openApiOperationId),
80
- stage: "authorization",
81
- status: "failed",
82
- level: "warn",
83
- request: req,
84
- response: {
85
- status: 403,
86
- body: {
87
- errors: [
88
- {
89
- name: error.name,
90
- message: error.message
91
- }
92
- ]
93
- }
94
- },
95
- errors: [error],
96
- message: `${await auditLogger.getActorId(
97
- req
98
- )} not authorized to request the '${req.method} ${req.path}' endpoint`
99
- });
100
- }
101
- function operationIdToEventName(openApiOperationId) {
102
- if (openApiOperationId.length === 0) {
103
- return EVENT_PREFIX;
104
- }
105
- return `${EVENT_PREFIX}${openApiOperationId.charAt(0).toUpperCase()}${openApiOperationId.slice(1)}`;
106
- }
107
-
108
- exports.auditLogAuthError = auditLogAuthError;
109
- exports.auditLogRequestError = auditLogRequestError;
110
- exports.auditLogRequestSuccess = auditLogRequestSuccess;
111
- exports.auditLogUnknownEndpoint = auditLogUnknownEndpoint;
112
- //# sourceMappingURL=auditLogUtils.cjs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auditLogUtils.cjs.js","sources":["../../src/helpers/auditLogUtils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { NotFoundError, type NotAllowedError } from '@backstage/errors';\n\nimport type { AuditLogger } from '@janus-idp/backstage-plugin-audit-log-node';\nimport express from 'express';\n\nconst EVENT_PREFIX = 'BulkImport';\nconst UNKNOWN_ENDPOINT_EVENT = `${EVENT_PREFIX}UnknownEndpoint`;\n\nexport async function auditLogRequestSuccess(\n auditLogger: AuditLogger,\n openApiOperationId: string | undefined,\n req: express.Request,\n responseStatus: number,\n) {\n if (!openApiOperationId) {\n auditLogUnknownEndpoint(auditLogger, req);\n return;\n }\n auditLogger.auditLog({\n eventName: operationIdToEventName(openApiOperationId),\n stage: 'completion',\n status: 'succeeded',\n level: 'info',\n request: req,\n response: {\n status: responseStatus,\n },\n message: `'${req.method} ${\n req.path\n }' endpoint hit by ${await auditLogger.getActorId(req)}`,\n });\n}\n\nexport async function auditLogRequestError(\n auditLogger: AuditLogger,\n openApiOperationId: string | undefined,\n req: express.Request,\n error: any,\n) {\n if (!openApiOperationId) {\n auditLogUnknownEndpoint(auditLogger, req);\n return;\n }\n auditLogger.auditLog({\n eventName: operationIdToEventName(openApiOperationId),\n stage: 'completion',\n status: 'failed',\n level: 'error',\n request: req,\n response: {\n status: 500,\n body: {\n errors: [\n {\n name: error.name,\n message: error.message || 'internal server error',\n },\n ],\n },\n },\n errors: [error],\n message: `Error while requesting the '${req.method} ${\n req.path\n }' endpoint (request from ${await auditLogger.getActorId(req)})`,\n });\n}\n\nexport async function auditLogUnknownEndpoint(\n auditLogger: AuditLogger,\n req: express.Request,\n) {\n const error = new NotFoundError(`'${req.method} ${req.path}' not found`);\n auditLogger.auditLog({\n eventName: UNKNOWN_ENDPOINT_EVENT,\n stage: 'initiation',\n status: 'failed',\n level: 'info',\n request: req,\n response: {\n status: 404,\n body: {\n errors: [\n {\n name: error.name,\n message: error.message,\n },\n ],\n },\n },\n errors: [error],\n message: `${await auditLogger.getActorId(req)} requested the unknown '${\n req.method\n } ${req.path}' endpoint`,\n });\n}\n\nexport async function auditLogAuthError(\n auditLogger: AuditLogger,\n openApiOperationId: string | undefined,\n req: express.Request,\n error: NotAllowedError,\n) {\n if (!openApiOperationId) {\n auditLogUnknownEndpoint(auditLogger, req);\n return;\n }\n auditLogger.auditLog({\n eventName: operationIdToEventName(openApiOperationId),\n stage: 'authorization',\n status: 'failed',\n level: 'warn',\n request: req,\n response: {\n status: 403,\n body: {\n errors: [\n {\n name: error.name,\n message: error.message,\n },\n ],\n },\n },\n errors: [error],\n message: `${await auditLogger.getActorId(\n req,\n )} not authorized to request the '${req.method} ${req.path}' endpoint`,\n });\n}\n\nfunction operationIdToEventName(openApiOperationId: string): string {\n if (openApiOperationId.length === 0) {\n return EVENT_PREFIX;\n }\n return `${EVENT_PREFIX}${openApiOperationId\n .charAt(0)\n .toUpperCase()}${openApiOperationId.slice(1)}`;\n}\n"],"names":["NotFoundError"],"mappings":"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"}