Skip to content

feat(users): allow users to regenerate their own API token#311

Open
guimard wants to merge 1 commit intomainfrom
feat/regenerate-own-api-token
Open

feat(users): allow users to regenerate their own API token#311
guimard wants to merge 1 commit intomainfrom
feat/regenerate-own-api-token

Conversation

@guimard
Copy link
Copy Markdown
Member

@guimard guimard commented Apr 19, 2026

Summary

  • Enforces the documented admin-or-self contract on POST /users/{user_id}/regenerate_token. The endpoint previously had no permission check at all — any valid token could rotate any user's token. Adds require_admin_or_self in openrag/routers/utils.py and wires it into the route.
  • Returns 404 instead of an AttributeError/500 when the target user does not exist (PartitionFileManager.regenerate_user_token now returns None for missing users and the route translates that to a 404).
  • Bumps the extern/indexer-ui submodule to pull in the UI branch that surfaces this action as a key-icon button in the NavBar.

Companion PR

Test plan

  • As admin, rotate another user's token: returns 200 with a new or-… token; the old token stops working.
  • As a non-admin user, rotate own token (user_id == current user): returns 200 with a new token; old token invalidated.
  • As a non-admin user, attempt to rotate another user's token: returns 403 with "Admin privileges or self-access required".
  • Rotate for a non-existent user_id: returns 404.
  • tests/api/users.robot :: Regenerate Token still passes against a running stack.

The POST /users/{user_id}/regenerate_token endpoint used to be
documented as "admin or self" but had no permission check at all —
any authenticated caller could rotate any other user's token. This
adds a `require_admin_or_self` dependency that enforces the
documented contract: admins may regenerate any user's token; non-admins
may only regenerate their own.

Also:
- Return 404 instead of crashing when the target user does not exist.
- Bump the indexer-ui submodule to pull in the companion UI branch
  that surfaces this action as a button in the NavBar.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 19, 2026

📝 Walkthrough

Walkthrough

The pull request introduces stricter authorization and validation for user token regeneration. A new authorization layer (require_admin_or_self) restricts access to admins or the account owner. The regeneration function now validates user existence and returns None for invalid users, with the endpoint raising a 404 error when regeneration fails.

Changes

Cohort / File(s) Summary
Submodule Update
extern/indexer-ui
Updated indexer-ui submodule to newer commit (92e8875 → 730d478).
Authorization Utilities
openrag/routers/utils.py
Added request_user_id() to extract user ID from request path params and require_admin_or_self() dependency to enforce admin-or-self access control with 403 error on unauthorized access.
Token Regeneration Logic
openrag/components/indexer/vectordb/utils.py
Updated regenerate_user_token() to return dict | None, adding early exit guard when user does not exist.
Endpoint Authorization & Error Handling
openrag/routers/users.py
Updated /users/{user_id}/regenerate_token endpoint to enforce require_admin_or_self authorization and raise 404 when token regeneration returns None.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Endpoint as /regenerate_token Endpoint
    participant AuthDep as require_admin_or_self
    participant ReqDep as request_user_id
    participant CurrentUser as current_user
    participant VectorDB as VectorDB
    participant Response

    Client->>Endpoint: POST /users/{user_id}/regenerate_token
    Endpoint->>AuthDep: Invoke authorization dependency
    AuthDep->>ReqDep: Extract user_id from path
    ReqDep->>Response: Return parsed user_id
    AuthDep->>CurrentUser: Get current user
    CurrentUser->>Response: Return user object
    AuthDep->>AuthDep: Check if admin OR user_id == current_user.id
    alt Authorization Failed
        AuthDep->>Response: Raise HTTPException (403)
    else Authorization Passed
        Endpoint->>VectorDB: regenerate_user_token(user_id)
        VectorDB->>VectorDB: Validate user exists
        alt User Not Found
            VectorDB->>Response: Return None
            Endpoint->>Response: Raise HTTPException (404)
        else User Found
            VectorDB->>Response: Return token dict
            Endpoint->>Client: Return token payload (200)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A token reborn with guards so tight,
Where admins and their own can set things right,
No spurious souls may pass through,
Four-oh-four when users are untrue,
Authorization hops—security in flight! 🔐

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(users): allow users to regenerate their own API token' accurately captures the main objective of the pull request, which is to enable users to regenerate their own API tokens while enforcing admin-or-self authorization.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/regenerate-own-api-token

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.

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
openrag/routers/users.py (1)

7-7: Use an absolute project import here.

This changed import still uses a relative package import while the rest of the file imports from the project root.

♻️ Proposed import update
-from .utils import DEFAULT_FILE_QUOTA, current_user, require_admin, require_admin_or_self
+from routers.utils import DEFAULT_FILE_QUOTA, current_user, require_admin, require_admin_or_self

As per coding guidelines, **/*.py: “Use absolute imports from the openrag/ directory rather than relative imports across packages”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openrag/routers/users.py` at line 7, The import in users.py uses a relative
import ("from .utils import DEFAULT_FILE_QUOTA, current_user, require_admin,
require_admin_or_self"); change it to an absolute project import (e.g., "from
openrag.utils import DEFAULT_FILE_QUOTA, current_user, require_admin,
require_admin_or_self") so it matches the repository's coding guideline and
other imports; update the import statement referencing DEFAULT_FILE_QUOTA,
current_user, require_admin, and require_admin_or_self accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@openrag/routers/users.py`:
- Line 7: The import in users.py uses a relative import ("from .utils import
DEFAULT_FILE_QUOTA, current_user, require_admin, require_admin_or_self"); change
it to an absolute project import (e.g., "from openrag.utils import
DEFAULT_FILE_QUOTA, current_user, require_admin, require_admin_or_self") so it
matches the repository's coding guideline and other imports; update the import
statement referencing DEFAULT_FILE_QUOTA, current_user, require_admin, and
require_admin_or_self accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bc5b1ed9-cde3-4ed0-aea3-5d2dc363b00f

📥 Commits

Reviewing files that changed from the base of the PR and between a91ad6d and 59b4b30.

📒 Files selected for processing (4)
  • extern/indexer-ui
  • openrag/components/indexer/vectordb/utils.py
  • openrag/routers/users.py
  • openrag/routers/utils.py

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.

1 participant