feat(users): allow users to regenerate their own API token#311
feat(users): allow users to regenerate their own API token#311
Conversation
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.
📝 WalkthroughWalkthroughThe pull request introduces stricter authorization and validation for user token regeneration. A new authorization layer ( Changes
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 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_selfAs per coding guidelines,
**/*.py: “Use absolute imports from theopenrag/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
📒 Files selected for processing (4)
extern/indexer-uiopenrag/components/indexer/vectordb/utils.pyopenrag/routers/users.pyopenrag/routers/utils.py
Summary
admin-or-selfcontract onPOST /users/{user_id}/regenerate_token. The endpoint previously had no permission check at all — any valid token could rotate any user's token. Addsrequire_admin_or_selfinopenrag/routers/utils.pyand wires it into the route.AttributeError/500 when the target user does not exist (PartitionFileManager.regenerate_user_tokennow returnsNonefor missing users and the route translates that to a 404).extern/indexer-uisubmodule to pull in the UI branch that surfaces this action as a key-icon button in the NavBar.Companion PR
Test plan
or-…token; the old token stops working.user_id == current user): returns 200 with a new token; old token invalidated."Admin privileges or self-access required".user_id: returns 404.tests/api/users.robot :: Regenerate Tokenstill passes against a running stack.