Skip to content

Commit e64c303

Browse files
committed
chore: audit organization member add/removals
1 parent 2ef2f97 commit e64c303

File tree

8 files changed

+45
-9
lines changed

8 files changed

+45
-9
lines changed

coderd/audit/diff.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ type Auditable interface {
2222
database.HealthSettings |
2323
database.OAuth2ProviderApp |
2424
database.OAuth2ProviderAppSecret |
25-
database.CustomRole
25+
database.CustomRole |
26+
database.OrganizationMember
2627
}
2728

2829
// Map is a map of changed fields in an audited resource. It maps field names to

coderd/audit/request.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
144144
return typed.ID
145145
case database.CustomRole:
146146
return typed.ID
147+
case database.OrganizationMember:
148+
return typed.UserID
147149
default:
148150
panic(fmt.Sprintf("unknown resource %T for ResourceID", tgt))
149151
}
@@ -181,6 +183,8 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
181183
return database.ResourceTypeOauth2ProviderAppSecret
182184
case database.CustomRole:
183185
return database.ResourceTypeCustomRole
186+
case database.OrganizationMember:
187+
return database.ResourceTypeOrganizationMember
184188
default:
185189
panic(fmt.Sprintf("unknown resource %T for ResourceType", typed))
186190
}
@@ -219,6 +223,8 @@ func ResourceRequiresOrgID[T Auditable]() bool {
219223
return false
220224
case database.CustomRole:
221225
return true
226+
case database.OrganizationMember:
227+
return true
222228
default:
223229
panic(fmt.Sprintf("unknown resource %T for ResourceRequiresOrgID", tgt))
224230
}

coderd/database/dump.sql

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/migrations/000220_audit_org_member.down.sql

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TYPE resource_type ADD VALUE IF NOT EXISTS 'organization_member';

coderd/database/models.go

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/members.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/google/uuid"
88
"golang.org/x/xerrors"
99

10+
"github.com/coder/coder/v2/coderd/audit"
1011
"github.com/coder/coder/v2/coderd/database"
1112
"github.com/coder/coder/v2/coderd/database/db2sdk"
1213
"github.com/coder/coder/v2/coderd/database/dbtime"
@@ -27,10 +28,19 @@ import (
2728
// @Router /organizations/{organization}/members/{user} [post]
2829
func (api *API) postOrganizationMember(rw http.ResponseWriter, r *http.Request) {
2930
var (
30-
ctx = r.Context()
31-
organization = httpmw.OrganizationParam(r)
32-
user = httpmw.UserParam(r)
31+
ctx = r.Context()
32+
organization = httpmw.OrganizationParam(r)
33+
user = httpmw.UserParam(r)
34+
auditor = api.Auditor.Load()
35+
aReq, commitAudit = audit.InitRequest[database.OrganizationMember](rw, &audit.RequestParams{
36+
Audit: *auditor,
37+
Log: api.Logger,
38+
Request: r,
39+
Action: database.AuditActionCreate,
40+
})
3341
)
42+
aReq.Old = database.OrganizationMember{}
43+
defer commitAudit()
3444

3545
member, err := api.Database.InsertOrganizationMember(ctx, database.InsertOrganizationMemberParams{
3646
OrganizationID: organization.ID,
@@ -54,6 +64,7 @@ func (api *API) postOrganizationMember(rw http.ResponseWriter, r *http.Request)
5464
return
5565
}
5666

67+
aReq.New = member
5768
resp, err := convertOrganizationMembers(ctx, api.Database, []database.OrganizationMember{member})
5869
if err != nil {
5970
httpapi.InternalServerError(rw, err)
@@ -79,10 +90,19 @@ func (api *API) postOrganizationMember(rw http.ResponseWriter, r *http.Request)
7990
// @Router /organizations/{organization}/members/{user} [delete]
8091
func (api *API) deleteOrganizationMember(rw http.ResponseWriter, r *http.Request) {
8192
var (
82-
ctx = r.Context()
83-
organization = httpmw.OrganizationParam(r)
84-
member = httpmw.OrganizationMemberParam(r)
93+
ctx = r.Context()
94+
organization = httpmw.OrganizationParam(r)
95+
member = httpmw.OrganizationMemberParam(r)
96+
auditor = api.Auditor.Load()
97+
aReq, commitAudit = audit.InitRequest[database.OrganizationMember](rw, &audit.RequestParams{
98+
Audit: *auditor,
99+
Log: api.Logger,
100+
Request: r,
101+
Action: database.AuditActionDelete,
102+
})
85103
)
104+
aReq.Old = member.OrganizationMember
105+
defer commitAudit()
86106

87107
err := api.Database.DeleteOrganizationMember(ctx, database.DeleteOrganizationMemberParams{
88108
OrganizationID: organization.ID,
@@ -97,6 +117,7 @@ func (api *API) deleteOrganizationMember(rw http.ResponseWriter, r *http.Request
97117
return
98118
}
99119

120+
aReq.New = database.OrganizationMember{}
100121
httpapi.Write(ctx, rw, http.StatusOK, "organization member removed")
101122
}
102123

codersdk/audit.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const (
3131
// nolint:gosec // This is not a secret.
3232
ResourceTypeOAuth2ProviderAppSecret ResourceType = "oauth2_provider_app_secret"
3333
ResourceTypeCustomRole ResourceType = "custom_role"
34+
ResourceTypeOrganizationMember = "organization_member"
3435
)
3536

3637
func (r ResourceType) FriendlyString() string {
@@ -69,6 +70,8 @@ func (r ResourceType) FriendlyString() string {
6970
return "oauth2 app secret"
7071
case ResourceTypeCustomRole:
7172
return "custom role"
73+
case ResourceTypeOrganizationMember:
74+
return "organization member"
7275
default:
7376
return "unknown"
7477
}

0 commit comments

Comments
 (0)