@red-hat-developer-hub/backstage-plugin-bulk-import-backend 7.3.7 → 8.0.1
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 +24 -0
- package/config.schema.json +21 -0
- package/dist/catalog/catalogHttpClient.cjs.js +43 -71
- package/dist/catalog/catalogHttpClient.cjs.js.map +1 -1
- package/dist/database/repositoryDao.cjs.js +6 -1
- package/dist/database/repositoryDao.cjs.js.map +1 -1
- package/dist/github/types.cjs.js.map +1 -1
- package/dist/github/utils/orgUtils.cjs.js.map +1 -1
- package/dist/helpers/auth.cjs.js +0 -8
- package/dist/helpers/auth.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/plugin.cjs.js +8 -4
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +2 -10
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +21 -24
- package/config.d.ts +0 -30
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @red-hat-developer-hub/backstage-plugin-bulk-import-backend
|
|
2
2
|
|
|
3
|
+
## 8.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e0d0986: Updated dependency `prettier` to `3.9.6`.
|
|
8
|
+
- 503c66e: Updated dependency `@openapitools/openapi-generator-cli` to `2.40.1`.
|
|
9
|
+
Updated dependency `@red-hat-developer-hub/backstage-plugin-theme` to `^0.15.0`.
|
|
10
|
+
- 8966faf: Updated dependency `prettier` to `3.9.5`.
|
|
11
|
+
- Updated dependencies [e0d0986]
|
|
12
|
+
- Updated dependencies [8966faf]
|
|
13
|
+
- @red-hat-developer-hub/backstage-plugin-bulk-import-common@8.0.1
|
|
14
|
+
|
|
15
|
+
## 8.0.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- 02db099: Backstage version bump to v1.52.0
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 8eb345e: Updated dependency `js-yaml` to `^4.3.0`.
|
|
24
|
+
- Updated dependencies [02db099]
|
|
25
|
+
- @red-hat-developer-hub/backstage-plugin-bulk-import-common@8.0.0
|
|
26
|
+
|
|
3
27
|
## 7.3.7
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"properties": {
|
|
5
|
+
"bulkImport": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"importTemplate": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The name of the scaffolder template or entity reference to execute for importing a repository.",
|
|
11
|
+
"visibility": "backend"
|
|
12
|
+
},
|
|
13
|
+
"orchestratorWorkflow": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "The orchestrator workflow id to execute for importing a repository.",
|
|
16
|
+
"visibility": "backend"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,53 +1,43 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
require('@backstage/errors');
|
|
4
|
+
require('@backstage/plugin-permission-common');
|
|
5
|
+
require('@red-hat-developer-hub/backstage-plugin-bulk-import-common');
|
|
6
|
+
require('just-kebab-case');
|
|
5
7
|
var loggingUtils = require('../helpers/loggingUtils.cjs.js');
|
|
6
8
|
require('@backstage/catalog-model');
|
|
7
|
-
require('@backstage/errors');
|
|
8
9
|
require('git-url-parse');
|
|
9
10
|
var catalogUtils = require('./catalogUtils.cjs.js');
|
|
10
11
|
|
|
11
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
12
|
-
|
|
13
|
-
var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
|
|
14
|
-
|
|
15
12
|
class CatalogHttpClient {
|
|
16
13
|
logger;
|
|
17
14
|
config;
|
|
18
|
-
discovery;
|
|
19
15
|
auth;
|
|
20
|
-
|
|
16
|
+
catalog;
|
|
21
17
|
constructor(deps) {
|
|
22
18
|
this.logger = deps.logger;
|
|
23
19
|
this.config = deps.config;
|
|
24
|
-
this.discovery = deps.discovery;
|
|
25
20
|
this.auth = deps.auth;
|
|
26
|
-
this.
|
|
21
|
+
this.catalog = deps.catalog;
|
|
22
|
+
}
|
|
23
|
+
async getCredentials() {
|
|
24
|
+
return this.auth.getOwnServiceCredentials();
|
|
27
25
|
}
|
|
28
26
|
// Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location
|
|
29
27
|
async analyzeLocation(repoUrl) {
|
|
30
28
|
this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);
|
|
31
|
-
const response = await
|
|
32
|
-
`${await this.discovery.getBaseUrl("catalog")}/analyze-location`,
|
|
29
|
+
const response = await this.catalog.analyzeLocation(
|
|
33
30
|
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
method: "POST",
|
|
42
|
-
body: JSON.stringify({
|
|
43
|
-
location: {
|
|
44
|
-
type: "github",
|
|
45
|
-
target: repoUrl
|
|
46
|
-
}
|
|
47
|
-
})
|
|
31
|
+
location: {
|
|
32
|
+
type: "github",
|
|
33
|
+
target: repoUrl
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
credentials: await this.getCredentials()
|
|
48
38
|
}
|
|
49
39
|
);
|
|
50
|
-
return
|
|
40
|
+
return response.generateEntities ?? [];
|
|
51
41
|
}
|
|
52
42
|
async listCatalogUrlLocations(search, pageNumber, pageSize) {
|
|
53
43
|
const byId = await this.listCatalogUrlLocationsById(
|
|
@@ -80,27 +70,19 @@ class CatalogHttpClient {
|
|
|
80
70
|
};
|
|
81
71
|
}
|
|
82
72
|
async listCatalogUrlLocationsByIdFromLocationsEndpoint(search) {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"catalog"
|
|
90
|
-
)}`
|
|
91
|
-
},
|
|
92
|
-
method: "GET"
|
|
93
|
-
});
|
|
94
|
-
const locations = await response.json();
|
|
73
|
+
const { items: locations } = await this.catalog.getLocations(
|
|
74
|
+
{},
|
|
75
|
+
{
|
|
76
|
+
credentials: await this.getCredentials()
|
|
77
|
+
}
|
|
78
|
+
);
|
|
95
79
|
if (!Array.isArray(locations)) {
|
|
96
80
|
return { locations: [] };
|
|
97
81
|
}
|
|
98
|
-
const res = locations.filter(
|
|
99
|
-
(location) => location.data?.target && location.data?.type === "url"
|
|
100
|
-
).map((location) => {
|
|
82
|
+
const res = locations.filter((location) => location.target && location.type === "url").map((location) => {
|
|
101
83
|
return {
|
|
102
|
-
id: location.
|
|
103
|
-
target: location.
|
|
84
|
+
id: location.id,
|
|
85
|
+
target: location.target,
|
|
104
86
|
source: "location"
|
|
105
87
|
};
|
|
106
88
|
});
|
|
@@ -123,7 +105,7 @@ class CatalogHttpClient {
|
|
|
123
105
|
return { locations: filtered, totalCount: filtered.length };
|
|
124
106
|
}
|
|
125
107
|
async listCatalogUrlLocationEntitiesById(search, _pageNumber, _pageSize) {
|
|
126
|
-
const result = await this.
|
|
108
|
+
const result = await this.catalog.getEntities(
|
|
127
109
|
{
|
|
128
110
|
filter: {
|
|
129
111
|
kind: "Location"
|
|
@@ -135,7 +117,7 @@ class CatalogHttpClient {
|
|
|
135
117
|
order: { field: "metadata.name", order: "desc" }
|
|
136
118
|
},
|
|
137
119
|
{
|
|
138
|
-
|
|
120
|
+
credentials: await this.getCredentials()
|
|
139
121
|
}
|
|
140
122
|
);
|
|
141
123
|
const locations = result?.items ?? [];
|
|
@@ -159,14 +141,14 @@ class CatalogHttpClient {
|
|
|
159
141
|
*/
|
|
160
142
|
async verifyLocationExistence(repoCatalogUrl) {
|
|
161
143
|
try {
|
|
162
|
-
const result = await this.
|
|
144
|
+
const result = await this.catalog.addLocation(
|
|
163
145
|
{
|
|
164
146
|
type: "url",
|
|
165
147
|
target: repoCatalogUrl,
|
|
166
148
|
dryRun: true
|
|
167
149
|
},
|
|
168
150
|
{
|
|
169
|
-
|
|
151
|
+
credentials: await this.getCredentials()
|
|
170
152
|
}
|
|
171
153
|
);
|
|
172
154
|
return result.exists;
|
|
@@ -178,7 +160,7 @@ class CatalogHttpClient {
|
|
|
178
160
|
}
|
|
179
161
|
}
|
|
180
162
|
async hasEntityInCatalog(entityName) {
|
|
181
|
-
return this.
|
|
163
|
+
return this.catalog.queryEntities(
|
|
182
164
|
{
|
|
183
165
|
filter: {
|
|
184
166
|
"metadata.name": entityName
|
|
@@ -186,19 +168,19 @@ class CatalogHttpClient {
|
|
|
186
168
|
limit: 1
|
|
187
169
|
},
|
|
188
170
|
{
|
|
189
|
-
|
|
171
|
+
credentials: await this.getCredentials()
|
|
190
172
|
}
|
|
191
173
|
).then((resp) => resp.items?.length > 0);
|
|
192
174
|
}
|
|
193
175
|
async possiblyCreateLocation(repoCatalogUrl) {
|
|
194
176
|
try {
|
|
195
|
-
await this.
|
|
177
|
+
await this.catalog.addLocation(
|
|
196
178
|
{
|
|
197
179
|
type: "url",
|
|
198
180
|
target: repoCatalogUrl
|
|
199
181
|
},
|
|
200
182
|
{
|
|
201
|
-
|
|
183
|
+
credentials: await this.getCredentials()
|
|
202
184
|
}
|
|
203
185
|
);
|
|
204
186
|
} catch (error) {
|
|
@@ -209,18 +191,8 @@ class CatalogHttpClient {
|
|
|
209
191
|
}
|
|
210
192
|
async deleteCatalogLocationById(locationId) {
|
|
211
193
|
try {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
)}/locations/${locationId}`;
|
|
215
|
-
await fetch__default.default(url, {
|
|
216
|
-
headers: {
|
|
217
|
-
Accept: "application/json",
|
|
218
|
-
Authorization: `Bearer ${await auth.getTokenForPlugin(
|
|
219
|
-
this.auth,
|
|
220
|
-
"catalog"
|
|
221
|
-
)}`
|
|
222
|
-
},
|
|
223
|
-
method: "DELETE"
|
|
194
|
+
await this.catalog.removeLocationById(locationId, {
|
|
195
|
+
credentials: await this.getCredentials()
|
|
224
196
|
});
|
|
225
197
|
} catch (error) {
|
|
226
198
|
loggingUtils.logErrorIfNeeded(
|
|
@@ -231,8 +203,8 @@ class CatalogHttpClient {
|
|
|
231
203
|
}
|
|
232
204
|
}
|
|
233
205
|
async deleteCatalogLocationEntityById(locationUid) {
|
|
234
|
-
await this.
|
|
235
|
-
|
|
206
|
+
await this.catalog.removeEntityByUid(locationUid, {
|
|
207
|
+
credentials: await this.getCredentials()
|
|
236
208
|
});
|
|
237
209
|
}
|
|
238
210
|
async findLocationEntitiesByRepoUrl(repoUrl, defaultBranch) {
|
|
@@ -241,7 +213,7 @@ class CatalogHttpClient {
|
|
|
241
213
|
);
|
|
242
214
|
}
|
|
243
215
|
async findLocationEntitiesByTargetUrl(targetUrl, limit) {
|
|
244
|
-
return this.
|
|
216
|
+
return this.catalog.queryEntities(
|
|
245
217
|
{
|
|
246
218
|
filter: [
|
|
247
219
|
{ kind: "Location", "spec.type": "url", "spec.target": targetUrl }
|
|
@@ -250,7 +222,7 @@ class CatalogHttpClient {
|
|
|
250
222
|
limit
|
|
251
223
|
},
|
|
252
224
|
{
|
|
253
|
-
|
|
225
|
+
credentials: await this.getCredentials()
|
|
254
226
|
}
|
|
255
227
|
).then((resp) => resp.items);
|
|
256
228
|
}
|
|
@@ -282,8 +254,8 @@ class CatalogHttpClient {
|
|
|
282
254
|
async refreshEntity(kind, name, namespace = "default") {
|
|
283
255
|
const entityRef = `${kind}:${namespace}/${name}`;
|
|
284
256
|
this.logger.debug(`Refreshing entityRef: ${entityRef}`);
|
|
285
|
-
await this.
|
|
286
|
-
|
|
257
|
+
await this.catalog.refreshEntity(entityRef, {
|
|
258
|
+
credentials: await this.getCredentials()
|
|
287
259
|
});
|
|
288
260
|
}
|
|
289
261
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalogHttpClient.cjs.js","sources":["../../src/catalog/catalogHttpClient.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 {\n AuthService,\n DiscoveryService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { CatalogApi } from '@backstage/catalog-client';\nimport type { LocationEntity } from '@backstage/catalog-model';\nimport type { Config } from '@backstage/config';\n\nimport fetch from 'node-fetch';\n\nimport { getTokenForPlugin, logErrorIfNeeded } from '../helpers';\nimport { filterLocations, getCatalogUrl } from './catalogUtils';\nimport { CatalogLocation } from './types';\n\nexport class CatalogHttpClient {\n private readonly logger: LoggerService;\n private readonly config: Config;\n private readonly discovery: DiscoveryService;\n private readonly auth: AuthService;\n private readonly catalogApi: CatalogApi;\n\n constructor(deps: {\n logger: LoggerService;\n config: Config;\n discovery: DiscoveryService;\n auth: AuthService;\n catalogApi: CatalogApi;\n }) {\n this.logger = deps.logger;\n this.config = deps.config;\n this.discovery = deps.discovery;\n this.auth = deps.auth;\n this.catalogApi = deps.catalogApi;\n }\n\n // Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location\n async analyzeLocation(repoUrl: string): Promise<any[]> {\n this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);\n const response = await fetch(\n `${await this.discovery.getBaseUrl('catalog')}/analyze-location`,\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'POST',\n body: JSON.stringify({\n location: {\n type: 'github',\n target: repoUrl,\n },\n }),\n },\n );\n return (await response.json()).generateEntities ?? [];\n }\n\n async listCatalogUrlLocations(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n uniqueCatalogUrlLocations: Map<string, CatalogLocation>;\n totalCount?: number;\n }> {\n // byId order: config, locations, other\n const byId = await this.listCatalogUrlLocationsById(\n search,\n pageNumber,\n pageSize,\n );\n const result = new Map<string, CatalogLocation>();\n\n for (const l of byId.locations) {\n if (!result.has(l.target)) {\n result.set(l.target, l);\n }\n }\n return {\n uniqueCatalogUrlLocations: result,\n totalCount: byId.totalCount,\n };\n }\n\n async listCatalogUrlLocationsById(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await Promise.all([\n this.listCatalogUrlLocationsFromConfig(search),\n this.listCatalogUrlLocationsByIdFromLocationsEndpoint(search),\n this.listCatalogUrlLocationEntitiesById(search, pageNumber, pageSize),\n ]);\n const locations = result.flatMap(u => u.locations);\n // we might have duplicate elements here\n const totalCount = result\n .map(l => l.totalCount ?? 0)\n .reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n return {\n locations,\n totalCount,\n };\n }\n\n async listCatalogUrlLocationsByIdFromLocationsEndpoint(\n search?: string,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const url = `${await this.discovery.getBaseUrl('catalog')}/locations`;\n const response = await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'GET',\n });\n const locations = (await response.json()) as {\n data: { id: string; target: string; type: string };\n }[];\n if (!Array.isArray(locations)) {\n return { locations: [] };\n }\n const res = locations\n .filter(\n location => location.data?.target && location.data?.type === 'url',\n )\n .map(location => {\n return {\n id: location.data?.id,\n target: location.data.target,\n source: 'location',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n listCatalogUrlLocationsFromConfig(search?: string): {\n locations: CatalogLocation[];\n totalCount?: number;\n } {\n const locationConfigs =\n this.config.getOptionalConfigArray('catalog.locations') ?? [];\n const res = locationConfigs\n .filter(\n location =>\n location.getOptionalString('target') &&\n location.getOptionalString('type') === 'url',\n )\n .map(location => {\n const target = location.getString('target');\n return {\n id: `app-config-location--${target}`,\n target,\n source: 'config',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n async listCatalogUrlLocationEntitiesById(\n search?: string,\n _pageNumber?: number,\n _pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await this.catalogApi.getEntities(\n {\n filter: {\n kind: 'Location',\n },\n // There is no query parameter to find entities with target URLs containing a string.\n // The existing filter does an exact matching. That's why we are retrieving this hard-coded high number of Locations.\n limit: 9999,\n offset: 0,\n order: { field: 'metadata.name', order: 'desc' },\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n const locations = (result?.items ?? []) as LocationEntity[];\n const res = locations\n .filter(\n location => location.spec?.target && location.spec?.type === 'url',\n )\n .map(location => {\n return {\n id: location.metadata.uid,\n target: location.spec.target!,\n source: 'integration',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n /**\n * verifyLocationExistence checks for the existence of the Location target.\n * Under the hood, it attempts to read the target URL and will return false if the target could not be found\n * and even if there is already a Location row in the database.\n * @param repoCatalogUrl\n */\n async verifyLocationExistence(repoCatalogUrl: string): Promise<boolean> {\n try {\n const result = await this.catalogApi.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n dryRun: true,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n // The `result.exists` field is only filled in dryRun mode\n return result.exists as boolean;\n } catch (error: any) {\n if (\n error.message?.includes('NotFoundError') ||\n error.body?.error?.message?.includes('NotFoundError')\n ) {\n return false;\n }\n throw error;\n }\n }\n\n async hasEntityInCatalog(entityName: string) {\n return this.catalogApi\n .queryEntities(\n {\n filter: {\n 'metadata.name': entityName,\n },\n limit: 1,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n )\n .then(resp => resp.items?.length > 0);\n }\n\n async possiblyCreateLocation(repoCatalogUrl: string) {\n try {\n await this.catalogApi.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n );\n } catch (error: any) {\n if (\n !(\n error.message?.includes('ConflictError') ||\n error.body?.error?.name?.includes('ConflictError')\n )\n ) {\n throw error;\n }\n // Location already exists, which is fine\n }\n }\n\n async deleteCatalogLocationById(locationId: string): Promise<void> {\n try {\n const url = `${await this.discovery.getBaseUrl(\n 'catalog',\n )}/locations/${locationId}`;\n await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${await getTokenForPlugin(\n this.auth,\n 'catalog',\n )}`,\n },\n method: 'DELETE',\n });\n } catch (error: any) {\n logErrorIfNeeded(\n this.logger,\n `Could not delete location ${locationId}`,\n error,\n );\n }\n }\n\n async deleteCatalogLocationEntityById(locationUid: string): Promise<void> {\n await this.catalogApi.removeEntityByUid(locationUid, {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n });\n }\n\n async findLocationEntitiesByRepoUrl(repoUrl: string, defaultBranch?: string) {\n return this.findLocationEntitiesByTargetUrl(\n getCatalogUrl(this.config, repoUrl, defaultBranch),\n );\n }\n\n async findLocationEntitiesByTargetUrl(targetUrl: string, limit?: number) {\n return this.catalogApi\n .queryEntities(\n {\n filter: [\n { kind: 'Location', 'spec.type': 'url', 'spec.target': targetUrl },\n ],\n fields: ['metadata.namespace', 'metadata.name', 'metadata.uid'],\n limit,\n },\n {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n },\n )\n .then(resp => resp.items);\n }\n\n async refreshLocationByRepoUrl(repoUrl: string, defaultBranch?: string) {\n const promises: Promise<void>[] = [];\n this.findLocationEntitiesByRepoUrl(repoUrl, defaultBranch).then(\n entities => {\n const nbEntities = entities.length;\n if (nbEntities === 0) {\n this.logger.debug(`No Location Entity found for repo: ${repoUrl}`);\n return;\n }\n this.logger.debug(\n `Refreshing ${nbEntities} Location(s) for repo: ${repoUrl}`,\n );\n entities.forEach(ent =>\n promises.push(\n this.refreshEntity(\n 'location',\n ent.metadata.name,\n ent.metadata.namespace,\n ),\n ),\n );\n },\n );\n await Promise.all(promises);\n }\n\n async refreshEntity(\n kind: string,\n name: string,\n namespace: string = 'default',\n ) {\n const entityRef = `${kind}:${namespace}/${name}`;\n this.logger.debug(`Refreshing entityRef: ${entityRef}`);\n await this.catalogApi.refreshEntity(entityRef, {\n token: await getTokenForPlugin(this.auth, 'catalog'),\n });\n }\n}\n"],"names":["fetch","getTokenForPlugin","filterLocations","logErrorIfNeeded","getCatalogUrl"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"catalogHttpClient.cjs.js","sources":["../../src/catalog/catalogHttpClient.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 { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport type { LocationEntity } from '@backstage/catalog-model';\nimport type { Config } from '@backstage/config';\nimport type { CatalogService } from '@backstage/plugin-catalog-node';\n\nimport { logErrorIfNeeded } from '../helpers';\nimport { filterLocations, getCatalogUrl } from './catalogUtils';\nimport { CatalogLocation } from './types';\n\nexport class CatalogHttpClient {\n private readonly logger: LoggerService;\n private readonly config: Config;\n private readonly auth: AuthService;\n private readonly catalog: CatalogService;\n\n constructor(deps: {\n logger: LoggerService;\n config: Config;\n auth: AuthService;\n catalog: CatalogService;\n }) {\n this.logger = deps.logger;\n this.config = deps.config;\n this.auth = deps.auth;\n this.catalog = deps.catalog;\n }\n\n private async getCredentials() {\n return this.auth.getOwnServiceCredentials();\n }\n\n // Wrapper for https://backstage.io/docs/features/software-catalog/software-catalog-api/#post-analyze-location\n async analyzeLocation(repoUrl: string): Promise<any[]> {\n this.logger.debug(`Forwarding request to analyze location: ${repoUrl}`);\n const response = await this.catalog.analyzeLocation(\n {\n location: {\n type: 'github',\n target: repoUrl,\n },\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n return response.generateEntities ?? [];\n }\n\n async listCatalogUrlLocations(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n uniqueCatalogUrlLocations: Map<string, CatalogLocation>;\n totalCount?: number;\n }> {\n // byId order: config, locations, other\n const byId = await this.listCatalogUrlLocationsById(\n search,\n pageNumber,\n pageSize,\n );\n const result = new Map<string, CatalogLocation>();\n\n for (const l of byId.locations) {\n if (!result.has(l.target)) {\n result.set(l.target, l);\n }\n }\n return {\n uniqueCatalogUrlLocations: result,\n totalCount: byId.totalCount,\n };\n }\n\n async listCatalogUrlLocationsById(\n search?: string,\n pageNumber?: number,\n pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await Promise.all([\n this.listCatalogUrlLocationsFromConfig(search),\n this.listCatalogUrlLocationsByIdFromLocationsEndpoint(search),\n this.listCatalogUrlLocationEntitiesById(search, pageNumber, pageSize),\n ]);\n const locations = result.flatMap(u => u.locations);\n // we might have duplicate elements here\n const totalCount = result\n .map(l => l.totalCount ?? 0)\n .reduce((accumulator, currentValue) => accumulator + currentValue, 0);\n return {\n locations,\n totalCount,\n };\n }\n\n async listCatalogUrlLocationsByIdFromLocationsEndpoint(\n search?: string,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const { items: locations } = await this.catalog.getLocations(\n {},\n {\n credentials: await this.getCredentials(),\n },\n );\n if (!Array.isArray(locations)) {\n return { locations: [] };\n }\n const res = locations\n .filter(location => location.target && location.type === 'url')\n .map(location => {\n return {\n id: location.id,\n target: location.target,\n source: 'location',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n listCatalogUrlLocationsFromConfig(search?: string): {\n locations: CatalogLocation[];\n totalCount?: number;\n } {\n const locationConfigs =\n this.config.getOptionalConfigArray('catalog.locations') ?? [];\n const res = locationConfigs\n .filter(\n location =>\n location.getOptionalString('target') &&\n location.getOptionalString('type') === 'url',\n )\n .map(location => {\n const target = location.getString('target');\n return {\n id: `app-config-location--${target}`,\n target,\n source: 'config',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n async listCatalogUrlLocationEntitiesById(\n search?: string,\n _pageNumber?: number,\n _pageSize?: number,\n ): Promise<{\n locations: CatalogLocation[];\n totalCount?: number;\n }> {\n const result = await this.catalog.getEntities(\n {\n filter: {\n kind: 'Location',\n },\n // There is no query parameter to find entities with target URLs containing a string.\n // The existing filter does an exact matching. That's why we are retrieving this hard-coded high number of Locations.\n limit: 9999,\n offset: 0,\n order: { field: 'metadata.name', order: 'desc' },\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n const locations = (result?.items ?? []) as LocationEntity[];\n const res = locations\n .filter(\n location => location.spec?.target && location.spec?.type === 'url',\n )\n .map(location => {\n return {\n id: location.metadata.uid,\n target: location.spec.target!,\n source: 'integration',\n } as CatalogLocation;\n });\n const filtered = filterLocations(res, search);\n return { locations: filtered, totalCount: filtered.length };\n }\n\n /**\n * verifyLocationExistence checks for the existence of the Location target.\n * Under the hood, it attempts to read the target URL and will return false if the target could not be found\n * and even if there is already a Location row in the database.\n * @param repoCatalogUrl\n */\n async verifyLocationExistence(repoCatalogUrl: string): Promise<boolean> {\n try {\n const result = await this.catalog.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n dryRun: true,\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n // The `result.exists` field is only filled in dryRun mode\n return result.exists as boolean;\n } catch (error: any) {\n if (\n error.message?.includes('NotFoundError') ||\n error.body?.error?.message?.includes('NotFoundError')\n ) {\n return false;\n }\n throw error;\n }\n }\n\n async hasEntityInCatalog(entityName: string) {\n return this.catalog\n .queryEntities(\n {\n filter: {\n 'metadata.name': entityName,\n },\n limit: 1,\n },\n {\n credentials: await this.getCredentials(),\n },\n )\n .then(resp => resp.items?.length > 0);\n }\n\n async possiblyCreateLocation(repoCatalogUrl: string) {\n try {\n await this.catalog.addLocation(\n {\n type: 'url',\n target: repoCatalogUrl,\n },\n {\n credentials: await this.getCredentials(),\n },\n );\n } catch (error: any) {\n if (!(\n error.message?.includes('ConflictError') ||\n error.body?.error?.name?.includes('ConflictError')\n )) {\n throw error;\n }\n // Location already exists, which is fine\n }\n }\n\n async deleteCatalogLocationById(locationId: string): Promise<void> {\n try {\n await this.catalog.removeLocationById(locationId, {\n credentials: await this.getCredentials(),\n });\n } catch (error: any) {\n logErrorIfNeeded(\n this.logger,\n `Could not delete location ${locationId}`,\n error,\n );\n }\n }\n\n async deleteCatalogLocationEntityById(locationUid: string): Promise<void> {\n await this.catalog.removeEntityByUid(locationUid, {\n credentials: await this.getCredentials(),\n });\n }\n\n async findLocationEntitiesByRepoUrl(repoUrl: string, defaultBranch?: string) {\n return this.findLocationEntitiesByTargetUrl(\n getCatalogUrl(this.config, repoUrl, defaultBranch),\n );\n }\n\n async findLocationEntitiesByTargetUrl(targetUrl: string, limit?: number) {\n return this.catalog\n .queryEntities(\n {\n filter: [\n { kind: 'Location', 'spec.type': 'url', 'spec.target': targetUrl },\n ],\n fields: ['metadata.namespace', 'metadata.name', 'metadata.uid'],\n limit,\n },\n {\n credentials: await this.getCredentials(),\n },\n )\n .then(resp => resp.items);\n }\n\n async refreshLocationByRepoUrl(repoUrl: string, defaultBranch?: string) {\n const promises: Promise<void>[] = [];\n this.findLocationEntitiesByRepoUrl(repoUrl, defaultBranch).then(\n entities => {\n const nbEntities = entities.length;\n if (nbEntities === 0) {\n this.logger.debug(`No Location Entity found for repo: ${repoUrl}`);\n return;\n }\n this.logger.debug(\n `Refreshing ${nbEntities} Location(s) for repo: ${repoUrl}`,\n );\n entities.forEach(ent =>\n promises.push(\n this.refreshEntity(\n 'location',\n ent.metadata.name,\n ent.metadata.namespace,\n ),\n ),\n );\n },\n );\n await Promise.all(promises);\n }\n\n async refreshEntity(\n kind: string,\n name: string,\n namespace: string = 'default',\n ) {\n const entityRef = `${kind}:${namespace}/${name}`;\n this.logger.debug(`Refreshing entityRef: ${entityRef}`);\n await this.catalog.refreshEntity(entityRef, {\n credentials: await this.getCredentials(),\n });\n }\n}\n"],"names":["filterLocations","logErrorIfNeeded","getCatalogUrl"],"mappings":"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"}
|
|
@@ -89,7 +89,12 @@ class ScaffolderTaskDao {
|
|
|
89
89
|
return result[0].taskId;
|
|
90
90
|
}
|
|
91
91
|
async findTasksByRepositoryId(repositoryId) {
|
|
92
|
-
return await this.knex("scaffolder_tasks").where({ repositoryId }).select(
|
|
92
|
+
return await this.knex("scaffolder_tasks").where({ repositoryId }).select(
|
|
93
|
+
"taskId",
|
|
94
|
+
"repositoryId",
|
|
95
|
+
"scaffolderOptions",
|
|
96
|
+
"executedAt"
|
|
97
|
+
);
|
|
93
98
|
}
|
|
94
99
|
async lastExecutedTaskByRepoId(repositoryId) {
|
|
95
100
|
return await this.knex("scaffolder_tasks").where({ repositoryId }).orderBy("executedAt", "desc").first();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repositoryDao.cjs.js","sources":["../../src/database/repositoryDao.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';\n\nimport { Knex } from 'knex';\n\nimport { Components } from '../generated/openapi';\n\nexport interface Repository {\n id: number;\n url: string;\n approvalTool: Components.Schemas.ApprovalTool;\n}\n\nexport interface ScaffolderTask {\n taskId: string;\n scaffolderOptions: any;\n repositoryId: number;\n executedAt?: Date;\n}\n\nexport interface PaginatedResult<T> {\n data: T[];\n page: number;\n size: number;\n total: number;\n totalPages: number;\n}\n\nexport async function paginateQuery<T>(\n queryBuilder: Knex.QueryBuilder<any, T[]>,\n page: number = 1,\n size: number = 10,\n search?: { column: string; term?: string },\n): Promise<PaginatedResult<T>> {\n const offset = (page - 1) * size;\n\n let baseQuery = queryBuilder.clone();\n\n if (search?.term) {\n if (queryBuilder.client.dialect === 'postgres') {\n baseQuery = baseQuery.whereILike(search.column, `%${search.term}%`);\n } else {\n baseQuery = baseQuery.whereLike(search.column, `%${search.term}%`);\n }\n }\n\n const countQuery = baseQuery\n .clone()\n .clearSelect()\n .clearOrder()\n .count<{ count: string }[]>('* as count');\n\n const [rows, [{ count }]] = await Promise.all([\n baseQuery.clone().limit(size).offset(offset),\n countQuery,\n ]);\n\n const total = Number(count);\n\n return {\n data: rows as T[],\n page,\n size,\n total,\n totalPages: Math.ceil(total / size),\n };\n}\n\nexport type RepositoryName = 'repositories' | 'orchestrator_repositories';\n\n// @internal\nexport class RepositoryDao<R extends RepositoryName> {\n constructor(\n private readonly knex: Knex<any, any[]>,\n private readonly logger: LoggerService,\n private readonly tableName: R,\n ) {}\n\n async findRepositories(\n page: number = 1,\n size: number = 10,\n search?: string,\n ): Promise<PaginatedResult<Repository>> {\n this.logger.debug(\n `Fetching repositories page=${page}, size=${size}, search=${search}`,\n );\n const query = this.knex(this.tableName).select('id', 'url', 'approvalTool');\n const searchParam = { column: 'url', term: search };\n return paginateQuery<Repository>(query, page, size, searchParam);\n }\n\n async insertRepository(\n repoUrl: string,\n taskOrWorkflowId: string,\n approvalTool: string,\n ): Promise<number> {\n this.logger.debug(\n `Saving repository ${repoUrl} for task/workflow ${taskOrWorkflowId} to database..`,\n );\n const repository = await this.knex(this.tableName)\n .where({ url: repoUrl })\n .first();\n\n let repositoryId;\n if (repository) {\n repositoryId = repository.id;\n } else {\n const [newRepository] = await this.knex(this.tableName)\n .insert({ url: repoUrl, approvalTool: approvalTool })\n .returning('id');\n repositoryId = newRepository.id;\n }\n return repositoryId;\n }\n\n async findRepositoryByUrl(url: string): Promise<Repository | undefined> {\n this.logger.debug(`Fetching repository from database by url ${url}...`);\n return await this.knex(this.tableName).where({ url: url }).first();\n }\n\n async deleteRepository(url: string): Promise<void> {\n this.logger.debug(`Deleting repository from database by url ${url}...`);\n const repository = await this.knex(this.tableName)\n .where({ url: url })\n .first();\n\n if (repository) {\n await this.knex(this.tableName).where({ id: repository.id }).del();\n }\n }\n}\n\n// @internal\nexport class ScaffolderTaskDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async findAllTasks(): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks').select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n );\n }\n\n async insertTask(task: ScaffolderTask): Promise<string> {\n const result = await this.knex('scaffolder_tasks')\n .insert<ScaffolderTask>({\n taskId: task.taskId,\n repositoryId: task.repositoryId,\n scaffolderOptions: JSON.stringify(task.scaffolderOptions),\n executedAt: task.executedAt,\n })\n .returning<{ taskId: string }[]>('taskId');\n\n return result[0].taskId;\n }\n\n async findTasksByRepositoryId(\n repositoryId: number,\n ): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .select<\n ScaffolderTask[]\n >('taskId', 'repositoryId', 'scaffolderOptions', 'executedAt');\n }\n\n async lastExecutedTaskByRepoId(\n repositoryId: number,\n ): Promise<ScaffolderTask | undefined> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .orderBy('executedAt', 'desc')\n .first<ScaffolderTask>();\n }\n}\n\nexport interface TaskLocation {\n id: number;\n taskId: string;\n location: string;\n type: string;\n}\n\n// @internal\nexport class TaskLocationsDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async addTaskLocation(\n taskId: string,\n location: string,\n type: string = 'component',\n ): Promise<void> {\n await this.knex('task_locations').insert({ taskId, location, type });\n }\n\n async findLocationsByTaskId(taskId: string): Promise<TaskLocation[]> {\n return await this.knex('task_locations')\n .where({ taskId })\n .select<TaskLocation[]>('id', 'taskId', 'location', 'type');\n }\n\n async findAllLocations(): Promise<TaskLocation[]> {\n return await this.knex('task_locations').select<TaskLocation[]>(\n 'id',\n 'taskId',\n 'location',\n 'type',\n );\n }\n}\n\nexport interface OrchestratorWorkflow {\n id: number;\n instanceId: string;\n repositoryId: number;\n createdAt: Date;\n status?: string;\n}\n\n// @internal\nexport class OrchestratorWorkflowDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async insertWorkflow(\n instanceId: string,\n repositoryId: number,\n ): Promise<number> {\n const [newWorkflow] = await this.knex('orchestrator_workflows')\n .insert({\n instance_id: instanceId,\n repositoryId: repositoryId,\n })\n .returning('id');\n return newWorkflow.id;\n }\n\n async lastExecutedWorkflowByRepoId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow | undefined> {\n const result = await this.knex('orchestrator_workflows')\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n })\n .where({ repositoryId: repositoryId })\n .orderBy('created_at', 'desc')\n .first();\n return result;\n }\n\n async findWorkflowsByRepositoryId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow[]> {\n return await this.knex('orchestrator_workflows')\n .where({ repositoryId: repositoryId })\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n });\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repositoryDao.cjs.js","sources":["../../src/database/repositoryDao.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';\n\nimport { Knex } from 'knex';\n\nimport { Components } from '../generated/openapi';\n\nexport interface Repository {\n id: number;\n url: string;\n approvalTool: Components.Schemas.ApprovalTool;\n}\n\nexport interface ScaffolderTask {\n taskId: string;\n scaffolderOptions: any;\n repositoryId: number;\n executedAt?: Date;\n}\n\nexport interface PaginatedResult<T> {\n data: T[];\n page: number;\n size: number;\n total: number;\n totalPages: number;\n}\n\nexport async function paginateQuery<T>(\n queryBuilder: Knex.QueryBuilder<any, T[]>,\n page: number = 1,\n size: number = 10,\n search?: { column: string; term?: string },\n): Promise<PaginatedResult<T>> {\n const offset = (page - 1) * size;\n\n let baseQuery = queryBuilder.clone();\n\n if (search?.term) {\n if (queryBuilder.client.dialect === 'postgres') {\n baseQuery = baseQuery.whereILike(search.column, `%${search.term}%`);\n } else {\n baseQuery = baseQuery.whereLike(search.column, `%${search.term}%`);\n }\n }\n\n const countQuery = baseQuery\n .clone()\n .clearSelect()\n .clearOrder()\n .count<{ count: string }[]>('* as count');\n\n const [rows, [{ count }]] = await Promise.all([\n baseQuery.clone().limit(size).offset(offset),\n countQuery,\n ]);\n\n const total = Number(count);\n\n return {\n data: rows as T[],\n page,\n size,\n total,\n totalPages: Math.ceil(total / size),\n };\n}\n\nexport type RepositoryName = 'repositories' | 'orchestrator_repositories';\n\n// @internal\nexport class RepositoryDao<R extends RepositoryName> {\n constructor(\n private readonly knex: Knex<any, any[]>,\n private readonly logger: LoggerService,\n private readonly tableName: R,\n ) {}\n\n async findRepositories(\n page: number = 1,\n size: number = 10,\n search?: string,\n ): Promise<PaginatedResult<Repository>> {\n this.logger.debug(\n `Fetching repositories page=${page}, size=${size}, search=${search}`,\n );\n const query = this.knex(this.tableName).select('id', 'url', 'approvalTool');\n const searchParam = { column: 'url', term: search };\n return paginateQuery<Repository>(query, page, size, searchParam);\n }\n\n async insertRepository(\n repoUrl: string,\n taskOrWorkflowId: string,\n approvalTool: string,\n ): Promise<number> {\n this.logger.debug(\n `Saving repository ${repoUrl} for task/workflow ${taskOrWorkflowId} to database..`,\n );\n const repository = await this.knex(this.tableName)\n .where({ url: repoUrl })\n .first();\n\n let repositoryId;\n if (repository) {\n repositoryId = repository.id;\n } else {\n const [newRepository] = await this.knex(this.tableName)\n .insert({ url: repoUrl, approvalTool: approvalTool })\n .returning('id');\n repositoryId = newRepository.id;\n }\n return repositoryId;\n }\n\n async findRepositoryByUrl(url: string): Promise<Repository | undefined> {\n this.logger.debug(`Fetching repository from database by url ${url}...`);\n return await this.knex(this.tableName).where({ url: url }).first();\n }\n\n async deleteRepository(url: string): Promise<void> {\n this.logger.debug(`Deleting repository from database by url ${url}...`);\n const repository = await this.knex(this.tableName)\n .where({ url: url })\n .first();\n\n if (repository) {\n await this.knex(this.tableName).where({ id: repository.id }).del();\n }\n }\n}\n\n// @internal\nexport class ScaffolderTaskDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async findAllTasks(): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks').select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n );\n }\n\n async insertTask(task: ScaffolderTask): Promise<string> {\n const result = await this.knex('scaffolder_tasks')\n .insert<ScaffolderTask>({\n taskId: task.taskId,\n repositoryId: task.repositoryId,\n scaffolderOptions: JSON.stringify(task.scaffolderOptions),\n executedAt: task.executedAt,\n })\n .returning<{ taskId: string }[]>('taskId');\n\n return result[0].taskId;\n }\n\n async findTasksByRepositoryId(\n repositoryId: number,\n ): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n 'executedAt',\n );\n }\n\n async lastExecutedTaskByRepoId(\n repositoryId: number,\n ): Promise<ScaffolderTask | undefined> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .orderBy('executedAt', 'desc')\n .first<ScaffolderTask>();\n }\n}\n\nexport interface TaskLocation {\n id: number;\n taskId: string;\n location: string;\n type: string;\n}\n\n// @internal\nexport class TaskLocationsDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async addTaskLocation(\n taskId: string,\n location: string,\n type: string = 'component',\n ): Promise<void> {\n await this.knex('task_locations').insert({ taskId, location, type });\n }\n\n async findLocationsByTaskId(taskId: string): Promise<TaskLocation[]> {\n return await this.knex('task_locations')\n .where({ taskId })\n .select<TaskLocation[]>('id', 'taskId', 'location', 'type');\n }\n\n async findAllLocations(): Promise<TaskLocation[]> {\n return await this.knex('task_locations').select<TaskLocation[]>(\n 'id',\n 'taskId',\n 'location',\n 'type',\n );\n }\n}\n\nexport interface OrchestratorWorkflow {\n id: number;\n instanceId: string;\n repositoryId: number;\n createdAt: Date;\n status?: string;\n}\n\n// @internal\nexport class OrchestratorWorkflowDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async insertWorkflow(\n instanceId: string,\n repositoryId: number,\n ): Promise<number> {\n const [newWorkflow] = await this.knex('orchestrator_workflows')\n .insert({\n instance_id: instanceId,\n repositoryId: repositoryId,\n })\n .returning('id');\n return newWorkflow.id;\n }\n\n async lastExecutedWorkflowByRepoId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow | undefined> {\n const result = await this.knex('orchestrator_workflows')\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n })\n .where({ repositoryId: repositoryId })\n .orderBy('created_at', 'desc')\n .first();\n return result;\n }\n\n async findWorkflowsByRepositoryId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow[]> {\n return await this.knex('orchestrator_workflows')\n .where({ repositoryId: repositoryId })\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n });\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs.js","sources":["../../src/github/types.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 {\n GithubCredentials,\n GithubCredentialsProvider,\n} from '@backstage/integration';\n\nimport { type RestEndpointMethodTypes } from '@octokit/rest';\n\nexport type {\n SCMFetchError as GithubFetchError,\n SCMOrganization as GithubOrganization,\n SCMOrganizationResponse as GithubOrganizationResponse,\n SCMRepository as GithubRepository,\n SCMRepositoryResponse as GithubRepositoryResponse,\n} from '../scm/types';\n\nexport type AppCredentialFetchResult = AppCredential | AppCredentialError;\n\nexport type AppCredential = {\n appId: number;\n accessToken: string | undefined;\n installationAccountLogin?: string;\n};\nexport type AppCredentialError = { appId: number; error: Error };\n\nexport type ExtendedGithubCredentials =\n
|
|
1
|
+
{"version":3,"file":"types.cjs.js","sources":["../../src/github/types.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 {\n GithubCredentials,\n GithubCredentialsProvider,\n} from '@backstage/integration';\n\nimport { type RestEndpointMethodTypes } from '@octokit/rest';\n\nexport type {\n SCMFetchError as GithubFetchError,\n SCMOrganization as GithubOrganization,\n SCMOrganizationResponse as GithubOrganizationResponse,\n SCMRepository as GithubRepository,\n SCMRepositoryResponse as GithubRepositoryResponse,\n} from '../scm/types';\n\nexport type AppCredentialFetchResult = AppCredential | AppCredentialError;\n\nexport type AppCredential = {\n appId: number;\n accessToken: string | undefined;\n installationAccountLogin?: string;\n};\nexport type AppCredentialError = { appId: number; error: Error };\n\nexport type ExtendedGithubCredentials =\n GithubCredentials | GithubAppCredentials | GithubAppError;\n\nexport type GithubAppCredentials = GithubCredentials & {\n type: 'app';\n appId: number;\n accountLogin?: string;\n};\n\nexport type GithubAppError = {\n type: 'app';\n appId: number;\n error: Error;\n};\n\nexport function isGithubAppCredential(\n credential: ExtendedGithubCredentials,\n): credential is GithubAppCredentials {\n return 'appId' in credential && credential.type === 'app';\n}\n\nexport interface ExtendedGithubCredentialsProvider extends GithubCredentialsProvider {\n getAllCredentials: (options: {\n host: string;\n }) => Promise<ExtendedGithubCredentials[]>;\n}\n\nexport type AuthenticatedUserRepositoryResponse =\n RestEndpointMethodTypes['repos']['listForAuthenticatedUser']['response'];\n\nexport type AuthenticatedUserRepositoryList =\n AuthenticatedUserRepositoryResponse['data'];\n\nexport type AppInstallationRepositoriesResponse =\n RestEndpointMethodTypes['apps']['listReposAccessibleToInstallation']['response'];\n\nexport type AppInstallationRepositories =\n AppInstallationRepositoriesResponse['data'];\n"],"names":[],"mappings":";;AAuDO,SAAS,sBACd,UAAA,EACoC;AACpC,EAAA,OAAO,OAAA,IAAW,UAAA,IAAc,UAAA,CAAW,IAAA,KAAS,KAAA;AACtD;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orgUtils.cjs.js","sources":["../../../src/github/utils/orgUtils.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 {\n GithubCredentials,\n GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { logErrorIfNeeded, paginateArray } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type { GithubFetchError, GithubOrganization } from '../types';\nimport { computeTotalCountFromGitHubToken, handleError } from './utils';\n\nexport async function getAllAppOrgs(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n credentialAccountLogin?: string,\n) {\n const result = new Map<string, GithubOrganization>();\n const resp = await githubCredentialsProvider.getAllAppInstallations(ghConfig);\n for (const installation of resp ?? []) {\n if (\n !(\n installation.account &&\n installation.target_type?.toLowerCase() === 'organization'\n )\n ) {\n continue;\n }\n const acc = installation.account!;\n if (credentialAccountLogin !== acc.login) {\n continue;\n }\n result.set(acc.url, {\n id: acc.id,\n description: acc.description ?? undefined,\n name: acc.login,\n url: acc.html_url,\n html_url: acc.html_url,\n repos_url: acc.repos_url,\n events_url: acc.events_url,\n });\n }\n return result;\n}\n\nexport async function addGithubAppOrgs(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n ghConfig: GithubIntegrationConfig,\n params: {\n credentialAccountLogin: string | undefined;\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n },\n): Promise<{ totalCount?: number }> {\n const credentialAccountLogin = params.credentialAccountLogin;\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n let totalCount = 0;\n try {\n const resp = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credentialAccountLogin,\n );\n for (const [orgUrl, ghOrg] of resp) {\n if (search && !ghOrg.name.toLowerCase().includes(search.toLowerCase())) {\n continue;\n }\n const orgData = await octokit.request(\n orgUrl.replace('/users/', '/orgs/'),\n );\n orgs.set(ghOrg.name, {\n ...ghOrg,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n });\n totalCount++;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching organizations with access token for github app`,\n err,\n );\n errors.set(-1, err.message);\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgs(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n params: {\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n pageNumber: number;\n pageSize: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n const pageNumber = params.pageNumber ?? DefaultPageNumber;\n const pageSize = params.pageSize ?? DefaultPageSize;\n\n let totalCount: number | undefined;\n try {\n let matchingOrgs;\n if (search) {\n // Initial idea was to leverage octokit.rest.search.users({q: `${search} type:org`}),\n // but this searches across all of GitHub, not only the orgs accessible by the current creds.\n // That's why we are searching in everything, hoping the list of organizations to not be that big in size\n const resp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const allMatchingOrgs =\n resp?.filter(org =>\n org.login.toLowerCase().includes(search.toLowerCase()),\n ) ?? [];\n const matchingOrgsPage = paginateArray(\n allMatchingOrgs,\n pageNumber,\n pageSize,\n );\n matchingOrgs = matchingOrgsPage.result;\n totalCount = matchingOrgsPage.totalCount;\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.orgs.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n matchingOrgs = resp?.data ?? [];\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.orgs\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'orgs.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n\n for (const org of matchingOrgs) {\n const orgData = await octokit.request(org.url);\n const ghOrg: GithubOrganization = {\n id: org.id,\n name: org.login,\n description: org.description ?? undefined,\n url: orgData?.data?.html_url ?? org.url,\n repos_url: org.repos_url,\n hooks_url: org.hooks_url,\n issues_url: org.issues_url,\n members_url: org.members_url,\n public_members_url: org.public_members_url,\n avatar_url: org.avatar_url,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n };\n orgs.set(org.login, ghOrg);\n }\n } catch (err) {\n handleError(\n { logger: deps.logger },\n 'Fetching orgs with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n"],"names":["logErrorIfNeeded","DefaultPageNumber","DefaultPageSize","paginateArray","computeTotalCountFromGitHubToken","handleError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"orgUtils.cjs.js","sources":["../../../src/github/utils/orgUtils.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 {\n GithubCredentials,\n GithubIntegrationConfig,\n} from '@backstage/integration';\n\nimport { Octokit } from '@octokit/rest';\n\nimport { logErrorIfNeeded, paginateArray } from '../../helpers';\nimport {\n DefaultPageNumber,\n DefaultPageSize,\n} from '../../service/handlers/handlers';\nimport type { CustomGithubCredentialsProvider } from '../GithubAppManager';\nimport type { GithubFetchError, GithubOrganization } from '../types';\nimport { computeTotalCountFromGitHubToken, handleError } from './utils';\n\nexport async function getAllAppOrgs(\n githubCredentialsProvider: CustomGithubCredentialsProvider,\n ghConfig: GithubIntegrationConfig,\n credentialAccountLogin?: string,\n) {\n const result = new Map<string, GithubOrganization>();\n const resp = await githubCredentialsProvider.getAllAppInstallations(ghConfig);\n for (const installation of resp ?? []) {\n if (!(\n installation.account &&\n installation.target_type?.toLowerCase() === 'organization'\n )) {\n continue;\n }\n const acc = installation.account!;\n if (credentialAccountLogin !== acc.login) {\n continue;\n }\n result.set(acc.url, {\n id: acc.id,\n description: acc.description ?? undefined,\n name: acc.login,\n url: acc.html_url,\n html_url: acc.html_url,\n repos_url: acc.repos_url,\n events_url: acc.events_url,\n });\n }\n return result;\n}\n\nexport async function addGithubAppOrgs(\n deps: {\n logger: LoggerService;\n githubCredentialsProvider: CustomGithubCredentialsProvider;\n },\n octokit: Octokit,\n ghConfig: GithubIntegrationConfig,\n params: {\n credentialAccountLogin: string | undefined;\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n },\n): Promise<{ totalCount?: number }> {\n const credentialAccountLogin = params.credentialAccountLogin;\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n let totalCount = 0;\n try {\n const resp = await getAllAppOrgs(\n deps.githubCredentialsProvider,\n ghConfig,\n credentialAccountLogin,\n );\n for (const [orgUrl, ghOrg] of resp) {\n if (search && !ghOrg.name.toLowerCase().includes(search.toLowerCase())) {\n continue;\n }\n const orgData = await octokit.request(\n orgUrl.replace('/users/', '/orgs/'),\n );\n orgs.set(ghOrg.name, {\n ...ghOrg,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n });\n totalCount++;\n }\n } catch (err: any) {\n logErrorIfNeeded(\n deps.logger,\n `Fetching organizations with access token for github app`,\n err,\n );\n errors.set(-1, err.message);\n }\n return { totalCount };\n}\n\nexport async function addGithubTokenOrgs(\n deps: {\n logger: LoggerService;\n },\n octokit: Octokit,\n credential: GithubCredentials,\n params: {\n search: string | undefined;\n orgs: Map<string, GithubOrganization>;\n errors: Map<number, GithubFetchError>;\n pageNumber: number;\n pageSize: number;\n },\n): Promise<{ totalCount?: number }> {\n const search = params.search;\n const orgs = params.orgs;\n const errors = params.errors;\n const pageNumber = params.pageNumber ?? DefaultPageNumber;\n const pageSize = params.pageSize ?? DefaultPageSize;\n\n let totalCount: number | undefined;\n try {\n let matchingOrgs;\n if (search) {\n // Initial idea was to leverage octokit.rest.search.users({q: `${search} type:org`}),\n // but this searches across all of GitHub, not only the orgs accessible by the current creds.\n // That's why we are searching in everything, hoping the list of organizations to not be that big in size\n const resp = await octokit.paginate(\n octokit.rest.orgs.listForAuthenticatedUser,\n {\n sort: 'full_name',\n direction: 'asc',\n },\n );\n const allMatchingOrgs =\n resp?.filter(org =>\n org.login.toLowerCase().includes(search.toLowerCase()),\n ) ?? [];\n const matchingOrgsPage = paginateArray(\n allMatchingOrgs,\n pageNumber,\n pageSize,\n );\n matchingOrgs = matchingOrgsPage.result;\n totalCount = matchingOrgsPage.totalCount;\n } else {\n /**\n * The listForAuthenticatedUser endpoint will grab all the repositories the github token has explicit access to.\n * These would include repositories they own, repositories where they are a collaborator,\n * and repositories that they can access through an organization membership.\n */\n const resp = await octokit.rest.orgs.listForAuthenticatedUser({\n page: pageNumber,\n per_page: pageSize,\n sort: 'full_name',\n direction: 'asc',\n });\n matchingOrgs = resp?.data ?? [];\n\n totalCount = await computeTotalCountFromGitHubToken(\n deps,\n async (lastPageNumber: number) =>\n octokit.orgs\n .listForAuthenticatedUser({\n page: lastPageNumber,\n per_page: 100,\n })\n .then(lastPageResp => lastPageResp.data.length),\n 'orgs.listForAuthenticatedUser',\n resp?.data?.length,\n resp?.headers?.link,\n );\n }\n\n for (const org of matchingOrgs) {\n const orgData = await octokit.request(org.url);\n const ghOrg: GithubOrganization = {\n id: org.id,\n name: org.login,\n description: org.description ?? undefined,\n url: orgData?.data?.html_url ?? org.url,\n repos_url: org.repos_url,\n hooks_url: org.hooks_url,\n issues_url: org.issues_url,\n members_url: org.members_url,\n public_members_url: org.public_members_url,\n avatar_url: org.avatar_url,\n public_repos: orgData?.data?.public_repos,\n total_private_repos: orgData?.data?.total_private_repos,\n owned_private_repos: orgData?.data?.owned_private_repos,\n };\n orgs.set(org.login, ghOrg);\n }\n } catch (err) {\n handleError(\n { logger: deps.logger },\n 'Fetching orgs with token from token',\n credential,\n errors,\n err,\n );\n }\n return { totalCount };\n}\n"],"names":["logErrorIfNeeded","DefaultPageNumber","DefaultPageSize","paginateArray","computeTotalCountFromGitHubToken","handleError"],"mappings":"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"}
|
package/dist/helpers/auth.cjs.js
CHANGED
|
@@ -28,14 +28,6 @@ async function permissionCheck(auditor, openApiOperationId, permissions, httpAut
|
|
|
28
28
|
throw err;
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
async function getTokenForPlugin(auth, targetPluginId) {
|
|
32
|
-
const resp = await auth.getPluginRequestToken({
|
|
33
|
-
onBehalfOf: await auth.getOwnServiceCredentials(),
|
|
34
|
-
targetPluginId
|
|
35
|
-
});
|
|
36
|
-
return resp.token;
|
|
37
|
-
}
|
|
38
31
|
|
|
39
|
-
exports.getTokenForPlugin = getTokenForPlugin;
|
|
40
32
|
exports.permissionCheck = permissionCheck;
|
|
41
33
|
//# sourceMappingURL=auth.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.cjs.js","sources":["../../src/helpers/auth.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 {\n AuditorService,\n
|
|
1
|
+
{"version":3,"file":"auth.cjs.js","sources":["../../src/helpers/auth.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 {\n AuditorService,\n HttpAuthService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport express from 'express';\n\nimport { bulkImportPermission } from '@red-hat-developer-hub/backstage-plugin-bulk-import-common';\n\nimport { auditCreateEvent } from './auditorUtils';\n\n/**\n * This will resolve to { result: AuthorizeResult.ALLOW } if the permission framework is disabled\n */\nexport async function permissionCheck(\n auditor: AuditorService,\n openApiOperationId: string | undefined,\n permissions: PermissionsService,\n httpAuth: HttpAuthService,\n req: express.Request,\n) {\n const decision = (\n await permissions.authorize(\n [\n {\n permission: bulkImportPermission,\n resourceRef: bulkImportPermission.resourceType,\n },\n ],\n {\n credentials: await httpAuth.credentials(req),\n },\n )\n )[0];\n\n if (decision.result === AuthorizeResult.DENY) {\n const err = new NotAllowedError('Unauthorized');\n const auditorEvent = await auditCreateEvent(\n auditor,\n openApiOperationId,\n req,\n );\n await auditorEvent.fail({ error: err, meta: { responseStatus: 403 } });\n throw err;\n }\n}\n"],"names":["bulkImportPermission","AuthorizeResult","NotAllowedError","auditCreateEvent"],"mappings":";;;;;;;AAiCA,eAAsB,eAAA,CACpB,OAAA,EACA,kBAAA,EACA,WAAA,EACA,UACA,GAAA,EACA;AACA,EAAA,MAAM,QAAA,GAAA,CACJ,MAAM,WAAA,CAAY,SAAA;AAAA,IAChB;AAAA,MACE;AAAA,QACE,UAAA,EAAYA,oDAAA;AAAA,QACZ,aAAaA,oDAAA,CAAqB;AAAA;AACpC,KACF;AAAA,IACA;AAAA,MACE,WAAA,EAAa,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG;AAAA;AAC7C,KAEF,CAAC,CAAA;AAEH,EAAA,IAAI,QAAA,CAAS,MAAA,KAAWC,sCAAA,CAAgB,IAAA,EAAM;AAC5C,IAAA,MAAM,GAAA,GAAM,IAAIC,sBAAA,CAAgB,cAAc,CAAA;AAC9C,IAAA,MAAM,eAAe,MAAMC,6BAAA;AAAA,MACzB,OAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,YAAA,CAAa,IAAA,CAAK,EAAE,KAAA,EAAO,GAAA,EAAK,MAAM,EAAE,cAAA,EAAgB,GAAA,EAAI,EAAG,CAAA;AACrE,IAAA,MAAM,GAAA;AAAA,EACR;AACF;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
2
|
import { LoggerService, CacheService, DiscoveryService, HttpAuthService, AuthService, AuditorService, DatabaseService } from '@backstage/backend-plugin-api';
|
|
3
|
-
import { CatalogApi } from '@backstage/catalog-client';
|
|
4
3
|
import { Config } from '@backstage/config';
|
|
4
|
+
import { CatalogService } from '@backstage/plugin-catalog-node';
|
|
5
5
|
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
|
6
6
|
import express from 'express';
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@ interface RouterOptions {
|
|
|
23
23
|
discovery: DiscoveryService;
|
|
24
24
|
httpAuth: HttpAuthService;
|
|
25
25
|
auth: AuthService;
|
|
26
|
-
|
|
26
|
+
catalog: CatalogService;
|
|
27
27
|
auditor: AuditorService;
|
|
28
28
|
database: DatabaseService;
|
|
29
29
|
}
|