Skip to content

Conversation

@GavinHemsada
Copy link

@GavinHemsada GavinHemsada commented Oct 31, 2025

Summary by CodeRabbit

  • Bug Fixes
    • Streamlined access-control checks for creating and publishing APIs for more consistent permission decisions.
    • Added early denials for missing or read-only users to prevent unintended access.
    • Tightened scope-based requirements for publish/edit actions so appropriate scopes are enforced.
    • Updated inline documentation describing the updated access-check behavior and return conditions.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@tharikaGitHub
Copy link
Member

Hi @GavinHemsada,

I tried this fix locally. Noticed the following.

When we log in as the admin or a privileged user than a read only user, I get the following screen when clicking on the scope tile. Shall we check the behaviour in other places too and fix it?

Screenshot 2025-10-31 at 19 13 24

Accessing

Screenshot 2025-10-31 at 19 14 17

@GavinHemsada
Copy link
Author

Hi @tharikaGitHub, i create new readonly user using https://localhost:9443/carbon and then try to create a REST(https://localhost:9443/publisher/apis/create/rest). It looks like this image below (I used the default one; I did undo all changes). issue: "Some paths, such as {basePath}/publisher/apis/create/rest, are still accessible to read-only users, even though create/edit operations are not allowed for the user."
Screenshot 2025-11-01 221525
Screenshot 2025-11-01 221747

@tharikaGitHub
Copy link
Member

Hi @tharikaGitHub, i create new readonly user using https://localhost:9443/carbon and then try to create a REST(https://localhost:9443/publisher/apis/create/rest). It looks like this image below (I used the default one; I did undo all changes). issue: "Some paths, such as {basePath}/publisher/apis/create/rest, are still accessible to read-only users, even though create/edit operations are not allowed for the user."

Hi @GavinHemsada,

Yes that is the current behaviour. With your fix the readonly user will not be able to access this page. So that will not be an issue.

@GavinHemsada
Copy link
Author

Hi @tharikaGitHub, I only made AuthManager changes.

} else {
return true;
}
return !user.scopes.includes('apim:api_publish');
Copy link
Member

Choose a reason for hiding this comment

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

@GavinHemsada the user object here return !user.scopes.includes('apim:api_publish'); does not seem to have been initialised.

@coderabbitai
Copy link

coderabbitai bot commented Nov 4, 2025

Walkthrough

Added an early denial in AuthManager.isRestricted that returns restricted when a retrieved user is read-only; documentation for isRestricted was expanded to describe parameters and return value. No signature changes.

Changes

Cohort / File(s) Summary
AuthManager — early read-only denial & docs
portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js
Added a pre-check in isRestricted to immediately return restricted when a user exists and isReadOnlyUser() is true; expanded function documentation to reflect the new early-deny behavior. No public API/signature changes.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as UI/Controller
  participant AuthMgr as AuthManager.isRestricted
  participant UserSvc as User Token/Scopes

  Caller->>AuthMgr: isRestricted(scopesAllowedToEdit, api)
  AuthMgr->>UserSvc: retrieve current user & check isReadOnlyUser()
  alt user exists AND isReadOnlyUser
    AuthMgr-->>Caller: deny (restricted)    %% early deny added
  else
    AuthMgr->>AuthMgr: continue existing scope/lifecycle checks
    AuthMgr-->>Caller: allow/deny (existing logic)
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Focus areas:
    • Confirm early-return condition uses the correct user existence and isReadOnlyUser() check.
    • Ensure documentation updates accurately describe behavior and return values.

Poem

🐇 I paused at a gate where the read-only stay,

I nudged the rules so they step another way.
A tiny early hop, neat and spry,
Now checks skip on by beneath my sky. 🥕

Pre-merge checks and finishing touches

✅ 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 'fix-publisher routes are not blocked for read only user' directly describes the main change: enhancing AuthManager to block publisher routes for read-only users by adding an early denial check in the isRestricted function.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8b51d9 and 62d9caf.

📒 Files selected for processing (1)
  • portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js

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.

@GavinHemsada
Copy link
Author

Hi @tharikaGitHub I fixed it.

Copy link

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9aed01 and 68b6de6.

📒 Files selected for processing (1)
  • portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js (1 hunks)

Comment on lines 235 to 238
if (Object.keys(api).length === 0 && api.constructor === Object) {
// Only allow users with create permission on create pages
return !user.scopes.includes('apim:api_create');
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Guard against api being null before calling Object.keys.

Several callers pass null while the API payload is still loading (e.g., initial React renders). With the new logic, Object.keys(api) will throw TypeError: Cannot convert undefined or null to object, breaking those routes before the user even hits the create-page path. Please short-circuit when api is falsy before touching Object.keys.

Apply this diff to avoid the crash:

-        if (Object.keys(api).length === 0 && api.constructor === Object) {
-            // Only allow users with create permission on create pages
-            return !user.scopes.includes('apim:api_create');
-        }
+        if (
+            !api
+            || (api.constructor === Object && Object.keys(api).length === 0)
+        ) {
+            // Only allow users with create permission on create pages
+            return !user.scopes.includes('apim:api_create');
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (Object.keys(api).length === 0 && api.constructor === Object) {
// Only allow users with create permission on create pages
return !user.scopes.includes('apim:api_create');
}
if (
!api
|| (api.constructor === Object && Object.keys(api).length === 0)
) {
// Only allow users with create permission on create pages
return !user.scopes.includes('apim:api_create');
}
🤖 Prompt for AI Agents
In portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js around
lines 235 to 238, guard against api being null/undefined before calling
Object.keys by short-circuiting when api is falsy; change the condition to first
check if (!api) return <appropriate value> or combine as if (!api ||
(Object.keys(api).length === 0 && api.constructor === Object)) { ... } so you
never call Object.keys on null/undefined and preserve the existing behavior of
only allowing users with 'apim:api_create' on create pages.

@tharikaGitHub
Copy link
Member

Hi @tharikaGitHub I fixed it.

Hi @GavinHemsada, thank you for addressing the previous comment. I reviewed the latest changes.

Seems with this change, publishers are unable to delete API Products created by them. Shall we check and fix it? Shall we also guard against the user object being null?

@GavinHemsada
Copy link
Author

Hi @tharikaGitHub, I fixed it.

@GavinHemsada
Copy link
Author

Hi @tharikaGitHub, I've done it.

Copy link

@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: 0

♻️ Duplicate comments (1)
portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js (1)

237-240: Guard against api being null or undefined before calling Object.keys.

This critical issue was flagged in previous reviews and remains unresolved. When api is explicitly passed as null (e.g., during initial React renders before the API payload loads), Object.keys(api) throws TypeError: Cannot convert undefined or null to object, breaking routes before they can render.

Apply this diff to guard against null/undefined:

-        if (Object.keys(api).length === 0 && api.constructor === Object) {
+        if (
+            !api
+            || (api.constructor === Object && Object.keys(api).length === 0)
+        ) {
             // Only allow users with create permission on create pages
             return !user.scopes.includes('apim:api_create');
         }

This ensures the null/undefined check happens before Object.keys is called, preventing runtime errors while preserving the existing create-page behavior.

🧹 Nitpick comments (1)
portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js (1)

242-245: Add a null guard for api.lifeCycleStatus access.

While accessing api.lifeCycleStatus on a null object won't throw an error (it evaluates to undefined and the condition becomes false), relying on this behavior is fragile. Once lines 237–240 are fixed to properly handle null api, consider adding an explicit null check here as well for clarity and defensive coding.

Apply this diff for defensive null checking:

+        // Guard against null api
+        if (!api) {
+            return true;
+        }
+
         // Allow creator access based on lifecycle status
         if (api.lifeCycleStatus === 'CREATED' || api.lifeCycleStatus === 'PROTOTYPED') {
             return false;
         }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a5c6647 and c8b51d9.

📒 Files selected for processing (1)
  • portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js (4)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/NewOverview/CustomizedStepper.jsx (1)
  • api (153-153)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/TryOut/TryOutConsole.jsx (1)
  • api (147-147)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Listing/components/ImageGenerator/APICards/APIThumbPlain.jsx (1)
  • api (164-166)
portals/publisher/src/main/webapp/source/src/app/components/Apis/Details/components/leftMenu/DevelopSectionMenu.jsx (1)
  • user (122-122)
🔇 Additional comments (3)
portals/publisher/src/main/webapp/source/src/app/data/AuthManager.js (3)

211-216: LGTM! Addresses the PR objective.

The early check for missing or read-only users directly addresses the reported issue where read-only users could access publisher routes. This prevents downstream access checks from running for unauthorized users.


218-220: Verify that bypassing scopesAllowedToEdit for API PRODUCT is intentional.

For apiType === 'APIPRODUCT', the function returns early based solely on the apim:api_publish scope, ignoring the scopesAllowedToEdit parameter entirely. While the comment suggests this is intended behavior, please confirm this design choice is correct—particularly if callers expect scopesAllowedToEdit to be honored for API PRODUCTs as well.


221-226: LGTM! Clean scope validation.

The logic correctly restricts access when the user lacks any of the required scopes from scopesAllowedToEdit, preventing unauthorized users from proceeding further in the access-control chain.

@tharikaGitHub
Copy link
Member

Hi @GavinHemsada

There is a UI build failure, in particular, publisher/019-read-only-user/00-verify-that-read-only-user-cannot-create-update-api.spec.js test case which is relevant to your fix. Shall we check and fix it? You can follow the steps in the readme of this repository to run this test locally and determine the issue.

Thanks,
Tharika.

@sonarqubecloud
Copy link

@GavinHemsada
Copy link
Author

@tharikaGitHub Hi, now the code is working without failing the test cases.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants