@platform-mesh/portal-ui-lib 0.52.0 → 0.52.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-mesh/portal-ui-lib",
3
- "version": "0.52.0",
3
+ "version": "0.52.2",
4
4
  "repository": {
5
5
  "url": "git+https://github.com/platform-mesh/portal-ui-lib.git"
6
6
  },
@@ -5,6 +5,45 @@ import { ObjectMeta, Condition } from 'kubernetes-types/meta/v1';
5
5
  declare const ALL_NAMESPACE = "-all-";
6
6
  declare const kcpRootOrgsPath = "root:orgs";
7
7
 
8
+ interface AccountInfo {
9
+ metadata: ObjectMeta;
10
+ spec: {
11
+ account: {
12
+ originClusterId: string;
13
+ };
14
+ clusterInfo: {
15
+ ca: string;
16
+ };
17
+ organization: {
18
+ originClusterId: string;
19
+ name: string;
20
+ };
21
+ oidc: {
22
+ issuerUrl: string;
23
+ clients: {
24
+ kubectl: {
25
+ clientId: string;
26
+ };
27
+ };
28
+ };
29
+ };
30
+ }
31
+
32
+ interface LogicalCluster {
33
+ status: {
34
+ phase: string;
35
+ };
36
+ }
37
+
38
+ interface Permission {
39
+ actions: string[];
40
+ resource: string;
41
+ }
42
+ interface InstancePermission extends Permission {
43
+ namespace?: string;
44
+ name?: string;
45
+ }
46
+
8
47
  type PlatformMeshFieldDefinition = TableFieldDefinition & Omit<FormFieldDefinition, 'name' | 'label'> & {
9
48
  label?: string;
10
49
  dynamicValuesDefinition?: {
@@ -56,6 +95,13 @@ interface Resource extends GenericResource {
56
95
  isAvailable?: boolean;
57
96
  accessibleName?: string;
58
97
  }
98
+ interface PermissionsDefinition {
99
+ group: string;
100
+ resource: string;
101
+ entityActions: string[];
102
+ resourceActions: string[];
103
+ entityContextKey: string;
104
+ }
59
105
  interface ResourceDefinition {
60
106
  apiGroup?: string;
61
107
  version: string;
@@ -66,6 +112,7 @@ interface ResourceDefinition {
66
112
  namespace?: string;
67
113
  readyCondition?: PlatformMeshFieldDefinition;
68
114
  ui?: UIDefinition;
115
+ permissionsDefinition?: PermissionsDefinition;
69
116
  }
70
117
  declare const ResourceOperationTypeMap: {
71
118
  readonly ADDED: "ADDED";
@@ -89,35 +136,5 @@ interface ResourceListResult {
89
136
  }
90
137
  type KubernetesScope = 'Cluster' | 'Namespaced';
91
138
 
92
- interface AccountInfo {
93
- metadata: ObjectMeta;
94
- spec: {
95
- account: {
96
- originClusterId: string;
97
- };
98
- clusterInfo: {
99
- ca: string;
100
- };
101
- organization: {
102
- originClusterId: string;
103
- name: string;
104
- };
105
- oidc: {
106
- issuerUrl: string;
107
- clients: {
108
- kubectl: {
109
- clientId: string;
110
- };
111
- };
112
- };
113
- };
114
- }
115
-
116
- interface LogicalCluster {
117
- status: {
118
- phase: string;
119
- };
120
- }
121
-
122
139
  export { ALL_NAMESPACE, ResourceOperationTypeMap, kcpRootOrgsPath };
123
- export type { AccountInfo, DetailView, KubernetesScope, ListView, LogicalCluster, PlatformMeshFieldDefinition, Resource, ResourceDefinition, ResourceListResult, ResourceMeta, ResourceOperationType, ResourcePagination, ResourceSpec, ResourceStatus, ResourceSubscriptionResult, UIDefinition, UiView };
140
+ export type { AccountInfo, DetailView, InstancePermission, KubernetesScope, ListView, LogicalCluster, Permission, PermissionsDefinition, PlatformMeshFieldDefinition, Resource, ResourceDefinition, ResourceListResult, ResourceMeta, ResourceOperationType, ResourcePagination, ResourceSpec, ResourceStatus, ResourceSubscriptionResult, UIDefinition, UiView };
@@ -1,5 +1,5 @@
1
1
  import { NodeContext, LuigiNode, EntityDefinition, CustomGlobalNodesService, HeaderBarConfigService, HeaderBarConfig, LuigiExtendedGlobalContextConfigService, NavigationRedirectStrategy, NodeChangeHookConfigService, NodeContextProcessingService, RoutingConfigService, UserProfileConfigService, UserProfile, CustomMessageListener } from '@openmfp/portal-ui-lib';
2
- import { ResourceDefinition } from '@platform-mesh/portal-ui-lib/models';
2
+ import { ResourceDefinition, Permission } from '@platform-mesh/portal-ui-lib/models';
3
3
  import * as i0 from '@angular/core';
4
4
 
5
5
  interface PortalContext extends Record<string, any> {
@@ -10,10 +10,6 @@ interface PortalEntityContext {
10
10
  id: string;
11
11
  };
12
12
  }
13
- interface Permission {
14
- actions: string[];
15
- resource: string;
16
- }
17
13
  interface PortalNodeContext extends NodeContext {
18
14
  portalContext: PortalContext;
19
15
  organizationId?: string;
@@ -85,11 +81,14 @@ declare class NodeChangeHookConfigServiceImpl implements NodeChangeHookConfigSer
85
81
  declare class NodeContextProcessingServiceImpl implements NodeContextProcessingService {
86
82
  private crdGatewayKcpPatchResolver;
87
83
  private accountInfoService;
84
+ private instancePermissionsService;
88
85
  private organizationReadyService;
89
86
  private errorHandlerService;
87
+ private luigiCoreService;
90
88
  processNodeContext(dynamicEntityId: string, entityNode: PortalLuigiNode, ctx: PortalNodeContext): Promise<void>;
91
89
  private addFieldsToContext;
92
90
  private addFieldsToContextFromAccountInfo;
91
+ private getEntityPermissions;
93
92
  private accamulatePortalPermissions;
94
93
  static ɵfac: i0.ɵɵFactoryDeclaration<NodeContextProcessingServiceImpl, never>;
95
94
  static ɵprov: i0.ɵɵInjectableDeclaration<NodeContextProcessingServiceImpl>;
@@ -1,21 +1,25 @@
1
1
  import { NodeContext } from '@openmfp/portal-ui-lib';
2
- import { ResourceDefinition, ResourceOperationType, ResourcePagination, Resource, ResourceListResult, ResourceSubscriptionResult, AccountInfo, LogicalCluster } from '@platform-mesh/portal-ui-lib/models';
2
+ import { ResourceDefinition, PermissionsDefinition, ResourceOperationType, ResourcePagination, Resource, ResourceListResult, ResourceSubscriptionResult, AccountInfo, LogicalCluster } from '@platform-mesh/portal-ui-lib/models';
3
3
  import * as apollo_angular from 'apollo-angular';
4
4
  import { Apollo } from 'apollo-angular';
5
5
  import * as i0 from '@angular/core';
6
- import { GenericResource } from '@openmfp/ngx';
7
6
  import { Observable } from 'rxjs';
7
+ import { GenericResource } from '@openmfp/ngx';
8
8
  import { VariableOptions } from 'gql-query-builder';
9
9
 
10
10
  interface ResourceNodeContext extends Partial<NodeContext> {
11
11
  resourceDefinition?: ResourceDefinition;
12
12
  organization?: string;
13
+ accountPath?: string;
13
14
  entityName?: string;
14
15
  resourceId?: string;
15
16
  accountId?: string;
16
17
  kcpCA?: string;
17
18
  namespaceId?: string;
18
19
  namespaces?: string[];
20
+ portalPermissions?: {
21
+ [key: string]: string[];
22
+ };
19
23
  portalContext: {
20
24
  crdGatewayApiUrl: string;
21
25
  openSearchApiUrl?: string;
@@ -65,6 +69,40 @@ declare class GatewayService {
65
69
  static ɵprov: i0.ɵɵInjectableDeclaration<GatewayService>;
66
70
  }
67
71
 
72
+ interface InstanceCheck {
73
+ resource: string;
74
+ group: string;
75
+ namespace?: string;
76
+ name: string;
77
+ actions: string[];
78
+ }
79
+ interface ResourceCheckRequest {
80
+ organization: string;
81
+ accountPath?: string;
82
+ checks: InstanceCheck[];
83
+ }
84
+ interface InstancePermissionResponse {
85
+ resource: string;
86
+ namespace?: string;
87
+ name?: string;
88
+ actions: string[];
89
+ }
90
+ declare class InstancePermissionsService {
91
+ private httpClient;
92
+ private luigiCoreService;
93
+ private requestChecks;
94
+ checkInstance(nodeContext: ResourceNodeContext, permissionsDefinition: PermissionsDefinition, instance: {
95
+ name: string;
96
+ namespace?: string;
97
+ }): Observable<InstancePermissionResponse[]>;
98
+ checkInstances(nodeContext: ResourceNodeContext, permissionsDefinition: PermissionsDefinition, instances: {
99
+ name: string;
100
+ namespace?: string;
101
+ }[]): Observable<InstancePermissionResponse[]>;
102
+ static ɵfac: i0.ɵɵFactoryDeclaration<InstancePermissionsService, never>;
103
+ static ɵprov: i0.ɵɵInjectableDeclaration<InstancePermissionsService>;
104
+ }
105
+
68
106
  interface ReadResourcesParams {
69
107
  /** Free-text query — used by the OpenSearch implementation; ignored by ResourceService. */
70
108
  q?: string;
@@ -187,5 +225,5 @@ declare class OrganizationReadyService {
187
225
  static ɵprov: i0.ɵɵInjectableDeclaration<OrganizationReadyService>;
188
226
  }
189
227
 
190
- export { AccountInfoService, ApolloFactory, ErrorHandlerService, GatewayService, LogicalClusterService, OrganizationReadyService, ResourceService };
191
- export type { ListOptions, ReadResources, ReadResourcesPagination, ReadResourcesParams, ReadResourcesResult, ReadResourcesSubscriptionResult, ResourceNodeContext, ResourceRequestParams };
228
+ export { AccountInfoService, ApolloFactory, ErrorHandlerService, GatewayService, InstancePermissionsService, LogicalClusterService, OrganizationReadyService, ResourceService };
229
+ export type { InstanceCheck, InstancePermissionResponse, ListOptions, ReadResources, ReadResourcesPagination, ReadResourcesParams, ReadResourcesResult, ReadResourcesSubscriptionResult, ResourceCheckRequest, ResourceNodeContext, ResourceRequestParams };
@@ -1,4 +1,4 @@
1
- import { PlatformMeshFieldDefinition, Resource, ResourceSubscriptionResult, PropertyField } from '@platform-mesh/portal-ui-lib/models';
1
+ import { PlatformMeshFieldDefinition, InstancePermission, Resource, ResourceSubscriptionResult, PropertyField } from '@platform-mesh/portal-ui-lib/models';
2
2
  import { NodeContext } from '@openmfp/portal-ui-lib';
3
3
 
4
4
  declare function buildGraphQLInputTypeName(apiGroup: string | undefined, version: string | undefined, entity: string): string;
@@ -13,6 +13,8 @@ declare const generateGraphQLFields: (uiFields: PlatformMeshFieldDefinition[]) =
13
13
 
14
14
  declare const getValueByPath: <T extends object, R = unknown>(obj: T, path: string) => R | undefined;
15
15
 
16
+ declare const permissionKey: (instance: Partial<Omit<InstancePermission, "actions">>) => string;
17
+
16
18
  declare const isLocalSetup: () => boolean;
17
19
 
18
20
  declare function isNamespacedResource(nodeContext: Partial<NodeContext>): boolean;
@@ -25,6 +27,18 @@ declare function mergeListWithSubscriptionResult<T>(items: T[], subscriptionResu
25
27
 
26
28
  declare const parseRawGqlQueryToFields: (s: string) => any[];
27
29
 
30
+ /**
31
+ * Tier-1 resource-level permission check (fail-open).
32
+ *
33
+ * Returns true when the verb is granted for the resource, OR when no
34
+ * permissions were fetched for the resource at all (no entry in
35
+ * portalPermissions → we don't gate). Returns false ONLY when permissions
36
+ * WERE fetched for the resource and the verb is absent.
37
+ */
38
+ declare const resourceActionAllowed: (portalPermissions: {
39
+ [key: string]: string[];
40
+ } | undefined, resource: string | undefined, verb: string) => boolean;
41
+
28
42
  declare const getResourceValueByJsonPath: <T>(resource: T, field: {
29
43
  jsonPathExpression?: string;
30
44
  property?: string | string[];
@@ -37,5 +51,5 @@ declare function stripTypename<T>(value: T): T;
37
51
 
38
52
  declare function setPropertyByPath<T extends Record<string, any>>(object: T, path: string, value: unknown): T;
39
53
 
40
- export { buildGraphQLInputTypeName, buildResourcePath, decodeBase64, encodeBase64, generateGraphQLFields, getResourceValueByJsonPath, getValueByPath, isLocalSetup, isNamespacedResource, mergeListWithSubscriptionResult, parseRawGqlQueryToFields, setPropertyByPath, stripTypename };
54
+ export { buildGraphQLInputTypeName, buildResourcePath, decodeBase64, encodeBase64, generateGraphQLFields, getResourceValueByJsonPath, getValueByPath, isLocalSetup, isNamespacedResource, mergeListWithSubscriptionResult, parseRawGqlQueryToFields, permissionKey, resourceActionAllowed, setPropertyByPath, stripTypename };
41
55
  export type { MergeListWithSubscriptionResultOptions };