mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 11:13:43 +08:00
Closes the authorization asymmetry between list endpoints (which filter by workspaceId) and direct-access endpoints (which did not): a logged-in user could reach another workspace's system / IM / webchat-owned conversation by id and run any of messages / delete / rename / pin / setModel / clear / chat-files download on it. Per the maintainer's guidance on issue #344, workspaces are now treated as untrusted isolation boundaries — the fix is the cross-cutting hardening, kept out of feature work. Behavior change (only for shared, non-direct convs): - requester is a global admin (user.role=admin) → pass - requester is a member of the conversation's workspace → pass - otherwise → deny Preserved to avoid regressions: - direct owner (username == conv.username) → pass without lookup - convs without workspace_id (legacy rows) → legacy system-owner check - anonymous user (authService returns null, e.g. permitAll reconnect) → legacy system-owner check Callers in ConversationController / ChatController / SubagentController / GoalController / ApprovalController (18 sites) are unchanged — the signature stays isConversationOwner(conversationId, username). The workspace membership check is done via WorkspaceService.hasPermissionCached (Caffeine-backed, same cache the WorkspaceAccessInterceptor uses) and ignores the X-Workspace-Id header, which is client-controlled. Tests: 11 cases in ConversationServiceOwnershipWorkspaceTest covering each branch of the new logic. No caller-side test changes — the 66 caller tests (ConversationService*Test, ChatController*Test, SubagentController*Test, GoalController*Test, ApprovalController*Test) still pass. |
||
|---|---|---|
| .. | ||
| java/vip/mate | ||
| resources | ||