Audit logging -- convert audit logs to use the new schema (#20526)

* Audit logging - new schema added, old schema removed.

* fix linter error by running goimports

* Address review comments

* Address review comments

* Example usage of new audit logging API for the updateUserAuth call

* fixed unit test on auditing updating user record

* Changed the `TestUpdateConfigDiffInAuditRecord` testcase---it failed, because this PR changes how the `meta` field is serialized into the audit log records.

* fix linter error

* use string constants for record keys

* new audit api calls for api4/bot

* `Auditable` interface implementations for model classes

* New audit calls for channel api

* New audit calls for channel_local

* renamed receivers for required style reasons

* New audit calls for api4/command

* renamed receiver

* New audit calls for api4/command_local

* renamed receiver

* fix unit test to reflect changes in the Auditable implementation of the user class

* new audit calls for compliance

* new audit calls for configs

* remove auditRec.addMeta from updateConfig and patchConfig

* new audit calls for config_local

* new audit calls

* new audit calls for ldap, license apis

* new audit calls

* new audit calls

* new audit calls

* new audit calls

* new audit calls

* new audit calls

* new audit calls

* new audit calls

* fix linter error

* fixed linter error

* fixed "user update" test

* Don't include all of config when audit logging config changes. Also fix unit test on TestUpdateConfigDiffInAuditRecord

* address review comments

* Added Auditable() method for UserPatch

* Fix duplicative method declaration from merge

* Fix styling and API changes issues introduced with merge

* Fix broken test

Co-authored-by: Daniel Schalla <daniel@schalla.me>
Этот коммит содержится в:
Ossi Väänänen
2022-07-14 14:52:46 +03:00
коммит произвёл GitHub
родитель 4d3bdab14c
Коммит 8f44fbf89c
60 изменённых файлов: 885 добавлений и 275 удалений

Просмотреть файл

@@ -32,12 +32,12 @@ func (a *Audit) Init(maxQueueSize int) {
// LogRecord emits an audit record with complete info.
func (a *Audit) LogRecord(level mlog.Level, rec Record) {
flds := []mlog.Field{
mlog.String("event_name", rec.EventName),
mlog.String(KeyEventName, rec.EventName),
mlog.String(KeyStatus, rec.Status),
mlog.Any("actor", rec.Actor),
mlog.Any("event", rec.EventData),
mlog.Any("meta", rec.Meta),
mlog.Any("error", rec.Error),
mlog.Any(KeyActor, rec.Actor),
mlog.Any(KeyEvent, rec.EventData),
mlog.Any(KeyMeta, rec.Meta),
mlog.Any(KeyError, rec.Error),
}
a.logger.Log(level, "", flds...)

Просмотреть файл

@@ -40,7 +40,7 @@ func TestAudit_LogRecord(t *testing.T) {
func(audit Audit) {
usr := &model.User{}
usr.Id = userId //"fasd21321sdasd12"
usr.Id = userId
usr.Username = "TestABC"
usr.Password = "hello_world"
@@ -56,7 +56,7 @@ func TestAudit_LogRecord(t *testing.T) {
audit.LogRecord(mlog.LvlAuditAPI, rec)
},
[]string{
strings.Replace(`{"timestamp":0,"level":"audit-api","msg":"","event_name":"User.Update","status":"success","actor":{"user_id":"","session_id":"","client":"","ip_address":""},"event":{"parameters":null,"prior_state":{"id":"_____USERID_____","username":"TestABC"},"resulting_state":{"id":"_____USERID_____","username":"TestDEF"},"object_type":"user"},"meta":null,"error":{}}`, "_____USERID_____", userId, -1),
strings.Replace(`{"timestamp":0,"level":"audit-api","msg":"","event_name":"User.Update","status":"success","actor":{"user_id":"","session_id":"","client":"","ip_address":""},"event":{"parameters":null,"prior_state":{"allow_marketing":false,"auth_service":"","bot_description":"","bot_last_icon_update":0,"create_at":0,"delete_at":0,"disable_welcome_email":false,"email":"","email_verified":false,"failed_attempts":0,"id":"_____USERID_____","is_bot":false,"last_activity_at":0,"last_password_update":0,"last_picture_update":0,"locale":"","mfa_active":false,"notify_props":null,"position":"","props":null,"remote_id":null,"roles":"","terms_of_service_create_at":0,"terms_of_service_id":"","timezone":null,"update_at":0,"username":"TestABC"},"resulting_state":{"allow_marketing":false,"auth_service":"","bot_description":"","bot_last_icon_update":0,"create_at":0,"delete_at":0,"disable_welcome_email":false,"email":"","email_verified":false,"failed_attempts":0,"id":"_____USERID_____","is_bot":false,"last_activity_at":0,"last_password_update":0,"last_picture_update":0,"locale":"","mfa_active":false,"notify_props":null,"position":"","props":null,"remote_id":null,"roles":"","terms_of_service_create_at":0,"terms_of_service_id":"","timezone":null,"update_at":0,"username":"TestDEF"},"object_type":"user"},"meta":null,"error":{}}`, "_____USERID_____", userId, -1),
},
},
}

Просмотреть файл

@@ -6,9 +6,13 @@ package audit
const (
DefMaxQueueSize = 1000
KeyActor = "actor"
KeyAPIPath = "api_path"
KeyEvent = "event"
KeyEventData = "event_data"
KeyEventName = "event_name"
KeyMeta = "meta"
KeyError = "error"
KeyStatus = "status"
KeyUserID = "user_id"
KeySessionID = "session_id"

Просмотреть файл

@@ -60,7 +60,15 @@ func (rec *Record) Fail() {
// AddEventParameter adds a parameter, e.g. query or post body, to the event
func (rec *Record) AddEventParameter(key string, val interface{}) {
rec.EventData.Parameters[key] = val
if rec.EventData.Parameters == nil {
rec.EventData.Parameters = make(map[string]interface{})
}
if auditableVal, ok := val.(Auditable); ok {
rec.EventData.Parameters[key] = auditableVal.Auditable()
} else {
rec.EventData.Parameters[key] = val
}
}
// AddEventPriorState adds the prior state of the modified object to the audit record