Skip to content

feat(flex): integrate new cedarling flow on Admin UI#2425

Merged
moabu merged 36 commits intomainfrom
2321-cedarling-integration
Nov 20, 2025
Merged

feat(flex): integrate new cedarling flow on Admin UI#2425
moabu merged 36 commits intomainfrom
2321-cedarling-integration

Conversation

@kdhttps
Copy link
Contributor

@kdhttps kdhttps commented Nov 6, 2025

close #2321

Summary by CodeRabbit

  • New Features

    • Resource-level access control with per-resource read/write/delete checks and a batch authorization helper.
    • Runtime policy store retrieval at startup so policy data can be loaded and refreshed.
  • Improvements

    • App UI now respects scoped permissions across pages — many views become read-only when appropriate.
    • Read-only modes applied to forms and components to prevent unauthorized edits.
    • Menu and route visibility now reflect resource-based permissions.
  • Localization

    • Added permission- and password-related translations (EN/ES/FR/PT).

✏️ Tip: You can customize this high-level summary in your review settings.

@kdhttps kdhttps self-assigned this Nov 6, 2025
@mo-auto mo-auto added comp-admin-ui Component affected by issue or PR kind-feature Issue or PR is a new feature request labels Nov 6, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 6, 2025

📝 Walkthrough

Walkthrough

Integrates Cedarling resource-scoped authorization across the Admin UI: adds CEDAR resource scopes/constants/types, rewrites useCedarling with caching and batch authorization, fetches/stores policyStoreJson at startup, updates many components/metadata to use resourceKey-based gating, and adds supporting utilities, hooks, and types.

Changes

Cohort / File(s) Summary
Cedarling config & constants
admin-ui/app/cedarling/config/cedarling-bootstrap-TBAC.json, admin-ui/app/cedarling/constants/resourceScopes.ts, admin-ui/app/cedarling/constants/index.ts, admin-ui/app/cedarling/constants.ts, admin-ui/app/cedarling/index.ts
Added typed CEDAR_RESOURCE_SCOPES and CEDARLING_CONSTANTS, updated bootstrap JSON (removed id and policy store id, added mapping keys), reorganized constants exports and removed old constants export.
Types & client
admin-ui/app/cedarling/types/index.ts, admin-ui/app/cedarling/client/CedarlingClient.ts
Added ResourceScopeEntry, CedarAction, AdminUiFeatureResource, ICedarEntityMappingResource; updated TokenAuthorizationRequest to use cedar_entity_mapping; removed an init console.log and adjusted imports.
Utility rework
admin-ui/app/cedarling/utility/resources.ts, admin-ui/app/cedarling/utility/index.ts (removed generateCedarPolicies.ts, mapRolePermissions.ts)
Added ADMIN_UI_RESOURCES, CEDARLING_BYPASS, findPermissionByUrl, buildCedarPermissionKey; removed legacy policy-generation and role-mapping utilities; updated utility exports.
useCedarling hook & surface
admin-ui/app/cedarling/hooks/useCedarling.ts
Full rewrite: builds authorization requests with cedar_entity_mapping, adds caching and cache-keying, introduces authorizeHelper for batch checks, exposes hasCedarRead/Write/DeletePermission helpers, improved errors/toasts and token handling.
Redux: cedar permissions & init
admin-ui/app/redux/features/cedarPermissionsSlice.ts, admin-ui/app/redux/features/initSlice.ts
Added policyStoreJson to cedar state, changed setCedarlingPermission payload to resourceId, added setPolicyStoreJson action; adjusted getScripts reducer signature to accept action param.
Backend API & auth flow
admin-ui/app/redux/api/backend-api.ts, admin-ui/app/utils/AppAuthProvider.tsx
Added fetchPolicyStore API and wired policyStoreJson fetch into AppAuthProvider to dispatch cedarPermissions/setPolicyStoreJson after obtaining API access token.
Permissions initializer
admin-ui/app/components/App/PermissionsPolicyInitializer.tsx
Replaced generated-policy flow with direct policyStoreJson validation/handling and bootstrapping via CEDARLING_POLICY_STORE_LOCAL; updated init readiness checks and selectors.
Saga & app init
admin-ui/app/redux/sagas/AppInitSaga.ts, admin-ui/app/redux/sagas/index.ts, admin-ui/app/redux/sagas/ProfileDetailsSaga.ts
Added AppInitSaga to coordinate guarded initialization and health actions; integrated it into root saga; ProfileDetailsSaga typed and cleaned with explicit payload handling.
Gating wrapper & UI components
admin-ui/app/routes/Apps/Gluu/GluuViewWrapper.tsx, many components under admin-ui/plugins/** and routes
New typed GluuViewWrapper with i18n missing-permission message; widespread updates across pages and plugins to use hasCedarRead/Write/DeletePermission and authorizeHelper for resource-scoped gating.
Menu, sidebar & metadata
admin-ui/app/routes/Apps/Gluu/GluuAppSidebar.tsx, admin-ui/app/components/Sidebar/types.ts, admin-ui/plugins/**/plugin-metadata.*
Sidebar/menu filtering updated to use resourceKey and CEDARLING_BYPASS; MenuItem type extended with resourceKey?: string and cedarlingPassed?: boolean; multiple plugins added resourceKey entries.
User management features
admin-ui/plugins/user-management/* (new hooks, utils, schema, components)
Added password hooks, AvailableClaimsPanel, PasswordChangeModal, usePasswordChange, usePasswordValidation, userFormUtils, userFormSchema, types; refactored UserForm to use new utilities.
Form readOnly propagation
FIDO/SCIM/SMTP components (DynamicConfiguration.tsx, StaticConfiguration.tsx, ScimConfiguration.tsx, SmtpForm.tsx, related types)
Introduced readOnly / canWrite gating props and logic so forms/submit/commit dialog respect write permissions.
Resources & helpers
admin-ui/app/helpers/navigation.ts, admin-ui/app/helpers/index.js, admin-ui/app/types/images.d.ts
Added useAppNavigation hook and re-exported navigation helpers; added SVG module declaration for image imports.
Permission cleanup
admin-ui/app/utils/PermChecker.ts
Removed hasAny and hasBoth helpers.
Localization
admin-ui/app/locales/{en,es,fr,pt}/translation.json
Added translation keys: missing_required_permission, insufficient_permissions_to_modify, and passwordRequirements in multiple locales.
Misc UI & performance
assorted files (SVG icons, memoized components, styles, removed unused imports/logs)
Added optional style/default fill to SVG menu icons, memoized components and items, added sidebar animations/styles, removed debug logs and unused imports.

Sequence Diagram(s)

sequenceDiagram
    participant AppInit
    participant AuthProvider
    participant Backend
    participant Redux
    participant Cedarling
    participant UI as Component

    AppInit->>AuthProvider: start
    AuthProvider->>Backend: fetchApiAccessToken(ujwt)
    Backend-->>AuthProvider: apiAccessToken
    AuthProvider->>Backend: fetchPolicyStore(access_token)
    Backend-->>AuthProvider: policyStoreJson
    AuthProvider->>Redux: dispatch(setPolicyStoreJson)
    Redux->>Cedarling: store policyStoreJson
    AppInit->>Cedarling: initialize with policyStoreJson
    UI->>Cedarling: authorizeHelper(scopes[])
    Cedarling->>Cedarling: dedupe & build requests
    alt cache hit
        Cedarling-->>UI: cached decision
    else
        Cedarling->>Cedarling: evaluate policies, cache result
        Cedarling-->>UI: decision
    end
    UI->>UI: render guarded by permissions
Loading
sequenceDiagram
    participant Component
    participant useCedarling
    participant authorizeHelper
    participant CedarEngine
    participant Redux

    Component->>useCedarling: obtain helpers
    Component->>authorizeHelper: batch(ResourceScopeEntry[])
    authorizeHelper->>authorizeHelper: dedupe(resourceId,action)
    loop unique checks
        authorizeHelper->>CedarEngine: build request (cedar_entity_mapping)
        CedarEngine->>CedarEngine: check cache
        alt hit
            CedarEngine-->>authorizeHelper: cached result
        else
            CedarEngine->>CedarEngine: evaluate against policyStore
            CedarEngine-->>authorizeHelper: result
            authorizeHelper->>Redux: optionally persist permissions
        end
    end
    authorizeHelper-->>Component: AuthorizationResult[]
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • admin-ui/app/cedarling/hooks/useCedarling.ts — payload shapes, cache keys, token handling, batching and error/toast behavior.
  • admin-ui/app/components/App/PermissionsPolicyInitializer.tsx & AppAuthProvider.tsx — policyStoreJson validation, bootstrapping lifecycle and where policy is injected into Cedarling.
  • New AppInitSaga — idempotence guard and ordering of dispatched health actions.
  • plugin-metadata and menu/sidebar resourceKey additions — ensure consistency of ADMIN_UI_RESOURCES values across many files.
  • user-management utilities/hooks and form schema — password validation, attribute mapping, and interactions with existing Formik usage.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • syntrydy
  • moabu
  • duttarnab

Poem

🐰 Hopped in with a tiny scroll,

I stitched scopes into every role.
Policies fetched, caches tight,
Components guard the Admin light.
Carrots for each permission right.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Out of Scope Changes check ❓ Inconclusive While the PR includes many changes related to Cedarling integration, several modifications appear tangential: SVG component style props (Administrator.tsx, OAuth.tsx), new translation keys, webhook-related types, and user profile enhancements. These changes, though potentially supportive, introduce scope beyond the core Cedarling authorization flow and may warrant separate PRs. Review whether SVG styling, translation additions, webhook types, profile features, and password validation utilities are essential to Cedarling integration or should be separated into focused, single-concern PRs.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: integrating a new Cedarling flow on the Admin UI. It is concise, specific, and directly related to the substantial code modifications throughout the codebase.
Linked Issues check ✅ Passed The PR closes issue #2321, which is referenced but lacks detailed requirements in the provided context. The changeset implements comprehensive Cedarling authorization integration with resource-scoped permissions, policy store handling, and permission checks across multiple components and plugins, which aligns with Cedarling feature integration objectives.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2321-cedarling-integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@faisalsiddique4400 faisalsiddique4400 marked this pull request as ready for review November 17, 2025 05:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 26

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (19)
admin-ui/plugins/schema/components/Person/AttributeListPage.tsx (1)

221-276: Permission-aware attributeActions wiring is correct; some disabled flags are redundant

The attributeActions memo correctly:

  • Builds actions conditionally based on canReadAttributes, canWriteAttributes, and canDeleteAttributes.
  • Uses stable callbacks (handleGoToAttribute*, handleAttribueDelete, DeleteOutlinedIcon).
  • Includes the right dependencies so actions recompute when permissions or translations change.

Two minor nits:

  1. Inside the guarded blocks, disabled: !canWriteAttributes and disabled: !canDeleteAttributes are redundant, because the action is only pushed when the corresponding can* is true. You could safely omit those disabled props without behavior change.
  2. The explicit generic on useMemo is correct but verbose; optionally, you could pull the action type into a type AttributeAction = Action<JansAttribute> | ((rowData: JansAttribute) => Action<JansAttribute>) alias to improve readability.

No functional issues here.

admin-ui/plugins/auth-server/components/Message/MessageForm.js (1)

49-82: Add UI-level authorization checks before form submission to improve user experience.

The form fields are unconditionally enabled (isDisabled = false), allowing users without write permissions to complete the entire form. While buildPayload only constructs the action payload without permission validation, and authorization is ultimately enforced by the backend (sagas catch 401 errors), this creates poor UX—users discover authorization errors only after submission.

Options:

  1. Check permissions before allowing form submission and dispatch
  2. Ensure backend returns and displays clear authorization error messages to users
  3. Confirm this authorization delegation pattern is intentional and consistent across all Admin UI configuration forms
admin-ui/plugins/fido/components/Fido.tsx (2)

68-122: Good defense‑in‑depth on writes; audit logging remains robust

Early‑returning from the submit handler when canWriteFido is false adds a solid safety net on top of the readOnly UI, preventing accidental writes if the UI is ever mis‑configured. The audit logging (with console.error in the catch) also aligns with prior guidance to keep full error details for unexpected failures. Based on learnings.

If you ever want clearer feedback for edge cases (e.g., if a write is somehow attempted without permission), you could emit an explicit “not authorized” toast before the return, but this is strictly optional given the current UI gating.


129-160: readOnly propagation to Static/Dynamic configuration looks correct

Passing readOnly={!canWriteFido} into both StaticConfiguration and DynamicConfiguration and including canWriteFido in the tabToShow dependencies ensures tab content re-renders correctly when permissions change. The write‑gating at this level looks coherent with the shared Cedarling model.

If you later need stricter “view‑only” behavior, consider also propagating a readOnly flag down into lower‑level input components so the fields themselves become visually disabled when write permission is missing.

admin-ui/plugins/fido/components/DynamicConfiguration.tsx (1)

18-65: readOnly handling correctly blocks dynamic FIDO updates

The readOnly prop is consistently honored across the dynamic configuration flow: Formik’s onSubmit, the internal submit handler, the form’s submit event, the Apply button, and the commit dialog all short‑circuit when readOnly is true, so no mutations can slip through.

If read‑only mode is intended to be strictly “view only,” you may also want to propagate readOnly/disabled down into the underlying Gluu* inputs and toggles so users can’t even make temporary local edits that they can’t save anyway.

Also applies to: 318-331

admin-ui/plugins/fido/components/StaticConfiguration.tsx (1)

35-67: Static configuration readOnly flow is consistent with dynamic config

The static configuration path mirrors the dynamic one: Formik onSubmit, submitForm, and the form submit handler are all guarded by readOnly, the Apply button is hidden, and the commit dialog is not rendered in read‑only mode. This gives you robust protection against unintended writes when the user lacks FIDO write permission.

  • As with the dynamic form, consider propagating a disabled/readOnly flag into the Gluu* field components if you want a fully non‑editable UI in read‑only mode.
  • If Cedarling becomes the single source of truth for permissions everywhere, you might eventually revisit whether feature={adminUiFeatures.fido_configuration_write} on GluuCommitDialog is still needed, to avoid mixing permission systems.

Also applies to: 132-141, 378-397

admin-ui/app/components/Sidebar/types.ts (1)

2-10: Consider narrowing resourceKey type to match ADMIN_UI_RESOURCES

resourceKey is currently a plain string, but it looks like it should line up with your Cedarling resource identifiers (e.g., keys of ADMIN_UI_RESOURCES). If you have a shared union type for those (such as AdminUiFeatureResource or keyof typeof ADMIN_UI_RESOURCES), using it here would catch typos at compile time while keeping the field optional. cedarlingPassed as an optional boolean flag is fine as-is.

admin-ui/plugins/auth-server/components/AuthN/AuthNListPage.js (1)

76-97: Fix TDZ: handleGoToAuthNEditPage is used in deps before it is declared.

handleGoToAuthNEditPage is referenced in the useEffect dependency array (Line 96) before its const ... = useCallback(...) declaration (Line 129). In JavaScript this hits the temporal dead zone and can throw a ReferenceError at render time, which matches the Biome noInvalidUseBeforeDeclaration error.

Move the useCallback above the effect (or otherwise ensure it’s declared first) so the identifier is initialized before use:

-  // Actions as state that will rebuild when permissions change
-  useEffect(() => {
-    const newActions = []
-
-    if (canWriteAuthN) {
-      newActions.push((rowData) => {
-        return {
-          icon: 'edit',
-          iconProps: {
-            id: 'editAutN' + rowData.inum,
-            style: { color: customColors.darkGray },
-          },
-          tooltip: `${t('messages.edit_authn')}`,
-          onClick: (event, rowData) => handleGoToAuthNEditPage(rowData),
-          disabled: !canWriteAuthN,
-        }
-      })
-    }
-
-    setMyActions(newActions)
-  }, [canWriteAuthN, t, handleGoToAuthNEditPage])
-
-  const handleGoToAuthNEditPage = useCallback(
-    (row) => {
-      dispatch(setCurrentItem({ item: row }))
-      return navigate(`/auth-server/authn/edit/:` + row.inum)
-    },
-    [dispatch, navigate],
-  )
+  const handleGoToAuthNEditPage = useCallback(
+    (row) => {
+      dispatch(setCurrentItem({ item: row }))
+      return navigate(`/auth-server/authn/edit/:` + row.inum)
+    },
+    [dispatch, navigate],
+  )
+
+  // Actions as state that will rebuild when permissions change
+  useEffect(() => {
+    const newActions = []
+
+    if (canWriteAuthN) {
+      newActions.push((rowData) => ({
+        icon: 'edit',
+        iconProps: {
+          id: 'editAutN' + rowData.inum,
+          style: { color: customColors.darkGray },
+        },
+        tooltip: `${t('messages.edit_authn')}`,
+        onClick: (event, rowData) => handleGoToAuthNEditPage(rowData),
+        disabled: !canWriteAuthN,
+      }))
+    }
+
+    setMyActions(newActions)
+  }, [canWriteAuthN, t, handleGoToAuthNEditPage])

Also applies to: 129-135

admin-ui/plugins/services/Components/Configuration/SqlListPage.js (1)

92-152: Resolve TDZ: SQL action handlers are used before they are declared.

In the actions useEffect dependency array (Lines 143‑152), handleGoToSqlAddPage, handleGoToSqlEditPage, and handleSqlDelete are referenced before their const ... = useCallback(...) declarations (Lines 154‑169). This is a temporal dead zone issue and matches the Biome noInvalidUseBeforeDeclaration errors; it can throw at render time.

Reorder so the callbacks are declared before the effect:

-  // Build actions only when permissions change
-  useEffect(() => {
-    const actions = []
-
-    if (canWriteSql) {
-      actions.push({
-        icon: 'add',
-        tooltip: `${t('tooltips.add_sql')}`,
-        iconProps: { color: 'primary', style: { color: customColors.lightBlue } },
-        isFreeAction: true,
-        onClick: handleGoToSqlAddPage,
-      })
-      actions.push((rowData) => ({
-        icon: 'edit',
-        iconProps: {
-          id: 'editSql' + rowData.configId,
-          style: { color: customColors.darkGray },
-        },
-        tooltip: `${t('tooltips.edit_sql')}`,
-        onClick: (event, rowData) => handleGoToSqlEditPage(rowData),
-        disabled: !canWriteSql,
-      }))
-    }
-
-    if (canReadSql) {
-      actions.push({
-        icon: 'refresh',
-        tooltip: `${t('tooltips.refresh_data')}`,
-        iconProps: { color: 'primary', style: { color: customColors.lightBlue } },
-        isFreeAction: true,
-        onClick: () => {
-          dispatch(getSqlConfig())
-        },
-      })
-    }
-
-    if (canDeleteSql) {
-      actions.push((rowData) => ({
-        icon: () => <DeleteOutlined />,
-        iconProps: {
-          color: 'secondary',
-          id: 'deleteSql' + rowData.configId,
-          style: { color: customColors.darkGray },
-        },
-        tooltip: `${t('tooltips.delete_record')}`,
-        onClick: (event, rowData) => handleSqlDelete(rowData),
-        disabled: !canDeleteSql,
-      }))
-    }
-
-    setMyActions(actions)
-  }, [
-    canReadSql,
-    canWriteSql,
-    canDeleteSql,
-    t,
-    dispatch,
-    handleGoToSqlAddPage,
-    handleGoToSqlEditPage,
-    handleSqlDelete,
-  ])
-
-  const handleGoToSqlEditPage = useCallback(
+  const handleGoToSqlEditPage = useCallback(
     (row) => {
       dispatch(setCurrentItem(row))
       navigate(`/config/sql/edit/:` + row.configId)
     },
     [dispatch, navigate],
   )
@@
   const handleGoToSqlAddPage = useCallback(() => {
     navigate('/config/sql/new')
   }, [navigate])
 
-  const onDeletionConfirmed = useCallback(
+  const onDeletionConfirmed = useCallback(
     (message) => {
       buildPayload(userAction, message, item.configId)
       dispatch(deleteSql(item.configId))
       navigate('/config/sql')
       toggle()
     },
     [item.configId, dispatch, navigate],
   )
+
+  // Build actions only when permissions change
+  useEffect(() => {
+    const actions = []
+
+    if (canWriteSql) {
+      actions.push({
+        icon: 'add',
+        tooltip: `${t('tooltips.add_sql')}`,
+        iconProps: { color: 'primary', style: { color: customColors.lightBlue } },
+        isFreeAction: true,
+        onClick: handleGoToSqlAddPage,
+      })
+      actions.push((rowData) => ({
+        icon: 'edit',
+        iconProps: {
+          id: 'editSql' + rowData.configId,
+          style: { color: customColors.darkGray },
+        },
+        tooltip: `${t('tooltips.edit_sql')}`,
+        onClick: (event, rowData) => handleGoToSqlEditPage(rowData),
+        disabled: !canWriteSql,
+      }))
+    }
+
+    if (canReadSql) {
+      actions.push({
+        icon: 'refresh',
+        tooltip: `${t('tooltips.refresh_data')}`,
+        iconProps: { color: 'primary', style: { color: customColors.lightBlue } },
+        isFreeAction: true,
+        onClick: () => {
+          dispatch(getSqlConfig())
+        },
+      })
+    }
+
+    if (canDeleteSql) {
+      actions.push((rowData) => ({
+        icon: () => <DeleteOutlined />,
+        iconProps: {
+          color: 'secondary',
+          id: 'deleteSql' + rowData.configId,
+          style: { color: customColors.darkGray },
+        },
+        tooltip: `${t('tooltips.delete_record')}`,
+        onClick: (event, rowData) => handleSqlDelete(rowData),
+        disabled: !canDeleteSql,
+      }))
+    }
+
+    setMyActions(actions)
+  }, [
+    canReadSql,
+    canWriteSql,
+    canDeleteSql,
+    t,
+    dispatch,
+    handleGoToSqlAddPage,
+    handleGoToSqlEditPage,
+    handleSqlDelete,
+  ])

Also applies to: 154-179

admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)

100-106: Fix patchHandler’s double state update and array mutation

patchHandler currently:

  • Calls setPatches with a functional update and then immediately mutates the stale patches array and calls setPatches again.
  • This risks duplicate entries and relies on a stale snapshot of patches.

You can simplify to a single, immutable update that also keeps operations in sync:

-  const patchHandler = (patch) => {
-    setPatches((existingPatches) => [...existingPatches, patch])
-    const newPatches = patches
-    newPatches.push(patch)
-    setPatches(newPatches)
-    setOperations(newPatches.concat(put))
-  }
+  const patchHandler = (patch) => {
+    setPatches((existingPatches) => {
+      const nextPatches = [...existingPatches, patch]
+      setOperations(nextPatches.concat(put))
+      return nextPatches
+    })
+  }
admin-ui/plugins/auth-server/components/Agama/AgamaAliasListPage.js (1)

69-98: Fix use-before-declaration of handleEdit in the actions effect

The temporal dead zone (TDZ) issue is confirmed and critical. handleEdit is referenced in the useEffect dependency array (line 98) before its const declaration at line 140. This throws a ReferenceError at first render.

The proposed fix correctly reorders the code: move handleEdit declaration (currently at line 140) before the useEffect that builds actions (currently at lines 69–98). This preserves the safe dependency chain: formik (line 104) → handleSubmit (line 115) → handleEdit (line 140) → useEffect (moves after line 140).

Apply the reordering as suggested in the review.

admin-ui/plugins/services/Components/Configuration/LdapListPage.js (2)

120-183: Simplify action disabled flags gated by can*Ldap

Inside the actions effect, you already wrap action creation in if (canWriteLdap) / if (canDeleteLdap). Within those branches, disabled: !canWriteLdap and disabled: !canDeleteLdap will always evaluate to false, so they don’t actually gate anything.

You can safely drop these disabled properties (or, if you want row-level gating later, base them on row data instead) to reduce confusion:

-        onClick: (event, rowData) => handleGoToLdapEditPage(rowData),
-        disabled: !canWriteLdap,
+        onClick: (event, rowData) => handleGoToLdapEditPage(rowData),
...
-        onClick: (event, rowData) => handleLdapDelete(rowData),
-        disabled: !canDeleteLdap,
+        onClick: (event, rowData) => handleLdapDelete(rowData),

196-204: Attach built audit payload to the dispatched delete action

buildPayload populates userAction.action_message and userAction.action_data, but LdapListPage dispatches only { configId: item.configId }, so LdapSaga’s addAdditionalData will not see the userAction and the audit will miss message/action_data — include the built userAction in the dispatched payload (e.g. dispatch(deleteLdap({ configId: item.configId, action: userAction }))) or change buildPayload to write into the payload shape the saga expects. File: admin-ui/plugins/services/Components/Configuration/LdapListPage.js (lines ~196–204).

admin-ui/app/routes/Apps/Gluu/GluuAppSidebar.tsx (2)

81-87: Deriving isReady from pluginMenus.length can cause an infinite loader

isReady is computed as pluginMenus.length > 0, and the sidebar only exits the loading state when isReady is true. If, after processing and authorization, there are legitimately no menu items (e.g., all filtered out due to health status or permissions, or processMenus returns an empty array), pluginMenus stays empty and:

  • isReady never becomes true,
  • the loader (<GluuLoader blocking />) is shown indefinitely,
  • the wave/footer uses the “fixed” loading style.

This conflates “finished loading, but there are no menus” with “still loading”.

Consider decoupling readiness from the number of menu items, e.g. by tracking a separate boolean that is set once loadMenus finishes (even if it yields an empty array):

-  const [pluginMenus, setPluginMenus] = useState<PluginMenu[]>([])
-  const didAnimateMenusRef = useRef<boolean>(false)
-  const isReady = pluginMenus.length > 0
+  const [pluginMenus, setPluginMenus] = useState<PluginMenu[]>([])
+  const didAnimateMenusRef = useRef<boolean>(false)
+  const [isReady, setIsReady] = useState(false)
...
   const loadMenus = async () => {
     try {
       const filteredMenus = await filterMenuItems(await memoizedFilteredMenus)
       setPluginMenus(filteredMenus)
     } finally {
       if (!didAnimateMenusRef.current) {
         didAnimateMenusRef.current = true
       }
+      setIsReady(true)
     }
   }

This way the UI can render an “empty menu” state without being stuck in a perpetual loading indicator.

Also applies to: 161-170, 183-235, 237-241


148-159: Avoid async useMemo for loading menus

memoizedFilteredMenus is defined as an async useMemo, returning a Promise<PluginMenu[]>. While this works because you later await memoizedFilteredMenus, using useMemo(async () => …) is an anti-pattern: useMemo is designed for synchronous calculations and will re-run in strict mode, potentially re-invoking processMenus more than expected.

A clearer pattern is to keep useMemo synchronous and move the async work entirely into loadMenus (or a dedicated useEffect), e.g.:

// Keep any cheap, sync derivations in useMemo if needed
const menuHealthFilter = useMemo(
  () => (menus: PluginMenu[]) =>
    !fetchedServersLength
      ? []
      : menus.filter((menu) => {
          const healthKey = VISIBILITY_CONDITIONS[menu.path || '']
          return healthKey ? health?.[healthKey] === 'Running' : true
        }),
  [health, fetchedServersLength],
)

// Then in loadMenus:
const loadMenus = useCallback(async () => {
  try {
    const menus = await processMenus()
    const filteredByHealth = menuHealthFilter(menus)
    const filteredMenus = await filterMenuItems(filteredByHealth)
    setPluginMenus(filteredMenus)
  } finally {
    // readiness handling...
  }
}, [menuHealthFilter, filterMenuItems])

This avoids async useMemo semantics and makes the dataflow easier to follow.

admin-ui/plugins/auth-server/components/Clients/ClientListPage.js (1)

198-214: Consider gating initial client fetch on read permission for consistency

The initial useEffect that calls dispatch(getOpenidClients({ action: options })) runs regardless of canReadClient. For unauthorized users, this may still trigger backend calls that will likely return 403s, while the UI is hidden by GluuViewWrapper.

This is not a functional bug, but for consistency with newer patterns (e.g., SAML identities list), you might consider conditioning the fetch on canReadClient once permissions are initialized, to avoid unnecessary calls and align behavior.

admin-ui/plugins/admin/components/Webhook/WebhookListPage.js (1)

92-175: TDZ bug: navigateToAddPage and navigateToEditPage used before declaration in effect dependencies

The useEffect at line 93 references navigateToAddPage and navigateToEditPage in its dependency array (lines 169–170), but both are declared as const arrow functions later at lines 225 and 230. During component render, the dependency array is evaluated synchronously when the effect hook is called, before those declarations are initialized, violating the temporal dead zone and causing a ReferenceError at runtime.

Move both callback declarations above the actions-building useEffect:

  const [limit, setLimit] = useState(10)
  const [pattern, setPattern] = useState(null)

+ const navigateToAddPage = useCallback(() => {
+   dispatch(setSelectedWebhook({}))
+   navigate('/adm/webhook/add')
+ }, [dispatch, navigate])
+
+ const navigateToEditPage = useCallback(
+   (data) => {
+     dispatch(setSelectedWebhook(data))
+     navigate(`/adm/webhook/edit/${data.inum}`)
+   },
+   [dispatch, navigate],
+ )
+
  // Initialize Cedar permissions
  useEffect(() => {

And remove the old declarations at lines 225–234.

admin-ui/plugins/auth-server/components/Scopes/ScopeListPage.tsx (2)

48-77: Scopes Cedarling integration is coherent; consider surfacing authorization errors if needed

Using ADMIN_UI_RESOURCES.Scopes plus CEDAR_RESOURCE_SCOPES and authorizeHelper(scopesScopes) is a clean way to prime Cedarling and then derive canReadScopes/canWriteScopes/canDeleteScopes via hasCedar*Permission. Dependencies on authorizeHelper and scopesScopes mean permissions are recomputed when Cedarling initializes, which avoids “stuck unauthorized” states.

Right now any errors returned from authorizeHelper are ignored; if you ever need better debuggability, you could optionally handle the returned results (e.g., log or toast the first failing entry), but that’s not required for correctness.

Also applies to: 115-137


220-225: Actions and delete dialog correctly respect Cedarling permissions (minor redundancy only)

The edit/add/delete actions are only created when canWriteScopes/canDeleteScopes are truthy, and the delete dialog is additionally gated by canDeleteScopes && item, so unauthorized users can neither trigger actions nor see the confirmation dialog. The disabled: !canWriteScopes / disabled: !canDeleteScopes flags are redundant given the surrounding if (canWriteScopes) / if (canDeleteScopes) guards but harmless; you could drop the disabled properties or, if you want to show disabled icons, always render actions and rely solely on disabled.

Also applies to: 257-311, 482-491

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (1)

190-202: Fix useEffect dependencies to match effect body usage.

The effect body uses the memoized flags canReadAssets, canWriteAssets, and canDeleteAssets (lines 124, 155, 175), but the dependency array lists the hook functions hasCedarReadPermission, hasCedarWritePermission, hasCedarDeletePermission (lines 197-199) instead. Additionally, cedarPermissions (line 191) is listed but never used in the effect body.

Hook functions are stable references that don't change between renders, so listing them as dependencies has no effect. The dependencies should include the memoized flags that are actually used.

Apply this diff to correct the dependencies:

   }, [
-    cedarPermissions,
+    canReadAssets,
+    canWriteAssets,
+    canDeleteAssets,
     limit,
     pattern,
     t,
     navigateToAddPage,
     navigateToEditPage,
-    hasCedarReadPermission,
-    hasCedarWritePermission,
-    hasCedarDeletePermission,
     handleOptionsChange,
     dispatch,
   ])
♻️ Duplicate comments (1)
admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (1)

36-44: Typo fixed, but add null-safety for assetScopes.

The typo from the previous review (AssestsAssets) has been corrected on line 42. However, assetScopes on line 43 still lacks the null-safety fallback suggested in the prior review. If CEDAR_RESOURCE_SCOPES[assetsResourceId] is undefined, authorizeHelper(assetScopes) on line 99 will receive undefined, potentially causing runtime errors.

Apply this diff to add null-safety:

   const assetScopes = useMemo(() => CEDAR_RESOURCE_SCOPES[assetsResourceId], [assetsResourceId])
+  const assetScopes = useMemo(
+    () => CEDAR_RESOURCE_SCOPES[assetsResourceId] ?? [],
+    [assetsResourceId],
+  )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 65f3056 and 5b329bc.

📒 Files selected for processing (1)
  • admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx
🧬 Code graph analysis (1)
admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (2)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (16-257)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (1)

121-202: Tighten myActions effect dependencies to match the new permission flags.

Inside the useEffect that builds actions, the logic now relies on canReadAssets, canWriteAssets, and canDeleteAssets, but the dependency array still includes hasCedarReadPermission, hasCedarWritePermission, and hasCedarDeletePermission instead of the derived flags.

You can simplify and make intent clearer by depending on the can*Assets booleans instead of the raw helpers:

-  useEffect(() => {
+  useEffect(() => {
     const actions: Action<Document>[] = []
     // ... uses canReadAssets / canWriteAssets / canDeleteAssets ...
     setMyActions(actions)
-  }, [
-    cedarPermissions,
-    limit,
-    pattern,
-    t,
-    navigateToAddPage,
-    navigateToEditPage,
-    hasCedarReadPermission,
-    hasCedarWritePermission,
-    hasCedarDeletePermission,
-    handleOptionsChange,
-    dispatch,
-  ])
+  }, [
+    cedarPermissions,
+    limit,
+    pattern,
+    t,
+    navigateToAddPage,
+    navigateToEditPage,
+    canReadAssets,
+    canWriteAssets,
+    canDeleteAssets,
+    handleOptionsChange,
+    dispatch,
+  ])

This keeps the effect tied to the actual booleans that drive the action set.

♻️ Duplicate comments (9)
admin-ui/plugins/fido/components/Fido.tsx (1)

167-171: Past review concern has been resolved.

The component now correctly wraps content with GluuViewWrapper canShow={canReadFido}, ensuring unauthorized users see the standard "Missing required permission" message instead of an indefinite loader. This addresses the previous review comment.

admin-ui/app/cedarling/utility/resources.ts (1)

39-44: Past review concern has been addressed.

The buildCedarPermissionKey function correctly accepts AdminUiFeatureResource (not a plain string) and returns the precise template literal type `${AdminUiFeatureResource}::${CedarAction}`. This provides compile-time guarantees for valid resource IDs and permission keys as requested in the previous review.

admin-ui/app/routes/Apps/Gluu/GluuDialog.tsx (1)

32-46: Past review concern has been resolved.

The defensive pattern has been correctly implemented with webhookScopes defaulting to || [] and the authorization effect properly guarded with a length check. This ensures the dialog degrades gracefully when scopes are missing.

admin-ui/app/utils/AppAuthProvider.tsx (1)

175-186: Past review concern about type annotation has been resolved.

The type annotation at line 177 has been correctly updated to { access_token: string }, matching the runtime shape returned by fetchApiAccessToken. The single-argument call at line 175 is safe since fetchApiAccessToken provides a default value (permissionTag || []) for the second parameter.

admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx (1)

50-64: Past review concern has been resolved.

The defensive pattern has been correctly implemented with webhookScopes defaulting to || [] and the authorization call properly guarded with a length check. This matches the pattern in GluuDialog.tsx and ensures graceful handling when scopes are missing.

admin-ui/plugins/user-management/components/UserList.tsx (1)

76-89: Apply defensive fallback pattern for consistency with codebase conventions.

While the code is functional, it inconsistently omits the || [] fallback that has been adopted across newer components (SsaListPage at line 62, AgamaListPage at line 85, GluuDialog at line 34, and GluuCommitDialog at line 52). Additionally, usersResourceId doesn't need memoization since ADMIN_UI_RESOURCES.Users is a static constant.

Apply this refactor to align with current codebase patterns:

-  const usersResourceId = useMemo(() => ADMIN_UI_RESOURCES.Users, [])
-  const usersScopes = useMemo(() => CEDAR_RESOURCE_SCOPES[usersResourceId], [usersResourceId])
+  const usersResourceId = ADMIN_UI_RESOURCES.Users
+  const usersScopes = useMemo(
+    () => CEDAR_RESOURCE_SCOPES[usersResourceId] || [],
+    [usersResourceId],
+  )

This removes unnecessary memoization of a static string and adds the defensive || [] safeguard.

admin-ui/plugins/schema/components/Person/AttributeListPage.tsx (1)

116-129: Optional: drop useMemo for static attribute resource constants.

Since ADMIN_UI_RESOURCES and CEDAR_RESOURCE_SCOPES are static, you can simplify this block by using plain constants instead of useMemo:

-  const attributeResourceId = useMemo(() => ADMIN_UI_RESOURCES.Attributes, [])
-  const attributeScopes = useMemo(() => CEDAR_RESOURCE_SCOPES[ADMIN_UI_RESOURCES.Attributes], [])
+  const attributeResourceId = ADMIN_UI_RESOURCES.Attributes
+  const attributeScopes = CEDAR_RESOURCE_SCOPES[ADMIN_UI_RESOURCES.Attributes]

Behavior remains the same but reduces hook noise and makes the resource wiring a bit easier to read.

admin-ui/app/cedarling/hooks/useCedarling.ts (2)

36-54: Action inference heuristic is reasonable; consider tightening case‑insensitive set

The executeUrls set plus getActionLabelFromUrl heuristic is a reasonable way to infer CedarAction from permission URLs. To make the special‑case matching more robust against future constant changes, you could normalize the set contents as well:

-  const executeUrls = new Set([SSA_ADMIN, SSA_DEVELOPER, SCIM_BULK, REVOKE_SESSION, OPENID])
+  const executeUrls = new Set(
+    [SSA_ADMIN, SSA_DEVELOPER, SCIM_BULK, REVOKE_SESSION, OPENID].map((u) => u.toLowerCase()),
+  )

This keeps the executeUrls.has(lowerUrl) check reliably case‑insensitive even if new constants are not already lower‑case.


55-61: Cache key usage is sound; confirm legacy fallback strategy

The buildAuthorizationRequest / getCachedDecisionByAction pattern correctly reuses buildCedarPermissionKey(resourceId, action) and safely short‑circuits on cachedDecision before touching request, which avoids unnecessary network calls.

In getCachedPermission, the preference for the explicit 'resource::read' key with a fallback to permissionsByResourceId[resourceId] is a good bridge for legacy cache entries; just ensure this fallback is intentionally kept for backward compatibility and plan to remove it once all entries are normalized to the composite key form.

Also applies to: 97-114

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b329bc and 050ce75.

📒 Files selected for processing (19)
  • admin-ui/app/cedarling/constants/resourceScopes.ts (1 hunks)
  • admin-ui/app/cedarling/hooks/useCedarling.ts (6 hunks)
  • admin-ui/app/cedarling/utility/resources.ts (1 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx (4 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuDialog.tsx (3 hunks)
  • admin-ui/app/routes/License/LicenseDetailsPage.tsx (6 hunks)
  • admin-ui/app/utils/AppAuthProvider.tsx (2 hunks)
  • admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (7 hunks)
  • admin-ui/plugins/auth-server/components/Agama/AgamaListPage.js (9 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.js (3 hunks)
  • admin-ui/plugins/auth-server/components/Sessions/SessionListPage.tsx (5 hunks)
  • admin-ui/plugins/auth-server/components/Ssa/SsaListPage.tsx (8 hunks)
  • admin-ui/plugins/fido/components/Fido.tsx (7 hunks)
  • admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx (2 hunks)
  • admin-ui/plugins/saml/components/SamlIdentityList.js (8 hunks)
  • admin-ui/plugins/saml/components/TrustRelationshipList.js (6 hunks)
  • admin-ui/plugins/schema/components/Person/AttributeListPage.tsx (9 hunks)
  • admin-ui/plugins/smtp-management/components/SmtpManagement/SmtpEditPage.tsx (6 hunks)
  • admin-ui/plugins/user-management/components/UserList.tsx (9 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/app/utils/AppAuthProvider.tsx
  • admin-ui/plugins/schema/components/Person/AttributeListPage.tsx
  • admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx
  • admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx
  • admin-ui/plugins/auth-server/components/Sessions/SessionListPage.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.js
  • admin-ui/plugins/user-management/components/UserList.tsx
  • admin-ui/plugins/saml/components/SamlIdentityList.js
  • admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx
  • admin-ui/app/cedarling/constants/resourceScopes.ts
  • admin-ui/plugins/fido/components/Fido.tsx
  • admin-ui/plugins/auth-server/components/Agama/AgamaListPage.js
  • admin-ui/app/cedarling/hooks/useCedarling.ts
  • admin-ui/app/routes/Apps/Gluu/GluuDialog.tsx
  • admin-ui/app/routes/License/LicenseDetailsPage.tsx
  • admin-ui/app/cedarling/utility/resources.ts
📚 Learning: 2025-11-07T12:17:39.857Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).

Applied to files:

  • admin-ui/plugins/schema/components/Person/AttributeListPage.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.js
  • admin-ui/plugins/user-management/components/UserList.tsx
  • admin-ui/app/cedarling/constants/resourceScopes.ts
  • admin-ui/app/routes/Apps/Gluu/GluuDialog.tsx
  • admin-ui/app/cedarling/utility/resources.ts
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx
  • admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx
  • admin-ui/plugins/auth-server/components/Sessions/SessionListPage.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.js
  • admin-ui/plugins/user-management/components/UserList.tsx
  • admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx
  • admin-ui/plugins/auth-server/components/Agama/AgamaListPage.js
  • admin-ui/app/cedarling/hooks/useCedarling.ts
  • admin-ui/app/routes/Apps/Gluu/GluuDialog.tsx
📚 Learning: 2025-11-11T15:17:34.651Z
Learnt from: devrimyatar
Repo: GluuFederation/flex PR: 2440
File: flex-linux-setup/flex_linux_setup/flex_setup.py:519-519
Timestamp: 2025-11-11T15:17:34.651Z
Learning: In flex-linux-setup/flex_linux_setup/flex_setup.py, the webhook LDIF (aui_webhook.ldif) should only be imported during fresh Admin UI installations, not during updates. The import is correctly guarded by the check `client_check_result['2001.'] == -1` which ensures it only runs when the Admin UI Web Client doesn't already exist. Docker update workflows differ from Linux update workflows in this regard.

Applied to files:

  • admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx
  • admin-ui/app/routes/Apps/Gluu/GluuDialog.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Ssa/SsaListPage.tsx
🧬 Code graph analysis (19)
admin-ui/app/utils/AppAuthProvider.tsx (1)
admin-ui/app/redux/api/backend-api.ts (2)
  • fetchApiAccessToken (72-83)
  • fetchPolicyStore (95-98)
admin-ui/plugins/schema/components/Person/AttributeListPage.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/jans-lock/components/JansLockConfiguration.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/app/routes/Apps/Gluu/GluuCommitDialog.tsx (2)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/plugins/auth-server/components/Sessions/SessionListPage.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.js (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/user-management/components/UserList.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/saml/components/SamlIdentityList.js (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/app/cedarling/constants/resourceScopes.ts (3)
admin-ui/app/cedarling/types/index.ts (2)
  • AdminUiFeatureResource (198-225)
  • ResourceScopeEntry (88-91)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/utils/PermChecker.ts (72)
  • STAT_READ (106-106)
  • STAT_JANS_READ (107-107)
  • LICENSE_DETAILS_READ (33-33)
  • LICENSE_DETAILS_WRITE (35-35)
  • ASSETS_READ (131-131)
  • ASSETS_WRITE (132-132)
  • ASSETS_DELETE (133-133)
  • WEBHOOK_READ (128-128)
  • WEBHOOK_WRITE (129-129)
  • WEBHOOK_DELETE (130-130)
  • SCRIPT_READ (61-61)
  • SCRIPT_WRITE (62-62)
  • SCRIPT_DELETE (63-63)
  • CACHE_READ (88-88)
  • CACHE_WRITE (89-89)
  • CACHE_DELETE (90-90)
  • PERSISTENCE_DETAIL (104-104)
  • SQL_READ (100-100)
  • SQL_WRITE (101-101)
  • SQL_DELETE (102-102)
  • LDAP_READ (92-92)
  • LDAP_WRITE (93-93)
  • LDAP_DELETE (94-94)
  • JANS_LOCK_READ (85-85)
  • JANS_LOCK_WRITE (86-86)
  • FIDO_READ (81-81)
  • FIDO_WRITE (82-82)
  • FIDO_DELETE (83-83)
  • SMTP_READ (65-65)
  • SMTP_WRITE (66-66)
  • SMTP_DELETE (67-67)
  • SCIM_CONFIG_READ (123-123)
  • SCIM_CONFIG_WRITE (124-124)
  • USER_READ (109-109)
  • USER_WRITE (110-110)
  • USER_DELETE (111-111)
  • SAML_READ (51-51)
  • SAML_WRITE (52-52)
  • SAML_DELETE (53-53)
  • SAML_TR_READ (55-55)
  • SAML_TR_WRITE (56-56)
  • SAML_CONFIG_READ (58-58)
  • SAML_CONFIG_WRITE (59-59)
  • ATTRIBUTE_READ (7-7)
  • ATTRIBUTE_WRITE (8-8)
  • ATTRIBUTE_DELETE (9-9)
  • SSA_PORTAL (41-41)
  • SSA_ADMIN (42-42)
  • SSA_DELETE (43-43)
  • SCOPE_READ (37-37)
  • SCOPE_WRITE (38-38)
  • SCOPE_DELETE (39-39)
  • SESSION_READ (117-117)
  • SESSION_DELETE (118-118)
  • ACR_READ (69-69)
  • ACR_WRITE (70-70)
  • AGAMA_READ (113-113)
  • AGAMA_WRITE (114-114)
  • AGAMA_DELETE (115-115)
  • CLIENT_READ (11-11)
  • CLIENT_WRITE (12-12)
  • CLIENT_DELETE (13-13)
  • PROPERTIES_WRITE (4-4)
  • API_CONFIG_READ (135-135)
  • API_CONFIG_WRITE (136-136)
  • LOGGING_READ (73-73)
  • LOGGING_WRITE (74-74)
  • JWKS_READ (77-77)
  • JWKS_WRITE (78-78)
  • ROLE_READ (15-15)
  • PERMISSION_READ (19-20)
  • MAPPING_READ (26-27)
admin-ui/plugins/fido/components/Fido.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/auth-server/components/Agama/AgamaListPage.js (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/app/cedarling/hooks/useCedarling.ts (5)
admin-ui/app/cedarling/types/index.ts (5)
  • UseCedarlingReturn (93-102)
  • CedarAction (229-229)
  • AdminUiFeatureResource (198-225)
  • ResourceScopeEntry (88-91)
  • AuthorizationResult (54-58)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDARLING_CONSTANTS (215-218)
admin-ui/app/utils/PermChecker.ts (5)
  • SSA_ADMIN (42-42)
  • SSA_DEVELOPER (44-44)
  • SCIM_BULK (49-49)
  • REVOKE_SESSION (46-46)
  • OPENID (47-47)
admin-ui/app/cedarling/utility/resources.ts (1)
  • buildCedarPermissionKey (39-44)
admin-ui/app/cedarling/client/CedarlingClient.ts (1)
  • cedarlingClient (56-59)
admin-ui/plugins/smtp-management/components/SmtpManagement/SmtpEditPage.tsx (4)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/smtp-management/redux/types/SmtpApi.type.ts (1)
  • SmtpTest (18-22)
admin-ui/app/routes/Apps/Gluu/GluuDialog.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/app/routes/License/LicenseDetailsPage.tsx (5)
admin-ui/app/redux/features/licenseDetailsSlice.ts (1)
  • LicenseDetailsState (21-24)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/routes/License/types.ts (1)
  • LicenseField (1-5)
admin-ui/app/utils/Util.ts (1)
  • formatDate (53-64)
admin-ui/app/cedarling/utility/resources.ts (2)
admin-ui/app/cedarling/types/index.ts (3)
  • AdminUiFeatureResource (198-225)
  • ApiPermissionType (227-227)
  • CedarAction (229-229)
admin-ui/plugins/admin/redux/sagas/ApiPermissionSaga.js (1)
  • apiPermissions (126-126)
admin-ui/plugins/saml/components/TrustRelationshipList.js (5)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/plugins/saml/components/SamlIdentityList.js (10)
  • useCedarling (40-45)
  • theme (51-51)
  • selectedTheme (52-52)
  • themeColors (53-53)
  • samlResourceId (61-61)
  • samlScopes (62-62)
  • dispatch (58-58)
  • tableActions (169-233)
  • handleGoToEditPage (86-88)
  • handleGoToAddPage (90-92)
admin-ui/plugins/user-management/types/CommonTypes.ts (1)
  • ThemeContext (13-17)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
admin-ui/plugins/auth-server/components/Ssa/SsaListPage.tsx (3)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (17-260)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (79-213)
🔇 Additional comments (14)
admin-ui/plugins/auth-server/components/Ssa/SsaListPage.tsx (1)

61-79: LGTM! Defensive pattern correctly implemented.

The Cedar permission wiring correctly uses the defensive || [] fallback for ssaScopes and properly guards the authorizeHelper call. This aligns with the pattern established across the codebase.

admin-ui/plugins/smtp-management/components/SmtpManagement/SmtpEditPage.tsx (1)

94-108: Cedar-based SMTP read/write gating and readOnly wiring look correct

The SMTP page now cleanly uses hasCedarReadPermission / hasCedarWritePermission for the SMTP resource, pre-warms permissions via authorizeHelper(smtpScopes), gates handleSubmit and handleTestSmtp with an early if (!canWriteSmtp) return, and drives both GluuViewWrapper canShow={canReadSmtp} and readOnly={!canWriteSmtp} on SmtpForm. This aligns with the Cedar patterns used elsewhere and should correctly prevent unauthorized writes while still showing the UI for authorized readers.

Also applies to: 149-191, 198-219

admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.js (1)

26-45: Logging Cedar permissions now use strict booleans and correctly gate data fetch & UI

canReadLogging / canWriteLogging are now strict booleans, authorizeHelper(loggingScopes) is called once with a scopes-length guard, and getLoggingConfig() is dispatched only when canReadLogging === true. The view and commit footer are gated by these flags, which aligns with the intended Cedar pattern and removes the previous cedarPermissions no-op wiring.

Also applies to: 51-62, 116-121, 206-218

admin-ui/app/routes/License/LicenseDetailsPage.tsx (1)

25-48: License Cedar write gating and typed license fields look good

The license details page now:

  • Uses a typed selector (LicenseDetailsState) for { item, loading }.
  • Derives licenseResourceId / licenseScopes and pre-warms Cedar via authorizeHelper(licenseScopes).
  • Computes canWriteLicense from hasCedarWritePermission(licenseResourceId) and uses it solely to gate the reset button and commit dialog.
  • Structures licenseFields as a typed LicenseField[] and centralizes rendering through renderLicenseField, including formatted validity dates via formatDate.

This is a clean, type-safe integration of Cedar write permissions without altering the existing read behavior.

Also applies to: 67-99, 144-168

admin-ui/plugins/auth-server/components/Sessions/SessionListPage.tsx (1)

33-35: Session delete/revoke flows are correctly gated by Cedar delete permission

The sessions list now derives sessionResourceId / sessionScopes, pre-warms Cedar with authorizeHelper(sessionScopes) (guarded on scopes length), and uses hasCedarDeletePermission(sessionResourceId) to drive canDeleteSession. That flag:

  • Disables the delete action via disabled: !canDeleteSession,
  • Controls whether the delete action is added to myActions, and
  • Gates the revoke-username UI ({canDeleteSession && (...)}).

This ensures delete and revoke operations are only available when Cedar has explicitly granted the delete permission, while leaving the base listing behavior unchanged.

Also applies to: 54-56, 172-181, 183-188, 203-225, 555-595

admin-ui/plugins/saml/components/SamlIdentityList.js (1)

40-45: Cedar-based permission wiring and action gating look consistent.

Using samlResourceId/samlScopes, authorizeHelper, and the derived canReadIdentities/canWriteIdentities/canDeleteIdentities flags aligns with the new resource-scoped model. Table actions, view wrapper (canShow={canReadIdentities}), and delete dialog gating by canDeleteIdentities are all coherent with how other Cedar-aware pages are structured.

Also applies to: 61-80, 169-223, 237-274

admin-ui/plugins/admin/components/Assets/JansAssetListPage.tsx (1)

30-43: Assets page Cedar integration and gating look correct.

assetsResourceId/assetScopes wiring, authorizeHelper(assetScopes) in the init effect, and the derived canReadAssets/canWriteAssets/canDeleteAssets booleans are consistent with the new Cedar model. Using canReadAssets for GluuViewWrapper and gating actions with can*Assets is a good improvement over the previous ad‑hoc checks.

Also applies to: 96-107, 108-119, 155-187, 271-331

admin-ui/plugins/saml/components/TrustRelationshipList.js (1)

20-27: TrustRelationship Cedar integration and action list refactor look solid.

  • samlResourceId/samlScopes and authorizeHelper(samlScopes) correctly initialize Cedar permissions for SAML.
  • canReadTrustRelationships/canWriteTrustRelationships are used consistently to gate fetching, table actions, view wrapper, and the delete dialog.
  • The rewritten tableActions now pushes each action in separate calls, eliminating the earlier nested actions.push bug and keeping the array clean.

Also applies to: 40-60, 82-127, 131-163

admin-ui/app/cedarling/constants/resourceScopes.ts (2)

1-213: Resource–scope map is well-typed and complete.

CEDAR_RESOURCE_SCOPES now uses Record<AdminUiFeatureResource, ResourceScopeEntry[]> with exhaustive entries for all ADMIN_UI_RESOURCES keys, and each resource is mapped to the expected permission constants. This addresses the earlier risk of missing mappings returning undefined at runtime and gives a single, type-safe source of truth for Cedar resource scopes.


215-218: CEDARLING_CONSTANTS definition matches hook usage.

Defining ACTION_TYPE and RESOURCE_TYPE here and consuming them via CEDARLING_CONSTANTS in useCedarling keeps Cedar action/resource identifiers centralized and easy to update.

admin-ui/plugins/schema/components/Person/AttributeListPage.tsx (1)

61-68: Attribute list Cedar permissions and action gating are consistent with the new model.

  • attributeResourceId / attributeScopes correctly point at ADMIN_UI_RESOURCES.Attributes and its scopes.
  • authorizeHelper(attributeScopes) is invoked once to populate Cedar decisions.
  • canRead/Write/DeleteAttributes are used coherently to:
    • gate the view (GluuViewWrapper canShow={canReadAttributes}),
    • control which row actions are available in attributeActions, and
    • guard the delete dialog via canDeleteAttributes.

This keeps attribute listing, editing, and deletion aligned with Cedarling-driven authorization.

Also applies to: 91-99, 116-129, 223-278, 367-501

admin-ui/app/cedarling/hooks/useCedarling.ts (3)

3-35: Redux wiring for Cedarling permissions looks consistent

Imports, token extraction from authReducer, and the cedarPermissions selector (including permissions, initialized, and isInitializing) are consistent with the new Cedarling-centric state model; no issues spotted here.


199-221: authorizeHelper fan‑out logic is correct and resilient

The authorizeHelper utility cleanly composes multiple authorize calls, short‑circuits on an empty input array, and uses Promise.allSettled to ensure one failing authorization does not prevent others from returning structured AuthorizationResults. The mapping of rejected promises into { isAuthorized: false, error: ... } keeps the return type consistent for callers.


116-123: I need to verify one more detail: whether the line 204 map pattern is wrapped by authorizeHelper, and whether any code actually passes multi-element arrays to authorize().


The authorize function accepts an array by design but intentionally processes only the first element. All verified call sites in the codebase already follow this pattern correctly:

  • Single-element calls: UiPermListPage.js, MappingPage.js, MappingItem.js, UiRoleListPage.js, GluuAppSidebar.tsx
  • Multi-entry fan-out: useCedarling.ts:204 uses resourceScopes.map((entry) => authorize([entry])), wrapping each entry individually

The API design is intentional. There are no silent failures or ignored entries—callers already pass single-element arrays or fan-out multi-entry checks via the map pattern, which pairs with authorizeHelper for aggregated results (as mentioned in your original review). No changes are required.

Likely an incorrect or invalid review comment.

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-ui/plugins/auth-server/plugin-metadata.js (1)

220-223: Add missing resourceKey to ReportPage route.

The ReportPage route at lines 220-223 lacks a resourceKey field, while all 17 other routes in this file include one. The Reports constant does not exist in ADMIN_UI_RESOURCES (defined in admin-ui/app/cedarling/utility/resources.ts). You must either:

  1. Add a new Reports constant to ADMIN_UI_RESOURCES and use resourceKey: ADMIN_UI_RESOURCES.Reports, or
  2. Use an existing appropriate constant such as ADMIN_UI_RESOURCES.Dashboard, or
  3. Use CEDARLING_BYPASS if this route should bypass Cedarling authorization checks.
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (1)

103-125: Simplify change‑diff construction and avoid heavy unknown casting around editLoggingConfig

The mergedValues / changedFieldsResult logic is correct, but the series of as unknown as Record<string, unknown> casts and the manual remap into changedFields: Record<string, { oldValue; newValue }> add noise and weaken type safety. Similarly, retyping editLoggingConfig via as unknown as (payload: EditLoggingPayload) => { … } sidelines the slice’s actual typing.

Two suggestions:

  1. Narrow the typings around diffing so you don’t need unknown:

    • Introduce a helper alias like type LoggingRecord = Record<keyof Logging, unknown> in utils.ts.
    • Call getMergedValues<LoggingRecord> / getChangedFields<LoggingRecord> and keep the return type, instead of down‑ and up‑casting through unknown and rebuilding the map with Object.keys + null checks.
  2. Fix the action creator typing at the source:

    • Update the editLoggingConfig creator in loggingSlice so its payload type matches { data: Record<string, string>; otherFields: { userMessage: string; changedFields: … } }.
    • Then you can call dispatch(editLoggingConfig({ data: opts, otherFields: { userMessage, changedFields } })) directly without the as unknown as override.

This will make the submit path more readable and prevent future payload shape mistakes from slipping past the compiler.

Also applies to: 138-159

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 991f625 and f7611f5.

📒 Files selected for processing (6)
  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (4 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (6 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Keys/Jwks/JwkListPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Keys/KeysPage.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Keys/hooks/useJwkActions.ts (1 hunks)
  • admin-ui/plugins/auth-server/plugin-metadata.js (5 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.
📚 Learning: 2025-11-07T12:17:39.857Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
  • admin-ui/plugins/auth-server/plugin-metadata.js
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
  • admin-ui/plugins/auth-server/plugin-metadata.js
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-03T08:47:33.943Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.943Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/plugin-metadata.js
🧬 Code graph analysis (3)
admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (1)
admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/types/configApiTypes.ts (1)
  • JsonPatch (3-3)
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (1)
admin-ui/plugins/auth-server/components/Configuration/Defaults/utils.ts (4)
  • LOG_LEVELS (1-1)
  • LOG_LAYOUTS (2-2)
  • getMergedValues (49-54)
  • getChangedFields (56-69)
admin-ui/plugins/auth-server/plugin-metadata.js (1)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
🔇 Additional comments (11)
admin-ui/plugins/auth-server/components/Configuration/Keys/hooks/useJwkActions.ts (1)

5-15: Question: Why was JSDoc removed in a Cedarling integration PR?

The AI summary indicates that JSDoc comments describing the useJwkActions hook were removed, but no functional changes were made to this file. This documentation removal seems unrelated to the PR's objective of integrating Cedarling flow.

Removing documentation generally reduces code maintainability. If this is incidental cleanup, consider:

  • Keeping the documentation unless it's outdated or incorrect
  • Moving documentation-only changes to a separate cleanup PR

Could you clarify the rationale for removing the JSDoc in this PR?

admin-ui/plugins/auth-server/plugin-metadata.js (2)

61-61: LGTM: Import enables resource-scoped authorization.

The import of ADMIN_UI_RESOURCES correctly supports the new Cedarling-based permission checks throughout the plugin metadata.


84-136: Excellent: Resource keys are consistently applied, and previous feedback addressed.

The resourceKey fields have been systematically added to all menu items and routes, correctly mapping them to their corresponding ADMIN_UI_RESOURCES constants. Notably, the Agama route at line 228 now includes resourceKey: ADMIN_UI_RESOURCES.Authentication, which addresses the previous review comment about consistency with other Authentication-related routes.

Also applies to: 151-252

admin-ui/plugins/auth-server/components/Configuration/Keys/Jwks/JwkListPage.tsx (1)

61-61: Documentation cleanup - no functional changes.

The removal of the explanatory comment is a minor documentation cleanup with no impact on functionality. The component implementation remains unchanged.

admin-ui/plugins/auth-server/components/Configuration/Keys/KeysPage.tsx (3)

1-11: Cedarling authorization imports added correctly.

The new imports for React hooks (useMemo, useEffect) and Cedarling utilities are appropriate for the authorization integration. The imports follow consistent patterns seen across the PR's Cedarling migration.


32-44: No issues found - GluuViewWrapper correctly handles unauthorized access.

The verification confirms that GluuViewWrapper appropriately handles the unauthorized case. When canShow is false or null, it renders a localized permission error message (t('messages.missing_required_permission')) with role="alert" for accessibility, rather than a blank page. The implementation in KeysPage.tsx correctly uses this wrapper to gate access based on the canReadKeys permission.


13-27: No issues found—authorization logic is properly optimized.

Verification confirms that authorizeHelper is correctly wrapped with useCallback and has appropriate dependencies: [authorize, getActionLabelFromUrl]. This ensures the function remains stable across renders, preventing unnecessary re-executions of the useEffect in KeysPage. The dependency array in the component's useEffect is correct.

admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (3)

1-1: LGTM: Import additions support the Cedarling integration.

The added imports (useMemo, CEDAR_RESOURCE_SCOPES, ADMIN_UI_RESOURCES) are all utilized in the new authorization flow.

Also applies to: 7-8


45-48: No changes required - memoization is correctly implemented.

Verification confirms that hasCedarWritePermission is properly wrapped in useCallback with appropriate dependencies in the useCedarling hook. The function is stable across renders, and configApiResourceId is a constant reference. The memoization setup in ApiConfigForm.tsx (lines 45–48) is correct and will effectively prevent unnecessary re-computations.


98-105: Authorization checks verified—no issues found.

All resource and scope definitions are properly configured:

  • ADMIN_UI_RESOURCES.ConfigApiConfiguration is defined in git/admin-ui/app/cedarling/utility/resources.ts
  • CEDAR_RESOURCE_SCOPES has the correct entry with both API_CONFIG_READ and API_CONFIG_WRITE permissions
  • canWriteConfigApi correctly uses hasCedarWritePermission(configApiResourceId) to control the rendering of both GluuCommitFooter and GluuCommitDialog

The conditional rendering implementation is sound and consistent with the authorization framework.

admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (1)

50-71: Cedarling permission wiring and gated fetch look solid

The loggingResourceId + loggingScopes setup, authorizeHelper(loggingScopes) effect, and the canReadLogging / canWriteLogging flags (used both to gate getLoggingConfig() and to drive GluuViewWrapper / footer visibility) form a clean, deterministic authorization flow and address earlier feedback about fetching only when read access is granted. No changes needed here.

Also applies to: 76-87, 166-170

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (1)

95-122: changedFields computation is correct but can be simplified

Functionally this is fine—getMergedValues followed by getChangedFields against localLogging gives you a precise diff for audit. The extra changedFields rebuild via Object.keys(changedFieldsResult) is redundant, since getChangedFields already omits unchanged fields; you could instead cast changedFieldsResult to the concrete Record<string, { oldValue; newValue }> type to avoid the second loop and branch.

♻️ Duplicate comments (2)
admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (2)

50-54: Authorization initialization pattern is correct.

The guard condition if (configApiScopes && configApiScopes.length > 0) (line 51) ensures authorizeHelper is only called when scopes are available, which matches the pattern used in other components and prevents unnecessary calls with empty arrays.


39-43: Consider optimizing constant resource ID usage.

The configApiResourceId is derived from a constant and never changes, so including it in the useMemo dependency array (line 42) causes unnecessary dependency tracking. Consider moving configApiResourceId to module scope as a constant.

Apply this diff to move the constant outside the component:

+const CONFIG_API_RESOURCE_ID = ADMIN_UI_RESOURCES.ConfigApiConfiguration
+
 const ApiConfigForm: React.FC<ApiConfigFormProps> = ({ configuration, onSubmit }) => {
   const { authorizeHelper, hasCedarWritePermission } = useCedarling()
   const navigate = useNavigate()
   const [modal, setModal] = useState(false)
   const [patches, setPatches] = useState<JsonPatch[]>([])
 
   const operations = patches
-  const configApiResourceId = ADMIN_UI_RESOURCES.ConfigApiConfiguration
   const configApiScopes = useMemo(
-    () => CEDAR_RESOURCE_SCOPES[configApiResourceId] || [],
-    [configApiResourceId],
+    () => CEDAR_RESOURCE_SCOPES[CONFIG_API_RESOURCE_ID] || [],
+    [],
   )
 
   const canWriteConfigApi = useMemo(
-    () => hasCedarWritePermission(configApiResourceId),
-    [hasCedarWritePermission, configApiResourceId],
+    () => hasCedarWritePermission(CONFIG_API_RESOURCE_ID),
+    [hasCedarWritePermission],
   )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7611f5 and 8b9cc5b.

📒 Files selected for processing (3)
  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (4 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (6 hunks)
  • admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.
📚 Learning: 2025-11-07T12:17:39.857Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-03T08:47:33.943Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.943Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (2)
admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (1)
  • RootState (10-12)
admin-ui/plugins/auth-server/components/Configuration/Defaults/utils.ts (4)
  • LOG_LEVELS (1-1)
  • LOG_LAYOUTS (2-2)
  • getMergedValues (49-54)
  • getChangedFields (56-69)
🔇 Additional comments (5)
admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (1)

100-116: LGTM! Conditional rendering based on write permissions.

The footer and dialog components are correctly gated by canWriteConfigApi, ensuring only authorized users can access write operations. The initial undefined state properly hides these components until authorization completes.

admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (2)

1-1: LGTM!

The type-only import is appropriate and follows TypeScript best practices.


4-7: LGTM!

The interface follows standard Redux state patterns with appropriate nullable typing for the logging configuration and a loading flag for async operations.

admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (2)

33-45: Good use of canonical RootState and Redux wiring

Importing RootState from loggingTypes and using typed useSelector for logging and loading keeps this page aligned with the slice/store definition and addresses the previous drift risk from local RootState declarations.


42-79: Cedar permission gating and logging fetch flow look solid

Deriving canReadLogging / canWriteLogging as strict booleans and splitting permission initialization (authorizeHelper(loggingScopes)) from the getLoggingConfig fetch gated on canReadLogging makes the flow clearer and ensures the API is only called when the user has read access, matching the Cedarling patterns used elsewhere.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)

84-84: Remove dead code.

This useEffect has an empty body and serves no purpose.

Apply this diff:

-  useEffect(() => {}, [cedarPermissions])
♻️ Duplicate comments (2)
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (1)

256-266: Add explicit onBack handler to navigate to auth-server configuration context.

The GluuFormFooter currently has showBack={true} but no onBack handler, so it defaults to navigateToHome() (dashboard). Based on recent learnings (PRs #2418, #2415), the Back button should navigate to the appropriate context—in this case, the auth-server configuration area—rather than the dashboard. This keeps users within the auth-server plugin context when they dismiss the form.

Add an onBack prop to GluuFormFooter (line 256-266) with a handler that navigates to the relevant auth-server configuration landing point instead of the default dashboard.

admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (1)

34-48: Avoid memoizing hasCedarWritePermission result to prevent stale permissions.

canWriteConfigApi is memoized from hasCedarWritePermission(configApiResourceId):

const canWriteConfigApi = useMemo(
  () => hasCedarWritePermission(configApiResourceId),
  [hasCedarWritePermission, configApiResourceId],
)

If hasCedarWritePermission is a stable callback from the Cedarling context (common pattern), its identity will not change when authorization state updates, so this useMemo may cache the initial permission and never recompute, causing the footer and dialog (gated by canWriteConfigApi) to stay hidden even after authorization completes.

Given the low cost of the check and the importance of correct permission gating, it’s safer to drop useMemo here and compute on each render:

-  const canWriteConfigApi = useMemo(
-    () => hasCedarWritePermission(configApiResourceId),
-    [hasCedarWritePermission, configApiResourceId],
-  )
+  const canWriteConfigApi = hasCedarWritePermission(configApiResourceId)

Optionally (as previously suggested), you can also hoist the resource ID to a module‑level constant to avoid recreating it and simplify memo dependencies, for example:

// At module scope
const CONFIG_API_RESOURCE_ID = ADMIN_UI_RESOURCES.ConfigApiConfiguration

// Inside the component
const configApiScopes = useMemo(
  () => CEDAR_RESOURCE_SCOPES[CONFIG_API_RESOURCE_ID] || [],
  [],
)
const canWriteConfigApi = hasCedarWritePermission(CONFIG_API_RESOURCE_ID)

Also applies to: 76-111

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b9cc5b and 126cbf9.

📒 Files selected for processing (7)
  • admin-ui/app/helpers/index.js (1 hunks)
  • admin-ui/app/helpers/navigation.ts (1 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx (2 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (5 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (6 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (6 hunks)
  • admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js
  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-07T12:17:39.857Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js
  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js
  • admin-ui/app/helpers/navigation.ts
  • admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-03T08:47:33.943Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.943Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js
  • admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js
  • admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
🧬 Code graph analysis (5)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (4)
admin-ui/app/cedarling/hooks/useCedarling.ts (1)
  • useCedarling (16-268)
admin-ui/app/helpers/navigation.ts (1)
  • useAppNavigation (8-21)
admin-ui/app/cedarling/utility/resources.ts (1)
  • ADMIN_UI_RESOURCES (5-33)
admin-ui/app/cedarling/constants/resourceScopes.ts (1)
  • CEDAR_RESOURCE_SCOPES (80-215)
admin-ui/app/helpers/navigation.ts (2)
admin-ui/plugins/auth-server/components/Configuration/Keys/constants.ts (1)
  • ROUTES (3-5)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • useAppNavigation (29-29)
admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (2)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (2)
  • useCedarling (28-28)
  • useAppNavigation (29-29)
admin-ui/app/helpers/navigation.ts (1)
  • useAppNavigation (8-21)
admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx (2)
admin-ui/app/helpers/navigation.ts (1)
  • useAppNavigation (8-21)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (1)
  • useAppNavigation (29-29)
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (2)
admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (2)
  • LoggingModuleRootState (10-12)
  • EditLoggingPayload (15-21)
admin-ui/plugins/auth-server/components/Configuration/Defaults/utils.ts (4)
  • LOG_LEVELS (1-1)
  • LOG_LAYOUTS (2-2)
  • getMergedValues (49-54)
  • getChangedFields (56-69)
🔇 Additional comments (9)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (3)

1-1: LGTM! Clean migration to Cedarling resource-scoped authorization.

The refactoring correctly:

  • Derives propertiesResourceId from ADMIN_UI_RESOURCES.AuthenticationServerConfiguration
  • Looks up scopes from CEDAR_RESOURCE_SCOPES
  • Computes canWriteProperties via hasCedarWritePermission
  • Memoizes derived values with appropriate dependencies

This pattern aligns with the broader Cedarling integration across the Admin UI.

Also applies to: 11-14, 25-25, 28-29, 41-50


69-70: LGTM! Batch authorization implemented correctly.

The authorizeHelper call properly checks permissions for propertiesScopes, and the dependency array is accurate.


139-139: LGTM! Navigation and rendering guards updated correctly.

The Back button now navigates to the home dashboard via navigateToHome(), which is appropriate for a configuration page. The rendering guards for GluuCommitFooter and GluuCommitDialog now correctly use canWriteProperties derived from the Cedarling permission check.

Also applies to: 216-223, 227-234

admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (1)

1-21: LGTM! Clean type definitions that support the Redux-based logging flow.

The type definitions are well-structured and the naming (especially LoggingModuleRootState) properly scopes them to the logging feature, avoiding confusion with the global Redux root state. The EditLoggingPayload interface correctly matches the payload structure used in the LoggingPage component.

admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (1)

44-79: LGTM! Cedar permissions and data fetching are properly implemented.

The permission flags are correctly coerced to strict booleans with !!, and the effects are properly split with the data fetch (getLoggingConfig) gated behind the canReadLogging permission. This ensures users without read access won't trigger unnecessary API calls.

admin-ui/app/helpers/navigation.ts (1)

1-21: Centralized navigation helper is correctly implemented.

useAppNavigation cleanly wraps useNavigate, memoizes navigateToHome, and centralizes the /home/dashboard route for reuse across the app.

admin-ui/app/helpers/index.js (1)

1-2: Barrel export for navigation helpers is appropriate.

Re-exporting ./navigation from the helpers index simplifies imports and keeps navigation utilities discoverable alongside other helpers.

admin-ui/app/routes/Apps/Gluu/GluuFormFooter.tsx (1)

7-81: Back button behavior now correctly routes via centralized navigation.

Using useAppNavigation().navigateToHome as the fallback when onBack is absent ensures Gluu form footers consistently go to /home/dashboard instead of relying on history, aligning with the documented requirement for this component. Based on learnings

admin-ui/plugins/auth-server/components/Configuration/ConfigApiConfiguration/ApiConfigForm.tsx (1)

50-55: Guarded authorization effect matches the Cedarling usage pattern.

Wrapping authorizeHelper(configApiScopes) in a length check ensures the helper is only invoked when there are scopes to authorize and aligns this component with the pattern used elsewhere.

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 126cbf9 and c8af8b6.

📒 Files selected for processing (4)
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (5 hunks)
  • admin-ui/plugins/auth-server/components/Configuration/Defaults/utils.ts (2 hunks)
  • admin-ui/plugins/auth-server/redux/features/loggingSlice.js (1 hunks)
  • admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.
📚 Learning: 2025-11-10T14:18:58.310Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:107-109
Timestamp: 2025-11-10T14:18:58.310Z
Learning: In the Cedarling configuration page (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), console.error calls should be kept in catch blocks when there are multiple operations in the try block, as they help print the whole error object with details for debugging unexpected errors.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-07T12:55:26.241Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:93-104
Timestamp: 2025-11-07T12:55:26.241Z
Learning: In the Cedarling configuration feature (admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx), the sync role to scopes mappings operation depends on the `auiPolicyStoreUrl`. The backend fetches content from this URL and syncs roles based on the response. Therefore, the audit log for the sync operation should include the `auiPolicyStoreUrl` in its payload to provide proper audit context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-07T12:17:39.857Z
Learnt from: kdhttps
Repo: GluuFederation/flex PR: 2378
File: admin-ui/plugins/admin/components/Cedarling/CedarlingConfigPage.tsx:43-149
Timestamp: 2025-11-07T12:17:39.857Z
Learning: In the Cedarling configuration UI PR (#2378), the `configApiPolicyStoreUrl` field is intentionally out of scope. It relates to config API configuration and will be covered in a separate PR. The current PR focuses on the Admin UI policy store URL (`auiPolicyStoreUrl`).

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-03T08:47:33.943Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2404
File: admin-ui/app/routes/Apps/Gluu/Gluuformfooter.tsx:70-77
Timestamp: 2025-11-03T08:47:33.943Z
Learning: In the admin-ui forms (Gluuformfooter component), the Back button should always navigate to '/home/dashboard' rather than using history-based navigation (navigate(-1)), as clarified by faisalsiddique4400 in PR #2404.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-05T19:57:35.143Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2415
File: admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx:148-153
Timestamp: 2025-11-05T19:57:35.143Z
Learning: In the SSA Add page (admin-ui/plugins/auth-server/components/Ssa/SsaAddPage.tsx), the Back button should fall back to '/auth-server/config/ssa' when browser history is unavailable, not '/home/dashboard', as this keeps users in the SSA management context.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
📚 Learning: 2025-11-06T08:23:20.948Z
Learnt from: faisalsiddique4400
Repo: GluuFederation/flex PR: 2418
File: admin-ui/plugins/user-management/components/UserForm.tsx:290-297
Timestamp: 2025-11-06T08:23:20.948Z
Learning: In the UserForm component (admin-ui/plugins/user-management/components/UserForm.tsx), the Back button should fall back to '/user/usersmanagement' when browser history is unavailable, not '/home/dashboard', as this keeps users in the user management context. This aligns with the new requirement that users should be redirected to the respective listing screen of the component rather than the dashboard.

Applied to files:

  • admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx
🧬 Code graph analysis (2)
admin-ui/plugins/auth-server/components/Configuration/Defaults/utils.ts (1)
admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (1)
  • ChangedFields (3-5)
admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (2)
admin-ui/plugins/auth-server/redux/features/types/loggingTypes.ts (3)
  • ChangedFields (3-5)
  • LoggingModuleRootState (14-16)
  • EditLoggingPayload (18-24)
admin-ui/plugins/auth-server/components/Configuration/ConfigPage.js (2)
  • useCedarling (28-28)
  • dispatch (35-35)
🔇 Additional comments (3)
admin-ui/plugins/auth-server/redux/features/loggingSlice.js (1)

22-24: Reducer signature change is safe and improves action compatibility

Accepting an _action parameter while keeping the body the same preserves behavior and makes the slice action creator compatible with payload‑carrying calls from sagas/components. Underscoring the unused param keeps lint noise down.

admin-ui/plugins/auth-server/components/Configuration/Defaults/LoggingPage.tsx (2)

45-81: Permission gating and fetch flow look solid

Deriving loggingResourceId from ADMIN_UI_RESOURCES, computing canReadLogging / canWriteLogging as strict booleans, calling authorizeHelper(loggingScopes) once, and only dispatching getLoggingConfig() when canReadLogging is true is a clean pattern. It avoids unnecessary API calls for unauthorized users and keeps the view/commit controls neatly permission‑gated.


97-132: Commit payload assembly is now strongly typed and guarded

Using the localLogging null‑check, getMergedValues + getChangedFields, and a typed EditLoggingPayload for editLoggingConfig removes the brittle casts from earlier iterations and makes the audit payload shape explicit. The pendingValues + commit dialog flow also keeps side effects well‑contained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-admin-ui Component affected by issue or PR kind-feature Issue or PR is a new feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(admin-ui): integrate cedarling on Admin-UI

5 participants