@spotify/backstage-plugin-rbac 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @spotify/backstage-plugin-rbac
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated backstage dependencies to `v1.24.0`
8
+ - Updated dependencies
9
+ - `@spotify/backstage-plugin-core` to `^0.7.0`
10
+ - `@spotify/backstage-plugin-rbac-common` to `^0.5.12`
11
+
3
12
  ## 0.6.0
4
13
 
5
14
  ### Minor Changes
package/README.md CHANGED
@@ -1,216 +1,5 @@
1
1
  # Spotify Plugins for Backstage: Role-Based Access Control (RBAC) - Frontend
2
2
 
3
- ![](https://spotify-plugins-for-backstage-readme-images.spotifycdn.com/rbac.png)
3
+ This plugin is part of [Spotify Plugins for Backstage](https://backstage.spotify.com/marketplace/spotify/bundle/spotify-plugins-bundle/).
4
4
 
5
- The RBAC plugin works with the [Backstage permission framework](https://backstage.io/docs/permissions/overview) to provide support for role-based access control in Backstage. The Backstage permission framework is a system in the open-source Backstage project, which allows granular control of access to specific resources or actions. The permission framework is currently supported in the Catalog and TechDocs, with other core features soon to come. In the future, we’ll encourage third-party plugin authors to add permission support too — which can be done without changes to the Backstage core.
6
-
7
- Permissions are controlled in a Backstage instance through a **policy**. A policy is simply an async function which receives a request to authorize a specific action for a user and (optional) resource, and returns a decision on whether to authorize that permission. Without the RBAC plugin, integrators must implement their own policies from scratch, or adapt reusable policies written by others.
8
-
9
- The RBAC plugin allows you to control permissions in Backstage without writing code. Instead, you can manage your policy using the RBAC interface integrated with Backstage. Once you publish the changes to your policy, they will be reflected immediately.
10
-
11
- With the RBAC plugin, you manage the permissions in your Backstage instance by assigning users and groups to roles, and configuring the rules that should apply for each role. You can use powerful matching features to keep your policy short, or supply granular decisions for each available permission and role.
12
-
13
- ## Prerequisites
14
-
15
- ### 1. Install the RBAC Backend plugin
16
-
17
- You must install the [RBAC Backend](https://npmjs.com/@spotify/backstage-plugin-rbac-backend) and all of its prerequisites before installing the RBAC frontend.
18
-
19
- ## Installation
20
-
21
- ### 1. Getting the plugin
22
-
23
- Add the RBAC packages as dependencies to your Backstage instance:
24
-
25
- ```bash
26
- yarn workspace app add @spotify/backstage-plugin-rbac
27
- ```
28
-
29
- ### 2. Install RBAC frontend
30
-
31
- First install the RBAC routes in the app within the `packages/app/src/App.tsx`. This will provide the UI for authoring your RBAC policy under the `/rbac` route. Note that this route can only be accessed by the `authorizedUsers` configured above.
32
-
33
- ```diff
34
- // packages/app/src/App.tsx
35
-
36
- + import { RBACRoot } from '@spotify/backstage-plugin-rbac';
37
-
38
- /* ... */
39
-
40
- const routes = (
41
- <FlatRoutes>
42
- /* ... */
43
- + <Route path="/rbac" element={<RBACRoot />} />
44
- </FlatRoutes>
45
- );
46
- ```
47
-
48
- RBAC also provides a sidebar item that will only be visible to RBAC `authorizedUsers`. This is an optional step, but it provides an easy way for RBAC authorized users to access the plugin.
49
-
50
- ```diff
51
- // packages/app/src/components/Root.tsx
52
-
53
- + import { RBACSidebarItem } from '@spotify/backstage-plugin-rbac';
54
-
55
- export const Root = ({ children }: PropsWithChildren<{}>) => (
56
- <SidebarPage>
57
- <Sidebar>
58
- <SidebarLogo />
59
-
60
- /* ... */
61
-
62
- <SidebarScrollWrapper>
63
- <SidebarItem icon={MapIcon} to="tech-radar" text="Tech Radar" />
64
- <SidebarItem
65
- icon={SkillExchangeIcon}
66
- to="skill-exchange"
67
- text="Skill Exchange"
68
- />
69
- <SidebarItem icon={PulseIcon} to="pulse" text="Pulse" />
70
- <SidebarItem icon={SoundcheckIcon} to="soundcheck" text="Soundcheck" />
71
- + <RBACSidebarItem />
72
- </SidebarScrollWrapper>
73
- </Sidebar>
74
- </SidebarPage>
75
- );
76
- ```
77
-
78
- ### 3. Configure an initial policy
79
-
80
- When there is no published RBAC policy, the default behaviour of RBAC is to deny all authorization requests sent to the permission framework. With this in mind, it's preferable to publish a simple RBAC policy before proceeding to install RBAC in the permission framework.
81
-
82
- The following instructions configure RBAC with a policy that allows all authorization requests. If you want to start with something more complex, refer to later sections of this documentation.
83
-
84
- 1. Open the RBAC UI by visiting the `/rbac` path in your Backstage instance, or clicking the RBAC item in the sidebar (if you've installed the `RBACSidebarItem`).
85
- 1. Click "New Version" to start working on a new draft policy, and choose a name for it.
86
- 1. Click "New Role" to create a role within the policy, and give that a name too.
87
- 1. Click the "New Permission Decision" button in the Permission Decisions table on the right hand side.
88
- 1. In the dialog, select "Match All Permissions".
89
- 1. Confirm that "Allow" is already selected at the bottom of the dialog.
90
- 1. Click "Save".
91
- 1. Confirm that the Members table on the left hand side contains a row for "All" users.
92
- 1. Click "Back to Policy"
93
- 1. Click "Save Draft"
94
- 1. Click "Publish", and confirm publishing in the confirmation dialog.
95
-
96
- ### 4. Install the RBAC policy in the permission framework
97
-
98
- To use the RBAC policy in the Backstage instance, we replace the `TestPermissionPolicy` we created when setting up the permission framework with an `RBACPolicy` instance which uses the roles we define in the UI.
99
-
100
- Adjust `packages/backend/src/plugins/permission.ts` as follows:
101
-
102
- ```diff
103
- import { createRouter } from '@backstage/plugin-permission-backend';
104
- - import {
105
- - AuthorizeResult,
106
- - PolicyDecision,
107
- - } from '@backstage/plugin-permission-common';
108
- - import { PermissionPolicy } from '@backstage/plugin-permission-node';
109
- + import { RBACPolicyBuilder } from '@spotify/backstage-plugin-rbac-backend';
110
- import { Router } from 'express';
111
- import { PluginEnvironment } from '../types';
112
-
113
- - class TestPermissionPolicy implements PermissionPolicy {
114
- - async handle(): Promise<PolicyDecision> {
115
- - return { result: AuthorizeResult.ALLOW };
116
- - }
117
- - }
118
- -
119
- export default async function createPlugin(
120
- env: PluginEnvironment,
121
- ): Promise<Router> {
122
- return await createRouter({
123
- config: env.config,
124
- logger: env.logger,
125
- discovery: env.discovery,
126
- - policy: new TestPermissionPolicy(),
127
- + policy: await RBACPolicyBuilder.create(env).build(),
128
- identity: env.identity,
129
- });
130
- }
131
- ```
132
-
133
- ### 5. Check everything is working
134
-
135
- If you've followed all the steps up to this point, the RBAC policy is now in place! You should find that Backstage adheres to the policy you configured in step 3. If you have any problems, please reach out to us and we'll be happy to provide support.
136
-
137
- ## Working with the RBAC UI
138
-
139
- ### Publishing Lifecycle
140
-
141
- The RBAC UI provides the ability to build **RBAC policies**. When a policy is first created, it is in **draft** state, and doesn't have any effect on the behavior of Backstage. You can save draft policies while you're working on them, and come back to them later. Once a draft policy is ready, it can be **published**. There is only one published policy in Backstage at any given time. A newly-published policy replaces the existing one, which moves to **inactive** state. Inactive policies can be republished at any time.
142
-
143
- ### Policy Overview
144
-
145
- The RBAC policy is configured by defining one or more **roles**, to which you can add users/groups as members. Each role can have multiple **permission decisions** configured, which match one or more **permissions**, and specify the authorization **decision** that should be made for those permissions.
146
-
147
- Users can be a member of multiple roles, and roles can overlap in the permissions they match. When a given permission matches multiple times, the **first match** will be the one used to determine the decision returned.
148
-
149
- ### Matching permissions
150
-
151
- Permissions are a core concept in the Backstage permission framework. Each plugin can define a set of permissions that control what users can see and do within that plugin. Each [permission](https://github.com/backstage/backstage/blob/master/plugins/permission-common/src/types/permission.ts#L39) is an object with the following fields:
152
-
153
- - **name**: a string which uniquely identifies the permission, such as `catalog.entity.read`
154
- - **attributes**: an object containing attributes which describe the characteristics of the permission, to allow matching multiple permissions when making a policy decision. We expect the number of supported attributes to increase over time, but for now, the only attribute is `action`, which can be set to `"create"`, `"read"`, `"update"`, or `"delete"`.
155
- - **resourceType**: the type of resource expected to be supplied when authorizing this permission, if applicable (for example `catalog-entity`).
156
-
157
- In the RBAC UI, it's possible to match a single specific permission by name, or to match using a combination of resourceType and actions in order to match multiple permissions with a single entry in the list. It's also possible to match all permissions with a single entry - this is mostly useful for defining a fallback at the end of your policy, in case no other permission decision in the policy matched a request.
158
-
159
- ### Specifying decisions
160
-
161
- The RBAC UI supports definitive `allow` or `deny` decisions, as well as [conditional decisions](https://backstage.io/docs/permissions/writing-a-policy#conditional-decisions) whose result can vary based on characteristics of the resource being authorized. Conditional decisions can only be returned for permissions with a resourceType - the RBAC UI handles enabling and disabling the "conditional" option as needed.
162
-
163
- Conditional decisions contain one or more **conditions**, which are exported by permissioned plugins and tied to a resourceType. The condition `HAS_ANNOTATION`, for example, is tied to the `catalog-entity` resourceType, and checks whether a catalog entity has a certain annotation. Multiple conditions can be combined using "any of" (return `allow` when any one of these conditions is true), or "all of" (only return `allow` when all of these conditions is true). It's also possible to negate conditions using "not", and combinations of conditions and logical operators can be deeply nested if needed.
164
-
165
- ## Other features
166
-
167
- ### Import / Export
168
-
169
- The RBAC plugin allows users to export existing policies, a feature which can be found within the policy page. You can import the resulting yaml file back into RBAC, which will result in a draft policy identical to the exported policy. This can be useful when working with multiple Backstage instances with similar configurations.
170
-
171
- ### Default policy
172
-
173
- The RBAC plugin allows Backstage administrators to configure a default policy for deployment. Setting a default policy allows RBAC to enforce an active policy from the start, before any administrator has interacted with the RBAC UI. You can set a default policy by:
174
-
175
- 1. Create a draft policy in the RBAC UI that represents the policy that you would like to become the default policy.
176
- 1. Go to the draft policy page, and download the policy by clicking "Export." Alternatively, you can export any previous version or the active policy from the respective policy pages.
177
- 1. Add a `defaultPolicy` field under the `rbac` field in your `app-config.yaml`, and point it to the file you saved from the previous step:
178
-
179
- ```yaml
180
- permission:
181
- rbac:
182
- defaultPolicy:
183
- $include: ./default-rbac-policy.yaml
184
- ```
185
-
186
- 1. You should now see that your Backstage instance behaves as configured in your default policy, even though you have not yet authored any other policies using the RBAC UI.
187
-
188
- **NOTE:** The default policy will be active if and only if no other active policies already exist.
189
-
190
- ### Fallback policy
191
-
192
- By default, when a request to the RBAC backend fails, RBAC will automatically switch to denying all permissions. You can configure this behavior by specifying a fallback policy in your `app-config.yaml` in the exact same way as the default policy:
193
-
194
- ```yaml
195
- permission:
196
- rbac:
197
- fallbackPolicy:
198
- $include: ./fallback-rbac-policy.yaml
199
- ```
200
-
201
- ### Decision resolution strategy
202
-
203
- Multiple decisions from multiple roles could be applicable to a single user when authorizing a permission request. By default, the `any-allow` strategy will be selected for a new policy.
204
-
205
- You can change the decision resolution strategy for a policy and read more about the options by following the steps below:
206
-
207
- 1. Go to the draft policy page and click the `more options` icon on the top right.
208
- 2. Select `Options`.
209
- 3. Select which resolution strategy makes sense for your policy.
210
- 4. Click `Back to Policy` when you are done. Your policy will be automatically updated with your selection, and it will be saved and/or published when save and publish your policy.
211
-
212
- ### Policy tester
213
-
214
- The policy tester is designed to display simulated policy decisions for a given set of permissions, helping you ensure that the configured policy returns the expected decisions. For each [Permission](https://backstage.io/docs/permissions/concepts#permission) selected in the UI, the policy tester will output the decision that would be returned by the policy in question for a user assigned to all of the selected policy roles. If the given permission request requires certain conditions to be met, the policy tester will list exactly which conditions would be required.
215
-
216
- You can find the policy tester in the Policy page of any active, draft, or previous policies.
5
+ If you are already a customer, you can find detailed documentation about the RBAC Plugins [here](https://backstage.spotify.com/docs/rbac).
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spotify/backstage-plugin-rbac",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "main": "../dist/alpha.esm.js",
5
5
  "module": "../dist/alpha.esm.js",
6
6
  "types": "../dist/alpha.d.ts"
package/dist/alpha.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import{createApiExtension as r,createApiFactory as t,fetchApiRef as o,discoveryApiRef as a,createPageExtension as i,createPlugin as p}from"@backstage/frontend-plugin-api";import{a as c,R as f,r as n}from"./esm/routes-28afb55d.esm.js";import{convertLegacyRouteRef as m,compatWrapper as s}from"@backstage/core-compat-api";import R from"react";import"@backstage/core-plugin-api";import"@backstage/errors";import"@spotify/backstage-plugin-rbac-common";const A=r({factory:t({api:c,deps:{fetchApi:o,discoveryApi:a},factory:e=>new f(e)})}),l=i({routeRef:m(n),defaultPath:"/rbac",loader:()=>import("./esm/Root-5eafe743.esm.js").then(e=>s(R.createElement(e.RBACRoot,null)))});var u=p({id:"rbac",extensions:[l,A]});export{u as default};
1
+ import{createApiExtension as r,createApiFactory as t,fetchApiRef as o,discoveryApiRef as a,createPageExtension as i,createPlugin as p}from"@backstage/frontend-plugin-api";import{a as c,R as f,r as n}from"./esm/routes-28afb55d.esm.js";import{convertLegacyRouteRef as m,compatWrapper as s}from"@backstage/core-compat-api";import R from"react";import"@backstage/core-plugin-api";import"@backstage/errors";import"@spotify/backstage-plugin-rbac-common";const A=r({factory:t({api:c,deps:{fetchApi:o,discoveryApi:a},factory:e=>new f(e)})}),l=i({routeRef:m(n),defaultPath:"/rbac",loader:()=>import("./esm/Root-4f6e8190.esm.js").then(e=>s(R.createElement(e.RBACRoot,null)))});var u=p({id:"rbac",extensions:[l,A]});export{u as default};
2
2
  //# sourceMappingURL=alpha.esm.js.map
@@ -1,2 +1,2 @@
1
1
  import{useApi as i}from"@backstage/core-plugin-api";import e from"react";import u from"react-use/lib/useAsync";import{a as m}from"./routes-28afb55d.esm.js";function p({children:n,loading:l=null,unauthorized:o=null}){var r;const a=i(m),t=u(()=>a.authorize(),[]);return t.loading?e.createElement(e.Fragment,null,l):(r=t.value)!=null&&r.authorized?e.createElement(e.Fragment,null,n):e.createElement(e.Fragment,null,o)}export{p as A};
2
- //# sourceMappingURL=Authorized-2a69c12e.esm.js.map
2
+ //# sourceMappingURL=Authorized-d5c231d1.esm.js.map
@@ -1,2 +1,2 @@
1
- import{SidebarItem as e}from"@backstage/core-components";import m from"@material-ui/icons/Lock";import t from"react";import{A as i}from"./Authorized-2a69c12e.esm.js";import"@backstage/core-plugin-api";import"react-use/lib/useAsync";import"./routes-28afb55d.esm.js";import"@backstage/errors";import"@spotify/backstage-plugin-rbac-common";function p({text:r="RBAC",...o}){return t.createElement(i,null,t.createElement(e,{icon:m,to:"rbac",text:r,...o}))}export{p as RBACSidebarItem};
2
- //# sourceMappingURL=RBACSidebarItem-9beee132.esm.js.map
1
+ import{SidebarItem as e}from"@backstage/core-components";import m from"@material-ui/icons/Lock";import t from"react";import{A as i}from"./Authorized-d5c231d1.esm.js";import"@backstage/core-plugin-api";import"react-use/lib/useAsync";import"./routes-28afb55d.esm.js";import"@backstage/errors";import"@spotify/backstage-plugin-rbac-common";function p({text:r="RBAC",...o}){return t.createElement(i,null,t.createElement(e,{icon:m,to:"rbac",text:r,...o}))}export{p as RBACSidebarItem};
2
+ //# sourceMappingURL=RBACSidebarItem-0273da79.esm.js.map
@@ -0,0 +1,3 @@
1
+ import{Breadcrumbs as Gn,Link as ae,Page as jn,Header as _n,Content as Yn,Table as Jn,Progress as ke,ErrorPanel as Nt,EmptyState as Oe,ContentHeader as Be,UserIcon as qn}from"@backstage/core-components";import{useRouteRef as Kn,useApi as k,alertApiRef as oe,useApp as tt,configApiRef as Qn}from"@backstage/core-plugin-api";import e,{createContext as Le,useState as R,useCallback as I,useMemo as B,useContext as Me,Fragment as Fe,useRef as ye,useEffect as J,useLayoutEffect as Xn,Children as Pt,isValidElement as ze,useReducer as Zn}from"react";import{useNavigate as q,Link as er,useParams as nt,Routes as tr,Route as We}from"react-router-dom";import{A as nr}from"./Authorized-d5c231d1.esm.js";import{makeStyles as C,Typography as h,Container as rr,Grid as O,Button as P,Box as E,Dialog as ie,DialogTitle as He,DialogContent as ee,TextField as ce,DialogActions as rt,CircularProgress as Tt,Tooltip as ge,Chip as se,Card as te,CardContent as he,List as lr,ListItem as St,ListItemIcon as me,ListItemText as Q,CardActions as ar,IconButton as j,CardActionArea as or,CardHeader as At,Radio as ir,FormControl as ve,InputLabel as de,Select as be,Input as Rt,MenuItem as H,Checkbox as Ce,FormHelperText as lt,TableCell as D,TableContainer as cr,Table as Ue,TableHead as Ve,TableRow as U,TableBody as Ge,Accordion as sr,AccordionSummary as mr,AccordionDetails as dr,Paper as at,DialogContentText as ur,ButtonGroup as pr,Menu as $t,MenuList as ot,Divider as it,FormControlLabel as It,Popper as Er,Tabs as fr,Tab as yr,debounce as gr,ButtonBase as hr}from"@material-ui/core";import vr from"react-use/lib/useMount";import{SpotifyLicenseBanner as br,useAutoUpdatingRelativeTime as Cr,invariant as je}from"@spotify/backstage-plugin-core";import{r as xr,a as V}from"./routes-28afb55d.esm.js";import ue from"react-use/lib/useAsyncFn";import{PolicyConfigParser as _e,isConditionalDecision as Ye,isAllOfPermissionCriteria as wr,isAnyOfPermissionCriteria as Dr,isNotPermissionCriteria as Nr,getMatchingRolePermissions as kt,UpdateDraftRequestParser as Pr,isMatchingPermission as Tr,BackstageUserPlaceholder as xe,RoleParser as Sr}from"@spotify/backstage-plugin-rbac-common";import Ar,{dump as Rr}from"js-yaml";import $r from"@material-ui/icons/FilterNone";import Ir from"@material-ui/icons/Publish";import{DateTime as Je}from"luxon";import ct from"@material-ui/icons/Close";import we from"react-use/lib/useAsync";import Ot from"lodash/keyBy";import kr from"lodash/isEqual";import Or from"@material-ui/icons/CalendarToday";import Bt from"@material-ui/icons/Person";import Br from"@material-ui/icons/FiberManualRecord";import{v4 as pe}from"uuid";import{saveAs as Lr}from"file-saver";import Lt from"lodash/omit";import Mr from"lodash/pickBy";import Mt from"@material-ui/icons/ReportProblemOutlined";import Ft from"react-use/lib/useLocalStorage";import{isResourcePermission as st,AuthorizeResult as F}from"@backstage/plugin-permission-common";import{forEach as Fr,mapValues as zr,groupBy as Wr,uniq as Hr}from"lodash";import Ur from"@material-ui/icons/Check";import Vr from"@material-ui/icons/Edit";import Gr from"@material-ui/icons/Clear";import{Alert as zt,Autocomplete as mt,ToggleButton as jr,ToggleButtonGroup as _r}from"@material-ui/lab";import Yr from"@material-ui/icons/ExpandMore";import Jr from"@material-ui/icons/AccountTreeOutlined";import qr from"@material-ui/icons/CheckSharp";import Kr from"@material-ui/icons/NotInterested";import dt from"ajv";import Qr from"@material-ui/icons/InfoOutlined";import{z as Wt}from"zod";import ut from"@material-ui/icons/Add";import De from"@material-ui/icons/Delete";import Xr from"@material-ui/icons/KeyboardArrowDown";import Zr from"@material-ui/icons/KeyboardArrowUp";import Ht from"@material-ui/icons/Info";import el from"../images/no-roles.svg";import tl from"@material-ui/icons/MoreHoriz";import nl from"@material-ui/icons/Save";import rl from"@material-ui/icons/Settings";import ll from"@material-ui/icons/Undo";import al from"@material-ui/icons/VerticalAlignTop";import ol from"lodash/uniqBy";import il from"@material-ui/icons/Remove";import{parseEntityRef as ne,DEFAULT_NAMESPACE as cl}from"@backstage/catalog-model";import{humanizeEntityRef as sl,catalogApiRef as ml}from"@backstage/plugin-catalog-react";import{List as dl}from"react-virtualized";import ul from"@material-ui/icons/Group";import pl from"@material-ui/icons/GroupWork";import El from"../images/no-permissions.svg";import"@backstage/errors";const fl=C(t=>({breadcrumbs:{marginBottom:t.spacing(4)}}));function yl({pages:t}){const n=Kn(xr),r=fl();return e.createElement(Gn,{className:r.breadcrumbs},e.createElement(ae,{to:n()},"Home"),t.map(({title:a,path:l},o)=>l?e.createElement(ae,{to:l,key:l,relative:"path"},a):e.createElement(h,{key:`${o}`},a)))}function qe({children:t,header:n,pages:r}){return e.createElement(jn,{themeId:"tool"},e.createElement(br,{backend:"rbac",invalidLicenseMessage:"Your existing policy will continue to apply, but you will be unable to make any changes until you enter a valid license."}),e.createElement(_n,{title:"Role Based Access Control"}),e.createElement(Yn,null,e.createElement(rr,{maxWidth:"lg"},e.createElement(O,{container:!0,spacing:4},e.createElement(O,{item:!0,xs:12},r&&e.createElement(yl,{pages:r}),n),t))))}const Ut=Le({hasDraftPolicy:!1,policies:void 0,setPolicies:()=>{},setPolicy:()=>{},getPolicy:()=>{},removePolicy:()=>{}}),Ke=()=>Me(Ut);function gl({children:t,initialState:n={policies:void 0,cache:{}}}){const[r,a]=R(n),l=I(m=>{a(s=>({...s,policies:m,cache:Vt(s.cache,m)}))},[]),o=I(m=>r.cache[m],[r.cache]),i=I(m=>a(s=>({...s,cache:{...s.cache,[m]:void 0},policies:void 0})),[]),c=I(m=>a(s=>({...s,policies:void 0,cache:Vt(s.cache,[m])})),[]);return e.createElement(Ut.Provider,{value:B(()=>{var m;return{hasDraftPolicy:((m=r.policies)==null?void 0:m.some(({status:s})=>s==="draft"))||!1,policies:r.policies,setPolicies:l,setPolicy:c,getPolicy:o,removePolicy:i}},[r.policies,l,c,o,i])},t)}function Vt(t,n){if(!n)return t;const r={...t};return n.forEach(a=>{r[a.id]=a}),r}const Ne=()=>{const t=k(V),{setPolicies:n,policies:r}=Ke(),[{loading:a,error:l},o]=ue(()=>t.getPolicies(),[t],r?{loading:!1,value:{items:r,totalItems:r.length}}:{loading:!0}),i=I(async()=>{const c=await o();n(c.items)},[o,n]);return{loading:a,error:l,fetchPolicies:i}};function hl(){const t=k(V),n=q(),r=k(oe);function a(l){var o,i;const c=(i=(o=l.target)==null?void 0:o.files)==null?void 0:i[0],m=new FileReader;c&&(m.readAsText(c,"utf-8"),m.onload=async s=>{var p,u;const d=(u=(p=s.target)==null?void 0:p.result)==null?void 0:u.toString();if(d){let x=null;try{x=Ar.load(d)}catch{r.post({message:"YAML file is invalid",severity:"error"});return}const f=_e.safeParse(x);if(!f.success){r.post({message:"Imported policy is invalid",severity:"error"});return}const y=f.data;if((await t.getPolicies()).items.some(w=>w.status==="draft")){r.post({message:"Unable to import new policy due to existing draft policy",severity:"error"});return}const g=await t.createDraft(y);n(`./versions/${g.id}`),r.post({message:"Policy imported successfully",severity:"success"})}})}return e.createElement(P,{variant:"outlined",color:"primary",component:"label"},"Import",e.createElement("input",{role:"input",type:"file",hidden:!0,onChange:a,accept:".yaml"}))}function vl(t){throw new Error("Invalid state")}function bl(t){var n;return Ye(t.decision)?"Conditional":(n={allow:"Allow",deny:"Deny"}[t.decision])!=null?n:"Unknown"}function pt(t){var n;if(t.match==="*")return"All";if(t.match.name)return t.match.name;const r=[];return t.match.resourceType&&r.push(t.match.resourceType),(n=t.match.actions)!=null&&n.length&&r.push(t.match.actions.join(", ")),r.join(" | ")}const Cl=(t,n)=>{const r={resolutionStrategy:{operation:"UNCHANGED",before:t==null?void 0:t.resolutionStrategy,after:n==null?void 0:n.resolutionStrategy}};for(const a of Object.keys(r)){const l=a;r[l].before!==r[l].after&&(r[l].operation="CHANGED")}return r},Et=(t,n)=>{const r=Object.entries(t);for(const[,a]of r){const l=n(a);for(const[,o]of r){const i=n(o);i.operation!=="ADDED"&&i.operation!=="REMOVED"&&(l.operation==="ADDED"&&l.indexAfter<i.indexAfter?i.indexBefore+=1:l.operation==="REMOVED"&&l.indexBefore<i.indexBefore&&(i.indexBefore-=1))}}for(const[,a]of r){const l=n(a);l.operation==="UNCHANGED"&&l.indexAfter!==l.indexBefore&&(l.operation=l.indexAfter>l.indexBefore?"MOVED_DOWN":"MOVED_UP")}return t},ft=(t,n)=>{if(t==="*")return n==="*"?{"*":{operation:"UNCHANGED",after:"*",before:"*",indexAfter:0,indexBefore:0}}:{"*":{operation:"REMOVED",after:null,before:"*",indexAfter:-1,indexBefore:0},...Object.fromEntries(n.map((a,l)=>[a,{operation:"ADDED",after:a,before:null,indexAfter:l,indexBefore:-1}]))};if(n==="*")return{"*":{operation:"ADDED",after:"*",before:null,indexAfter:0,indexBefore:-1},...Object.fromEntries(t.map((a,l)=>[a,{operation:"REMOVED",after:null,before:a,indexAfter:-1,indexBefore:l}]))};const r=Object.fromEntries(n.map((a,l)=>[a,{operation:"ADDED",after:a,before:null,indexAfter:l,indexBefore:-1}]));for(let a=0;a<t.length;a++){const l=t[a];r[l]?(r[l].before=l,r[l].indexBefore=a,r[l].operation="UNCHANGED"):r[l]={operation:"REMOVED",after:null,before:l,indexAfter:-1,indexBefore:a}}return Et(r,a=>a)},yt=(t,n)=>{const r=Ot(n,"id"),a=Object.fromEntries(n.map((l,o)=>[l.id,{operation:"ADDED",indexAfter:o,indexBefore:-1,after:l,before:null}]));for(let l=0;l<t.length;l++){const o=t[l];if(a[o.id]){const i=!kr(o,r[o.id]);a[o.id].before=o,a[o.id].indexBefore=l,a[o.id].operation=i?"CHANGED":"UNCHANGED"}else a[o.id]={operation:"REMOVED",after:null,before:o,indexAfter:-1,indexBefore:l}}return Et(a,l=>l)},xl=(t=[],n=[])=>{const r=Ot(n,"id"),a=Object.fromEntries(n.map((l,o)=>[l.id,{role:{operation:"ADDED",indexAfter:o,indexBefore:-1,after:l,before:null},members:ft([],l.members),permissions:yt([],l.permissions)}]));for(let l=0;l<t.length;l++){const o=t[l];if(r[o.id]){const i=r[o.id],c=ft(o.members,i.members),m=yt(o.permissions,i.permissions),s=Object.values(m).some(({operation:d})=>d!=="UNCHANGED"),p=Object.values(c).some(({operation:d})=>d!=="UNCHANGED"),u=o.name!==i.name||s||p;a[o.id].role.before=o,a[o.id].role.indexBefore=l,a[o.id].role.operation=u?"CHANGED":"UNCHANGED",a[o.id].members=c,a[o.id].permissions=m}else a[o.id]={role:{operation:"REMOVED",after:null,before:o,indexAfter:-1,indexBefore:l},members:ft(o.members,[]),permissions:yt(o.permissions,[])}}return Et(a,({role:l})=>l)},wl=(t,n)=>{const r=xl((t==null?void 0:t.roles)||[],n.roles||[]),a=Cl(t==null?void 0:t.options,n.options),l=(t==null?void 0:t.name)!==n.name,o=Object.values(a).some(({operation:i})=>i!=="UNCHANGED");return{policy:{operation:l||o?"CHANGED":"UNCHANGED",before:t,after:n},roles:r,options:a}},Gt=t=>{const n=k(V),{value:r,loading:a,error:l}=we(()=>n.getActivePolicy(),[n]);return B(()=>t&&!a&&!l?wl(r,t):null,[r,t,a,l])},Dl=(t,n)=>{switch(n){case"ADDED":return t.palette.success.main;case"REMOVED":return t.palette.errorText;case"CHANGED":return t.palette.infoText;case"MOVED_UP":case"MOVED_DOWN":return t.palette.infoText;case"UNCHANGED":default:return t.palette.text.primary}},Nl=t=>{switch(t){case"ADDED":return"success";case"REMOVED":return"error";case"CHANGED":return"info";case"MOVED_UP":case"MOVED_DOWN":return"info";case"UNCHANGED":default:return"info"}},Pl=t=>{switch(t){case"ADDED":return"New";case"REMOVED":return"Removed";case"CHANGED":return"Changed";case"MOVED_UP":return"Moved up";case"MOVED_DOWN":return"Moved down";case"UNCHANGED":default:return"No changes"}},Tl=C(t=>({root:({operation:n})=>({color:Dl(t,n)})})),W=t=>e.createElement(h,{...t,variant:"body2"}),N=t=>{const n=Tl(t);return e.createElement(E,{...t,className:n.root,component:"span",fontWeight:"fontWeightBold"})},jt=({policy:t})=>{var n,r,a,l;const o=Gt(t),i=(o==null?void 0:o.policy.operation)==="CHANGED"||Object.values((n=o==null?void 0:o.roles)!=null?n:{}).some(u=>u.role.operation!=="UNCHANGED")||((r=o==null?void 0:o.options)==null?void 0:r.resolutionStrategy.operation)==="CHANGED";if(!o||!i)return e.createElement(E,null,"No changes");const c=!!o.policy.before&&!!o.policy.after&&o.policy.before.name!==o.policy.after.name,m=o.options.resolutionStrategy.operation==="CHANGED",s=({before:u,after:d})=>u&&d&&u.name!==d.name,p=({operation:u})=>u!=="ADDED"&&u!=="REMOVED";return e.createElement(E,null,c&&e.createElement(W,null,"Policy name ",e.createElement(N,{operation:"CHANGED"},"changed")," from"," ",e.createElement(N,null,'"',(a=o.policy.before)==null?void 0:a.name,'"')," to"," ",e.createElement(N,null,'"',(l=o.policy.after)==null?void 0:l.name,'"')),m&&e.createElement(W,null,"Resolution Strategy ",e.createElement(N,{operation:"CHANGED"},"changed")," ","from ",e.createElement(N,null,'"',o.options.resolutionStrategy.before,'"')," to"," ",e.createElement(N,null,'"',o.options.resolutionStrategy.after,'"')),Object.entries(o.roles).map(([u,{role:d,permissions:x,members:f}])=>{var y,g,w,S,T,z;return e.createElement(Fe,{key:u},d.operation==="ADDED"&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(y=d.after)==null?void 0:y.name,'"')," has been"," ",e.createElement(N,{operation:"ADDED"},"added")),d.operation==="REMOVED"&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(g=d.before)==null?void 0:g.name,'"')," has been"," ",e.createElement(N,{operation:"REMOVED"},"removed")),s(d)&&e.createElement(W,null,"Role name changed from ",e.createElement(N,null,'"',(w=d.before)==null?void 0:w.name,'"')," ","to ",e.createElement(N,null,'"',(S=d.after)==null?void 0:S.name,'"')),d.indexAfter>d.indexBefore&&d.indexBefore!==-1&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(T=d.after)==null?void 0:T.name,'"')," has been"," ",e.createElement(N,{operation:"MOVED_DOWN"},"moved down")," in priority"),d.indexAfter<d.indexBefore&&d.indexAfter!==-1&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(z=d.after)==null?void 0:z.name,'"')," has been"," ",e.createElement(N,{operation:"MOVED_UP"},"moved up")," in priority"),p(d)&&e.createElement(e.Fragment,null,Object.entries(x).map(([M,b])=>{var A,v,$,L,re;const{before:X,after:Ee}=b,le=X&&pt(X),Z=Ee&&pt(Ee);return e.createElement(Fe,{key:M},b.operation==="ADDED"&&b.after&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',Z,'"')," has been"," ",e.createElement(N,{operation:"ADDED"},"added")," to"," ",e.createElement(N,null,'"',(A=d.after)==null?void 0:A.name,'"')),b.operation==="REMOVED"&&b.before&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',le,'"')," has been"," ",e.createElement(N,{operation:"REMOVED"},"removed")," ","from ",e.createElement(N,null,'"',(v=d.after)==null?void 0:v.name,'"')),b.operation==="CHANGED"&&e.createElement(W,null,le!==Z?e.createElement(e.Fragment,null,"Permission decision"," ",e.createElement(N,null,'"',le,'"')," has been"," ",e.createElement(N,{operation:"CHANGED"},"updated")," ","to ",e.createElement(N,null,'"',Z,'"')):e.createElement(e.Fragment,null,"Permission decision"," ",e.createElement(N,null,'"',le,'"')," has been"," ",e.createElement(N,{operation:"CHANGED"},"updated"))," ","in ",e.createElement(N,null,'"',($=d.after)==null?void 0:$.name,'"')),b.indexAfter>b.indexBefore&&b.indexBefore!==-1&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',Z,'"')," has been"," ",e.createElement(N,{operation:"MOVED_DOWN"},"moved down")," ","in priority in"," ",e.createElement(N,null,'"',(L=d.after)==null?void 0:L.name,'"')),b.indexAfter<b.indexBefore&&b.indexAfter!==-1&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',Z,'"')," has been"," ",e.createElement(N,{operation:"MOVED_UP"},"moved up")," ","in priority in"," ",e.createElement(N,null,'"',(re=d.after)==null?void 0:re.name,'"')))}),Object.entries(f).map(([M,b])=>{var A,v;return e.createElement(Fe,{key:M},b.operation==="ADDED"&&b.after&&e.createElement(W,null,"Member ",e.createElement(N,null,'"',b.after,'"')," has been"," ",e.createElement(N,{operation:"ADDED"},"added")," to"," ",e.createElement(N,null,'"',(A=d.after)==null?void 0:A.name,'"')),b.operation==="REMOVED"&&b.before&&e.createElement(W,null,"Member ",e.createElement(N,null,'"',b.before,'"')," has been"," ",e.createElement(N,{operation:"REMOVED"},"removed")," from"," ",e.createElement(N,null,'"',(v=d.after)==null?void 0:v.name,'"')))})))}))},Sl=C(t=>({closeButton:{color:t.palette.text.secondary},diffSummaryContainer:{backgroundColor:t.palette.background.default,marginBottom:t.spacing(2)}}));function gt({open:t,onPublish:n,onClose:r,policy:a}){const[l,o]=R(!1),i=Sl(),c=ye(null),m=async()=>{var s,p;o(!0),await n((p=(s=c.current)==null?void 0:s.value)!=null?p:""),o(!1)};return e.createElement(ie,{open:t,onClose:r,fullWidth:!0},e.createElement(He,null,e.createElement(E,{display:"flex",justifyContent:"space-between",alignItems:"center"},"Ready to publish?",e.createElement(P,{startIcon:e.createElement(ct,null),onClick:r,className:i.closeButton},"Close")),e.createElement(h,null,"Double check your changes, then click Publish to activate this version of your policy. This will immediately apply the permissions defined in this version across Backstage.")),e.createElement(ee,{className:i.diffSummaryContainer,dividers:!0},e.createElement(jt,{policy:a})),e.createElement(ee,null,e.createElement(ce,{variant:"outlined",fullWidth:!0,label:"Summary (optional)",placeholder:"Briefly describe this version (or changes from a previous version)",inputRef:c})),e.createElement(rt,null,e.createElement(P,{color:"primary",onClick:m,disabled:l},l?e.createElement(Tt,{size:20}):"Publish")))}const Al=C(()=>({root:{display:"inline-flex"}})),_t=({timestamp:t,description:n})=>{const r=Al(),a=Je.fromISO(t).toLocaleString(Je.DATETIME_FULL),l=Cr(t),o=n?`${n}${l}`:l;return e.createElement("span",{className:r.root},e.createElement(ge,{title:a},e.createElement(h,{component:"span",display:"inline",variant:"inherit"},o)))};function Yt(t,n,r){var a,l;let o=n.created,i=t.createdBy;r!=null&&r.created&&(i=r.created+i);let c=t.createdAt;return t.status==="active"?(o=n.published,i=(a=t.lastPublishedBy)!=null?a:"",r!=null&&r.published&&(i=r.published+i),c=(l=t.lastPublishedAt)!=null?l:""):t.createdAt!==t.updatedAt&&(o=n.updated,i=t.updatedBy,r!=null&&r.updated&&(i=r.updated+i),c=t.updatedAt),{activityDateText:o,activityUser:i,timestamp:c}}const Rl=C(t=>({chip:{margin:0},icon:{color:t.palette.success.main}}));function Jt(t){const n=Rl();return t.status==="inactive"?null:t.status==="draft"?e.createElement(se,{className:n.chip,label:"Draft",size:t.size}):e.createElement(se,{className:n.chip,classes:{icon:n.icon},label:"Active",icon:e.createElement(Br,null),size:t.size})}const $l=C(t=>({card:n=>({backgroundImage:n.policy.status==="active"?"linear-gradient(256.15deg, #00782A 19.77%, #1DB954 100%)":"linear-gradient(256.15deg, #BDBDBD 19.77%, #EEEEEE 100%)",backgroundPosition:"top",backgroundSize:"100% 8px",backgroundRepeat:"no-repeat",paddingTop:"8px",height:"100%"}),diffSummaryContainer:{backgroundColor:t.palette.background.default,padding:t.spacing(2),borderWidth:"1px",borderStyle:"solid",borderColor:t.palette.divider,borderRadius:t.shape.borderRadius},header:{display:"flex",justifyContent:"space-between",alignItems:"center"},detailsHeader:{...t.typography.body1,paddingTop:t.spacing(2),color:t.palette.text.secondary},activityList:{color:t.palette.text.secondary},activityListItem:{padding:0},actions:{justifyContent:"flex-start"}}));function Pe(t){const n=$l(t),{policy:r,to:a,withChangeSummary:l}=t,o=`${r.name} ${r.status==="draft"?"- Draft":""}`,i={created:"Created: ",published:"Published: ",updated:"Updated: "},c={created:"Created by ",published:"Published by ",updated:"Updated by "},{activityDateText:m,activityUser:s,timestamp:p}=Yt(r,i,c);return e.createElement(te,{className:n.card},e.createElement(he,null,e.createElement("div",{className:n.header},a?e.createElement(ae,{to:`versions/${r.id}`},e.createElement(h,{variant:"h5",component:"h1"},o)):e.createElement(h,{variant:"h5",component:"h1"},o),r.status==="active"?e.createElement(Jt,{status:"active",size:"small"}):null),r.description?e.createElement(h,{variant:"body1",color:"textSecondary"},'"',r.description,'"'):null,e.createElement(h,{component:"h2",className:n.detailsHeader},"Details"),e.createElement(lr,{className:n.activityList},e.createElement(St,{className:n.activityListItem},e.createElement(me,null,e.createElement(Or,null)),e.createElement(Q,{primary:e.createElement(_t,{timestamp:p,description:m})})),e.createElement(St,{className:n.activityListItem},e.createElement(me,null,e.createElement(Bt,null)),e.createElement(Q,{primary:s}))),l&&e.createElement(E,{paddingTop:2},e.createElement(h,{gutterBottom:!0,variant:"subtitle2"},"What's changed"),e.createElement(E,{className:n.diffSummaryContainer},e.createElement(jt,{policy:r})))),t.actions?e.createElement(ar,{className:n.actions},t.actions):null)}const Il=C(t=>({paper:{padding:t.spacing(2,2,0,2)}})),ht=({isOpen:t,onClose:n,policy:r})=>{const a=Il();return e.createElement(ie,{classes:{...a},open:t,onClose:n},e.createElement(He,{disableTypography:!0},e.createElement(E,{display:"flex",flexDirection:"row"},e.createElement(E,null,e.createElement(h,{variant:"h4",component:"h2"},"Success!"),e.createElement(h,null,r.name," has been published and is now your active policy.")),e.createElement(E,null,e.createElement(j,{onClick:n,title:"Close dialog"},e.createElement(ct,null))))),e.createElement(ee,null,e.createElement(Pe,{policy:r})),e.createElement(rt,null,e.createElement(E,{display:"flex",flexDirection:"row",flexGrow:1,justifyContent:"flex-start"},e.createElement(P,{component:er,color:"primary",onClick:n,role:"link",to:"/rbac"},"View all versions"))))};function vt(){const t=k(V),n=k(oe),r=q(),{fetchPolicies:a}=Ne();return ue(async l=>{if(!l)return;const{roles:o,name:i,options:c}=l;try{const m=await t.createDraft({roles:o,options:c,name:i});return await a(),r(`/rbac/versions/${m.id}`),m}catch(m){throw m instanceof Error&&n.post({message:m.message,severity:"error"}),m}},[r,t,n,a])}function bt(){const t=k(V),n=k(oe),r=ue(async(l,o,i)=>{if(l)return await t.publishPolicy(l.id,{description:o,update:i}),t.getPolicy(l.id)},[]),[{error:a}]=r;return J(()=>{a&&n.post({message:a.message,severity:"error"})},[a,n]),r}const kl=[{title:"Name",field:"name",render:t=>e.createElement(ae,{to:`versions/${t.id}`},t.name)},{title:"Status",field:"status",render:t=>{switch(t.status){case"active":return"Active";case"draft":return"Draft";case"inactive":return"Inactive";default:return vl(t.status)}}},{title:"Publish date",field:"lastPublishedAt",render:t=>t.lastPublishedAt?Je.fromISO(t.lastPublishedAt).toLocaleString(Je.DATETIME_MED_WITH_SECONDS):"",type:"datetime",defaultSort:"desc"},{title:"Published by",field:"lastPublishedBy"}];function Ol(t){const n=t.data.length>3,{fetchPolicies:r}=Ne(),[{loading:a},l]=vt(),[{loading:o,value:i},c]=bt(),[m,s]=R(void 0),[p,u]=R(!1),d=()=>{s(void 0),r()},x=(m==null?void 0:m.id)===(i==null?void 0:i.id)?i:void 0,f=[y=>{const{tableData:g,...w}=y;return{icon:Ir,tooltip:"Republish",onClick:()=>{s(w),u(!0)},disabled:o}},y=>{const{tableData:g,...w}=y;return{icon:$r,tooltip:"Duplicate",disabled:a||!t.canDuplicate,onClick:()=>l(w)}}];return e.createElement(e.Fragment,null,e.createElement(Jn,{title:"Previous Versions",columns:kl,data:t.data,options:{paging:n,pageSize:3,pageSizeOptions:[3,5,10,20],actionsColumnIndex:-1,loadingType:"linear"},actions:f}),m&&e.createElement(gt,{open:p,onPublish:y=>{c(m,y),u(!1)},onClose:()=>{s(void 0),u(!1)},policy:m}),x&&e.createElement(ht,{isOpen:!0,policy:x,onClose:d}))}function Bl(t){var n,r;return((r=(n=t==null?void 0:t.body)==null?void 0:n.response)==null?void 0:r.statusCode)===404}function qt(t){const n=new Blob([Ll(t)],{type:"text/yaml"});Lr(n,`${(t.name||"policy").toLocaleLowerCase().replace(/\W/g,"-")}.yaml`)}function Ll(t){const{name:n,roles:r,options:a,description:l}=t;return`# this is an autogenerated file, do not edit
2
+ ${Rr(Mr({name:n,description:l,options:a,roles:r.map(({permissions:o,...i})=>({...Lt(i,["id"]),permissions:o.map(c=>Lt(c,["id"]))}))},o=>o!==null||o!==void 0))}`}const Ml=({serverPolicy:t,localPolicy:n})=>!n||!t?{policy:t,policyConflict:!1}:t.status!=="draft"?{policy:t,policyConflict:!1}:n.id!==t.id?{policy:t,policyConflict:!1}:n.updatedAt===t.updatedAt?{policy:n,policyConflict:!1}:{policy:n,policyConflict:!0},Fl=C(t=>({icon:{color:t.palette.warning.main,width:"2rem",height:"2rem"},label:{align:"center",display:"block",marginBottom:t.spacing(1),color:t.palette.text.secondary,fontSize:t.typography.caption.fontSize},policiesContainer:{display:"flex",gap:t.spacing(4),marginTop:t.spacing(4),marginBottom:t.spacing(4)},button:{marginTop:t.spacing(4)}})),zl=({localPolicy:t,onSelectLocalPolicy:n,onSelectServerPolicy:r,serverPolicy:a})=>{const l=Fl();return e.createElement(ie,{open:!0,maxWidth:"md"},e.createElement(ee,null,e.createElement(E,{display:"flex",flexDirection:"column",gridGap:8},e.createElement(E,{display:"flex",justifyContent:"center"},e.createElement(Mt,{className:l.icon})),e.createElement(h,{align:"center",variant:"h6"},"There is a conflict with your drafts"),e.createElement(E,null,e.createElement(h,{align:"center"},"A newer version of the draft you are trying to edit has been recently saved."),e.createElement(h,{align:"center"},"Please review the changes and decide on a version to keep."))),e.createElement(E,{className:l.policiesContainer},e.createElement(E,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%"},e.createElement(h,{className:l.label,variant:"button"},"Your local draft"),e.createElement(Pe,{policy:t,withChangeSummary:!0}),e.createElement(P,{className:l.button,color:"primary",onClick:n,variant:"outlined"},"Keep local draft")),e.createElement(E,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%"},e.createElement(h,{className:l.label,variant:"button"},"Recently saved draft"),e.createElement(Pe,{policy:a,withChangeSummary:!0}),e.createElement(P,{className:l.button,color:"primary",onClick:r,variant:"outlined"},"Keep recently saved draft")))))},Wl=C(t=>({icon:{color:t.palette.warning.main,width:"2rem",height:"2rem"}})),Hl=({onConfirm:t,policy:n})=>{const r=Wl(),a=()=>{qt(n)};return e.createElement(ie,{open:!0},e.createElement(ee,null,e.createElement(E,{display:"flex",flexDirection:"column",gridGap:16},e.createElement(E,{display:"flex",flexDirection:"column",gridGap:4},e.createElement(E,{display:"flex",justifyContent:"center"},e.createElement(Mt,{className:r.icon})),e.createElement(h,{align:"center",variant:"h6"},"Invalid local draft")),e.createElement(E,{display:"flex",flexDirection:"column",gridGap:8},e.createElement(h,{align:"center"},"You have a local draft that is no longer compatible or has become corrupted."),e.createElement(h,{align:"center"},"Click export to download your draft. You can attempt to restore your draft by importing this file on the RBAC home page."),e.createElement(h,{align:"center"},"Clicking continue will discard your draft."," ",e.createElement(E,{component:"span",fontWeight:"fontWeightBold"},"This action cannot be undone."))),e.createElement(E,{display:"flex",justifyContent:"center",gridGap:8,marginY:3},e.createElement(P,{color:"primary",onClick:a,variant:"outlined"},"Export"),e.createElement(P,{color:"primary",onClick:t,variant:"contained"},"Discard and continue")))))},Ul=()=>Ft("@spotify/backstage-plugin-rbac:draftPolicy"),Vl={canPublish:!1,diff:null,hasChanges:!1,isValid:!1,policy:void 0,createNewRole:()=>"",discardLocalDraft:()=>{},exportPolicy:()=>{},publish:()=>{},saveLocalDraftToServer:()=>Promise.reject(),saveAndPublish:()=>Promise.reject(),refetchPolicy:()=>Promise.reject(),updateLocalDraft:()=>{}},Kt=Le(Vl),_=()=>Me(Kt);function Qe({children:t,policyId:n}){const r=q(),a=k(oe),l=k(V),{getPolicy:o,setPolicy:i}=Ke(),c=tt(),{NotFoundErrorPage:m}=c.getComponents(),[s,p]=R({active:!1,update:!1}),[u,d]=R(!1),[{loading:x,value:f},y]=bt(),g=o(n),[w,S,T]=Ul(),z=!w||_e.safeParse(w).success,M=z?w:void 0,{policy:b,policyConflict:A}=Ml({serverPolicy:g,localPolicy:M}),v=Gt(b),$=_e.safeParse(b).success,L=$&&!M&&!x,[{loading:re,error:X},Ee]=ue(()=>l.getPolicy(n),[l,n],g?{loading:!1,value:g}:{loading:!0}),le=()=>{p({active:!0,update:!1})},Z=()=>{p({active:!0,update:!0})},K=I(async()=>{const G=await Ee();i(G)},[Ee,i]),Bn=I(async G=>{await y(b,G,s.update?b:void 0),p({active:!1,update:!1}),K==null||K()},[b,s,y,p,K]),Ln=async()=>{d(!1)},Mn=()=>{S(G=>G&&g&&{...G,updatedAt:g.updatedAt})},Fn=I(async()=>{if(!b)throw new Error("No policy to save");try{await l.updateDraft(b.id,{name:b.name,roles:b.roles,options:b.options}),a.post({message:"Policy saved",severity:"success"}),T(),K==null||K()}catch(G){a.post({message:(G==null?void 0:G.message)||"An error occurred while updating the policy",severity:"error"})}},[a,l,b,K,T]),zn=I(()=>{if(!b)throw new Error("No policy to create a new role");const G=new Set(b.roles.map(Vn=>Vn.id));let fe;do fe=pe().split("-")[0];while(G.has(fe));const Un={name:`Role ${fe}`,permissions:[],members:"*",id:fe};return S({...b,roles:[...b.roles,Un]}),fe},[b,S]),Wn=()=>{T(),r("/rbac")},Hn=()=>{b&&qt(b)};return J(()=>{g||K()},[K,g]),J(()=>{f&&d(!0)},[f]),z?b?e.createElement(Kt.Provider,{value:{canPublish:L,diff:v,hasChanges:!!M,isValid:$,policy:b,createNewRole:zn,discardLocalDraft:T,exportPolicy:Hn,publish:le,saveLocalDraftToServer:Fn,refetchPolicy:K,updateLocalDraft:S,saveAndPublish:Z}},A&&M&&g&&e.createElement(zl,{localPolicy:M,onSelectLocalPolicy:Mn,onSelectServerPolicy:T,serverPolicy:g}),e.createElement(gt,{open:s.active,onClose:()=>p({active:!1,update:!1}),onPublish:Bn,policy:b}),f&&e.createElement(ht,{isOpen:u,onClose:Ln,policy:f}),t):re?e.createElement(ke,null):X?Bl(X)?e.createElement(m,null):e.createElement(Nt,{error:X!=null?X:new Error("Unknown")}):null:e.createElement(Hl,{onConfirm:Wn,policy:w})}const Gl=t=>{const[n,r]=R(!1),{fetchPolicies:a}=Ne(),[{loading:l,value:o},i]=bt(),{policy:c,hasChanges:m}=_(),s=_e.safeParse(c).success,p=!m&&s,u=async x=>{await i(c,x),r(!1)},d=()=>{a()};return e.createElement(e.Fragment,null,e.createElement(P,{...t,onClick:()=>r(!0),disabled:!p||l},"Publish"),e.createElement(gt,{open:n,onClose:()=>r(!1),onPublish:u,policy:c}),o&&e.createElement(ht,{isOpen:!0,onClose:d,policy:o}))};function jl(t){const n=k(V),r=k(oe),{fetchPolicies:a}=Ne();return ue(async()=>{if(t)return n.deleteDraft(t.id).then(a).catch(l=>(r.post({message:l.message,severity:"error"}),Promise.reject(l)))},[t])}function _l({policies:t}){const n=t.find(s=>s.status==="draft"),r=t.find(s=>s.status==="active"),[a,l]=vt(),[o,i]=jl(n),c=q(),m=Yl(t);return e.createElement(O,{container:!0,spacing:4},r?e.createElement(O,{item:!0,xs:12,md:6},e.createElement(Pe,{policy:r,to:`./versions/${r.id}`,actions:e.createElement(P,{color:"primary",disabled:a.loading||!!n,onClick:()=>l(r)},"Duplicate")})):null,n?e.createElement(O,{item:!0,xs:12,md:6},e.createElement(Pe,{policy:n,to:`./versions/${n.id}`,actions:e.createElement(e.Fragment,null,e.createElement(P,{onClick:()=>c(`versions/${n.id}`),color:"primary"},"Edit"),e.createElement(P,{color:"primary",disabled:o.loading,onClick:i},"Delete Draft"),e.createElement(Qe,{policyId:n.id},e.createElement(Gl,{color:"primary"})))})):null,e.createElement(O,{item:!0,xs:12},e.createElement(Ol,{data:m,canDuplicate:!n})))}function Yl(t){return t.filter(({status:n})=>n==="inactive")}const Jl=C(t=>({cardContent:{padding:t.spacing(6,3),"& > *":{background:"transparent"}}}));function ql(){const t=Jl(),n=k(V),r=q(),[a,l]=ue(async()=>n.createDraft({roles:[],options:{resolutionStrategy:"any-allow"}}),[n]);return J(()=>{a.value&&r(`./versions/${a.value.id}`)},[r,a.value]),e.createElement(te,null,e.createElement(he,{className:t.cardContent},e.createElement(Oe,{missing:"content",title:"No policy configured",description:e.createElement(e.Fragment,null,e.createElement(E,{component:"span",display:"block",pb:2},"Until you've configured your policy, authorization will be denied for all permissions."),e.createElement(E,{component:"span",display:"block"},"Click the button below to create the first version of your policy.")),action:e.createElement(P,{variant:"contained",color:"primary",disabled:a.loading,onClick:l},"New version")})))}function Kl(){const{policies:t}=Ke(),{loading:n,error:r,fetchPolicies:a}=Ne();vr(()=>{t||a()});let l;return n?l=e.createElement(O,{item:!0,xs:12},e.createElement(ke,null)):r?l=e.createElement(Nt,{error:r}):!t||t.length===0?l=e.createElement(ql,null):l=e.createElement(_l,{policies:t}),e.createElement(qe,{pages:void 0,header:e.createElement(Be,{title:"RBAC Policies"},e.createElement(hl,null))},l)}const Qt=Le({loading:!1}),Ql=({children:t})=>{const n=k(V),r=we(async()=>await n.searchMembers({query:""}),[n]);return e.createElement(Qt.Provider,{value:r},t)},Xl=()=>Me(Qt),Xt=Le(null),Zl=({children:t})=>{const n=k(Qn),r=k(V),a=k(oe),[l,o]=R(null),i=I(async()=>{var c;if(!l){const m=await r.fetchAllPermissionMetadata((c=n.getOptionalStringArray("permission.permissionedPlugins"))!=null?c:[]),s=ta(m.rules);Fr(s,u=>{u.length!==1&&a.post({message:`The plugin(s) ${u.slice(1).join(", ")} expose rules which are conflicting with rules exposed by the ${u[0]} plugin. These rules will not be available for use. Please contact RBAC support if you need assistance resolving this issue.`,severity:"error"})});const p=na(m,s);return o(p),p}return l},[a,l,r,n]);return e.createElement(Xt.Provider,{value:B(()=>({getMetadata:i}),[i])},t)};function Xe(){const t=Me(Xt),{value:n,loading:r}=we(async()=>t==null?void 0:t.getMetadata(),[t]);return{metadata:n,isLoading:r}}function Zt(){var t;const{metadata:n}=Xe();return(t=n==null?void 0:n.rules)!=null?t:null}function Te(){var t;const{metadata:n,isLoading:r}=Xe();return{permissions:(t=n==null?void 0:n.permissions)!=null?t:null,isLoading:r}}function en(){const{metadata:t}=Xe();return t?[...new Set(t.permissions.filter(n=>st(n)).map(({resourceType:n})=>n))]:null}function ea(){const{metadata:t}=Xe(),n=en();return!t||!n?null:n.reduce((r,a)=>{const l=t.rules.find(o=>o.resourceType===a);return l&&(r[a]={pluginId:l.pluginId}),r},{})}function ta(t){return zr(Wr(t,"resourceType"),n=>Hr(n.map(({pluginId:r})=>r)))}function na(t,n){return{...t,rules:t.rules.filter(({resourceType:r,pluginId:a})=>{const l=n[r];return a===l[0]})}}const ra=C(t=>({card:n=>({marginTop:t.spacing(3),height:"100%","&:hover":n.readonly?{pointerEvents:"none"}:{}}),cardHeader:{paddingBottom:t.spacing(2),alignItems:"flex-start"},defaultChip:{marginLeft:t.spacing(1),marginBottom:0},title:{display:"flex",alignItems:"center",paddingTop:t.spacing(.5),paddingBottom:t.spacing(1)}}));function tn(t){const n=ra(t),{title:r,description:a,active:l,changeResolutionStrategy:o,defaultOption:i,readonly:c}=t,m=()=>{c||o()};return e.createElement(te,{className:`${n.card}`,onClick:m},e.createElement(or,{disabled:c},e.createElement(he,null,e.createElement(At,{className:n.cardHeader,avatar:e.createElement(ir,{checked:l,color:"primary",disabled:c}),title:e.createElement("div",{className:n.title},e.createElement(h,{variant:"h6",component:"h2"},r),i?e.createElement(se,{label:"Default",size:"small",className:n.defaultChip}):null),subheader:a}))))}const la=C(t=>({title:{display:"flex",alignItems:"center",paddingBottom:t.spacing(2)},maxWidthWrapper:{maxWidth:"800px"},readOnlyChip:{marginLeft:t.spacing(1)},paragraph:{paddingBottom:t.spacing(1)}}));function aa(){const{versionId:t}=nt();return je(t),e.createElement(Qe,{policyId:t},e.createElement(oa,null))}function oa(){const t=la(),{policy:n,updateLocalDraft:r}=_(),a=q(),l=n.status!=="draft",o=i=>{r({...n,options:{...n.options,resolutionStrategy:i}})};return e.createElement(qe,{pages:[{title:n.name,path:".."},{title:"Options"}],header:e.createElement(Be,{title:"Options"},e.createElement(P,{variant:"outlined",color:"primary",onClick:()=>a("..",{relative:"path"})},"Back to policy"))},e.createElement(O,{item:!0,xs:12,className:t.maxWidthWrapper},e.createElement("div",null,e.createElement("div",{className:t.title},e.createElement(h,{variant:"h5",component:"h1"},"Decision resolution strategy"),l?e.createElement(se,{label:"Read only",className:t.readOnlyChip}):null),e.createElement(h,{variant:"body2",component:"p",className:t.paragraph},"Multiple decisions from multiple roles could be applicable to a single user when authorizing a permission request. Please select the decision resolution strategy that makes sense for your policy."),e.createElement(h,{variant:"body2",component:"p",className:t.paragraph},"Please note this strategy will be applied to the whole policy and greatly affects the outcome of permission decisions."),e.createElement(tn,{title:"Any-allow",changeResolutionStrategy:()=>o("any-allow"),readonly:l,defaultOption:!0,description:e.createElement(e.Fragment,null,e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"The first allow decision from all of the roles and decisions is the final result. A single explicit allow or an allow as a result of a conditional decision would result in a final allow decision, otherwise the decision is deny."),e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"With this option, the order of roles and decisions does not matter.")),active:n.options.resolutionStrategy==="any-allow"}),e.createElement(tn,{title:"First match",changeResolutionStrategy:()=>o("first-match"),readonly:l,description:e.createElement(e.Fragment,null,e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"The first matching decision from the first matching role that is applicable to the user is the final result, regardless if that decision is an allow, deny or conditional."),e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"With this option, the order in which you define roles and decisions matters.")),active:n.options.resolutionStrategy==="first-match"}))))}const nn=t=>{if(t.success)return{};const n={};for(const r of t.error.issues)n[r.path.join(".")]=!0;return n},ia=C(t=>({container:{display:"flex",position:"relative",alignItems:"center",gap:t.spacing(1),flexShrink:1,maxWidth:"100%",minWidth:0},input:({invalid:n})=>({boxSizing:"content-box",display:"block",maxWidth:"100%",padding:0,borderWidth:2,borderStyle:"solid",borderColor:n?t.palette.error.main:"transparent",borderRadius:t.shape.borderRadius,backgroundColor:"transparent",color:t.palette.textContrast,fontFamily:"inherit",fontSize:"inherit",lineHeight:"inherit",fontWeight:"inherit",textOverflow:"ellipsis"}),hiddenSpan:{position:"absolute",top:0,left:0,borderWidth:1,whiteSpace:"pre",opacity:0,pointerEvents:"none"}}));function rn({invalid:t,name:n,value:r,onTextChange:a}){const l=ia({invalid:t}),[o,i]=R(!1),[c,m]=R(null),s=ye(null),[p,u]=R(r);J(()=>{u(r)},[r]),Xn(()=>{s.current&&c&&s.current.style.setProperty("width",`max(${c.getBoundingClientRect().width}px, 3ch)`)},[c,p]);const d=()=>{i(!1),u(r)},x=()=>{i(!1),a==null||a(p)},f=()=>{var g;o?x():(i(!0),(g=s.current)==null||g.focus())},y=g=>{var w;g.key==="Enter"&&((w=s.current)==null||w.blur()),g.key==="Escape"&&d()};return e.createElement(e.Fragment,null,e.createElement("div",{className:l.container},e.createElement("input",{"aria-label":n,className:l.input,name:n,ref:s,onChange:g=>u(g.target.value),onFocus:f,onBlur:x,onKeyDown:y,value:p}),e.createElement("span",{"aria-hidden":"true",className:l.hiddenSpan,ref:m},p),e.createElement(j,{onClick:f,size:"small"},o?e.createElement(Ur,{"aria-label":"Save title"}):e.createElement(Vr,{"aria-label":"Edit title"}))))}const ca=C(t=>({titleWrapper:{display:"flex",alignItems:"center",gap:t.spacing(2)}}));function ln({children:t}){const n=ca();return e.createElement(h,{noWrap:!0,variant:"h4",component:"h2",color:"textSecondary",className:n.titleWrapper},t)}const sa=C(t=>({fieldset:{border:"none",margin:`${t.spacing(3)}px 0 ${t.spacing(3)}px`,paddingLeft:"0"}})),an=({children:t,title:n})=>{const r=sa();return e.createElement("fieldset",{className:r.fieldset},e.createElement(h,{variant:"h6",component:"legend"},n),t)},ma=C(t=>({chipContainer:{marginTop:t.spacing(1),marginLeft:t.spacing(1),display:"flex",flexWrap:"wrap"}})),da=e.forwardRef(({selectedPermissionNames:t,setSelectedPermissionNames:n,errorMessage:r},a)=>{const l=ma(),{permissions:o}=Te();return e.createElement(e.Fragment,null,e.createElement(ve,{fullWidth:!0,error:!!r},e.createElement(de,{id:"selectLabel"},"Select permissions"),e.createElement(be,{ref:a,native:!1,displayEmpty:!0,multiple:!0,value:t,onChange:i=>n(i.target.value),input:e.createElement(Rt,null),"aria-labelledby":"selectLabel",renderValue:i=>e.createElement("div",{className:l.chipContainer,"aria-labelledby":"selectLabel"},o==null?void 0:o.filter(c=>i.includes(c.name)).map(c=>e.createElement(se,{key:c.name,label:c.name})))},o==null?void 0:o.map(i=>e.createElement(H,{key:i.name,value:i.name},e.createElement(Ce,{color:"primary",checked:t.includes(i.name),name:i.name,value:i.name,required:!0}),e.createElement(Q,{primary:i.name})))),e.createElement(lt,null,r)))}),Y=({name:t})=>{const n=B(()=>t.includes(".")?t.split(/(\.)/g).flatMap(r=>[r,e.createElement("wbr",null)]):[t],[t]);return e.createElement(e.Fragment,null,n.map((r,a)=>e.createElement(e.Fragment,{key:a},r)))},on=({authorizeResult:t,size:n})=>{switch(t){case F.ALLOW:return e.createElement(qr,{fontSize:n});case F.DENY:return e.createElement(Kr,{fontSize:n});case F.CONDITIONAL:return e.createElement(Jr,{fontSize:n});default:return null}},ua=["condition","anyOf","allOf","not"],cn={condition:"Condition",anyOf:"Any of",allOf:"All of",not:"Not"};function Ct(t){return t===null?!1:t.hasOwnProperty("id")&&t.hasOwnProperty("ruleName")&&t.hasOwnProperty("parameters")}function Se(t){return t.hasOwnProperty("levelType")}function pa(t){return t==="anyOf"||t==="allOf"||t==="not"}const Ea=C(()=>({root:{fontFamily:"monospace"}})),sn=({children:t})=>{const n=Ea();return e.createElement(h,{variant:"body2",className:n.root},t)},fa=C(t=>({rule:{color:t.palette.type==="light"?"#EB0014":"#FF8F9C"},parameters:{color:t.palette.type==="light"?"#E22134":"#EE96A0"}}));function mn({condition:t}){const n=fa();return e.createElement(sn,null,e.createElement(E,{component:"span",className:n.rule},t.ruleName,"(",e.createElement(E,{component:"span",className:n.parameters},JSON.stringify(t.parameters,null,1)),")"))}const ya=({children:t})=>e.createElement(E,{pl:2},t);function dn({level:t}){return e.createElement(e.Fragment,null,e.createElement(sn,null,cn[t.levelType]),e.createElement(ya,null,t.children.map((n,r)=>Se(n)?e.createElement(dn,{key:r,level:n}):e.createElement(mn,{key:r,condition:n}))))}const ga=C(t=>({resultsBox:{border:`1px solid ${t.palette.border}`,borderRadius:t.shape.borderRadius,padding:t.spacing(2)}}));function ha({permissionCriteria:t}){const n=ga();return e.createElement(E,{className:n.resultsBox},Ct(t)&&e.createElement(mn,{condition:t}),Se(t)&&e.createElement(dn,{level:t}))}const va=C(t=>({conditionResultText:{color:t.palette.success.main},conditionDecisionText:{padding:`0 0 ${t.spacing(3)}px`}}));function un({permissionCriteria:t}){const n=va();return e.createElement("div",null,e.createElement(h,{component:"p",variant:"body1",className:n.conditionDecisionText},"If the below conditions are met then the action is"," ",e.createElement("strong",{className:n.conditionResultText},"allowed.")),e.createElement(ha,{permissionCriteria:t}))}function ba(t){return t?{id:t.id,match:Ca(t),decisionType:xa(t),criteria:Ye(t.decision)?Ae(t.decision.conditions):null}:{id:pe(),match:{method:"specificPermission"},decisionType:"allow",criteria:null}}function Ca(t){var n;return t.match==="*"?{method:"all"}:t.match.name?{method:"specificPermission",name:t.match.name}:t.match.resourceType||(n=t.match.actions)!=null&&n.length?{method:"filter",resourceType:t.match.resourceType,actions:t.match.actions}:{method:"specificPermission"}}function xa(t){return typeof t.decision=="string"?t.decision:"conditional"}function Ae(t){const n=pe();return wr(t)?{id:n,levelType:"allOf",children:t.allOf.map(r=>Ae(r))}:Dr(t)?{id:n,levelType:"anyOf",children:t.anyOf.map(r=>Ae(r))}:Nr(t)?{id:n,levelType:"not",children:[Ae(t.not)]}:{id:n,ruleName:t.rule,parameters:t.params}}function pn(t,n){if(!t)return!1;if(Se(t))return t.children.length>0&&t.children.every(a=>pn(a,n));if(!t.ruleName)return!1;const r=n==null?void 0:n.find(({name:a})=>a===t.ruleName);return r?r.paramsSchema?new dt({allErrors:!0}).compile(r.paramsSchema)(t.parameters):!0:!1}function wa(t,n,r){return{id:t,match:En(n,r),decision:r}}function En({method:t,...n},r){return t==="all"?"*":r&&Ye(r)?{resourceType:r.resourceType,...n}:n}function xt(t){return Ct(t)?{rule:t.ruleName,params:t.parameters}:t.levelType==="not"?{not:xt(t.children[0])}:{[t.levelType]:t.children.map(n=>xt(n))}}const Da=C(()=>({decisionRowCell:{fontWeight:"bold"}})),Ze=({children:t,ledToDecision:n,color:r})=>{const a=Da();return e.createElement(h,{variant:"body1",component:"span",classes:{root:n?a.decisionRowCell:void 0},color:r},t)},Na=({ledToDecision:t})=>e.createElement(Ze,{ledToDecision:t,color:t===!1?"textSecondary":void 0},t?"Yes":"No"),Pa=C(t=>({decisionCell:{display:"flex",justifyItems:"center"},decisionIconContainer:{display:"flex",alignItems:"center",marginRight:t.spacing(1)},decisionIconAllow:{color:t.palette.success.main},decisionIconDeny:{color:t.palette.error.main},decisionIconConditional:{color:t.palette.info.main}})),Ta=t=>{switch(t){case F.ALLOW:return"Allow";case F.DENY:return"Deny";case F.CONDITIONAL:return"Conditional";default:return"Permission not found in role"}},Sa=(t,n)=>{let r;switch(t){case F.ALLOW:r=n.decisionIconAllow;break;case F.DENY:r=n.decisionIconDeny;break;case F.CONDITIONAL:r=n.decisionIconConditional;break;default:return}return`${n.decisionIconContainer} ${r}`},Aa=({ledToDecision:t,authorizeResult:n})=>{const r=Pa();return e.createElement("div",{className:r.decisionCell},n!==null&&e.createElement("span",{className:Sa(n,r)},e.createElement(on,{authorizeResult:n,size:"small"})),e.createElement(Ze,{ledToDecision:t,color:t===!1?"textSecondary":void 0},Ta(n)))},Ra=({permissionName:t,ledToDecision:n})=>e.createElement(Ze,{ledToDecision:n,color:n===!1?"textSecondary":void 0},e.createElement(Y,{name:t})),$a=({role:t,ledToDecision:n})=>e.createElement(ae,{to:`roles/${t.id}`},e.createElement(Ze,{ledToDecision:n,color:"primary"},t.name)),Ia=C(t=>({tableHeader:{borderBottom:`1px solid ${t.palette.border}`}})),Re=({children:t})=>{const n=Ia();return e.createElement(D,{size:"small",classes:{root:n.tableHeader}},t)},ka=C(t=>({userCell:{borderRight:`1px solid ${t.palette.border}`,color:t.palette.text.secondary,background:t.palette.background.paper}})),Oa=({rowCount:t})=>{const n=ka();return e.createElement(D,{size:"small",padding:"none",align:"center",rowSpan:t,classes:{root:n.userCell}},e.createElement(qn,null))},Ba=C(t=>({tableContainer:{border:`1px solid ${t.palette.border}`,borderRadius:t.shape.borderRadius},tableRow:{"&, &:nth-child(odd)":{background:t.palette.background.paper}},decisionTableRow:{"&, &:nth-child(odd)":{background:t.palette.type==="light"?t.palette.infoBackground:t.palette.grey[900]}}})),La=t=>{if(Ye(t))return F.CONDITIONAL;if(typeof t=="string")switch(t){case"allow":return F.ALLOW;case"deny":return F.DENY;default:throw new Error(`Unknown decision: ${t}`)}throw new Error("Unknown decision type found.")},Ma=(t,n)=>n.some(r=>r.rolePermissionId===t.id),Fa=t=>B(()=>{const{roles:n,permission:r,decisionOrigin:a}=t,l=[];for(const o of n){const i=kt(o,r);if(i.length>0)for(const c of i)l.push({role:o,permission:r,authorizeResult:La(c.decision),ledToDecision:Ma(c,a)});else l.push({role:o,permission:r,authorizeResult:null,ledToDecision:!1})}return l},[t]),za=({resultRow:t})=>{const n=Ba(),r=Fa(t);return e.createElement(E,{marginTop:3,marginBottom:3},e.createElement(cr,{classes:{root:n.tableContainer}},e.createElement(Ue,null,e.createElement(Ve,null,e.createElement(U,{classes:{root:n.tableRow}},e.createElement(Re,null),e.createElement(Re,null,"Role"),e.createElement(Re,null,"Permission"),e.createElement(Re,null,"Decision"),e.createElement(Re,null,"Is deciding role"))),e.createElement(Ge,null,r.map((a,l)=>{const o=l===0;return e.createElement(U,{key:l,classes:{root:a.ledToDecision?n.decisionTableRow:n.tableRow}},o?e.createElement(Oa,{rowCount:r.length}):null,e.createElement(D,{size:"small"},e.createElement($a,{role:a.role,ledToDecision:a.ledToDecision})),e.createElement(D,{size:"small"},e.createElement(Ra,{permissionName:a.permission.name,ledToDecision:a.ledToDecision})),e.createElement(D,{size:"small"},e.createElement(Aa,{authorizeResult:a.authorizeResult,ledToDecision:a.ledToDecision})),e.createElement(D,{size:"small"},e.createElement(Na,{ledToDecision:a.ledToDecision})))})))))},Wa=C(t=>({container:{display:"flex",flexDirection:"row",gap:t.spacing(1)},infoIcon:{color:t.palette.textSubtle}})),Ha=({policy:t,roles:n,permission:r})=>{const a=n.flatMap(o=>kt(o,r));let l;if(n.length===0)l=e.createElement(e.Fragment,null,"A user with no assigned roles will be denied access to"," ",e.createElement("strong",null,e.createElement(Y,{name:r.name})),".");else if(!a.length)l=e.createElement(e.Fragment,null,"None of the roles explicitly sets a rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:r.name})),", which means that a user who has all of these roles will be denied access to"," ",e.createElement("strong",null,e.createElement(Y,{name:r.name})),".");else if(t.options.resolutionStrategy==="any-allow")l=e.createElement(e.Fragment,null,"None of the roles explicitly sets an allow or conditional rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:r.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", a user who has all of these roles will be denied access to"," ",e.createElement("strong",null,e.createElement(Y,{name:r.name})),".");else throw t.options.resolutionStrategy==="first-match"?new Error("Trying to render ImplicitDecisionInfo for a first-match policy that has matching role permission. This should not happen, since the decision should be explicit by the matching role permission."):new Error(`Unknown resolution strategy ${t.options.resolutionStrategy}. Cannot render ImplicitDecisionInfo.`);return e.createElement(e.Fragment,null,e.createElement("strong",null,"Implicit decision")," \u2013 ",l)},Ua=({policy:t,permission:n,roles:r,decision:a,decisionOrigin:l})=>{const o=r.find(c=>c.id===l[0].roleId);let i;if(t.options.resolutionStrategy==="first-match"){if(!o)throw new Error("Expected decision origin role for first-match explicit decision but found none.");i=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,o.name)," explicitly sets a rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"first-match"),", no other roles are applied.")}else if(t.options.resolutionStrategy==="any-allow"){if(a.result===F.ALLOW){if(!o)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");i=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,o.name)," is the first role that explicitly sets an allow decision for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", this decides the outcome.")}else if(a.result===F.CONDITIONAL)if(l.length===1){if(!o)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");i=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,o.name)," is the first role that explicitly sets a decision for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", this decides the outcome.")}else i=e.createElement(e.Fragment,null,"Multiple roles explicitly set a rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", these decide the outcome.")}else throw new Error(`Unknown resolution strategy ${t.options.resolutionStrategy}. Cannot render ExplicitDecisionInfo.`);return e.createElement(e.Fragment,null,e.createElement("strong",null,"Explicit decision")," \u2013 ",i)},Va=({roles:t,permission:n,decision:r,decisionOrigin:a})=>{const{policy:l}=_(),o=Wa();return e.createElement("div",{className:o.container},e.createElement(Qr,{fontSize:"small",titleAccess:"",className:o.infoIcon}),e.createElement(h,{variant:"body1",component:"p"},a.length===0?e.createElement(Ha,{policy:l,roles:t,permission:n}):e.createElement(Ua,{policy:l,permission:n,roles:t,decision:r,decisionOrigin:a})))},Ga=C(t=>({heading:{fontWeight:"bold"},subtitle:{color:t.palette.text.secondary},criteriaSummarySpacing:{marginBottom:t.spacing(3)}})),ja=({resultRow:t})=>{const n=Ga();return e.createElement(e.Fragment,null,t.roles.length>0?e.createElement(e.Fragment,null,e.createElement(h,{variant:"body1",component:"h6",className:n.heading},"Decision breakdown"),e.createElement(h,{variant:"subtitle1",component:"p",className:n.subtitle},"See what role results in this decision."),e.createElement(za,{resultRow:t})):null,t.decision.result===F.CONDITIONAL?e.createElement("div",{className:n.criteriaSummarySpacing},e.createElement(un,{permissionCriteria:Ae(t.decision.conditions)})):null,e.createElement(Va,{roles:t.roles,permission:t.permission,decision:t.decision,decisionOrigin:t.decisionOrigin}))};function fn(t,n){switch(n){case"small":return t.typography.caption;case"medium":return t.typography.body1;case"large":return t.typography.subtitle1;default:return t.typography.caption}}function yn(t){switch(t){case"small":return .2;case"medium":return .3;case"large":return 1;default:return .8}}const _a=C(t=>({root:{display:"inline-flex",fontWeight:"bold",borderRadius:"1000px",margin:t.spacing(1),padding:t.spacing(0,1)},message:({size:n})=>({fontSize:fn(t,n).fontSize,font:fn(t,n).font,verticalAlign:"middle",padding:t.spacing(yn(n),0,yn(n),0)})}),{name:"MuiAlert"});function gn(t){var n;const r=_a({size:t.size||"small"});return e.createElement(zt,{classes:{root:r.root,message:r.message},role:"textbox",severity:t.severity,icon:(n=t.icon)!=null?n:!1,variant:t.outlined?"outlined":"standard",title:t.text},t.text)}function Ya({decision:t}){let n;switch(t.result){case"ALLOW":n={severity:"success",text:"Allow"};break;case"DENY":n={severity:"error",text:"Deny"};break;default:n={severity:"info",text:"Conditional"};break}return e.createElement(gn,{text:n.text,severity:n.severity,icon:e.createElement(on,{authorizeResult:t.result}),title:`${n.text} decision chip`,size:"large"})}const Ja=C(t=>({permissionName:{display:"flex",alignItems:"center",height:"100%",fontWeight:"bold"},detailsContainer:{padding:`${t.spacing(2)}px ${t.spacing(1)}px 0`,borderTop:`1px solid ${t.palette.divider}`}})),qa=({resultRow:t})=>{const n=Ja();return e.createElement(sr,null,e.createElement(mr,{expandIcon:e.createElement(Yr,null),"aria-controls":"result{$resultIndex}-content",id:t.permission.name},e.createElement(O,{container:!0},e.createElement(O,{item:!0,xs:12,md:4},e.createElement(h,{variant:"body1",className:n.permissionName,component:"h5"},e.createElement(Y,{name:t.permission.name}))),e.createElement(O,{item:!0,xs:12,md:8},e.createElement(h,{variant:"body2"},t.roles.length>0?"For a user who has all the selected roles, the result will be:":"For a user with no assigned roles, the result will be:"),e.createElement(Ya,{decision:t.decision})))),e.createElement(dr,null,e.createElement("div",{className:n.detailsContainer},e.createElement(ja,{resultRow:t}))))},Ka=C(t=>({header:{borderTop:`1px solid ${t.palette.divider}`,padding:`${t.spacing(3)}px ${t.spacing(1)}px`,borderBottom:`1px solid ${t.palette.divider}`},resultHeading:{marginBottom:t.spacing(1)},accordionHeader:{padding:`${t.spacing(1)}px ${t.spacing(6)}px ${t.spacing(1)}px ${t.spacing(0)}px`,margin:"0"}})),Qa=({results:t,resolutionStrategy:n})=>{const r=Ka();return t.length?e.createElement(e.Fragment,null,e.createElement("div",{className:r.header},e.createElement(h,{variant:"h5",component:"h4",color:"textPrimary",className:r.resultHeading},"Test results"),e.createElement(zt,{severity:"info"},"All the tests are evaluated using"," ",e.createElement("strong",null,n),", which is the policy resolution strategy")),e.createElement(O,{container:!0,className:r.accordionHeader},e.createElement(O,{item:!0,xs:12,md:4},e.createElement(h,{variant:"body1",color:"textSecondary"},"Permission")),e.createElement(O,{item:!0,xs:12,md:8},e.createElement(h,{variant:"body1",color:"textSecondary"},"Result"))),t.map(a=>e.createElement(qa,{resultRow:a,key:a.permission.name}))):null},Xa=C(t=>({chipContainer:{marginTop:t.spacing(1),marginLeft:t.spacing(1),display:"flex",flexWrap:"wrap"}})),Za=({selectedRoleIds:t,setSelectedRoleIds:n})=>{const r=Xa(),{policy:a}=_();return e.createElement(e.Fragment,null,e.createElement(ve,{fullWidth:!0},e.createElement(de,{id:"selectLabel"},"Select roles"),e.createElement(be,{native:!1,displayEmpty:!0,multiple:!0,value:t,onChange:l=>n(l.target.value),input:e.createElement(Rt,null),"aria-labelledby":"selectLabel",renderValue:l=>e.createElement("div",{className:r.chipContainer,"aria-labelledby":"selectLabel"},a.roles.filter(o=>l.includes(o.id)).map(o=>e.createElement(se,{key:o.name,label:o.name})))},a.roles.map(l=>e.createElement(H,{key:l.id,value:l.id},e.createElement(Ce,{color:"primary",checked:t.includes(l.id),name:l.name,value:l.id}),e.createElement(Q,{primary:l.name}))))))},eo=Wt.array(Wt.string()),hn=(t,n,r)=>{const[a,l]=Ft(`@spotify/backstage-plugin-rbac:policyTesterForm:${t}`,[],{raw:!1,serializer:i=>JSON.stringify(i),deserializer:i=>{let c;try{c=JSON.parse(i)}catch(s){return console.error("Failed to parse json",s),[]}const m=eo.safeParse(c);return m.success?m.data:(console.error(`Stored value for ${t} has the wrong shape`,m.error),[])}}),o=B(()=>a!=null?a:[],[a]);return J(()=>{const i=new Set(n),c=o.some(m=>!i.has(m));!r&&c&&l(o.filter(m=>i.has(m)))},[n,o,l,r]),[o,l]},to=()=>{const{policy:t}=_(),{permissions:n}=Te(),r=k(V),[a,l]=R([]),o=I(async(c,m)=>{if(!n)return;const s=(await r.testPolicyDecisions(n.filter(p=>m.includes(p.name)).map(p=>({policyConfig:t,roleIds:c,permission:p})))).map(p=>({...p,roles:t.roles.filter(u=>c.includes(u.id))}));l(s)},[t,n,r,l]),i=I(()=>{l([])},[l]);return[a,o,i]},no=C(t=>({bodyText:{margin:`${t.spacing(1)}px 0`},clearButton:{marginLeft:t.spacing(1)}}));function ro(){const{policy:t}=_(),{permissions:n,isLoading:r}=Te(),a=B(()=>t.roles.map(T=>T.id),[t.roles]),l=B(()=>(n==null?void 0:n.map(T=>T.name))||[],[n]),o=ye(null),[i,c]=hn("roleIds",a),[m,s]=hn("permissionNames",l,r),[p,u]=R(""),[d,x,f]=to();J(()=>{f()},[t.roles,t.options,f]);const y=()=>{var T,z;m.length===0?((z=(T=o.current)==null?void 0:T.firstChild)==null||z.focus(),u("Please select at least one permission.")):x(i,m)},g=()=>{c([]),s([]),f(),u("")},w=no(),S=T=>{s(T),T.length>0&&u("")};return e.createElement(at,null,e.createElement(E,{justifyContent:"space-between",padding:2},e.createElement(h,{variant:"h3"},"Policy Tester"),e.createElement(h,{variant:"body1",component:"p",className:w.bodyText},"Use the policy tester to check if your changes will provide the access you intended for a user that has the roles you select below."),e.createElement(an,{title:"Which permissions do you want to test?"},e.createElement(da,{selectedPermissionNames:m,setSelectedPermissionNames:S,ref:o,errorMessage:p})),e.createElement(an,{title:"Which roles should the simulated user have?"},e.createElement(Za,{selectedRoleIds:i,setSelectedRoleIds:c})),e.createElement(E,{marginTop:3,component:"section"},e.createElement(P,{onClick:y,variant:"contained",color:"primary"},"Run tests"),e.createElement(P,{className:w.clearButton,color:"primary",variant:"outlined",startIcon:e.createElement(Gr,null),onClick:g},"Clear")),d&&d.length?e.createElement(E,{sx:{flexGrow:1},marginTop:4},e.createElement(Qa,{results:d,resolutionStrategy:t.options.resolutionStrategy})):null))}const vn=({children:t,onConfirm:n,message:r,title:a})=>{const[l,o]=R(!1),i=()=>o(!1),c=()=>o(!0),m=()=>{n(),i()};return e.createElement(e.Fragment,null,t({onClick:c}),e.createElement(ie,{open:l,onClose:i},e.createElement(He,null,e.createElement(E,{display:"flex",justifyContent:"space-between",alignItems:"center"},a)),e.createElement(ee,null,e.createElement(ur,null,r)),e.createElement(rt,null,e.createElement(P,{"aria-label":"Cancel action",color:"primary",onClick:i},"Cancel"),e.createElement(P,{"aria-label":"Confirm action",color:"secondary",onClick:m,variant:"contained"},"Confirm"))))},$e=t=>{const n=Pl(t.operation);return!t.operation||t.operation==="UNCHANGED"?null:e.createElement(gn,{size:t.size,text:n,severity:Nl(t.operation),outlined:!0})},bn=(t,n,r)=>{const a=n+r;if(a<0||a>=t.length)return t;const l=[...t];return[l[a],l[n]]=[l[n],l[a]],l},Cn=({array:t,index:n,onReorder:r})=>{const a=n===0,l=n===t.length-1;return e.createElement(E,{display:"flex"},e.createElement(j,{disabled:a,onClick:()=>r(bn(t,n,-1)),"aria-label":"Move up",size:"small"},e.createElement(Zr,null)),e.createElement(j,{disabled:l,onClick:()=>r(bn(t,n,1)),"aria-label":"Move down",size:"small"},e.createElement(Xr,null)))},xn=({helpText:t})=>e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(E,{component:"span",mr:1},e.createElement(h,{variant:"body2",noWrap:!0},"Reorder")),e.createElement(ge,{title:t},e.createElement(Ht,{color:"primary","aria-label":t}))),lo="Use the arrows to change the order in which roles are evaluated.";function ao({}){const{diff:t,policy:n,createNewRole:r,updateLocalDraft:a}=_(),l=q(),o=oo(n),i=n.status!=="draft",c=n.options.resolutionStrategy==="any-allow",m=u=>{a({...n,roles:u})},s=u=>{a({...n,roles:n.roles.filter(({id:d})=>d!==u)})},p=()=>{l(`./roles/${r()}`)};return e.createElement(at,null,e.createElement(E,{display:"flex",justifyContent:"space-between",padding:2},e.createElement(h,{variant:"h3"},"Roles"),!i&&e.createElement(P,{color:"primary",variant:"outlined",startIcon:e.createElement(ut,null),onClick:()=>p()},"New role")),e.createElement(Ue,{"data-testid":"rolesTable"},e.createElement(Ve,null,e.createElement(U,null,!i&&!c&&e.createElement(D,{style:{width:0}},e.createElement(xn,{helpText:lo})),e.createElement(D,null,"Name"),e.createElement(D,null,"Users"),e.createElement(D,null,"Groups"),!i&&e.createElement(D,{style:{width:0}}))),e.createElement(Ge,null,o.map((u,d)=>e.createElement(U,{key:d},!i&&!c&&e.createElement(D,null,e.createElement(Cn,{array:n.roles,index:d,onReorder:m})),e.createElement(D,null,e.createElement(E,{alignItems:"center",display:"flex",gridGap:8},e.createElement(ae,{to:`roles/${u.id}`},u.name),e.createElement($e,{operation:t==null?void 0:t.roles[u.id].role.operation}))),e.createElement(D,null,u.userCount),e.createElement(D,null,u.groupCount),!i&&e.createElement(D,{align:"right"},e.createElement(vn,{message:"Are you sure you want to remove this role?",title:"Remove role?",onConfirm:()=>s(u.id)},x=>e.createElement(j,{...x,"aria-label":"Remove role",size:"small"},e.createElement(De,null)))))))))}function oo(t){return t.roles.map(n=>({id:n.id,name:n.name,userCount:Array.isArray(n.members)?n.members.filter(r=>r.startsWith("user:")).length:n.members,groupCount:Array.isArray(n.members)?n.members.filter(r=>r.startsWith("group:")).length:n.members}))}const io=C(()=>({emptyStateImage:{width:"95%",zIndex:2,position:"relative",left:"50%",top:"50%",transform:"translate(-50%, 15%)"}}));function wn({src:t,alt:n}){const r=io();return e.createElement("img",{src:t,className:`${r.emptyStateImage} `,alt:n})}const co=C(t=>({cardHeader:{padding:t.spacing(3,3),borderBottom:`1px solid ${t.palette.border}`},cardContent:{padding:t.spacing(6,3),"& > *":{background:"transparent"}},emptyStateImage:{width:"95%",zIndex:2,position:"relative",left:"50%",top:"50%",transform:"translate(-50%, 15%)"}}));function so({readonly:t}){const n=co(),r=q(),{createNewRole:a}=_(),l=()=>{const o=a();r(`./roles/${o}`)};return e.createElement(te,null,e.createElement(At,{title:"Roles",className:n.cardHeader}),e.createElement(he,{className:n.cardContent},t?e.createElement(Oe,{title:"No roles configured",missing:"content"}):e.createElement(Oe,{title:"No roles yet",description:"Click the button below to create your first role.",missing:{customImage:e.createElement(wn,{src:el,alt:"No roles placeholder"})},action:e.createElement(P,{variant:"contained",color:"primary",onClick:()=>l()},"New role")})))}function mo(){const[t,n]=R(null),{hasDraftPolicy:r}=Ke(),{isValid:a,discardLocalDraft:l,exportPolicy:o,hasChanges:i,policy:c,saveLocalDraftToServer:m,saveAndPublish:s,publish:p}=_(),u=q(),[d,x]=vt(),f=g=>{n(g.currentTarget)},y=()=>{n(null)};return e.createElement(e.Fragment,null,e.createElement(pr,{variant:"contained",color:"primary"},c.status==="draft"&&e.createElement(P,{disabled:!a,onClick:()=>m()},"Save"),c.status==="inactive"&&e.createElement(P,{onClick:()=>p()},"Republish"),c.status==="active"&&e.createElement(P,{disabled:r||d.loading,onClick:()=>x(c)},"Duplicate"),e.createElement(P,{color:"primary",title:"options",size:"small",onClick:f},e.createElement(tl,null))),e.createElement($t,{getContentAnchorEl:null,anchorEl:t,anchorOrigin:{vertical:"bottom",horizontal:"right"},open:!!t,onClose:y,PaperProps:{style:{width:240}}},c.status==="draft"&&e.createElement(ot,null,e.createElement(H,{disabled:!a,onClick:()=>s()},e.createElement(me,null,e.createElement(nl,{fontSize:"small"})),e.createElement(Q,null,"Save & Publish")),e.createElement(H,{disabled:!i,onClick:()=>l()},e.createElement(me,null,e.createElement(ll,{color:i?"secondary":"inherit",fontSize:"small"})),e.createElement(Q,null,e.createElement(h,{color:i?"secondary":"inherit"},"Discard changes"))),e.createElement(it,null)),e.createElement(ot,null,e.createElement(H,{onClick:()=>o()},e.createElement(me,null,e.createElement(al,{fontSize:"small"})),e.createElement(Q,null,"Export"))),e.createElement(it,null),e.createElement(ot,null,e.createElement(H,{disabled:!a,onClick:()=>u("./options")},e.createElement(me,null,e.createElement(rl,{fontSize:"small"})),e.createElement(Q,null,"Options")))))}function uo(){const{versionId:t}=nt();return je(t),e.createElement(Qe,{policyId:t},e.createElement(po,null))}function po(){const{policy:t,updateLocalDraft:n}=_(),r=o=>{n({...t,name:o})},a=nn(Pr.safeParse(t)).name,l=t.status!=="draft";return e.createElement(qe,{pages:[{title:t.name}],header:e.createElement(Be,{title:t.name,titleComponent:e.createElement(e.Fragment,null,e.createElement(ln,null,l?t.name:e.createElement(rn,{invalid:a,name:"Policy name",value:t.name,onTextChange:r}),e.createElement(Jt,{status:t.status})),Eo(t))},e.createElement(mo,null))},e.createElement(O,{container:!0,spacing:4},e.createElement(O,{item:!0,xs:12},t.roles.length>0?e.createElement(ao,null):e.createElement(so,{readonly:l})),e.createElement(O,{item:!0,xs:12},e.createElement(ro,null))))}function Eo(t){const n={created:"Created by ",published:"Last published by ",updated:"Last updated by "},{activityDateText:r,activityUser:a,timestamp:l}=Yt(t,n);return e.createElement(h,{variant:"body2"},e.createElement(h,{component:"span",display:"inline",variant:"body2"},`${r} ${a} `),e.createElement(_t,{timestamp:l}))}function fo(t,n){const r=(t!=null?t:[]).filter(o=>Tr(o,En(n))),a=ol(r,o=>st(o)?o.resourceType:void 0),l=a.length===1&&st(a[0])?a[0].resourceType:void 0;return{permissions:r,commonResourceType:l}}const yo=C(()=>({addButton:{paddingLeft:40,paddingRight:40}}));function Dn({onSelect:t}){const n=yo(),r=ye(null),[a,l]=R(!1),o=()=>{l(i=>!i)};return e.createElement("div",null,e.createElement(P,{className:n.addButton,variant:"outlined",color:"primary",onClick:o,ref:r},"Add"),e.createElement($t,{anchorEl:r.current,open:a,onClose:o,BackdropProps:{}},ua.map(i=>e.createElement(H,{key:i,onClick:()=>{t==null||t(i),l(!1)}},cn[i]))))}const go=[];function ho(t){const{onChange:n,schema:r,name:a}=t,{description:l,items:o}=r,[i,c]=e.useState(!1),m=Array.isArray(t.value)?t.value:go,s=m.includes(xe),p=(g,w)=>{if(!Array.isArray(w)){const S=[...m];S[g]=w||"",n(S)}},u=I(()=>{n([...m,""])},[n,m]),d=g=>{n(m.filter((w,S)=>S!==g))},x=()=>{n(s?[]:[xe])},f=()=>{s&&c(!0)},y=()=>{c(!1)};return J(()=>{m.length?s&&m.length>1&&n([xe]):u()},[u,n,m,s]),!o||!("type"in o)?null:e.createElement(e.Fragment,null,(m!=null?m:[]).map((g,w,{length:S})=>e.createElement(Pn,{allowEmptyStrings:!0,key:w,onChange:T=>p(w,T),name:w===0?a:"",schema:{description:w===S-1?l:"",type:o.type},value:g,controls:e.createElement(j,{size:"small",onClick:()=>d(w)},e.createElement(il,null))})),!!(m!=null&&m.length)&&e.createElement(E,{alignItems:"center",display:"flex",flexDirection:"row",justifyContent:"space-between"},e.createElement(E,null,e.createElement(It,{control:e.createElement(Ce,{checked:s,onChange:x,name:"checkedB",color:"primary"}),label:"Use the claims from the logged in users token"})),e.createElement(E,null,e.createElement(ge,{onClose:y,onOpen:f,open:i,title:"To add additional entries you must uncheck using the claims from the logged in user."},e.createElement("span",null,e.createElement(j,{disabled:s,size:"small",onClick:u},e.createElement(ut,null)))))))}function vo(t){const{onChange:n,schema:r,name:a,value:l}=t,{description:o}=r;return e.createElement(E,{mb:1},e.createElement(It,{control:e.createElement(Ce,{checked:l===!0,onChange:i=>{n(i.target.checked)},name:a,color:"primary"}),label:a}),o&&e.createElement(h,{display:"block",variant:"caption",color:"textSecondary"},o))}function bo({allowEmptyStrings:t,controls:n,name:r,onChange:a,schema:l,value:o}){const i=c=>{a(xo({value:c.currentTarget.value,type:l.type}))};return e.createElement(E,{mb:1},e.createElement(E,{display:"flex",gridGap:6},e.createElement(ce,{fullWidth:!0,id:r,label:r,placeholder:"Enter",variant:"outlined",size:"small",value:Co(o,t),onChange:wt(o,t)?void 0:i,disabled:wt(o,t)}),n&&e.createElement(E,{alignSelf:"center"},n)),l.description&&e.createElement(h,{variant:"caption",color:"textSecondary"},l.description,wt(o)&&!t&&e.createElement(e.Fragment,null," (switch to JSON editor to edit)")))}function wt(t,n=!1){return!n&&t===""||t===null||t===xe}function Co(t,n=!1){return!n&&t===""?"[empty string]":t===null?"[null]":t===xe?"[BackstageUserClaims]":t||""}function xo({value:t,type:n}){switch(n){case"string":return t===""?void 0:t;case"number":case"integer":return Number.isNaN(Number(t))?void 0:Number(t);case"null":return t==="null"?null:void 0;default:return}}function Nn(t){return!!t&&"type"in t&&(t.type==="array"||t.type==="boolean"||t.type==="null"||t.type==="number"||t.type==="integer"||t.type==="string")}function wo(t){return"type"in t&&t.type==="array"}function Do(t){return"type"in t&&t.type==="boolean"}function Pn({schema:t,...n}){return Nn(t)?wo(t)?e.createElement(ho,{...n,schema:t}):Do(t)?e.createElement(vo,{...n,schema:t}):e.createElement(bo,{...n,schema:t}):null}const No=new dt({allErrors:!0}),Po=C({textarea:{fontFamily:"monospace"}});function To({onChange:t,schema:n,value:r}){const a=Po(),[l,o]=R(!1),i=B(()=>No.compile(n),[n]);return e.createElement(ce,{InputProps:{classes:{input:a.textarea}},multiline:!0,fullWidth:!0,variant:"outlined",minRows:3,error:l,defaultValue:JSON.stringify(r,void 0,2),onChange:c=>{const m=c.target.value;if(m)try{const s=JSON.parse(m);i(s)&&(o(!1),t(s))}catch{o(!0)}}})}const So=new dt({allErrors:!0});function Ao({onChange:t,schema:n,value:r}){var a;const l=B(()=>So.compile(n),[n]),o=B(()=>l(r),[l,r]),i=Object.entries(n.properties),c=m=>s=>{t({...r,[m]:s})};return e.createElement(e.Fragment,null,i.map(([m,s])=>{var p;return e.createElement(Pn,{isRequired:((p=n.required)==null?void 0:p.includes(m))||!1,key:m,name:m,onChange:c(m),schema:s,value:r==null?void 0:r[m]})}),e.createElement(lt,{error:!o},(a=l.errors)==null?void 0:a[0].message))}const Ro=t=>!!t&&"properties"in t;function $o({onChange:t,rule:n,value:r}){const[a,l]=R(!1),{paramsSchema:o}=n!=null?n:{},i=()=>l(p=>!p);if(!Ro(o))return null;const c=!Io(o),m=c||a,s=e.createElement(P,{size:"small",onClick:i,disabled:c},m?"Close editor":"Edit as JSON");return e.createElement(E,{marginTop:2},e.createElement("form",null,m?e.createElement(To,{onChange:t,schema:o,value:r}):e.createElement(e.Fragment,null,e.createElement(E,{marginBottom:2},e.createElement(de,null,"Parameters")),e.createElement(Ao,{onChange:t,schema:o,value:r}))),e.createElement(E,{display:"flex",flexDirection:"column",alignItems:"flex-end",marginTop:1},c?e.createElement(ge,{title:"Only JSON editing is supported for this parameter",arrow:!0},e.createElement("span",null,s)):s))}function Io(t){return Object.values(t.properties).every(Nn)}const ko=C(t=>({conditionCard:{minWidth:t.spacing(63)},conditionCardBar:{height:t.spacing(1),backgroundImage:"linear-gradient(90deg, #007DFF 0%, #0057B2 100%)"},autocomplete:{flex:1}}));function Tn({ruleName:t,parameters:n,resourceType:r,onChange:a,onDelete:l}){var o;const i=ko(),c=Zt(),m=(o=c==null?void 0:c.filter(d=>d.resourceType===r))!=null?o:[],s=m.find(d=>d.name===t),p=d=>{a(d,{})},u=I(d=>{a(t,d)},[a,t]);return e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(te,{className:i.conditionCard},e.createElement("div",{className:i.conditionCardBar}),e.createElement(he,null,e.createElement(E,null,e.createElement(E,null,e.createElement(mt,{className:i.autocomplete,"data-testid":"rule-select",getOptionLabel:d=>d.name,getOptionSelected:(d,x)=>d.name===x.name,options:m,onChange:(d,x)=>p(x?x.name:null),renderInput:d=>e.createElement(e.Fragment,null,e.createElement(E,{marginBottom:2},e.createElement(de,null,"Rule")),e.createElement(ce,{...d,placeholder:"Select",variant:"outlined",size:"small",name:"rule"})),renderOption:d=>e.createElement(E,null,e.createElement(h,{variant:"body2"},d.name),e.createElement(h,{noWrap:!0,variant:"caption"},d.description)),value:s||null,PopperComponent:d=>e.createElement(Er,{...d,style:{width:"auto"},placement:"bottom-start"})})),e.createElement(E,{flex:"1"},e.createElement(E,{display:"flex",flexDirection:"column"},e.createElement($o,{rule:s,onChange:u,value:n})))))),e.createElement(E,{ml:1},e.createElement(j,{"aria-label":"delete",onClick:l,size:"small"},e.createElement(De,null))))}const Oo=C(t=>({conditionTypeFormControl:{minWidth:80,marginLeft:t.spacing(1)}}));function Bo({level:t,onSelect:n}){const r=Oo(),a=t.children.length>1;return e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(ve,{className:r.conditionTypeFormControl},e.createElement(be,{value:t.levelType,onChange:l=>n==null?void 0:n(l.target.value)},e.createElement(H,{key:"anyOf",value:"anyOf"},"Any of"),e.createElement(H,{key:"allOf",value:"allOf"},"All of"),e.createElement(H,{key:"not",value:"not",disabled:a},"Not"))),e.createElement(E,{ml:1},e.createElement(j,{"aria-label":"delete",onClick:()=>n==null?void 0:n(null),size:"small"},e.createElement(De,null))))}function et(){return{id:pe(),ruleName:null,parameters:{}}}const Lo=C(t=>({treeVerticalSpacer:{width:t.spacing(2),borderLeft:`1px solid ${t.palette.status.aborted}`},treeHorizontalSpacer:{height:t.spacing(3),borderLeft:`1px solid ${t.palette.status.aborted}`},treeVerticalBranchHalf:{position:"absolute",height:"50%",borderLeft:`1px solid ${t.palette.status.aborted}`,alignSelf:"flex-start"},treeVerticalBranchFull:{borderLeft:`1px solid ${t.palette.status.aborted}`,alignSelf:"stretch"},treeHorizontalBranch:{width:t.spacing(2),borderTop:`1px solid ${t.palette.status.aborted}`}}));function Sn({level:t,resourceType:n,onChange:r,parentConditionType:a,isRoot:l=!1}){const o=Lo(),i=I((f,y)=>{const g=[...t.children];return g.splice(f,1,y),g},[t]),c=I(f=>{r({...t,children:f})},[r,t]),m=I(f=>{f===null?r(null):f==="not"&&t.children.length>1?r({...t,levelType:f,children:t.children.slice(0,1)}):r({...t,levelType:f})},[r,t]),s=I((f,y)=>{c(f===null?An(t.children,y):i(y,f))},[t,c,i]),p=f=>{const y=pe();f==="condition"?c([...t.children,et()]):f==="not"?c([...t.children,{id:y,levelType:f,children:[]}]):pa(f)&&c([...t.children,{id:y,levelType:f,children:[et()]}])},u=f=>{c(An(t.children,f))},d=B(()=>t.children.map((f,y)=>(g,w)=>{c(i(y,{...f,ruleName:g,parameters:w}))}),[t.children,c,i]),x=B(()=>t.children.map((f,y)=>g=>s(g,y)),[t.children,s]);return e.createElement("div",null,!l&&e.createElement("div",{className:o.treeHorizontalSpacer}),e.createElement(E,{display:"flex",alignItems:"center",position:"relative"},!l&&e.createElement(e.Fragment,null,e.createElement("div",{className:a==="not"?o.treeVerticalBranchHalf:o.treeVerticalBranchFull}),e.createElement("div",{className:o.treeHorizontalBranch})),e.createElement(Bo,{level:t,onSelect:m})),e.createElement(E,{display:"flex"},l||a==="not"?e.createElement(E,{pl:2}):e.createElement("div",{className:o.treeVerticalSpacer}),!l&&e.createElement(E,{pl:2}),e.createElement("div",null,t.children.map((f,y)=>Se(f)?e.createElement(E,{key:f.id},e.createElement(Sn,{level:f,resourceType:n,parentConditionType:t.levelType,onChange:x[y]})):e.createElement(Fe,{key:f.id},e.createElement("div",{className:o.treeHorizontalSpacer}),e.createElement(E,{display:"flex",alignItems:"center",position:"relative"},e.createElement("div",{className:t.levelType==="not"?o.treeVerticalBranchHalf:o.treeVerticalBranchFull}),e.createElement("div",{className:o.treeHorizontalBranch}),e.createElement(Tn,{ruleName:f.ruleName,parameters:f.parameters,resourceType:n,onChange:d[y],onDelete:()=>u(y)})))),!(t.levelType==="not"&&t.children.length>=1)&&e.createElement(e.Fragment,null,e.createElement("div",{className:o.treeHorizontalSpacer}),e.createElement(E,{display:"flex",alignItems:"center",position:"relative"},e.createElement("div",{className:o.treeVerticalBranchHalf}),e.createElement("div",{className:o.treeHorizontalBranch}),e.createElement(Dn,{onSelect:p}))))))}function An(t,n){const r=[...t];return r.splice(n,1),r}const Mo=C(t=>({paper:{backgroundColor:t.palette.background.default,padding:t.spacing(3),marginBottom:t.spacing(3),minHeight:t.spacing(48)}}));function Fo({permissionCriteria:t,resourceType:n,onUpdate:r,readonly:a=!1}){const l=Mo(),o=I(p=>{r(u=>({...u,...p}))},[r]),i=I(p=>{const u=pe();o(p==="condition"?et():p==="not"?{id:u,levelType:p,children:[]}:{id:u,levelType:p,children:[et()]})},[o]),c=I((p,u)=>{r(d=>({...d,ruleName:p,parameters:u}))},[r]),m=I(()=>{r(null)},[r]);let s;return a?s=e.createElement(un,{permissionCriteria:t}):t===null?s=e.createElement(Dn,{onSelect:i}):Ct(t)?s=e.createElement(Tn,{ruleName:t.ruleName,parameters:t.parameters,resourceType:n,onChange:c,onDelete:m}):Se(t)&&(s=e.createElement(Sn,{level:t,resourceType:n,onChange:r,isRoot:!0})),e.createElement(at,{variant:"outlined",className:l.paper},s)}const zo="Action";function Wo({actions:t,readonly:n,onActionsChange:r}){return e.createElement(mt,{multiple:!0,id:"match-by-attribute-dropdown",options:["create","read","update","delete"],getOptionLabel:a=>a,value:t!=null?t:[],onChange:(a,l)=>r==null?void 0:r(l),filterSelectedOptions:!0,renderInput:a=>e.createElement(ce,{...a,variant:"outlined",label:zo,placeholder:"Choose attributes",margin:"normal"}),disabled:n})}const Ho=C(()=>({fullWidth:{width:"100%","& > *":{flexGrow:1}}})),Rn="Permission name";function Uo({name:t="",readonly:n,onNameChange:r}){const a=Ho(),{permissions:l}=Te();return e.createElement(ve,{className:a.fullWidth,variant:"outlined",disabled:n,"data-testid":"match-by-name-select"},e.createElement(de,{id:"match-by-name-dropdown"},Rn),e.createElement(be,{labelId:"match-by-name-dropdown",label:Rn,value:l?t:"",onChange:o=>r==null?void 0:r(o.target.value)},l==null?void 0:l.map(o=>e.createElement(H,{key:o.name,value:o.name},o.name))))}const Vo=C(()=>({fullWidth:{width:"100%","& > *":{flexGrow:1}}})),$n="Resource type";function Go({resourceType:t="",readonly:n,onResourceTypeChange:r}){const a=Vo(),l=en();return e.createElement(ve,{className:a.fullWidth,variant:"outlined",disabled:n,"data-testid":"match-by-resource-select"},e.createElement(de,{id:"match-by-resource-dropdown"},$n),e.createElement(be,{labelId:"match-by-resource-dropdown",label:$n,value:l?t:"",onChange:o=>r==null?void 0:r(o.target.value),displayEmpty:!0},l==null?void 0:l.map(o=>e.createElement(H,{key:o,value:o},o))))}function In(t){return`${t.palette.primary.main}50`}const jo=C(t=>({toggleButton:{"&.Mui-selected":{backgroundColor:In(t),color:t.palette.primary.main},"&.Mui-selected:hover":{backgroundColor:"#97BBE8"},color:t.palette.primary.main,border:`1px solid ${t.palette.primary.main}`}}));function Dt({className:t,...n}){const r=jo();return e.createElement(jr,{className:`${r.toggleButton} ${t}`,...n})}const _o=C({fullWidth:{width:"100%","& > *":{flexGrow:1}}});function Yo({className:t,fullWidth:n,...r}){const a=_o();return e.createElement(_r,{className:`${n?a.fullWidth:""} ${t}`,...r})}const Jo=C(t=>({indicator:{right:"unset"},tab:{maxWidth:"none","&.Mui-selected":{backgroundColor:In(t),color:t.palette.primary.main}}}));function qo({options:t,selected:n,onChange:r,readonly:a=!1}){const l=Jo();return e.createElement(fr,{orientation:"vertical",value:t.map(({id:o})=>o).indexOf(n),onChange:(o,i)=>r(t[i].id),indicatorColor:"primary",TabIndicatorProps:{className:l.indicator}},t.map(o=>e.createElement(yr,{key:o.id,label:o.displayText.toUpperCase(),className:l.tab,disabled:a})))}const Ko=C(t=>({dialogTitle:{display:"flex",alignItems:"center",justifyContent:"space-between"},fullWidth:{width:"100%","& > *":{flexGrow:1}},infoIcon:{position:"absolute",right:t.spacing(3)},content:{padding:t.spacing(7)},saveButton:{paddingLeft:t.spacing(5),paddingRight:t.spacing(5)},contentContainerConditional:{display:"flex",gap:t.spacing(5),maxWidth:1480}})),Qo={specificPermission:"Choose a specific permission",filter:"Filter by permission properties",all:"Match all permissions"},kn="Choose the name of a resource permission or filter by resource type to set a conditional decision.";function Xo({rolePermission:t,readonly:n=!1,onClose:r,onSave:a}){const l=Ko(),{permissions:o}=Te(),i=Zt(),c=ea(),m=ba(t),[s,p]=R(m.match),[u,d]=R(m.decisionType),[x,f]=R(m.criteria),y=B(()=>fo(o,s),[o,s]),g=u==="conditional",w=g?"xl":"sm";J(()=>{g&&o&&!y.commonResourceType&&d("allow")},[g,o,y.commonResourceType,d]);const S=A=>{A!==null&&d(A)},T=B(()=>s.method==="specificPermission"&&!s.name||s.method==="filter"&&!s.resourceType&&!s.actions,[s]),z=B(()=>y.permissions.length===0?!1:!T,[y,T]),M=B(()=>u!=="conditional"?!0:!(!y.commonResourceType||!(c!=null&&c[y.commonResourceType].pluginId)||!pn(x,i)),[u,y,c,x,i]),b=()=>{a==null||a(wa(m.id,s,u==="conditional"?{resourceType:y.commonResourceType,pluginId:c[y.commonResourceType].pluginId,conditions:xt(x)}:u))};return e.createElement(ie,{open:!0,maxWidth:w,onClose:r,fullWidth:!0},e.createElement(He,{disableTypography:!0,className:l.dialogTitle},e.createElement(h,{variant:"h4",component:"h2"},"New Permission Decision"),e.createElement(P,{startIcon:e.createElement(ct,null),onClick:r},"Close")),e.createElement(ee,{dividers:!0,className:l.content},e.createElement(E,{className:g?l.contentContainerConditional:void 0},e.createElement(E,{mb:5,flex:1},e.createElement(qo,{options:Object.entries(Qo).map(([A,v])=>({id:A,displayText:v})),selected:s.method,onChange:A=>p({method:A}),readonly:n})),e.createElement(E,{mb:5,height:189,flex:1},s.method==="specificPermission"&&e.createElement(Uo,{name:s.name,readonly:n,onNameChange:A=>p({...s,name:A})}),s.method==="filter"&&e.createElement(e.Fragment,null,e.createElement(Go,{resourceType:s.resourceType,readonly:n,onResourceTypeChange:A=>p({...s,resourceType:A})}),e.createElement(Wo,{actions:s.actions,readonly:n,onActionsChange:A=>p({...s,actions:A.length?A:void 0})}),T?null:e.createElement(e.Fragment,null,e.createElement(E,{marginY:2},e.createElement(it,{variant:"middle"})),e.createElement(lt,null,`Matched ${y.permissions.length} ${y.permissions.length===1?"permission":"permissions"}`)))),e.createElement(E,{mb:5,flex:1},e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(Yo,{value:u,exclusive:!0,fullWidth:!0,"aria-label":"Decision result",onChange:(A,v)=>S(v)},e.createElement(Dt,{value:"allow","aria-label":"Decision allowed",disabled:n},"Allow"),e.createElement(Dt,{value:"deny","aria-label":"Decision denied",disabled:n},"Deny"),e.createElement(Dt,{value:"conditional","aria-label":"Decision conditionally allowed",disabled:!y.commonResourceType||n},"Conditional")),!g&&!n&&e.createElement(ge,{title:kn},e.createElement(Ht,{className:l.infoIcon,color:"primary","aria-label":kn}))))),u==="conditional"&&!!y.commonResourceType&&e.createElement(Fo,{permissionCriteria:x,resourceType:y.commonResourceType,onUpdate:f,readonly:n}),!n&&e.createElement(E,{display:"flex",justifyContent:"flex-end"},e.createElement(P,{variant:"contained",color:"primary",className:l.saveButton,onClick:b,disabled:!z||!M},"Save"))))}const Zo=e.forwardRef(function({children:t,role:n,...r},a){const l=B(()=>{const i=[];return Pt.forEach(t,c=>{if(ze(c)){const m=c.props.children[0];ze(m)&&i.push(m);const s=c.props.children[1];if(ze(s)){const p=Pt.toArray(s.props.children).filter(ze);i.push(...p)}}}),i},[t]),o=l.length;return e.createElement("div",{ref:a},e.createElement("ul",{...r},e.createElement(dl,{height:250,width:250,rowHeight:54,overscanCount:5,rowCount:o,rowRenderer:i=>e.cloneElement(l[i.index],{style:{...i.style,whiteSpace:"nowrap"}}),role:n})))}),ei=C({autocomplete:{display:"flex",flex:1}});function ti({members:t,options:n,namespaceOptions:r,loading:a=!1,disabled:l=!1,isMultiNamespaces:o=!1,onTextChange:i,onToggleMember:c,onChange:m}){const[s,p]=R(!1),u=ei(),[d,x]=Zn(g=>g+1,0),f=(g,w)=>{w&&(c(w),x())};J(()=>{s&&i("")},[s,i]);const y=o?r.concat((n==null?void 0:n.members)||[]):(n==null?void 0:n.members)||[];return e.createElement(E,{width:250},e.createElement(mt,{key:`${d}`,open:s,onOpen:()=>{p(!0)},onClose:()=>{p(!1)},onChange:f,getOptionLabel:Ie,groupBy:ni,ListboxComponent:Zo,renderOption:g=>e.createElement(e.Fragment,null,e.createElement(Ce,{id:`checkbox-${g.entityRef}`,checked:t.includes(g.entityRef),color:"primary"}),e.createElement("label",{htmlFor:`checkbox-${g.entityRef}`},o?Ie(g,!1):Ie(g))),options:y,openOnFocus:!0,disabled:l,loading:a,className:u.autocomplete,renderInput:g=>e.createElement(ce,{...g,label:o?"Select members":"Select specific users/groups",variant:"standard",onChange:m,InputProps:{...g.InputProps,endAdornment:e.createElement(e.Fragment,null,a?e.createElement(Tt,{color:"inherit",size:20}):null,g.InputProps.endAdornment)}})}))}function Ie(t,n=!0){var r;const a=ne(t.entityRef);return a.name==="*"?a.namespace:sl({...a,name:(r=t.name)!=null?r:a.name},{defaultKind:a.kind,defaultNamespace:n?cl:!1})}const On={user:"USERS",group:"GROUPS",namespace:"NAMESPACES"};function ni(t){const{name:n,kind:r}=ne(t.entityRef),a=n==="*"?"namespace":r;if(!On[a])throw new Error(`Group '${a}' is not supported for members in a policy`);return On[a]}const ri=C(t=>({actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0},typeIcon:{color:t.palette.grey[500]}}));function li({diff:t,loading:n,isMultiNamespaces:r,members:a,error:l,onToggleMember:o,readonly:i=!1}){const c=ri();if(n)return e.createElement(U,null,e.createElement(D,{scope:"row",colSpan:i?4:5},e.createElement(ke,null)));if(l&&l.message!=null,a==="*")return e.createElement(U,null,e.createElement(D,{colSpan:2,height:80},"All"),e.createElement(D,{colSpan:i?2:3},e.createElement($e,{operation:t==null?void 0:t.members["*"].operation})));if(a.length===0)return e.createElement(U,null,e.createElement(D,{scope:"row",colSpan:i?4:5},"Select users or groups using the drop-down menu above."));const m=a.sort((s,p)=>{let u=0;r&&p.name==="*"&&s.name!=="*"?u=1:r&&s.name==="*"&&p.name!=="*"&&(u=-1);const d=s.type.localeCompare(p.type),x=ne(s.entityRef).namespace.localeCompare(ne(p.entityRef).namespace),f=ne(s.entityRef).name.localeCompare(ne(p.entityRef).name);return u||d||x||f});return e.createElement(e.Fragment,null,m.map(s=>{var p;const{name:u,type:d,entityRef:x}=s;return e.createElement(U,{key:x},e.createElement(D,{className:c.typeIconCol},d==="group"&&e.createElement(ul,{className:c.typeIcon})||r&&u==="*"&&e.createElement(pl,{className:c.typeIcon})||e.createElement(Bt,{className:c.typeIcon})),e.createElement(D,{scope:"row",className:c.nameCol},(p=r?Ie(s,!1):Ie(s))!=null?p:"Unknown"),e.createElement(D,{scope:"row"},u==="*"&&r?"namespace":d),e.createElement(D,null,u&&e.createElement($e,{operation:t==null?void 0:t.members[x].operation})),!i&&e.createElement(D,{scope:"row",className:c.actionCol},e.createElement(j,{"aria-label":"Remove member",onClick:()=>o(s),size:"small"},e.createElement(De,null))))}))}const ai=C(()=>({header:{display:"flex",flexDirection:"row",justifyContent:"space-between",paddingLeft:"1rem",paddingRight:"1rem",gap:"1rem"},actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0}}));function oi({diff:t,policyId:n,role:r,onToggleMember:a,readonly:l=!1,debounceTime:o=1e3}){const i=k(V),c=k(ml),m=ai(),s=r.members==="*",[p,u]=R(""),{current:d}=ye({}),x=v=>{d[v.entityRef]=v,a(v.entityRef)},f=v=>{var $;if(d[v])return d[v];const L=ne(v);return{entityRef:v,type:L.kind.toLowerCase(),name:($=L.name)!=null?$:v}},{value:y,loading:g}=Xl(),{loading:w,value:S}=we(async()=>{const v=await c.getEntityFacets({facets:["metadata.namespace"]}).then($=>$.facets["metadata.namespace"].map(L=>L.value));return ii(v)},[c]),T=S?(S==null?void 0:S.length)>1:!1,z=S?S.filter(v=>v.entityRef.toLowerCase().includes(p)):[],M=B(()=>gr(v=>{u(v.target.value.toLowerCase())},o),[u,o]),{loading:b,error:A}=we(async()=>{r.members==="*"||r.members.length===0||(await i.getPolicy(n)).roles.find(v=>v.id===r.id)===void 0||r.members.forEach(v=>{const $=f(v);d[$.entityRef]=$})},[n,s]);return e.createElement(e.Fragment,null,e.createElement("div",{className:m.header},e.createElement("h2",null,"Members"),e.createElement(ti,{onToggleMember:x,members:r.members,disabled:l,options:y,namespaceOptions:z,isMultiNamespaces:T,loading:g||w,onTextChange:u,onChange:M})),e.createElement(Ue,{"data-testid":"membersTable"},e.createElement(Ve,null,e.createElement(U,null,e.createElement(D,{className:m.typeIconCol}),e.createElement(D,{className:m.nameCol},"Name"),e.createElement(D,null,"Type"),e.createElement(D,null),!l&&e.createElement(D,{className:m.actionCol}))),e.createElement(Ge,null,e.createElement(li,{diff:t,loading:b||w,isMultiNamespaces:T,error:A,members:Array.isArray(r.members)?r.members.map(f):r.members,onToggleMember:x,readonly:l}))))}function ii(t){return t.map(n=>({name:"*",type:"user",entityRef:`user:${n}/*`})).sort((n,r)=>n.entityRef.toLowerCase().localeCompare(r.entityRef.toLowerCase()))}const ci="Use the arrows to change the order in which permission decisions are evaluated.";function si({diff:t,permissions:n,onReorderPermissions:r,onNewPermissionClick:a,onOpenPermission:l,onRemovePermissionClick:o,anyAllow:i,readonly:c=!1}){return e.createElement(e.Fragment,null,e.createElement(E,{display:"flex",justifyContent:"space-between",padding:2},e.createElement(h,{variant:"h5"},"Permission Decisions"),!c&&n.length!==0&&e.createElement(P,{color:"primary",variant:"outlined",startIcon:e.createElement(ut,null),onClick:a},"New")),e.createElement(Ue,{"data-testid":"permissionsTable"},e.createElement(Ve,null,e.createElement(U,null,!c&&!i&&e.createElement(D,{style:{width:0}},e.createElement(xn,{helpText:ci})),e.createElement(D,null,"Match by"),e.createElement(D,null,"Decision"),e.createElement(D,null),!c&&e.createElement(D,null))),e.createElement(Ge,null,n.length===0&&e.createElement(U,null,e.createElement(D,{colSpan:5},e.createElement(Oe,{title:"No permission decisions set",description:"Click the button below to create your first permission.",missing:{customImage:e.createElement(wn,{src:El,alt:"No permission placeholder"})},action:e.createElement(P,{variant:"contained",color:"primary",onClick:a},"New permission decision")}))),n.map((m,s)=>e.createElement(U,{key:s},!c&&!i&&e.createElement(D,null,e.createElement(Cn,{array:n,index:s,onReorder:r})),e.createElement(D,null,e.createElement(hr,{onClick:()=>l(s)},e.createElement(h,{variant:"body2",color:"primary"},pt(m)))),e.createElement(D,null,bl(m)),e.createElement(D,null,e.createElement($e,{operation:t==null?void 0:t.permissions[m.id].operation})),!c&&e.createElement(D,{align:"right"},e.createElement(vn,{message:"Are you sure you want to remove this permission decision?",onConfirm:()=>o(s),title:"Remove?"},p=>e.createElement(j,{...p,"aria-label":"Remove permission decision",size:"small"},e.createElement(De,null)))))))))}function mi({roleId:t}){const{versionId:n,roleId:r}=nt(),a=t!=null?t:r;return je(a),je(n),e.createElement(Qe,{policyId:n},e.createElement(ui,{roleId:a}))}const di=C(t=>({cardContainer:{margin:t.spacing(0)}}));function ui({roleId:t}){const{diff:n,updateLocalDraft:r,policy:a}=_(),l=a.roles.find(v=>v.id===t),o=n==null?void 0:n.roles[t],[i,c]=R(null),[m,s]=R(!1),p=tt(),{NotFoundErrorPage:u}=p.getComponents(),d=q(),x=di();if(!l)return e.createElement(u,null);const f=l.name,y=v=>{const $=a.roles.findIndex(re=>re.id===v.id),L=[...a.roles];L.splice($,1,v),r({...a,roles:L})},g=v=>{y({...l,name:v})},w=v=>{if(i===null)y({...l,permissions:[v,...l.permissions]});else{const $=[...l.permissions];$.splice(i,1,v),y({...l,permissions:$})}s(!1)},S=v=>{if(v==="*")y({...l,members:l.members==="*"?[]:"*"});else if(l.members==="*")y({...l,members:[v]});else{const $=l.members.includes(v)?l.members.filter(L=>L!==v):[...l.members,v];y({...l,members:$.length===0?"*":$})}},T=v=>{y({...l,permissions:l.permissions.filter(($,L)=>v!==L)})},z=v=>{y({...l,permissions:v})},M=nn(Sr.safeParse(l)).name,b=a.status!=="draft",A=a.options.resolutionStrategy==="any-allow";return e.createElement(e.Fragment,null,e.createElement(qe,{pages:[{title:a.name,path:`../../../${a.id}`},{title:f}],header:e.createElement(Be,{titleComponent:e.createElement(ln,null,a.name," \xA0\u01C0",b?e.createElement(e.Fragment,null,"\xA0",f):e.createElement(rn,{invalid:M,value:f,name:"Role name",onTextChange:g}),e.createElement($e,{operation:o==null?void 0:o.role.operation,size:"medium"})),description:a.description||void 0},e.createElement(P,{variant:"outlined",color:"primary",onClick:()=>d("../..",{relative:"path"})},"Back to policy"))},e.createElement(O,{container:!0,className:x.cardContainer,spacing:4,direction:"row"},e.createElement(O,{item:!0,xs:6},e.createElement(te,null,e.createElement(oi,{diff:o||null,role:l,policyId:a.id,onToggleMember:S,readonly:b}))),e.createElement(O,{item:!0,xs:6},e.createElement(te,null,e.createElement(si,{diff:o||null,permissions:l.permissions,onNewPermissionClick:()=>{c(null),s(!0)},onOpenPermission:v=>{c(v),s(!0)},onReorderPermissions:z,onRemovePermissionClick:T,anyAllow:A,readonly:b}))))),m&&e.createElement(Xo,{rolePermission:i!==null?l.permissions[i]:void 0,onClose:()=>s(!1),onSave:w,readonly:b}))}function pi(){const t=tt(),{NotFoundErrorPage:n}=t.getComponents();return e.createElement(nr,{loading:e.createElement(ke,null),unauthorized:e.createElement(n,null)},e.createElement(gl,null,e.createElement(Zl,null,e.createElement(Ql,null,e.createElement(tr,null,e.createElement(We,{element:e.createElement(Kl,null),path:"/"}),e.createElement(We,{element:e.createElement(uo,null),path:"/versions/:versionId"}),e.createElement(We,{element:e.createElement(aa,null),path:"/versions/:versionId/options"}),e.createElement(We,{element:e.createElement(mi,null),path:"/versions/:versionId/roles/:roleId"}))))))}export{pi as RBACRoot};
3
+ //# sourceMappingURL=Root-4f6e8190.esm.js.map
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import{createPlugin as r,createApiFactory as i,fetchApiRef as a,discoveryApiRef as p,createRoutableExtension as n,createComponentExtension as m}from"@backstage/core-plugin-api";import{r as t,a as R,R as c}from"./esm/routes-28afb55d.esm.js";import"@backstage/errors";import"@spotify/backstage-plugin-rbac-common";const o=r({id:"rbac",routes:{root:t},apis:[i({api:R,deps:{fetchApi:a,discoveryApi:p},factory(e){return new c(e)}})]}),A=o.provide(n({name:"RBACRoot",component:()=>import("./esm/Root-5eafe743.esm.js").then(e=>e.RBACRoot),mountPoint:t})),s=o.provide(m({name:"RBACSidebarItem",component:{lazy:()=>import("./esm/RBACSidebarItem-9beee132.esm.js").then(e=>e.RBACSidebarItem)}}));export{A as RBACRoot,s as RBACSidebarItem,o as rbacPlugin};
1
+ import{createPlugin as r,createApiFactory as i,fetchApiRef as a,discoveryApiRef as p,createRoutableExtension as n,createComponentExtension as m}from"@backstage/core-plugin-api";import{r as t,a as R,R as c}from"./esm/routes-28afb55d.esm.js";import"@backstage/errors";import"@spotify/backstage-plugin-rbac-common";const o=r({id:"rbac",routes:{root:t},apis:[i({api:R,deps:{fetchApi:a,discoveryApi:p},factory(e){return new c(e)}})]}),A=o.provide(n({name:"RBACRoot",component:()=>import("./esm/Root-4f6e8190.esm.js").then(e=>e.RBACRoot),mountPoint:t})),s=o.provide(m({name:"RBACSidebarItem",component:{lazy:()=>import("./esm/RBACSidebarItem-0273da79.esm.js").then(e=>e.RBACSidebarItem)}}));export{A as RBACRoot,s as RBACSidebarItem,o as rbacPlugin};
2
2
  //# sourceMappingURL=index.esm.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spotify/backstage-plugin-rbac",
3
3
  "description": "Control access to actions and data in Backstage with ease.",
4
- "version": "0.6.0",
4
+ "version": "0.6.1",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "homepage": "https://backstage.spotify.com",
7
7
  "main": "./dist/index.esm.js",
@@ -34,23 +34,23 @@
34
34
  "postpack": "backstage-cli package postpack"
35
35
  },
36
36
  "dependencies": {
37
- "@backstage/catalog-model": "^1.4.4",
38
- "@backstage/core-compat-api": "^0.2.0",
39
- "@backstage/core-components": "^0.14.0",
40
- "@backstage/core-plugin-api": "^1.9.0",
41
- "@backstage/errors": "^1.2.3",
42
- "@backstage/frontend-plugin-api": "^0.6.0",
43
- "@backstage/plugin-catalog-react": "^1.10.0",
44
- "@backstage/plugin-permission-common": "^0.7.12",
45
- "@backstage/plugin-permission-node": "^0.7.21",
46
- "@backstage/plugin-permission-react": "^0.4.20",
47
- "@backstage/theme": "^0.5.1",
37
+ "@backstage/catalog-model": "^1.4.5",
38
+ "@backstage/core-compat-api": "^0.2.1",
39
+ "@backstage/core-components": "^0.14.1",
40
+ "@backstage/core-plugin-api": "^1.9.1",
41
+ "@backstage/errors": "^1.2.4",
42
+ "@backstage/frontend-plugin-api": "^0.6.1",
43
+ "@backstage/plugin-catalog-react": "^1.11.0",
44
+ "@backstage/plugin-permission-common": "^0.7.13",
45
+ "@backstage/plugin-permission-node": "^0.7.25",
46
+ "@backstage/plugin-permission-react": "^0.4.21",
47
+ "@backstage/theme": "^0.5.2",
48
48
  "@backstage/types": "^1.1.1",
49
49
  "@material-ui/core": "^4.12.2",
50
50
  "@material-ui/icons": "^4.9.1",
51
51
  "@material-ui/lab": "4.0.0-alpha.61",
52
- "@spotify/backstage-plugin-core": "^0.6.0",
53
- "@spotify/backstage-plugin-rbac-common": "^0.5.11",
52
+ "@spotify/backstage-plugin-core": "^0.7.0",
53
+ "@spotify/backstage-plugin-rbac-common": "^0.5.12",
54
54
  "ajv": "^8.11.2",
55
55
  "file-saver": "^2.0.5",
56
56
  "js-yaml": "^4.1.0",
@@ -64,19 +64,19 @@
64
64
  "zod-to-json-schema": "^3.20.2"
65
65
  },
66
66
  "peerDependencies": {
67
- "@backstage/plugin-permission-node": "^0.7.21",
67
+ "@backstage/plugin-permission-node": "^0.7.25",
68
68
  "react": "^16.13.1 || ^17.0.0 || ^18.0.0",
69
69
  "react-router-dom": "6.0.0-beta.0 || ^6.3.0"
70
70
  },
71
71
  "devDependencies": {
72
- "@backstage/cli": "^0.25.2",
73
- "@backstage/core-app-api": "^1.12.0",
74
- "@backstage/dev-utils": "^1.0.27",
72
+ "@backstage/cli": "^0.26.0",
73
+ "@backstage/core-app-api": "^1.12.1",
74
+ "@backstage/dev-utils": "^1.0.28",
75
75
  "@backstage/e2e-test-utils": "^0.1.1",
76
- "@backstage/frontend-test-utils": "^0.1.2",
77
- "@backstage/test-utils": "^1.5.0",
76
+ "@backstage/frontend-test-utils": "^0.1.3",
77
+ "@backstage/test-utils": "^1.5.1",
78
78
  "@playwright/test": "^1.32.3",
79
- "@sp4b-dev/test-utils": "^0.0.1",
79
+ "@sp4b-dev/test-utils": "^0.0.2",
80
80
  "@testing-library/jest-dom": "^6.0.0",
81
81
  "@testing-library/react": "^14.0.0",
82
82
  "@testing-library/user-event": "^14.0.0",
@@ -1,3 +0,0 @@
1
- import{Breadcrumbs as Gn,Link as ae,Page as jn,Header as _n,Content as Yn,Table as Jn,Progress as ke,ErrorPanel as Nt,EmptyState as Oe,ContentHeader as Be,UserIcon as qn}from"@backstage/core-components";import{useRouteRef as Kn,useApi as k,alertApiRef as oe,useApp as tt,configApiRef as Qn}from"@backstage/core-plugin-api";import e,{createContext as Le,useState as R,useCallback as I,useMemo as B,useContext as Me,Fragment as Fe,useRef as ye,useEffect as J,useLayoutEffect as Xn,Children as Pt,isValidElement as ze,useReducer as Zn}from"react";import{useNavigate as q,Link as el,useParams as nt,Routes as tl,Route as We}from"react-router-dom";import{A as nl}from"./Authorized-2a69c12e.esm.js";import{makeStyles as C,Typography as h,Container as ll,Grid as O,Button as P,Box as E,Dialog as ie,DialogTitle as He,DialogContent as ee,TextField as ce,DialogActions as lt,CircularProgress as Tt,Tooltip as ge,Chip as se,Card as te,CardContent as he,List as rl,ListItem as St,ListItemIcon as me,ListItemText as Q,CardActions as al,IconButton as j,CardActionArea as ol,CardHeader as At,Radio as il,FormControl as ve,InputLabel as de,Select as be,Input as Rt,MenuItem as H,Checkbox as Ce,FormHelperText as rt,TableCell as D,TableContainer as cl,Table as Ue,TableHead as Ve,TableRow as U,TableBody as Ge,Accordion as sl,AccordionSummary as ml,AccordionDetails as dl,Paper as at,DialogContentText as ul,ButtonGroup as pl,Menu as $t,MenuList as ot,Divider as it,FormControlLabel as It,Popper as El,Tabs as fl,Tab as yl,debounce as gl,ButtonBase as hl}from"@material-ui/core";import vl from"react-use/lib/useMount";import{SpotifyLicenseBanner as bl,useAutoUpdatingRelativeTime as Cl,invariant as je}from"@spotify/backstage-plugin-core";import{r as xl,a as V}from"./routes-28afb55d.esm.js";import ue from"react-use/lib/useAsyncFn";import{PolicyConfigParser as _e,isConditionalDecision as Ye,isAllOfPermissionCriteria as wl,isAnyOfPermissionCriteria as Dl,isNotPermissionCriteria as Nl,getMatchingRolePermissions as kt,UpdateDraftRequestParser as Pl,isMatchingPermission as Tl,BackstageUserPlaceholder as xe,RoleParser as Sl}from"@spotify/backstage-plugin-rbac-common";import Al,{dump as Rl}from"js-yaml";import $l from"@material-ui/icons/FilterNone";import Il from"@material-ui/icons/Publish";import{DateTime as Je}from"luxon";import ct from"@material-ui/icons/Close";import we from"react-use/lib/useAsync";import Ot from"lodash/keyBy";import kl from"lodash/isEqual";import Ol from"@material-ui/icons/CalendarToday";import Bt from"@material-ui/icons/Person";import Bl from"@material-ui/icons/FiberManualRecord";import{v4 as pe}from"uuid";import{saveAs as Ll}from"file-saver";import Lt from"lodash/omit";import Ml from"lodash/pickBy";import Mt from"@material-ui/icons/ReportProblemOutlined";import Ft from"react-use/lib/useLocalStorage";import{isResourcePermission as st,AuthorizeResult as F}from"@backstage/plugin-permission-common";import{forEach as Fl,mapValues as zl,groupBy as Wl,uniq as Hl}from"lodash";import Ul from"@material-ui/icons/Check";import Vl from"@material-ui/icons/Edit";import Gl from"@material-ui/icons/Clear";import{Alert as zt,Autocomplete as mt,ToggleButton as jl,ToggleButtonGroup as _l}from"@material-ui/lab";import Yl from"@material-ui/icons/ExpandMore";import Jl from"@material-ui/icons/AccountTreeOutlined";import ql from"@material-ui/icons/CheckSharp";import Kl from"@material-ui/icons/NotInterested";import dt from"ajv";import Ql from"@material-ui/icons/InfoOutlined";import{z as Wt}from"zod";import ut from"@material-ui/icons/Add";import De from"@material-ui/icons/Delete";import Xl from"@material-ui/icons/KeyboardArrowDown";import Zl from"@material-ui/icons/KeyboardArrowUp";import Ht from"@material-ui/icons/Info";import er from"../images/no-roles.svg";import tr from"@material-ui/icons/MoreHoriz";import nr from"@material-ui/icons/Save";import lr from"@material-ui/icons/Settings";import rr from"@material-ui/icons/Undo";import ar from"@material-ui/icons/VerticalAlignTop";import or from"lodash/uniqBy";import ir from"@material-ui/icons/Remove";import{parseEntityRef as ne,DEFAULT_NAMESPACE as cr}from"@backstage/catalog-model";import{humanizeEntityRef as sr,catalogApiRef as mr}from"@backstage/plugin-catalog-react";import{List as dr}from"react-virtualized";import ur from"@material-ui/icons/Group";import pr from"@material-ui/icons/GroupWork";import Er from"../images/no-permissions.svg";import"@backstage/errors";const fr=C(t=>({breadcrumbs:{marginBottom:t.spacing(4)}}));function yr({pages:t}){const n=Kn(xl),l=fr();return e.createElement(Gn,{className:l.breadcrumbs},e.createElement(ae,{to:n()},"Home"),t.map(({title:a,path:r},o)=>r?e.createElement(ae,{to:r,key:r,relative:"path"},a):e.createElement(h,{key:`${o}`},a)))}function qe({children:t,header:n,pages:l}){return e.createElement(jn,{themeId:"tool"},e.createElement(bl,{backend:"rbac",invalidLicenseMessage:"Your existing policy will continue to apply, but you will be unable to make any changes until you enter a valid license."}),e.createElement(_n,{title:"Role Based Access Control"}),e.createElement(Yn,null,e.createElement(ll,{maxWidth:"lg"},e.createElement(O,{container:!0,spacing:4},e.createElement(O,{item:!0,xs:12},l&&e.createElement(yr,{pages:l}),n),t))))}const Ut=Le({hasDraftPolicy:!1,policies:void 0,setPolicies:()=>{},setPolicy:()=>{},getPolicy:()=>{},removePolicy:()=>{}}),Ke=()=>Me(Ut);function gr({children:t,initialState:n={policies:void 0,cache:{}}}){const[l,a]=R(n),r=I(m=>{a(s=>({...s,policies:m,cache:Vt(s.cache,m)}))},[]),o=I(m=>l.cache[m],[l.cache]),i=I(m=>a(s=>({...s,cache:{...s.cache,[m]:void 0},policies:void 0})),[]),c=I(m=>a(s=>({...s,policies:void 0,cache:Vt(s.cache,[m])})),[]);return e.createElement(Ut.Provider,{value:B(()=>{var m;return{hasDraftPolicy:((m=l.policies)==null?void 0:m.some(({status:s})=>s==="draft"))||!1,policies:l.policies,setPolicies:r,setPolicy:c,getPolicy:o,removePolicy:i}},[l.policies,r,c,o,i])},t)}function Vt(t,n){if(!n)return t;const l={...t};return n.forEach(a=>{l[a.id]=a}),l}const Ne=()=>{const t=k(V),{setPolicies:n,policies:l}=Ke(),[{loading:a,error:r},o]=ue(()=>t.getPolicies(),[t],l?{loading:!1,value:{items:l,totalItems:l.length}}:{loading:!0}),i=I(async()=>{const c=await o();n(c.items)},[o,n]);return{loading:a,error:r,fetchPolicies:i}};function hr(){const t=k(V),n=q(),l=k(oe);function a(r){var o,i;const c=(i=(o=r.target)==null?void 0:o.files)==null?void 0:i[0],m=new FileReader;c&&(m.readAsText(c,"utf-8"),m.onload=async s=>{var p,u;const d=(u=(p=s.target)==null?void 0:p.result)==null?void 0:u.toString();if(d){let x=null;try{x=Al.load(d)}catch{l.post({message:"YAML file is invalid",severity:"error"});return}const f=_e.safeParse(x);if(!f.success){l.post({message:"Imported policy is invalid",severity:"error"});return}const y=f.data;if((await t.getPolicies()).items.some(w=>w.status==="draft")){l.post({message:"Unable to import new policy due to existing draft policy",severity:"error"});return}const g=await t.createDraft(y);n(`./versions/${g.id}`),l.post({message:"Policy imported successfully",severity:"success"})}})}return e.createElement(P,{variant:"outlined",color:"primary",component:"label"},"Import",e.createElement("input",{role:"input",type:"file",hidden:!0,onChange:a,accept:".yaml"}))}function vr(t){throw new Error("Invalid state")}function br(t){var n;return Ye(t.decision)?"Conditional":(n={allow:"Allow",deny:"Deny"}[t.decision])!=null?n:"Unknown"}function pt(t){var n;if(t.match==="*")return"All";if(t.match.name)return t.match.name;const l=[];return t.match.resourceType&&l.push(t.match.resourceType),(n=t.match.actions)!=null&&n.length&&l.push(t.match.actions.join(", ")),l.join(" | ")}const Cr=(t,n)=>{const l={resolutionStrategy:{operation:"UNCHANGED",before:t==null?void 0:t.resolutionStrategy,after:n==null?void 0:n.resolutionStrategy}};for(const a of Object.keys(l)){const r=a;l[r].before!==l[r].after&&(l[r].operation="CHANGED")}return l},Et=(t,n)=>{const l=Object.entries(t);for(const[,a]of l){const r=n(a);for(const[,o]of l){const i=n(o);i.operation!=="ADDED"&&i.operation!=="REMOVED"&&(r.operation==="ADDED"&&r.indexAfter<i.indexAfter?i.indexBefore+=1:r.operation==="REMOVED"&&r.indexBefore<i.indexBefore&&(i.indexBefore-=1))}}for(const[,a]of l){const r=n(a);r.operation==="UNCHANGED"&&r.indexAfter!==r.indexBefore&&(r.operation=r.indexAfter>r.indexBefore?"MOVED_DOWN":"MOVED_UP")}return t},ft=(t,n)=>{if(t==="*")return n==="*"?{"*":{operation:"UNCHANGED",after:"*",before:"*",indexAfter:0,indexBefore:0}}:{"*":{operation:"REMOVED",after:null,before:"*",indexAfter:-1,indexBefore:0},...Object.fromEntries(n.map((a,r)=>[a,{operation:"ADDED",after:a,before:null,indexAfter:r,indexBefore:-1}]))};if(n==="*")return{"*":{operation:"ADDED",after:"*",before:null,indexAfter:0,indexBefore:-1},...Object.fromEntries(t.map((a,r)=>[a,{operation:"REMOVED",after:null,before:a,indexAfter:-1,indexBefore:r}]))};const l=Object.fromEntries(n.map((a,r)=>[a,{operation:"ADDED",after:a,before:null,indexAfter:r,indexBefore:-1}]));for(let a=0;a<t.length;a++){const r=t[a];l[r]?(l[r].before=r,l[r].indexBefore=a,l[r].operation="UNCHANGED"):l[r]={operation:"REMOVED",after:null,before:r,indexAfter:-1,indexBefore:a}}return Et(l,a=>a)},yt=(t,n)=>{const l=Ot(n,"id"),a=Object.fromEntries(n.map((r,o)=>[r.id,{operation:"ADDED",indexAfter:o,indexBefore:-1,after:r,before:null}]));for(let r=0;r<t.length;r++){const o=t[r];if(a[o.id]){const i=!kl(o,l[o.id]);a[o.id].before=o,a[o.id].indexBefore=r,a[o.id].operation=i?"CHANGED":"UNCHANGED"}else a[o.id]={operation:"REMOVED",after:null,before:o,indexAfter:-1,indexBefore:r}}return Et(a,r=>r)},xr=(t=[],n=[])=>{const l=Ot(n,"id"),a=Object.fromEntries(n.map((r,o)=>[r.id,{role:{operation:"ADDED",indexAfter:o,indexBefore:-1,after:r,before:null},members:ft([],r.members),permissions:yt([],r.permissions)}]));for(let r=0;r<t.length;r++){const o=t[r];if(l[o.id]){const i=l[o.id],c=ft(o.members,i.members),m=yt(o.permissions,i.permissions),s=Object.values(m).some(({operation:d})=>d!=="UNCHANGED"),p=Object.values(c).some(({operation:d})=>d!=="UNCHANGED"),u=o.name!==i.name||s||p;a[o.id].role.before=o,a[o.id].role.indexBefore=r,a[o.id].role.operation=u?"CHANGED":"UNCHANGED",a[o.id].members=c,a[o.id].permissions=m}else a[o.id]={role:{operation:"REMOVED",after:null,before:o,indexAfter:-1,indexBefore:r},members:ft(o.members,[]),permissions:yt(o.permissions,[])}}return Et(a,({role:r})=>r)},wr=(t,n)=>{const l=xr((t==null?void 0:t.roles)||[],n.roles||[]),a=Cr(t==null?void 0:t.options,n.options),r=(t==null?void 0:t.name)!==n.name,o=Object.values(a).some(({operation:i})=>i!=="UNCHANGED");return{policy:{operation:r||o?"CHANGED":"UNCHANGED",before:t,after:n},roles:l,options:a}},Gt=t=>{const n=k(V),{value:l,loading:a,error:r}=we(()=>n.getActivePolicy(),[n]);return B(()=>t&&!a&&!r?wr(l,t):null,[l,t,a,r])},Dr=(t,n)=>{switch(n){case"ADDED":return t.palette.success.main;case"REMOVED":return t.palette.errorText;case"CHANGED":return t.palette.infoText;case"MOVED_UP":case"MOVED_DOWN":return t.palette.infoText;case"UNCHANGED":default:return t.palette.text.primary}},Nr=t=>{switch(t){case"ADDED":return"success";case"REMOVED":return"error";case"CHANGED":return"info";case"MOVED_UP":case"MOVED_DOWN":return"info";case"UNCHANGED":default:return"info"}},Pr=t=>{switch(t){case"ADDED":return"New";case"REMOVED":return"Removed";case"CHANGED":return"Changed";case"MOVED_UP":return"Moved up";case"MOVED_DOWN":return"Moved down";case"UNCHANGED":default:return"No changes"}},Tr=C(t=>({root:({operation:n})=>({color:Dr(t,n)})})),W=t=>e.createElement(h,{...t,variant:"body2"}),N=t=>{const n=Tr(t);return e.createElement(E,{...t,className:n.root,component:"span",fontWeight:"fontWeightBold"})},jt=({policy:t})=>{var n,l,a,r;const o=Gt(t),i=(o==null?void 0:o.policy.operation)==="CHANGED"||Object.values((n=o==null?void 0:o.roles)!=null?n:{}).some(u=>u.role.operation!=="UNCHANGED")||((l=o==null?void 0:o.options)==null?void 0:l.resolutionStrategy.operation)==="CHANGED";if(!o||!i)return e.createElement(E,null,"No changes");const c=!!o.policy.before&&!!o.policy.after&&o.policy.before.name!==o.policy.after.name,m=o.options.resolutionStrategy.operation==="CHANGED",s=({before:u,after:d})=>u&&d&&u.name!==d.name,p=({operation:u})=>u!=="ADDED"&&u!=="REMOVED";return e.createElement(E,null,c&&e.createElement(W,null,"Policy name ",e.createElement(N,{operation:"CHANGED"},"changed")," from"," ",e.createElement(N,null,'"',(a=o.policy.before)==null?void 0:a.name,'"')," to"," ",e.createElement(N,null,'"',(r=o.policy.after)==null?void 0:r.name,'"')),m&&e.createElement(W,null,"Resolution Strategy ",e.createElement(N,{operation:"CHANGED"},"changed")," ","from ",e.createElement(N,null,'"',o.options.resolutionStrategy.before,'"')," to"," ",e.createElement(N,null,'"',o.options.resolutionStrategy.after,'"')),Object.entries(o.roles).map(([u,{role:d,permissions:x,members:f}])=>{var y,g,w,S,T,z;return e.createElement(Fe,{key:u},d.operation==="ADDED"&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(y=d.after)==null?void 0:y.name,'"')," has been"," ",e.createElement(N,{operation:"ADDED"},"added")),d.operation==="REMOVED"&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(g=d.before)==null?void 0:g.name,'"')," has been"," ",e.createElement(N,{operation:"REMOVED"},"removed")),s(d)&&e.createElement(W,null,"Role name changed from ",e.createElement(N,null,'"',(w=d.before)==null?void 0:w.name,'"')," ","to ",e.createElement(N,null,'"',(S=d.after)==null?void 0:S.name,'"')),d.indexAfter>d.indexBefore&&d.indexBefore!==-1&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(T=d.after)==null?void 0:T.name,'"')," has been"," ",e.createElement(N,{operation:"MOVED_DOWN"},"moved down")," in priority"),d.indexAfter<d.indexBefore&&d.indexAfter!==-1&&e.createElement(W,null,"Role ",e.createElement(N,null,'"',(z=d.after)==null?void 0:z.name,'"')," has been"," ",e.createElement(N,{operation:"MOVED_UP"},"moved up")," in priority"),p(d)&&e.createElement(e.Fragment,null,Object.entries(x).map(([M,b])=>{var A,v,$,L,le;const{before:X,after:Ee}=b,re=X&&pt(X),Z=Ee&&pt(Ee);return e.createElement(Fe,{key:M},b.operation==="ADDED"&&b.after&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',Z,'"')," has been"," ",e.createElement(N,{operation:"ADDED"},"added")," to"," ",e.createElement(N,null,'"',(A=d.after)==null?void 0:A.name,'"')),b.operation==="REMOVED"&&b.before&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',re,'"')," has been"," ",e.createElement(N,{operation:"REMOVED"},"removed")," ","from ",e.createElement(N,null,'"',(v=d.after)==null?void 0:v.name,'"')),b.operation==="CHANGED"&&e.createElement(W,null,re!==Z?e.createElement(e.Fragment,null,"Permission decision"," ",e.createElement(N,null,'"',re,'"')," has been"," ",e.createElement(N,{operation:"CHANGED"},"updated")," ","to ",e.createElement(N,null,'"',Z,'"')):e.createElement(e.Fragment,null,"Permission decision"," ",e.createElement(N,null,'"',re,'"')," has been"," ",e.createElement(N,{operation:"CHANGED"},"updated"))," ","in ",e.createElement(N,null,'"',($=d.after)==null?void 0:$.name,'"')),b.indexAfter>b.indexBefore&&b.indexBefore!==-1&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',Z,'"')," has been"," ",e.createElement(N,{operation:"MOVED_DOWN"},"moved down")," ","in priority in"," ",e.createElement(N,null,'"',(L=d.after)==null?void 0:L.name,'"')),b.indexAfter<b.indexBefore&&b.indexAfter!==-1&&e.createElement(W,null,"Permission decision"," ",e.createElement(N,null,'"',Z,'"')," has been"," ",e.createElement(N,{operation:"MOVED_UP"},"moved up")," ","in priority in"," ",e.createElement(N,null,'"',(le=d.after)==null?void 0:le.name,'"')))}),Object.entries(f).map(([M,b])=>{var A,v;return e.createElement(Fe,{key:M},b.operation==="ADDED"&&b.after&&e.createElement(W,null,"Member ",e.createElement(N,null,'"',b.after,'"')," has been"," ",e.createElement(N,{operation:"ADDED"},"added")," to"," ",e.createElement(N,null,'"',(A=d.after)==null?void 0:A.name,'"')),b.operation==="REMOVED"&&b.before&&e.createElement(W,null,"Member ",e.createElement(N,null,'"',b.before,'"')," has been"," ",e.createElement(N,{operation:"REMOVED"},"removed")," from"," ",e.createElement(N,null,'"',(v=d.after)==null?void 0:v.name,'"')))})))}))},Sr=C(t=>({closeButton:{color:t.palette.text.secondary},diffSummaryContainer:{backgroundColor:t.palette.background.default,marginBottom:t.spacing(2)}}));function gt({open:t,onPublish:n,onClose:l,policy:a}){const[r,o]=R(!1),i=Sr(),c=ye(null),m=async()=>{var s,p;o(!0),await n((p=(s=c.current)==null?void 0:s.value)!=null?p:""),o(!1)};return e.createElement(ie,{open:t,onClose:l,fullWidth:!0},e.createElement(He,null,e.createElement(E,{display:"flex",justifyContent:"space-between",alignItems:"center"},"Ready to publish?",e.createElement(P,{startIcon:e.createElement(ct,null),onClick:l,className:i.closeButton},"Close")),e.createElement(h,null,"Double check your changes, then click Publish to activate this version of your policy. This will immediately apply the permissions defined in this version across Backstage.")),e.createElement(ee,{className:i.diffSummaryContainer,dividers:!0},e.createElement(jt,{policy:a})),e.createElement(ee,null,e.createElement(ce,{variant:"outlined",fullWidth:!0,label:"Summary (optional)",placeholder:"Briefly describe this version (or changes from a previous version)",inputRef:c})),e.createElement(lt,null,e.createElement(P,{color:"primary",onClick:m,disabled:r},r?e.createElement(Tt,{size:20}):"Publish")))}const Ar=C(()=>({root:{display:"inline-flex"}})),_t=({timestamp:t,description:n})=>{const l=Ar(),a=Je.fromISO(t).toLocaleString(Je.DATETIME_FULL),r=Cl(t),o=n?`${n}${r}`:r;return e.createElement("span",{className:l.root},e.createElement(ge,{title:a},e.createElement(h,{component:"span",display:"inline",variant:"inherit"},o)))};function Yt(t,n,l){var a,r;let o=n.created,i=t.createdBy;l!=null&&l.created&&(i=l.created+i);let c=t.createdAt;return t.status==="active"?(o=n.published,i=(a=t.lastPublishedBy)!=null?a:"",l!=null&&l.published&&(i=l.published+i),c=(r=t.lastPublishedAt)!=null?r:""):t.createdAt!==t.updatedAt&&(o=n.updated,i=t.updatedBy,l!=null&&l.updated&&(i=l.updated+i),c=t.updatedAt),{activityDateText:o,activityUser:i,timestamp:c}}const Rr=C(t=>({chip:{margin:0},icon:{color:t.palette.success.main}}));function Jt(t){const n=Rr();return t.status==="inactive"?null:t.status==="draft"?e.createElement(se,{className:n.chip,label:"Draft",size:t.size}):e.createElement(se,{className:n.chip,classes:{icon:n.icon},label:"Active",icon:e.createElement(Bl,null),size:t.size})}const $r=C(t=>({card:n=>({backgroundImage:n.policy.status==="active"?"linear-gradient(256.15deg, #00782A 19.77%, #1DB954 100%)":"linear-gradient(256.15deg, #BDBDBD 19.77%, #EEEEEE 100%)",backgroundPosition:"top",backgroundSize:"100% 8px",backgroundRepeat:"no-repeat",paddingTop:"8px",height:"100%"}),diffSummaryContainer:{backgroundColor:t.palette.background.default,padding:t.spacing(2),borderWidth:"1px",borderStyle:"solid",borderColor:t.palette.divider,borderRadius:t.shape.borderRadius},header:{display:"flex",justifyContent:"space-between",alignItems:"center"},detailsHeader:{...t.typography.body1,paddingTop:t.spacing(2),color:t.palette.text.secondary},activityList:{color:t.palette.text.secondary},activityListItem:{padding:0},actions:{justifyContent:"flex-start"}}));function Pe(t){const n=$r(t),{policy:l,to:a,withChangeSummary:r}=t,o=`${l.name} ${l.status==="draft"?"- Draft":""}`,i={created:"Created: ",published:"Published: ",updated:"Updated: "},c={created:"Created by ",published:"Published by ",updated:"Updated by "},{activityDateText:m,activityUser:s,timestamp:p}=Yt(l,i,c);return e.createElement(te,{className:n.card},e.createElement(he,null,e.createElement("div",{className:n.header},a?e.createElement(ae,{to:`versions/${l.id}`},e.createElement(h,{variant:"h5",component:"h1"},o)):e.createElement(h,{variant:"h5",component:"h1"},o),l.status==="active"?e.createElement(Jt,{status:"active",size:"small"}):null),l.description?e.createElement(h,{variant:"body1",color:"textSecondary"},'"',l.description,'"'):null,e.createElement(h,{component:"h2",className:n.detailsHeader},"Details"),e.createElement(rl,{className:n.activityList},e.createElement(St,{className:n.activityListItem},e.createElement(me,null,e.createElement(Ol,null)),e.createElement(Q,{primary:e.createElement(_t,{timestamp:p,description:m})})),e.createElement(St,{className:n.activityListItem},e.createElement(me,null,e.createElement(Bt,null)),e.createElement(Q,{primary:s}))),r&&e.createElement(E,{paddingTop:2},e.createElement(h,{gutterBottom:!0,variant:"subtitle2"},"What's changed"),e.createElement(E,{className:n.diffSummaryContainer},e.createElement(jt,{policy:l})))),t.actions?e.createElement(al,{className:n.actions},t.actions):null)}const Ir=C(t=>({paper:{padding:t.spacing(2,2,0,2)}})),ht=({isOpen:t,onClose:n,policy:l})=>{const a=Ir();return e.createElement(ie,{classes:{...a},open:t,onClose:n},e.createElement(He,{disableTypography:!0},e.createElement(E,{display:"flex",flexDirection:"row"},e.createElement(E,null,e.createElement(h,{variant:"h4",component:"h2"},"Success!"),e.createElement(h,null,l.name," has been published and is now your active policy.")),e.createElement(E,null,e.createElement(j,{onClick:n,title:"Close dialog"},e.createElement(ct,null))))),e.createElement(ee,null,e.createElement(Pe,{policy:l})),e.createElement(lt,null,e.createElement(E,{display:"flex",flexDirection:"row",flexGrow:1,justifyContent:"flex-start"},e.createElement(P,{component:el,color:"primary",onClick:n,role:"link",to:"/rbac"},"View all versions"))))};function vt(){const t=k(V),n=k(oe),l=q(),{fetchPolicies:a}=Ne();return ue(async r=>{if(!r)return;const{roles:o,name:i,options:c}=r;try{const m=await t.createDraft({roles:o,options:c,name:i});return await a(),l(`/rbac/versions/${m.id}`),m}catch(m){throw m instanceof Error&&n.post({message:m.message,severity:"error"}),m}},[l,t,n,a])}function bt(){const t=k(V),n=k(oe),l=ue(async(r,o,i)=>{if(r)return await t.publishPolicy(r.id,{description:o,update:i}),t.getPolicy(r.id)},[]),[{error:a}]=l;return J(()=>{a&&n.post({message:a.message,severity:"error"})},[a,n]),l}const kr=[{title:"Name",field:"name",render:t=>e.createElement(ae,{to:`versions/${t.id}`},t.name)},{title:"Status",field:"status",render:t=>{switch(t.status){case"active":return"Active";case"draft":return"Draft";case"inactive":return"Inactive";default:return vr(t.status)}}},{title:"Publish date",field:"lastPublishedAt",render:t=>t.lastPublishedAt?Je.fromISO(t.lastPublishedAt).toLocaleString(Je.DATETIME_MED_WITH_SECONDS):"",type:"datetime",defaultSort:"desc"},{title:"Published by",field:"lastPublishedBy"}];function Or(t){const n=t.data.length>3,{fetchPolicies:l}=Ne(),[{loading:a},r]=vt(),[{loading:o,value:i},c]=bt(),[m,s]=R(void 0),[p,u]=R(!1),d=()=>{s(void 0),l()},x=(m==null?void 0:m.id)===(i==null?void 0:i.id)?i:void 0,f=[y=>{const{tableData:g,...w}=y;return{icon:Il,tooltip:"Republish",onClick:()=>{s(w),u(!0)},disabled:o}},y=>{const{tableData:g,...w}=y;return{icon:$l,tooltip:"Duplicate",disabled:a||!t.canDuplicate,onClick:()=>r(w)}}];return e.createElement(e.Fragment,null,e.createElement(Jn,{title:"Previous Versions",columns:kr,data:t.data,options:{paging:n,pageSize:3,pageSizeOptions:[3,5,10,20],actionsColumnIndex:-1,loadingType:"linear"},actions:f}),m&&e.createElement(gt,{open:p,onPublish:y=>{c(m,y),u(!1)},onClose:()=>{s(void 0),u(!1)},policy:m}),x&&e.createElement(ht,{isOpen:!0,policy:x,onClose:d}))}function Br(t){var n,l;return((l=(n=t==null?void 0:t.body)==null?void 0:n.response)==null?void 0:l.statusCode)===404}function qt(t){const n=new Blob([Lr(t)],{type:"text/yaml"});Ll(n,`${(t.name||"policy").toLocaleLowerCase().replace(/\W/g,"-")}.yaml`)}function Lr(t){const{name:n,roles:l,options:a,description:r}=t;return`# this is an autogenerated file, do not edit
2
- ${Rl(Ml({name:n,description:r,options:a,roles:l.map(({permissions:o,...i})=>({...Lt(i,["id"]),permissions:o.map(c=>Lt(c,["id"]))}))},o=>o!==null||o!==void 0))}`}const Mr=({serverPolicy:t,localPolicy:n})=>!n||!t?{policy:t,policyConflict:!1}:t.status!=="draft"?{policy:t,policyConflict:!1}:n.id!==t.id?{policy:t,policyConflict:!1}:n.updatedAt===t.updatedAt?{policy:n,policyConflict:!1}:{policy:n,policyConflict:!0},Fr=C(t=>({icon:{color:t.palette.warning.main,width:"2rem",height:"2rem"},label:{align:"center",display:"block",marginBottom:t.spacing(1),color:t.palette.text.secondary,fontSize:t.typography.caption.fontSize},policiesContainer:{display:"flex",gap:t.spacing(4),marginTop:t.spacing(4),marginBottom:t.spacing(4)},button:{marginTop:t.spacing(4)}})),zr=({localPolicy:t,onSelectLocalPolicy:n,onSelectServerPolicy:l,serverPolicy:a})=>{const r=Fr();return e.createElement(ie,{open:!0,maxWidth:"md"},e.createElement(ee,null,e.createElement(E,{display:"flex",flexDirection:"column",gridGap:8},e.createElement(E,{display:"flex",justifyContent:"center"},e.createElement(Mt,{className:r.icon})),e.createElement(h,{align:"center",variant:"h6"},"There is a conflict with your drafts"),e.createElement(E,null,e.createElement(h,{align:"center"},"A newer version of the draft you are trying to edit has been recently saved."),e.createElement(h,{align:"center"},"Please review the changes and decide on a version to keep."))),e.createElement(E,{className:r.policiesContainer},e.createElement(E,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%"},e.createElement(h,{className:r.label,variant:"button"},"Your local draft"),e.createElement(Pe,{policy:t,withChangeSummary:!0}),e.createElement(P,{className:r.button,color:"primary",onClick:n,variant:"outlined"},"Keep local draft")),e.createElement(E,{alignItems:"center",display:"flex",flexDirection:"column",flex:"1 1 0%"},e.createElement(h,{className:r.label,variant:"button"},"Recently saved draft"),e.createElement(Pe,{policy:a,withChangeSummary:!0}),e.createElement(P,{className:r.button,color:"primary",onClick:l,variant:"outlined"},"Keep recently saved draft")))))},Wr=C(t=>({icon:{color:t.palette.warning.main,width:"2rem",height:"2rem"}})),Hr=({onConfirm:t,policy:n})=>{const l=Wr(),a=()=>{qt(n)};return e.createElement(ie,{open:!0},e.createElement(ee,null,e.createElement(E,{display:"flex",flexDirection:"column",gridGap:16},e.createElement(E,{display:"flex",flexDirection:"column",gridGap:4},e.createElement(E,{display:"flex",justifyContent:"center"},e.createElement(Mt,{className:l.icon})),e.createElement(h,{align:"center",variant:"h6"},"Invalid local draft")),e.createElement(E,{display:"flex",flexDirection:"column",gridGap:8},e.createElement(h,{align:"center"},"You have a local draft that is no longer compatible or has become corrupted."),e.createElement(h,{align:"center"},"Click export to download your draft. You can attempt to restore your draft by importing this file on the RBAC home page."),e.createElement(h,{align:"center"},"Clicking continue will discard your draft."," ",e.createElement(E,{component:"span",fontWeight:"fontWeightBold"},"This action cannot be undone."))),e.createElement(E,{display:"flex",justifyContent:"center",gridGap:8,marginY:3},e.createElement(P,{color:"primary",onClick:a,variant:"outlined"},"Export"),e.createElement(P,{color:"primary",onClick:t,variant:"contained"},"Discard and continue")))))},Ur=()=>Ft("@spotify/backstage-plugin-rbac:draftPolicy"),Vr={canPublish:!1,diff:null,hasChanges:!1,isValid:!1,policy:void 0,createNewRole:()=>"",discardLocalDraft:()=>{},exportPolicy:()=>{},publish:()=>{},saveLocalDraftToServer:()=>Promise.reject(),saveAndPublish:()=>Promise.reject(),refetchPolicy:()=>Promise.reject(),updateLocalDraft:()=>{}},Kt=Le(Vr),_=()=>Me(Kt);function Qe({children:t,policyId:n}){const l=q(),a=k(oe),r=k(V),{getPolicy:o,setPolicy:i}=Ke(),c=tt(),{NotFoundErrorPage:m}=c.getComponents(),[s,p]=R({active:!1,update:!1}),[u,d]=R(!1),[{loading:x,value:f},y]=bt(),g=o(n),[w,S,T]=Ur(),z=!w||_e.safeParse(w).success,M=z?w:void 0,{policy:b,policyConflict:A}=Mr({serverPolicy:g,localPolicy:M}),v=Gt(b),$=_e.safeParse(b).success,L=$&&!M&&!x,[{loading:le,error:X},Ee]=ue(()=>r.getPolicy(n),[r,n],g?{loading:!1,value:g}:{loading:!0}),re=()=>{p({active:!0,update:!1})},Z=()=>{p({active:!0,update:!0})},K=I(async()=>{const G=await Ee();i(G)},[Ee,i]),Bn=I(async G=>{await y(b,G,s.update?b:void 0),p({active:!1,update:!1}),K==null||K()},[b,s,y,p,K]),Ln=async()=>{d(!1)},Mn=()=>{S(G=>G&&g&&{...G,updatedAt:g.updatedAt})},Fn=I(async()=>{if(!b)throw new Error("No policy to save");try{await r.updateDraft(b.id,{name:b.name,roles:b.roles,options:b.options}),a.post({message:"Policy saved",severity:"success"}),T(),K==null||K()}catch(G){a.post({message:(G==null?void 0:G.message)||"An error occurred while updating the policy",severity:"error"})}},[a,r,b,K,T]),zn=I(()=>{if(!b)throw new Error("No policy to create a new role");const G=new Set(b.roles.map(Vn=>Vn.id));let fe;do fe=pe().split("-")[0];while(G.has(fe));const Un={name:`Role ${fe}`,permissions:[],members:"*",id:fe};return S({...b,roles:[...b.roles,Un]}),fe},[b,S]),Wn=()=>{T(),l("/rbac")},Hn=()=>{b&&qt(b)};return J(()=>{g||K()},[K,g]),J(()=>{f&&d(!0)},[f]),z?b?e.createElement(Kt.Provider,{value:{canPublish:L,diff:v,hasChanges:!!M,isValid:$,policy:b,createNewRole:zn,discardLocalDraft:T,exportPolicy:Hn,publish:re,saveLocalDraftToServer:Fn,refetchPolicy:K,updateLocalDraft:S,saveAndPublish:Z}},A&&M&&g&&e.createElement(zr,{localPolicy:M,onSelectLocalPolicy:Mn,onSelectServerPolicy:T,serverPolicy:g}),e.createElement(gt,{open:s.active,onClose:()=>p({active:!1,update:!1}),onPublish:Bn,policy:b}),f&&e.createElement(ht,{isOpen:u,onClose:Ln,policy:f}),t):le?e.createElement(ke,null):X?Br(X)?e.createElement(m,null):e.createElement(Nt,{error:X!=null?X:new Error("Unknown")}):null:e.createElement(Hr,{onConfirm:Wn,policy:w})}const Gr=t=>{const[n,l]=R(!1),{fetchPolicies:a}=Ne(),[{loading:r,value:o},i]=bt(),{policy:c,hasChanges:m}=_(),s=_e.safeParse(c).success,p=!m&&s,u=async x=>{await i(c,x),l(!1)},d=()=>{a()};return e.createElement(e.Fragment,null,e.createElement(P,{...t,onClick:()=>l(!0),disabled:!p||r},"Publish"),e.createElement(gt,{open:n,onClose:()=>l(!1),onPublish:u,policy:c}),o&&e.createElement(ht,{isOpen:!0,onClose:d,policy:o}))};function jr(t){const n=k(V),l=k(oe),{fetchPolicies:a}=Ne();return ue(async()=>{if(t)return n.deleteDraft(t.id).then(a).catch(r=>(l.post({message:r.message,severity:"error"}),Promise.reject(r)))},[t])}function _r({policies:t}){const n=t.find(s=>s.status==="draft"),l=t.find(s=>s.status==="active"),[a,r]=vt(),[o,i]=jr(n),c=q(),m=Yr(t);return e.createElement(O,{container:!0,spacing:4},l?e.createElement(O,{item:!0,xs:12,md:6},e.createElement(Pe,{policy:l,to:`./versions/${l.id}`,actions:e.createElement(P,{color:"primary",disabled:a.loading||!!n,onClick:()=>r(l)},"Duplicate")})):null,n?e.createElement(O,{item:!0,xs:12,md:6},e.createElement(Pe,{policy:n,to:`./versions/${n.id}`,actions:e.createElement(e.Fragment,null,e.createElement(P,{onClick:()=>c(`versions/${n.id}`),color:"primary"},"Edit"),e.createElement(P,{color:"primary",disabled:o.loading,onClick:i},"Delete Draft"),e.createElement(Qe,{policyId:n.id},e.createElement(Gr,{color:"primary"})))})):null,e.createElement(O,{item:!0,xs:12},e.createElement(Or,{data:m,canDuplicate:!n})))}function Yr(t){return t.filter(({status:n})=>n==="inactive")}const Jr=C(t=>({cardContent:{padding:t.spacing(6,3),"& > *":{background:"transparent"}}}));function qr(){const t=Jr(),n=k(V),l=q(),[a,r]=ue(async()=>n.createDraft({roles:[],options:{resolutionStrategy:"any-allow"}}),[n]);return J(()=>{a.value&&l(`./versions/${a.value.id}`)},[l,a.value]),e.createElement(te,null,e.createElement(he,{className:t.cardContent},e.createElement(Oe,{missing:"content",title:"No policy configured",description:e.createElement(e.Fragment,null,e.createElement(E,{component:"span",display:"block",pb:2},"Until you've configured your policy, authorization will be denied for all permissions."),e.createElement(E,{component:"span",display:"block"},"Click the button below to create the first version of your policy.")),action:e.createElement(P,{variant:"contained",color:"primary",disabled:a.loading,onClick:r},"New version")})))}function Kr(){const{policies:t}=Ke(),{loading:n,error:l,fetchPolicies:a}=Ne();vl(()=>{t||a()});let r;return n?r=e.createElement(O,{item:!0,xs:12},e.createElement(ke,null)):l?r=e.createElement(Nt,{error:l}):!t||t.length===0?r=e.createElement(qr,null):r=e.createElement(_r,{policies:t}),e.createElement(qe,{pages:void 0,header:e.createElement(Be,{title:"RBAC Policies"},e.createElement(hr,null))},r)}const Qt=Le({loading:!1}),Qr=({children:t})=>{const n=k(V),l=we(async()=>await n.searchMembers({query:""}),[n]);return e.createElement(Qt.Provider,{value:l},t)},Xr=()=>Me(Qt),Xt=Le(null),Zr=({children:t})=>{const n=k(Qn),l=k(V),a=k(oe),[r,o]=R(null),i=I(async()=>{var c;if(!r){const m=await l.fetchAllPermissionMetadata((c=n.getOptionalStringArray("permission.permissionedPlugins"))!=null?c:[]),s=ta(m.rules);Fl(s,u=>{u.length!==1&&a.post({message:`The plugin(s) ${u.slice(1).join(", ")} expose rules which are conflicting with rules exposed by the ${u[0]} plugin. These rules will not be available for use. Please contact RBAC support if you need assistance resolving this issue.`,severity:"error"})});const p=na(m,s);return o(p),p}return r},[a,r,l,n]);return e.createElement(Xt.Provider,{value:B(()=>({getMetadata:i}),[i])},t)};function Xe(){const t=Me(Xt),{value:n,loading:l}=we(async()=>t==null?void 0:t.getMetadata(),[t]);return{metadata:n,isLoading:l}}function Zt(){var t;const{metadata:n}=Xe();return(t=n==null?void 0:n.rules)!=null?t:null}function Te(){var t;const{metadata:n,isLoading:l}=Xe();return{permissions:(t=n==null?void 0:n.permissions)!=null?t:null,isLoading:l}}function en(){const{metadata:t}=Xe();return t?[...new Set(t.permissions.filter(n=>st(n)).map(({resourceType:n})=>n))]:null}function ea(){const{metadata:t}=Xe(),n=en();return!t||!n?null:n.reduce((l,a)=>{const r=t.rules.find(o=>o.resourceType===a);return r&&(l[a]={pluginId:r.pluginId}),l},{})}function ta(t){return zl(Wl(t,"resourceType"),n=>Hl(n.map(({pluginId:l})=>l)))}function na(t,n){return{...t,rules:t.rules.filter(({resourceType:l,pluginId:a})=>{const r=n[l];return a===r[0]})}}const la=C(t=>({card:n=>({marginTop:t.spacing(3),height:"100%","&:hover":n.readonly?{pointerEvents:"none"}:{}}),cardHeader:{paddingBottom:t.spacing(2),alignItems:"flex-start"},defaultChip:{marginLeft:t.spacing(1),marginBottom:0},title:{display:"flex",alignItems:"center",paddingTop:t.spacing(.5),paddingBottom:t.spacing(1)}}));function tn(t){const n=la(t),{title:l,description:a,active:r,changeResolutionStrategy:o,defaultOption:i,readonly:c}=t,m=()=>{c||o()};return e.createElement(te,{className:`${n.card}`,onClick:m},e.createElement(ol,{disabled:c},e.createElement(he,null,e.createElement(At,{className:n.cardHeader,avatar:e.createElement(il,{checked:r,color:"primary",disabled:c}),title:e.createElement("div",{className:n.title},e.createElement(h,{variant:"h6",component:"h2"},l),i?e.createElement(se,{label:"Default",size:"small",className:n.defaultChip}):null),subheader:a}))))}const ra=C(t=>({title:{display:"flex",alignItems:"center",paddingBottom:t.spacing(2)},maxWidthWrapper:{maxWidth:"800px"},readOnlyChip:{marginLeft:t.spacing(1)},paragraph:{paddingBottom:t.spacing(1)}}));function aa(){const{versionId:t}=nt();return je(t),e.createElement(Qe,{policyId:t},e.createElement(oa,null))}function oa(){const t=ra(),{policy:n,updateLocalDraft:l}=_(),a=q(),r=n.status!=="draft",o=i=>{l({...n,options:{...n.options,resolutionStrategy:i}})};return e.createElement(qe,{pages:[{title:n.name,path:".."},{title:"Options"}],header:e.createElement(Be,{title:"Options"},e.createElement(P,{variant:"outlined",color:"primary",onClick:()=>a("..",{relative:"path"})},"Back to policy"))},e.createElement(O,{item:!0,xs:12,className:t.maxWidthWrapper},e.createElement("div",null,e.createElement("div",{className:t.title},e.createElement(h,{variant:"h5",component:"h1"},"Decision resolution strategy"),r?e.createElement(se,{label:"Read only",className:t.readOnlyChip}):null),e.createElement(h,{variant:"body2",component:"p",className:t.paragraph},"Multiple decisions from multiple roles could be applicable to a single user when authorizing a permission request. Please select the decision resolution strategy that makes sense for your policy."),e.createElement(h,{variant:"body2",component:"p",className:t.paragraph},"Please note this strategy will be applied to the whole policy and greatly affects the outcome of permission decisions."),e.createElement(tn,{title:"Any-allow",changeResolutionStrategy:()=>o("any-allow"),readonly:r,defaultOption:!0,description:e.createElement(e.Fragment,null,e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"The first allow decision from all of the roles and decisions is the final result. A single explicit allow or an allow as a result of a conditional decision would result in a final allow decision, otherwise the decision is deny."),e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"With this option, the order of roles and decisions does not matter.")),active:n.options.resolutionStrategy==="any-allow"}),e.createElement(tn,{title:"First match",changeResolutionStrategy:()=>o("first-match"),readonly:r,description:e.createElement(e.Fragment,null,e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"The first matching decision from the first matching role that is applicable to the user is the final result, regardless if that decision is an allow, deny or conditional."),e.createElement(h,{variant:"body2",color:"textSecondary",component:"p",className:t.paragraph},"With this option, the order in which you define roles and decisions matters.")),active:n.options.resolutionStrategy==="first-match"}))))}const nn=t=>{if(t.success)return{};const n={};for(const l of t.error.issues)n[l.path.join(".")]=!0;return n},ia=C(t=>({container:{display:"flex",position:"relative",alignItems:"center",gap:t.spacing(1),flexShrink:1,maxWidth:"100%",minWidth:0},input:({invalid:n})=>({boxSizing:"content-box",display:"block",maxWidth:"100%",padding:0,borderWidth:2,borderStyle:"solid",borderColor:n?t.palette.error.main:"transparent",borderRadius:t.shape.borderRadius,backgroundColor:"transparent",color:t.palette.textContrast,fontFamily:"inherit",fontSize:"inherit",lineHeight:"inherit",fontWeight:"inherit",textOverflow:"ellipsis"}),hiddenSpan:{position:"absolute",top:0,left:0,borderWidth:1,whiteSpace:"pre",opacity:0,pointerEvents:"none"}}));function ln({invalid:t,name:n,value:l,onTextChange:a}){const r=ia({invalid:t}),[o,i]=R(!1),[c,m]=R(null),s=ye(null),[p,u]=R(l);J(()=>{u(l)},[l]),Xn(()=>{s.current&&c&&s.current.style.setProperty("width",`max(${c.getBoundingClientRect().width}px, 3ch)`)},[c,p]);const d=()=>{i(!1),u(l)},x=()=>{i(!1),a==null||a(p)},f=()=>{var g;o?x():(i(!0),(g=s.current)==null||g.focus())},y=g=>{var w;g.key==="Enter"&&((w=s.current)==null||w.blur()),g.key==="Escape"&&d()};return e.createElement(e.Fragment,null,e.createElement("div",{className:r.container},e.createElement("input",{"aria-label":n,className:r.input,name:n,ref:s,onChange:g=>u(g.target.value),onFocus:f,onBlur:x,onKeyDown:y,value:p}),e.createElement("span",{"aria-hidden":"true",className:r.hiddenSpan,ref:m},p),e.createElement(j,{onClick:f,size:"small"},o?e.createElement(Ul,{"aria-label":"Save title"}):e.createElement(Vl,{"aria-label":"Edit title"}))))}const ca=C(t=>({titleWrapper:{display:"flex",alignItems:"center",gap:t.spacing(2)}}));function rn({children:t}){const n=ca();return e.createElement(h,{noWrap:!0,variant:"h4",component:"h2",color:"textSecondary",className:n.titleWrapper},t)}const sa=C(t=>({fieldset:{border:"none",margin:`${t.spacing(3)}px 0 ${t.spacing(3)}px`,paddingLeft:"0"}})),an=({children:t,title:n})=>{const l=sa();return e.createElement("fieldset",{className:l.fieldset},e.createElement(h,{variant:"h6",component:"legend"},n),t)},ma=C(t=>({chipContainer:{marginTop:t.spacing(1),marginLeft:t.spacing(1),display:"flex",flexWrap:"wrap"}})),da=e.forwardRef(({selectedPermissionNames:t,setSelectedPermissionNames:n,errorMessage:l},a)=>{const r=ma(),{permissions:o}=Te();return e.createElement(e.Fragment,null,e.createElement(ve,{fullWidth:!0,error:!!l},e.createElement(de,{id:"selectLabel"},"Select permissions"),e.createElement(be,{ref:a,native:!1,displayEmpty:!0,multiple:!0,value:t,onChange:i=>n(i.target.value),input:e.createElement(Rt,null),"aria-labelledby":"selectLabel",renderValue:i=>e.createElement("div",{className:r.chipContainer,"aria-labelledby":"selectLabel"},o==null?void 0:o.filter(c=>i.includes(c.name)).map(c=>e.createElement(se,{key:c.name,label:c.name})))},o==null?void 0:o.map(i=>e.createElement(H,{key:i.name,value:i.name},e.createElement(Ce,{color:"primary",checked:t.includes(i.name),name:i.name,value:i.name,required:!0}),e.createElement(Q,{primary:i.name})))),e.createElement(rt,null,l)))}),Y=({name:t})=>{const n=B(()=>t.includes(".")?t.split(/(\.)/g).flatMap(l=>[l,e.createElement("wbr",null)]):[t],[t]);return e.createElement(e.Fragment,null,n.map((l,a)=>e.createElement(e.Fragment,{key:a},l)))},on=({authorizeResult:t,size:n})=>{switch(t){case F.ALLOW:return e.createElement(ql,{fontSize:n});case F.DENY:return e.createElement(Kl,{fontSize:n});case F.CONDITIONAL:return e.createElement(Jl,{fontSize:n});default:return null}},ua=["condition","anyOf","allOf","not"],cn={condition:"Condition",anyOf:"Any of",allOf:"All of",not:"Not"};function Ct(t){return t===null?!1:t.hasOwnProperty("id")&&t.hasOwnProperty("ruleName")&&t.hasOwnProperty("parameters")}function Se(t){return t.hasOwnProperty("levelType")}function pa(t){return t==="anyOf"||t==="allOf"||t==="not"}const Ea=C(()=>({root:{fontFamily:"monospace"}})),sn=({children:t})=>{const n=Ea();return e.createElement(h,{variant:"body2",className:n.root},t)},fa=C(t=>({rule:{color:t.palette.type==="light"?"#EB0014":"#FF8F9C"},parameters:{color:t.palette.type==="light"?"#E22134":"#EE96A0"}}));function mn({condition:t}){const n=fa();return e.createElement(sn,null,e.createElement(E,{component:"span",className:n.rule},t.ruleName,"(",e.createElement(E,{component:"span",className:n.parameters},JSON.stringify(t.parameters,null,1)),")"))}const ya=({children:t})=>e.createElement(E,{pl:2},t);function dn({level:t}){return e.createElement(e.Fragment,null,e.createElement(sn,null,cn[t.levelType]),e.createElement(ya,null,t.children.map((n,l)=>Se(n)?e.createElement(dn,{key:l,level:n}):e.createElement(mn,{key:l,condition:n}))))}const ga=C(t=>({resultsBox:{border:`1px solid ${t.palette.border}`,borderRadius:t.shape.borderRadius,padding:t.spacing(2)}}));function ha({permissionCriteria:t}){const n=ga();return e.createElement(E,{className:n.resultsBox},Ct(t)&&e.createElement(mn,{condition:t}),Se(t)&&e.createElement(dn,{level:t}))}const va=C(t=>({conditionResultText:{color:t.palette.success.main},conditionDecisionText:{padding:`0 0 ${t.spacing(3)}px`}}));function un({permissionCriteria:t}){const n=va();return e.createElement("div",null,e.createElement(h,{component:"p",variant:"body1",className:n.conditionDecisionText},"If the below conditions are met then the action is"," ",e.createElement("strong",{className:n.conditionResultText},"allowed.")),e.createElement(ha,{permissionCriteria:t}))}function ba(t){return t?{id:t.id,match:Ca(t),decisionType:xa(t),criteria:Ye(t.decision)?Ae(t.decision.conditions):null}:{id:pe(),match:{method:"specificPermission"},decisionType:"allow",criteria:null}}function Ca(t){var n;return t.match==="*"?{method:"all"}:t.match.name?{method:"specificPermission",name:t.match.name}:t.match.resourceType||(n=t.match.actions)!=null&&n.length?{method:"filter",resourceType:t.match.resourceType,actions:t.match.actions}:{method:"specificPermission"}}function xa(t){return typeof t.decision=="string"?t.decision:"conditional"}function Ae(t){const n=pe();return wl(t)?{id:n,levelType:"allOf",children:t.allOf.map(l=>Ae(l))}:Dl(t)?{id:n,levelType:"anyOf",children:t.anyOf.map(l=>Ae(l))}:Nl(t)?{id:n,levelType:"not",children:[Ae(t.not)]}:{id:n,ruleName:t.rule,parameters:t.params}}function pn(t,n){if(!t)return!1;if(Se(t))return t.children.length>0&&t.children.every(a=>pn(a,n));if(!t.ruleName)return!1;const l=n==null?void 0:n.find(({name:a})=>a===t.ruleName);return l?l.paramsSchema?new dt({allErrors:!0}).compile(l.paramsSchema)(t.parameters):!0:!1}function wa(t,n,l){return{id:t,match:En(n,l),decision:l}}function En({method:t,...n},l){return t==="all"?"*":l&&Ye(l)?{resourceType:l.resourceType,...n}:n}function xt(t){return Ct(t)?{rule:t.ruleName,params:t.parameters}:t.levelType==="not"?{not:xt(t.children[0])}:{[t.levelType]:t.children.map(n=>xt(n))}}const Da=C(()=>({decisionRowCell:{fontWeight:"bold"}})),Ze=({children:t,ledToDecision:n,color:l})=>{const a=Da();return e.createElement(h,{variant:"body1",component:"span",classes:{root:n?a.decisionRowCell:void 0},color:l},t)},Na=({ledToDecision:t})=>e.createElement(Ze,{ledToDecision:t,color:t===!1?"textSecondary":void 0},t?"Yes":"No"),Pa=C(t=>({decisionCell:{display:"flex",justifyItems:"center"},decisionIconContainer:{display:"flex",alignItems:"center",marginRight:t.spacing(1)},decisionIconAllow:{color:t.palette.success.main},decisionIconDeny:{color:t.palette.error.main},decisionIconConditional:{color:t.palette.info.main}})),Ta=t=>{switch(t){case F.ALLOW:return"Allow";case F.DENY:return"Deny";case F.CONDITIONAL:return"Conditional";default:return"Permission not found in role"}},Sa=(t,n)=>{let l;switch(t){case F.ALLOW:l=n.decisionIconAllow;break;case F.DENY:l=n.decisionIconDeny;break;case F.CONDITIONAL:l=n.decisionIconConditional;break;default:return}return`${n.decisionIconContainer} ${l}`},Aa=({ledToDecision:t,authorizeResult:n})=>{const l=Pa();return e.createElement("div",{className:l.decisionCell},n!==null&&e.createElement("span",{className:Sa(n,l)},e.createElement(on,{authorizeResult:n,size:"small"})),e.createElement(Ze,{ledToDecision:t,color:t===!1?"textSecondary":void 0},Ta(n)))},Ra=({permissionName:t,ledToDecision:n})=>e.createElement(Ze,{ledToDecision:n,color:n===!1?"textSecondary":void 0},e.createElement(Y,{name:t})),$a=({role:t,ledToDecision:n})=>e.createElement(ae,{to:`roles/${t.id}`},e.createElement(Ze,{ledToDecision:n,color:"primary"},t.name)),Ia=C(t=>({tableHeader:{borderBottom:`1px solid ${t.palette.border}`}})),Re=({children:t})=>{const n=Ia();return e.createElement(D,{size:"small",classes:{root:n.tableHeader}},t)},ka=C(t=>({userCell:{borderRight:`1px solid ${t.palette.border}`,color:t.palette.text.secondary,background:t.palette.background.paper}})),Oa=({rowCount:t})=>{const n=ka();return e.createElement(D,{size:"small",padding:"none",align:"center",rowSpan:t,classes:{root:n.userCell}},e.createElement(qn,null))},Ba=C(t=>({tableContainer:{border:`1px solid ${t.palette.border}`,borderRadius:t.shape.borderRadius},tableRow:{"&, &:nth-child(odd)":{background:t.palette.background.paper}},decisionTableRow:{"&, &:nth-child(odd)":{background:t.palette.type==="light"?t.palette.infoBackground:t.palette.grey[900]}}})),La=t=>{if(Ye(t))return F.CONDITIONAL;if(typeof t=="string")switch(t){case"allow":return F.ALLOW;case"deny":return F.DENY;default:throw new Error(`Unknown decision: ${t}`)}throw new Error("Unknown decision type found.")},Ma=(t,n)=>n.some(l=>l.rolePermissionId===t.id),Fa=t=>B(()=>{const{roles:n,permission:l,decisionOrigin:a}=t,r=[];for(const o of n){const i=kt(o,l);if(i.length>0)for(const c of i)r.push({role:o,permission:l,authorizeResult:La(c.decision),ledToDecision:Ma(c,a)});else r.push({role:o,permission:l,authorizeResult:null,ledToDecision:!1})}return r},[t]),za=({resultRow:t})=>{const n=Ba(),l=Fa(t);return e.createElement(E,{marginTop:3,marginBottom:3},e.createElement(cl,{classes:{root:n.tableContainer}},e.createElement(Ue,null,e.createElement(Ve,null,e.createElement(U,{classes:{root:n.tableRow}},e.createElement(Re,null),e.createElement(Re,null,"Role"),e.createElement(Re,null,"Permission"),e.createElement(Re,null,"Decision"),e.createElement(Re,null,"Is deciding role"))),e.createElement(Ge,null,l.map((a,r)=>{const o=r===0;return e.createElement(U,{key:r,classes:{root:a.ledToDecision?n.decisionTableRow:n.tableRow}},o?e.createElement(Oa,{rowCount:l.length}):null,e.createElement(D,{size:"small"},e.createElement($a,{role:a.role,ledToDecision:a.ledToDecision})),e.createElement(D,{size:"small"},e.createElement(Ra,{permissionName:a.permission.name,ledToDecision:a.ledToDecision})),e.createElement(D,{size:"small"},e.createElement(Aa,{authorizeResult:a.authorizeResult,ledToDecision:a.ledToDecision})),e.createElement(D,{size:"small"},e.createElement(Na,{ledToDecision:a.ledToDecision})))})))))},Wa=C(t=>({container:{display:"flex",flexDirection:"row",gap:t.spacing(1)},infoIcon:{color:t.palette.textSubtle}})),Ha=({policy:t,roles:n,permission:l})=>{const a=n.flatMap(o=>kt(o,l));let r;if(n.length===0)r=e.createElement(e.Fragment,null,"A user with no assigned roles will be denied access to"," ",e.createElement("strong",null,e.createElement(Y,{name:l.name})),".");else if(!a.length)r=e.createElement(e.Fragment,null,"None of the roles explicitly sets a rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:l.name})),", which means that a user who has all of these roles will be denied access to"," ",e.createElement("strong",null,e.createElement(Y,{name:l.name})),".");else if(t.options.resolutionStrategy==="any-allow")r=e.createElement(e.Fragment,null,"None of the roles explicitly sets an allow or conditional rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:l.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", a user who has all of these roles will be denied access to"," ",e.createElement("strong",null,e.createElement(Y,{name:l.name})),".");else throw t.options.resolutionStrategy==="first-match"?new Error("Trying to render ImplicitDecisionInfo for a first-match policy that has matching role permission. This should not happen, since the decision should be explicit by the matching role permission."):new Error(`Unknown resolution strategy ${t.options.resolutionStrategy}. Cannot render ImplicitDecisionInfo.`);return e.createElement(e.Fragment,null,e.createElement("strong",null,"Implicit decision")," \u2013 ",r)},Ua=({policy:t,permission:n,roles:l,decision:a,decisionOrigin:r})=>{const o=l.find(c=>c.id===r[0].roleId);let i;if(t.options.resolutionStrategy==="first-match"){if(!o)throw new Error("Expected decision origin role for first-match explicit decision but found none.");i=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,o.name)," explicitly sets a rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"first-match"),", no other roles are applied.")}else if(t.options.resolutionStrategy==="any-allow"){if(a.result===F.ALLOW){if(!o)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");i=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,o.name)," is the first role that explicitly sets an allow decision for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", this decides the outcome.")}else if(a.result===F.CONDITIONAL)if(r.length===1){if(!o)throw new Error("Expected decision origin role for any-allow explicit allow decision but found none.");i=e.createElement(e.Fragment,null,"The role ",e.createElement("strong",null,o.name)," is the first role that explicitly sets a decision for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", this decides the outcome.")}else i=e.createElement(e.Fragment,null,"Multiple roles explicitly set a rule for the permission"," ",e.createElement("strong",null,e.createElement(Y,{name:n.name})),". Since the resolution strategy for this policy is"," ",e.createElement("strong",null,"any-allow"),", these decide the outcome.")}else throw new Error(`Unknown resolution strategy ${t.options.resolutionStrategy}. Cannot render ExplicitDecisionInfo.`);return e.createElement(e.Fragment,null,e.createElement("strong",null,"Explicit decision")," \u2013 ",i)},Va=({roles:t,permission:n,decision:l,decisionOrigin:a})=>{const{policy:r}=_(),o=Wa();return e.createElement("div",{className:o.container},e.createElement(Ql,{fontSize:"small",titleAccess:"",className:o.infoIcon}),e.createElement(h,{variant:"body1",component:"p"},a.length===0?e.createElement(Ha,{policy:r,roles:t,permission:n}):e.createElement(Ua,{policy:r,permission:n,roles:t,decision:l,decisionOrigin:a})))},Ga=C(t=>({heading:{fontWeight:"bold"},subtitle:{color:t.palette.text.secondary},criteriaSummarySpacing:{marginBottom:t.spacing(3)}})),ja=({resultRow:t})=>{const n=Ga();return e.createElement(e.Fragment,null,t.roles.length>0?e.createElement(e.Fragment,null,e.createElement(h,{variant:"body1",component:"h6",className:n.heading},"Decision breakdown"),e.createElement(h,{variant:"subtitle1",component:"p",className:n.subtitle},"See what role results in this decision."),e.createElement(za,{resultRow:t})):null,t.decision.result===F.CONDITIONAL?e.createElement("div",{className:n.criteriaSummarySpacing},e.createElement(un,{permissionCriteria:Ae(t.decision.conditions)})):null,e.createElement(Va,{roles:t.roles,permission:t.permission,decision:t.decision,decisionOrigin:t.decisionOrigin}))};function fn(t,n){switch(n){case"small":return t.typography.caption;case"medium":return t.typography.body1;case"large":return t.typography.subtitle1;default:return t.typography.caption}}function yn(t){switch(t){case"small":return .2;case"medium":return .3;case"large":return 1;default:return .8}}const _a=C(t=>({root:{display:"inline-flex",fontWeight:"bold",borderRadius:"1000px",margin:t.spacing(1),padding:t.spacing(0,1)},message:({size:n})=>({fontSize:fn(t,n).fontSize,font:fn(t,n).font,verticalAlign:"middle",padding:t.spacing(yn(n),0,yn(n),0)})}),{name:"MuiAlert"});function gn(t){var n;const l=_a({size:t.size||"small"});return e.createElement(zt,{classes:{root:l.root,message:l.message},role:"textbox",severity:t.severity,icon:(n=t.icon)!=null?n:!1,variant:t.outlined?"outlined":"standard",title:t.text},t.text)}function Ya({decision:t}){let n;switch(t.result){case"ALLOW":n={severity:"success",text:"Allow"};break;case"DENY":n={severity:"error",text:"Deny"};break;default:n={severity:"info",text:"Conditional"};break}return e.createElement(gn,{text:n.text,severity:n.severity,icon:e.createElement(on,{authorizeResult:t.result}),title:`${n.text} decision chip`,size:"large"})}const Ja=C(t=>({permissionName:{display:"flex",alignItems:"center",height:"100%",fontWeight:"bold"},detailsContainer:{padding:`${t.spacing(2)}px ${t.spacing(1)}px 0`,borderTop:`1px solid ${t.palette.divider}`}})),qa=({resultRow:t})=>{const n=Ja();return e.createElement(sl,null,e.createElement(ml,{expandIcon:e.createElement(Yl,null),"aria-controls":"result{$resultIndex}-content",id:t.permission.name},e.createElement(O,{container:!0},e.createElement(O,{item:!0,xs:12,md:4},e.createElement(h,{variant:"body1",className:n.permissionName,component:"h5"},e.createElement(Y,{name:t.permission.name}))),e.createElement(O,{item:!0,xs:12,md:8},e.createElement(h,{variant:"body2"},t.roles.length>0?"For a user who has all the selected roles, the result will be:":"For a user with no assigned roles, the result will be:"),e.createElement(Ya,{decision:t.decision})))),e.createElement(dl,null,e.createElement("div",{className:n.detailsContainer},e.createElement(ja,{resultRow:t}))))},Ka=C(t=>({header:{borderTop:`1px solid ${t.palette.divider}`,padding:`${t.spacing(3)}px ${t.spacing(1)}px`,borderBottom:`1px solid ${t.palette.divider}`},resultHeading:{marginBottom:t.spacing(1)},accordionHeader:{padding:`${t.spacing(1)}px ${t.spacing(6)}px ${t.spacing(1)}px ${t.spacing(0)}px`,margin:"0"}})),Qa=({results:t,resolutionStrategy:n})=>{const l=Ka();return t.length?e.createElement(e.Fragment,null,e.createElement("div",{className:l.header},e.createElement(h,{variant:"h5",component:"h4",color:"textPrimary",className:l.resultHeading},"Test results"),e.createElement(zt,{severity:"info"},"All the tests are evaluated using"," ",e.createElement("strong",null,n),", which is the policy resolution strategy")),e.createElement(O,{container:!0,className:l.accordionHeader},e.createElement(O,{item:!0,xs:12,md:4},e.createElement(h,{variant:"body1",color:"textSecondary"},"Permission")),e.createElement(O,{item:!0,xs:12,md:8},e.createElement(h,{variant:"body1",color:"textSecondary"},"Result"))),t.map(a=>e.createElement(qa,{resultRow:a,key:a.permission.name}))):null},Xa=C(t=>({chipContainer:{marginTop:t.spacing(1),marginLeft:t.spacing(1),display:"flex",flexWrap:"wrap"}})),Za=({selectedRoleIds:t,setSelectedRoleIds:n})=>{const l=Xa(),{policy:a}=_();return e.createElement(e.Fragment,null,e.createElement(ve,{fullWidth:!0},e.createElement(de,{id:"selectLabel"},"Select roles"),e.createElement(be,{native:!1,displayEmpty:!0,multiple:!0,value:t,onChange:r=>n(r.target.value),input:e.createElement(Rt,null),"aria-labelledby":"selectLabel",renderValue:r=>e.createElement("div",{className:l.chipContainer,"aria-labelledby":"selectLabel"},a.roles.filter(o=>r.includes(o.id)).map(o=>e.createElement(se,{key:o.name,label:o.name})))},a.roles.map(r=>e.createElement(H,{key:r.id,value:r.id},e.createElement(Ce,{color:"primary",checked:t.includes(r.id),name:r.name,value:r.id}),e.createElement(Q,{primary:r.name}))))))},eo=Wt.array(Wt.string()),hn=(t,n,l)=>{const[a,r]=Ft(`@spotify/backstage-plugin-rbac:policyTesterForm:${t}`,[],{raw:!1,serializer:i=>JSON.stringify(i),deserializer:i=>{let c;try{c=JSON.parse(i)}catch(s){return console.error("Failed to parse json",s),[]}const m=eo.safeParse(c);return m.success?m.data:(console.error(`Stored value for ${t} has the wrong shape`,m.error),[])}}),o=B(()=>a!=null?a:[],[a]);return J(()=>{const i=new Set(n),c=o.some(m=>!i.has(m));!l&&c&&r(o.filter(m=>i.has(m)))},[n,o,r,l]),[o,r]},to=()=>{const{policy:t}=_(),{permissions:n}=Te(),l=k(V),[a,r]=R([]),o=I(async(c,m)=>{if(!n)return;const s=(await l.testPolicyDecisions(n.filter(p=>m.includes(p.name)).map(p=>({policyConfig:t,roleIds:c,permission:p})))).map(p=>({...p,roles:t.roles.filter(u=>c.includes(u.id))}));r(s)},[t,n,l,r]),i=I(()=>{r([])},[r]);return[a,o,i]},no=C(t=>({bodyText:{margin:`${t.spacing(1)}px 0`},clearButton:{marginLeft:t.spacing(1)}}));function lo(){const{policy:t}=_(),{permissions:n,isLoading:l}=Te(),a=B(()=>t.roles.map(T=>T.id),[t.roles]),r=B(()=>(n==null?void 0:n.map(T=>T.name))||[],[n]),o=ye(null),[i,c]=hn("roleIds",a),[m,s]=hn("permissionNames",r,l),[p,u]=R(""),[d,x,f]=to();J(()=>{f()},[t.roles,t.options,f]);const y=()=>{var T,z;m.length===0?((z=(T=o.current)==null?void 0:T.firstChild)==null||z.focus(),u("Please select at least one permission.")):x(i,m)},g=()=>{c([]),s([]),f(),u("")},w=no(),S=T=>{s(T),T.length>0&&u("")};return e.createElement(at,null,e.createElement(E,{justifyContent:"space-between",padding:2},e.createElement(h,{variant:"h3"},"Policy Tester"),e.createElement(h,{variant:"body1",component:"p",className:w.bodyText},"Use the policy tester to check if your changes will provide the access you intended for a user that has the roles you select below."),e.createElement(an,{title:"Which permissions do you want to test?"},e.createElement(da,{selectedPermissionNames:m,setSelectedPermissionNames:S,ref:o,errorMessage:p})),e.createElement(an,{title:"Which roles should the simulated user have?"},e.createElement(Za,{selectedRoleIds:i,setSelectedRoleIds:c})),e.createElement(E,{marginTop:3,component:"section"},e.createElement(P,{onClick:y,variant:"contained",color:"primary"},"Run tests"),e.createElement(P,{className:w.clearButton,color:"primary",variant:"outlined",startIcon:e.createElement(Gl,null),onClick:g},"Clear")),d&&d.length?e.createElement(E,{sx:{flexGrow:1},marginTop:4},e.createElement(Qa,{results:d,resolutionStrategy:t.options.resolutionStrategy})):null))}const vn=({children:t,onConfirm:n,message:l,title:a})=>{const[r,o]=R(!1),i=()=>o(!1),c=()=>o(!0),m=()=>{n(),i()};return e.createElement(e.Fragment,null,t({onClick:c}),e.createElement(ie,{open:r,onClose:i},e.createElement(He,null,e.createElement(E,{display:"flex",justifyContent:"space-between",alignItems:"center"},a)),e.createElement(ee,null,e.createElement(ul,null,l)),e.createElement(lt,null,e.createElement(P,{"aria-label":"Cancel action",color:"primary",onClick:i},"Cancel"),e.createElement(P,{"aria-label":"Confirm action",color:"secondary",onClick:m,variant:"contained"},"Confirm"))))},$e=t=>{const n=Pr(t.operation);return!t.operation||t.operation==="UNCHANGED"?null:e.createElement(gn,{size:t.size,text:n,severity:Nr(t.operation),outlined:!0})},bn=(t,n,l)=>{const a=n+l;if(a<0||a>=t.length)return t;const r=[...t];return[r[a],r[n]]=[r[n],r[a]],r},Cn=({array:t,index:n,onReorder:l})=>{const a=n===0,r=n===t.length-1;return e.createElement(E,{display:"flex"},e.createElement(j,{disabled:a,onClick:()=>l(bn(t,n,-1)),"aria-label":"Move up",size:"small"},e.createElement(Zl,null)),e.createElement(j,{disabled:r,onClick:()=>l(bn(t,n,1)),"aria-label":"Move down",size:"small"},e.createElement(Xl,null)))},xn=({helpText:t})=>e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(E,{component:"span",mr:1},e.createElement(h,{variant:"body2",noWrap:!0},"Reorder")),e.createElement(ge,{title:t},e.createElement(Ht,{color:"primary","aria-label":t}))),ro="Use the arrows to change the order in which roles are evaluated.";function ao({}){const{diff:t,policy:n,createNewRole:l,updateLocalDraft:a}=_(),r=q(),o=oo(n),i=n.status!=="draft",c=n.options.resolutionStrategy==="any-allow",m=u=>{a({...n,roles:u})},s=u=>{a({...n,roles:n.roles.filter(({id:d})=>d!==u)})},p=()=>{r(`./roles/${l()}`)};return e.createElement(at,null,e.createElement(E,{display:"flex",justifyContent:"space-between",padding:2},e.createElement(h,{variant:"h3"},"Roles"),!i&&e.createElement(P,{color:"primary",variant:"outlined",startIcon:e.createElement(ut,null),onClick:()=>p()},"New role")),e.createElement(Ue,null,e.createElement(Ve,null,e.createElement(U,null,!i&&!c&&e.createElement(D,{style:{width:0}},e.createElement(xn,{helpText:ro})),e.createElement(D,null,"Name"),e.createElement(D,null,"Users"),e.createElement(D,null,"Groups"),!i&&e.createElement(D,{style:{width:0}}))),e.createElement(Ge,null,o.map((u,d)=>e.createElement(U,{key:d},!i&&!c&&e.createElement(D,null,e.createElement(Cn,{array:n.roles,index:d,onReorder:m})),e.createElement(D,null,e.createElement(E,{alignItems:"center",display:"flex",gridGap:8},e.createElement(ae,{to:`roles/${u.id}`},u.name),e.createElement($e,{operation:t==null?void 0:t.roles[u.id].role.operation}))),e.createElement(D,null,u.userCount),e.createElement(D,null,u.groupCount),!i&&e.createElement(D,{align:"right"},e.createElement(vn,{message:"Are you sure you want to remove this role?",title:"Remove role?",onConfirm:()=>s(u.id)},x=>e.createElement(j,{...x,"aria-label":"Remove role",size:"small"},e.createElement(De,null)))))))))}function oo(t){return t.roles.map(n=>({id:n.id,name:n.name,userCount:Array.isArray(n.members)?n.members.filter(l=>l.startsWith("user:")).length:n.members,groupCount:Array.isArray(n.members)?n.members.filter(l=>l.startsWith("group:")).length:n.members}))}const io=C(()=>({emptyStateImage:{width:"95%",zIndex:2,position:"relative",left:"50%",top:"50%",transform:"translate(-50%, 15%)"}}));function wn({src:t,alt:n}){const l=io();return e.createElement("img",{src:t,className:`${l.emptyStateImage} `,alt:n})}const co=C(t=>({cardHeader:{padding:t.spacing(3,3),borderBottom:`1px solid ${t.palette.border}`},cardContent:{padding:t.spacing(6,3),"& > *":{background:"transparent"}},emptyStateImage:{width:"95%",zIndex:2,position:"relative",left:"50%",top:"50%",transform:"translate(-50%, 15%)"}}));function so({readonly:t}){const n=co(),l=q(),{createNewRole:a}=_(),r=()=>{const o=a();l(`./roles/${o}`)};return e.createElement(te,null,e.createElement(At,{title:"Roles",className:n.cardHeader}),e.createElement(he,{className:n.cardContent},t?e.createElement(Oe,{title:"No roles configured",missing:"content"}):e.createElement(Oe,{title:"No roles yet",description:"Click the button below to create your first role.",missing:{customImage:e.createElement(wn,{src:er,alt:"No roles placeholder"})},action:e.createElement(P,{variant:"contained",color:"primary",onClick:()=>r()},"New role")})))}function mo(){const[t,n]=R(null),{hasDraftPolicy:l}=Ke(),{isValid:a,discardLocalDraft:r,exportPolicy:o,hasChanges:i,policy:c,saveLocalDraftToServer:m,saveAndPublish:s,publish:p}=_(),u=q(),[d,x]=vt(),f=g=>{n(g.currentTarget)},y=()=>{n(null)};return e.createElement(e.Fragment,null,e.createElement(pl,{variant:"contained",color:"primary"},c.status==="draft"&&e.createElement(P,{disabled:!a,onClick:()=>m()},"Save"),c.status==="inactive"&&e.createElement(P,{onClick:()=>p()},"Republish"),c.status==="active"&&e.createElement(P,{disabled:l||d.loading,onClick:()=>x(c)},"Duplicate"),e.createElement(P,{color:"primary",title:"options",size:"small",onClick:f},e.createElement(tr,null))),e.createElement($t,{getContentAnchorEl:null,anchorEl:t,anchorOrigin:{vertical:"bottom",horizontal:"right"},open:!!t,onClose:y,PaperProps:{style:{width:240}}},c.status==="draft"&&e.createElement(ot,null,e.createElement(H,{disabled:!a,onClick:()=>s()},e.createElement(me,null,e.createElement(nr,{fontSize:"small"})),e.createElement(Q,null,"Save & Publish")),e.createElement(H,{disabled:!i,onClick:()=>r()},e.createElement(me,null,e.createElement(rr,{color:i?"secondary":"inherit",fontSize:"small"})),e.createElement(Q,null,e.createElement(h,{color:i?"secondary":"inherit"},"Discard changes"))),e.createElement(it,null)),e.createElement(ot,null,e.createElement(H,{onClick:()=>o()},e.createElement(me,null,e.createElement(ar,{fontSize:"small"})),e.createElement(Q,null,"Export"))),e.createElement(it,null),e.createElement(ot,null,e.createElement(H,{disabled:!a,onClick:()=>u("./options")},e.createElement(me,null,e.createElement(lr,{fontSize:"small"})),e.createElement(Q,null,"Options")))))}function uo(){const{versionId:t}=nt();return je(t),e.createElement(Qe,{policyId:t},e.createElement(po,null))}function po(){const{policy:t,updateLocalDraft:n}=_(),l=o=>{n({...t,name:o})},a=nn(Pl.safeParse(t)).name,r=t.status!=="draft";return e.createElement(qe,{pages:[{title:t.name}],header:e.createElement(Be,{title:t.name,titleComponent:e.createElement(e.Fragment,null,e.createElement(rn,null,r?t.name:e.createElement(ln,{invalid:a,name:"Policy name",value:t.name,onTextChange:l}),e.createElement(Jt,{status:t.status})),Eo(t))},e.createElement(mo,null))},e.createElement(O,{container:!0,spacing:4},e.createElement(O,{item:!0,xs:12},t.roles.length>0?e.createElement(ao,null):e.createElement(so,{readonly:r})),e.createElement(O,{item:!0,xs:12},e.createElement(lo,null))))}function Eo(t){const n={created:"Created by ",published:"Last published by ",updated:"Last updated by "},{activityDateText:l,activityUser:a,timestamp:r}=Yt(t,n);return e.createElement(h,{variant:"body2"},e.createElement(h,{component:"span",display:"inline",variant:"body2"},`${l} ${a} `),e.createElement(_t,{timestamp:r}))}function fo(t,n){const l=(t!=null?t:[]).filter(o=>Tl(o,En(n))),a=or(l,o=>st(o)?o.resourceType:void 0),r=a.length===1&&st(a[0])?a[0].resourceType:void 0;return{permissions:l,commonResourceType:r}}const yo=C(()=>({addButton:{paddingLeft:40,paddingRight:40}}));function Dn({onSelect:t}){const n=yo(),l=ye(null),[a,r]=R(!1),o=()=>{r(i=>!i)};return e.createElement("div",null,e.createElement(P,{className:n.addButton,variant:"outlined",color:"primary",onClick:o,ref:l},"Add"),e.createElement($t,{anchorEl:l.current,open:a,onClose:o,BackdropProps:{}},ua.map(i=>e.createElement(H,{key:i,onClick:()=>{t==null||t(i),r(!1)}},cn[i]))))}const go=[];function ho(t){const{onChange:n,schema:l,name:a}=t,{description:r,items:o}=l,[i,c]=e.useState(!1),m=Array.isArray(t.value)?t.value:go,s=m.includes(xe),p=(g,w)=>{if(!Array.isArray(w)){const S=[...m];S[g]=w||"",n(S)}},u=I(()=>{n([...m,""])},[n,m]),d=g=>{n(m.filter((w,S)=>S!==g))},x=()=>{n(s?[]:[xe])},f=()=>{s&&c(!0)},y=()=>{c(!1)};return J(()=>{m.length?s&&m.length>1&&n([xe]):u()},[u,n,m,s]),!o||!("type"in o)?null:e.createElement(e.Fragment,null,(m!=null?m:[]).map((g,w,{length:S})=>e.createElement(Pn,{allowEmptyStrings:!0,key:w,onChange:T=>p(w,T),name:w===0?a:"",schema:{description:w===S-1?r:"",type:o.type},value:g,controls:e.createElement(j,{size:"small",onClick:()=>d(w)},e.createElement(ir,null))})),!!(m!=null&&m.length)&&e.createElement(E,{alignItems:"center",display:"flex",flexDirection:"row",justifyContent:"space-between"},e.createElement(E,null,e.createElement(It,{control:e.createElement(Ce,{checked:s,onChange:x,name:"checkedB",color:"primary"}),label:"Use the claims from the logged in users token"})),e.createElement(E,null,e.createElement(ge,{onClose:y,onOpen:f,open:i,title:"To add additional entries you must uncheck using the claims from the logged in user."},e.createElement("span",null,e.createElement(j,{disabled:s,size:"small",onClick:u},e.createElement(ut,null)))))))}function vo(t){const{onChange:n,schema:l,name:a,value:r}=t,{description:o}=l;return e.createElement(E,{mb:1},e.createElement(It,{control:e.createElement(Ce,{checked:r===!0,onChange:i=>{n(i.target.checked)},name:a,color:"primary"}),label:a}),o&&e.createElement(h,{display:"block",variant:"caption",color:"textSecondary"},o))}function bo({allowEmptyStrings:t,controls:n,name:l,onChange:a,schema:r,value:o}){const i=c=>{a(xo({value:c.currentTarget.value,type:r.type}))};return e.createElement(E,{mb:1},e.createElement(E,{display:"flex",gridGap:6},e.createElement(ce,{fullWidth:!0,id:l,label:l,placeholder:"Enter",variant:"outlined",size:"small",value:Co(o,t),onChange:wt(o,t)?void 0:i,disabled:wt(o,t)}),n&&e.createElement(E,{alignSelf:"center"},n)),r.description&&e.createElement(h,{variant:"caption",color:"textSecondary"},r.description,wt(o)&&!t&&e.createElement(e.Fragment,null," (switch to JSON editor to edit)")))}function wt(t,n=!1){return!n&&t===""||t===null||t===xe}function Co(t,n=!1){return!n&&t===""?"[empty string]":t===null?"[null]":t===xe?"[BackstageUserClaims]":t||""}function xo({value:t,type:n}){switch(n){case"string":return t===""?void 0:t;case"number":case"integer":return Number.isNaN(Number(t))?void 0:Number(t);case"null":return t==="null"?null:void 0;default:return}}function Nn(t){return!!t&&"type"in t&&(t.type==="array"||t.type==="boolean"||t.type==="null"||t.type==="number"||t.type==="integer"||t.type==="string")}function wo(t){return"type"in t&&t.type==="array"}function Do(t){return"type"in t&&t.type==="boolean"}function Pn({schema:t,...n}){return Nn(t)?wo(t)?e.createElement(ho,{...n,schema:t}):Do(t)?e.createElement(vo,{...n,schema:t}):e.createElement(bo,{...n,schema:t}):null}const No=new dt({allErrors:!0}),Po=C({textarea:{fontFamily:"monospace"}});function To({onChange:t,schema:n,value:l}){const a=Po(),[r,o]=R(!1),i=B(()=>No.compile(n),[n]);return e.createElement(ce,{InputProps:{classes:{input:a.textarea}},multiline:!0,fullWidth:!0,variant:"outlined",minRows:3,error:r,defaultValue:JSON.stringify(l,void 0,2),onChange:c=>{const m=c.target.value;if(m)try{const s=JSON.parse(m);i(s)&&(o(!1),t(s))}catch{o(!0)}}})}const So=new dt({allErrors:!0});function Ao({onChange:t,schema:n,value:l}){var a;const r=B(()=>So.compile(n),[n]),o=B(()=>r(l),[r,l]),i=Object.entries(n.properties),c=m=>s=>{t({...l,[m]:s})};return e.createElement(e.Fragment,null,i.map(([m,s])=>{var p;return e.createElement(Pn,{isRequired:((p=n.required)==null?void 0:p.includes(m))||!1,key:m,name:m,onChange:c(m),schema:s,value:l==null?void 0:l[m]})}),e.createElement(rt,{error:!o},(a=r.errors)==null?void 0:a[0].message))}const Ro=t=>!!t&&"properties"in t;function $o({onChange:t,rule:n,value:l}){const[a,r]=R(!1),{paramsSchema:o}=n!=null?n:{},i=()=>r(p=>!p);if(!Ro(o))return null;const c=!Io(o),m=c||a,s=e.createElement(P,{size:"small",onClick:i,disabled:c},m?"Close editor":"Edit as JSON");return e.createElement(E,{marginTop:2},e.createElement("form",null,m?e.createElement(To,{onChange:t,schema:o,value:l}):e.createElement(e.Fragment,null,e.createElement(E,{marginBottom:2},e.createElement(de,null,"Parameters")),e.createElement(Ao,{onChange:t,schema:o,value:l}))),e.createElement(E,{display:"flex",flexDirection:"column",alignItems:"flex-end",marginTop:1},c?e.createElement(ge,{title:"Only JSON editing is supported for this parameter",arrow:!0},e.createElement("span",null,s)):s))}function Io(t){return Object.values(t.properties).every(Nn)}const ko=C(t=>({conditionCard:{minWidth:t.spacing(63)},conditionCardBar:{height:t.spacing(1),backgroundImage:"linear-gradient(90deg, #007DFF 0%, #0057B2 100%)"},autocomplete:{flex:1}}));function Tn({ruleName:t,parameters:n,resourceType:l,onChange:a,onDelete:r}){var o;const i=ko(),c=Zt(),m=(o=c==null?void 0:c.filter(d=>d.resourceType===l))!=null?o:[],s=m.find(d=>d.name===t),p=d=>{a(d,{})},u=I(d=>{a(t,d)},[a,t]);return e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(te,{className:i.conditionCard},e.createElement("div",{className:i.conditionCardBar}),e.createElement(he,null,e.createElement(E,null,e.createElement(E,null,e.createElement(mt,{className:i.autocomplete,"data-testid":"rule-select",getOptionLabel:d=>d.name,getOptionSelected:(d,x)=>d.name===x.name,options:m,onChange:(d,x)=>p(x?x.name:null),renderInput:d=>e.createElement(e.Fragment,null,e.createElement(E,{marginBottom:2},e.createElement(de,null,"Rule")),e.createElement(ce,{...d,placeholder:"Select",variant:"outlined",size:"small",name:"rule"})),renderOption:d=>e.createElement(E,null,e.createElement(h,{variant:"body2"},d.name),e.createElement(h,{noWrap:!0,variant:"caption"},d.description)),value:s||null,PopperComponent:d=>e.createElement(El,{...d,style:{width:"auto"},placement:"bottom-start"})})),e.createElement(E,{flex:"1"},e.createElement(E,{display:"flex",flexDirection:"column"},e.createElement($o,{rule:s,onChange:u,value:n})))))),e.createElement(E,{ml:1},e.createElement(j,{"aria-label":"delete",onClick:r,size:"small"},e.createElement(De,null))))}const Oo=C(t=>({conditionTypeFormControl:{minWidth:80,marginLeft:t.spacing(1)}}));function Bo({level:t,onSelect:n}){const l=Oo(),a=t.children.length>1;return e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(ve,{className:l.conditionTypeFormControl},e.createElement(be,{value:t.levelType,onChange:r=>n==null?void 0:n(r.target.value)},e.createElement(H,{key:"anyOf",value:"anyOf"},"Any of"),e.createElement(H,{key:"allOf",value:"allOf"},"All of"),e.createElement(H,{key:"not",value:"not",disabled:a},"Not"))),e.createElement(E,{ml:1},e.createElement(j,{"aria-label":"delete",onClick:()=>n==null?void 0:n(null),size:"small"},e.createElement(De,null))))}function et(){return{id:pe(),ruleName:null,parameters:{}}}const Lo=C(t=>({treeVerticalSpacer:{width:t.spacing(2),borderLeft:`1px solid ${t.palette.status.aborted}`},treeHorizontalSpacer:{height:t.spacing(3),borderLeft:`1px solid ${t.palette.status.aborted}`},treeVerticalBranchHalf:{position:"absolute",height:"50%",borderLeft:`1px solid ${t.palette.status.aborted}`,alignSelf:"flex-start"},treeVerticalBranchFull:{borderLeft:`1px solid ${t.palette.status.aborted}`,alignSelf:"stretch"},treeHorizontalBranch:{width:t.spacing(2),borderTop:`1px solid ${t.palette.status.aborted}`}}));function Sn({level:t,resourceType:n,onChange:l,parentConditionType:a,isRoot:r=!1}){const o=Lo(),i=I((f,y)=>{const g=[...t.children];return g.splice(f,1,y),g},[t]),c=I(f=>{l({...t,children:f})},[l,t]),m=I(f=>{f===null?l(null):f==="not"&&t.children.length>1?l({...t,levelType:f,children:t.children.slice(0,1)}):l({...t,levelType:f})},[l,t]),s=I((f,y)=>{c(f===null?An(t.children,y):i(y,f))},[t,c,i]),p=f=>{const y=pe();f==="condition"?c([...t.children,et()]):f==="not"?c([...t.children,{id:y,levelType:f,children:[]}]):pa(f)&&c([...t.children,{id:y,levelType:f,children:[et()]}])},u=f=>{c(An(t.children,f))},d=B(()=>t.children.map((f,y)=>(g,w)=>{c(i(y,{...f,ruleName:g,parameters:w}))}),[t.children,c,i]),x=B(()=>t.children.map((f,y)=>g=>s(g,y)),[t.children,s]);return e.createElement("div",null,!r&&e.createElement("div",{className:o.treeHorizontalSpacer}),e.createElement(E,{display:"flex",alignItems:"center",position:"relative"},!r&&e.createElement(e.Fragment,null,e.createElement("div",{className:a==="not"?o.treeVerticalBranchHalf:o.treeVerticalBranchFull}),e.createElement("div",{className:o.treeHorizontalBranch})),e.createElement(Bo,{level:t,onSelect:m})),e.createElement(E,{display:"flex"},r||a==="not"?e.createElement(E,{pl:2}):e.createElement("div",{className:o.treeVerticalSpacer}),!r&&e.createElement(E,{pl:2}),e.createElement("div",null,t.children.map((f,y)=>Se(f)?e.createElement(E,{key:f.id},e.createElement(Sn,{level:f,resourceType:n,parentConditionType:t.levelType,onChange:x[y]})):e.createElement(Fe,{key:f.id},e.createElement("div",{className:o.treeHorizontalSpacer}),e.createElement(E,{display:"flex",alignItems:"center",position:"relative"},e.createElement("div",{className:t.levelType==="not"?o.treeVerticalBranchHalf:o.treeVerticalBranchFull}),e.createElement("div",{className:o.treeHorizontalBranch}),e.createElement(Tn,{ruleName:f.ruleName,parameters:f.parameters,resourceType:n,onChange:d[y],onDelete:()=>u(y)})))),!(t.levelType==="not"&&t.children.length>=1)&&e.createElement(e.Fragment,null,e.createElement("div",{className:o.treeHorizontalSpacer}),e.createElement(E,{display:"flex",alignItems:"center",position:"relative"},e.createElement("div",{className:o.treeVerticalBranchHalf}),e.createElement("div",{className:o.treeHorizontalBranch}),e.createElement(Dn,{onSelect:p}))))))}function An(t,n){const l=[...t];return l.splice(n,1),l}const Mo=C(t=>({paper:{backgroundColor:t.palette.background.default,padding:t.spacing(3),marginBottom:t.spacing(3),minHeight:t.spacing(48)}}));function Fo({permissionCriteria:t,resourceType:n,onUpdate:l,readonly:a=!1}){const r=Mo(),o=I(p=>{l(u=>({...u,...p}))},[l]),i=I(p=>{const u=pe();o(p==="condition"?et():p==="not"?{id:u,levelType:p,children:[]}:{id:u,levelType:p,children:[et()]})},[o]),c=I((p,u)=>{l(d=>({...d,ruleName:p,parameters:u}))},[l]),m=I(()=>{l(null)},[l]);let s;return a?s=e.createElement(un,{permissionCriteria:t}):t===null?s=e.createElement(Dn,{onSelect:i}):Ct(t)?s=e.createElement(Tn,{ruleName:t.ruleName,parameters:t.parameters,resourceType:n,onChange:c,onDelete:m}):Se(t)&&(s=e.createElement(Sn,{level:t,resourceType:n,onChange:l,isRoot:!0})),e.createElement(at,{variant:"outlined",className:r.paper},s)}const zo="Action";function Wo({actions:t,readonly:n,onActionsChange:l}){return e.createElement(mt,{multiple:!0,id:"match-by-attribute-dropdown",options:["create","read","update","delete"],getOptionLabel:a=>a,value:t!=null?t:[],onChange:(a,r)=>l==null?void 0:l(r),filterSelectedOptions:!0,renderInput:a=>e.createElement(ce,{...a,variant:"outlined",label:zo,placeholder:"Choose attributes",margin:"normal"}),disabled:n})}const Ho=C(()=>({fullWidth:{width:"100%","& > *":{flexGrow:1}}})),Rn="Permission name";function Uo({name:t="",readonly:n,onNameChange:l}){const a=Ho(),{permissions:r}=Te();return e.createElement(ve,{className:a.fullWidth,variant:"outlined",disabled:n},e.createElement(de,{id:"match-by-name-dropdown"},Rn),e.createElement(be,{labelId:"match-by-name-dropdown",label:Rn,value:r?t:"",onChange:o=>l==null?void 0:l(o.target.value)},r==null?void 0:r.map(o=>e.createElement(H,{key:o.name,value:o.name},o.name))))}const Vo=C(()=>({fullWidth:{width:"100%","& > *":{flexGrow:1}}})),$n="Resource type";function Go({resourceType:t="",readonly:n,onResourceTypeChange:l}){const a=Vo(),r=en();return e.createElement(ve,{className:a.fullWidth,variant:"outlined",disabled:n},e.createElement(de,{id:"match-by-resource-dropdown"},$n),e.createElement(be,{labelId:"match-by-resource-dropdown",label:$n,value:r?t:"",onChange:o=>l==null?void 0:l(o.target.value),displayEmpty:!0},r==null?void 0:r.map(o=>e.createElement(H,{key:o,value:o},o))))}function In(t){return`${t.palette.primary.main}50`}const jo=C(t=>({toggleButton:{"&.Mui-selected":{backgroundColor:In(t),color:t.palette.primary.main},"&.Mui-selected:hover":{backgroundColor:"#97BBE8"},color:t.palette.primary.main,border:`1px solid ${t.palette.primary.main}`}}));function Dt({className:t,...n}){const l=jo();return e.createElement(jl,{className:`${l.toggleButton} ${t}`,...n})}const _o=C({fullWidth:{width:"100%","& > *":{flexGrow:1}}});function Yo({className:t,fullWidth:n,...l}){const a=_o();return e.createElement(_l,{className:`${n?a.fullWidth:""} ${t}`,...l})}const Jo=C(t=>({indicator:{right:"unset"},tab:{maxWidth:"none","&.Mui-selected":{backgroundColor:In(t),color:t.palette.primary.main}}}));function qo({options:t,selected:n,onChange:l,readonly:a=!1}){const r=Jo();return e.createElement(fl,{orientation:"vertical",value:t.map(({id:o})=>o).indexOf(n),onChange:(o,i)=>l(t[i].id),indicatorColor:"primary",TabIndicatorProps:{className:r.indicator}},t.map(o=>e.createElement(yl,{key:o.id,label:o.displayText.toUpperCase(),className:r.tab,disabled:a})))}const Ko=C(t=>({dialogTitle:{display:"flex",alignItems:"center",justifyContent:"space-between"},fullWidth:{width:"100%","& > *":{flexGrow:1}},infoIcon:{position:"absolute",right:t.spacing(3)},content:{padding:t.spacing(7)},saveButton:{paddingLeft:t.spacing(5),paddingRight:t.spacing(5)},contentContainerConditional:{display:"flex",gap:t.spacing(5),maxWidth:1480}})),Qo={specificPermission:"Choose a specific permission",filter:"Filter by permission properties",all:"Match all permissions"},kn="Choose the name of a resource permission or filter by resource type to set a conditional decision.";function Xo({rolePermission:t,readonly:n=!1,onClose:l,onSave:a}){const r=Ko(),{permissions:o}=Te(),i=Zt(),c=ea(),m=ba(t),[s,p]=R(m.match),[u,d]=R(m.decisionType),[x,f]=R(m.criteria),y=B(()=>fo(o,s),[o,s]),g=u==="conditional",w=g?"xl":"sm";J(()=>{g&&o&&!y.commonResourceType&&d("allow")},[g,o,y.commonResourceType,d]);const S=A=>{A!==null&&d(A)},T=B(()=>s.method==="specificPermission"&&!s.name||s.method==="filter"&&!s.resourceType&&!s.actions,[s]),z=B(()=>y.permissions.length===0?!1:!T,[y,T]),M=B(()=>u!=="conditional"?!0:!(!y.commonResourceType||!(c!=null&&c[y.commonResourceType].pluginId)||!pn(x,i)),[u,y,c,x,i]),b=()=>{a==null||a(wa(m.id,s,u==="conditional"?{resourceType:y.commonResourceType,pluginId:c[y.commonResourceType].pluginId,conditions:xt(x)}:u))};return e.createElement(ie,{open:!0,maxWidth:w,onClose:l,fullWidth:!0},e.createElement(He,{disableTypography:!0,className:r.dialogTitle},e.createElement(h,{variant:"h4",component:"h2"},"New Permission Decision"),e.createElement(P,{startIcon:e.createElement(ct,null),onClick:l},"Close")),e.createElement(ee,{dividers:!0,className:r.content},e.createElement(E,{className:g?r.contentContainerConditional:void 0},e.createElement(E,{mb:5,flex:1},e.createElement(qo,{options:Object.entries(Qo).map(([A,v])=>({id:A,displayText:v})),selected:s.method,onChange:A=>p({method:A}),readonly:n})),e.createElement(E,{mb:5,height:189,flex:1},s.method==="specificPermission"&&e.createElement(Uo,{name:s.name,readonly:n,onNameChange:A=>p({...s,name:A})}),s.method==="filter"&&e.createElement(e.Fragment,null,e.createElement(Go,{resourceType:s.resourceType,readonly:n,onResourceTypeChange:A=>p({...s,resourceType:A})}),e.createElement(Wo,{actions:s.actions,readonly:n,onActionsChange:A=>p({...s,actions:A.length?A:void 0})}),T?null:e.createElement(e.Fragment,null,e.createElement(E,{marginY:2},e.createElement(it,{variant:"middle"})),e.createElement(rt,null,`Matched ${y.permissions.length} ${y.permissions.length===1?"permission":"permissions"}`)))),e.createElement(E,{mb:5,flex:1},e.createElement(E,{display:"flex",alignItems:"center"},e.createElement(Yo,{value:u,exclusive:!0,fullWidth:!0,"aria-label":"Decision result",onChange:(A,v)=>S(v)},e.createElement(Dt,{value:"allow","aria-label":"Decision allowed",disabled:n},"Allow"),e.createElement(Dt,{value:"deny","aria-label":"Decision denied",disabled:n},"Deny"),e.createElement(Dt,{value:"conditional","aria-label":"Decision conditionally allowed",disabled:!y.commonResourceType||n},"Conditional")),!g&&!n&&e.createElement(ge,{title:kn},e.createElement(Ht,{className:r.infoIcon,color:"primary","aria-label":kn}))))),u==="conditional"&&!!y.commonResourceType&&e.createElement(Fo,{permissionCriteria:x,resourceType:y.commonResourceType,onUpdate:f,readonly:n}),!n&&e.createElement(E,{display:"flex",justifyContent:"flex-end"},e.createElement(P,{variant:"contained",color:"primary",className:r.saveButton,onClick:b,disabled:!z||!M},"Save"))))}const Zo=e.forwardRef(function({children:t,role:n,...l},a){const r=B(()=>{const i=[];return Pt.forEach(t,c=>{if(ze(c)){const m=c.props.children[0];ze(m)&&i.push(m);const s=c.props.children[1];if(ze(s)){const p=Pt.toArray(s.props.children).filter(ze);i.push(...p)}}}),i},[t]),o=r.length;return e.createElement("div",{ref:a},e.createElement("ul",{...l},e.createElement(dr,{height:250,width:250,rowHeight:54,overscanCount:5,rowCount:o,rowRenderer:i=>e.cloneElement(r[i.index],{style:{...i.style,whiteSpace:"nowrap"}}),role:n})))}),ei=C({autocomplete:{display:"flex",flex:1}});function ti({members:t,options:n,namespaceOptions:l,loading:a=!1,disabled:r=!1,isMultiNamespaces:o=!1,onTextChange:i,onToggleMember:c,onChange:m}){const[s,p]=R(!1),u=ei(),[d,x]=Zn(g=>g+1,0),f=(g,w)=>{w&&(c(w),x())};J(()=>{s&&i("")},[s,i]);const y=o?l.concat((n==null?void 0:n.members)||[]):(n==null?void 0:n.members)||[];return e.createElement(E,{width:250},e.createElement(mt,{key:`${d}`,open:s,onOpen:()=>{p(!0)},onClose:()=>{p(!1)},onChange:f,getOptionLabel:Ie,groupBy:ni,ListboxComponent:Zo,renderOption:g=>e.createElement(e.Fragment,null,e.createElement(Ce,{id:`checkbox-${g.entityRef}`,checked:t.includes(g.entityRef),color:"primary"}),e.createElement("label",{htmlFor:`checkbox-${g.entityRef}`},o?Ie(g,!1):Ie(g))),options:y,openOnFocus:!0,disabled:r,loading:a,className:u.autocomplete,renderInput:g=>e.createElement(ce,{...g,label:o?"Select members":"Select specific users/groups",variant:"standard",onChange:m,InputProps:{...g.InputProps,endAdornment:e.createElement(e.Fragment,null,a?e.createElement(Tt,{color:"inherit",size:20}):null,g.InputProps.endAdornment)}})}))}function Ie(t,n=!0){var l;const a=ne(t.entityRef);return a.name==="*"?a.namespace:sr({...a,name:(l=t.name)!=null?l:a.name},{defaultKind:a.kind,defaultNamespace:n?cr:!1})}const On={user:"USERS",group:"GROUPS",namespace:"NAMESPACES"};function ni(t){const{name:n,kind:l}=ne(t.entityRef),a=n==="*"?"namespace":l;if(!On[a])throw new Error(`Group '${a}' is not supported for members in a policy`);return On[a]}const li=C(t=>({actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0},typeIcon:{color:t.palette.grey[500]}}));function ri({diff:t,loading:n,isMultiNamespaces:l,members:a,error:r,onToggleMember:o,readonly:i=!1}){const c=li();if(n)return e.createElement(U,null,e.createElement(D,{scope:"row",colSpan:i?4:5},e.createElement(ke,null)));if(r&&r.message!=null,a==="*")return e.createElement(U,null,e.createElement(D,{colSpan:2,height:80},"All"),e.createElement(D,{colSpan:i?2:3},e.createElement($e,{operation:t==null?void 0:t.members["*"].operation})));if(a.length===0)return e.createElement(U,null,e.createElement(D,{scope:"row",colSpan:i?4:5},"Select users or groups using the drop-down menu above."));const m=a.sort((s,p)=>{let u=0;l&&p.name==="*"&&s.name!=="*"?u=1:l&&s.name==="*"&&p.name!=="*"&&(u=-1);const d=s.type.localeCompare(p.type),x=ne(s.entityRef).namespace.localeCompare(ne(p.entityRef).namespace),f=ne(s.entityRef).name.localeCompare(ne(p.entityRef).name);return u||d||x||f});return e.createElement(e.Fragment,null,m.map(s=>{var p;const{name:u,type:d,entityRef:x}=s;return e.createElement(U,{key:x},e.createElement(D,{className:c.typeIconCol},d==="group"&&e.createElement(ur,{className:c.typeIcon})||l&&u==="*"&&e.createElement(pr,{className:c.typeIcon})||e.createElement(Bt,{className:c.typeIcon})),e.createElement(D,{scope:"row",className:c.nameCol},(p=l?Ie(s,!1):Ie(s))!=null?p:"Unknown"),e.createElement(D,{scope:"row"},u==="*"&&l?"namespace":d),e.createElement(D,null,u&&e.createElement($e,{operation:t==null?void 0:t.members[x].operation})),!i&&e.createElement(D,{scope:"row",className:c.actionCol},e.createElement(j,{"aria-label":"delete",onClick:()=>o(s),size:"small"},e.createElement(De,null))))}))}const ai=C(()=>({header:{display:"flex",flexDirection:"row",justifyContent:"space-between",paddingLeft:"1rem",paddingRight:"1rem",gap:"1rem"},actionCol:{width:48},typeIconCol:{paddingRight:"0.4rem"},nameCol:{paddingLeft:0}}));function oi({diff:t,policyId:n,role:l,onToggleMember:a,readonly:r=!1,debounceTime:o=1e3}){const i=k(V),c=k(mr),m=ai(),s=l.members==="*",[p,u]=R(""),{current:d}=ye({}),x=v=>{d[v.entityRef]=v,a(v.entityRef)},f=v=>{var $;if(d[v])return d[v];const L=ne(v);return{entityRef:v,type:L.kind.toLowerCase(),name:($=L.name)!=null?$:v}},{value:y,loading:g}=Xr(),{loading:w,value:S}=we(async()=>{const v=await c.getEntityFacets({facets:["metadata.namespace"]}).then($=>$.facets["metadata.namespace"].map(L=>L.value));return ii(v)},[c]),T=S?(S==null?void 0:S.length)>1:!1,z=S?S.filter(v=>v.entityRef.toLowerCase().includes(p)):[],M=B(()=>gl(v=>{u(v.target.value.toLowerCase())},o),[u,o]),{loading:b,error:A}=we(async()=>{l.members==="*"||l.members.length===0||(await i.getPolicy(n)).roles.find(v=>v.id===l.id)===void 0||l.members.forEach(v=>{const $=f(v);d[$.entityRef]=$})},[n,s]);return e.createElement(e.Fragment,null,e.createElement("div",{className:m.header},e.createElement("h2",null,"Members"),e.createElement(ti,{onToggleMember:x,members:l.members,disabled:r,options:y,namespaceOptions:z,isMultiNamespaces:T,loading:g||w,onTextChange:u,onChange:M})),e.createElement(Ue,null,e.createElement(Ve,null,e.createElement(U,null,e.createElement(D,{className:m.typeIconCol}),e.createElement(D,{className:m.nameCol},"Name"),e.createElement(D,null,"Type"),e.createElement(D,null),!r&&e.createElement(D,{className:m.actionCol}))),e.createElement(Ge,null,e.createElement(ri,{diff:t,loading:b||w,isMultiNamespaces:T,error:A,members:Array.isArray(l.members)?l.members.map(f):l.members,onToggleMember:x,readonly:r}))))}function ii(t){return t.map(n=>({name:"*",type:"user",entityRef:`user:${n}/*`})).sort((n,l)=>n.entityRef.toLowerCase().localeCompare(l.entityRef.toLowerCase()))}const ci="Use the arrows to change the order in which permission decisions are evaluated.";function si({diff:t,permissions:n,onReorderPermissions:l,onNewPermissionClick:a,onOpenPermission:r,onRemovePermissionClick:o,anyAllow:i,readonly:c=!1}){return e.createElement(e.Fragment,null,e.createElement(E,{display:"flex",justifyContent:"space-between",padding:2},e.createElement(h,{variant:"h5"},"Permission Decisions"),!c&&n.length!==0&&e.createElement(P,{color:"primary",variant:"outlined",startIcon:e.createElement(ut,null),onClick:a},"New")),e.createElement(Ue,null,e.createElement(Ve,null,e.createElement(U,null,!c&&!i&&e.createElement(D,{style:{width:0}},e.createElement(xn,{helpText:ci})),e.createElement(D,null,"Match by"),e.createElement(D,null,"Decision"),e.createElement(D,null),!c&&e.createElement(D,null))),e.createElement(Ge,null,n.length===0&&e.createElement(U,null,e.createElement(D,{colSpan:5},e.createElement(Oe,{title:"No permission decisions set",description:"Click the button below to create your first permission.",missing:{customImage:e.createElement(wn,{src:Er,alt:"No permission placeholder"})},action:e.createElement(P,{variant:"contained",color:"primary",onClick:a},"New permission decision")}))),n.map((m,s)=>e.createElement(U,{key:s},!c&&!i&&e.createElement(D,null,e.createElement(Cn,{array:n,index:s,onReorder:l})),e.createElement(D,null,e.createElement(hl,{onClick:()=>r(s)},e.createElement(h,{variant:"body2",color:"primary"},pt(m)))),e.createElement(D,null,br(m)),e.createElement(D,null,e.createElement($e,{operation:t==null?void 0:t.permissions[m.id].operation})),!c&&e.createElement(D,{align:"right"},e.createElement(vn,{message:"Are you sure you want to remove this permission decision?",onConfirm:()=>o(s),title:"Remove?"},p=>e.createElement(j,{...p,"aria-label":"Remove permission decision",size:"small"},e.createElement(De,null)))))))))}function mi({roleId:t}){const{versionId:n,roleId:l}=nt(),a=t!=null?t:l;return je(a),je(n),e.createElement(Qe,{policyId:n},e.createElement(ui,{roleId:a}))}const di=C(t=>({cardContainer:{margin:t.spacing(0)}}));function ui({roleId:t}){const{diff:n,updateLocalDraft:l,policy:a}=_(),r=a.roles.find(v=>v.id===t),o=n==null?void 0:n.roles[t],[i,c]=R(null),[m,s]=R(!1),p=tt(),{NotFoundErrorPage:u}=p.getComponents(),d=q(),x=di();if(!r)return e.createElement(u,null);const f=r.name,y=v=>{const $=a.roles.findIndex(le=>le.id===v.id),L=[...a.roles];L.splice($,1,v),l({...a,roles:L})},g=v=>{y({...r,name:v})},w=v=>{if(i===null)y({...r,permissions:[v,...r.permissions]});else{const $=[...r.permissions];$.splice(i,1,v),y({...r,permissions:$})}s(!1)},S=v=>{if(v==="*")y({...r,members:r.members==="*"?[]:"*"});else if(r.members==="*")y({...r,members:[v]});else{const $=r.members.includes(v)?r.members.filter(L=>L!==v):[...r.members,v];y({...r,members:$.length===0?"*":$})}},T=v=>{y({...r,permissions:r.permissions.filter(($,L)=>v!==L)})},z=v=>{y({...r,permissions:v})},M=nn(Sl.safeParse(r)).name,b=a.status!=="draft",A=a.options.resolutionStrategy==="any-allow";return e.createElement(e.Fragment,null,e.createElement(qe,{pages:[{title:a.name,path:`../../../${a.id}`},{title:f}],header:e.createElement(Be,{titleComponent:e.createElement(rn,null,a.name," \xA0\u01C0",b?e.createElement(e.Fragment,null,"\xA0",f):e.createElement(ln,{invalid:M,value:f,onTextChange:g}),e.createElement($e,{operation:o==null?void 0:o.role.operation,size:"medium"})),description:a.description||void 0},e.createElement(P,{variant:"outlined",color:"primary",onClick:()=>d("../..",{relative:"path"})},"Back to policy"))},e.createElement(O,{container:!0,className:x.cardContainer,spacing:4,direction:"row"},e.createElement(O,{item:!0,xs:6},e.createElement(te,null,e.createElement(oi,{diff:o||null,role:r,policyId:a.id,onToggleMember:S,readonly:b}))),e.createElement(O,{item:!0,xs:6},e.createElement(te,null,e.createElement(si,{diff:o||null,permissions:r.permissions,onNewPermissionClick:()=>{c(null),s(!0)},onOpenPermission:v=>{c(v),s(!0)},onReorderPermissions:z,onRemovePermissionClick:T,anyAllow:A,readonly:b}))))),m&&e.createElement(Xo,{rolePermission:i!==null?r.permissions[i]:void 0,onClose:()=>s(!1),onSave:w,readonly:b}))}function pi(){const t=tt(),{NotFoundErrorPage:n}=t.getComponents();return e.createElement(nl,{loading:e.createElement(ke,null),unauthorized:e.createElement(n,null)},e.createElement(gr,null,e.createElement(Zr,null,e.createElement(Qr,null,e.createElement(tl,null,e.createElement(We,{element:e.createElement(Kr,null),path:"/"}),e.createElement(We,{element:e.createElement(uo,null),path:"/versions/:versionId"}),e.createElement(We,{element:e.createElement(aa,null),path:"/versions/:versionId/options"}),e.createElement(We,{element:e.createElement(mi,null),path:"/versions/:versionId/roles/:roleId"}))))))}export{pi as RBACRoot};
3
- //# sourceMappingURL=Root-5eafe743.esm.js.map