@red-hat-developer-hub/backstage-plugin-bulk-import-backend 7.2.0 → 7.3.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.
- package/CHANGELOG.md +51 -0
- package/README.md +41 -4
- package/dist/database/repositoryDao.cjs.js +6 -0
- package/dist/database/repositoryDao.cjs.js.map +1 -1
- package/dist/generated/openapidocument.cjs.js +89 -0
- package/dist/generated/openapidocument.cjs.js.map +1 -1
- package/dist/github/GithubAppManager.cjs.js +3 -0
- package/dist/github/GithubAppManager.cjs.js.map +1 -1
- package/dist/github/githubApiService.cjs.js +140 -144
- package/dist/github/githubApiService.cjs.js.map +1 -1
- package/dist/github/types.cjs.js.map +1 -1
- package/dist/github/utils/ghUtils.cjs.js +3 -3
- package/dist/github/utils/ghUtils.cjs.js.map +1 -1
- package/dist/github/utils/repoUtils.cjs.js +53 -99
- package/dist/github/utils/repoUtils.cjs.js.map +1 -1
- package/dist/gitlab/GitlabAppManager.cjs.js +2 -0
- package/dist/gitlab/GitlabAppManager.cjs.js.map +1 -1
- package/dist/gitlab/gitlabApiService.cjs.js +65 -8
- package/dist/gitlab/gitlabApiService.cjs.js.map +1 -1
- package/dist/gitlab/utils/glUtils.cjs.js +1 -1
- package/dist/gitlab/utils/glUtils.cjs.js.map +1 -1
- package/dist/gitlab/utils/repoUtils.cjs.js +32 -57
- package/dist/gitlab/utils/repoUtils.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js +14 -6
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/handlers/import/importStatus.cjs.js.map +1 -1
- package/dist/service/handlers/organization/organizations.cjs.js +2 -2
- package/dist/service/handlers/organization/organizations.cjs.js.map +1 -1
- package/dist/service/handlers/repository/repositories.cjs.js +41 -6
- package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
- package/dist/service/handlers/scm/scm.cjs.js +16 -0
- package/dist/service/handlers/scm/scm.cjs.js.map +1 -0
- package/dist/service/router.cjs.js +81 -9
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +16 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repositories.cjs.js","sources":["../../../../src/service/handlers/repository/repositories.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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport type { Components } from '../../../generated/openapi';\nimport type {\n GithubApiService,\n GithubRepositoryResponse,\n} from '../../../github';\nimport { GitlabApiService, GitlabRepositoryResponse } from '../../../gitlab';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n type HandlerResponse,\n} from '../handlers';\nimport { getImportStatusFromLocations } from '../import';\n\nexport async function findAllRepositories(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams?: {\n approvalTool?: string;\n search?: string;\n checkStatus?: boolean;\n pageNumber?: number;\n pageSize?: number;\n },\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n const search = reqParams?.search;\n const checkStatus = reqParams?.checkStatus ?? false;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n deps.logger.debug(\n `Getting all repositories - (search,page,size)=('${\n search ?? ''\n }',${pageNumber},${pageSize})..`,\n );\n\n const repos = await deps.gitApiService\n .getRepositoriesFromIntegrations(search, pageNumber, pageSize)\n .then(response => formatResponse(deps, response, checkStatus));\n\n return repos;\n}\n\nexport async function findRepositoriesByOrganization(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n orgName: string,\n search?: string,\n checkStatus: boolean = false,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n deps.logger.debug(\n `Getting all repositories for org \"${orgName}\" - (search,page,size)=(${search},${pageNumber},${pageSize})..`,\n );\n\n const glReposByOrg = await deps.gitApiService\n .getOrgRepositoriesFromIntegrations(orgName, search, pageNumber, pageSize)\n .then(response => formatResponse(deps, response, checkStatus));\n\n return glReposByOrg;\n}\n\nfunction sortRepos(repoList: Components.Schemas.Repository[]) {\n // sorting the output to make it deterministic and easy to navigate in the UI\n repoList.sort((a, b) => {\n if (a.name === undefined && b.name === undefined) {\n return 0;\n }\n if (a.name === undefined) {\n return -1;\n }\n if (b.name === undefined) {\n return 1;\n }\n return a.name.localeCompare(b.name);\n });\n}\n\ntype ImportStatus =\n | { status: Components.Schemas.ImportStatus; lastUpdate?: string }\n | null\n | undefined;\n\nasync function formatResponse(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GithubApiService | GitlabApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n allReposAccessible: GithubRepositoryResponse | GitlabRepositoryResponse,\n checkStatus: boolean,\n) {\n const errorList =\n allReposAccessible.errors\n ?.map(err => err.error?.message)\n ?.filter(msg => msg) ?? [];\n if (allReposAccessible.repositories?.length === 0 && errorList.length > 0) {\n return {\n statusCode: 500,\n responseBody: {\n errors: errorList,\n },\n };\n }\n\n let catalogLocations: Iterable<string> = [];\n if (checkStatus) {\n catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n }\n const repoList: Components.Schemas.Repository[] = [];\n for (const repo of allReposAccessible.repositories) {\n const gitUrl = gitUrlParse(repo.html_url);\n const errors: string[] = [];\n let importStatus: ImportStatus;\n if (checkStatus) {\n importStatus = await getImportStatusFromLocations(\n deps,\n repo.html_url,\n catalogLocations,\n repo.default_branch,\n ).catch((error: any) => {\n errors.push(error.message);\n return undefined;\n });\n }\n const repoUpdatedAt = repo.updated_at ?? undefined;\n repoList.push({\n id: `${gitUrl.organization}/${repo.name}`,\n name: repo.name,\n organization: gitUrl.organization,\n url: repo.html_url,\n defaultBranch: repo.default_branch,\n importStatus: importStatus?.status,\n lastUpdate: importStatus?.lastUpdate ?? repoUpdatedAt,\n errors: errors,\n });\n }\n\n sortRepos(repoList);\n\n return {\n statusCode: 200,\n responseBody: {\n errors: errorList,\n repositories: repoList,\n totalCount: allReposAccessible.totalCount,\n },\n };\n}\n"],"names":["DefaultPageNumber","DefaultPageSize","gitUrlParse","importStatus","getImportStatusFromLocations"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repositories.cjs.js","sources":["../../../../src/service/handlers/repository/repositories.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 type { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\n\nimport gitUrlParse from 'git-url-parse';\n\nimport { CatalogHttpClient } from '../../../catalog/catalogHttpClient';\nimport { getCatalogUrl } from '../../../catalog/catalogUtils';\nimport type { Components } from '../../../generated/openapi';\nimport { GitApiService } from '../../../scm/GitApiService';\nimport type { SCMRepositoryResponse } from '../../../scm/types';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n type HandlerResponse,\n} from '../handlers';\nimport { getImportStatusFromLocations } from '../import';\n\nexport async function findAllRepositories(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n reqParams?: {\n search?: string;\n checkStatus?: boolean;\n pageNumber?: number;\n pageSize?: number;\n userTokens?: Record<string, string>;\n },\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n const search = reqParams?.search;\n const checkStatus = reqParams?.checkStatus ?? false;\n const pageNumber = reqParams?.pageNumber ?? DefaultPageNumber;\n const pageSize = reqParams?.pageSize ?? DefaultPageSize;\n const userTokens = reqParams?.userTokens;\n deps.logger.debug(\n `Getting all repositories - (search,page,size)=('${\n search ?? ''\n }',${pageNumber},${pageSize})..`,\n );\n\n const [alreadyImportedRepositories, allRepositoriesResponse] =\n await Promise.all([\n deps.catalogHttpClient.listCatalogUrlLocations(),\n deps.gitApiService.getRepositoriesFromIntegrations(search, userTokens),\n ]);\n\n const alreadyImportedRepositoriesLocationTargets = new Set(\n alreadyImportedRepositories.uniqueCatalogUrlLocations.keys(),\n );\n\n const { repositories: allRepositories, errors } = allRepositoriesResponse;\n\n const notImportedYetRepositories = allRepositories.filter(repo => {\n const catalogUrl = getCatalogUrl(\n deps.config,\n repo.html_url.replace(/\\/$/, ''),\n repo.default_branch,\n );\n\n let alreadyImported =\n alreadyImportedRepositoriesLocationTargets.has(catalogUrl);\n\n if (!alreadyImported) {\n // Workaround: when a GitHub repository is imported via Backstage, the\n // resulting registered catalog location may use a '/tree/' URL for the\n // target instead of the '/blob/' URL format returned by getCatalogUrl.\n // To correctly detect already-imported repositories regardless of which\n // format was persisted, the '/tree/' variant is also checked here.\n // This branch can be removed once catalog locations are consistently\n // stored using the same '/blob/' format as getCatalogUrl returns.\n alreadyImported = alreadyImportedRepositoriesLocationTargets.has(\n catalogUrl.replace('/blob/', '/tree/'),\n );\n }\n\n return !alreadyImported;\n });\n\n sortRepos(notImportedYetRepositories);\n\n const gitRepositoryResponse: SCMRepositoryResponse = {\n repositories: notImportedYetRepositories,\n errors,\n totalCount: notImportedYetRepositories.length,\n };\n\n return await formatResponse(deps, gitRepositoryResponse, checkStatus);\n}\n\nexport async function findRepositoriesByOrganization(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n orgName: string,\n search?: string,\n checkStatus: boolean = false,\n pageNumber: number = DefaultPageNumber,\n pageSize: number = DefaultPageSize,\n userTokens?: Record<string, string>,\n): Promise<HandlerResponse<Components.Schemas.RepositoryList>> {\n deps.logger.debug(\n `Getting all repositories for org \"${orgName}\" - (search,page,size)=(${search},${pageNumber},${pageSize})..`,\n );\n\n const glReposByOrg =\n await deps.gitApiService.getOrgRepositoriesFromIntegrations(\n orgName,\n search,\n pageNumber,\n pageSize,\n userTokens,\n );\n\n sortRepos(glReposByOrg.repositories);\n\n return formatResponse(deps, glReposByOrg, checkStatus);\n}\n\nfunction sortRepos(repoList: Components.Schemas.Repository[]) {\n // sorting the output to make it deterministic and easy to navigate in the UI\n repoList.sort((a, b) => {\n if (a.name === undefined && b.name === undefined) {\n return 0;\n }\n if (a.name === undefined) {\n return -1;\n }\n if (b.name === undefined) {\n return 1;\n }\n return a.name.localeCompare(b.name);\n });\n}\n\ntype ImportStatus =\n | { status: Components.Schemas.ImportStatus; lastUpdate?: string }\n | null\n | undefined;\n\nasync function formatResponse(\n deps: {\n logger: LoggerService;\n config: Config;\n gitApiService: GitApiService;\n catalogHttpClient: CatalogHttpClient;\n },\n allReposAccessible: SCMRepositoryResponse,\n checkStatus: boolean,\n) {\n const errorList =\n allReposAccessible.errors\n ?.map(err => err.error?.message)\n ?.filter(msg => msg) ?? [];\n if (allReposAccessible.repositories?.length === 0 && errorList.length > 0) {\n return {\n statusCode: 500,\n responseBody: {\n errors: errorList,\n },\n };\n }\n\n let catalogLocations: Iterable<string> = [];\n if (checkStatus) {\n catalogLocations = (\n await deps.catalogHttpClient.listCatalogUrlLocations()\n ).uniqueCatalogUrlLocations.keys();\n }\n const repoList: Components.Schemas.Repository[] = [];\n for (const repo of allReposAccessible.repositories) {\n const gitUrl = gitUrlParse(repo.html_url);\n const errors: string[] = [];\n let importStatus: ImportStatus;\n if (checkStatus) {\n importStatus = await getImportStatusFromLocations(\n deps,\n repo.html_url,\n catalogLocations,\n repo.default_branch,\n ).catch((error: any) => {\n errors.push(error.message);\n return undefined;\n });\n }\n const repoUpdatedAt = repo.updated_at ?? undefined;\n repoList.push({\n id: `${gitUrl.organization}/${repo.name}`,\n name: repo.name,\n organization: gitUrl.organization,\n url: repo.html_url,\n defaultBranch: repo.default_branch,\n importStatus: importStatus?.status,\n lastUpdate: importStatus?.lastUpdate ?? repoUpdatedAt,\n errors: errors,\n });\n }\n\n return {\n statusCode: 200,\n responseBody: {\n errors: errorList,\n repositories: repoList,\n totalCount: allReposAccessible.totalCount,\n },\n };\n}\n"],"names":["DefaultPageNumber","DefaultPageSize","getCatalogUrl","gitUrlParse","importStatus","getImportStatusFromLocations"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var integration = require('@backstage/integration');
|
|
4
|
+
|
|
5
|
+
async function findAllSCMHosts(config) {
|
|
6
|
+
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
7
|
+
const githubHosts = integrations.github.list().map((i) => `https://${i.config.host}`);
|
|
8
|
+
const gitlabHosts = integrations.gitlab.list().map((i) => i.config.baseUrl.replace(/\/$/, ""));
|
|
9
|
+
return {
|
|
10
|
+
statusCode: 200,
|
|
11
|
+
responseBody: { github: githubHosts, gitlab: gitlabHosts }
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
exports.findAllSCMHosts = findAllSCMHosts;
|
|
16
|
+
//# sourceMappingURL=scm.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scm.cjs.js","sources":["../../../../src/service/handlers/scm/scm.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 { Config } from '@backstage/config';\nimport { ScmIntegrations } from '@backstage/integration';\n\nimport type { Paths } from '../../../generated/openapi';\nimport type { HandlerResponse } from '../handlers';\n\nexport async function findAllSCMHosts(\n config: Config,\n): Promise<HandlerResponse<Paths.FindAllSCMHosts.Responses.$200>> {\n const integrations = ScmIntegrations.fromConfig(config);\n const githubHosts = integrations.github\n .list()\n .map(i => `https://${i.config.host}`);\n const gitlabHosts = integrations.gitlab\n .list()\n .map(i => i.config.baseUrl.replace(/\\/$/, ''));\n return {\n statusCode: 200,\n responseBody: { github: githubHosts, gitlab: gitlabHosts },\n };\n}\n"],"names":["ScmIntegrations"],"mappings":";;;;AAsBA,eAAsB,gBACpB,MAAA,EACgE;AAChE,EAAA,MAAM,YAAA,GAAeA,2BAAA,CAAgB,UAAA,CAAW,MAAM,CAAA;AACtD,EAAA,MAAM,WAAA,GAAc,YAAA,CAAa,MAAA,CAC9B,IAAA,EAAK,CACL,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,QAAA,EAAW,CAAA,CAAE,MAAA,CAAO,IAAI,CAAA,CAAE,CAAA;AACtC,EAAA,MAAM,WAAA,GAAc,YAAA,CAAa,MAAA,CAC9B,IAAA,EAAK,CACL,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA;AAC/C,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,GAAA;AAAA,IACZ,YAAA,EAAc,EAAE,MAAA,EAAQ,WAAA,EAAa,QAAQ,WAAA;AAAY,GAC3D;AACF;;;;"}
|
|
@@ -27,6 +27,7 @@ var executeTemplate = require('./handlers/import/execute-template.cjs.js');
|
|
|
27
27
|
var organizations = require('./handlers/organization/organizations.cjs.js');
|
|
28
28
|
var ping = require('./handlers/ping/ping.cjs.js');
|
|
29
29
|
var repositories = require('./handlers/repository/repositories.cjs.js');
|
|
30
|
+
var scm = require('./handlers/scm/scm.cjs.js');
|
|
30
31
|
|
|
31
32
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
32
33
|
|
|
@@ -35,6 +36,7 @@ var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
|
35
36
|
var Operations;
|
|
36
37
|
((Operations2) => {
|
|
37
38
|
Operations2.PING = "ping";
|
|
39
|
+
Operations2.FIND_ALL_SCM_HOSTS = "findAllSCMHosts";
|
|
38
40
|
Operations2.FIND_ALL_ORGANIZATIONS = "findAllOrganizations";
|
|
39
41
|
Operations2.FIND_ALL_REPOSITORIES = "findAllRepositories";
|
|
40
42
|
Operations2.FIND_REPOSITORIES_BY_ORGANIZATION = "findRepositoriesByOrganization";
|
|
@@ -51,6 +53,32 @@ var Operations;
|
|
|
51
53
|
Operations2.DELETE_TASK_IMPORT_BY_REPO = "deleteTaskImportByRepo";
|
|
52
54
|
Operations2.DELETE_ORCHESTRATOR_IMPORT_BY_REPO = "deleteOrchestratorImportByRepo";
|
|
53
55
|
})(Operations || (Operations = {}));
|
|
56
|
+
const SCM_TOKENS_MAX_BYTES = 4096;
|
|
57
|
+
const isValidTokenMap = (v) => typeof v === "object" && v !== null && Object.values(v).every((val) => typeof val === "string" && val.length > 0);
|
|
58
|
+
function parseScmTokensHeader(rawTokenHeader, logger) {
|
|
59
|
+
let token;
|
|
60
|
+
if (!rawTokenHeader) return void 0;
|
|
61
|
+
if (rawTokenHeader.length > SCM_TOKENS_MAX_BYTES) {
|
|
62
|
+
logger.warn("x-scm-tokens header exceeds maximum allowed size; ignoring");
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
token = JSON.parse(rawTokenHeader);
|
|
67
|
+
if (typeof token !== "object" || token === null || Array.isArray(token)) {
|
|
68
|
+
throw new Error("x-scm-tokens must be a JSON object");
|
|
69
|
+
}
|
|
70
|
+
} catch (e) {
|
|
71
|
+
throw new errors.InputError(
|
|
72
|
+
`Invalid x-scm-tokens header: ${e.message}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (!isValidTokenMap(token)) {
|
|
76
|
+
throw new errors.InputError(
|
|
77
|
+
"Invalid x-scm-tokens header: all values must be non-empty strings"
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return token;
|
|
81
|
+
}
|
|
54
82
|
async function createRouter(options) {
|
|
55
83
|
const {
|
|
56
84
|
logger,
|
|
@@ -117,6 +145,13 @@ async function createRouter(options) {
|
|
|
117
145
|
return res.status(result.statusCode).json(result.responseBody);
|
|
118
146
|
}
|
|
119
147
|
);
|
|
148
|
+
api.register(
|
|
149
|
+
Operations.FIND_ALL_SCM_HOSTS,
|
|
150
|
+
async (_c, _req, res) => {
|
|
151
|
+
const result = await scm.findAllSCMHosts(config);
|
|
152
|
+
return res.status(result.statusCode).json(result.responseBody);
|
|
153
|
+
}
|
|
154
|
+
);
|
|
120
155
|
api.register(
|
|
121
156
|
Operations.FIND_ALL_ORGANIZATIONS,
|
|
122
157
|
async (c, _req, res) => {
|
|
@@ -151,6 +186,12 @@ async function createRouter(options) {
|
|
|
151
186
|
q.pagePerIntegration = stringToNumber(q.pagePerIntegration);
|
|
152
187
|
q.sizePerIntegration = stringToNumber(q.sizePerIntegration);
|
|
153
188
|
q.checkImportStatus = stringToBoolean(q.checkImportStatus);
|
|
189
|
+
const userTokens = res.locals.scmTokens;
|
|
190
|
+
if (!userTokens || Object.keys(userTokens).length === 0) {
|
|
191
|
+
return res.status(401).json({
|
|
192
|
+
error: "User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured."
|
|
193
|
+
});
|
|
194
|
+
}
|
|
154
195
|
const response = await repositories.findAllRepositories(
|
|
155
196
|
{
|
|
156
197
|
logger,
|
|
@@ -162,7 +203,9 @@ async function createRouter(options) {
|
|
|
162
203
|
search: q.search,
|
|
163
204
|
checkStatus: q.checkImportStatus,
|
|
164
205
|
pageNumber: q.pagePerIntegration,
|
|
165
|
-
pageSize: q.sizePerIntegration
|
|
206
|
+
pageSize: q.sizePerIntegration,
|
|
207
|
+
userTokens
|
|
208
|
+
}
|
|
166
209
|
);
|
|
167
210
|
const repos = response.responseBody?.repositories;
|
|
168
211
|
return res.status(response.statusCode).json({
|
|
@@ -184,6 +227,12 @@ async function createRouter(options) {
|
|
|
184
227
|
q.pagePerIntegration = stringToNumber(q.pagePerIntegration);
|
|
185
228
|
q.sizePerIntegration = stringToNumber(q.sizePerIntegration);
|
|
186
229
|
q.checkImportStatus = stringToBoolean(q.checkImportStatus);
|
|
230
|
+
const userTokens = res.locals.scmTokens;
|
|
231
|
+
if (!userTokens || Object.keys(userTokens).length === 0) {
|
|
232
|
+
return res.status(401).json({
|
|
233
|
+
error: "User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured."
|
|
234
|
+
});
|
|
235
|
+
}
|
|
187
236
|
const response = await repositories.findRepositoriesByOrganization(
|
|
188
237
|
{
|
|
189
238
|
logger,
|
|
@@ -195,7 +244,8 @@ async function createRouter(options) {
|
|
|
195
244
|
q.search,
|
|
196
245
|
q.checkImportStatus,
|
|
197
246
|
q.pagePerIntegration,
|
|
198
|
-
q.sizePerIntegration
|
|
247
|
+
q.sizePerIntegration,
|
|
248
|
+
userTokens
|
|
199
249
|
);
|
|
200
250
|
const repos = response.responseBody?.repositories;
|
|
201
251
|
return res.status(response.statusCode).json({
|
|
@@ -530,15 +580,34 @@ async function createRouter(options) {
|
|
|
530
580
|
permissions: [backstagePluginBulkImportCommon.bulkImportPermission]
|
|
531
581
|
});
|
|
532
582
|
router.use(permissionIntegrationRouter);
|
|
583
|
+
router.use((req, res, next) => {
|
|
584
|
+
const raw = req.headers["x-scm-tokens"];
|
|
585
|
+
const rawStr = Array.isArray(raw) ? raw[0] : raw;
|
|
586
|
+
delete req.headers["x-scm-tokens"];
|
|
587
|
+
if (rawStr) {
|
|
588
|
+
try {
|
|
589
|
+
res.locals.scmTokens = parseScmTokensHeader(rawStr, logger);
|
|
590
|
+
} catch (e) {
|
|
591
|
+
next(e);
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
next();
|
|
596
|
+
});
|
|
533
597
|
router.use(async (req, _res, next) => {
|
|
534
598
|
if (req.path !== "/ping") {
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
599
|
+
try {
|
|
600
|
+
await auth.permissionCheck(
|
|
601
|
+
auditor,
|
|
602
|
+
api.matchOperation(req)?.operationId,
|
|
603
|
+
permissions,
|
|
604
|
+
httpAuth,
|
|
605
|
+
req
|
|
606
|
+
);
|
|
607
|
+
} catch (e) {
|
|
608
|
+
next(e);
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
542
611
|
}
|
|
543
612
|
next();
|
|
544
613
|
});
|
|
@@ -569,6 +638,9 @@ async function createAuditorEventByOperationId(operationId, req, auditor) {
|
|
|
569
638
|
case Operations.PING:
|
|
570
639
|
auditorEvent = await auditorUtils.auditCreateEvent(auditor, "ping", req);
|
|
571
640
|
break;
|
|
641
|
+
case Operations.FIND_ALL_SCM_HOSTS:
|
|
642
|
+
auditorEvent = await auditorUtils.auditCreateEvent(auditor, "scm-hosts-read", req);
|
|
643
|
+
break;
|
|
572
644
|
case Operations.FIND_ALL_ORGANIZATIONS:
|
|
573
645
|
auditorEvent = await auditorUtils.auditCreateEvent(auditor, "org-read", req, {
|
|
574
646
|
queryType: req.query.search ? "by-query" : "all",
|
|
@@ -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 AuditorService,\n AuditorServiceEvent,\n AuthService,\n CacheService,\n DatabaseService,\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 { InputError } from '@backstage/errors';\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 Document,\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 { migrate } from '../database/migration';\nimport {\n OrchestratorWorkflowDao,\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../database/repositoryDao';\nimport type { Components, Paths, SourceImport } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { GitlabApiService } from '../gitlab';\nimport {\n getImportTemplateRef,\n parseGitURLForApprovalTool,\n permissionCheck,\n} from '../helpers';\nimport { auditCreateEvent } from '../helpers/auditorUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n deleteRepositoryRecord,\n findAllImports,\n findImportStatusByRepo,\n findOrchestratorImportStatusByRepo,\n findTaskImportStatusByRepo,\n sortImports,\n} from './handlers/import';\nimport { createWorkflowImportJobs } from './handlers/import/execute-orchestrator-workflow';\nimport { createTaskImportJobs } from './handlers/import/execute-template';\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 database: DatabaseService;\n}\n\nnamespace Operations {\n export const PING = 'ping';\n export const FIND_ALL_ORGANIZATIONS = 'findAllOrganizations';\n export const FIND_ALL_REPOSITORIES = 'findAllRepositories';\n\n export const FIND_REPOSITORIES_BY_ORGANIZATION =\n 'findRepositoriesByOrganization';\n\n export const FIND_ALL_IMPORTS = 'findAllImports';\n export const FIND_ALL_TASK_IMPORTS = 'findAllTaskImports';\n export const FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS =\n 'findAllOrchestratorWorkflowImports';\n\n export const CREATE_IMPORT_JOBS = 'createImportJobs';\n export const CREATE_TASK_IMPORT_JOBS = 'createTaskImportJobs';\n export const CREATE_ORCHESTRATOR_WORKFLOW_JOBS =\n 'createOrchestratorWorkflowJobs';\n\n export const FIND_IMPORT_STATUS_BY_REPO = 'findImportStatusByRepo';\n export const FIND_TASK_IMPORT_STATUS_BY_REPO = 'findTaskImportStatusByRepo';\n export const FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO =\n 'findOrchestratorImportStatusByRepo';\n\n export const DELETE_IMPORT_BY_REPO = 'deleteImportByRepo';\n export const DELETE_TASK_IMPORT_BY_REPO = 'deleteTaskImportByRepo';\n export const DELETE_ORCHESTRATOR_IMPORT_BY_REPO =\n 'deleteOrchestratorImportByRepo';\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 database,\n } = options;\n\n const knex = await migrate(database);\n const repositoryDao = new RepositoryDao(knex, logger, 'repositories');\n const taskDao = new ScaffolderTaskDao(knex);\n const taskLocationsDao = new TaskLocationsDao(knex);\n const orchestratorRepositoryDao = new RepositoryDao(\n knex,\n logger,\n 'orchestrator_repositories',\n );\n const orchestratorWorkflowDao = new OrchestratorWorkflowDao(knex);\n // This should probably be sometype of object that holds all the scm API service objects\n const githubApiService = new GithubApiService(logger, config, cache);\n const gitlabApiService = new GitlabApiService(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 const templateRef = config.getOptionalString('bulkImport.importTemplate');\n let finalTemplateRef: string | undefined;\n if (templateRef) {\n finalTemplateRef = getImportTemplateRef(templateRef);\n }\n\n const orchestratorWorkflowId = config.getOptionalString(\n 'bulkImport.orchestratorWorkflow',\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 q.approvalTool === 'GITLAB' ? gitlabApiService : 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 approvalTool: q.approvalTool,\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 gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n approvalTool: q.approvalTool,\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 approvalTool: q.approvalTool,\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 gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : 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 approvalTool: q.approvalTool,\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 {\n pageNumber,\n pageSize,\n apiVersion,\n search,\n sortColumn,\n sortOrder,\n } = getFindImportsParams(c);\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search,\n pageNumber,\n pageSize,\n sortColumn,\n sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n api.register(\n Operations.FIND_ALL_TASK_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await repositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n for (const repo of repositories.data) {\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n repo.url,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS,\n async (c: Context, req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await orchestratorRepositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n const token = getBearerTokenFromReq(req);\n\n for (const repo of repositories.data) {\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n repo.url,\n token,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(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 gitlabApiService,\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.CREATE_TASK_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n if (!finalTemplateRef) {\n throw new Error(\n `Missing required config value: 'bulkImport.importTemplate'`,\n );\n }\n const response = await createTaskImportJobs(\n finalTemplateRef,\n discovery,\n logger,\n auth,\n config,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n c.request.requestBody,\n githubApiService,\n );\n\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n req: Request,\n res: Response,\n ) => {\n if (!orchestratorWorkflowId) {\n throw new Error(\n `Missing required config value: 'bulkImport.orchestratorWorkflow'`,\n );\n }\n\n const token = getBearerTokenFromReq(req);\n\n const response = await createWorkflowImportJobs({\n orchestratorWorkflowId,\n discovery,\n token,\n requestBody: c.request.requestBody,\n orchestratorWorkflowDao,\n orchestratorRepositoryDao,\n githubApiService,\n gitlabApiService,\n });\n\n res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_TASK_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 findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n q.repo,\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 gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n approvalTool: q.approvalTool,\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.FIND_ORCHESTRATOR_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 token = getBearerTokenFromReq(req);\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n q.repo,\n token,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_TASK_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 deleteRepositoryRecord(\n {\n logger,\n dao: repositoryDao,\n },\n q.repo,\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 gitApiService:\n parseGitURLForApprovalTool(q.repo) === 'GITLAB'\n ? gitlabApiService\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 api.register(\n Operations.DELETE_ORCHESTRATOR_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 deleteRepositoryRecord(\n {\n logger,\n dao: orchestratorRepositoryDao,\n },\n q.repo,\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 case Operations.FIND_ALL_TASK_IMPORTS:\n case Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_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 case Operations.CREATE_TASK_IMPORT_JOBS:\n case Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'create',\n });\n break;\n case Operations.FIND_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_TASK_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_ORCHESTRATOR_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 case Operations.DELETE_TASK_IMPORT_BY_REPO:\n case Operations.DELETE_ORCHESTRATOR_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}\nfunction getFindImportsParams(c: Context<any, any, any, any, any, Document>): {\n pageNumber?: number;\n pageSize?: number;\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n search?: string;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n} {\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 pageNumber: number | undefined;\n let pageSize: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n pageNumber = stringToNumber(q.page || q.pagePerIntegration);\n pageSize = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n pageNumber = stringToNumber(q.page);\n pageSize = stringToNumber(q.size);\n }\n return {\n pageNumber,\n pageSize,\n apiVersion: apiVersion,\n search: q.search,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n };\n}\n\nfunction getBearerTokenFromReq(req: express.Request): string {\n const header = req.header('authorization') ?? req.headers.authorization;\n if (header?.startsWith(`Bearer `)) {\n return header.replace('Bearer ', '');\n }\n throw new InputError(`Request provided without token`);\n}\n"],"names":["Operations","auth","migrate","repositoryDao","RepositoryDao","ScaffolderTaskDao","TaskLocationsDao","OrchestratorWorkflowDao","githubApiService","GithubApiService","gitlabApiService","GitlabApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","getImportTemplateRef","ping","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","findTaskImportStatusByRepo","sortImports","findOrchestratorImportStatusByRepo","createImportJobs","createTaskImportJobs","createWorkflowImportJobs","findImportStatusByRepo","deleteRepositoryRecord","deleteImportByRepo","parseGitURLForApprovalTool","Router","express","createPermissionIntegrationRouter","bulkImportPermission","permissionCheck","MiddlewareFactory","auditCreateEvent","InputError"],"mappings":"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"}
|
|
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 DatabaseService,\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 { InputError } from '@backstage/errors';\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 Document,\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 { migrate } from '../database/migration';\nimport {\n OrchestratorWorkflowDao,\n RepositoryDao,\n ScaffolderTaskDao,\n TaskLocationsDao,\n} from '../database/repositoryDao';\nimport type { Components, Paths, SourceImport } from '../generated/openapi.d';\nimport { openApiDocument } from '../generated/openapidocument';\nimport { GithubApiService } from '../github';\nimport { GitlabApiService } from '../gitlab';\nimport {\n getImportTemplateRef,\n parseGitURLForApprovalTool,\n permissionCheck,\n} from '../helpers';\nimport { auditCreateEvent } from '../helpers/auditorUtils';\nimport {\n createImportJobs,\n deleteImportByRepo,\n deleteRepositoryRecord,\n findAllImports,\n findImportStatusByRepo,\n findOrchestratorImportStatusByRepo,\n findTaskImportStatusByRepo,\n sortImports,\n} from './handlers/import';\nimport { createWorkflowImportJobs } from './handlers/import/execute-orchestrator-workflow';\nimport { createTaskImportJobs } from './handlers/import/execute-template';\nimport { findAllOrganizations } from './handlers/organization';\nimport { ping } from './handlers/ping';\nimport {\n findAllRepositories,\n findRepositoriesByOrganization,\n} from './handlers/repository';\nimport { findAllSCMHosts } from './handlers/scm/scm';\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 database: DatabaseService;\n}\n\nnamespace Operations {\n export const PING = 'ping';\n export const FIND_ALL_SCM_HOSTS = 'findAllSCMHosts';\n export const FIND_ALL_ORGANIZATIONS = 'findAllOrganizations';\n export const FIND_ALL_REPOSITORIES = 'findAllRepositories';\n\n export const FIND_REPOSITORIES_BY_ORGANIZATION =\n 'findRepositoriesByOrganization';\n\n export const FIND_ALL_IMPORTS = 'findAllImports';\n export const FIND_ALL_TASK_IMPORTS = 'findAllTaskImports';\n export const FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS =\n 'findAllOrchestratorWorkflowImports';\n\n export const CREATE_IMPORT_JOBS = 'createImportJobs';\n export const CREATE_TASK_IMPORT_JOBS = 'createTaskImportJobs';\n export const CREATE_ORCHESTRATOR_WORKFLOW_JOBS =\n 'createOrchestratorWorkflowJobs';\n\n export const FIND_IMPORT_STATUS_BY_REPO = 'findImportStatusByRepo';\n export const FIND_TASK_IMPORT_STATUS_BY_REPO = 'findTaskImportStatusByRepo';\n export const FIND_ORCHESTRATOR_IMPORT_STATUS_BY_REPO =\n 'findOrchestratorImportStatusByRepo';\n\n export const DELETE_IMPORT_BY_REPO = 'deleteImportByRepo';\n export const DELETE_TASK_IMPORT_BY_REPO = 'deleteTaskImportByRepo';\n export const DELETE_ORCHESTRATOR_IMPORT_BY_REPO =\n 'deleteOrchestratorImportByRepo';\n}\n\nconst SCM_TOKENS_MAX_BYTES = 4096;\n\nconst isValidTokenMap = (v: unknown): v is Record<string, string> =>\n typeof v === 'object' &&\n v !== null &&\n Object.values(v).every(val => typeof val === 'string' && val.length > 0);\n\nfunction parseScmTokensHeader(\n rawTokenHeader: string | undefined,\n logger: LoggerService,\n): Record<string, string> | undefined {\n let token: Record<string, string> | undefined;\n if (!rawTokenHeader) return undefined;\n if (rawTokenHeader.length > SCM_TOKENS_MAX_BYTES) {\n logger.warn('x-scm-tokens header exceeds maximum allowed size; ignoring');\n return undefined;\n }\n try {\n token = JSON.parse(rawTokenHeader) as Record<string, string>;\n if (typeof token !== 'object' || token === null || Array.isArray(token)) {\n throw new Error('x-scm-tokens must be a JSON object');\n }\n } catch (e) {\n throw new InputError(\n `Invalid x-scm-tokens header: ${(e as Error).message}`,\n );\n }\n\n if (!isValidTokenMap(token)) {\n throw new InputError(\n 'Invalid x-scm-tokens header: all values must be non-empty strings',\n );\n }\n return token;\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 database,\n } = options;\n\n const knex = await migrate(database);\n const repositoryDao = new RepositoryDao(knex, logger, 'repositories');\n const taskDao = new ScaffolderTaskDao(knex);\n const taskLocationsDao = new TaskLocationsDao(knex);\n const orchestratorRepositoryDao = new RepositoryDao(\n knex,\n logger,\n 'orchestrator_repositories',\n );\n const orchestratorWorkflowDao = new OrchestratorWorkflowDao(knex);\n // GitHub and GitLab both implement the GitApiService interface; the router\n // selects the appropriate service per request based on approvalTool.\n const githubApiService = new GithubApiService(logger, config, cache);\n const gitlabApiService = new GitlabApiService(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 const templateRef = config.getOptionalString('bulkImport.importTemplate');\n let finalTemplateRef: string | undefined;\n if (templateRef) {\n finalTemplateRef = getImportTemplateRef(templateRef);\n }\n\n const orchestratorWorkflowId = config.getOptionalString(\n 'bulkImport.orchestratorWorkflow',\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_SCM_HOSTS,\n async (_c: Context, _req: Request, res: Response) => {\n const result = await findAllSCMHosts(config);\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 q.approvalTool === 'GITLAB' ? gitlabApiService : 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 approvalTool: q.approvalTool,\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\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findAllRepositories(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n {\n search: q.search,\n checkStatus: q.checkImportStatus,\n pageNumber: q.pagePerIntegration,\n pageSize: q.sizePerIntegration,\n userTokens,\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 approvalTool: q.approvalTool,\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\n const userTokens = res.locals.scmTokens as\n | Record<string, string>\n | undefined;\n\n if (!userTokens || Object.keys(userTokens).length === 0) {\n return res.status(401).json({\n error:\n 'User SCM credentials are required to list repositories. Ensure the SCM OAuth integration is configured.',\n });\n }\n\n const response = await findRepositoriesByOrganization(\n {\n logger,\n config,\n gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n },\n c.request.params.organizationName?.toString(),\n q.search,\n q.checkImportStatus,\n q.pagePerIntegration,\n q.sizePerIntegration,\n userTokens,\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 approvalTool: q.approvalTool,\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 {\n pageNumber,\n pageSize,\n apiVersion,\n search,\n sortColumn,\n sortOrder,\n } = getFindImportsParams(c);\n const response = await findAllImports(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n },\n {\n apiVersion,\n },\n {\n search,\n pageNumber,\n pageSize,\n sortColumn,\n sortOrder,\n },\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n api.register(\n Operations.FIND_ALL_TASK_IMPORTS,\n async (c: Context, _req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await repositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n for (const repo of repositories.data) {\n const response = await findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n repo.url,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(responseBody);\n },\n );\n\n api.register(\n Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_IMPORTS,\n async (c: Context, req: Request, res: Response) => {\n const { pageNumber, pageSize, search, sortColumn, sortOrder } =\n getFindImportsParams(c);\n const imports: SourceImport[] = [];\n const repositories = await orchestratorRepositoryDao.findRepositories(\n pageNumber,\n pageSize,\n search,\n );\n\n const token = getBearerTokenFromReq(req);\n\n for (const repo of repositories.data) {\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n repo.url,\n token,\n true,\n );\n if (response.responseBody) {\n imports.push(response.responseBody);\n }\n }\n\n sortImports(imports, sortColumn, sortOrder);\n\n const responseBody: Components.Schemas.ImportJobListV2 = {\n imports,\n totalCount: repositories.total,\n page: pageNumber || 1,\n size: pageSize || 5,\n };\n\n return res.status(200).json(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 gitlabApiService,\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.CREATE_TASK_IMPORT_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n _req: Request,\n res: Response,\n ) => {\n if (!finalTemplateRef) {\n throw new Error(\n `Missing required config value: 'bulkImport.importTemplate'`,\n );\n }\n const response = await createTaskImportJobs(\n finalTemplateRef,\n discovery,\n logger,\n auth,\n config,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n c.request.requestBody,\n githubApiService,\n );\n\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS,\n async (\n c: Context<Paths.CreateImportJobs.RequestBody>,\n req: Request,\n res: Response,\n ) => {\n if (!orchestratorWorkflowId) {\n throw new Error(\n `Missing required config value: 'bulkImport.orchestratorWorkflow'`,\n );\n }\n\n const token = getBearerTokenFromReq(req);\n\n const response = await createWorkflowImportJobs({\n orchestratorWorkflowId,\n discovery,\n token,\n requestBody: c.request.requestBody,\n orchestratorWorkflowDao,\n orchestratorRepositoryDao,\n githubApiService,\n gitlabApiService,\n });\n\n res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.FIND_TASK_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 findTaskImportStatusByRepo(\n {\n logger,\n config,\n githubApiService,\n gitlabApiService,\n catalogHttpClient,\n repositoryDao,\n taskDao,\n taskLocationsDao,\n discovery,\n auth,\n },\n q.repo,\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 gitApiService:\n q.approvalTool === 'GITLAB' ? gitlabApiService : githubApiService,\n catalogHttpClient,\n approvalTool: q.approvalTool,\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.FIND_ORCHESTRATOR_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 token = getBearerTokenFromReq(req);\n const response = await findOrchestratorImportStatusByRepo(\n {\n logger,\n orchestratorRepositoryDao,\n orchestratorWorkflowDao,\n discovery,\n },\n q.repo,\n token,\n );\n return res.status(response.statusCode).json(response.responseBody);\n },\n );\n\n api.register(\n Operations.DELETE_TASK_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 deleteRepositoryRecord(\n {\n logger,\n dao: repositoryDao,\n },\n q.repo,\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 gitApiService:\n parseGitURLForApprovalTool(q.repo) === 'GITLAB'\n ? gitlabApiService\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 api.register(\n Operations.DELETE_ORCHESTRATOR_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 deleteRepositoryRecord(\n {\n logger,\n dao: orchestratorRepositoryDao,\n },\n q.repo,\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 // Strip x-scm-tokens from req.headers before the permission check and audit\n // middleware run so that OAuth tokens are never captured in audit logs.\n // The parsed map is stored in res.locals.scmTokens for handler use.\n router.use((req, res, next) => {\n const raw = req.headers['x-scm-tokens'];\n const rawStr = Array.isArray(raw) ? raw[0] : raw;\n delete req.headers['x-scm-tokens'];\n if (rawStr) {\n try {\n res.locals.scmTokens = parseScmTokensHeader(rawStr, logger);\n } catch (e) {\n next(e);\n return;\n }\n }\n next();\n });\n\n router.use(async (req, _res, next) => {\n if (req.path !== '/ping') {\n try {\n await permissionCheck(\n auditor,\n api.matchOperation(req as OpenAPIRequest)?.operationId,\n permissions,\n httpAuth,\n req,\n );\n } catch (e) {\n next(e);\n return;\n }\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_SCM_HOSTS:\n auditorEvent = await auditCreateEvent(auditor, 'scm-hosts-read', req);\n break;\n\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 case Operations.FIND_ALL_TASK_IMPORTS:\n case Operations.FIND_ALL_ORCHESTRATOR_WORKFLOW_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 case Operations.CREATE_TASK_IMPORT_JOBS:\n case Operations.CREATE_ORCHESTRATOR_WORKFLOW_JOBS:\n auditorEvent = await auditCreateEvent(auditor, 'import-write', req, {\n actionType: 'create',\n });\n break;\n case Operations.FIND_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_TASK_IMPORT_STATUS_BY_REPO:\n case Operations.FIND_ORCHESTRATOR_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 case Operations.DELETE_TASK_IMPORT_BY_REPO:\n case Operations.DELETE_ORCHESTRATOR_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}\nfunction getFindImportsParams(c: Context<any, any, any, any, any, Document>): {\n pageNumber?: number;\n pageSize?: number;\n apiVersion?: Paths.FindAllImports.Parameters.ApiVersion;\n search?: string;\n sortColumn?: Components.Parameters.SortColumnQueryParam;\n sortOrder?: Components.Parameters.SortOrderQueryParam;\n} {\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 pageNumber: number | undefined;\n let pageSize: number | undefined;\n if (apiVersion === undefined || apiVersion === 'v1') {\n // pagePerIntegration and sizePerIntegration deprecated in v1. 'page' and 'size' take precedence.\n pageNumber = stringToNumber(q.page || q.pagePerIntegration);\n pageSize = stringToNumber(q.size || q.sizePerIntegration);\n } else {\n // pagePerIntegration and sizePerIntegration removed in v2+ and replaced by 'page' and 'size'.\n pageNumber = stringToNumber(q.page);\n pageSize = stringToNumber(q.size);\n }\n return {\n pageNumber,\n pageSize,\n apiVersion: apiVersion,\n search: q.search,\n sortColumn: q.sortColumn,\n sortOrder: q.sortOrder,\n };\n}\n\nfunction getBearerTokenFromReq(req: express.Request): string {\n const header = req.header('authorization') ?? req.headers.authorization;\n if (header?.startsWith(`Bearer `)) {\n return header.replace('Bearer ', '');\n }\n throw new InputError(`Request provided without token`);\n}\n"],"names":["Operations","InputError","auth","migrate","repositoryDao","RepositoryDao","ScaffolderTaskDao","TaskLocationsDao","OrchestratorWorkflowDao","githubApiService","GithubApiService","gitlabApiService","GitlabApiService","catalogHttpClient","CatalogHttpClient","catalogInfoGenerator","CatalogInfoGenerator","OpenAPIBackend","fullFormats","openApiDocument","getImportTemplateRef","ping","findAllSCMHosts","findAllOrganizations","findAllRepositories","findRepositoriesByOrganization","findAllImports","findTaskImportStatusByRepo","sortImports","findOrchestratorImportStatusByRepo","createImportJobs","createTaskImportJobs","createWorkflowImportJobs","findImportStatusByRepo","deleteRepositoryRecord","deleteImportByRepo","parseGitURLForApprovalTool","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": "7.
|
|
3
|
+
"version": "7.3.0",
|
|
4
4
|
"main": "./dist/index.cjs.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -50,19 +50,19 @@
|
|
|
50
50
|
"openapi": "./scripts/openapi.sh"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@backstage/backend-defaults": "^0.
|
|
54
|
-
"@backstage/backend-plugin-api": "^1.
|
|
55
|
-
"@backstage/catalog-model": "^1.7.
|
|
53
|
+
"@backstage/backend-defaults": "^0.16.0",
|
|
54
|
+
"@backstage/backend-plugin-api": "^1.8.0",
|
|
55
|
+
"@backstage/catalog-model": "^1.7.7",
|
|
56
56
|
"@backstage/config": "^1.3.6",
|
|
57
57
|
"@backstage/errors": "^1.2.7",
|
|
58
|
-
"@backstage/integration": "^
|
|
59
|
-
"@backstage/plugin-catalog-node": "^1.
|
|
60
|
-
"@backstage/plugin-permission-common": "^0.9.
|
|
61
|
-
"@backstage/plugin-permission-node": "^0.10.
|
|
58
|
+
"@backstage/integration": "^2.0.0",
|
|
59
|
+
"@backstage/plugin-catalog-node": "^2.1.0",
|
|
60
|
+
"@backstage/plugin-permission-common": "^0.9.7",
|
|
61
|
+
"@backstage/plugin-permission-node": "^0.10.11",
|
|
62
62
|
"@gitbeaker/rest": "^43.4.0",
|
|
63
63
|
"@octokit/auth-app": "^7.2.2",
|
|
64
64
|
"@octokit/rest": "^20.0.2",
|
|
65
|
-
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^7.
|
|
65
|
+
"@red-hat-developer-hub/backstage-plugin-bulk-import-common": "^7.3.0",
|
|
66
66
|
"@red-hat-developer-hub/backstage-plugin-orchestrator-common": "^3.2.0",
|
|
67
67
|
"ajv-formats": "^3.0.1",
|
|
68
68
|
"eventsource-client": "^1.2.0",
|
|
@@ -76,13 +76,13 @@
|
|
|
76
76
|
"openapi-backend": "^5.10.6"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@backstage/backend-test-utils": "^1.
|
|
80
|
-
"@backstage/catalog-client": "^1.
|
|
81
|
-
"@backstage/cli": "^0.
|
|
79
|
+
"@backstage/backend-test-utils": "^1.11.1",
|
|
80
|
+
"@backstage/catalog-client": "^1.14.0",
|
|
81
|
+
"@backstage/cli": "^0.36.0",
|
|
82
82
|
"@backstage/config": "^1.3.6",
|
|
83
|
-
"@backstage/plugin-catalog-backend": "^3.
|
|
83
|
+
"@backstage/plugin-catalog-backend": "^3.5.0",
|
|
84
84
|
"@backstage/types": "^1.2.2",
|
|
85
|
-
"@openapitools/openapi-generator-cli": "2.
|
|
85
|
+
"@openapitools/openapi-generator-cli": "2.31.1",
|
|
86
86
|
"@spotify/prettier-config": "^15.0.0",
|
|
87
87
|
"@types/express": "4.17.25",
|
|
88
88
|
"@types/git-url-parse": "^9.0.0",
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"@types/supertest": "2.0.16",
|
|
92
92
|
"js-yaml-cli": "0.6.0",
|
|
93
93
|
"msw": "1.3.5",
|
|
94
|
-
"openapicmd": "2.
|
|
95
|
-
"prettier": "3.8.
|
|
94
|
+
"openapicmd": "2.9.2",
|
|
95
|
+
"prettier": "3.8.3",
|
|
96
96
|
"supertest": "6.3.4"
|
|
97
97
|
},
|
|
98
98
|
"files": [
|