mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-02 18:50:39 +02:00
Overriding is working
This commit is contained in:
+2
-1
@@ -872,6 +872,7 @@
|
|||||||
"resourcePolicyOtpEmpty": "No one time password",
|
"resourcePolicyOtpEmpty": "No one time password",
|
||||||
"resourcePolicyReadOnly": "This policy is Read only",
|
"resourcePolicyReadOnly": "This policy is Read only",
|
||||||
"resourcePolicyReadOnlyDescription": "This resource policy is shared accross multiple resources, you cannot edit it on this page.",
|
"resourcePolicyReadOnlyDescription": "This resource policy is shared accross multiple resources, you cannot edit it on this page.",
|
||||||
|
"editSharedPolicy": "Edit Shared Policy",
|
||||||
"resourcePolicyTypeSave": "Save Resource type",
|
"resourcePolicyTypeSave": "Save Resource type",
|
||||||
"resourcePolicySelect": "Select resource policy",
|
"resourcePolicySelect": "Select resource policy",
|
||||||
"resourcePolicySelectError": "Select a resource policy",
|
"resourcePolicySelectError": "Select a resource policy",
|
||||||
@@ -918,7 +919,7 @@
|
|||||||
"resourcePolicyInline": "Inline Resource Policy",
|
"resourcePolicyInline": "Inline Resource Policy",
|
||||||
"resourcePolicyInlineDescription": "Access Policy scoped to only this resource",
|
"resourcePolicyInlineDescription": "Access Policy scoped to only this resource",
|
||||||
"resourcePolicyShared": "Shared Resource Policy",
|
"resourcePolicyShared": "Shared Resource Policy",
|
||||||
"resourcePolicySharedDescription": "Access Policy shared accross multiple resources",
|
"resourcePolicySharedDescription": "This resource uses a shared policy. Policy-level settings (auth methods, email whitelist) are locked. You can add resource-specific rules, roles, and users below.",
|
||||||
"resourceUsersRoles": "Access Controls",
|
"resourceUsersRoles": "Access Controls",
|
||||||
"resourceUsersRolesDescription": "Configure which users and roles can visit this resource",
|
"resourceUsersRolesDescription": "Configure which users and roles can visit this resource",
|
||||||
"resourceUsersRolesSubmit": "Save Access Controls",
|
"resourceUsersRolesSubmit": "Save Access Controls",
|
||||||
|
|||||||
@@ -315,13 +315,13 @@ export default function ResourceAuthenticationPage() {
|
|||||||
key={policies.sharedPolicy.resourcePolicyId}
|
key={policies.sharedPolicy.resourcePolicyId}
|
||||||
>
|
>
|
||||||
<ActionBanner
|
<ActionBanner
|
||||||
variant="warning"
|
variant="info"
|
||||||
title={t("resourcePolicyReadOnly")}
|
title={t("resourcePolicyShared")}
|
||||||
titleIcon={
|
titleIcon={
|
||||||
<ShieldAlertIcon className="w-5 h-5" />
|
<ShieldAlertIcon className="w-5 h-5" />
|
||||||
}
|
}
|
||||||
description={t(
|
description={t(
|
||||||
"resourcePolicyReadOnlyDescription"
|
"resourcePolicySharedDescription"
|
||||||
)}
|
)}
|
||||||
actions={
|
actions={
|
||||||
<Button
|
<Button
|
||||||
@@ -332,14 +332,13 @@ export default function ResourceAuthenticationPage() {
|
|||||||
<Link
|
<Link
|
||||||
href={`/${org.org.orgId}/settings/policies/resource/${policies.sharedPolicy.niceId}`}
|
href={`/${org.org.orgId}/settings/policies/resource/${policies.sharedPolicy.niceId}`}
|
||||||
>
|
>
|
||||||
{t("edit")}
|
{t("editSharedPolicy")}
|
||||||
<ArrowRightIcon className="size-4" />
|
<ArrowRightIcon className="size-4" />
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<EditPolicyForm
|
<EditPolicyForm
|
||||||
readonly
|
|
||||||
resourceId={resource.resourceId}
|
resourceId={resource.resourceId}
|
||||||
/>
|
/>
|
||||||
</ResourcePolicyProvider>
|
</ResourcePolicyProvider>
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ export function EditPolicyForm({
|
|||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
// In overlay mode (resourceId provided), policy-level sections are locked.
|
||||||
|
// Rules and users/roles sections handle their own hybrid logic via resourceId.
|
||||||
|
const isOverlay = resourceId !== undefined;
|
||||||
|
const policyLevelReadonly = readonly || isOverlay;
|
||||||
|
|
||||||
const isMaxmindAvailable = !!(
|
const isMaxmindAvailable = !!(
|
||||||
env.server.maxmind_db_path && env.server.maxmind_db_path.length > 0
|
env.server.maxmind_db_path && env.server.maxmind_db_path.length > 0
|
||||||
);
|
);
|
||||||
@@ -79,7 +84,7 @@ export function EditPolicyForm({
|
|||||||
return (
|
return (
|
||||||
<SettingsContainer>
|
<SettingsContainer>
|
||||||
{!hidePolicyNameForm && (
|
{!hidePolicyNameForm && (
|
||||||
<EditPolicyNameSectionForm readonly={readonly} />
|
<EditPolicyNameSectionForm readonly={policyLevelReadonly} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<EditPolicyUsersRolesSectionForm
|
<EditPolicyUsersRolesSectionForm
|
||||||
@@ -89,11 +94,11 @@ export function EditPolicyForm({
|
|||||||
resourceId={resourceId}
|
resourceId={resourceId}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EditPolicyAuthMethodsSectionForm readonly={readonly} />
|
<EditPolicyAuthMethodsSectionForm readonly={policyLevelReadonly} />
|
||||||
|
|
||||||
<EditPolicyOtpEmailSectionForm
|
<EditPolicyOtpEmailSectionForm
|
||||||
emailEnabled={env.email.emailEnabled}
|
emailEnabled={env.email.emailEnabled}
|
||||||
readonly={readonly}
|
readonly={policyLevelReadonly}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EditPolicyRulesSectionForm
|
<EditPolicyRulesSectionForm
|
||||||
|
|||||||
@@ -268,59 +268,29 @@ export function EditPolicyUsersRolesSectionForm({
|
|||||||
setIsSavingOverlay(true);
|
setIsSavingOverlay(true);
|
||||||
try {
|
try {
|
||||||
// Compute which roles/users are resource-specific (non-locked)
|
// Compute which roles/users are resource-specific (non-locked)
|
||||||
const currentResourceRoleIds = new Set(
|
const currentResourceRoleIds = combinedRoles
|
||||||
combinedRoles
|
.filter((r) => !policyRoleLockedIds.has(r.id))
|
||||||
.filter((r) => !policyRoleLockedIds.has(r.id))
|
.map((r) => Number(r.id));
|
||||||
.map((r) => r.id)
|
const currentResourceUserIds = combinedUsers
|
||||||
);
|
.filter((u) => !policyUserLockedIds.has(u.id))
|
||||||
const currentResourceUserIds = new Set(
|
.map((u) => u.id);
|
||||||
combinedUsers
|
|
||||||
.filter((u) => !policyUserLockedIds.has(u.id))
|
|
||||||
.map((u) => u.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialRoleIds = initialResourceRoleIdsRef.current;
|
|
||||||
const initialUserIds = initialResourceUserIdsRef.current;
|
|
||||||
|
|
||||||
const addedRoleIds = [...currentResourceRoleIds].filter(
|
|
||||||
(id) => !initialRoleIds.has(id)
|
|
||||||
);
|
|
||||||
const removedRoleIds = [...initialRoleIds].filter(
|
|
||||||
(id) => !currentResourceRoleIds.has(id)
|
|
||||||
);
|
|
||||||
const addedUserIds = [...currentResourceUserIds].filter(
|
|
||||||
(id) => !initialUserIds.has(id)
|
|
||||||
);
|
|
||||||
const removedUserIds = [...initialUserIds].filter(
|
|
||||||
(id) => !currentResourceUserIds.has(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Use bulk-set endpoints (session-authenticated) which replace
|
||||||
|
// all resource-specific roles/users in one call
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
...addedRoleIds.map((id) =>
|
api.post(`/resource/${resourceId}/roles`, {
|
||||||
api.post(`/resource/${resourceId}/roles/add`, {
|
roleIds: currentResourceRoleIds
|
||||||
roleId: Number(id)
|
}),
|
||||||
})
|
api.post(`/resource/${resourceId}/users`, {
|
||||||
),
|
userIds: currentResourceUserIds
|
||||||
...removedRoleIds.map((id) =>
|
})
|
||||||
api.post(`/resource/${resourceId}/roles/remove`, {
|
|
||||||
roleId: Number(id)
|
|
||||||
})
|
|
||||||
),
|
|
||||||
...addedUserIds.map((id) =>
|
|
||||||
api.post(`/resource/${resourceId}/users/add`, {
|
|
||||||
userId: id
|
|
||||||
})
|
|
||||||
),
|
|
||||||
...removedUserIds.map((id) =>
|
|
||||||
api.post(`/resource/${resourceId}/users/remove`, {
|
|
||||||
userId: id
|
|
||||||
})
|
|
||||||
)
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Update refs to reflect new state
|
// Update refs to reflect new state
|
||||||
initialResourceRoleIdsRef.current = currentResourceRoleIds;
|
initialResourceRoleIdsRef.current = new Set(
|
||||||
initialResourceUserIdsRef.current = currentResourceUserIds;
|
currentResourceRoleIds.map(String)
|
||||||
|
);
|
||||||
|
initialResourceUserIdsRef.current = new Set(currentResourceUserIds);
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: t("success"),
|
title: t("success"),
|
||||||
|
|||||||
Reference in New Issue
Block a user