chore: audit log entries for all idp sync changes (#15919)

This commit is contained in:
Steven Masley
2025-01-02 15:02:04 -06:00
committed by GitHub
parent 761a19663f
commit 73ec6b2635
18 changed files with 259 additions and 64 deletions
+12 -2
View File
@@ -12937,7 +12937,12 @@ const docTemplate = `{
"organization",
"oauth2_provider_app",
"oauth2_provider_app_secret",
"custom_role"
"custom_role",
"organization_member",
"notification_template",
"idp_sync_settings_organization",
"idp_sync_settings_group",
"idp_sync_settings_role"
],
"x-enum-varnames": [
"ResourceTypeTemplate",
@@ -12956,7 +12961,12 @@ const docTemplate = `{
"ResourceTypeOrganization",
"ResourceTypeOAuth2ProviderApp",
"ResourceTypeOAuth2ProviderAppSecret",
"ResourceTypeCustomRole"
"ResourceTypeCustomRole",
"ResourceTypeOrganizationMember",
"ResourceTypeNotificationTemplate",
"ResourceTypeIdpSyncSettingsOrganization",
"ResourceTypeIdpSyncSettingsGroup",
"ResourceTypeIdpSyncSettingsRole"
]
},
"codersdk.Response": {
+12 -2
View File
@@ -11694,7 +11694,12 @@
"organization",
"oauth2_provider_app",
"oauth2_provider_app_secret",
"custom_role"
"custom_role",
"organization_member",
"notification_template",
"idp_sync_settings_organization",
"idp_sync_settings_group",
"idp_sync_settings_role"
],
"x-enum-varnames": [
"ResourceTypeTemplate",
@@ -11713,7 +11718,12 @@
"ResourceTypeOrganization",
"ResourceTypeOAuth2ProviderApp",
"ResourceTypeOAuth2ProviderAppSecret",
"ResourceTypeCustomRole"
"ResourceTypeCustomRole",
"ResourceTypeOrganizationMember",
"ResourceTypeNotificationTemplate",
"ResourceTypeIdpSyncSettingsOrganization",
"ResourceTypeIdpSyncSettingsGroup",
"ResourceTypeIdpSyncSettingsRole"
]
},
"codersdk.Response": {
+5 -1
View File
@@ -2,6 +2,7 @@ package audit
import (
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/idpsync"
)
// Auditable is mostly a marker interface. It contains a definitive list of all
@@ -26,7 +27,10 @@ type Auditable interface {
database.CustomRole |
database.AuditableOrganizationMember |
database.Organization |
database.NotificationTemplate
database.NotificationTemplate |
idpsync.OrganizationSyncSettings |
idpsync.GroupSyncSettings |
idpsync.RoleSyncSettings
}
// Map is a map of changed fields in an audited resource. It maps field names to
+30
View File
@@ -20,6 +20,7 @@ import (
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/idpsync"
"github.com/coder/coder/v2/coderd/tracing"
)
@@ -121,11 +122,22 @@ func ResourceTarget[T Auditable](tgt T) string {
return typed.Name
case database.NotificationTemplate:
return typed.Name
case idpsync.OrganizationSyncSettings:
return "Organization Sync"
case idpsync.GroupSyncSettings:
return "Organization Group Sync"
case idpsync.RoleSyncSettings:
return "Organization Role Sync"
default:
panic(fmt.Sprintf("unknown resource %T for ResourceTarget", tgt))
}
}
// noID can be used for resources that do not have an uuid.
// An example is singleton configuration resources.
// 51A51C = "Static"
var noID = uuid.MustParse("51A51C00-0000-0000-0000-000000000000")
func ResourceID[T Auditable](tgt T) uuid.UUID {
switch typed := any(tgt).(type) {
case database.Template:
@@ -169,6 +181,12 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
return typed.ID
case database.NotificationTemplate:
return typed.ID
case idpsync.OrganizationSyncSettings:
return noID // Deployment all uses the same org sync settings
case idpsync.GroupSyncSettings:
return noID // Org field on audit log has org id
case idpsync.RoleSyncSettings:
return noID // Org field on audit log has org id
default:
panic(fmt.Sprintf("unknown resource %T for ResourceID", tgt))
}
@@ -214,6 +232,12 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
return database.ResourceTypeOrganization
case database.NotificationTemplate:
return database.ResourceTypeNotificationTemplate
case idpsync.OrganizationSyncSettings:
return database.ResourceTypeIdpSyncSettingsOrganization
case idpsync.RoleSyncSettings:
return database.ResourceTypeIdpSyncSettingsRole
case idpsync.GroupSyncSettings:
return database.ResourceTypeIdpSyncSettingsGroup
default:
panic(fmt.Sprintf("unknown resource %T for ResourceType", typed))
}
@@ -261,6 +285,12 @@ func ResourceRequiresOrgID[T Auditable]() bool {
return true
case database.NotificationTemplate:
return false
case idpsync.OrganizationSyncSettings:
return false
case idpsync.GroupSyncSettings:
return true
case idpsync.RoleSyncSettings:
return true
default:
panic(fmt.Sprintf("unknown resource %T for ResourceRequiresOrgID", tgt))
}
+4 -1
View File
@@ -190,7 +190,10 @@ CREATE TYPE resource_type AS ENUM (
'custom_role',
'organization_member',
'notifications_settings',
'notification_template'
'notification_template',
'idp_sync_settings_organization',
'idp_sync_settings_group',
'idp_sync_settings_role'
);
CREATE TYPE startup_script_behavior AS ENUM (
@@ -0,0 +1 @@
-- Nothing to do
@@ -0,0 +1,4 @@
-- Allow modifications to notification templates to be audited.
ALTER TYPE resource_type ADD VALUE IF NOT EXISTS 'idp_sync_settings_organization';
ALTER TYPE resource_type ADD VALUE IF NOT EXISTS 'idp_sync_settings_group';
ALTER TYPE resource_type ADD VALUE IF NOT EXISTS 'idp_sync_settings_role';
+29 -20
View File
@@ -1524,25 +1524,28 @@ func AllProvisionerTypeValues() []ProvisionerType {
type ResourceType string
const (
ResourceTypeOrganization ResourceType = "organization"
ResourceTypeTemplate ResourceType = "template"
ResourceTypeTemplateVersion ResourceType = "template_version"
ResourceTypeUser ResourceType = "user"
ResourceTypeWorkspace ResourceType = "workspace"
ResourceTypeGitSshKey ResourceType = "git_ssh_key"
ResourceTypeApiKey ResourceType = "api_key"
ResourceTypeGroup ResourceType = "group"
ResourceTypeWorkspaceBuild ResourceType = "workspace_build"
ResourceTypeLicense ResourceType = "license"
ResourceTypeWorkspaceProxy ResourceType = "workspace_proxy"
ResourceTypeConvertLogin ResourceType = "convert_login"
ResourceTypeHealthSettings ResourceType = "health_settings"
ResourceTypeOauth2ProviderApp ResourceType = "oauth2_provider_app"
ResourceTypeOauth2ProviderAppSecret ResourceType = "oauth2_provider_app_secret"
ResourceTypeCustomRole ResourceType = "custom_role"
ResourceTypeOrganizationMember ResourceType = "organization_member"
ResourceTypeNotificationsSettings ResourceType = "notifications_settings"
ResourceTypeNotificationTemplate ResourceType = "notification_template"
ResourceTypeOrganization ResourceType = "organization"
ResourceTypeTemplate ResourceType = "template"
ResourceTypeTemplateVersion ResourceType = "template_version"
ResourceTypeUser ResourceType = "user"
ResourceTypeWorkspace ResourceType = "workspace"
ResourceTypeGitSshKey ResourceType = "git_ssh_key"
ResourceTypeApiKey ResourceType = "api_key"
ResourceTypeGroup ResourceType = "group"
ResourceTypeWorkspaceBuild ResourceType = "workspace_build"
ResourceTypeLicense ResourceType = "license"
ResourceTypeWorkspaceProxy ResourceType = "workspace_proxy"
ResourceTypeConvertLogin ResourceType = "convert_login"
ResourceTypeHealthSettings ResourceType = "health_settings"
ResourceTypeOauth2ProviderApp ResourceType = "oauth2_provider_app"
ResourceTypeOauth2ProviderAppSecret ResourceType = "oauth2_provider_app_secret"
ResourceTypeCustomRole ResourceType = "custom_role"
ResourceTypeOrganizationMember ResourceType = "organization_member"
ResourceTypeNotificationsSettings ResourceType = "notifications_settings"
ResourceTypeNotificationTemplate ResourceType = "notification_template"
ResourceTypeIdpSyncSettingsOrganization ResourceType = "idp_sync_settings_organization"
ResourceTypeIdpSyncSettingsGroup ResourceType = "idp_sync_settings_group"
ResourceTypeIdpSyncSettingsRole ResourceType = "idp_sync_settings_role"
)
func (e *ResourceType) Scan(src interface{}) error {
@@ -1600,7 +1603,10 @@ func (e ResourceType) Valid() bool {
ResourceTypeCustomRole,
ResourceTypeOrganizationMember,
ResourceTypeNotificationsSettings,
ResourceTypeNotificationTemplate:
ResourceTypeNotificationTemplate,
ResourceTypeIdpSyncSettingsOrganization,
ResourceTypeIdpSyncSettingsGroup,
ResourceTypeIdpSyncSettingsRole:
return true
}
return false
@@ -1627,6 +1633,9 @@ func AllResourceTypeValues() []ResourceType {
ResourceTypeOrganizationMember,
ResourceTypeNotificationsSettings,
ResourceTypeNotificationTemplate,
ResourceTypeIdpSyncSettingsOrganization,
ResourceTypeIdpSyncSettingsGroup,
ResourceTypeIdpSyncSettingsRole,
}
}
+3 -3
View File
@@ -149,13 +149,13 @@ type OrganizationSyncSettings struct {
// Field selects the claim field to be used as the created user's
// organizations. If the field is the empty string, then no organization updates
// will ever come from the OIDC provider.
Field string
Field string `json:"field"`
// Mapping controls how organizations returned by the OIDC provider get mapped
Mapping map[string][]uuid.UUID
Mapping map[string][]uuid.UUID `json:"mapping"`
// AssignDefault will ensure all users that authenticate will be
// placed into the default organization. This is mostly a hack to support
// legacy deployments.
AssignDefault bool
AssignDefault bool `json:"assign_default"`
}
func (s *OrganizationSyncSettings) Set(v string) error {