mirror of
https://github.com/coder/coder.git
synced 2026-06-07 15:08:20 +00:00
2a990ce758
Replaces the generic red `ErrorAlert` ("Forbidden.") with a proactive
permission check and friendly info alert when a user lacks the
`agents-access` role.
- Add `createChat` permission check to `permissions.json` using
`owner_id: "me"`
- Handle `"me"` owner substitution in `renderPermissions` (SSR path)
- Pass `canCreateChat` from `useAuthenticated().permissions` into
`AgentCreateForm`
- Show `ChatAccessDeniedAlert` and disable input immediately (no need to
trigger a 403 first)
- Also catch 403 errors as a fallback in case permissions aren't yet
loaded
- Add `ForbiddenNoAgentsRole` Storybook story with `play` assertions
- Add `TestRenderPermissionsResolvesMe` Go test to pin the `"me"`
sentinel substitution
<details><summary>Implementation plan & decision log</summary>
- Uses the existing `permissions.json` + `checkAuthorization` system
rather than a separate API call
- `owner_id: "me"` is resolved to the actor's ID by both the auth-check
API endpoint and the SSR `renderPermissions` function
- Go test uses a real `rbac.StrictCachingAuthorizer` (not a mock) so it
verifies both the sentinel substitution and the RBAC role evaluation
end-to-end
- Alert follows the exact same `Alert` pattern as the 409 usage-limit
block
- Uses `severity="info"` and links to the getting-started docs Step 3
- Textarea is disabled proactively so the user never sees the scary
generic error
</details>
> 🤖 Created by a Coder Agent and will be reviewed by a human.
127 lines
3.1 KiB
JSON
127 lines
3.1 KiB
JSON
{
|
|
"viewAllUsers": {
|
|
"object": { "resource_type": "user" },
|
|
"action": "read"
|
|
},
|
|
"updateUsers": {
|
|
"object": { "resource_type": "user" },
|
|
"action": "update"
|
|
},
|
|
"createUser": {
|
|
"object": { "resource_type": "user" },
|
|
"action": "create"
|
|
},
|
|
"createTemplates": {
|
|
"object": { "resource_type": "template", "any_org": true },
|
|
"action": "create"
|
|
},
|
|
"updateTemplates": {
|
|
"object": { "resource_type": "template" },
|
|
"action": "update"
|
|
},
|
|
"deleteTemplates": {
|
|
"object": { "resource_type": "template" },
|
|
"action": "delete"
|
|
},
|
|
"viewDeploymentConfig": {
|
|
"object": { "resource_type": "deployment_config" },
|
|
"action": "read"
|
|
},
|
|
"editDeploymentConfig": {
|
|
"object": { "resource_type": "deployment_config" },
|
|
"action": "update"
|
|
},
|
|
"viewDeploymentStats": {
|
|
"object": { "resource_type": "deployment_stats" },
|
|
"action": "read"
|
|
},
|
|
"readWorkspaceProxies": {
|
|
"object": { "resource_type": "workspace_proxy" },
|
|
"action": "read"
|
|
},
|
|
"editWorkspaceProxies": {
|
|
"object": { "resource_type": "workspace_proxy" },
|
|
"action": "create"
|
|
},
|
|
"createOrganization": {
|
|
"object": { "resource_type": "organization" },
|
|
"action": "create"
|
|
},
|
|
"viewAnyGroup": {
|
|
"object": { "resource_type": "group" },
|
|
"action": "read"
|
|
},
|
|
"createGroup": {
|
|
"object": { "resource_type": "group" },
|
|
"action": "create"
|
|
},
|
|
"viewAllLicenses": {
|
|
"object": { "resource_type": "license" },
|
|
"action": "read"
|
|
},
|
|
"viewNotificationTemplate": {
|
|
"object": { "resource_type": "notification_template" },
|
|
"action": "read"
|
|
},
|
|
"viewOrganizationIDPSyncSettings": {
|
|
"object": { "resource_type": "idpsync_settings" },
|
|
"action": "read"
|
|
},
|
|
"viewAnyMembers": {
|
|
"object": { "resource_type": "organization_member", "any_org": true },
|
|
"action": "read"
|
|
},
|
|
"editAnyGroups": {
|
|
"object": { "resource_type": "group", "any_org": true },
|
|
"action": "update"
|
|
},
|
|
"assignAnyRoles": {
|
|
"object": { "resource_type": "assign_org_role", "any_org": true },
|
|
"action": "assign"
|
|
},
|
|
"viewAnyIdpSyncSettings": {
|
|
"object": { "resource_type": "idpsync_settings", "any_org": true },
|
|
"action": "read"
|
|
},
|
|
"editAnySettings": {
|
|
"object": { "resource_type": "organization", "any_org": true },
|
|
"action": "update"
|
|
},
|
|
"viewAnyAuditLog": {
|
|
"object": { "resource_type": "audit_log", "any_org": true },
|
|
"action": "read"
|
|
},
|
|
"viewAnyConnectionLog": {
|
|
"object": { "resource_type": "connection_log", "any_org": true },
|
|
"action": "read"
|
|
},
|
|
"viewDebugInfo": {
|
|
"object": { "resource_type": "debug_info" },
|
|
"action": "read"
|
|
},
|
|
"viewAnyAIBridgeInterception": {
|
|
"object": { "resource_type": "aibridge_interception", "any_org": true },
|
|
"action": "read"
|
|
},
|
|
"createOAuth2App": {
|
|
"object": { "resource_type": "oauth2_app" },
|
|
"action": "create"
|
|
},
|
|
"editOAuth2App": {
|
|
"object": { "resource_type": "oauth2_app" },
|
|
"action": "update"
|
|
},
|
|
"deleteOAuth2App": {
|
|
"object": { "resource_type": "oauth2_app" },
|
|
"action": "delete"
|
|
},
|
|
"viewOAuth2AppSecrets": {
|
|
"object": { "resource_type": "oauth2_app_secret" },
|
|
"action": "read"
|
|
},
|
|
"createChat": {
|
|
"object": { "resource_type": "chat", "owner_id": "me" },
|
|
"action": "create"
|
|
}
|
|
}
|