@kuadrant/kuadrant-backstage-plugin-frontend 0.0.1-test.1-2bfd8489 → 0.0.1-test.1-57ace816

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.
@@ -1,30 +1,21 @@
1
1
  import React from 'react';
2
2
  import { Box, Typography } from '@material-ui/core';
3
3
  import { Progress } from '@backstage/core-components';
4
- import { useUserRole } from '../../hooks/useUserRole.esm.js';
4
+ import { useKuadrantPermission } from '../../utils/permissions.esm.js';
5
5
 
6
- const PermissionGate = ({ children, requireRole, requireAnyRole, fallback }) => {
7
- const { userInfo, loading } = useUserRole();
6
+ const PermissionGate = ({ children, permission, fallback, errorMessage }) => {
7
+ const { allowed, loading, error } = useKuadrantPermission(permission);
8
8
  if (loading) {
9
9
  return /* @__PURE__ */ React.createElement(Progress, null);
10
10
  }
11
- if (!userInfo) {
12
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
11
+ if (error) {
12
+ return /* @__PURE__ */ React.createElement(Box, { p: 4 }, /* @__PURE__ */ React.createElement(Typography, { color: "error" }, "Unable to check permissions: ", error.message), /* @__PURE__ */ React.createElement(Typography, { variant: "body2", color: "textSecondary" }, "Please try again or contact your administrator"));
13
13
  }
14
- const hasPermission = () => {
15
- if (requireRole) {
16
- return userInfo.role === requireRole;
17
- }
18
- if (requireAnyRole) {
19
- return requireAnyRole.includes(userInfo.role);
20
- }
21
- return true;
22
- };
23
- if (!hasPermission()) {
14
+ if (!allowed) {
24
15
  if (fallback) {
25
16
  return /* @__PURE__ */ React.createElement(React.Fragment, null, fallback);
26
17
  }
27
- return /* @__PURE__ */ React.createElement(Box, { p: 4 }, /* @__PURE__ */ React.createElement(Typography, { color: "textSecondary" }, "you don't have permission to view this page"), /* @__PURE__ */ React.createElement(Box, { mt: 1 }, /* @__PURE__ */ React.createElement(Typography, { variant: "caption", color: "textSecondary" }, "required role: ", requireRole || requireAnyRole?.join(" or "))), /* @__PURE__ */ React.createElement(Typography, { variant: "caption", color: "textSecondary" }, "your role: ", userInfo.role));
18
+ return /* @__PURE__ */ React.createElement(Box, { p: 4 }, /* @__PURE__ */ React.createElement(Typography, { color: "textSecondary" }, errorMessage || "You don't have permission to view this page"), /* @__PURE__ */ React.createElement(Box, { mt: 1 }, /* @__PURE__ */ React.createElement(Typography, { variant: "caption", color: "textSecondary" }, "Required permission: ", permission.name)));
28
19
  }
29
20
  return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
30
21
  };
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionGate.esm.js","sources":["../../../src/components/PermissionGate/PermissionGate.tsx"],"sourcesContent":["import React from 'react';\nimport { Typography, Box } from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { useUserRole } from '../../hooks/useUserRole';\n\ninterface PermissionGateProps {\n children: React.ReactNode;\n requireRole?: 'platform-engineer' | 'api-owner' | 'api-consumer';\n requireAnyRole?: Array<'platform-engineer' | 'api-owner' | 'api-consumer'>;\n fallback?: React.ReactNode;\n}\n\nexport const PermissionGate = ({ children, requireRole, requireAnyRole, fallback }: PermissionGateProps) => {\n const { userInfo, loading } = useUserRole();\n\n if (loading) {\n return <Progress />;\n }\n\n if (!userInfo) {\n // in dev mode without auth backend, allow access\n return <>{children}</>;\n }\n\n const hasPermission = () => {\n if (requireRole) {\n return userInfo.role === requireRole;\n }\n if (requireAnyRole) {\n return requireAnyRole.includes(userInfo.role as any);\n }\n return true;\n };\n\n if (!hasPermission()) {\n if (fallback) {\n return <>{fallback}</>;\n }\n return (\n <Box p={4}>\n <Typography color=\"textSecondary\">\n you don't have permission to view this page\n </Typography>\n <Box mt={1}>\n <Typography variant=\"caption\" color=\"textSecondary\">\n required role: {requireRole || requireAnyRole?.join(' or ')}\n </Typography>\n </Box>\n <Typography variant=\"caption\" color=\"textSecondary\">\n your role: {userInfo.role}\n </Typography>\n </Box>\n );\n }\n\n return <>{children}</>;\n};\n"],"names":[],"mappings":";;;;;AAYO,MAAM,iBAAiB,CAAC,EAAE,UAAU,WAAa,EAAA,cAAA,EAAgB,UAAoC,KAAA;AAC1G,EAAA,MAAM,EAAE,QAAA,EAAU,OAAQ,EAAA,GAAI,WAAY,EAAA;AAE1C,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA;AAAA;AAGnB,EAAA,IAAI,CAAC,QAAU,EAAA;AAEb,IAAA,iEAAU,QAAS,CAAA;AAAA;AAGrB,EAAA,MAAM,gBAAgB,MAAM;AAC1B,IAAA,IAAI,WAAa,EAAA;AACf,MAAA,OAAO,SAAS,IAAS,KAAA,WAAA;AAAA;AAE3B,IAAA,IAAI,cAAgB,EAAA;AAClB,MAAO,OAAA,cAAA,CAAe,QAAS,CAAA,QAAA,CAAS,IAAW,CAAA;AAAA;AAErD,IAAO,OAAA,IAAA;AAAA,GACT;AAEA,EAAI,IAAA,CAAC,eAAiB,EAAA;AACpB,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,iEAAU,QAAS,CAAA;AAAA;AAErB,IAAA,2CACG,GAAI,EAAA,EAAA,CAAA,EAAG,CACN,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,KAAM,EAAA,eAAA,EAAA,EAAgB,6CAElC,CAAA,sCACC,GAAI,EAAA,EAAA,EAAA,EAAI,CACP,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,OAAQ,EAAA,SAAA,EAAU,KAAM,EAAA,eAAA,EAAA,EAAgB,mBAClC,WAAe,IAAA,cAAA,EAAgB,IAAK,CAAA,MAAM,CAC5D,CACF,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,SAAQ,SAAU,EAAA,KAAA,EAAM,mBAAgB,aACtC,EAAA,QAAA,CAAS,IACvB,CACF,CAAA;AAAA;AAIJ,EAAA,iEAAU,QAAS,CAAA;AACrB;;;;"}
1
+ {"version":3,"file":"PermissionGate.esm.js","sources":["../../../src/components/PermissionGate/PermissionGate.tsx"],"sourcesContent":["import React from 'react';\nimport { Typography, Box } from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { Permission } from '@backstage/plugin-permission-common';\nimport { useKuadrantPermission } from '../../utils/permissions';\n\ninterface PermissionGateProps {\n children: React.ReactNode;\n permission: Permission;\n fallback?: React.ReactNode;\n errorMessage?: string;\n}\n\nexport const PermissionGate = ({ children, permission, fallback, errorMessage }: PermissionGateProps) => {\n const { allowed, loading, error } = useKuadrantPermission(permission);\n\n if (loading) {\n return <Progress />;\n }\n\n if (error) {\n return (\n <Box p={4}>\n <Typography color=\"error\">\n Unable to check permissions: {error.message}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n Please try again or contact your administrator\n </Typography>\n </Box>\n );\n }\n\n if (!allowed) {\n if (fallback) {\n return <>{fallback}</>;\n }\n return (\n <Box p={4}>\n <Typography color=\"textSecondary\">\n {errorMessage || 'You don\\'t have permission to view this page'}\n </Typography>\n <Box mt={1}>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Required permission: {permission.name}\n </Typography>\n </Box>\n </Box>\n );\n }\n\n return <>{children}</>;\n};\n"],"names":[],"mappings":";;;;;AAaO,MAAM,iBAAiB,CAAC,EAAE,UAAU,UAAY,EAAA,QAAA,EAAU,cAAwC,KAAA;AACvG,EAAA,MAAM,EAAE,OAAS,EAAA,OAAA,EAAS,KAAM,EAAA,GAAI,sBAAsB,UAAU,CAAA;AAEpE,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA;AAAA;AAGnB,EAAA,IAAI,KAAO,EAAA;AACT,IAAA,2CACG,GAAI,EAAA,EAAA,CAAA,EAAG,qBACL,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAM,OAAQ,EAAA,EAAA,+BAAA,EACM,MAAM,OACtC,CAAA,sCACC,UAAW,EAAA,EAAA,OAAA,EAAQ,SAAQ,KAAM,EAAA,eAAA,EAAA,EAAgB,gDAElD,CACF,CAAA;AAAA;AAIJ,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAA,IAAI,QAAU,EAAA;AACZ,MAAA,iEAAU,QAAS,CAAA;AAAA;AAErB,IACE,uBAAA,KAAA,CAAA,aAAA,CAAC,GAAI,EAAA,EAAA,CAAA,EAAG,CACN,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,KAAM,EAAA,eAAA,EAAA,EACf,YAAgB,IAAA,6CACnB,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,OAAI,EAAI,EAAA,CAAA,EAAA,kBACN,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,SAAA,EAAU,KAAM,EAAA,eAAA,EAAA,EAAgB,uBAC5B,EAAA,UAAA,CAAW,IACnC,CACF,CACF,CAAA;AAAA;AAIJ,EAAA,iEAAU,QAAS,CAAA;AACrB;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import react__default from 'react';
3
3
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
4
+ import * as _backstage_plugin_permission_common from '@backstage/plugin-permission-common';
4
5
 
5
6
  interface ApiKeyManagementTabProps {
6
7
  namespace?: string;
@@ -28,4 +29,83 @@ declare const ApiProductInfoCard: () => react__default.JSX.Element;
28
29
 
29
30
  declare const ApprovalQueueCard: () => react__default.JSX.Element;
30
31
 
31
- export { ApiAccessCard, ApiKeyManagementTab, ApiProductInfoCard, ApprovalQueueCard, EntityKuadrantApiAccessCard, EntityKuadrantApiKeyManagementTab, EntityKuadrantApiKeysContent, EntityKuadrantApiProductInfoContent, KuadrantApprovalQueueCard, KuadrantPage, PlanPolicyDetailPage, kuadrantPlugin };
32
+ /**
33
+ * permission definitions for the kuadrant plugin
34
+ *
35
+ * these permissions control access to kuadrant resources and operations.
36
+ * they must match the permissions defined in the backend plugin.
37
+ *
38
+ * permission types:
39
+ * - BasicPermission: standard permission that applies globally
40
+ * - ResourcePermission: permission scoped to specific resource types (e.g., apiproduct)
41
+ *
42
+ * permission patterns:
43
+ * - `.create` - create new resources
44
+ * - `.read` - read resource details
45
+ * - `.read.own` - read only resources owned by the user
46
+ * - `.read.all` - read all resources regardless of ownership
47
+ * - `.update` - modify existing resources
48
+ * - `.delete` - delete resources
49
+ * - `.delete.own` - delete only resources owned by the user
50
+ * - `.delete.all` - delete any resource regardless of ownership
51
+ * - `.list` - list/view collections of resources
52
+ */
53
+ declare const kuadrantPlanPolicyCreatePermission: _backstage_plugin_permission_common.BasicPermission;
54
+ declare const kuadrantPlanPolicyReadPermission: _backstage_plugin_permission_common.BasicPermission;
55
+ declare const kuadrantPlanPolicyUpdatePermission: _backstage_plugin_permission_common.BasicPermission;
56
+ declare const kuadrantPlanPolicyDeletePermission: _backstage_plugin_permission_common.BasicPermission;
57
+ declare const kuadrantPlanPolicyListPermission: _backstage_plugin_permission_common.BasicPermission;
58
+ declare const kuadrantApiProductCreatePermission: _backstage_plugin_permission_common.BasicPermission;
59
+ declare const kuadrantApiProductReadPermission: _backstage_plugin_permission_common.BasicPermission;
60
+ declare const kuadrantApiProductUpdatePermission: _backstage_plugin_permission_common.BasicPermission;
61
+ declare const kuadrantApiProductDeletePermission: _backstage_plugin_permission_common.BasicPermission;
62
+ declare const kuadrantApiProductListPermission: _backstage_plugin_permission_common.BasicPermission;
63
+ /**
64
+ * permission to create API key requests
65
+ *
66
+ * this is a ResourcePermission scoped to 'apiproduct', allowing
67
+ * fine-grained control over which API products users can request access to.
68
+ *
69
+ * use in frontend: useKuadrantPermission(kuadrantApiKeyRequestCreatePermission)
70
+ * use in backend with resource: { permission, resourceRef: 'apiproduct:namespace/name' }
71
+ */
72
+ declare const kuadrantApiKeyRequestCreatePermission: _backstage_plugin_permission_common.ResourcePermission<"apiproduct">;
73
+ /**
74
+ * permission to read API key requests created by the current user
75
+ * use this for allowing users to see their own request history
76
+ */
77
+ declare const kuadrantApiKeyRequestReadOwnPermission: _backstage_plugin_permission_common.BasicPermission;
78
+ /**
79
+ * permission to read all API key requests regardless of who created them
80
+ * use this for platform engineers/admins who need to view the approval queue
81
+ */
82
+ declare const kuadrantApiKeyRequestReadAllPermission: _backstage_plugin_permission_common.BasicPermission;
83
+ /**
84
+ * permission to approve or reject API key requests
85
+ * typically granted to API owners and platform engineers
86
+ */
87
+ declare const kuadrantApiKeyRequestUpdatePermission: _backstage_plugin_permission_common.BasicPermission;
88
+ declare const kuadrantApiKeyRequestListPermission: _backstage_plugin_permission_common.BasicPermission;
89
+ /**
90
+ * permission to read API keys owned by the current user
91
+ * allows users to view their own active API keys
92
+ */
93
+ declare const kuadrantApiKeyReadOwnPermission: _backstage_plugin_permission_common.BasicPermission;
94
+ /**
95
+ * permission to read all API keys regardless of ownership
96
+ * for platform engineers/admins who need to audit keys
97
+ */
98
+ declare const kuadrantApiKeyReadAllPermission: _backstage_plugin_permission_common.BasicPermission;
99
+ /**
100
+ * permission to delete API keys owned by the current user
101
+ * allows users to revoke their own access
102
+ */
103
+ declare const kuadrantApiKeyDeleteOwnPermission: _backstage_plugin_permission_common.BasicPermission;
104
+ /**
105
+ * permission to delete any API key regardless of ownership
106
+ * for platform engineers/admins who need to revoke access
107
+ */
108
+ declare const kuadrantApiKeyDeleteAllPermission: _backstage_plugin_permission_common.BasicPermission;
109
+ declare const kuadrantPermissions: (_backstage_plugin_permission_common.BasicPermission | _backstage_plugin_permission_common.ResourcePermission<"apiproduct">)[];
110
+
111
+ export { ApiAccessCard, ApiKeyManagementTab, ApiProductInfoCard, ApprovalQueueCard, EntityKuadrantApiAccessCard, EntityKuadrantApiKeyManagementTab, EntityKuadrantApiKeysContent, EntityKuadrantApiProductInfoContent, KuadrantApprovalQueueCard, KuadrantPage, PlanPolicyDetailPage, kuadrantApiKeyDeleteAllPermission, kuadrantApiKeyDeleteOwnPermission, kuadrantApiKeyReadAllPermission, kuadrantApiKeyReadOwnPermission, kuadrantApiKeyRequestCreatePermission, kuadrantApiKeyRequestListPermission, kuadrantApiKeyRequestReadAllPermission, kuadrantApiKeyRequestReadOwnPermission, kuadrantApiKeyRequestUpdatePermission, kuadrantApiProductCreatePermission, kuadrantApiProductDeletePermission, kuadrantApiProductListPermission, kuadrantApiProductReadPermission, kuadrantApiProductUpdatePermission, kuadrantPermissions, kuadrantPlanPolicyCreatePermission, kuadrantPlanPolicyDeletePermission, kuadrantPlanPolicyListPermission, kuadrantPlanPolicyReadPermission, kuadrantPlanPolicyUpdatePermission, kuadrantPlugin };
package/dist/index.esm.js CHANGED
@@ -3,4 +3,5 @@ export { ApiAccessCard } from './components/ApiAccessCard/ApiAccessCard.esm.js';
3
3
  export { ApiKeyManagementTab } from './components/ApiKeyManagementTab/ApiKeyManagementTab.esm.js';
4
4
  export { ApiProductInfoCard } from './components/ApiProductInfoCard/ApiProductInfoCard.esm.js';
5
5
  export { ApprovalQueueCard } from './components/ApprovalQueueCard/ApprovalQueueCard.esm.js';
6
+ export { kuadrantApiKeyDeleteAllPermission, kuadrantApiKeyDeleteOwnPermission, kuadrantApiKeyReadAllPermission, kuadrantApiKeyReadOwnPermission, kuadrantApiKeyRequestCreatePermission, kuadrantApiKeyRequestListPermission, kuadrantApiKeyRequestReadAllPermission, kuadrantApiKeyRequestReadOwnPermission, kuadrantApiKeyRequestUpdatePermission, kuadrantApiProductCreatePermission, kuadrantApiProductDeletePermission, kuadrantApiProductListPermission, kuadrantApiProductReadPermission, kuadrantApiProductUpdatePermission, kuadrantPermissions, kuadrantPlanPolicyCreatePermission, kuadrantPlanPolicyDeletePermission, kuadrantPlanPolicyListPermission, kuadrantPlanPolicyReadPermission, kuadrantPlanPolicyUpdatePermission } from './permissions.esm.js';
6
7
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
@@ -0,0 +1,103 @@
1
+ import { createPermission } from '@backstage/plugin-permission-common';
2
+
3
+ const kuadrantPlanPolicyCreatePermission = createPermission({
4
+ name: "kuadrant.planpolicy.create",
5
+ attributes: { action: "create" }
6
+ });
7
+ const kuadrantPlanPolicyReadPermission = createPermission({
8
+ name: "kuadrant.planpolicy.read",
9
+ attributes: { action: "read" }
10
+ });
11
+ const kuadrantPlanPolicyUpdatePermission = createPermission({
12
+ name: "kuadrant.planpolicy.update",
13
+ attributes: { action: "update" }
14
+ });
15
+ const kuadrantPlanPolicyDeletePermission = createPermission({
16
+ name: "kuadrant.planpolicy.delete",
17
+ attributes: { action: "delete" }
18
+ });
19
+ const kuadrantPlanPolicyListPermission = createPermission({
20
+ name: "kuadrant.planpolicy.list",
21
+ attributes: { action: "read" }
22
+ });
23
+ const kuadrantApiProductCreatePermission = createPermission({
24
+ name: "kuadrant.apiproduct.create",
25
+ attributes: { action: "create" }
26
+ });
27
+ const kuadrantApiProductReadPermission = createPermission({
28
+ name: "kuadrant.apiproduct.read",
29
+ attributes: { action: "read" }
30
+ });
31
+ const kuadrantApiProductUpdatePermission = createPermission({
32
+ name: "kuadrant.apiproduct.update",
33
+ attributes: { action: "update" }
34
+ });
35
+ const kuadrantApiProductDeletePermission = createPermission({
36
+ name: "kuadrant.apiproduct.delete",
37
+ attributes: { action: "delete" }
38
+ });
39
+ const kuadrantApiProductListPermission = createPermission({
40
+ name: "kuadrant.apiproduct.list",
41
+ attributes: { action: "read" }
42
+ });
43
+ const kuadrantApiKeyRequestCreatePermission = createPermission({
44
+ name: "kuadrant.apikeyrequest.create",
45
+ attributes: { action: "create" },
46
+ resourceType: "apiproduct"
47
+ });
48
+ const kuadrantApiKeyRequestReadOwnPermission = createPermission({
49
+ name: "kuadrant.apikeyrequest.read.own",
50
+ attributes: { action: "read" }
51
+ });
52
+ const kuadrantApiKeyRequestReadAllPermission = createPermission({
53
+ name: "kuadrant.apikeyrequest.read.all",
54
+ attributes: { action: "read" }
55
+ });
56
+ const kuadrantApiKeyRequestUpdatePermission = createPermission({
57
+ name: "kuadrant.apikeyrequest.update",
58
+ attributes: { action: "update" }
59
+ });
60
+ const kuadrantApiKeyRequestListPermission = createPermission({
61
+ name: "kuadrant.apikeyrequest.list",
62
+ attributes: { action: "read" }
63
+ });
64
+ const kuadrantApiKeyReadOwnPermission = createPermission({
65
+ name: "kuadrant.apikey.read.own",
66
+ attributes: { action: "read" }
67
+ });
68
+ const kuadrantApiKeyReadAllPermission = createPermission({
69
+ name: "kuadrant.apikey.read.all",
70
+ attributes: { action: "read" }
71
+ });
72
+ const kuadrantApiKeyDeleteOwnPermission = createPermission({
73
+ name: "kuadrant.apikey.delete.own",
74
+ attributes: { action: "delete" }
75
+ });
76
+ const kuadrantApiKeyDeleteAllPermission = createPermission({
77
+ name: "kuadrant.apikey.delete.all",
78
+ attributes: { action: "delete" }
79
+ });
80
+ const kuadrantPermissions = [
81
+ kuadrantPlanPolicyCreatePermission,
82
+ kuadrantPlanPolicyReadPermission,
83
+ kuadrantPlanPolicyUpdatePermission,
84
+ kuadrantPlanPolicyDeletePermission,
85
+ kuadrantPlanPolicyListPermission,
86
+ kuadrantApiProductCreatePermission,
87
+ kuadrantApiProductReadPermission,
88
+ kuadrantApiProductUpdatePermission,
89
+ kuadrantApiProductDeletePermission,
90
+ kuadrantApiProductListPermission,
91
+ kuadrantApiKeyRequestCreatePermission,
92
+ kuadrantApiKeyRequestReadOwnPermission,
93
+ kuadrantApiKeyRequestReadAllPermission,
94
+ kuadrantApiKeyRequestUpdatePermission,
95
+ kuadrantApiKeyRequestListPermission,
96
+ kuadrantApiKeyReadOwnPermission,
97
+ kuadrantApiKeyReadAllPermission,
98
+ kuadrantApiKeyDeleteOwnPermission,
99
+ kuadrantApiKeyDeleteAllPermission
100
+ ];
101
+
102
+ export { kuadrantApiKeyDeleteAllPermission, kuadrantApiKeyDeleteOwnPermission, kuadrantApiKeyReadAllPermission, kuadrantApiKeyReadOwnPermission, kuadrantApiKeyRequestCreatePermission, kuadrantApiKeyRequestListPermission, kuadrantApiKeyRequestReadAllPermission, kuadrantApiKeyRequestReadOwnPermission, kuadrantApiKeyRequestUpdatePermission, kuadrantApiProductCreatePermission, kuadrantApiProductDeletePermission, kuadrantApiProductListPermission, kuadrantApiProductReadPermission, kuadrantApiProductUpdatePermission, kuadrantPermissions, kuadrantPlanPolicyCreatePermission, kuadrantPlanPolicyDeletePermission, kuadrantPlanPolicyListPermission, kuadrantPlanPolicyReadPermission, kuadrantPlanPolicyUpdatePermission };
103
+ //# sourceMappingURL=permissions.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.esm.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 kuadrant resources and operations.\n * they must match the permissions defined in the backend plugin.\n *\n * permission types:\n * - BasicPermission: standard permission that applies globally\n * - ResourcePermission: permission scoped to specific resource types (e.g., apiproduct)\n *\n * permission patterns:\n * - `.create` - create new resources\n * - `.read` - read resource details\n * - `.read.own` - read only resources owned by the user\n * - `.read.all` - read all resources regardless of ownership\n * - `.update` - modify existing resources\n * - `.delete` - delete resources\n * - `.delete.own` - delete only resources owned by the user\n * - `.delete.all` - delete any resource regardless of ownership\n * - `.list` - list/view collections of resources\n */\n\n// planpolicy permissions\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\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\n\n/**\n * permission to create API key requests\n *\n * this is a ResourcePermission scoped to 'apiproduct', allowing\n * fine-grained control over which API products users can request access to.\n *\n * use in frontend: useKuadrantPermission(kuadrantApiKeyRequestCreatePermission)\n * use in backend with resource: { permission, resourceRef: 'apiproduct:namespace/name' }\n */\nexport const kuadrantApiKeyRequestCreatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.create',\n attributes: { action: 'create' },\n resourceType: 'apiproduct',\n});\n\n/**\n * permission to read API key requests created by the current user\n * use this for allowing users to see their own request history\n */\nexport const kuadrantApiKeyRequestReadOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.own',\n attributes: { action: 'read' },\n});\n\n/**\n * permission to read all API key requests regardless of who created them\n * use this for platform engineers/admins who need to view the approval queue\n */\nexport const kuadrantApiKeyRequestReadAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.all',\n attributes: { action: 'read' },\n});\n\n/**\n * permission to approve or reject API key requests\n * typically granted to API owners and platform engineers\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\n\n/**\n * permission to read API keys owned by the current user\n * allows users to view their own active API keys\n */\nexport const kuadrantApiKeyReadOwnPermission = createPermission({\n name: 'kuadrant.apikey.read.own',\n attributes: { action: 'read' },\n});\n\n/**\n * permission to read all API keys regardless of ownership\n * for platform engineers/admins who need to audit keys\n */\nexport const kuadrantApiKeyReadAllPermission = createPermission({\n name: 'kuadrant.apikey.read.all',\n attributes: { action: 'read' },\n});\n\n/**\n * permission to delete API keys owned by the current user\n * allows users to revoke their own access\n */\nexport const kuadrantApiKeyDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikey.delete.own',\n attributes: { action: 'delete' },\n});\n\n/**\n * permission to delete any API key regardless of ownership\n * for platform engineers/admins who need to revoke access\n */\nexport const kuadrantApiKeyDeleteAllPermission = createPermission({\n name: 'kuadrant.apikey.delete.all',\n attributes: { action: 'delete' },\n});\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":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { usePermission } from '@backstage/plugin-permission-react';
2
+
3
+ function useKuadrantPermission(permission, resourceRef) {
4
+ const permissionRequest = "resourceType" in permission ? { permission, resourceRef } : { permission };
5
+ const result = usePermission(permissionRequest);
6
+ return {
7
+ allowed: result.allowed,
8
+ loading: result.loading,
9
+ error: result.error
10
+ };
11
+ }
12
+ function canDeleteResource(ownerId, currentUserId, canDeleteOwn, canDeleteAll) {
13
+ if (canDeleteAll) return true;
14
+ if (canDeleteOwn && ownerId === currentUserId) return true;
15
+ return false;
16
+ }
17
+
18
+ export { canDeleteResource, useKuadrantPermission };
19
+ //# sourceMappingURL=permissions.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.esm.js","sources":["../../src/utils/permissions.ts"],"sourcesContent":["import { usePermission } from '@backstage/plugin-permission-react';\nimport { Permission, ResourcePermission } from '@backstage/plugin-permission-common';\n\n/**\n * result of a permission check including error state\n */\nexport interface PermissionCheckResult {\n allowed: boolean;\n loading: boolean;\n error?: Error;\n}\n\n/**\n * custom hook for checking kuadrant permissions that handles both\n * BasicPermission and ResourcePermission types without type bypasses\n *\n * @param permission - the permission to check\n * @param resourceRef - optional resource reference for ResourcePermissions\n * @returns permission check result with error handling\n *\n * @example\n * // basic permission\n * const { allowed, loading, error } = useKuadrantPermission(\n * kuadrantApiProductListPermission\n * );\n *\n * @example\n * // resource permission\n * const { allowed, loading, error } = useKuadrantPermission(\n * kuadrantApiKeyRequestCreatePermission,\n * 'apiproduct:namespace/name'\n * );\n */\nexport function useKuadrantPermission(\n permission: Permission,\n resourceRef?: string,\n): PermissionCheckResult {\n // construct the permission request based on whether it's a ResourcePermission\n const permissionRequest = 'resourceType' in permission\n ? { permission: permission as ResourcePermission, resourceRef }\n : { permission };\n\n const result = usePermission(permissionRequest as any);\n\n return {\n allowed: result.allowed,\n loading: result.loading,\n error: result.error,\n };\n}\n\n/**\n * helper to determine if a user can delete a specific API key or request\n *\n * @param ownerId - the user id who owns the key/request\n * @param currentUserId - the current user's id\n * @param canDeleteOwn - whether user has permission to delete their own keys\n * @param canDeleteAll - whether user has permission to delete all keys\n * @returns true if user can delete this specific key/request\n */\nexport function canDeleteResource(\n ownerId: string,\n currentUserId: string,\n canDeleteOwn: boolean,\n canDeleteAll: boolean,\n): boolean {\n if (canDeleteAll) return true;\n if (canDeleteOwn && ownerId === currentUserId) return true;\n return false;\n}\n"],"names":[],"mappings":";;AAiCgB,SAAA,qBAAA,CACd,YACA,WACuB,EAAA;AAEvB,EAAM,MAAA,iBAAA,GAAoB,kBAAkB,UACxC,GAAA,EAAE,YAA8C,WAAY,EAAA,GAC5D,EAAE,UAAW,EAAA;AAEjB,EAAM,MAAA,MAAA,GAAS,cAAc,iBAAwB,CAAA;AAErD,EAAO,OAAA;AAAA,IACL,SAAS,MAAO,CAAA,OAAA;AAAA,IAChB,SAAS,MAAO,CAAA,OAAA;AAAA,IAChB,OAAO,MAAO,CAAA;AAAA,GAChB;AACF;AAWO,SAAS,iBACd,CAAA,OAAA,EACA,aACA,EAAA,YAAA,EACA,YACS,EAAA;AACT,EAAA,IAAI,cAAqB,OAAA,IAAA;AACzB,EAAI,IAAA,YAAA,IAAgB,OAAY,KAAA,aAAA,EAAsB,OAAA,IAAA;AACtD,EAAO,OAAA,KAAA;AACT;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuadrant/kuadrant-backstage-plugin-frontend",
3
- "version": "0.0.1-test.1-2bfd8489",
3
+ "version": "0.0.1-test.1-57ace816",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,49 +0,0 @@
1
- import { useApi, identityApiRef } from '@backstage/core-plugin-api';
2
- import useAsync from 'react-use/lib/useAsync';
3
-
4
- function useUserRole() {
5
- const identityApi = useApi(identityApiRef);
6
- const { value, loading } = useAsync(async () => {
7
- try {
8
- const identity = await identityApi.getBackstageIdentity();
9
- const userId = identity.userEntityRef.split("/")[1] || "guest";
10
- const ownershipRefs = identity.ownershipEntityRefs || [];
11
- console.log("useUserRole debug:", { userId, ownershipRefs });
12
- const isPlatformEngineer = ownershipRefs.includes("group:default/platform-engineers") || ownershipRefs.includes("group:default/platform-admins");
13
- const isApiOwner = ownershipRefs.includes("group:default/api-owners") || ownershipRefs.includes("group:default/app-developers");
14
- const isApiConsumer = ownershipRefs.includes("group:default/api-consumers");
15
- let role = "unknown";
16
- if (isPlatformEngineer) {
17
- role = "platform-engineer";
18
- } else if (isApiOwner) {
19
- role = "api-owner";
20
- } else if (isApiConsumer) {
21
- role = "api-consumer";
22
- }
23
- console.log("useUserRole result:", { role, isPlatformEngineer, isApiOwner, isApiConsumer });
24
- return {
25
- userId,
26
- role,
27
- isPlatformEngineer,
28
- isApiOwner,
29
- isApiConsumer
30
- };
31
- } catch (error) {
32
- console.log("useUserRole error, returning guest with full access:", error);
33
- return {
34
- userId: "guest",
35
- role: "platform-engineer",
36
- isPlatformEngineer: true,
37
- isApiOwner: true,
38
- isApiConsumer: true
39
- };
40
- }
41
- }, [identityApi]);
42
- return {
43
- userInfo: value || null,
44
- loading
45
- };
46
- }
47
-
48
- export { useUserRole };
49
- //# sourceMappingURL=useUserRole.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useUserRole.esm.js","sources":["../../src/hooks/useUserRole.ts"],"sourcesContent":["import { useApi, identityApiRef } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\n\nexport type UserRole = 'platform-engineer' | 'api-owner' | 'api-consumer' | 'unknown';\n\nexport interface UserInfo {\n userId: string;\n role: UserRole;\n isPlatformEngineer: boolean;\n isApiOwner: boolean;\n isApiConsumer: boolean;\n}\n\nexport function useUserRole(): { userInfo: UserInfo | null; loading: boolean } {\n const identityApi = useApi(identityApiRef);\n\n const { value, loading } = useAsync(async () => {\n try {\n const identity = await identityApi.getBackstageIdentity();\n const userId = identity.userEntityRef.split('/')[1] || 'guest';\n const ownershipRefs = identity.ownershipEntityRefs || [];\n\n console.log('useUserRole debug:', { userId, ownershipRefs });\n\n // determine roles based on group membership (not hierarchical)\n const isPlatformEngineer = ownershipRefs.includes('group:default/platform-engineers') ||\n ownershipRefs.includes('group:default/platform-admins');\n\n const isApiOwner = ownershipRefs.includes('group:default/api-owners') ||\n ownershipRefs.includes('group:default/app-developers');\n\n const isApiConsumer = ownershipRefs.includes('group:default/api-consumers');\n\n // primary role (for display)\n let role: UserRole = 'unknown';\n if (isPlatformEngineer) {\n role = 'platform-engineer';\n } else if (isApiOwner) {\n role = 'api-owner';\n } else if (isApiConsumer) {\n role = 'api-consumer';\n }\n\n console.log('useUserRole result:', { role, isPlatformEngineer, isApiOwner, isApiConsumer });\n\n return {\n userId,\n role,\n isPlatformEngineer,\n isApiOwner,\n isApiConsumer,\n };\n } catch (error) {\n console.log('useUserRole error, returning guest with full access:', error);\n // in dev mode without auth backend, return default guest with full access\n return {\n userId: 'guest',\n role: 'platform-engineer' as UserRole,\n isPlatformEngineer: true,\n isApiOwner: true,\n isApiConsumer: true,\n };\n }\n }, [identityApi]);\n\n return {\n userInfo: value || null,\n loading,\n };\n}\n"],"names":[],"mappings":";;;AAaO,SAAS,WAA+D,GAAA;AAC7E,EAAM,MAAA,WAAA,GAAc,OAAO,cAAc,CAAA;AAEzC,EAAA,MAAM,EAAE,KAAA,EAAO,OAAQ,EAAA,GAAI,SAAS,YAAY;AAC9C,IAAI,IAAA;AACF,MAAM,MAAA,QAAA,GAAW,MAAM,WAAA,CAAY,oBAAqB,EAAA;AACxD,MAAA,MAAM,SAAS,QAAS,CAAA,aAAA,CAAc,MAAM,GAAG,CAAA,CAAE,CAAC,CAAK,IAAA,OAAA;AACvD,MAAM,MAAA,aAAA,GAAgB,QAAS,CAAA,mBAAA,IAAuB,EAAC;AAEvD,MAAA,OAAA,CAAQ,GAAI,CAAA,oBAAA,EAAsB,EAAE,MAAA,EAAQ,eAAe,CAAA;AAG3D,MAAA,MAAM,qBAAqB,aAAc,CAAA,QAAA,CAAS,kCAAkC,CACzD,IAAA,aAAA,CAAc,SAAS,+BAA+B,CAAA;AAEjF,MAAA,MAAM,aAAa,aAAc,CAAA,QAAA,CAAS,0BAA0B,CACjD,IAAA,aAAA,CAAc,SAAS,8BAA8B,CAAA;AAExE,MAAM,MAAA,aAAA,GAAgB,aAAc,CAAA,QAAA,CAAS,6BAA6B,CAAA;AAG1E,MAAA,IAAI,IAAiB,GAAA,SAAA;AACrB,MAAA,IAAI,kBAAoB,EAAA;AACtB,QAAO,IAAA,GAAA,mBAAA;AAAA,iBACE,UAAY,EAAA;AACrB,QAAO,IAAA,GAAA,WAAA;AAAA,iBACE,aAAe,EAAA;AACxB,QAAO,IAAA,GAAA,cAAA;AAAA;AAGT,MAAA,OAAA,CAAQ,IAAI,qBAAuB,EAAA,EAAE,MAAM,kBAAoB,EAAA,UAAA,EAAY,eAAe,CAAA;AAE1F,MAAO,OAAA;AAAA,QACL,MAAA;AAAA,QACA,IAAA;AAAA,QACA,kBAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA,OACF;AAAA,aACO,KAAO,EAAA;AACd,MAAQ,OAAA,CAAA,GAAA,CAAI,wDAAwD,KAAK,CAAA;AAEzE,MAAO,OAAA;AAAA,QACL,MAAQ,EAAA,OAAA;AAAA,QACR,IAAM,EAAA,mBAAA;AAAA,QACN,kBAAoB,EAAA,IAAA;AAAA,QACpB,UAAY,EAAA,IAAA;AAAA,QACZ,aAAe,EAAA;AAAA,OACjB;AAAA;AACF,GACF,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAO,OAAA;AAAA,IACL,UAAU,KAAS,IAAA,IAAA;AAAA,IACnB;AAAA,GACF;AACF;;;;"}