Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit65b9f9b

Browse files
authored
chore: audit organization member add/delete/edit (#13620)
* chore: audit organization member add/removals
1 parent9463973 commit65b9f9b

File tree

11 files changed

+86
-14
lines changed

11 files changed

+86
-14
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.AuditableOrganizationMember
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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ func ResourceTarget[T Auditable](tgt T) string {
105105
returntyped.DisplaySecret
106106
case database.CustomRole:
107107
returntyped.Name
108+
case database.AuditableOrganizationMember:
109+
returntyped.Username
108110
default:
109111
panic(fmt.Sprintf("unknown resource %T for ResourceTarget",tgt))
110112
}
@@ -144,6 +146,8 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
144146
returntyped.ID
145147
case database.CustomRole:
146148
returntyped.ID
149+
case database.AuditableOrganizationMember:
150+
returntyped.UserID
147151
default:
148152
panic(fmt.Sprintf("unknown resource %T for ResourceID",tgt))
149153
}
@@ -181,6 +185,8 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
181185
returndatabase.ResourceTypeOauth2ProviderAppSecret
182186
case database.CustomRole:
183187
returndatabase.ResourceTypeCustomRole
188+
case database.AuditableOrganizationMember:
189+
returndatabase.ResourceTypeOrganizationMember
184190
default:
185191
panic(fmt.Sprintf("unknown resource %T for ResourceType",typed))
186192
}
@@ -219,6 +225,8 @@ func ResourceRequiresOrgID[T Auditable]() bool {
219225
returnfalse
220226
case database.CustomRole:
221227
returntrue
228+
case database.AuditableOrganizationMember:
229+
returntrue
222230
default:
223231
panic(fmt.Sprintf("unknown resource %T for ResourceRequiresOrgID",tgt))
224232
}

‎coderd/database/dump.sql‎

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing 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+
ALTERTYPE resource_type ADD VALUE IF NOT EXISTS'organization_member';

‎coderd/database/modelmethods.go‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ func (s WorkspaceAgentStatus) Valid() bool {
6060
}
6161
}
6262

63+
typeAuditableOrganizationMemberstruct {
64+
OrganizationMember
65+
Usernamestring`json:"username"`
66+
}
67+
68+
func (mOrganizationMember)Auditable(usernamestring)AuditableOrganizationMember {
69+
returnAuditableOrganizationMember{
70+
OrganizationMember:m,
71+
Username:username,
72+
}
73+
}
74+
6375
typeAuditableGroupstruct {
6476
Group
6577
Members []GroupMember`json:"members"`

‎coderd/database/models.go‎

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

‎coderd/members.go‎

Lines changed: 45 additions & 11 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.AuditableOrganizationMember](rw,&audit.RequestParams{
36+
Audit:*auditor,
37+
Log:api.Logger,
38+
Request:r,
39+
Action:database.AuditActionCreate,
40+
})
3341
)
42+
aReq.Old= database.AuditableOrganizationMember{}
43+
defercommitAudit()
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.Auditable(user.Username)
5768
resp,err:=convertOrganizationMembers(ctx,api.Database, []database.OrganizationMember{member})
5869
iferr!=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.AuditableOrganizationMember](rw,&audit.RequestParams{
98+
Audit:*auditor,
99+
Log:api.Logger,
100+
Request:r,
101+
Action:database.AuditActionDelete,
102+
})
85103
)
104+
aReq.Old=member.OrganizationMember.Auditable(member.Username)
105+
defercommitAudit()
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.AuditableOrganizationMember{}
100121
httpapi.Write(ctx,rw,http.StatusOK,"organization member removed")
101122
}
102123

@@ -149,13 +170,22 @@ func (api *API) listMembers(rw http.ResponseWriter, r *http.Request) {
149170
// @Router /organizations/{organization}/members/{user}/roles [put]
150171
func (api*API)putMemberRoles(rw http.ResponseWriter,r*http.Request) {
151172
var (
152-
ctx=r.Context()
153-
organization=httpmw.OrganizationParam(r)
154-
member=httpmw.OrganizationMemberParam(r)
155-
apiKey=httpmw.APIKey(r)
173+
ctx=r.Context()
174+
organization=httpmw.OrganizationParam(r)
175+
member=httpmw.OrganizationMemberParam(r)
176+
apiKey=httpmw.APIKey(r)
177+
auditor=api.Auditor.Load()
178+
aReq,commitAudit=audit.InitRequest[database.AuditableOrganizationMember](rw,&audit.RequestParams{
179+
Audit:*auditor,
180+
Log:api.Logger,
181+
Request:r,
182+
Action:database.AuditActionWrite,
183+
})
156184
)
185+
aReq.Old=member.OrganizationMember.Auditable(member.Username)
186+
defercommitAudit()
157187

158-
ifapiKey.UserID==member.UserID {
188+
ifapiKey.UserID==member.OrganizationMember.UserID {
159189
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
160190
Message:"You cannot change your own organization roles.",
161191
})
@@ -182,6 +212,10 @@ func (api *API) putMemberRoles(rw http.ResponseWriter, r *http.Request) {
182212
})
183213
return
184214
}
215+
aReq.New= database.AuditableOrganizationMember{
216+
OrganizationMember:updatedUser,
217+
Username:member.Username,
218+
}
185219

186220
resp,err:=convertOrganizationMembers(ctx,api.Database, []database.OrganizationMember{updatedUser})
187221
iferr!=nil {

‎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
ResourceTypeOAuth2ProviderAppSecretResourceType="oauth2_provider_app_secret"
3333
ResourceTypeCustomRoleResourceType="custom_role"
34+
ResourceTypeOrganizationMember="organization_member"
3435
)
3536

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

‎docs/admin/audit-logs.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ We track the following resources:
1313
| APIKey<br><i>login, logout, register, create, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody><tr><td>created_at</td><td>true</td></tr><tr><td>expires_at</td><td>true</td></tr><tr><td>hashed_secret</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>ip_address</td><td>false</td></tr><tr><td>last_used</td><td>true</td></tr><tr><td>lifetime_seconds</td><td>false</td></tr><tr><td>login_type</td><td>false</td></tr><tr><td>scope</td><td>false</td></tr><tr><td>token_name</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table> |
1414
| AuditOAuthConvertState<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody><tr><td>created_at</td><td>true</td></tr><tr><td>expires_at</td><td>true</td></tr><tr><td>from_login_type</td><td>true</td></tr><tr><td>to_login_type</td><td>true</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table> |
1515
| Group<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody><tr><td>avatar_url</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>members</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>quota_allowance</td><td>true</td></tr><tr><td>source</td><td>false</td></tr></tbody></table> |
16+
| AuditableOrganizationMember<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody><tr><td>created_at</td><td>true</td></tr><tr><td>organization_id</td><td>true</td></tr><tr><td>roles</td><td>true</td></tr><tr><td>updated_at</td><td>true</td></tr><tr><td>user_id</td><td>true</td></tr><tr><td>username</td><td>true</td></tr></tbody></table> |
1617
| CustomRole<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody><tr><td>created_at</td><td>false</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>id</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>org_permissions</td><td>true</td></tr><tr><td>organization_id</td><td>true</td></tr><tr><td>site_permissions</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_permissions</td><td>true</td></tr></tbody></table> |
1718
| GitSSHKey<br><i>create</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody><tr><td>created_at</td><td>false</td></tr><tr><td>private_key</td><td>true</td></tr><tr><td>public_key</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr></tbody></table> |
1819
| HealthSettings<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody><tr><td>dismissed_healthchecks</td><td>true</td></tr><tr><td>id</td><td>false</td></tr></tbody></table> |

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp