core: group api#1168
Conversation
WalkthroughThis PR refactors group querying by moving filtering logic from API handlers into dedicated model layer helpers. The UserModel gains two methods: listGroup is extended with optional name-based filtering, and a new searchGroups method performs case-insensitive regex matching. The DomainApi.groups endpoint now conditionally delegates to these helpers based on query parameters (names, search, or all groups), and DomainApi.userGroups is updated with explicit schema definitions and uses the enhanced listGroup method. Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
packages/hydrooj/src/handler/domain.tsESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox. packages/hydrooj/src/model/user.tsESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox. 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.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/hydrooj/src/handler/domain.ts`:
- Around line 447-455: The permission checks currently use ctx.user but the
resource being queried is args.domainId; update the code so authorization is
performed against the target domain's context before returning groups: obtain
the domain-specific user/authorization context for args.domainId (e.g., call a
helper like ctx.forDomain(args.domainId) / ctx.getDomainUser(args.domainId) or
use an existing domain authorization method), then call hasPerm/hasPriv on that
domain-scoped user instead of ctx.user, and only after that call user.listGroup,
user.searchGroups or user.listGroup with args.domainId; apply the same change to
the other similar block that calls user.listGroup/user.searchGroups to ensure
checks use the target domain context.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f4e0a869-3bfa-4dea-be58-969853e8808d
📒 Files selected for processing (2)
packages/hydrooj/src/handler/domain.tspackages/hydrooj/src/model/user.ts
| if (!ctx.user.hasPerm(PERM.PERM_VIEW) && !ctx.user.hasPriv(PRIV.PRIV_VIEW_ALL_DOMAIN)) throw new PermissionError(PERM.PERM_VIEW); | ||
| const groups = await user.listGroup(args.domainId); | ||
| if (args.names?.length) { | ||
| return groups.filter((g) => args.names.includes(g.name)); | ||
| return user.listGroup(args.domainId, undefined, args.names); | ||
| } | ||
| if (args.search) { | ||
| const searchLower = args.search.toLowerCase(); | ||
| return groups.filter((g) => g.name.toLowerCase().includes(searchLower)); | ||
| return user.searchGroups(args.domainId, args.search, args.limit ?? 10); | ||
| } | ||
| return groups; | ||
| return user.listGroup(args.domainId); | ||
| }, |
There was a problem hiding this comment.
Authorize using the target domain context before returning groups.
Line 447 and Line 463 validate permissions on ctx.user, but the queried resource is args.domainId. This can expose another domain’s groups/user-groups when a caller passes a different domainId.
🔒 Suggested fix
async (ctx, args) => {
- if (!ctx.user.hasPerm(PERM.PERM_VIEW) && !ctx.user.hasPriv(PRIV.PRIV_VIEW_ALL_DOMAIN)) throw new PermissionError(PERM.PERM_VIEW);
+ const targetUser = await user.getById(args.domainId, ctx.user._id);
+ if (!targetUser || (!targetUser.hasPerm(PERM.PERM_VIEW) && !targetUser.hasPriv(PRIV.PRIV_VIEW_ALL_DOMAIN))) {
+ throw new PermissionError(PERM.PERM_VIEW);
+ }
if (args.names?.length) {
return user.listGroup(args.domainId, undefined, args.names);
}
@@
async (ctx, args) => {
- if (!ctx.user.hasPerm(PERM.PERM_VIEW) && !ctx.user.hasPriv(PRIV.PRIV_VIEW_ALL_DOMAIN)) throw new PermissionError(PERM.PERM_VIEW);
+ const targetUser = await user.getById(args.domainId, ctx.user._id);
+ if (!targetUser || (!targetUser.hasPerm(PERM.PERM_VIEW) && !targetUser.hasPriv(PRIV.PRIV_VIEW_ALL_DOMAIN))) {
+ throw new PermissionError(PERM.PERM_VIEW);
+ }
return user.listGroup(args.domainId, args.uid);
},Also applies to: 463-465
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/hydrooj/src/handler/domain.ts` around lines 447 - 455, The
permission checks currently use ctx.user but the resource being queried is
args.domainId; update the code so authorization is performed against the target
domain's context before returning groups: obtain the domain-specific
user/authorization context for args.domainId (e.g., call a helper like
ctx.forDomain(args.domainId) / ctx.getDomainUser(args.domainId) or use an
existing domain authorization method), then call hasPerm/hasPriv on that
domain-scoped user instead of ctx.user, and only after that call user.listGroup,
user.searchGroups or user.listGroup with args.domainId; apply the same change to
the other similar block that calls user.listGroup/user.searchGroups to ensure
checks use the target domain context.
Summary by CodeRabbit
New Features
Improvements