feat: add auditing to user routes (#3961)

This commit is contained in:
Colin Adler
2022-09-08 21:16:16 -05:00
committed by GitHub
parent c026464375
commit 4e26e325a6
11 changed files with 258 additions and 61 deletions

View File

@ -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 {