@kuadrant/kuadrant-backstage-plugin-backend 0.0.1-test.1-57ace816 → 0.0.1-test.1-48246e3

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.
@@ -0,0 +1,27 @@
1
+ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
+ import { RootConfigService } from '@backstage/backend-plugin-api';
3
+ import { EntityProvider, EntityProviderConnection } from '@backstage/plugin-catalog-node';
4
+
5
+ declare class APIProductEntityProvider implements EntityProvider {
6
+ private readonly k8sClient;
7
+ private connection?;
8
+ private readonly providerId;
9
+ constructor(config: RootConfigService);
10
+ getProviderName(): string;
11
+ connect(connection: EntityProviderConnection): Promise<void>;
12
+ refresh(): Promise<void>;
13
+ private transformToEntity;
14
+ }
15
+
16
+ /**
17
+ * get the apiproduct entity provider instance
18
+ * @public
19
+ */
20
+ declare function getAPIProductEntityProvider(): APIProductEntityProvider | null;
21
+ /**
22
+ * backend module for apiproduct entity provider
23
+ * @public
24
+ */
25
+ declare const catalogModuleApiProductEntityProvider: _backstage_backend_plugin_api.BackendFeature;
26
+
27
+ export { catalogModuleApiProductEntityProvider, catalogModuleApiProductEntityProvider as default, getAPIProductEntityProvider };
package/dist/index.cjs.js CHANGED
@@ -15,9 +15,12 @@ exports.kuadrantApiKeyDeleteOwnPermission = permissions.kuadrantApiKeyDeleteOwnP
15
15
  exports.kuadrantApiKeyReadAllPermission = permissions.kuadrantApiKeyReadAllPermission;
16
16
  exports.kuadrantApiKeyReadOwnPermission = permissions.kuadrantApiKeyReadOwnPermission;
17
17
  exports.kuadrantApiKeyRequestCreatePermission = permissions.kuadrantApiKeyRequestCreatePermission;
18
+ exports.kuadrantApiKeyRequestDeleteAllPermission = permissions.kuadrantApiKeyRequestDeleteAllPermission;
19
+ exports.kuadrantApiKeyRequestDeleteOwnPermission = permissions.kuadrantApiKeyRequestDeleteOwnPermission;
18
20
  exports.kuadrantApiKeyRequestListPermission = permissions.kuadrantApiKeyRequestListPermission;
19
21
  exports.kuadrantApiKeyRequestReadAllPermission = permissions.kuadrantApiKeyRequestReadAllPermission;
20
22
  exports.kuadrantApiKeyRequestReadOwnPermission = permissions.kuadrantApiKeyRequestReadOwnPermission;
23
+ exports.kuadrantApiKeyRequestUpdateOwnPermission = permissions.kuadrantApiKeyRequestUpdateOwnPermission;
21
24
  exports.kuadrantApiKeyRequestUpdatePermission = permissions.kuadrantApiKeyRequestUpdatePermission;
22
25
  exports.kuadrantApiProductCreatePermission = permissions.kuadrantApiProductCreatePermission;
23
26
  exports.kuadrantApiProductDeletePermission = permissions.kuadrantApiProductDeletePermission;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,50 @@
1
+ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
+ import * as _backstage_plugin_permission_common from '@backstage/plugin-permission-common';
3
+ export { default as catalogModuleApiProductEntityProvider } from './alpha.js';
4
+ export { default as kuadrantRbacModule } from './rbac.js';
5
+ import '@backstage/plugin-catalog-node';
6
+
7
+ /**
8
+ * kuadrantPlugin backend plugin
9
+ *
10
+ * @public
11
+ */
12
+ declare const kuadrantPlugin: _backstage_backend_plugin_api.BackendFeature;
13
+
14
+ /**
15
+ * Permission definitions for the Kuadrant plugin
16
+ *
17
+ * These permissions control access to PlanPolicy, APIProduct, APIKeyRequest,
18
+ * and API key management within the Kuadrant Backstage plugin.
19
+ *
20
+ * Permissions are composable - use them to build custom roles beyond the
21
+ * three reference personas (Platform Engineer, API Owner, API Consumer).
22
+ */
23
+ declare const kuadrantPlanPolicyCreatePermission: _backstage_plugin_permission_common.BasicPermission;
24
+ declare const kuadrantPlanPolicyReadPermission: _backstage_plugin_permission_common.BasicPermission;
25
+ declare const kuadrantPlanPolicyUpdatePermission: _backstage_plugin_permission_common.BasicPermission;
26
+ declare const kuadrantPlanPolicyDeletePermission: _backstage_plugin_permission_common.BasicPermission;
27
+ declare const kuadrantPlanPolicyListPermission: _backstage_plugin_permission_common.BasicPermission;
28
+ declare const kuadrantApiProductCreatePermission: _backstage_plugin_permission_common.BasicPermission;
29
+ declare const kuadrantApiProductReadPermission: _backstage_plugin_permission_common.BasicPermission;
30
+ declare const kuadrantApiProductUpdatePermission: _backstage_plugin_permission_common.BasicPermission;
31
+ declare const kuadrantApiProductDeletePermission: _backstage_plugin_permission_common.BasicPermission;
32
+ declare const kuadrantApiProductListPermission: _backstage_plugin_permission_common.BasicPermission;
33
+ declare const kuadrantApiKeyRequestCreatePermission: _backstage_plugin_permission_common.ResourcePermission<"apiproduct">;
34
+ declare const kuadrantApiKeyRequestReadOwnPermission: _backstage_plugin_permission_common.BasicPermission;
35
+ declare const kuadrantApiKeyRequestReadAllPermission: _backstage_plugin_permission_common.BasicPermission;
36
+ declare const kuadrantApiKeyRequestUpdatePermission: _backstage_plugin_permission_common.BasicPermission;
37
+ declare const kuadrantApiKeyRequestListPermission: _backstage_plugin_permission_common.BasicPermission;
38
+ declare const kuadrantApiKeyRequestUpdateOwnPermission: _backstage_plugin_permission_common.BasicPermission;
39
+ declare const kuadrantApiKeyRequestDeleteOwnPermission: _backstage_plugin_permission_common.BasicPermission;
40
+ declare const kuadrantApiKeyRequestDeleteAllPermission: _backstage_plugin_permission_common.BasicPermission;
41
+ declare const kuadrantApiKeyReadOwnPermission: _backstage_plugin_permission_common.BasicPermission;
42
+ declare const kuadrantApiKeyReadAllPermission: _backstage_plugin_permission_common.BasicPermission;
43
+ declare const kuadrantApiKeyDeleteOwnPermission: _backstage_plugin_permission_common.BasicPermission;
44
+ declare const kuadrantApiKeyDeleteAllPermission: _backstage_plugin_permission_common.BasicPermission;
45
+ /**
46
+ * All Kuadrant permissions as an array for easy iteration
47
+ */
48
+ declare const kuadrantPermissions: (_backstage_plugin_permission_common.BasicPermission | _backstage_plugin_permission_common.ResourcePermission<"apiproduct">)[];
49
+
50
+ export { kuadrantPlugin as default, kuadrantApiKeyDeleteAllPermission, kuadrantApiKeyDeleteOwnPermission, kuadrantApiKeyReadAllPermission, kuadrantApiKeyReadOwnPermission, kuadrantApiKeyRequestCreatePermission, kuadrantApiKeyRequestDeleteAllPermission, kuadrantApiKeyRequestDeleteOwnPermission, kuadrantApiKeyRequestListPermission, kuadrantApiKeyRequestReadAllPermission, kuadrantApiKeyRequestReadOwnPermission, kuadrantApiKeyRequestUpdateOwnPermission, kuadrantApiKeyRequestUpdatePermission, kuadrantApiProductCreatePermission, kuadrantApiProductDeletePermission, kuadrantApiProductListPermission, kuadrantApiProductReadPermission, kuadrantApiProductUpdatePermission, kuadrantPermissions, kuadrantPlanPolicyCreatePermission, kuadrantPlanPolicyDeletePermission, kuadrantPlanPolicyListPermission, kuadrantPlanPolicyReadPermission, kuadrantPlanPolicyUpdatePermission };
@@ -63,6 +63,18 @@ const kuadrantApiKeyRequestListPermission = pluginPermissionCommon.createPermiss
63
63
  name: "kuadrant.apikeyrequest.list",
64
64
  attributes: { action: "read" }
65
65
  });
66
+ const kuadrantApiKeyRequestUpdateOwnPermission = pluginPermissionCommon.createPermission({
67
+ name: "kuadrant.apikeyrequest.update.own",
68
+ attributes: { action: "update" }
69
+ });
70
+ const kuadrantApiKeyRequestDeleteOwnPermission = pluginPermissionCommon.createPermission({
71
+ name: "kuadrant.apikeyrequest.delete.own",
72
+ attributes: { action: "delete" }
73
+ });
74
+ const kuadrantApiKeyRequestDeleteAllPermission = pluginPermissionCommon.createPermission({
75
+ name: "kuadrant.apikeyrequest.delete.all",
76
+ attributes: { action: "delete" }
77
+ });
66
78
  const kuadrantApiKeyReadOwnPermission = pluginPermissionCommon.createPermission({
67
79
  name: "kuadrant.apikey.read.own",
68
80
  attributes: { action: "read" }
@@ -94,7 +106,10 @@ const kuadrantPermissions = [
94
106
  kuadrantApiKeyRequestReadOwnPermission,
95
107
  kuadrantApiKeyRequestReadAllPermission,
96
108
  kuadrantApiKeyRequestUpdatePermission,
109
+ kuadrantApiKeyRequestUpdateOwnPermission,
97
110
  kuadrantApiKeyRequestListPermission,
111
+ kuadrantApiKeyRequestDeleteOwnPermission,
112
+ kuadrantApiKeyRequestDeleteAllPermission,
98
113
  kuadrantApiKeyReadOwnPermission,
99
114
  kuadrantApiKeyReadAllPermission,
100
115
  kuadrantApiKeyDeleteOwnPermission,
@@ -106,9 +121,12 @@ exports.kuadrantApiKeyDeleteOwnPermission = kuadrantApiKeyDeleteOwnPermission;
106
121
  exports.kuadrantApiKeyReadAllPermission = kuadrantApiKeyReadAllPermission;
107
122
  exports.kuadrantApiKeyReadOwnPermission = kuadrantApiKeyReadOwnPermission;
108
123
  exports.kuadrantApiKeyRequestCreatePermission = kuadrantApiKeyRequestCreatePermission;
124
+ exports.kuadrantApiKeyRequestDeleteAllPermission = kuadrantApiKeyRequestDeleteAllPermission;
125
+ exports.kuadrantApiKeyRequestDeleteOwnPermission = kuadrantApiKeyRequestDeleteOwnPermission;
109
126
  exports.kuadrantApiKeyRequestListPermission = kuadrantApiKeyRequestListPermission;
110
127
  exports.kuadrantApiKeyRequestReadAllPermission = kuadrantApiKeyRequestReadAllPermission;
111
128
  exports.kuadrantApiKeyRequestReadOwnPermission = kuadrantApiKeyRequestReadOwnPermission;
129
+ exports.kuadrantApiKeyRequestUpdateOwnPermission = kuadrantApiKeyRequestUpdateOwnPermission;
112
130
  exports.kuadrantApiKeyRequestUpdatePermission = kuadrantApiKeyRequestUpdatePermission;
113
131
  exports.kuadrantApiProductCreatePermission = kuadrantApiProductCreatePermission;
114
132
  exports.kuadrantApiProductDeletePermission = kuadrantApiProductDeletePermission;
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.cjs.js","sources":["../src/permissions.ts"],"sourcesContent":["import { createPermission } from '@backstage/plugin-permission-common';\n\n/**\n * Permission definitions for the Kuadrant plugin\n *\n * These permissions control access to PlanPolicy, APIProduct, APIKeyRequest,\n * and API key management within the Kuadrant Backstage plugin.\n *\n * Permissions are composable - use them to build custom roles beyond the\n * three reference personas (Platform Engineer, API Owner, API Consumer).\n */\n\n// planpolicy permissions (rate limit tiers)\nexport const kuadrantPlanPolicyCreatePermission = createPermission({\n name: 'kuadrant.planpolicy.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantPlanPolicyReadPermission = createPermission({\n name: 'kuadrant.planpolicy.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantPlanPolicyUpdatePermission = createPermission({\n name: 'kuadrant.planpolicy.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantPlanPolicyDeletePermission = createPermission({\n name: 'kuadrant.planpolicy.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantPlanPolicyListPermission = createPermission({\n name: 'kuadrant.planpolicy.list',\n attributes: { action: 'read' },\n});\n\n// apiproduct permissions (catalog entries)\nexport const kuadrantApiProductCreatePermission = createPermission({\n name: 'kuadrant.apiproduct.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantApiProductReadPermission = createPermission({\n name: 'kuadrant.apiproduct.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiProductUpdatePermission = createPermission({\n name: 'kuadrant.apiproduct.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiProductDeletePermission = createPermission({\n name: 'kuadrant.apiproduct.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiProductListPermission = createPermission({\n name: 'kuadrant.apiproduct.list',\n attributes: { action: 'read' },\n});\n\n// apikeyrequest permissions (access requests)\nexport const kuadrantApiKeyRequestCreatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.create',\n attributes: { action: 'create' },\n resourceType: 'apiproduct',\n});\n\nexport const kuadrantApiKeyRequestReadOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestReadAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestUpdatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestListPermission = createPermission({\n name: 'kuadrant.apikeyrequest.list',\n attributes: { action: 'read' },\n});\n\n// api key permissions (managed secrets)\nexport const kuadrantApiKeyReadOwnPermission = createPermission({\n name: 'kuadrant.apikey.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyReadAllPermission = createPermission({\n name: 'kuadrant.apikey.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikey.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyDeleteAllPermission = createPermission({\n name: 'kuadrant.apikey.delete.all',\n attributes: { action: 'delete' },\n});\n\n/**\n * All Kuadrant permissions as an array for easy iteration\n */\nexport const kuadrantPermissions = [\n kuadrantPlanPolicyCreatePermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantPlanPolicyUpdatePermission,\n kuadrantPlanPolicyDeletePermission,\n kuadrantPlanPolicyListPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductReadPermission,\n kuadrantApiProductUpdatePermission,\n kuadrantApiProductDeletePermission,\n kuadrantApiProductListPermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestUpdatePermission,\n kuadrantApiKeyRequestListPermission,\n kuadrantApiKeyReadOwnPermission,\n kuadrantApiKeyReadAllPermission,\n kuadrantApiKeyDeleteOwnPermission,\n kuadrantApiKeyDeleteAllPermission,\n];\n"],"names":["createPermission"],"mappings":"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"}
1
+ {"version":3,"file":"permissions.cjs.js","sources":["../src/permissions.ts"],"sourcesContent":["import { createPermission } from '@backstage/plugin-permission-common';\n\n/**\n * Permission definitions for the Kuadrant plugin\n *\n * These permissions control access to PlanPolicy, APIProduct, APIKeyRequest,\n * and API key management within the Kuadrant Backstage plugin.\n *\n * Permissions are composable - use them to build custom roles beyond the\n * three reference personas (Platform Engineer, API Owner, API Consumer).\n */\n\n// planpolicy permissions (rate limit tiers)\nexport const kuadrantPlanPolicyCreatePermission = createPermission({\n name: 'kuadrant.planpolicy.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantPlanPolicyReadPermission = createPermission({\n name: 'kuadrant.planpolicy.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantPlanPolicyUpdatePermission = createPermission({\n name: 'kuadrant.planpolicy.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantPlanPolicyDeletePermission = createPermission({\n name: 'kuadrant.planpolicy.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantPlanPolicyListPermission = createPermission({\n name: 'kuadrant.planpolicy.list',\n attributes: { action: 'read' },\n});\n\n// apiproduct permissions (catalog entries)\nexport const kuadrantApiProductCreatePermission = createPermission({\n name: 'kuadrant.apiproduct.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantApiProductReadPermission = createPermission({\n name: 'kuadrant.apiproduct.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiProductUpdatePermission = createPermission({\n name: 'kuadrant.apiproduct.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiProductDeletePermission = createPermission({\n name: 'kuadrant.apiproduct.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiProductListPermission = createPermission({\n name: 'kuadrant.apiproduct.list',\n attributes: { action: 'read' },\n});\n\n// apikeyrequest permissions (access requests)\nexport const kuadrantApiKeyRequestCreatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.create',\n attributes: { action: 'create' },\n resourceType: 'apiproduct',\n});\n\nexport const kuadrantApiKeyRequestReadOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestReadAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestUpdatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestListPermission = createPermission({\n name: 'kuadrant.apikeyrequest.list',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestUpdateOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.update.own',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyRequestDeleteAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.delete.all',\n attributes: { action: 'delete' },\n});\n\n// api key permissions (managed secrets)\nexport const kuadrantApiKeyReadOwnPermission = createPermission({\n name: 'kuadrant.apikey.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyReadAllPermission = createPermission({\n name: 'kuadrant.apikey.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikey.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyDeleteAllPermission = createPermission({\n name: 'kuadrant.apikey.delete.all',\n attributes: { action: 'delete' },\n});\n\n/**\n * All Kuadrant permissions as an array for easy iteration\n */\nexport const kuadrantPermissions = [\n kuadrantPlanPolicyCreatePermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantPlanPolicyUpdatePermission,\n kuadrantPlanPolicyDeletePermission,\n kuadrantPlanPolicyListPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductReadPermission,\n kuadrantApiProductUpdatePermission,\n kuadrantApiProductDeletePermission,\n kuadrantApiProductListPermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestUpdatePermission,\n kuadrantApiKeyRequestUpdateOwnPermission,\n kuadrantApiKeyRequestListPermission,\n kuadrantApiKeyRequestDeleteOwnPermission,\n kuadrantApiKeyRequestDeleteAllPermission,\n kuadrantApiKeyReadOwnPermission,\n kuadrantApiKeyReadAllPermission,\n kuadrantApiKeyDeleteOwnPermission,\n kuadrantApiKeyDeleteAllPermission,\n];\n"],"names":["createPermission"],"mappings":"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"}
package/dist/rbac.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
+
3
+ /**
4
+ * backend module that registers kuadrant plugin id with rbac
5
+ * this makes kuadrant permissions discoverable in the rbac ui
6
+ *
7
+ * @public
8
+ */
9
+ declare const kuadrantRbacModule: _backstage_backend_plugin_api.BackendFeature;
10
+
11
+ export { kuadrantRbacModule as default, kuadrantRbacModule };
@@ -22,45 +22,19 @@ function generateApiKey() {
22
22
  return crypto.randomBytes(32).toString("hex");
23
23
  }
24
24
  async function getUserIdentity(req, httpAuth, userInfo) {
25
- try {
26
- const credentials = await httpAuth.credentials(req, { allow: ["user", "none"] });
27
- if (!credentials || !credentials.principal || credentials.principal.type === "none") {
28
- console.log("no user credentials, treating as guest api owner");
29
- return {
30
- userId: "guest",
31
- isPlatformEngineer: false,
32
- isApiOwner: true,
33
- // allow guest as api owner in development
34
- isApiConsumer: true,
35
- groups: []
36
- };
37
- }
38
- const info = await userInfo.getUserInfo(credentials);
39
- const userId = info.userEntityRef.split("/")[1] || "guest";
40
- const groups = info.ownershipEntityRefs || [];
41
- const isPlatformEngineer = userId === "guest" || groups.some(
42
- (ref) => ref === "group:default/platform-engineers" || ref === "group:default/platform-admins"
43
- );
44
- const isApiOwner = userId === "guest" || groups.some(
45
- (ref) => ref === "group:default/api-owners" || ref === "group:default/app-developers"
46
- );
47
- const isApiConsumer = groups.some(
48
- (ref) => ref === "group:default/api-consumers"
49
- );
50
- console.log(`user identity resolved: userId=${userId}, isPlatformEngineer=${isPlatformEngineer}, isApiOwner=${isApiOwner}, isApiConsumer=${isApiConsumer}, groups=${groups.join(",")}`);
51
- return { userId, isPlatformEngineer, isApiOwner, isApiConsumer, groups };
52
- } catch (error) {
53
- const errorMsg = error instanceof Error ? error.message : String(error);
54
- console.warn(`failed to get user identity, defaulting to guest api owner: ${errorMsg}`);
55
- return {
56
- userId: "guest",
57
- isPlatformEngineer: false,
58
- isApiOwner: true,
59
- // allow guest as api owner in development
60
- isApiConsumer: true,
61
- groups: []
62
- };
25
+ const credentials = await httpAuth.credentials(req);
26
+ if (!credentials || !credentials.principal) {
27
+ throw new errors.NotAllowedError("authentication required");
63
28
  }
29
+ const info = await userInfo.getUserInfo(credentials);
30
+ const userId = info.userEntityRef.split("/")[1];
31
+ const groups = info.ownershipEntityRefs || [];
32
+ console.log(`user identity resolved: userId=${userId}, userEntityRef=${info.userEntityRef}, groups=${groups.join(",")}`);
33
+ return {
34
+ userId,
35
+ userEntityRef: info.userEntityRef,
36
+ groups
37
+ };
64
38
  }
65
39
  async function createRouter({
66
40
  httpAuth,
@@ -130,19 +104,17 @@ async function createRouter({
130
104
  }
131
105
  const { userId } = await getUserIdentity(req, httpAuth, userInfo);
132
106
  const apiProduct = req.body;
133
- const namespace = apiProduct.metadata?.namespace;
134
107
  const targetRef = apiProduct.spec?.targetRef;
135
- if (!namespace) {
136
- throw new errors.InputError("namespace is required in metadata");
137
- }
138
- if (!targetRef?.name || !targetRef?.kind) {
139
- throw new errors.InputError("targetRef with name and kind is required");
108
+ if (!targetRef?.name || !targetRef?.kind || !targetRef?.namespace) {
109
+ throw new errors.InputError("targetRef with name, kind, and namespace is required");
140
110
  }
111
+ const namespace = targetRef.namespace;
112
+ apiProduct.metadata.namespace = namespace;
141
113
  if (!apiProduct.spec.contact) {
142
114
  apiProduct.spec.contact = {};
143
115
  }
144
116
  apiProduct.spec.contact.team = `user:default/${userId}`;
145
- const httpRouteNamespace = targetRef.namespace || namespace;
117
+ const httpRouteNamespace = namespace;
146
118
  const httpRouteName = targetRef.name;
147
119
  try {
148
120
  const planPoliciesResponse = await k8sClient$1.listCustomResources(
@@ -246,8 +218,34 @@ async function createRouter({
246
218
  }
247
219
  });
248
220
  router.patch("/apiproducts/:namespace/:name", async (req, res) => {
221
+ const patchSchema = zod.z.object({
222
+ spec: zod.z.object({
223
+ displayName: zod.z.string().optional(),
224
+ description: zod.z.string().optional(),
225
+ version: zod.z.string().optional(),
226
+ publishStatus: zod.z.enum(["Draft", "Published"]).optional(),
227
+ approvalMode: zod.z.enum(["automatic", "manual"]).optional(),
228
+ tags: zod.z.array(zod.z.string()).optional(),
229
+ contact: zod.z.object({
230
+ email: zod.z.string().optional(),
231
+ team: zod.z.string().optional(),
232
+ slack: zod.z.string().optional()
233
+ }).partial().optional(),
234
+ documentation: zod.z.object({
235
+ docsURL: zod.z.string().optional(),
236
+ openAPISpec: zod.z.string().optional()
237
+ }).partial().optional()
238
+ }).partial()
239
+ });
240
+ const parsed = patchSchema.safeParse(req.body);
241
+ if (!parsed.success) {
242
+ return res.status(400).json({ error: "invalid patch: " + parsed.error.toString() });
243
+ }
249
244
  try {
250
- const credentials = await httpAuth.credentials(req, { allow: ["user", "none"] });
245
+ const credentials = await httpAuth.credentials(req);
246
+ if (!credentials || !credentials.principal) {
247
+ throw new errors.NotAllowedError("authentication required");
248
+ }
251
249
  const decision = await permissions$1.authorize(
252
250
  [{ permission: permissions.kuadrantApiProductUpdatePermission }],
253
251
  { credentials }
@@ -256,25 +254,24 @@ async function createRouter({
256
254
  throw new errors.NotAllowedError("unauthorised");
257
255
  }
258
256
  const { namespace, name } = req.params;
259
- const patch = req.body;
260
257
  const updated = await k8sClient$1.patchCustomResource(
261
258
  "extensions.kuadrant.io",
262
259
  "v1alpha1",
263
260
  namespace,
264
261
  "apiproducts",
265
262
  name,
266
- patch
263
+ parsed.data
267
264
  );
268
- res.json(updated);
265
+ return res.json(updated);
269
266
  } catch (error) {
270
267
  console.error("error updating apiproduct:", error);
271
268
  const errorMessage = error instanceof Error ? error.message : String(error);
272
269
  if (error instanceof errors.NotAllowedError) {
273
- res.status(403).json({ error: error.message });
270
+ return res.status(403).json({ error: error.message });
274
271
  } else if (error instanceof errors.InputError) {
275
- res.status(400).json({ error: error.message });
272
+ return res.status(400).json({ error: error.message });
276
273
  } else {
277
- res.status(500).json({ error: errorMessage });
274
+ return res.status(500).json({ error: errorMessage });
278
275
  }
279
276
  }
280
277
  });
@@ -294,7 +291,19 @@ async function createRouter({
294
291
  metadata: {
295
292
  name: policy.metadata.name,
296
293
  namespace: policy.metadata.namespace
297
- }
294
+ },
295
+ // only expose targetRef to allow UI to match PlanPolicy -> HTTPRoute
296
+ targetRef: policy.spec?.targetRef ? {
297
+ kind: policy.spec.targetRef.kind,
298
+ name: policy.spec.targetRef.name,
299
+ namespace: policy.spec.targetRef.namespace
300
+ } : void 0,
301
+ // only expose plan tier info, no other spec details
302
+ plans: (policy.spec?.plans || []).map((plan) => ({
303
+ tier: plan.tier,
304
+ description: plan.description,
305
+ limits: plan.limits
306
+ }))
298
307
  }))
299
308
  };
300
309
  res.json(filtered);
@@ -329,85 +338,12 @@ async function createRouter({
329
338
  }
330
339
  }
331
340
  });
332
- router.get("/apikeys", async (req, res) => {
333
- try {
334
- const credentials = await httpAuth.credentials(req);
335
- const userId = req.query.userId;
336
- const namespace = req.query.namespace;
337
- if (!namespace) {
338
- throw new errors.InputError("namespace query parameter is required");
339
- }
340
- const permission = userId ? permissions.kuadrantApiKeyReadOwnPermission : permissions.kuadrantApiKeyReadAllPermission;
341
- const decision = await permissions$1.authorize(
342
- [{ permission }],
343
- { credentials }
344
- );
345
- if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
346
- throw new errors.NotAllowedError("unauthorised");
347
- }
348
- const data = await k8sClient$1.listSecrets(namespace);
349
- let filteredItems = data.items || [];
350
- if (userId) {
351
- filteredItems = filteredItems.filter(
352
- (secret) => secret.metadata?.annotations?.["secret.kuadrant.io/user-id"] === userId
353
- );
354
- }
355
- filteredItems = filteredItems.filter(
356
- (secret) => secret.metadata?.annotations?.["secret.kuadrant.io/user-id"]
357
- );
358
- res.json({ items: filteredItems });
359
- } catch (error) {
360
- console.error("error fetching api keys:", error);
361
- if (error instanceof errors.NotAllowedError) {
362
- res.status(403).json({ error: error.message });
363
- } else {
364
- res.status(500).json({ error: "failed to fetch api keys" });
365
- }
366
- }
367
- });
368
- router.delete("/apikeys/:namespace/:name", async (req, res) => {
369
- try {
370
- const credentials = await httpAuth.credentials(req);
371
- const { userId } = await getUserIdentity(req, httpAuth, userInfo);
372
- const { namespace, name } = req.params;
373
- const secret = await k8sClient$1.getSecret(namespace, name);
374
- const secretUserId = secret.metadata?.annotations?.["secret.kuadrant.io/user-id"];
375
- const deleteAllDecision = await permissions$1.authorize(
376
- [{ permission: permissions.kuadrantApiKeyDeleteAllPermission }],
377
- { credentials }
378
- );
379
- const canDeleteAll = deleteAllDecision[0].result === pluginPermissionCommon.AuthorizeResult.ALLOW;
380
- if (!canDeleteAll) {
381
- const deleteOwnDecision = await permissions$1.authorize(
382
- [{ permission: permissions.kuadrantApiKeyDeleteOwnPermission }],
383
- { credentials }
384
- );
385
- if (deleteOwnDecision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
386
- throw new errors.NotAllowedError("unauthorised");
387
- }
388
- if (secretUserId !== userId) {
389
- throw new errors.NotAllowedError("you can only delete your own api keys");
390
- }
391
- }
392
- await k8sClient$1.deleteSecret(namespace, name);
393
- res.status(204).send();
394
- } catch (error) {
395
- console.error("error deleting api key:", error);
396
- if (error instanceof errors.NotAllowedError) {
397
- res.status(403).json({ error: error.message });
398
- } else {
399
- res.status(500).json({ error: "failed to delete api key" });
400
- }
401
- }
402
- });
403
341
  const requestSchema = zod.z.object({
404
342
  apiName: zod.z.string(),
405
343
  apiNamespace: zod.z.string(),
406
344
  planTier: zod.z.string(),
407
345
  useCase: zod.z.string().optional(),
408
- userId: zod.z.string(),
409
- userEmail: zod.z.string().optional(),
410
- namespace: zod.z.string()
346
+ userEmail: zod.z.string().optional()
411
347
  });
412
348
  router.post("/requests", async (req, res) => {
413
349
  const parsed = requestSchema.safeParse(req.body);
@@ -416,7 +352,8 @@ async function createRouter({
416
352
  }
417
353
  try {
418
354
  const credentials = await httpAuth.credentials(req);
419
- const { apiName, apiNamespace, planTier, useCase, userId, userEmail, namespace } = parsed.data;
355
+ const { apiName, apiNamespace, planTier, useCase, userEmail } = parsed.data;
356
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
420
357
  const resourceRef = `apiproduct:${apiNamespace}/${apiName}`;
421
358
  const decision = await permissions$1.authorize(
422
359
  [{
@@ -428,11 +365,6 @@ async function createRouter({
428
365
  if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
429
366
  throw new errors.NotAllowedError(`not authorised to request access to ${apiName}`);
430
367
  }
431
- const { userId: authenticatedUserId, isPlatformEngineer, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);
432
- const canCreateForOthers = isPlatformEngineer || isApiOwner;
433
- if (!canCreateForOthers && userId !== authenticatedUserId) {
434
- throw new errors.NotAllowedError("you can only create api key requests for yourself");
435
- }
436
368
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
437
369
  const randomSuffix = crypto.randomBytes(4).toString("hex");
438
370
  const requestName = `${userId}-${apiName}-${randomSuffix}`.toLowerCase().replace(/[^a-z0-9-]/g, "-");
@@ -445,7 +377,7 @@ async function createRouter({
445
377
  kind: "APIKeyRequest",
446
378
  metadata: {
447
379
  name: requestName,
448
- namespace
380
+ namespace: apiNamespace
449
381
  },
450
382
  spec: {
451
383
  apiName,
@@ -459,7 +391,7 @@ async function createRouter({
459
391
  const created = await k8sClient$1.createCustomResource(
460
392
  "extensions.kuadrant.io",
461
393
  "v1alpha1",
462
- namespace,
394
+ apiNamespace,
463
395
  "apikeyrequests",
464
396
  request
465
397
  );
@@ -529,7 +461,7 @@ async function createRouter({
529
461
  await k8sClient$1.patchCustomResourceStatus(
530
462
  "extensions.kuadrant.io",
531
463
  "v1alpha1",
532
- namespace,
464
+ apiNamespace,
533
465
  "apikeyrequests",
534
466
  requestName,
535
467
  status
@@ -593,11 +525,8 @@ async function createRouter({
593
525
  if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
594
526
  throw new errors.NotAllowedError("unauthorised");
595
527
  }
596
- const userId = req.query.userId;
528
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
597
529
  const namespace = req.query.namespace;
598
- if (!userId) {
599
- throw new errors.InputError("userId query parameter is required");
600
- }
601
530
  let data;
602
531
  if (namespace) {
603
532
  data = await k8sClient$1.listCustomResources("extensions.kuadrant.io", "v1alpha1", "apikeyrequests", namespace);
@@ -626,24 +555,14 @@ async function createRouter({
626
555
  throw new errors.InputError(parsed.error.toString());
627
556
  }
628
557
  try {
629
- const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);
630
- let canApprove = isApiOwner;
631
- if (!canApprove) {
632
- try {
633
- const credentials = await httpAuth.credentials(req, { allow: ["none"] });
634
- if (credentials) {
635
- const decision = await permissions$1.authorize(
636
- [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
637
- { credentials }
638
- );
639
- canApprove = decision[0].result === pluginPermissionCommon.AuthorizeResult.ALLOW;
640
- }
641
- } catch (error) {
642
- console.warn("permission check failed, using group-based authorization:", error);
643
- }
644
- }
645
- if (!canApprove) {
646
- throw new errors.NotAllowedError("you do not have permission to approve api key requests");
558
+ const credentials = await httpAuth.credentials(req);
559
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
560
+ const decision = await permissions$1.authorize(
561
+ [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
562
+ { credentials }
563
+ );
564
+ if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
565
+ throw new errors.NotAllowedError("unauthorised");
647
566
  }
648
567
  const { namespace, name } = req.params;
649
568
  const { comment } = parsed.data;
@@ -761,24 +680,14 @@ async function createRouter({
761
680
  throw new errors.InputError(parsed.error.toString());
762
681
  }
763
682
  try {
764
- const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);
765
- let canReject = isApiOwner;
766
- if (!canReject) {
767
- try {
768
- const credentials = await httpAuth.credentials(req, { allow: ["none"] });
769
- if (credentials) {
770
- const decision = await permissions$1.authorize(
771
- [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
772
- { credentials }
773
- );
774
- canReject = decision[0].result === pluginPermissionCommon.AuthorizeResult.ALLOW;
775
- }
776
- } catch (error) {
777
- console.warn("permission check failed, using group-based authorization:", error);
778
- }
779
- }
780
- if (!canReject) {
781
- throw new errors.NotAllowedError("you do not have permission to reject api key requests");
683
+ const credentials = await httpAuth.credentials(req);
684
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
685
+ const decision = await permissions$1.authorize(
686
+ [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
687
+ { credentials }
688
+ );
689
+ if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
690
+ throw new errors.NotAllowedError("unauthorised");
782
691
  }
783
692
  const { namespace, name } = req.params;
784
693
  const { comment } = parsed.data;
@@ -820,24 +729,14 @@ async function createRouter({
820
729
  throw new errors.InputError(parsed.error.toString());
821
730
  }
822
731
  try {
823
- const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);
824
- let canApprove = isApiOwner;
825
- if (!canApprove) {
826
- try {
827
- const credentials = await httpAuth.credentials(req, { allow: ["none"] });
828
- if (credentials) {
829
- const decision = await permissions$1.authorize(
830
- [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
831
- { credentials }
832
- );
833
- canApprove = decision[0].result === pluginPermissionCommon.AuthorizeResult.ALLOW;
834
- }
835
- } catch (error) {
836
- console.warn("permission check failed, using group-based authorization:", error);
837
- }
838
- }
839
- if (!canApprove) {
840
- throw new errors.NotAllowedError("you do not have permission to approve api key requests");
732
+ const credentials = await httpAuth.credentials(req);
733
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
734
+ const decision = await permissions$1.authorize(
735
+ [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
736
+ { credentials }
737
+ );
738
+ if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
739
+ throw new errors.NotAllowedError("unauthorised");
841
740
  }
842
741
  const { requests, comment } = parsed.data;
843
742
  const reviewedBy = `user:default/${userId}`;
@@ -968,24 +867,14 @@ async function createRouter({
968
867
  throw new errors.InputError(parsed.error.toString());
969
868
  }
970
869
  try {
971
- const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);
972
- let canReject = isApiOwner;
973
- if (!canReject) {
974
- try {
975
- const credentials = await httpAuth.credentials(req, { allow: ["none"] });
976
- if (credentials) {
977
- const decision = await permissions$1.authorize(
978
- [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
979
- { credentials }
980
- );
981
- canReject = decision[0].result === pluginPermissionCommon.AuthorizeResult.ALLOW;
982
- }
983
- } catch (error) {
984
- console.warn("permission check failed, using group-based authorization:", error);
985
- }
986
- }
987
- if (!canReject) {
988
- throw new errors.NotAllowedError("you do not have permission to reject api key requests");
870
+ const credentials = await httpAuth.credentials(req);
871
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
872
+ const decision = await permissions$1.authorize(
873
+ [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
874
+ { credentials }
875
+ );
876
+ if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
877
+ throw new errors.NotAllowedError("unauthorised");
989
878
  }
990
879
  const { requests, comment } = parsed.data;
991
880
  const reviewedBy = `user:default/${userId}`;
@@ -1029,7 +918,8 @@ async function createRouter({
1029
918
  });
1030
919
  router.delete("/requests/:namespace/:name", async (req, res) => {
1031
920
  try {
1032
- const { userId, isPlatformEngineer, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);
921
+ const credentials = await httpAuth.credentials(req);
922
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
1033
923
  const { namespace, name } = req.params;
1034
924
  const request = await k8sClient$1.getCustomResource(
1035
925
  "extensions.kuadrant.io",
@@ -1039,9 +929,22 @@ async function createRouter({
1039
929
  name
1040
930
  );
1041
931
  const requestUserId = request.spec?.requestedBy?.userId;
1042
- const canDeleteAll = isPlatformEngineer || isApiOwner;
1043
- if (!canDeleteAll && requestUserId !== userId) {
1044
- throw new errors.NotAllowedError("you can only delete your own api key requests");
932
+ const deleteAllDecision = await permissions$1.authorize(
933
+ [{ permission: permissions.kuadrantApiKeyRequestDeleteAllPermission }],
934
+ { credentials }
935
+ );
936
+ const canDeleteAll = deleteAllDecision[0].result === pluginPermissionCommon.AuthorizeResult.ALLOW;
937
+ if (!canDeleteAll) {
938
+ const deleteOwnDecision = await permissions$1.authorize(
939
+ [{ permission: permissions.kuadrantApiKeyRequestDeleteOwnPermission }],
940
+ { credentials }
941
+ );
942
+ if (deleteOwnDecision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
943
+ throw new errors.NotAllowedError("unauthorised");
944
+ }
945
+ if (requestUserId !== userId) {
946
+ throw new errors.NotAllowedError("you can only delete your own api key requests");
947
+ }
1045
948
  }
1046
949
  if (request.status?.phase === "Approved") {
1047
950
  try {
@@ -1078,30 +981,57 @@ async function createRouter({
1078
981
  }
1079
982
  });
1080
983
  router.patch("/requests/:namespace/:name", async (req, res) => {
984
+ const patchSchema = zod.z.object({
985
+ spec: zod.z.object({
986
+ useCase: zod.z.string().optional()
987
+ }).partial()
988
+ });
989
+ const parsed = patchSchema.safeParse(req.body);
990
+ if (!parsed.success) {
991
+ throw new errors.InputError("invalid patch: " + parsed.error.toString());
992
+ }
1081
993
  try {
1082
994
  const credentials = await httpAuth.credentials(req);
1083
- const decision = await permissions$1.authorize(
995
+ const { userId } = await getUserIdentity(req, httpAuth, userInfo);
996
+ const { namespace, name } = req.params;
997
+ const existing = await k8sClient$1.getCustomResource(
998
+ "extensions.kuadrant.io",
999
+ "v1alpha1",
1000
+ namespace,
1001
+ "apikeyrequests",
1002
+ name
1003
+ );
1004
+ const updateAllDecision = await permissions$1.authorize(
1084
1005
  [{ permission: permissions.kuadrantApiKeyRequestUpdatePermission }],
1085
1006
  { credentials }
1086
1007
  );
1087
- if (decision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
1088
- throw new errors.NotAllowedError("unauthorised");
1008
+ if (updateAllDecision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
1009
+ const updateOwnDecision = await permissions$1.authorize(
1010
+ [{ permission: permissions.kuadrantApiKeyRequestUpdateOwnPermission }],
1011
+ { credentials }
1012
+ );
1013
+ if (updateOwnDecision[0].result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
1014
+ throw new errors.NotAllowedError("unauthorised");
1015
+ }
1016
+ if (existing.spec?.requestedBy?.userId !== userId) {
1017
+ throw new errors.NotAllowedError("you can only update your own api key requests");
1018
+ }
1089
1019
  }
1090
- const { namespace, name } = req.params;
1091
- const patch = req.body;
1092
1020
  const updated = await k8sClient$1.patchCustomResource(
1093
1021
  "extensions.kuadrant.io",
1094
1022
  "v1alpha1",
1095
1023
  namespace,
1096
1024
  "apikeyrequests",
1097
1025
  name,
1098
- patch
1026
+ parsed.data
1099
1027
  );
1100
1028
  res.json(updated);
1101
1029
  } catch (error) {
1102
1030
  console.error("error updating api key request:", error);
1103
1031
  if (error instanceof errors.NotAllowedError) {
1104
1032
  res.status(403).json({ error: error.message });
1033
+ } else if (error instanceof errors.InputError) {
1034
+ res.status(400).json({ error: error.message });
1105
1035
  } else {
1106
1036
  res.status(500).json({ error: "failed to update api key request" });
1107
1037
  }
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../src/router.ts"],"sourcesContent":["import { HttpAuthService, RootConfigService, UserInfoService, PermissionsService } from '@backstage/backend-plugin-api';\nimport { InputError, NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { z } from 'zod';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport cors from 'cors';\nimport { randomBytes } from 'crypto';\nimport { KuadrantK8sClient } from './k8s-client';\nimport { getAPIProductEntityProvider } from './module';\nimport {\n kuadrantPermissions,\n kuadrantApiKeyDeleteAllPermission,\n kuadrantPlanPolicyListPermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantApiProductListPermission,\n kuadrantApiProductReadPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductDeletePermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestUpdatePermission,\n kuadrantApiKeyRequestListPermission,\n kuadrantApiKeyReadOwnPermission,\n kuadrantApiKeyReadAllPermission,\n kuadrantApiKeyDeleteOwnPermission, kuadrantApiProductUpdatePermission,\n} from './permissions';\n\nfunction generateApiKey(): string {\n return randomBytes(32).toString('hex');\n}\n\nasync function getUserIdentity(req: express.Request, httpAuth: HttpAuthService, userInfo: UserInfoService): Promise<{\n userId: string;\n isPlatformEngineer: boolean;\n isApiOwner: boolean;\n isApiConsumer: boolean;\n groups: string[];\n}> {\n try {\n // allow both user credentials and unauthenticated (guest) access\n const credentials = await httpAuth.credentials(req, { allow: ['user', 'none'] });\n\n if (!credentials || !credentials.principal || credentials.principal.type === 'none') {\n // no credentials or guest user - treat as api owner in development\n console.log('no user credentials, treating as guest api owner');\n return {\n userId: 'guest',\n isPlatformEngineer: false,\n isApiOwner: true, // allow guest as api owner in development\n isApiConsumer: true,\n groups: []\n };\n }\n\n // get user info from credentials\n const info = await userInfo.getUserInfo(credentials);\n\n // extract userId from entity ref (format: \"user:default/alice\" -> \"alice\")\n const userId = info.userEntityRef.split('/')[1] || 'guest';\n const groups = info.ownershipEntityRefs || [];\n\n // check user roles based on group membership\n const isPlatformEngineer = userId === 'guest' || groups.some((ref: string) =>\n ref === 'group:default/platform-engineers' ||\n ref === 'group:default/platform-admins'\n );\n\n const isApiOwner = userId === 'guest' || groups.some((ref: string) =>\n ref === 'group:default/api-owners' ||\n ref === 'group:default/app-developers'\n );\n\n const isApiConsumer = groups.some((ref: string) =>\n ref === 'group:default/api-consumers'\n );\n\n console.log(`user identity resolved: userId=${userId}, isPlatformEngineer=${isPlatformEngineer}, isApiOwner=${isApiOwner}, isApiConsumer=${isApiConsumer}, groups=${groups.join(',')}`);\n return { userId, isPlatformEngineer, isApiOwner, isApiConsumer, groups };\n } catch (error) {\n // if credentials fail to verify (e.g. JWT issues with guest auth), treat as guest api owner\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.warn(`failed to get user identity, defaulting to guest api owner: ${errorMsg}`);\n return {\n userId: 'guest',\n isPlatformEngineer: false,\n isApiOwner: true, // allow guest as api owner in development\n isApiConsumer: true,\n groups: []\n };\n }\n}\n\nexport async function createRouter({\n httpAuth,\n userInfo,\n config,\n permissions,\n}: {\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n config: RootConfigService;\n permissions: PermissionsService;\n}): Promise<express.Router> {\n const router = Router();\n\n // enable cors for dev mode (allows frontend on :3000 to call backend on :7007)\n router.use(cors({\n origin: 'http://localhost:3000',\n credentials: true,\n }));\n\n router.use(express.json());\n\n const k8sClient = new KuadrantK8sClient(config);\n\n // apiproduct endpoints\n router.get('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n res.json(data);\n } catch (error) {\n console.error('error fetching apiproducts:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproducts' });\n }\n }\n });\n\n router.get('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n res.json(data);\n } catch (error) {\n console.error('error fetching apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproduct' });\n }\n }\n });\n\n router.post('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductCreatePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n const apiProduct = req.body;\n const namespace = apiProduct.metadata?.namespace;\n const targetRef = apiProduct.spec?.targetRef;\n\n if (!namespace) {\n throw new InputError('namespace is required in metadata');\n }\n\n if (!targetRef?.name || !targetRef?.kind) {\n throw new InputError('targetRef with name and kind is required');\n }\n\n // set the owner to the authenticated user\n if (!apiProduct.spec.contact) {\n apiProduct.spec.contact = {};\n }\n apiProduct.spec.contact.team = `user:default/${userId}`;\n\n // temporary: populate plans from planpolicy until controller implements this\n // look up httproute and find planpolicy targeting it\n const httpRouteNamespace = targetRef.namespace || namespace;\n const httpRouteName = targetRef.name;\n\n try {\n // list all planpolicies in the httproute's namespace\n const planPoliciesResponse = await k8sClient.listCustomResources(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n 'planpolicies',\n httpRouteNamespace\n );\n\n // find planpolicy targeting this httproute\n const planPolicy = (planPoliciesResponse.items || []).find((pp: any) => {\n const ref = pp.spec?.targetRef;\n return ref?.kind === 'HTTPRoute' &&\n ref?.name === httpRouteName &&\n (!ref?.namespace || ref?.namespace === httpRouteNamespace);\n });\n\n if (planPolicy && planPolicy.spec?.plans) {\n // copy plans from planpolicy to apiproduct spec\n apiProduct.spec.plans = planPolicy.spec.plans.map((plan: any) => ({\n tier: plan.tier,\n description: plan.description,\n limits: plan.limits\n }));\n console.log(`copied ${apiProduct.spec.plans.length} plans from planpolicy ${planPolicy.metadata.name}`);\n } else {\n console.log(`no planpolicy found for httproute ${httpRouteNamespace}/${httpRouteName}`);\n }\n } catch (error) {\n console.warn('failed to populate plans from planpolicy:', error);\n // continue without plans rather than failing the creation\n }\n\n const created = await k8sClient.createCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n apiProduct,\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n // pass the detailed error message to the frontend\n res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n router.delete('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductDeletePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n\n await k8sClient.deleteCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(204).send();\n } catch (error) {\n console.error('error deleting apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete apiproduct' });\n }\n }\n });\n\n // httproute endpoints\n router.get('/httproutes', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('gateway.networking.k8s.io', 'v1', 'httproutes');\n\n res.json(data);\n } catch (error) {\n console.error('error fetching httproutes:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch httproutes' });\n }\n }\n });\n\n router.patch('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req, { allow: ['user', 'none'] });\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdatePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const patch = req.body;\n\n const updated = await k8sClient.patchCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name,\n patch,\n );\n\n res.json(updated);\n } catch (error) {\n console.error('error updating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n // planpolicy endpoints\n router.get('/planpolicies', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'planpolicies');\n\n // filter to only return name and namespace to avoid leaking plan details\n const filtered = {\n items: (data.items || []).map((policy: any) => ({\n metadata: {\n name: policy.metadata.name,\n namespace: policy.metadata.namespace,\n },\n })),\n };\n\n res.json(filtered);\n } catch (error) {\n console.error('error fetching planpolicies:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicies' });\n }\n }\n });\n\n router.get('/planpolicies/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyReadPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'planpolicies', name);\n res.json(data);\n } catch (error) {\n console.error('error fetching planpolicy:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicy' });\n }\n }\n });\n\n // api key secret management (for viewing existing keys)\n router.get('/apikeys', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const userId = req.query.userId as string;\n const namespace = req.query.namespace as string;\n\n if (!namespace) {\n throw new InputError('namespace query parameter is required');\n }\n\n // if userId is provided, check for .own permission, otherwise .all permission\n const permission = userId ? kuadrantApiKeyReadOwnPermission : kuadrantApiKeyReadAllPermission;\n const decision = await permissions.authorize(\n [{ permission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listSecrets(namespace);\n\n let filteredItems = data.items || [];\n if (userId) {\n filteredItems = filteredItems.filter((secret: any) =>\n secret.metadata?.annotations?.['secret.kuadrant.io/user-id'] === userId\n );\n }\n\n filteredItems = filteredItems.filter((secret: any) =>\n secret.metadata?.annotations?.['secret.kuadrant.io/user-id']\n );\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching api keys:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch api keys' });\n }\n }\n });\n\n router.delete('/apikeys/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n const secret = await k8sClient.getSecret(namespace, name);\n const secretUserId = secret.metadata?.annotations?.['secret.kuadrant.io/user-id'];\n\n // check if user can delete all keys or just their own\n const deleteAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyDeleteAllPermission }],\n { credentials }\n );\n\n const canDeleteAll = deleteAllDecision[0].result === AuthorizeResult.ALLOW;\n\n if (!canDeleteAll) {\n // check if user can delete their own keys\n const deleteOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyDeleteOwnPermission }],\n { credentials }\n );\n\n if (deleteOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n if (secretUserId !== userId) {\n throw new NotAllowedError('you can only delete your own api keys');\n }\n }\n\n await k8sClient.deleteSecret(namespace, name);\n res.status(204).send();\n } catch (error) {\n console.error('error deleting api key:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete api key' });\n }\n }\n });\n\n // apikeyrequest crud endpoints\n const requestSchema = z.object({\n apiName: z.string(),\n apiNamespace: z.string(),\n planTier: z.string(),\n useCase: z.string().optional(),\n userId: z.string(),\n userEmail: z.string().optional(),\n namespace: z.string(),\n });\n\n router.post('/requests', async (req, res) => {\n const parsed = requestSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { apiName, apiNamespace, planTier, useCase, userId, userEmail, namespace } = parsed.data;\n\n // check permission with resource reference (per-apiproduct access control)\n const resourceRef = `apiproduct:${apiNamespace}/${apiName}`;\n const decision = await permissions.authorize(\n [{\n permission: kuadrantApiKeyRequestCreatePermission,\n resourceRef,\n }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError(`not authorised to request access to ${apiName}`);\n }\n\n const { userId: authenticatedUserId, isPlatformEngineer, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);\n\n // validate userId matches authenticated user (platform engineers and api owners can create on behalf of others)\n const canCreateForOthers = isPlatformEngineer || isApiOwner;\n if (!canCreateForOthers && userId !== authenticatedUserId) {\n throw new NotAllowedError('you can only create api key requests for yourself');\n }\n const timestamp = new Date().toISOString();\n const randomSuffix = randomBytes(4).toString('hex');\n const requestName = `${userId}-${apiName}-${randomSuffix}`.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n\n const requestedBy: any = { userId };\n if (userEmail) {\n requestedBy.email = userEmail;\n }\n\n const request = {\n apiVersion: 'extensions.kuadrant.io/v1alpha1',\n kind: 'APIKeyRequest',\n metadata: {\n name: requestName,\n namespace,\n },\n spec: {\n apiName,\n apiNamespace,\n planTier,\n useCase: useCase || '',\n requestedBy,\n requestedAt: timestamp,\n },\n };\n\n const created = await k8sClient.createCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n request,\n );\n\n // check if apiproduct has automatic approval mode\n try {\n const apiProduct = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n apiNamespace,\n 'apiproducts',\n apiName,\n );\n\n if (apiProduct.spec?.approvalMode === 'automatic') {\n // automatically approve and create secret\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const secretName = `${userId}-${apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: apiNamespace,\n labels: {\n app: apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': planTier,\n 'secret.kuadrant.io/user-id': userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(apiNamespace, secret);\n\n // get plan limits\n let planLimits: any = null;\n const plan = apiProduct.spec?.plans?.find((p: any) => p.tier === planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n apiNamespace,\n 'httproutes',\n apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n // update request status to approved\n const status = {\n phase: 'Approved',\n reviewedBy: 'system',\n reviewedAt: new Date().toISOString(),\n reason: 'automatic approval',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n requestName,\n status,\n );\n }\n } catch (error) {\n console.warn('could not check approval mode or auto-approve:', error);\n // continue anyway - request was created successfully\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to create api key request' });\n }\n }\n });\n\n router.get('/requests', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const status = req.query.status as string;\n const namespace = req.query.namespace as string;\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests', namespace);\n } else {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests');\n }\n\n let filteredItems = data.items || [];\n if (status) {\n filteredItems = filteredItems.filter((req: any) => {\n const phase = req.status?.phase || 'Pending';\n return phase === status;\n });\n }\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch api key requests' });\n }\n }\n });\n\n router.get('/requests/my', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadOwnPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const userId = req.query.userId as string;\n const namespace = req.query.namespace as string;\n\n if (!userId) {\n throw new InputError('userId query parameter is required');\n }\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests', namespace);\n } else {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests');\n }\n\n const filteredItems = (data.items || []).filter(\n (req: any) => req.spec?.requestedBy?.userId === userId\n );\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching user api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch user api key requests' });\n }\n }\n });\n\n const approveRejectSchema = z.object({\n comment: z.string().optional(),\n });\n\n router.post('/requests/:namespace/:name/approve', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);\n let canApprove = isApiOwner; // api owners can approve requests\n\n // if permissions are enabled, also check via permission framework\n if (!canApprove) {\n try {\n const credentials = await httpAuth.credentials(req, { allow: ['none'] });\n if (credentials) {\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n canApprove = decision[0].result === AuthorizeResult.ALLOW;\n }\n } catch (error) {\n // permission check failed, rely on group-based check\n console.warn('permission check failed, using group-based authorization:', error);\n }\n }\n\n if (!canApprove) {\n throw new NotAllowedError('you do not have permission to approve api key requests');\n }\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const spec = request.spec as any;\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const secretName = `${spec.requestedBy.userId}-${spec.apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: spec.apiNamespace,\n labels: {\n app: spec.apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(spec.apiNamespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'planpolicies',\n `${spec.apiName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${spec.apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n spec.apiNamespace,\n 'httproutes',\n spec.apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${spec.apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n status,\n );\n\n res.json({ secretName });\n } catch (error) {\n console.error('error approving api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to approve api key request' });\n }\n }\n });\n\n router.post('/requests/:namespace/:name/reject', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);\n let canReject = isApiOwner; // api owners can reject requests\n\n // if permissions are enabled, also check via permission framework\n if (!canReject) {\n try {\n const credentials = await httpAuth.credentials(req, { allow: ['none'] });\n if (credentials) {\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n canReject = decision[0].result === AuthorizeResult.ALLOW;\n }\n } catch (error) {\n // permission check failed, rely on group-based check\n console.warn('permission check failed, using group-based authorization:', error);\n }\n }\n\n if (!canReject) {\n throw new NotAllowedError('you do not have permission to reject api key requests');\n }\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n status,\n );\n\n res.status(204).send();\n } catch (error) {\n console.error('error rejecting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to reject api key request' });\n }\n }\n });\n\n const bulkApproveSchema = z.object({\n requests: z.array(z.object({\n namespace: z.string(),\n name: z.string(),\n })),\n comment: z.string().optional(),\n });\n\n router.post('/requests/bulk-approve', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);\n let canApprove = isApiOwner;\n\n // if permissions are enabled, also check via permission framework\n if (!canApprove) {\n try {\n const credentials = await httpAuth.credentials(req, { allow: ['none'] });\n if (credentials) {\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n canApprove = decision[0].result === AuthorizeResult.ALLOW;\n }\n } catch (error) {\n console.warn('permission check failed, using group-based authorization:', error);\n }\n }\n\n if (!canApprove) {\n throw new NotAllowedError('you do not have permission to approve api key requests');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n );\n\n const spec = request.spec as any;\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const secretName = `${spec.requestedBy.userId}-${spec.apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: spec.apiNamespace,\n labels: {\n app: spec.apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(spec.apiNamespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'planpolicies',\n `${spec.apiName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${spec.apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n spec.apiNamespace,\n 'httproutes',\n spec.apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${spec.apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true, secretName });\n } catch (error) {\n console.error(`error approving request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk approve:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk approve api key requests' });\n }\n }\n });\n\n router.post('/requests/bulk-reject', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const { userId, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);\n let canReject = isApiOwner;\n\n // if permissions are enabled, also check via permission framework\n if (!canReject) {\n try {\n const credentials = await httpAuth.credentials(req, { allow: ['none'] });\n if (credentials) {\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n canReject = decision[0].result === AuthorizeResult.ALLOW;\n }\n } catch (error) {\n console.warn('permission check failed, using group-based authorization:', error);\n }\n }\n\n if (!canReject) {\n throw new NotAllowedError('you do not have permission to reject api key requests');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true });\n } catch (error) {\n console.error(`error rejecting request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk reject:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk reject api key requests' });\n }\n }\n });\n\n router.delete('/requests/:namespace/:name', async (req, res) => {\n try {\n const { userId, isPlatformEngineer, isApiOwner } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n // get request to verify ownership\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const requestUserId = request.spec?.requestedBy?.userId;\n\n // platform engineers and api owners can delete any request, consumers can only delete their own\n const canDeleteAll = isPlatformEngineer || isApiOwner;\n if (!canDeleteAll && requestUserId !== userId) {\n throw new NotAllowedError('you can only delete your own api key requests');\n }\n\n // if request is approved, find and delete associated secret\n if (request.status?.phase === 'Approved') {\n try {\n const apiNamespace = request.spec?.apiNamespace;\n const apiName = request.spec?.apiName;\n const planTier = request.spec?.planTier;\n\n // list secrets in the api namespace and find the one with matching annotations\n const secrets = await k8sClient.listSecrets(apiNamespace);\n const matchingSecret = secrets.items?.find((s: any) => {\n const annotations = s.metadata?.annotations || {};\n return (\n annotations['secret.kuadrant.io/user-id'] === requestUserId &&\n annotations['secret.kuadrant.io/plan-id'] === planTier &&\n s.metadata?.labels?.app === apiName\n );\n });\n\n if (matchingSecret) {\n await k8sClient.deleteSecret(apiNamespace, matchingSecret.metadata.name);\n }\n } catch (error) {\n console.warn('failed to delete associated secret:', error);\n // continue with request deletion even if secret deletion fails\n }\n }\n\n await k8sClient.deleteCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n res.status(204).send();\n } catch (error) {\n console.error('error deleting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete api key request' });\n }\n }\n });\n\n router.patch('/requests/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const patch = req.body;\n\n const updated = await k8sClient.patchCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n patch,\n );\n\n res.json(updated);\n } catch (error) {\n console.error('error updating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to update api key request' });\n }\n }\n });\n\n // expose permissions for backstage permission framework\n router.use(createPermissionIntegrationRouter({\n permissions: kuadrantPermissions,\n }));\n\n return router;\n}\n"],"names":["randomBytes","permissions","Router","cors","express","k8sClient","KuadrantK8sClient","kuadrantApiProductListPermission","AuthorizeResult","NotAllowedError","kuadrantApiProductReadPermission","kuadrantApiProductCreatePermission","InputError","getAPIProductEntityProvider","kuadrantApiProductDeletePermission","kuadrantApiProductUpdatePermission","kuadrantPlanPolicyListPermission","kuadrantPlanPolicyReadPermission","kuadrantApiKeyReadOwnPermission","kuadrantApiKeyReadAllPermission","kuadrantApiKeyDeleteAllPermission","kuadrantApiKeyDeleteOwnPermission","z","kuadrantApiKeyRequestCreatePermission","timestamp","kuadrantApiKeyRequestListPermission","req","kuadrantApiKeyRequestReadOwnPermission","kuadrantApiKeyRequestUpdatePermission","createPermissionIntegrationRouter","kuadrantPermissions"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../src/router.ts"],"sourcesContent":["import { HttpAuthService, RootConfigService, UserInfoService, PermissionsService } from '@backstage/backend-plugin-api';\nimport { InputError, NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { z } from 'zod';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport cors from 'cors';\nimport { randomBytes } from 'crypto';\nimport { KuadrantK8sClient } from './k8s-client';\nimport { getAPIProductEntityProvider } from './module';\nimport {\n kuadrantPermissions,\n kuadrantPlanPolicyListPermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantApiProductListPermission,\n kuadrantApiProductReadPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductDeletePermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestUpdatePermission,\n kuadrantApiKeyRequestUpdateOwnPermission,\n kuadrantApiKeyRequestListPermission,\n kuadrantApiKeyRequestDeleteOwnPermission,\n kuadrantApiKeyRequestDeleteAllPermission,\n kuadrantApiProductUpdatePermission,\n} from './permissions';\n\nfunction generateApiKey(): string {\n return randomBytes(32).toString('hex');\n}\n\nasync function getUserIdentity(req: express.Request, httpAuth: HttpAuthService, userInfo: UserInfoService): Promise<{\n userId: string;\n userEntityRef: string;\n groups: string[];\n}> {\n const credentials = await httpAuth.credentials(req);\n\n if (!credentials || !credentials.principal) {\n throw new NotAllowedError('authentication required');\n }\n\n // get user info from credentials\n const info = await userInfo.getUserInfo(credentials);\n\n // extract userId from entity ref (format: \"user:default/alice\" -> \"alice\")\n const userId = info.userEntityRef.split('/')[1];\n const groups = info.ownershipEntityRefs || [];\n\n console.log(`user identity resolved: userId=${userId}, userEntityRef=${info.userEntityRef}, groups=${groups.join(',')}`);\n return {\n userId,\n userEntityRef: info.userEntityRef,\n groups\n };\n}\n\nexport async function createRouter({\n httpAuth,\n userInfo,\n config,\n permissions,\n}: {\n httpAuth: HttpAuthService;\n userInfo: UserInfoService;\n config: RootConfigService;\n permissions: PermissionsService;\n}): Promise<express.Router> {\n const router = Router();\n\n // enable cors for dev mode (allows frontend on :3000 to call backend on :7007)\n router.use(cors({\n origin: 'http://localhost:3000',\n credentials: true,\n }));\n\n router.use(express.json());\n\n const k8sClient = new KuadrantK8sClient(config);\n\n // apiproduct endpoints\n router.get('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n res.json(data);\n } catch (error) {\n console.error('error fetching apiproducts:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproducts' });\n }\n }\n });\n\n router.get('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductReadPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'apiproducts', name);\n res.json(data);\n } catch (error) {\n console.error('error fetching apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch apiproduct' });\n }\n }\n });\n\n router.post('/apiproducts', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductCreatePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n const apiProduct = req.body;\n const targetRef = apiProduct.spec?.targetRef;\n\n if (!targetRef?.name || !targetRef?.kind || !targetRef?.namespace) {\n throw new InputError('targetRef with name, kind, and namespace is required');\n }\n\n // derive namespace from httproute - apiproduct lives in same namespace as httproute\n const namespace = targetRef.namespace;\n apiProduct.metadata.namespace = namespace;\n\n // set the owner to the authenticated user\n if (!apiProduct.spec.contact) {\n apiProduct.spec.contact = {};\n }\n apiProduct.spec.contact.team = `user:default/${userId}`;\n\n // temporary: populate plans from planpolicy until controller implements this\n // look up httproute and find planpolicy targeting it\n const httpRouteNamespace = namespace;\n const httpRouteName = targetRef.name;\n\n try {\n // list all planpolicies in the httproute's namespace\n const planPoliciesResponse = await k8sClient.listCustomResources(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n 'planpolicies',\n httpRouteNamespace\n );\n\n // find planpolicy targeting this httproute\n const planPolicy = (planPoliciesResponse.items || []).find((pp: any) => {\n const ref = pp.spec?.targetRef;\n return ref?.kind === 'HTTPRoute' &&\n ref?.name === httpRouteName &&\n (!ref?.namespace || ref?.namespace === httpRouteNamespace);\n });\n\n if (planPolicy && planPolicy.spec?.plans) {\n // copy plans from planpolicy to apiproduct spec\n apiProduct.spec.plans = planPolicy.spec.plans.map((plan: any) => ({\n tier: plan.tier,\n description: plan.description,\n limits: plan.limits\n }));\n console.log(`copied ${apiProduct.spec.plans.length} plans from planpolicy ${planPolicy.metadata.name}`);\n } else {\n console.log(`no planpolicy found for httproute ${httpRouteNamespace}/${httpRouteName}`);\n }\n } catch (error) {\n console.warn('failed to populate plans from planpolicy:', error);\n // continue without plans rather than failing the creation\n }\n\n const created = await k8sClient.createCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n apiProduct,\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n // pass the detailed error message to the frontend\n res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n router.delete('/apiproducts/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductDeletePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n\n await k8sClient.deleteCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name\n );\n\n // trigger immediate catalog sync\n const provider = getAPIProductEntityProvider();\n if (provider) {\n await provider.refresh();\n }\n\n res.status(204).send();\n } catch (error) {\n console.error('error deleting apiproduct:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete apiproduct' });\n }\n }\n });\n\n // httproute endpoints\n router.get('/httproutes', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('gateway.networking.k8s.io', 'v1', 'httproutes');\n\n res.json(data);\n } catch (error) {\n console.error('error fetching httproutes:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch httproutes' });\n }\n }\n });\n\n router.patch('/apiproducts/:namespace/:name', async (req, res) => {\n // whitelist allowed fields for patching\n const patchSchema = z.object({\n spec: z.object({\n displayName: z.string().optional(),\n description: z.string().optional(),\n version: z.string().optional(),\n publishStatus: z.enum(['Draft', 'Published']).optional(),\n approvalMode: z.enum(['automatic', 'manual']).optional(),\n tags: z.array(z.string()).optional(),\n contact: z.object({\n email: z.string().optional(),\n team: z.string().optional(),\n slack: z.string().optional(),\n }).partial().optional(),\n documentation: z.object({\n docsURL: z.string().optional(),\n openAPISpec: z.string().optional(),\n }).partial().optional(),\n }).partial(),\n });\n\n const parsed = patchSchema.safeParse(req.body);\n if (!parsed.success) {\n return res.status(400).json({ error: 'invalid patch: ' + parsed.error.toString() });\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n if (!credentials || !credentials.principal) {\n throw new NotAllowedError('authentication required');\n }\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiProductUpdatePermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n\n const updated = await k8sClient.patchCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apiproducts',\n name,\n parsed.data,\n );\n\n return res.json(updated);\n } catch (error) {\n console.error('error updating apiproduct:', error);\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (error instanceof NotAllowedError) {\n return res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n return res.status(400).json({ error: error.message });\n } else {\n return res.status(500).json({ error: errorMessage });\n }\n }\n });\n\n // planpolicy endpoints\n router.get('/planpolicies', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'planpolicies');\n\n // only expose minimal info needed for UI association\n const filtered = {\n items: (data.items || []).map((policy: any) => ({\n metadata: {\n name: policy.metadata.name,\n namespace: policy.metadata.namespace,\n },\n // only expose targetRef to allow UI to match PlanPolicy -> HTTPRoute\n targetRef: policy.spec?.targetRef ? {\n kind: policy.spec.targetRef.kind,\n name: policy.spec.targetRef.name,\n namespace: policy.spec.targetRef.namespace,\n } : undefined,\n // only expose plan tier info, no other spec details\n plans: (policy.spec?.plans || []).map((plan: any) => ({\n tier: plan.tier,\n description: plan.description,\n limits: plan.limits,\n })),\n })),\n };\n\n res.json(filtered);\n } catch (error) {\n console.error('error fetching planpolicies:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicies' });\n }\n }\n });\n\n router.get('/planpolicies/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantPlanPolicyReadPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const data = await k8sClient.getCustomResource('extensions.kuadrant.io', 'v1alpha1', namespace, 'planpolicies', name);\n res.json(data);\n } catch (error) {\n console.error('error fetching planpolicy:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch planpolicy' });\n }\n }\n });\n\n // apikeyrequest crud endpoints\n const requestSchema = z.object({\n apiName: z.string(),\n apiNamespace: z.string(),\n planTier: z.string(),\n useCase: z.string().optional(),\n userEmail: z.string().optional(),\n });\n\n router.post('/requests', async (req, res) => {\n const parsed = requestSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { apiName, apiNamespace, planTier, useCase, userEmail } = parsed.data;\n\n // extract userId from authenticated credentials, not from request body\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n\n // check permission with resource reference (per-apiproduct access control)\n const resourceRef = `apiproduct:${apiNamespace}/${apiName}`;\n const decision = await permissions.authorize(\n [{\n permission: kuadrantApiKeyRequestCreatePermission,\n resourceRef,\n }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError(`not authorised to request access to ${apiName}`);\n }\n const timestamp = new Date().toISOString();\n const randomSuffix = randomBytes(4).toString('hex');\n const requestName = `${userId}-${apiName}-${randomSuffix}`.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n\n const requestedBy: any = { userId };\n if (userEmail) {\n requestedBy.email = userEmail;\n }\n\n const request = {\n apiVersion: 'extensions.kuadrant.io/v1alpha1',\n kind: 'APIKeyRequest',\n metadata: {\n name: requestName,\n namespace: apiNamespace,\n },\n spec: {\n apiName,\n apiNamespace,\n planTier,\n useCase: useCase || '',\n requestedBy,\n requestedAt: timestamp,\n },\n };\n\n const created = await k8sClient.createCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n apiNamespace,\n 'apikeyrequests',\n request,\n );\n\n // check if apiproduct has automatic approval mode\n try {\n const apiProduct = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n apiNamespace,\n 'apiproducts',\n apiName,\n );\n\n if (apiProduct.spec?.approvalMode === 'automatic') {\n // automatically approve and create secret\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const secretName = `${userId}-${apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: apiNamespace,\n labels: {\n app: apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': planTier,\n 'secret.kuadrant.io/user-id': userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(apiNamespace, secret);\n\n // get plan limits\n let planLimits: any = null;\n const plan = apiProduct.spec?.plans?.find((p: any) => p.tier === planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n apiNamespace,\n 'httproutes',\n apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n // update request status to approved\n const status = {\n phase: 'Approved',\n reviewedBy: 'system',\n reviewedAt: new Date().toISOString(),\n reason: 'automatic approval',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n apiNamespace,\n 'apikeyrequests',\n requestName,\n status,\n );\n }\n } catch (error) {\n console.warn('could not check approval mode or auto-approve:', error);\n // continue anyway - request was created successfully\n }\n\n res.status(201).json(created);\n } catch (error) {\n console.error('error creating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to create api key request' });\n }\n }\n });\n\n router.get('/requests', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestListPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const status = req.query.status as string;\n const namespace = req.query.namespace as string;\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests', namespace);\n } else {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests');\n }\n\n let filteredItems = data.items || [];\n if (status) {\n filteredItems = filteredItems.filter((req: any) => {\n const phase = req.status?.phase || 'Pending';\n return phase === status;\n });\n }\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch api key requests' });\n }\n }\n });\n\n router.get('/requests/my', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestReadOwnPermission }],\n { credentials }\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // extract userId from authenticated credentials, not from query params\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n const namespace = req.query.namespace as string;\n\n let data;\n if (namespace) {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests', namespace);\n } else {\n data = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apikeyrequests');\n }\n\n const filteredItems = (data.items || []).filter(\n (req: any) => req.spec?.requestedBy?.userId === userId\n );\n\n res.json({ items: filteredItems });\n } catch (error) {\n console.error('error fetching user api key requests:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to fetch user api key requests' });\n }\n }\n });\n\n const approveRejectSchema = z.object({\n comment: z.string().optional(),\n });\n\n router.post('/requests/:namespace/:name/approve', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const spec = request.spec as any;\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const secretName = `${spec.requestedBy.userId}-${spec.apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: spec.apiNamespace,\n labels: {\n app: spec.apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(spec.apiNamespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'planpolicies',\n `${spec.apiName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${spec.apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n spec.apiNamespace,\n 'httproutes',\n spec.apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${spec.apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n status,\n );\n\n res.json({ secretName });\n } catch (error) {\n console.error('error approving api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to approve api key request' });\n }\n }\n });\n\n router.post('/requests/:namespace/:name/reject', async (req, res) => {\n const parsed = approveRejectSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { namespace, name } = req.params;\n const { comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n status,\n );\n\n res.status(204).send();\n } catch (error) {\n console.error('error rejecting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to reject api key request' });\n }\n }\n });\n\n const bulkApproveSchema = z.object({\n requests: z.array(z.object({\n namespace: z.string(),\n name: z.string(),\n })),\n comment: z.string().optional(),\n });\n\n router.post('/requests/bulk-approve', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n );\n\n const spec = request.spec as any;\n const apiKey = generateApiKey();\n const timestamp = Date.now();\n const secretName = `${spec.requestedBy.userId}-${spec.apiName}-${timestamp}`\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-');\n\n const secret = {\n apiVersion: 'v1',\n kind: 'Secret',\n metadata: {\n name: secretName,\n namespace: spec.apiNamespace,\n labels: {\n app: spec.apiName,\n },\n annotations: {\n 'secret.kuadrant.io/plan-id': spec.planTier,\n 'secret.kuadrant.io/user-id': spec.requestedBy.userId,\n },\n },\n stringData: {\n api_key: apiKey,\n },\n type: 'Opaque',\n };\n\n await k8sClient.createSecret(spec.apiNamespace, secret);\n\n // try to get plan limits from apiproduct or planpolicy\n let planLimits: any = null;\n try {\n const products = await k8sClient.listCustomResources('extensions.kuadrant.io', 'v1alpha1', 'apiproducts');\n const product = (products.items || []).find((p: any) =>\n p.metadata.name.includes(spec.apiName) || p.spec?.displayName?.toLowerCase().includes(spec.apiName.toLowerCase())\n );\n if (product) {\n const plan = product.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n }\n } catch (e) {\n console.warn('could not fetch apiproduct for plan limits:', e);\n }\n\n if (!planLimits) {\n try {\n const policy = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n spec.apiNamespace,\n 'planpolicies',\n `${spec.apiName}-plan`,\n );\n const plan = policy.spec?.plans?.find((p: any) => p.tier === spec.planTier);\n if (plan) {\n planLimits = plan.limits;\n }\n } catch (e) {\n console.warn('could not fetch planpolicy for plan limits:', e);\n }\n }\n\n // fetch httproute to get hostname\n let apiHostname = `${spec.apiName}.apps.example.com`;\n try {\n const httproute = await k8sClient.getCustomResource(\n 'gateway.networking.k8s.io',\n 'v1',\n spec.apiNamespace,\n 'httproutes',\n spec.apiName,\n );\n if (httproute.spec?.hostnames && httproute.spec.hostnames.length > 0) {\n apiHostname = httproute.spec.hostnames[0];\n }\n } catch (error) {\n console.warn('could not fetch httproute for hostname, using default:', error);\n }\n\n const status = {\n phase: 'Approved',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'approved',\n apiKey,\n apiHostname,\n apiBasePath: '/api/v1',\n apiDescription: `${spec.apiName} api`,\n planLimits,\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true, secretName });\n } catch (error) {\n console.error(`error approving request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk approve:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk approve api key requests' });\n }\n }\n });\n\n router.post('/requests/bulk-reject', async (req, res) => {\n const parsed = bulkApproveSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError(parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n\n const decision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials },\n );\n\n if (decision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n const { requests, comment } = parsed.data;\n const reviewedBy = `user:default/${userId}`;\n const results = [];\n\n for (const reqRef of requests) {\n try {\n const status = {\n phase: 'Rejected',\n reviewedBy,\n reviewedAt: new Date().toISOString(),\n reason: comment || 'rejected',\n };\n\n await k8sClient.patchCustomResourceStatus(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n reqRef.namespace,\n 'apikeyrequests',\n reqRef.name,\n status,\n );\n\n results.push({ namespace: reqRef.namespace, name: reqRef.name, success: true });\n } catch (error) {\n console.error(`error rejecting request ${reqRef.namespace}/${reqRef.name}:`, error);\n results.push({\n namespace: reqRef.namespace,\n name: reqRef.name,\n success: false,\n error: error instanceof Error ? error.message : 'unknown error'\n });\n }\n }\n\n res.json({ results });\n } catch (error) {\n console.error('error in bulk reject:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to bulk reject api key requests' });\n }\n }\n });\n\n router.delete('/requests/:namespace/:name', async (req, res) => {\n try {\n const credentials = await httpAuth.credentials(req);\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n // get request to verify ownership\n const request = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n const requestUserId = request.spec?.requestedBy?.userId;\n\n // check if user can delete all requests or just their own\n const deleteAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestDeleteAllPermission }],\n { credentials }\n );\n\n const canDeleteAll = deleteAllDecision[0].result === AuthorizeResult.ALLOW;\n\n if (!canDeleteAll) {\n // check if user can delete their own requests\n const deleteOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestDeleteOwnPermission }],\n { credentials }\n );\n\n if (deleteOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n if (requestUserId !== userId) {\n throw new NotAllowedError('you can only delete your own api key requests');\n }\n }\n\n // if request is approved, find and delete associated secret\n if (request.status?.phase === 'Approved') {\n try {\n const apiNamespace = request.spec?.apiNamespace;\n const apiName = request.spec?.apiName;\n const planTier = request.spec?.planTier;\n\n // list secrets in the api namespace and find the one with matching annotations\n const secrets = await k8sClient.listSecrets(apiNamespace);\n const matchingSecret = secrets.items?.find((s: any) => {\n const annotations = s.metadata?.annotations || {};\n return (\n annotations['secret.kuadrant.io/user-id'] === requestUserId &&\n annotations['secret.kuadrant.io/plan-id'] === planTier &&\n s.metadata?.labels?.app === apiName\n );\n });\n\n if (matchingSecret) {\n await k8sClient.deleteSecret(apiNamespace, matchingSecret.metadata.name);\n }\n } catch (error) {\n console.warn('failed to delete associated secret:', error);\n // continue with request deletion even if secret deletion fails\n }\n }\n\n await k8sClient.deleteCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n res.status(204).send();\n } catch (error) {\n console.error('error deleting api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to delete api key request' });\n }\n }\n });\n\n router.patch('/requests/:namespace/:name', async (req, res) => {\n // whitelist allowed fields for patching\n const patchSchema = z.object({\n spec: z.object({\n useCase: z.string().optional(),\n }).partial(),\n });\n\n const parsed = patchSchema.safeParse(req.body);\n if (!parsed.success) {\n throw new InputError('invalid patch: ' + parsed.error.toString());\n }\n\n try {\n const credentials = await httpAuth.credentials(req);\n const { userId } = await getUserIdentity(req, httpAuth, userInfo);\n const { namespace, name } = req.params;\n\n // get existing request to check ownership\n const existing = await k8sClient.getCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n );\n\n // check if user can update all requests or just their own\n const updateAllDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdatePermission }],\n { credentials }\n );\n\n if (updateAllDecision[0].result !== AuthorizeResult.ALLOW) {\n // check if user can update their own requests\n const updateOwnDecision = await permissions.authorize(\n [{ permission: kuadrantApiKeyRequestUpdateOwnPermission }],\n { credentials }\n );\n\n if (updateOwnDecision[0].result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('unauthorised');\n }\n\n // verify ownership\n if (existing.spec?.requestedBy?.userId !== userId) {\n throw new NotAllowedError('you can only update your own api key requests');\n }\n }\n\n // apply validated patch\n const updated = await k8sClient.patchCustomResource(\n 'extensions.kuadrant.io',\n 'v1alpha1',\n namespace,\n 'apikeyrequests',\n name,\n parsed.data,\n );\n\n res.json(updated);\n } catch (error) {\n console.error('error updating api key request:', error);\n if (error instanceof NotAllowedError) {\n res.status(403).json({ error: error.message });\n } else if (error instanceof InputError) {\n res.status(400).json({ error: error.message });\n } else {\n res.status(500).json({ error: 'failed to update api key request' });\n }\n }\n });\n\n // expose permissions for backstage permission framework\n router.use(createPermissionIntegrationRouter({\n permissions: kuadrantPermissions,\n }));\n\n return router;\n}\n"],"names":["randomBytes","NotAllowedError","permissions","Router","cors","express","k8sClient","KuadrantK8sClient","kuadrantApiProductListPermission","AuthorizeResult","kuadrantApiProductReadPermission","kuadrantApiProductCreatePermission","InputError","getAPIProductEntityProvider","kuadrantApiProductDeletePermission","z","kuadrantApiProductUpdatePermission","kuadrantPlanPolicyListPermission","kuadrantPlanPolicyReadPermission","kuadrantApiKeyRequestCreatePermission","timestamp","kuadrantApiKeyRequestListPermission","req","kuadrantApiKeyRequestReadOwnPermission","kuadrantApiKeyRequestUpdatePermission","kuadrantApiKeyRequestDeleteAllPermission","kuadrantApiKeyRequestDeleteOwnPermission","kuadrantApiKeyRequestUpdateOwnPermission","createPermissionIntegrationRouter","kuadrantPermissions"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuadrant/kuadrant-backstage-plugin-backend",
3
- "version": "0.0.1-test.1-57ace816",
3
+ "version": "0.0.1-test.1-48246e3",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,19 +19,38 @@
19
19
  "pluginId": "kuadrant",
20
20
  "pluginPackages": [
21
21
  "@kuadrant/kuadrant-backstage-plugin-backend"
22
- ]
22
+ ],
23
+ "features": {
24
+ ".": "@backstage/BackendFeature",
25
+ "./alpha": "@backstage/BackendFeature",
26
+ "./rbac": "@backstage/BackendFeature"
27
+ }
28
+ },
29
+ "scalprum": {
30
+ "name": "internal.plugin-kuadrant-backend",
31
+ "exposedModules": {
32
+ "PluginRoot": "./src/index.ts",
33
+ "KuadrantAlpha": "./src/module.ts",
34
+ "KuadrantRBAC": "./src/rbac-module.ts"
35
+ }
23
36
  },
24
37
  "exports": {
25
38
  ".": {
39
+ "backstage": "@backstage/BackendFeature",
26
40
  "require": "./dist/index.cjs.js",
41
+ "types": "./dist/index.d.ts",
27
42
  "default": "./dist/index.cjs.js"
28
43
  },
29
44
  "./alpha": {
45
+ "backstage": "@backstage/BackendFeature",
30
46
  "require": "./dist/alpha.cjs.js",
47
+ "types": "./dist/alpha.d.ts",
31
48
  "default": "./dist/alpha.cjs.js"
32
49
  },
33
50
  "./rbac": {
51
+ "backstage": "@backstage/BackendFeature",
34
52
  "require": "./dist/rbac.cjs.js",
53
+ "types": "./dist/rbac.d.ts",
35
54
  "default": "./dist/rbac.cjs.js"
36
55
  },
37
56
  "./package.json": "./package.json"
@@ -44,7 +63,9 @@
44
63
  "clean": "backstage-cli package clean",
45
64
  "prepack": "backstage-cli package prepack",
46
65
  "postpack": "backstage-cli package postpack",
47
- "tsc": "tsc"
66
+ "tsc": "tsc",
67
+ "export-dynamic": "janus-cli package export-dynamic-plugin --in-place",
68
+ "export-dynamic:clean": "run export-dynamic --clean"
48
69
  },
49
70
  "dependencies": {
50
71
  "@backstage/backend-defaults": "^0.12.1",
@@ -65,6 +86,7 @@
65
86
  "devDependencies": {
66
87
  "@backstage/backend-test-utils": "^1.9.0",
67
88
  "@backstage/cli": "^0.34.2",
89
+ "@janus-idp/cli": "^1.13.0",
68
90
  "@types/express": "^4.17.6",
69
91
  "@types/supertest": "^2.0.12",
70
92
  "supertest": "^6.2.4",
@@ -73,6 +95,20 @@
73
95
  "files": [
74
96
  "dist",
75
97
  "alpha",
76
- "rbac"
77
- ]
98
+ "rbac",
99
+ "dist-dynamic"
100
+ ],
101
+ "typesVersions": {
102
+ "*": {
103
+ "alpha": [
104
+ "dist/alpha.d.ts"
105
+ ],
106
+ "rbac": [
107
+ "dist/rbac.d.ts"
108
+ ],
109
+ "package.json": [
110
+ "package.json"
111
+ ]
112
+ }
113
+ }
78
114
  }