feat: generate RBAC scope name constants (#19896)

# Generate RBAC scope name constants

This PR adds a new generated file `coderd/rbac/scopes_constants_gen.go` that contains typed constants for all RBAC scope names in the format `Scope<Resource><Action>`. For example, `ScopeWorkspaceRead` for the scope "workspace:read".

These constants make it easier to reference specific scopes in code without using string literals, improving type safety and making refactoring easier.

The PR:
- Adds a new template file `scripts/typegen/scopenames.gotmpl`
- Updates the typegen script to support generating scope name constants
- Updates the Makefile to include the new generated file in build targets
This commit is contained in:
Thomas Kosiewski
2025-09-24 18:40:36 +02:00
committed by GitHub
parent 5ff503b8fc
commit adb7521066
5 changed files with 545 additions and 0 deletions
+11
View File
@@ -646,6 +646,7 @@ GEN_FILES := \
$(SITE_GEN_FILES) \
coderd/rbac/object_gen.go \
codersdk/rbacresources_gen.go \
coderd/rbac/scopes_constants_gen.go \
docs/admin/integrations/prometheus.md \
docs/reference/cli/index.md \
docs/admin/security/audit-logs.md \
@@ -695,6 +696,7 @@ gen/mark-fresh:
site/src/api/typesGenerated.ts \
coderd/rbac/object_gen.go \
codersdk/rbacresources_gen.go \
coderd/rbac/scopes_constants_gen.go \
site/src/api/rbacresourcesGenerated.ts \
site/src/api/countriesGenerated.ts \
docs/admin/integrations/prometheus.md \
@@ -842,6 +844,15 @@ coderd/rbac/object_gen.go: scripts/typegen/rbacobject.gotmpl scripts/typegen/mai
rmdir -v "$$tempdir"
touch "$@"
coderd/rbac/scopes_constants_gen.go: scripts/typegen/scopenames.gotmpl scripts/typegen/main.go coderd/rbac/policy/policy.go
# Generate typed low-level ScopeName constants from RBACPermissions
# Write to a temp file first to avoid truncating the package during build
# since the generator imports the rbac package.
tempfile=$(shell mktemp /tmp/scopes_constants_gen.XXXXXX)
go run ./scripts/typegen/main.go rbac scopenames > "$$tempfile"
mv -v "$$tempfile" coderd/rbac/scopes_constants_gen.go
touch "$@"
codersdk/rbacresources_gen.go: scripts/typegen/codersdk.gotmpl scripts/typegen/main.go coderd/rbac/object.go coderd/rbac/policy/policy.go
# Do no overwrite codersdk/rbacresources_gen.go directly, as it would make the file empty, breaking
# the `codersdk` package and any parallel build targets.
+13
View File
@@ -2,6 +2,7 @@ package rbac
import (
"fmt"
"slices"
"strings"
"github.com/google/uuid"
@@ -107,6 +108,18 @@ var builtinScopes = map[ScopeName]Scope{
},
}
// BuiltinScopeNames returns the list of built-in high-level scope names
// defined in this package (e.g., "all", "application_connect"). The result
// is sorted for deterministic ordering in code generation and tests.
func BuiltinScopeNames() []ScopeName {
names := make([]ScopeName, 0, len(builtinScopes))
for name := range builtinScopes {
names = append(names, name)
}
slices.Sort(names)
return names
}
type ExpandableScope interface {
Expand() (Scope, error)
// Name is for logging and tracing purposes, we want to know the human
+448
View File
@@ -0,0 +1,448 @@
// Code generated by: go run ./scripts/typegen rbac scopenames; DO NOT EDIT.
package rbac
// ScopeName constants generated from policy.RBACPermissions.
// These represent low-level "<resource>:<action>" scope names.
// Built-in non-low-level scopes like "all" and "application_connect" remain
// declared in code, not here, to avoid duplication.
const (
ScopeAibridgeInterceptionCreate ScopeName = "aibridge_interception:create"
ScopeAibridgeInterceptionRead ScopeName = "aibridge_interception:read"
ScopeAibridgeInterceptionUpdate ScopeName = "aibridge_interception:update"
ScopeApiKeyCreate ScopeName = "api_key:create"
ScopeApiKeyDelete ScopeName = "api_key:delete"
ScopeApiKeyRead ScopeName = "api_key:read"
ScopeApiKeyUpdate ScopeName = "api_key:update"
ScopeAssignOrgRoleAssign ScopeName = "assign_org_role:assign"
ScopeAssignOrgRoleCreate ScopeName = "assign_org_role:create"
ScopeAssignOrgRoleDelete ScopeName = "assign_org_role:delete"
ScopeAssignOrgRoleRead ScopeName = "assign_org_role:read"
ScopeAssignOrgRoleUnassign ScopeName = "assign_org_role:unassign"
ScopeAssignOrgRoleUpdate ScopeName = "assign_org_role:update"
ScopeAssignRoleAssign ScopeName = "assign_role:assign"
ScopeAssignRoleRead ScopeName = "assign_role:read"
ScopeAssignRoleUnassign ScopeName = "assign_role:unassign"
ScopeAuditLogCreate ScopeName = "audit_log:create"
ScopeAuditLogRead ScopeName = "audit_log:read"
ScopeConnectionLogRead ScopeName = "connection_log:read"
ScopeConnectionLogUpdate ScopeName = "connection_log:update"
ScopeCryptoKeyCreate ScopeName = "crypto_key:create"
ScopeCryptoKeyDelete ScopeName = "crypto_key:delete"
ScopeCryptoKeyRead ScopeName = "crypto_key:read"
ScopeCryptoKeyUpdate ScopeName = "crypto_key:update"
ScopeDebugInfoRead ScopeName = "debug_info:read"
ScopeDeploymentConfigRead ScopeName = "deployment_config:read"
ScopeDeploymentConfigUpdate ScopeName = "deployment_config:update"
ScopeDeploymentStatsRead ScopeName = "deployment_stats:read"
ScopeFileCreate ScopeName = "file:create"
ScopeFileRead ScopeName = "file:read"
ScopeGroupCreate ScopeName = "group:create"
ScopeGroupDelete ScopeName = "group:delete"
ScopeGroupRead ScopeName = "group:read"
ScopeGroupUpdate ScopeName = "group:update"
ScopeGroupMemberRead ScopeName = "group_member:read"
ScopeIdpsyncSettingsRead ScopeName = "idpsync_settings:read"
ScopeIdpsyncSettingsUpdate ScopeName = "idpsync_settings:update"
ScopeInboxNotificationCreate ScopeName = "inbox_notification:create"
ScopeInboxNotificationRead ScopeName = "inbox_notification:read"
ScopeInboxNotificationUpdate ScopeName = "inbox_notification:update"
ScopeLicenseCreate ScopeName = "license:create"
ScopeLicenseDelete ScopeName = "license:delete"
ScopeLicenseRead ScopeName = "license:read"
ScopeNotificationMessageCreate ScopeName = "notification_message:create"
ScopeNotificationMessageDelete ScopeName = "notification_message:delete"
ScopeNotificationMessageRead ScopeName = "notification_message:read"
ScopeNotificationMessageUpdate ScopeName = "notification_message:update"
ScopeNotificationPreferenceRead ScopeName = "notification_preference:read"
ScopeNotificationPreferenceUpdate ScopeName = "notification_preference:update"
ScopeNotificationTemplateRead ScopeName = "notification_template:read"
ScopeNotificationTemplateUpdate ScopeName = "notification_template:update"
ScopeOauth2AppCreate ScopeName = "oauth2_app:create"
ScopeOauth2AppDelete ScopeName = "oauth2_app:delete"
ScopeOauth2AppRead ScopeName = "oauth2_app:read"
ScopeOauth2AppUpdate ScopeName = "oauth2_app:update"
ScopeOauth2AppCodeTokenCreate ScopeName = "oauth2_app_code_token:create"
ScopeOauth2AppCodeTokenDelete ScopeName = "oauth2_app_code_token:delete"
ScopeOauth2AppCodeTokenRead ScopeName = "oauth2_app_code_token:read"
ScopeOauth2AppSecretCreate ScopeName = "oauth2_app_secret:create"
ScopeOauth2AppSecretDelete ScopeName = "oauth2_app_secret:delete"
ScopeOauth2AppSecretRead ScopeName = "oauth2_app_secret:read"
ScopeOauth2AppSecretUpdate ScopeName = "oauth2_app_secret:update"
ScopeOrganizationCreate ScopeName = "organization:create"
ScopeOrganizationDelete ScopeName = "organization:delete"
ScopeOrganizationRead ScopeName = "organization:read"
ScopeOrganizationUpdate ScopeName = "organization:update"
ScopeOrganizationMemberCreate ScopeName = "organization_member:create"
ScopeOrganizationMemberDelete ScopeName = "organization_member:delete"
ScopeOrganizationMemberRead ScopeName = "organization_member:read"
ScopeOrganizationMemberUpdate ScopeName = "organization_member:update"
ScopePrebuiltWorkspaceDelete ScopeName = "prebuilt_workspace:delete"
ScopePrebuiltWorkspaceUpdate ScopeName = "prebuilt_workspace:update"
ScopeProvisionerDaemonCreate ScopeName = "provisioner_daemon:create"
ScopeProvisionerDaemonDelete ScopeName = "provisioner_daemon:delete"
ScopeProvisionerDaemonRead ScopeName = "provisioner_daemon:read"
ScopeProvisionerDaemonUpdate ScopeName = "provisioner_daemon:update"
ScopeProvisionerJobsCreate ScopeName = "provisioner_jobs:create"
ScopeProvisionerJobsRead ScopeName = "provisioner_jobs:read"
ScopeProvisionerJobsUpdate ScopeName = "provisioner_jobs:update"
ScopeReplicasRead ScopeName = "replicas:read"
ScopeSystemCreate ScopeName = "system:create"
ScopeSystemDelete ScopeName = "system:delete"
ScopeSystemRead ScopeName = "system:read"
ScopeSystemUpdate ScopeName = "system:update"
ScopeTailnetCoordinatorCreate ScopeName = "tailnet_coordinator:create"
ScopeTailnetCoordinatorDelete ScopeName = "tailnet_coordinator:delete"
ScopeTailnetCoordinatorRead ScopeName = "tailnet_coordinator:read"
ScopeTailnetCoordinatorUpdate ScopeName = "tailnet_coordinator:update"
ScopeTemplateCreate ScopeName = "template:create"
ScopeTemplateDelete ScopeName = "template:delete"
ScopeTemplateRead ScopeName = "template:read"
ScopeTemplateUpdate ScopeName = "template:update"
ScopeTemplateUse ScopeName = "template:use"
ScopeTemplateViewInsights ScopeName = "template:view_insights"
ScopeUsageEventCreate ScopeName = "usage_event:create"
ScopeUsageEventRead ScopeName = "usage_event:read"
ScopeUsageEventUpdate ScopeName = "usage_event:update"
ScopeUserCreate ScopeName = "user:create"
ScopeUserDelete ScopeName = "user:delete"
ScopeUserRead ScopeName = "user:read"
ScopeUserReadPersonal ScopeName = "user:read_personal"
ScopeUserUpdate ScopeName = "user:update"
ScopeUserUpdatePersonal ScopeName = "user:update_personal"
ScopeUserSecretCreate ScopeName = "user_secret:create"
ScopeUserSecretDelete ScopeName = "user_secret:delete"
ScopeUserSecretRead ScopeName = "user_secret:read"
ScopeUserSecretUpdate ScopeName = "user_secret:update"
ScopeWebpushSubscriptionCreate ScopeName = "webpush_subscription:create"
ScopeWebpushSubscriptionDelete ScopeName = "webpush_subscription:delete"
ScopeWebpushSubscriptionRead ScopeName = "webpush_subscription:read"
ScopeWorkspaceApplicationConnect ScopeName = "workspace:application_connect"
ScopeWorkspaceCreate ScopeName = "workspace:create"
ScopeWorkspaceCreateAgent ScopeName = "workspace:create_agent"
ScopeWorkspaceDelete ScopeName = "workspace:delete"
ScopeWorkspaceDeleteAgent ScopeName = "workspace:delete_agent"
ScopeWorkspaceRead ScopeName = "workspace:read"
ScopeWorkspaceSsh ScopeName = "workspace:ssh"
ScopeWorkspaceStart ScopeName = "workspace:start"
ScopeWorkspaceStop ScopeName = "workspace:stop"
ScopeWorkspaceUpdate ScopeName = "workspace:update"
ScopeWorkspaceAgentDevcontainersCreate ScopeName = "workspace_agent_devcontainers:create"
ScopeWorkspaceAgentResourceMonitorCreate ScopeName = "workspace_agent_resource_monitor:create"
ScopeWorkspaceAgentResourceMonitorRead ScopeName = "workspace_agent_resource_monitor:read"
ScopeWorkspaceAgentResourceMonitorUpdate ScopeName = "workspace_agent_resource_monitor:update"
ScopeWorkspaceDormantApplicationConnect ScopeName = "workspace_dormant:application_connect"
ScopeWorkspaceDormantCreate ScopeName = "workspace_dormant:create"
ScopeWorkspaceDormantCreateAgent ScopeName = "workspace_dormant:create_agent"
ScopeWorkspaceDormantDelete ScopeName = "workspace_dormant:delete"
ScopeWorkspaceDormantDeleteAgent ScopeName = "workspace_dormant:delete_agent"
ScopeWorkspaceDormantRead ScopeName = "workspace_dormant:read"
ScopeWorkspaceDormantSsh ScopeName = "workspace_dormant:ssh"
ScopeWorkspaceDormantStart ScopeName = "workspace_dormant:start"
ScopeWorkspaceDormantStop ScopeName = "workspace_dormant:stop"
ScopeWorkspaceDormantUpdate ScopeName = "workspace_dormant:update"
ScopeWorkspaceProxyCreate ScopeName = "workspace_proxy:create"
ScopeWorkspaceProxyDelete ScopeName = "workspace_proxy:delete"
ScopeWorkspaceProxyRead ScopeName = "workspace_proxy:read"
ScopeWorkspaceProxyUpdate ScopeName = "workspace_proxy:update"
)
// Valid reports whether the ScopeName matches one of the known scope values.
// This includes both builtin scope names and generated low-level scopes.
// Builtins are sourced from rbac.BuiltinScopeNames() at generation time to
// ensure changes in rbac/scopes.go remain in sync here.
func (e ScopeName) Valid() bool {
switch e {
case ScopeName("all"),
ScopeName("application_connect"),
ScopeName("no_user_data"),
ScopeAibridgeInterceptionCreate,
ScopeAibridgeInterceptionRead,
ScopeAibridgeInterceptionUpdate,
ScopeApiKeyCreate,
ScopeApiKeyDelete,
ScopeApiKeyRead,
ScopeApiKeyUpdate,
ScopeAssignOrgRoleAssign,
ScopeAssignOrgRoleCreate,
ScopeAssignOrgRoleDelete,
ScopeAssignOrgRoleRead,
ScopeAssignOrgRoleUnassign,
ScopeAssignOrgRoleUpdate,
ScopeAssignRoleAssign,
ScopeAssignRoleRead,
ScopeAssignRoleUnassign,
ScopeAuditLogCreate,
ScopeAuditLogRead,
ScopeConnectionLogRead,
ScopeConnectionLogUpdate,
ScopeCryptoKeyCreate,
ScopeCryptoKeyDelete,
ScopeCryptoKeyRead,
ScopeCryptoKeyUpdate,
ScopeDebugInfoRead,
ScopeDeploymentConfigRead,
ScopeDeploymentConfigUpdate,
ScopeDeploymentStatsRead,
ScopeFileCreate,
ScopeFileRead,
ScopeGroupCreate,
ScopeGroupDelete,
ScopeGroupRead,
ScopeGroupUpdate,
ScopeGroupMemberRead,
ScopeIdpsyncSettingsRead,
ScopeIdpsyncSettingsUpdate,
ScopeInboxNotificationCreate,
ScopeInboxNotificationRead,
ScopeInboxNotificationUpdate,
ScopeLicenseCreate,
ScopeLicenseDelete,
ScopeLicenseRead,
ScopeNotificationMessageCreate,
ScopeNotificationMessageDelete,
ScopeNotificationMessageRead,
ScopeNotificationMessageUpdate,
ScopeNotificationPreferenceRead,
ScopeNotificationPreferenceUpdate,
ScopeNotificationTemplateRead,
ScopeNotificationTemplateUpdate,
ScopeOauth2AppCreate,
ScopeOauth2AppDelete,
ScopeOauth2AppRead,
ScopeOauth2AppUpdate,
ScopeOauth2AppCodeTokenCreate,
ScopeOauth2AppCodeTokenDelete,
ScopeOauth2AppCodeTokenRead,
ScopeOauth2AppSecretCreate,
ScopeOauth2AppSecretDelete,
ScopeOauth2AppSecretRead,
ScopeOauth2AppSecretUpdate,
ScopeOrganizationCreate,
ScopeOrganizationDelete,
ScopeOrganizationRead,
ScopeOrganizationUpdate,
ScopeOrganizationMemberCreate,
ScopeOrganizationMemberDelete,
ScopeOrganizationMemberRead,
ScopeOrganizationMemberUpdate,
ScopePrebuiltWorkspaceDelete,
ScopePrebuiltWorkspaceUpdate,
ScopeProvisionerDaemonCreate,
ScopeProvisionerDaemonDelete,
ScopeProvisionerDaemonRead,
ScopeProvisionerDaemonUpdate,
ScopeProvisionerJobsCreate,
ScopeProvisionerJobsRead,
ScopeProvisionerJobsUpdate,
ScopeReplicasRead,
ScopeSystemCreate,
ScopeSystemDelete,
ScopeSystemRead,
ScopeSystemUpdate,
ScopeTailnetCoordinatorCreate,
ScopeTailnetCoordinatorDelete,
ScopeTailnetCoordinatorRead,
ScopeTailnetCoordinatorUpdate,
ScopeTemplateCreate,
ScopeTemplateDelete,
ScopeTemplateRead,
ScopeTemplateUpdate,
ScopeTemplateUse,
ScopeTemplateViewInsights,
ScopeUsageEventCreate,
ScopeUsageEventRead,
ScopeUsageEventUpdate,
ScopeUserCreate,
ScopeUserDelete,
ScopeUserRead,
ScopeUserReadPersonal,
ScopeUserUpdate,
ScopeUserUpdatePersonal,
ScopeUserSecretCreate,
ScopeUserSecretDelete,
ScopeUserSecretRead,
ScopeUserSecretUpdate,
ScopeWebpushSubscriptionCreate,
ScopeWebpushSubscriptionDelete,
ScopeWebpushSubscriptionRead,
ScopeWorkspaceApplicationConnect,
ScopeWorkspaceCreate,
ScopeWorkspaceCreateAgent,
ScopeWorkspaceDelete,
ScopeWorkspaceDeleteAgent,
ScopeWorkspaceRead,
ScopeWorkspaceSsh,
ScopeWorkspaceStart,
ScopeWorkspaceStop,
ScopeWorkspaceUpdate,
ScopeWorkspaceAgentDevcontainersCreate,
ScopeWorkspaceAgentResourceMonitorCreate,
ScopeWorkspaceAgentResourceMonitorRead,
ScopeWorkspaceAgentResourceMonitorUpdate,
ScopeWorkspaceDormantApplicationConnect,
ScopeWorkspaceDormantCreate,
ScopeWorkspaceDormantCreateAgent,
ScopeWorkspaceDormantDelete,
ScopeWorkspaceDormantDeleteAgent,
ScopeWorkspaceDormantRead,
ScopeWorkspaceDormantSsh,
ScopeWorkspaceDormantStart,
ScopeWorkspaceDormantStop,
ScopeWorkspaceDormantUpdate,
ScopeWorkspaceProxyCreate,
ScopeWorkspaceProxyDelete,
ScopeWorkspaceProxyRead,
ScopeWorkspaceProxyUpdate:
return true
}
return false
}
// AllScopeNameValues returns a slice containing all known scope values,
// including builtin and generated low-level scopes.
func AllScopeNameValues() []ScopeName {
return []ScopeName{
ScopeName("all"),
ScopeName("application_connect"),
ScopeName("no_user_data"),
ScopeAibridgeInterceptionCreate,
ScopeAibridgeInterceptionRead,
ScopeAibridgeInterceptionUpdate,
ScopeApiKeyCreate,
ScopeApiKeyDelete,
ScopeApiKeyRead,
ScopeApiKeyUpdate,
ScopeAssignOrgRoleAssign,
ScopeAssignOrgRoleCreate,
ScopeAssignOrgRoleDelete,
ScopeAssignOrgRoleRead,
ScopeAssignOrgRoleUnassign,
ScopeAssignOrgRoleUpdate,
ScopeAssignRoleAssign,
ScopeAssignRoleRead,
ScopeAssignRoleUnassign,
ScopeAuditLogCreate,
ScopeAuditLogRead,
ScopeConnectionLogRead,
ScopeConnectionLogUpdate,
ScopeCryptoKeyCreate,
ScopeCryptoKeyDelete,
ScopeCryptoKeyRead,
ScopeCryptoKeyUpdate,
ScopeDebugInfoRead,
ScopeDeploymentConfigRead,
ScopeDeploymentConfigUpdate,
ScopeDeploymentStatsRead,
ScopeFileCreate,
ScopeFileRead,
ScopeGroupCreate,
ScopeGroupDelete,
ScopeGroupRead,
ScopeGroupUpdate,
ScopeGroupMemberRead,
ScopeIdpsyncSettingsRead,
ScopeIdpsyncSettingsUpdate,
ScopeInboxNotificationCreate,
ScopeInboxNotificationRead,
ScopeInboxNotificationUpdate,
ScopeLicenseCreate,
ScopeLicenseDelete,
ScopeLicenseRead,
ScopeNotificationMessageCreate,
ScopeNotificationMessageDelete,
ScopeNotificationMessageRead,
ScopeNotificationMessageUpdate,
ScopeNotificationPreferenceRead,
ScopeNotificationPreferenceUpdate,
ScopeNotificationTemplateRead,
ScopeNotificationTemplateUpdate,
ScopeOauth2AppCreate,
ScopeOauth2AppDelete,
ScopeOauth2AppRead,
ScopeOauth2AppUpdate,
ScopeOauth2AppCodeTokenCreate,
ScopeOauth2AppCodeTokenDelete,
ScopeOauth2AppCodeTokenRead,
ScopeOauth2AppSecretCreate,
ScopeOauth2AppSecretDelete,
ScopeOauth2AppSecretRead,
ScopeOauth2AppSecretUpdate,
ScopeOrganizationCreate,
ScopeOrganizationDelete,
ScopeOrganizationRead,
ScopeOrganizationUpdate,
ScopeOrganizationMemberCreate,
ScopeOrganizationMemberDelete,
ScopeOrganizationMemberRead,
ScopeOrganizationMemberUpdate,
ScopePrebuiltWorkspaceDelete,
ScopePrebuiltWorkspaceUpdate,
ScopeProvisionerDaemonCreate,
ScopeProvisionerDaemonDelete,
ScopeProvisionerDaemonRead,
ScopeProvisionerDaemonUpdate,
ScopeProvisionerJobsCreate,
ScopeProvisionerJobsRead,
ScopeProvisionerJobsUpdate,
ScopeReplicasRead,
ScopeSystemCreate,
ScopeSystemDelete,
ScopeSystemRead,
ScopeSystemUpdate,
ScopeTailnetCoordinatorCreate,
ScopeTailnetCoordinatorDelete,
ScopeTailnetCoordinatorRead,
ScopeTailnetCoordinatorUpdate,
ScopeTemplateCreate,
ScopeTemplateDelete,
ScopeTemplateRead,
ScopeTemplateUpdate,
ScopeTemplateUse,
ScopeTemplateViewInsights,
ScopeUsageEventCreate,
ScopeUsageEventRead,
ScopeUsageEventUpdate,
ScopeUserCreate,
ScopeUserDelete,
ScopeUserRead,
ScopeUserReadPersonal,
ScopeUserUpdate,
ScopeUserUpdatePersonal,
ScopeUserSecretCreate,
ScopeUserSecretDelete,
ScopeUserSecretRead,
ScopeUserSecretUpdate,
ScopeWebpushSubscriptionCreate,
ScopeWebpushSubscriptionDelete,
ScopeWebpushSubscriptionRead,
ScopeWorkspaceApplicationConnect,
ScopeWorkspaceCreate,
ScopeWorkspaceCreateAgent,
ScopeWorkspaceDelete,
ScopeWorkspaceDeleteAgent,
ScopeWorkspaceRead,
ScopeWorkspaceSsh,
ScopeWorkspaceStart,
ScopeWorkspaceStop,
ScopeWorkspaceUpdate,
ScopeWorkspaceAgentDevcontainersCreate,
ScopeWorkspaceAgentResourceMonitorCreate,
ScopeWorkspaceAgentResourceMonitorRead,
ScopeWorkspaceAgentResourceMonitorUpdate,
ScopeWorkspaceDormantApplicationConnect,
ScopeWorkspaceDormantCreate,
ScopeWorkspaceDormantCreateAgent,
ScopeWorkspaceDormantDelete,
ScopeWorkspaceDormantDeleteAgent,
ScopeWorkspaceDormantRead,
ScopeWorkspaceDormantSsh,
ScopeWorkspaceDormantStart,
ScopeWorkspaceDormantStop,
ScopeWorkspaceDormantUpdate,
ScopeWorkspaceProxyCreate,
ScopeWorkspaceProxyDelete,
ScopeWorkspaceProxyRead,
ScopeWorkspaceProxyUpdate,
}
}
+37
View File
@@ -18,6 +18,7 @@ import (
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/rbac/policy"
"github.com/coder/coder/v2/codersdk"
)
@@ -31,6 +32,9 @@ var codersdkTemplate string
//go:embed typescript.tstmpl
var typescriptTemplate string
//go:embed scopenames.gotmpl
var scopenamesTemplate string
//go:embed countries.tstmpl
var countriesTemplate string
@@ -96,6 +100,8 @@ func generateRBAC(tmpl string) ([]byte, error) {
// No typescript formatting
return src, nil
}
case "scopenames":
source = scopenamesTemplate
default:
return nil, xerrors.Errorf("%q is not a valid RBAC template target", tmpl)
}
@@ -225,6 +231,37 @@ func generateRbacObjects(templateSource string) ([]byte, error) {
"actionsList": func() []ActionDetails {
return actionList
},
"actionsOf": func(d Definition) []string {
// Extract and sort action string keys for deterministic output.
list := make([]string, 0, len(d.Actions))
for a := range d.Actions {
list = append(list, string(a))
}
slices.Sort(list)
return list
},
"allCaseList": func(defs []Definition) string {
// Build a multi-line comma-separated list of all scope constants (including builtins)
// suitable for use in a `case ...:` clause, without a trailing comma.
var names []string
// Builtins first, sourced dynamically from the rbac package to avoid drift.
for _, n := range rbac.BuiltinScopeNames() {
// Use typed string literals to avoid relying on constant identifiers.
names = append(names, fmt.Sprintf("ScopeName(%q)", string(n)))
}
for _, d := range defs {
res := pascalCaseName[string](d.Type)
acts := make([]string, 0, len(d.Actions))
for a := range d.Actions {
acts = append(acts, string(a))
}
slices.Sort(acts)
for _, a := range acts {
names = append(names, "Scope"+res+pascalCaseName[string](a))
}
}
return strings.Join(names, ",\n\t\t")
},
"actionEnum": func(action policy.Action) string {
x++
v, ok := actionMap[string(action)]
+36
View File
@@ -0,0 +1,36 @@
// Code generated by: go run ./scripts/typegen rbac scopenames; DO NOT EDIT.
package rbac
// ScopeName constants generated from policy.RBACPermissions.
// These represent low-level "<resource>:<action>" scope names.
// Built-in non-low-level scopes like "all" and "application_connect" remain
// declared in code, not here, to avoid duplication.
const (
{{- range $def := . }}
{{- $Res := pascalCaseName $def.Type }}
{{- range $act := actionsOf $def }}
Scope{{$Res}}{{ pascalCaseName $act }} ScopeName = "{{ $def.Type }}:{{ $act }}"
{{- end }}
{{- end }}
)
// Valid reports whether the ScopeName matches one of the known scope values.
// This includes both builtin scope names and generated low-level scopes.
// Builtins are sourced from rbac.BuiltinScopeNames() at generation time to
// ensure changes in rbac/scopes.go remain in sync here.
func (e ScopeName) Valid() bool {
switch e {
case {{ allCaseList . }}:
return true
}
return false
}
// AllScopeNameValues returns a slice containing all known scope values,
// including builtin and generated low-level scopes.
func AllScopeNameValues() []ScopeName {
return []ScopeName{
{{ allCaseList . }},
}
}