-
Notifications
You must be signed in to change notification settings - Fork 10
fix: enhance user context validation in auth module and add integrati… #1726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…on tests for AuthZGuard - Improved error handling in the auth module to ensure user context is present and valid. - Added checks for user roles and identifiers, throwing appropriate exceptions for missing or invalid data. - Introduced a new integration test suite for AuthZGuard, validating role-based access control for various actions in the application. - Tests cover scenarios for viewer and admin roles, ensuring correct permissions are enforced.
|
Caution Review failedThe pull request is closed. WalkthroughDelegates subject extraction in the auth module to a new utility Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant GQL as GraphQL Resolver
participant Guard as AuthZGuard
participant Ctx as ExecutionContext
participant Resolver as resolveSubjectFromUser
participant Enforcer as Casbin Enforcer
Client->>GQL: call resolver/mutation
GQL->>Guard: canActivate(Ctx)
Guard->>Ctx: get request.user
Guard->>Resolver: resolveSubjectFromUser(request.user)
alt resolution fails
Resolver-->>Guard: throws UnauthorizedException
Guard-->>GQL: deny (401/Forbidden)
GQL-->>Client: error
else resolution succeeds
Resolver-->>Guard: subject
Guard->>Enforcer: enforce(subject, action, resource)
alt allowed
Enforcer-->>Guard: true
Guard-->>GQL: allow
GQL-->>Client: success
else denied
Enforcer-->>Guard: false
Guard-->>GQL: deny (Forbidden)
GQL-->>Client: error
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
Comment |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1726 +/- ##
==========================================
+ Coverage 53.29% 53.34% +0.05%
==========================================
Files 859 860 +1
Lines 48247 48271 +24
Branches 4912 4926 +14
==========================================
+ Hits 25715 25752 +37
+ Misses 22463 22450 -13
Partials 69 69 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this 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
🧹 Nitpick comments (4)
api/src/unraid-api/auth/auth.module.ts (1)
40-40: Hoist Logger and log stack traces properly.Avoid per-call Logger creation and pass stack/trace to Logger.error for clarity.
Apply this diff to reuse a shared logger and improve error logging:
- const logger = new Logger('AuthZModule'); + const logger = AUTHZ_LOGGER; @@ - } catch (error) { - logger.error('Failed to extract user context', error); + } catch (error) { + logger.error( + 'Failed to extract user context', + error instanceof Error ? error.stack : String(error) + ); throw new UnauthorizedException('Failed to authenticate user'); }Add this at module scope (top of file) to define the shared logger:
const AUTHZ_LOGGER = new Logger('AuthModule');Also applies to: 66-69
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.ts (3)
19-20: Use unknown[] instead of any[].Tighten the handler signature to avoid any.
As per coding guidelines
-type Handler = (...args: any[]) => unknown; +type Handler = (...args: unknown[]) => unknown;
69-79: Mirror module’s user presence check and safer subject fallback in tests.Keep test mapper aligned with production to catch mismatches early.
Apply this diff:
- userFromContext: (ctx: ExecutionContext) => { - const request = getRequest(ctx) as TestRequest | undefined; - const user: TestUser = request?.user ?? {}; - const roles = user.roles ?? []; - - if (!Array.isArray(roles)) { - throw new UnauthorizedException('User roles must be an array'); - } - - return typeof user.id === 'string' && user.id.length > 0 ? user.id : roles.join(','); - }, + userFromContext: (ctx: ExecutionContext) => { + const request = getRequest(ctx) as TestRequest | undefined; + const user = request?.user; + if (!user) { + throw new UnauthorizedException('Request user context missing'); + } + const roles = user.roles ?? []; + if (!Array.isArray(roles)) { + throw new UnauthorizedException('User roles must be an array'); + } + const userId = typeof user.id === 'string' ? user.id.trim() : ''; + const subject = userId || (roles.length === 1 ? String(roles[0]) : ''); + if (!subject) { + throw new UnauthorizedException('User identifier (id) or single role is required'); + } + return subject; + },
54-81: Add negative-path tests for missing user/invalid roles.Strengthens guarantees around Unauthorized flows and aligns with test guidelines.
As per coding guidelines
it('rejects when user context is missing', async () => { // Create a context with no user const context = (() => { const graphqlContextHost = new ExecutionContextHost( [undefined, undefined, { req: {} as TestRequest }, undefined], DockerResolver, DockerResolver.prototype.containers ); graphqlContextHost.setType('graphql'); return graphqlContextHost as unknown as ExecutionContext; })(); await expect(guard.canActivate(context)).rejects.toThrow(); }); it('rejects when roles is not an array', async () => { // roles: as any to simulate a malformed token/user object const badRoles = null as unknown as Role[]; const context = createExecutionContext( DockerResolver.prototype.containers, DockerResolver, badRoles, 'api-key-viewer' ); await expect(guard.canActivate(context)).rejects.toThrow(); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
api/src/unraid-api/auth/auth.module.ts(1 hunks)api/src/unraid-api/auth/casbin/authz.guard.integration.spec.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
api/src/unraid-api/**
📄 CodeRabbit inference engine (.cursor/rules/api-rules.mdc)
Prefer adding new files to the Nest repo at api/src/unraid-api/ instead of legacy code
Files:
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.tsapi/src/unraid-api/auth/auth.module.ts
api/**/*.{test,spec}.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/api-rules.mdc)
api/**/*.{test,spec}.{js,jsx,ts,tsx}: Use Vitest for tests in the api; do not use Jest
Prefer not to mock simple dependencies in tests
For error testing, use.rejects.toThrow()without arguments; avoid asserting exact error messages unless the message format is the subject under test
Files:
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use TypeScript import specifiers with .js extensions for ESM compatibility
Never use the any type; prefer precise typing
Avoid type casting; model proper types from the start
Files:
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.tsapi/src/unraid-api/auth/auth.module.ts
api/**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
api/**/*.{test,spec}.{ts,tsx}: API test suite is Vitest; do not use Jest
Prefer not to mock simple dependencies in API tests
Files:
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.ts
{api,web}/**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
{api,web}/**/*.{test,spec}.{ts,tsx}: For error tests, use .rejects.toThrow() without arguments; avoid asserting exact error messages unless that format is the subject
Focus tests on behavior, not implementation details
Avoid brittle tests tied to exact error or log wording
Use mocks as nouns, not verbs
Always await async operations before making assertions
Place all mock declarations at the top level; use factory functions for module mocks; clear mocks between tests
Files:
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.ts
api/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
cache-manager v7 TTL values must be in milliseconds (e.g., 600000 for 10 minutes)
Files:
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.tsapi/src/unraid-api/auth/auth.module.ts
🧬 Code graph analysis (1)
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.ts (2)
api/src/unraid-api/auth/casbin/model.ts (1)
CASBIN_MODEL(1-18)api/src/unraid-api/auth/casbin/policy.ts (1)
BASE_POLICY(9-26)
🔇 Additional comments (4)
api/src/unraid-api/auth/auth.module.ts (1)
46-49: Good: strict user/roles validation before subject derivation.The explicit user presence check and enforcing roles to be an array harden the context extraction path.
Also applies to: 52-55
api/src/unraid-api/auth/casbin/authz.guard.integration.spec.ts (3)
65-79: Verify AuthZGuard constructor signature against nest-authz 2.17.0.Direct instantiation with (reflector, enforcer, options) may vary by version; ensure it compiles and behaves as expected.
Run the test suite locally/CI and confirm the guard is constructed successfully with these params.
82-124: LGTM: clear, behavior-focused authorization checks for viewer/admin.The scenarios align with policy/grouping and assert on canActivate without brittle message coupling.
126-137: LGTM: custom subject policy path is exercised.Good coverage for direct p.sub subject permissions independent of role grouping.
…xtraction - Introduced a new utility function, `resolveSubjectFromUser`, to streamline user context extraction in the auth module. - Replaced direct user role and ID checks with the new utility for improved readability and maintainability. - Added unit tests for `resolveSubjectFromUser` to ensure robust validation of user roles and identifiers. - Updated integration tests for AuthZGuard to utilize the new utility, enhancing error handling and user context validation.
|
This plugin has been deployed to Cloudflare R2 and is available for testing. |
🤖 I have created a release *beep* *boop* --- ## [4.25.0](v4.24.1...v4.25.0) (2025-09-26) ### Features * add Tailwind scoping plugin and integrate into Vite config ([#1722](#1722)) ([b7afaf4](b7afaf4)) * notification filter controls pill buttons ([#1718](#1718)) ([661865f](661865f)) ### Bug Fixes * enable auth guard for nested fields - thanks [@ingel81](https://github.com/ingel81) ([7bdeca8](7bdeca8)) * enhance user context validation in auth module ([#1726](#1726)) ([cd5eff1](cd5eff1)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…on tests for AuthZGuard
Summary by CodeRabbit
New Features
Bug Fixes
Tests