mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
feat: audit oauth2 app management (#12275)
* Audit oauth2 app management * Use 201 for creating secrets
This commit is contained in:
8
coderd/apidoc/docs.go
generated
8
coderd/apidoc/docs.go
generated
@ -11504,7 +11504,9 @@ const docTemplate = `{
|
||||
"convert_login",
|
||||
"health_settings",
|
||||
"workspace_proxy",
|
||||
"organization"
|
||||
"organization",
|
||||
"oauth2_provider_app",
|
||||
"oauth2_provider_app_secret"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ResourceTypeTemplate",
|
||||
@ -11519,7 +11521,9 @@ const docTemplate = `{
|
||||
"ResourceTypeConvertLogin",
|
||||
"ResourceTypeHealthSettings",
|
||||
"ResourceTypeWorkspaceProxy",
|
||||
"ResourceTypeOrganization"
|
||||
"ResourceTypeOrganization",
|
||||
"ResourceTypeOAuth2ProviderApp",
|
||||
"ResourceTypeOAuth2ProviderAppSecret"
|
||||
]
|
||||
},
|
||||
"codersdk.Response": {
|
||||
|
8
coderd/apidoc/swagger.json
generated
8
coderd/apidoc/swagger.json
generated
@ -10378,7 +10378,9 @@
|
||||
"convert_login",
|
||||
"health_settings",
|
||||
"workspace_proxy",
|
||||
"organization"
|
||||
"organization",
|
||||
"oauth2_provider_app",
|
||||
"oauth2_provider_app_secret"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ResourceTypeTemplate",
|
||||
@ -10393,7 +10395,9 @@
|
||||
"ResourceTypeConvertLogin",
|
||||
"ResourceTypeHealthSettings",
|
||||
"ResourceTypeWorkspaceProxy",
|
||||
"ResourceTypeOrganization"
|
||||
"ResourceTypeOrganization",
|
||||
"ResourceTypeOAuth2ProviderApp",
|
||||
"ResourceTypeOAuth2ProviderAppSecret"
|
||||
]
|
||||
},
|
||||
"codersdk.Response": {
|
||||
|
@ -333,6 +333,22 @@ func (api *API) auditLogIsResourceDeleted(ctx context.Context, alog database.Get
|
||||
api.Logger.Error(ctx, "unable to fetch workspace", slog.Error(err))
|
||||
}
|
||||
return workspace.Deleted
|
||||
case database.ResourceTypeOauth2ProviderApp:
|
||||
_, err := api.Database.GetOAuth2ProviderAppByID(ctx, alog.ResourceID)
|
||||
if xerrors.Is(err, sql.ErrNoRows) {
|
||||
return true
|
||||
} else if err != nil {
|
||||
api.Logger.Error(ctx, "unable to fetch oauth2 app", slog.Error(err))
|
||||
}
|
||||
return false
|
||||
case database.ResourceTypeOauth2ProviderAppSecret:
|
||||
_, err := api.Database.GetOAuth2ProviderAppSecretByID(ctx, alog.ResourceID)
|
||||
if xerrors.Is(err, sql.ErrNoRows) {
|
||||
return true
|
||||
} else if err != nil {
|
||||
api.Logger.Error(ctx, "unable to fetch oauth2 app secret", slog.Error(err))
|
||||
}
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@ -379,6 +395,16 @@ func (api *API) auditLogResourceLink(ctx context.Context, alog database.GetAudit
|
||||
return fmt.Sprintf("/@%s/%s/builds/%s",
|
||||
workspaceOwner.Username, additionalFields.WorkspaceName, additionalFields.BuildNumber)
|
||||
|
||||
case database.ResourceTypeOauth2ProviderApp:
|
||||
return fmt.Sprintf("/deployment/oauth2-provider/apps/%s", alog.ResourceID)
|
||||
|
||||
case database.ResourceTypeOauth2ProviderAppSecret:
|
||||
secret, err := api.Database.GetOAuth2ProviderAppSecretByID(ctx, alog.ResourceID)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("/deployment/oauth2-provider/apps/%s", secret.AppID)
|
||||
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ type Auditable interface {
|
||||
database.License |
|
||||
database.WorkspaceProxy |
|
||||
database.AuditOAuthConvertState |
|
||||
database.HealthSettings
|
||||
database.HealthSettings |
|
||||
database.OAuth2ProviderApp |
|
||||
database.OAuth2ProviderAppSecret
|
||||
}
|
||||
|
||||
// Map is a map of changed fields in an audited resource. It maps field names to
|
||||
|
@ -99,6 +99,10 @@ func ResourceTarget[T Auditable](tgt T) string {
|
||||
return string(typed.ToLoginType)
|
||||
case database.HealthSettings:
|
||||
return "" // no target?
|
||||
case database.OAuth2ProviderApp:
|
||||
return typed.Name
|
||||
case database.OAuth2ProviderAppSecret:
|
||||
return typed.DisplaySecret
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown resource %T for ResourceTarget", tgt))
|
||||
}
|
||||
@ -132,6 +136,10 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
|
||||
case database.HealthSettings:
|
||||
// Artificial ID for auditing purposes
|
||||
return typed.ID
|
||||
case database.OAuth2ProviderApp:
|
||||
return typed.ID
|
||||
case database.OAuth2ProviderAppSecret:
|
||||
return typed.ID
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown resource %T for ResourceID", tgt))
|
||||
}
|
||||
@ -163,6 +171,10 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
|
||||
return database.ResourceTypeConvertLogin
|
||||
case database.HealthSettings:
|
||||
return database.ResourceTypeHealthSettings
|
||||
case database.OAuth2ProviderApp:
|
||||
return database.ResourceTypeOauth2ProviderApp
|
||||
case database.OAuth2ProviderAppSecret:
|
||||
return database.ResourceTypeOauth2ProviderAppSecret
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown resource %T for ResourceType", typed))
|
||||
}
|
||||
@ -195,6 +207,10 @@ func ResourceRequiresOrgID[T Auditable]() bool {
|
||||
case database.HealthSettings:
|
||||
// Artificial ID for auditing purposes
|
||||
return false
|
||||
case database.OAuth2ProviderApp:
|
||||
return false
|
||||
case database.OAuth2ProviderAppSecret:
|
||||
return false
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown resource %T for ResourceRequiresOrgID", tgt))
|
||||
}
|
||||
|
4
coderd/database/dump.sql
generated
4
coderd/database/dump.sql
generated
@ -135,7 +135,9 @@ CREATE TYPE resource_type AS ENUM (
|
||||
'license',
|
||||
'workspace_proxy',
|
||||
'convert_login',
|
||||
'health_settings'
|
||||
'health_settings',
|
||||
'oauth2_provider_app',
|
||||
'oauth2_provider_app_secret'
|
||||
);
|
||||
|
||||
CREATE TYPE startup_script_behavior AS ENUM (
|
||||
|
@ -0,0 +1,2 @@
|
||||
-- It is not possible to drop enum values from enum types, so the UPs on
|
||||
-- resource_type have "IF NOT EXISTS".
|
@ -0,0 +1,2 @@
|
||||
ALTER TYPE resource_type ADD VALUE IF NOT EXISTS 'oauth2_provider_app';
|
||||
ALTER TYPE resource_type ADD VALUE IF NOT EXISTS 'oauth2_provider_app_secret';
|
@ -1149,19 +1149,21 @@ 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"
|
||||
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"
|
||||
)
|
||||
|
||||
func (e *ResourceType) Scan(src interface{}) error {
|
||||
@ -1213,7 +1215,9 @@ func (e ResourceType) Valid() bool {
|
||||
ResourceTypeLicense,
|
||||
ResourceTypeWorkspaceProxy,
|
||||
ResourceTypeConvertLogin,
|
||||
ResourceTypeHealthSettings:
|
||||
ResourceTypeHealthSettings,
|
||||
ResourceTypeOauth2ProviderApp,
|
||||
ResourceTypeOauth2ProviderAppSecret:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -1234,6 +1238,8 @@ func AllResourceTypeValues() []ResourceType {
|
||||
ResourceTypeWorkspaceProxy,
|
||||
ResourceTypeConvertLogin,
|
||||
ResourceTypeHealthSettings,
|
||||
ResourceTypeOauth2ProviderApp,
|
||||
ResourceTypeOauth2ProviderAppSecret,
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user