mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: add auditing to user routes (#3961)
This commit is contained in:
@ -21,6 +21,7 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"cdr.dev/slog"
|
||||
"github.com/coder/coder/coderd/audit"
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/gitsshkey"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
@ -254,6 +255,14 @@ func (api *API) users(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Creates a new user.
|
||||
func (api *API) postUser(rw http.ResponseWriter, r *http.Request) {
|
||||
aReq, commitAudit := audit.InitRequest[database.User](rw, &audit.RequestParams{
|
||||
Features: api.FeaturesService,
|
||||
Log: api.Logger,
|
||||
Request: r,
|
||||
Action: database.AuditActionCreate,
|
||||
})
|
||||
defer commitAudit()
|
||||
|
||||
// Create the user on the site.
|
||||
if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceUser) {
|
||||
httpapi.Forbidden(rw)
|
||||
@ -319,6 +328,8 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
aReq.New = user
|
||||
|
||||
// Report when users are added!
|
||||
api.Telemetry.Report(&telemetry.Snapshot{
|
||||
Users: []telemetry.User{telemetry.ConvertUser(user)},
|
||||
@ -350,7 +361,17 @@ func (api *API) userByName(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (api *API) putUserProfile(rw http.ResponseWriter, r *http.Request) {
|
||||
user := httpmw.UserParam(r)
|
||||
var (
|
||||
user = httpmw.UserParam(r)
|
||||
aReq, commitAudit = audit.InitRequest[database.User](rw, &audit.RequestParams{
|
||||
Features: api.FeaturesService,
|
||||
Log: api.Logger,
|
||||
Request: r,
|
||||
Action: database.AuditActionWrite,
|
||||
})
|
||||
)
|
||||
defer commitAudit()
|
||||
aReq.Old = user
|
||||
|
||||
if !api.Authorize(r, rbac.ActionUpdate, rbac.ResourceUser) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
@ -395,6 +416,7 @@ func (api *API) putUserProfile(rw http.ResponseWriter, r *http.Request) {
|
||||
Username: params.Username,
|
||||
UpdatedAt: database.Now(),
|
||||
})
|
||||
aReq.New = updatedUserProfile
|
||||
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
|
||||
@ -418,8 +440,18 @@ func (api *API) putUserProfile(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseWriter, r *http.Request) {
|
||||
return func(rw http.ResponseWriter, r *http.Request) {
|
||||
user := httpmw.UserParam(r)
|
||||
apiKey := httpmw.APIKey(r)
|
||||
var (
|
||||
user = httpmw.UserParam(r)
|
||||
apiKey = httpmw.APIKey(r)
|
||||
aReq, commitAudit = audit.InitRequest[database.User](rw, &audit.RequestParams{
|
||||
Features: api.FeaturesService,
|
||||
Log: api.Logger,
|
||||
Request: r,
|
||||
Action: database.AuditActionWrite,
|
||||
})
|
||||
)
|
||||
defer commitAudit()
|
||||
aReq.Old = user
|
||||
|
||||
if !api.Authorize(r, rbac.ActionDelete, rbac.ResourceUser) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
@ -451,7 +483,6 @@ func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseW
|
||||
Status: status,
|
||||
UpdatedAt: database.Now(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: fmt.Sprintf("Internal error updating user's status to %q.", status),
|
||||
@ -459,6 +490,7 @@ func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseW
|
||||
})
|
||||
return
|
||||
}
|
||||
aReq.New = suspendedUser
|
||||
|
||||
organizations, err := userOrganizationIDs(r.Context(), api, user)
|
||||
if err != nil {
|
||||
@ -475,9 +507,17 @@ func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseW
|
||||
|
||||
func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) {
|
||||
var (
|
||||
user = httpmw.UserParam(r)
|
||||
params codersdk.UpdateUserPasswordRequest
|
||||
user = httpmw.UserParam(r)
|
||||
params codersdk.UpdateUserPasswordRequest
|
||||
aReq, commitAudit = audit.InitRequest[database.User](rw, &audit.RequestParams{
|
||||
Features: api.FeaturesService,
|
||||
Log: api.Logger,
|
||||
Request: r,
|
||||
Action: database.AuditActionWrite,
|
||||
})
|
||||
)
|
||||
defer commitAudit()
|
||||
aReq.Old = user
|
||||
|
||||
if !api.Authorize(r, rbac.ActionUpdate, rbac.ResourceUserData.WithOwner(user.ID.String())) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
@ -552,6 +592,10 @@ func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
newUser := user
|
||||
newUser.HashedPassword = []byte(hashedPassword)
|
||||
aReq.New = newUser
|
||||
|
||||
httpapi.Write(rw, http.StatusNoContent, nil)
|
||||
}
|
||||
|
||||
@ -598,10 +642,20 @@ func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (api *API) putUserRoles(rw http.ResponseWriter, r *http.Request) {
|
||||
// User is the user to modify.
|
||||
user := httpmw.UserParam(r)
|
||||
actorRoles := httpmw.AuthorizationUserRoles(r)
|
||||
apiKey := httpmw.APIKey(r)
|
||||
var (
|
||||
// User is the user to modify.
|
||||
user = httpmw.UserParam(r)
|
||||
actorRoles = httpmw.AuthorizationUserRoles(r)
|
||||
apiKey = httpmw.APIKey(r)
|
||||
aReq, commitAudit = audit.InitRequest[database.User](rw, &audit.RequestParams{
|
||||
Features: api.FeaturesService,
|
||||
Log: api.Logger,
|
||||
Request: r,
|
||||
Action: database.AuditActionWrite,
|
||||
})
|
||||
)
|
||||
defer commitAudit()
|
||||
aReq.Old = user
|
||||
|
||||
if apiKey.UserID == user.ID {
|
||||
httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{
|
||||
@ -654,6 +708,7 @@ func (api *API) putUserRoles(rw http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
return
|
||||
}
|
||||
aReq.New = updatedUser
|
||||
|
||||
organizationIDs, err := userOrganizationIDs(r.Context(), api, user)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user