diff --git a/api4/bot.go b/api4/bot.go index fc948af374..fad11c8114 100644 --- a/api4/bot.go +++ b/api4/bot.go @@ -39,7 +39,7 @@ func createBot(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createBot", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("bot", bot) + auditRec.AddEventParameter("bot", bot) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreateBot) { c.SetPermissionError(model.PermissionCreateBot) @@ -65,7 +65,8 @@ func createBot(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("bot", createdBot) // overwrite meta + auditRec.AddEventObjectType("bot") + auditRec.AddEventResultState(createdBot) // overwrite meta w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(createdBot); err != nil { @@ -89,7 +90,8 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("patchBot", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("bot_id", botUserId) + auditRec.AddEventParameter("id", botUserId) + auditRec.AddEventParameter("bot", botPatch) if err := c.App.SessionHasPermissionToManageBot(*c.AppContext.Session(), botUserId); err != nil { c.Err = err @@ -103,7 +105,8 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("bot", updatedBot) + auditRec.AddEventResultState(updatedBot) + auditRec.AddEventObjectType("bot") if err := json.NewEncoder(w).Encode(updatedBot); err != nil { mlog.Warn("Error while writing response", mlog.Err(err)) @@ -205,8 +208,8 @@ func updateBotActive(c *Context, w http.ResponseWriter, active bool) { auditRec := c.MakeAuditRecord("updateBotActive", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("bot_id", botUserId) - auditRec.AddMeta("enable", active) + auditRec.AddEventParameter("id", botUserId) + auditRec.AddEventParameter("enable", active) if err := c.App.SessionHasPermissionToManageBot(*c.AppContext.Session(), botUserId); err != nil { c.Err = err @@ -220,7 +223,8 @@ func updateBotActive(c *Context, w http.ResponseWriter, active bool) { } auditRec.Success() - auditRec.AddMeta("bot", bot) + auditRec.AddEventResultState(bot) + auditRec.AddEventObjectType("bot") if err := json.NewEncoder(w).Encode(bot); err != nil { mlog.Warn("Error while writing response", mlog.Err(err)) @@ -238,8 +242,8 @@ func assignBot(c *Context, w http.ResponseWriter, _ *http.Request) { auditRec := c.MakeAuditRecord("assignBot", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("bot_id", botUserId) - auditRec.AddMeta("assign_user_id", userId) + auditRec.AddEventParameter("id", botUserId) + auditRec.AddEventParameter("user_id", userId) if err := c.App.SessionHasPermissionToManageBot(*c.AppContext.Session(), botUserId); err != nil { c.Err = err @@ -260,7 +264,8 @@ func assignBot(c *Context, w http.ResponseWriter, _ *http.Request) { } auditRec.Success() - auditRec.AddMeta("bot", bot) + auditRec.AddEventResultState(bot) + auditRec.AddEventObjectType("bot") if err := json.NewEncoder(w).Encode(bot); err != nil { mlog.Warn("Error while writing response", mlog.Err(err)) @@ -290,9 +295,9 @@ func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("convertBotToUser", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("bot", bot) - auditRec.AddMeta("userPatch", userPatch) - auditRec.AddMeta("set_system_admin", systemAdmin) + auditRec.AddEventParameter("bot", bot) + auditRec.AddEventParameter("userPatch", userPatch) + auditRec.AddEventParameter("set_system_admin", systemAdmin) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { c.SetPermissionError(model.PermissionManageSystem) @@ -306,7 +311,8 @@ func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("convertedTo", user) + auditRec.AddEventResultState(user) + auditRec.AddEventObjectType("user") if err := json.NewEncoder(w).Encode(user); err != nil { mlog.Warn("Error while writing response", mlog.Err(err)) diff --git a/api4/channel.go b/api4/channel.go index 72abc6bc0e..c686bfd272 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -88,7 +88,7 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createChannel", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) + auditRec.AddEventParameter("channel", channel) if channel.Type == model.ChannelTypeOpen && !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), channel.TeamId, model.PermissionCreatePublicChannel) { c.SetPermissionError(model.PermissionCreatePublicChannel) @@ -107,7 +107,8 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("channel", sc) // overwrite meta + auditRec.AddEventResultState(sc) + auditRec.AddEventObjectType("channel") c.LogAudit("name=" + channel.Name) w.WriteHeader(http.StatusCreated) @@ -136,6 +137,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updateChannel", audit.Fail) + auditRec.AddEventParameter("channel", channel) defer c.LogAuditRec(auditRec) originalOldChannel, appErr := c.App.GetChannel(c.AppContext, channel.Id) @@ -145,7 +147,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) { } oldChannel := originalOldChannel.DeepCopy() - auditRec.AddMeta("channel", oldChannel) + auditRec.AddEventPriorState(oldChannel) switch oldChannel.Type { case model.ChannelTypeOpen: @@ -220,6 +222,8 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) { } } + auditRec.AddEventResultState(updatedChannel) + auditRec.AddEventObjectType("channel") auditRec.Success() c.LogAudit("name=" + channel.Name) @@ -249,8 +253,8 @@ func updateChannelPrivacy(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("updateChannelPrivacy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) - auditRec.AddMeta("new_type", privacy) + auditRec.AddEventParameter("props", props) + auditRec.AddEventPriorState(channel) if model.ChannelType(privacy) == model.ChannelTypeOpen && !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), c.Params.ChannelId, model.PermissionConvertPrivateChannelToPublic) { c.SetPermissionError(model.PermissionConvertPrivateChannelToPublic) @@ -272,7 +276,6 @@ func updateChannelPrivacy(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("user", user) channel.Type = model.ChannelType(privacy) @@ -282,6 +285,8 @@ func updateChannelPrivacy(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(updatedChannel) + auditRec.AddEventObjectType("channel") auditRec.Success() c.LogAudit("name=" + updatedChannel.Name) @@ -311,7 +316,8 @@ func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("patchChannel", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", oldChannel) + auditRec.AddEventParameter("channel", patch) + auditRec.AddEventPriorState(oldChannel) switch oldChannel.Type { case model.ChannelTypeOpen: @@ -357,9 +363,10 @@ func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(rchannel) + auditRec.AddEventObjectType("channel") auditRec.Success() c.LogAudit("") - auditRec.AddMeta("patch", rchannel) if err := json.NewEncoder(w).Encode(rchannel); err != nil { c.Logger.Warn("Error while writing response", mlog.Err(err)) @@ -381,7 +388,7 @@ func restoreChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("restoreChannel", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) + auditRec.AddEventPriorState(channel) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), teamId, model.PermissionManageTeam) { c.SetPermissionError(model.PermissionManageTeam) @@ -394,6 +401,8 @@ func restoreChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(channel) + auditRec.AddEventObjectType("channel") auditRec.Success() c.LogAudit("name=" + channel.Name) @@ -422,6 +431,7 @@ func createDirectChannel(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("createDirectChannel", audit.Fail) + auditRec.AddEventParameter("user_ids", userIds) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreateDirectChannel) { @@ -439,7 +449,7 @@ func createDirectChannel(c *Context, w http.ResponseWriter, r *http.Request) { otherUserId = userIds[1] } - auditRec.AddMeta("other_user_id", otherUserId) + auditRec.AddEventParameter("user_id", otherUserId) canSee, err := c.App.UserCanSeeOtherUser(c.AppContext.Session().UserId, otherUserId) if err != nil { @@ -458,8 +468,9 @@ func createDirectChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(sc) + auditRec.AddEventObjectType("channel") auditRec.Success() - auditRec.AddMeta("channel", sc) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(sc); err != nil { @@ -510,6 +521,7 @@ func createGroupChannel(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("createGroupChannel", audit.Fail) + auditRec.AddEventParameter("user_ids", userIds) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreateGroupChannel) { @@ -542,8 +554,9 @@ func createGroupChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(groupChannel) + auditRec.AddEventObjectType("channel") auditRec.Success() - auditRec.AddMeta("channel", groupChannel) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(groupChannel); err != nil { @@ -1211,8 +1224,9 @@ func deleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("deleteChannel", audit.Fail) + auditRec.AddEventParameter("id", c.Params.ChannelId) + auditRec.AddEventPriorState(channel) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channeld", channel) if channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup { c.Err = model.NewAppError("deleteChannel", "api.channel.delete_channel.type.invalid", nil, "", http.StatusBadRequest) @@ -1507,8 +1521,8 @@ func updateChannelMemberRoles(c *Context, w http.ResponseWriter, r *http.Request auditRec := c.MakeAuditRecord("updateChannelMemberRoles", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel_id", c.Params.ChannelId) - auditRec.AddMeta("roles", newRoles) + auditRec.AddEventParameter("props", props) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), c.Params.ChannelId, model.PermissionManageChannelRoles) { c.SetPermissionError(model.PermissionManageChannelRoles) @@ -1539,8 +1553,8 @@ func updateChannelMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.R auditRec := c.MakeAuditRecord("updateChannelMemberSchemeRoles", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel_id", c.Params.ChannelId) - auditRec.AddMeta("roles", schemeRoles) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) + auditRec.AddEventParameter("roles", schemeRoles) if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), c.Params.ChannelId, model.PermissionManageChannelRoles) { c.SetPermissionError(model.PermissionManageChannelRoles) @@ -1571,8 +1585,8 @@ func updateChannelMemberNotifyProps(c *Context, w http.ResponseWriter, r *http.R auditRec := c.MakeAuditRecord("updateChannelMemberNotifyProps", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel_id", c.Params.ChannelId) - auditRec.AddMeta("props", props) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) + auditRec.AddEventParameter("props", props) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { c.SetPermissionError(model.PermissionEditOtherUsers) @@ -1603,6 +1617,10 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec := c.MakeAuditRecord("addChannelMember", audit.Fail) + defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("props", props) + member := &model.ChannelMember{ ChannelId: c.Params.ChannelId, UserId: userId, @@ -1632,9 +1650,7 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec := c.MakeAuditRecord("addChannelMember", audit.Fail) - defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) + auditRec.AddEventParameter("channel_id", member.ChannelId) if channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup { c.Err = model.NewAppError("addUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusBadRequest) @@ -1719,6 +1735,8 @@ func addChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() + auditRec.AddEventResultState(cm) + auditRec.AddEventObjectType("channel_member") auditRec.AddMeta("add_user_id", cm.UserId) c.LogAudit("name=" + channel.Name + " user_id=" + cm.UserId) @@ -1748,8 +1766,8 @@ func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("removeChannelMember", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) - auditRec.AddMeta("remove_user_id", user.Id) + auditRec.AddEventParameter("channel_id", channel.Id) + auditRec.AddEventParameter("user_id", user.Id) if !(channel.Type == model.ChannelTypeOpen || channel.Type == model.ChannelTypePrivate) { c.Err = model.NewAppError("removeChannelMember", "api.channel.remove_channel_member.type.app_error", nil, "", http.StatusBadRequest) @@ -1799,7 +1817,7 @@ func updateChannelScheme(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("updateChannelScheme", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("new_scheme_id", *schemeID) + auditRec.AddEventParameter("scheme_id", *schemeID) if c.App.Channels().License() == nil { c.Err = model.NewAppError("Api4.UpdateChannelScheme", "api.channel.update_channel_scheme.license.error", nil, "", http.StatusNotImplemented) @@ -1828,17 +1846,19 @@ func updateChannelScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("channel", channel) - auditRec.AddMeta("old_scheme_id", channel.SchemeId) + auditRec.AddEventPriorState(channel) channel.SchemeId = &scheme.Id - _, err = c.App.UpdateChannelScheme(c.AppContext, channel) + updatedChannel, err := c.App.UpdateChannelScheme(c.AppContext, channel) if err != nil { c.Err = err return } + auditRec.AddEventResultState(updatedChannel) + auditRec.AddEventObjectType("channel") + auditRec.Success() ReturnStatusOK(w) @@ -2002,7 +2022,7 @@ func patchChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) c.Err = appErr return } - auditRec.AddMeta("patch", channelModerationsPatch) + auditRec.AddEventParameter("patch", channelModerationsPatch) b, marshalErr := json.Marshal(channelModerations) if marshalErr != nil { @@ -2047,7 +2067,11 @@ func moveChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("moveChannel", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel_id", channel.Id) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) + auditRec.AddEventParameter("props", props) + auditRec.AddEventPriorState(channel) + + // TODO check and verify if the below three things are parameters or prior state if any auditRec.AddMeta("channel_name", channel.Name) auditRec.AddMeta("team_id", team.Id) auditRec.AddMeta("team_name", team.Name) @@ -2088,6 +2112,9 @@ func moveChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(channel) + auditRec.AddEventObjectType("channel") + auditRec.Success() c.LogAudit("channel=" + channel.Name) c.LogAudit("team=" + team.Name) diff --git a/api4/channel_local.go b/api4/channel_local.go index 5784d63a3e..bb5286b44f 100644 --- a/api4/channel_local.go +++ b/api4/channel_local.go @@ -47,7 +47,7 @@ func localCreateChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("localCreateChannel", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) + auditRec.AddEventParameter("channel", channel) sc, appErr := c.App.CreateChannel(c.AppContext, channel, false) if appErr != nil { @@ -56,7 +56,8 @@ func localCreateChannel(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("channel", sc) // overwrite meta + auditRec.AddEventResultState(sc) + auditRec.AddEventObjectType("channel") c.LogAudit("name=" + channel.Name) w.WriteHeader(http.StatusCreated) @@ -86,8 +87,7 @@ func localUpdateChannelPrivacy(c *Context, w http.ResponseWriter, r *http.Reques auditRec := c.MakeAuditRecord("localUpdateChannelPrivacy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) - auditRec.AddMeta("new_type", privacy) + auditRec.AddEventParameter("props", props) if channel.Name == model.DefaultChannelName && model.ChannelType(privacy) == model.ChannelTypePrivate { c.Err = model.NewAppError("updateChannelPrivacy", "api.channel.update_channel_privacy.default_channel_error", nil, "", http.StatusBadRequest) @@ -101,6 +101,8 @@ func localUpdateChannelPrivacy(c *Context, w http.ResponseWriter, r *http.Reques return } + auditRec.AddEventResultState(channel) + auditRec.AddEventObjectType("channel") auditRec.Success() c.LogAudit("name=" + updatedChannel.Name) @@ -123,7 +125,7 @@ func localRestoreChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("localRestoreChannel", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) channel, err = c.App.RestoreChannel(c.AppContext, channel, "") if err != nil { @@ -131,6 +133,8 @@ func localRestoreChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(channel) + auditRec.AddEventObjectType("channel") auditRec.Success() c.LogAudit("name=" + channel.Name) @@ -182,6 +186,7 @@ func localAddChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("localAddChannelMember", audit.Fail) + auditRec.AddEventParameter("props", props) defer c.LogAuditRec(auditRec) auditRec.AddMeta("channel", channel) @@ -216,6 +221,8 @@ func localAddChannelMember(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() auditRec.AddMeta("add_user_id", cm.UserId) + auditRec.AddEventResultState(cm) + auditRec.AddEventObjectType("channel_member") c.LogAudit("name=" + channel.Name + " user_id=" + cm.UserId) w.WriteHeader(http.StatusCreated) @@ -254,8 +261,8 @@ func localRemoveChannelMember(c *Context, w http.ResponseWriter, r *http.Request auditRec := c.MakeAuditRecord("localRemoveChannelMember", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) - auditRec.AddMeta("remove_user_id", user.Id) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) + auditRec.AddEventParameter("remove_user_id", c.Params.UserId) if err = c.App.RemoveUserFromChannel(c.AppContext, c.Params.UserId, "", channel); err != nil { c.Err = err @@ -290,7 +297,7 @@ func localPatchChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("localPatchChannel", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel", channel) + auditRec.AddEventParameter("channel_patch", patch) channel.Patch(patch) rchannel, appErr := c.App.UpdateChannel(c.AppContext, channel) @@ -307,7 +314,8 @@ func localPatchChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() c.LogAudit("") - auditRec.AddMeta("patch", rchannel) + auditRec.AddEventResultState(rchannel) + auditRec.AddEventObjectType("channel") if err := json.NewEncoder(w).Encode(rchannel); err != nil { c.Logger.Warn("Error while writing response", mlog.Err(err)) @@ -347,6 +355,9 @@ func localMoveChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("localMoveChannel", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("props", props) + + // TODO do we need these? auditRec.AddMeta("channel_id", channel.Id) auditRec.AddMeta("channel_name", channel.Name) auditRec.AddMeta("team_id", team.Id) @@ -377,6 +388,8 @@ func localMoveChannel(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(channel) + auditRec.AddEventObjectType("channel") auditRec.Success() c.LogAudit("channel=" + channel.Name) c.LogAudit("team=" + team.Name) @@ -401,6 +414,7 @@ func localDeleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("localDeleteChannel", audit.Fail) defer c.LogAuditRec(auditRec) auditRec.AddMeta("channeld", channel) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) if channel.Type == model.ChannelTypeDirect || channel.Type == model.ChannelTypeGroup { c.Err = model.NewAppError("localDeleteChannel", "api.channel.delete_channel.type.invalid", nil, "", http.StatusBadRequest) @@ -418,6 +432,8 @@ func localDeleteChannel(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() + auditRec.AddEventResultState(channel) + auditRec.AddEventObjectType("channel") c.LogAudit("name=" + channel.Name) ReturnStatusOK(w) diff --git a/api4/command.go b/api4/command.go index c775fd805f..fa627b32d2 100644 --- a/api4/command.go +++ b/api4/command.go @@ -37,6 +37,7 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("createCommand", audit.Fail) + auditRec.AddEventParameter("command", cmd) defer c.LogAuditRec(auditRec) c.LogAudit("attempt") @@ -56,6 +57,8 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() c.LogAudit("success") auditRec.AddMeta("command", rcmd) + auditRec.AddEventResultState(rcmd) + auditRec.AddEventObjectType("command") w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rcmd); err != nil { @@ -76,6 +79,7 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updateCommand", audit.Fail) + auditRec.AddEventParameter("command", cmd) defer c.LogAuditRec(auditRec) c.LogAudit("attempt") @@ -112,6 +116,8 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(rcmd) + auditRec.AddEventObjectType("command") auditRec.Success() c.LogAudit("success") @@ -133,6 +139,7 @@ func moveCommand(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("moveCommand", audit.Fail) + auditRec.AddEventParameter("command_move_request", cmr) defer c.LogAuditRec(auditRec) c.LogAudit("attempt") @@ -169,6 +176,8 @@ func moveCommand(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(cmd) + auditRec.AddEventObjectType("command") auditRec.Success() c.LogAudit("success") @@ -182,6 +191,7 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("deleteCommand", audit.Fail) + auditRec.AddEventParameter("command_id", c.Params.CommandId) defer c.LogAuditRec(auditRec) c.LogAudit("attempt") @@ -212,6 +222,8 @@ func deleteCommand(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(cmd) + auditRec.AddEventObjectType("command") auditRec.Success() c.LogAudit("success") @@ -311,6 +323,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("executeCommand", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("command_args", commandArgs) auditRec.AddMeta("commandargs", commandArgs) // checks that user is a member of the specified channel, and that they have permission to use slash commands in it @@ -345,7 +358,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { commandArgs.SiteURL = c.GetSiteURLHeader() commandArgs.Session = *c.AppContext.Session() - auditRec.AddMeta("commandargs", commandArgs) // overwrite in case teamid changed + auditRec.AddMeta("commandargs", commandArgs) // overwrite in case teamid changed. TODO do we need to log this too? is the original commandArgs not enough response, err := c.App.ExecuteCommand(c.AppContext, &commandArgs) if err != nil { @@ -448,6 +461,7 @@ func regenCommandToken(c *Context, w http.ResponseWriter, r *http.Request) { return } auditRec.AddMeta("command", cmd) + auditRec.AddEventParameter("command_id", c.Params.CommandId) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), cmd.TeamId, model.PermissionManageSlashCommands) { c.LogAudit("fail - inappropriate permissions") diff --git a/api4/command_local.go b/api4/command_local.go index d14d6a10eb..cf22bb744a 100644 --- a/api4/command_local.go +++ b/api4/command_local.go @@ -30,6 +30,7 @@ func localCreateCommand(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("localCreateCommand", audit.Fail) + auditRec.AddEventParameter("command", cmd) defer c.LogAuditRec(auditRec) c.LogAudit("attempt") @@ -41,7 +42,8 @@ func localCreateCommand(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() c.LogAudit("success") - auditRec.AddMeta("command", rcmd) + auditRec.AddEventResultState(rcmd) + auditRec.AddEventObjectType("command") w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rcmd); err != nil { diff --git a/api4/compliance.go b/api4/compliance.go index 32d1380eea..f828a03c08 100644 --- a/api4/compliance.go +++ b/api4/compliance.go @@ -30,6 +30,7 @@ func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) } auditRec := c.MakeAuditRecord("createComplianceReport", audit.Fail) + auditRec.AddEventParameter("compliance", job) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreateComplianceExportJob) { @@ -46,6 +47,8 @@ func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) } auditRec.Success() + auditRec.AddEventResultState(rjob) + auditRec.AddEventObjectType("compliance") auditRec.AddMeta("compliance_id", rjob.Id) auditRec.AddMeta("compliance_desc", rjob.Desc) c.LogAudit("") @@ -91,6 +94,7 @@ func getComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventParameter("report_id", c.Params.ReportId) job, err := c.App.GetComplianceReport(c.Params.ReportId) if err != nil { c.Err = err @@ -114,7 +118,7 @@ func downloadComplianceReport(c *Context, w http.ResponseWriter, r *http.Request auditRec := c.MakeAuditRecord("downloadComplianceReport", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("compliance_id", c.Params.ReportId) + auditRec.AddEventParameter("compliance_id", c.Params.ReportId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionDownloadComplianceExportResult) { c.SetPermissionError(model.PermissionDownloadComplianceExportResult) @@ -126,8 +130,8 @@ func downloadComplianceReport(c *Context, w http.ResponseWriter, r *http.Request c.Err = err return } - auditRec.AddMeta("compliance_id", job.Id) - auditRec.AddMeta("compliance_desc", job.Desc) + auditRec.AddEventResultState(job) + auditRec.AddEventObjectType("compliance") reportBytes, err := c.App.GetComplianceFile(job) if err != nil { diff --git a/api4/config.go b/api4/config.go index 6412c06e43..e08cdccf55 100644 --- a/api4/config.go +++ b/api4/config.go @@ -115,6 +115,8 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updateConfig", audit.Fail) + + // auditRec.AddEventParameter("config", cfg) // TODO We can do this but do we want to? defer c.LogAuditRec(auditRec) cfg.SetDefaults() @@ -187,7 +189,7 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("updateConfig", "api.config.update_config.diff.app_error", nil, diffErr.Error(), http.StatusInternalServerError) return } - auditRec.AddMeta("diff", diffs.Sanitize()) + auditRec.AddEventPriorState(&diffs) newCfg.Sanitize() @@ -201,6 +203,8 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { return } + //auditRec.AddEventResultState(cfg) // TODO we can do this too but do we want to? the config object is huge + auditRec.AddEventObjectType("config") auditRec.Success() c.LogAudit("updateConfig") @@ -337,7 +341,8 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("patchConfig", "api.config.patch_config.diff.app_error", nil, diffErr.Error(), http.StatusInternalServerError) return } - auditRec.AddMeta("diff", diffs.Sanitize()) + + auditRec.AddEventPriorState(&diffs) newCfg.Sanitize() diff --git a/api4/config_local.go b/api4/config_local.go index a6e4f0f683..b120e93bd7 100644 --- a/api4/config_local.go +++ b/api4/config_local.go @@ -73,7 +73,7 @@ func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("updateConfig", "api.config.update_config.diff.app_error", nil, diffErr.Error(), http.StatusInternalServerError) return } - auditRec.AddMeta("diff", diffs.Sanitize()) + auditRec.AddEventPriorState(&diffs) newCfg.Sanitize() @@ -131,7 +131,7 @@ func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("patchConfig", "api.config.patch_config.diff.app_error", nil, diffErr.Error(), http.StatusInternalServerError) return } - auditRec.AddMeta("diff", diffs.Sanitize()) + auditRec.AddEventPriorState(&diffs) auditRec.Success() diff --git a/api4/config_test.go b/api4/config_test.go index 0609851dc5..c200e306fc 100644 --- a/api4/config_test.go +++ b/api4/config_test.go @@ -574,8 +574,8 @@ func TestUpdateConfigDiffInAuditRecord(t *testing.T) { require.NotEmpty(t, data) require.Contains(t, string(data), - fmt.Sprintf(`"diff":[{"path":"ServiceSettings.ReadTimeout","base_val":%d,"actual_val":%d}]`, - timeoutVal, timeoutVal+1)) + fmt.Sprintf(`"config_diffs":[{"actual_val":%d,"base_val":%d,"path":"ServiceSettings.ReadTimeout"}]`, + timeoutVal+1, timeoutVal)) } func TestGetEnvironmentConfig(t *testing.T) { diff --git a/api4/data_retention.go b/api4/data_retention.go index 10cc28b0a2..0749c1d5a5 100644 --- a/api4/data_retention.go +++ b/api4/data_retention.go @@ -116,7 +116,7 @@ func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("createPolicy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("policy", policy) + auditRec.AddEventParameter("policy", policy) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) { c.SetPermissionError(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) @@ -129,7 +129,8 @@ func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("policy", newPolicy) // overwrite meta + auditRec.AddEventResultState(newPolicy) + auditRec.AddEventObjectType("policy") js, jsonErr := json.Marshal(newPolicy) if jsonErr != nil { c.Err = model.NewAppError("createPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) @@ -151,7 +152,7 @@ func patchPolicy(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("patchPolicy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("patch", patch) + auditRec.AddEventParameter("patch", patch) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) { c.SetPermissionError(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) @@ -163,6 +164,10 @@ func patchPolicy(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } + + auditRec.AddEventResultState(policy) + auditRec.AddEventObjectType("retention_policy") + js, jsonErr := json.Marshal(policy) if jsonErr != nil { c.Err = model.NewAppError("patchPolicy", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) @@ -178,7 +183,7 @@ func deletePolicy(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("deletePolicy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("policy_id", policyId) + auditRec.AddEventParameter("policy_id", policyId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) { c.SetPermissionError(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) return @@ -261,8 +266,8 @@ func addTeamsToPolicy(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("addTeamsToPolicy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("policy_id", policyId) - auditRec.AddMeta("team_ids", teamIDs) + auditRec.AddEventParameter("policy_id", policyId) + auditRec.AddEventParameter("team_ids", teamIDs) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) { c.SetPermissionError(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) return @@ -289,8 +294,8 @@ func removeTeamsFromPolicy(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("removeTeamsFromPolicy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("policy_id", policyId) - auditRec.AddMeta("team_ids", teamIDs) + auditRec.AddEventParameter("policy_id", policyId) + auditRec.AddEventParameter("team_ids", teamIDs) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) { c.SetPermissionError(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) @@ -382,8 +387,8 @@ func addChannelsToPolicy(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("addChannelsToPolicy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("policy_id", policyId) - auditRec.AddMeta("channel_ids", channelIDs) + auditRec.AddEventParameter("policy_id", policyId) + auditRec.AddEventParameter("channel_ids", channelIDs) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) { c.SetPermissionError(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) @@ -411,8 +416,8 @@ func removeChannelsFromPolicy(c *Context, w http.ResponseWriter, r *http.Request } auditRec := c.MakeAuditRecord("removeChannelsFromPolicy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("policy_id", policyId) - auditRec.AddMeta("channel_ids", channelIDs) + auditRec.AddEventParameter("policy_id", policyId) + auditRec.AddEventParameter("channel_ids", channelIDs) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) { c.SetPermissionError(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy) diff --git a/api4/emoji.go b/api4/emoji.go index ac5e849cd7..c7d15962c8 100644 --- a/api4/emoji.go +++ b/api4/emoji.go @@ -88,7 +88,8 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("emoji", emoji) + auditRec.AddEventResultState(&emoji) + auditRec.AddEventObjectType("emoji") newEmoji, err := c.App.CreateEmoji(c.AppContext.Session().UserId, &emoji, m) if err != nil { @@ -136,11 +137,12 @@ func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) { emoji, err := c.App.GetEmoji(c.Params.EmojiId) if err != nil { - auditRec.AddMeta("emoji_id", c.Params.EmojiId) + auditRec.AddEventParameter("emoji_id", c.Params.EmojiId) c.Err = err return } - auditRec.AddMeta("emoji", emoji) + auditRec.AddEventPriorState(emoji) + auditRec.AddEventObjectType("emoji") // Allow any user with DELETE_EMOJIS permission at Team level to delete emojis at system level memberships, err := c.App.GetTeamMembersForUser(c.AppContext.Session().UserId, "", true) diff --git a/api4/export.go b/api4/export.go index 823a8f4b27..36248746fe 100644 --- a/api4/export.go +++ b/api4/export.go @@ -43,7 +43,7 @@ func listExports(c *Context, w http.ResponseWriter, r *http.Request) { func deleteExport(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("deleteExport", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("export_name", c.Params.ExportName) + auditRec.AddEventParameter("export_name", c.Params.ExportName) if !c.IsSystemAdmin() { c.SetPermissionError(model.PermissionManageSystem) diff --git a/api4/file.go b/api4/file.go index 21c7cd556b..6dc5ac04b0 100644 --- a/api4/file.go +++ b/api4/file.go @@ -165,7 +165,7 @@ func uploadFileSimple(c *Context, r *http.Request, timestamp time.Time) *model.F auditRec := c.MakeAuditRecord("uploadFileSimple", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel_id", c.Params.ChannelId) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), c.Params.ChannelId, model.PermissionUploadFile) { c.SetPermissionError(model.PermissionUploadFile) @@ -173,7 +173,7 @@ func uploadFileSimple(c *Context, r *http.Request, timestamp time.Time) *model.F } clientId := r.Form.Get("client_id") - auditRec.AddMeta("client_id", clientId) + auditRec.AddEventParameter("client_id", clientId) info, appErr := c.App.UploadFileX(c.AppContext, c.Params.ChannelId, c.Params.Filename, r.Body, app.UploadFileSetTeamId(FileTeamId), @@ -335,8 +335,8 @@ NextPart: } auditRec := c.MakeAuditRecord("uploadFileMultipart", audit.Fail) - auditRec.AddMeta("channel_id", c.Params.ChannelId) - auditRec.AddMeta("client_id", clientId) + auditRec.AddEventParameter("channel_id", c.Params.ChannelId) + auditRec.AddEventParameter("client_id", clientId) info, appErr := c.App.UploadFileX(c.AppContext, c.Params.ChannelId, filename, part, app.UploadFileSetTeamId(FileTeamId), @@ -438,8 +438,8 @@ func uploadFileMultipartLegacy(c *Context, mr *multipart.Reader, auditRec := c.MakeAuditRecord("uploadFileMultipartLegacy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("channel_id", channelId) - auditRec.AddMeta("client_id", clientId) + auditRec.AddEventParameter("channel_id", channelId) + auditRec.AddEventParameter("client_id", clientId) info, appErr := c.App.UploadFileX(c.AppContext, c.Params.ChannelId, fileHeader.Filename, f, app.UploadFileSetTeamId(FileTeamId), @@ -477,7 +477,7 @@ func getFile(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("getFile", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("force_download", forceDownload) + auditRec.AddEventParameter("force_download", forceDownload) info, err := c.App.GetFileInfo(c.Params.FileId) if err != nil { diff --git a/api4/group.go b/api4/group.go index 049cfb1ef8..cf0046d213 100644 --- a/api4/group.go +++ b/api4/group.go @@ -164,7 +164,7 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createGroup", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("group", group) + auditRec.AddEventParameter("group", group) newGroup, err := c.App.CreateGroupWithUserIds(group) if err != nil { @@ -172,7 +172,8 @@ func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("group", newGroup) + auditRec.AddEventResultState(newGroup) + auditRec.AddEventObjectType("group") js, jsonErr := json.Marshal(newGroup) if jsonErr != nil { c.Err = model.NewAppError("createGroup", "api.marshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) @@ -225,7 +226,7 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("patchGroup", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("group", group) + auditRec.AddEventParameter("group", group) if groupPatch.AllowReference != nil && *groupPatch.AllowReference { if groupPatch.Name == nil { @@ -261,7 +262,8 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("patch", group) + auditRec.AddEventResultState(group) + auditRec.AddEventObjectType("group") b, marshalErr := json.Marshal(group) if marshalErr != nil { @@ -310,9 +312,9 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("linkGroupSyncable", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("group_id", c.Params.GroupId) - auditRec.AddMeta("syncable_id", syncableID) - auditRec.AddMeta("syncable_type", syncableType) + auditRec.AddEventParameter("group_id", c.Params.GroupId) + auditRec.AddEventParameter("syncable_id", syncableID) + auditRec.AddEventParameter("syncable_type", syncableType) var patch *model.GroupSyncablePatch err = json.Unmarshal(body, &patch) @@ -321,6 +323,8 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventParameter("patch", patch) + if !*c.App.Channels().License().Features.LDAPGroups { c.Err = model.NewAppError("Api4.createGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) return @@ -344,6 +348,9 @@ func linkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(groupSyncable) + auditRec.AddEventObjectType("group_syncable") + c.App.Srv().Go(func() { c.App.SyncRolesAndMembership(c.AppContext, syncableID, syncableType, false) }) @@ -465,9 +472,9 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("patchGroupSyncable", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("group_id", c.Params.GroupId) - auditRec.AddMeta("old_syncable_id", syncableID) - auditRec.AddMeta("old_syncable_type", syncableType) + auditRec.AddEventParameter("group_id", c.Params.GroupId) + auditRec.AddEventParameter("old_syncable_id", syncableID) + auditRec.AddEventParameter("old_syncable_type", syncableType) var patch *model.GroupSyncablePatch err = json.Unmarshal(body, &patch) @@ -476,6 +483,8 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventParameter("patch", patch) + if !*c.App.Channels().License().Features.LDAPGroups { c.Err = model.NewAppError("Api4.patchGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) @@ -502,8 +511,8 @@ func patchGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("new_syncable_id", groupSyncable.SyncableId) - auditRec.AddMeta("new_syncable_type", groupSyncable.Type) + auditRec.AddEventResultState(groupSyncable) + auditRec.AddEventObjectType("group_syncable") c.App.Srv().Go(func() { c.App.SyncRolesAndMembership(c.AppContext, syncableID, syncableType, false) @@ -538,9 +547,9 @@ func unlinkGroupSyncable(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("unlinkGroupSyncable", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("group_id", c.Params.GroupId) - auditRec.AddMeta("syncable_id", syncableID) - auditRec.AddMeta("syncable_type", syncableType) + auditRec.AddEventParameter("group_id", c.Params.GroupId) + auditRec.AddEventParameter("syncable_id", syncableID) + auditRec.AddEventParameter("syncable_type", syncableType) if !*c.App.Channels().License().Features.LDAPGroups { c.Err = model.NewAppError("Api4.unlinkGroupSyncable", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) @@ -978,7 +987,7 @@ func deleteGroup(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("deleteGroup", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("group_id", c.Params.GroupId) + auditRec.AddEventParameter("group_id", c.Params.GroupId) _, err = c.App.DeleteGroup(c.Params.GroupId) if err != nil { @@ -1027,7 +1036,7 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("addGroupMembers", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("addGroupMembers", newMembers) + auditRec.AddEventParameter("addGroupMembers", newMembers) members, err := c.App.UpsertGroupMembers(c.Params.GroupId, newMembers.UserIds) if err != nil { @@ -1080,7 +1089,7 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("deleteGroupMembers", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("deleteGroupMembers", deleteBody) + auditRec.AddEventParameter("deleteGroupMembers", deleteBody) members, err := c.App.DeleteGroupMembers(c.Params.GroupId, deleteBody.UserIds) if err != nil { diff --git a/api4/job.go b/api4/job.go index 5cac87a950..6e2ec56f82 100644 --- a/api4/job.go +++ b/api4/job.go @@ -112,7 +112,7 @@ func createJob(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createJob", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("job", job) + auditRec.AddEventParameter("job", job) hasPermission, permissionRequired := c.App.SessionHasPermissionToCreateJob(*c.AppContext.Session(), &job) if permissionRequired == nil { @@ -132,7 +132,8 @@ func createJob(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("job", rjob) // overwrite meta + auditRec.AddEventResultState(rjob) + auditRec.AddEventObjectType("job") w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rjob); err != nil { @@ -213,7 +214,7 @@ func cancelJob(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("cancelJob", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("job_id", c.Params.JobId) + auditRec.AddEventParameter("job_id", c.Params.JobId) job, err := c.App.GetJob(c.Params.JobId) if err != nil { @@ -221,6 +222,9 @@ func cancelJob(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventPriorState(job) + auditRec.AddEventObjectType("job") + // if permission to create, permission to cancel, same permission hasPermission, permissionRequired := c.App.SessionHasPermissionToCreateJob(*c.AppContext.Session(), job) if permissionRequired == nil { diff --git a/api4/ldap.go b/api4/ldap.go index 646689b976..4ee9c8cc1f 100644 --- a/api4/ldap.go +++ b/api4/ldap.go @@ -151,7 +151,7 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("linkLdapGroup", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("remote_id", c.Params.RemoteId) + auditRec.AddEventParameter("remote_id", c.Params.RemoteId) if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.LDAPGroups { c.Err = model.NewAppError("Api4.linkLdapGroup", "api.ldap_groups.license_error", nil, "", http.StatusNotImplemented) @@ -163,6 +163,7 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } + auditRec.AddMeta("ldap_group", ldapGroup) if ldapGroup == nil { @@ -203,6 +204,8 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } + auditRec.AddEventResultState(newOrUpdatedGroup) + auditRec.AddEventObjectType("group") } status = http.StatusOK } else { @@ -220,6 +223,8 @@ func linkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } + auditRec.AddEventResultState(newOrUpdatedGroup) + auditRec.AddEventObjectType("group") status = http.StatusCreated } @@ -243,7 +248,7 @@ func unlinkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("unlinkLdapGroup", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("remote_id", c.Params.RemoteId) + auditRec.AddEventParameter("remote_id", c.Params.RemoteId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteUserManagementGroups) { c.SetPermissionError(model.PermissionSysconsoleWriteUserManagementGroups) @@ -260,14 +265,16 @@ func unlinkLdapGroup(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("group", group) + auditRec.AddEventPriorState(group) + auditRec.AddEventObjectType("group") if group.DeleteAt == 0 { - _, err = c.App.DeleteGroup(group.Id) + deletedGroup, err := c.App.DeleteGroup(group.Id) if err != nil { c.Err = err return } + auditRec.AddEventResultState(deletedGroup) } auditRec.Success() @@ -283,6 +290,7 @@ func migrateIdLdap(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("idMigrateLdap", audit.Fail) + auditRec.AddEventParameter("props", props) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { @@ -338,7 +346,7 @@ func addLdapPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request auditRec := c.MakeAuditRecord("addLdapPublicCertificate", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("filename", fileData.Filename) + auditRec.AddEventParameter("filename", fileData.Filename) if err := c.App.AddLdapPublicCertificate(fileData); err != nil { c.Err = err @@ -362,7 +370,7 @@ func addLdapPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Reques auditRec := c.MakeAuditRecord("addLdapPrivateCertificate", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("filename", fileData.Filename) + auditRec.AddEventParameter("filename", fileData.Filename) if err := c.App.AddLdapPrivateCertificate(fileData); err != nil { c.Err = err diff --git a/api4/license.go b/api4/license.go index f6ad9efd19..f4b0d079f0 100644 --- a/api4/license.go +++ b/api4/license.go @@ -86,7 +86,7 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) { } fileData := fileArray[0] - auditRec.AddMeta("filename", fileData.Filename) + auditRec.AddEventParameter("filename", fileData.Filename) file, err := fileData.Open() if err != nil { diff --git a/api4/license_local.go b/api4/license_local.go index 1f61aaed5b..7dbb4e51f5 100644 --- a/api4/license_local.go +++ b/api4/license_local.go @@ -44,7 +44,7 @@ func localAddLicense(c *Context, w http.ResponseWriter, r *http.Request) { } fileData := fileArray[0] - auditRec.AddMeta("filename", fileData.Filename) + auditRec.AddEventParameter("filename", fileData.Filename) file, err := fileData.Open() if err != nil { diff --git a/api4/oauth.go b/api4/oauth.go index 78194a3256..2cb4c6cc26 100644 --- a/api4/oauth.go +++ b/api4/oauth.go @@ -32,6 +32,8 @@ func createOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("createOAuthApp", audit.Fail) + auditRec.AddEventParameter("oauth_app", oauthApp) + defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOAuth) { @@ -52,7 +54,8 @@ func createOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("oauth_app", rapp) + auditRec.AddEventResultState(rapp) + auditRec.AddEventObjectType("oauth_app") c.LogAudit("client_id=" + rapp.Id) w.WriteHeader(http.StatusCreated) @@ -69,7 +72,7 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("updateOAuthApp", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("oauth_app_id", c.Params.AppId) + auditRec.AddEventParameter("oauth_app_id", c.Params.AppId) c.LogAudit("attempt") if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOAuth) { @@ -82,6 +85,7 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { c.SetInvalidParam("oauth_app") return } + auditRec.AddEventParameter("oauth_app", oauthApp) // The app being updated in the payload must be the same one as indicated in the URL. if oauthApp.Id != c.Params.AppId { @@ -94,7 +98,7 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("oauth_app", oldOAuthApp) + auditRec.AddEventPriorState(oldOAuthApp) if c.AppContext.Session().UserId != oldOAuthApp.CreatorId && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystemWideOAuth) { c.SetPermissionError(model.PermissionManageSystemWideOAuth) @@ -111,8 +115,9 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(updatedOAuthApp) + auditRec.AddEventObjectType("oauth_app") auditRec.Success() - auditRec.AddMeta("update", updatedOAuthApp) c.LogAudit("success") if err := json.NewEncoder(w).Encode(updatedOAuthApp); err != nil { @@ -203,7 +208,7 @@ func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("deleteOAuthApp", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("oauth_app_id", c.Params.AppId) + auditRec.AddEventParameter("oauth_app_id", c.Params.AppId) c.LogAudit("attempt") if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOAuth) { @@ -216,7 +221,8 @@ func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("oauth_app", oauthApp) + auditRec.AddEventPriorState(oauthApp) + auditRec.AddEventObjectType("oauth_app") if c.AppContext.Session().UserId != oauthApp.CreatorId && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystemWideOAuth) { c.SetPermissionError(model.PermissionManageSystemWideOAuth) @@ -243,7 +249,7 @@ func regenerateOAuthAppSecret(c *Context, w http.ResponseWriter, r *http.Request auditRec := c.MakeAuditRecord("regenerateOAuthAppSecret", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("oauth_app_id", c.Params.AppId) + auditRec.AddEventParameter("oauth_app_id", c.Params.AppId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageOAuth) { c.SetPermissionError(model.PermissionManageOAuth) @@ -255,7 +261,8 @@ func regenerateOAuthAppSecret(c *Context, w http.ResponseWriter, r *http.Request c.Err = err return } - auditRec.AddMeta("oauth_app", oauthApp) + auditRec.AddEventPriorState(oauthApp) + auditRec.AddEventObjectType("oauth_app") if oauthApp.CreatorId != c.AppContext.Session().UserId && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystemWideOAuth) { c.SetPermissionError(model.PermissionManageSystemWideOAuth) @@ -268,6 +275,7 @@ func regenerateOAuthAppSecret(c *Context, w http.ResponseWriter, r *http.Request return } + auditRec.AddEventResultState(oauthApp) auditRec.Success() c.LogAudit("success") diff --git a/api4/plugin.go b/api4/plugin.go index 13bed46757..43a744a070 100644 --- a/api4/plugin.go +++ b/api4/plugin.go @@ -77,7 +77,7 @@ func uploadPlugin(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("uploadPlugin", "api.plugin.upload.array.app_error", nil, "", http.StatusBadRequest) return } - auditRec.AddMeta("filename", pluginArray[0].Filename) + auditRec.AddEventParameter("filename", pluginArray[0].Filename) file, err := pluginArray[0].Open() if err != nil { @@ -113,7 +113,7 @@ func installPluginFromURL(c *Context, w http.ResponseWriter, r *http.Request) { force, _ := strconv.ParseBool(r.URL.Query().Get("force")) downloadURL := r.URL.Query().Get("plugin_download_url") - auditRec.AddMeta("url", downloadURL) + auditRec.AddEventParameter("url", downloadURL) pluginFileBytes, err := c.App.DownloadFromURL(downloadURL) if err != nil { @@ -149,7 +149,7 @@ func installMarketplacePlugin(c *Context, w http.ResponseWriter, r *http.Request c.Err = model.NewAppError("installMarketplacePlugin", "app.plugin.marketplace_plugin_request.app_error", nil, err.Error(), http.StatusNotImplemented) return } - auditRec.AddMeta("plugin_id", pluginRequest.Id) + auditRec.AddEventParameter("plugin_id", pluginRequest.Id) // Always install the latest compatible version // https://mattermost.atlassian.net/browse/MM-41981 @@ -228,7 +228,7 @@ func removePlugin(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("removePlugin", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("plugin_id", c.Params.PluginId) + auditRec.AddEventParameter("plugin_id", c.Params.PluginId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWritePlugins) { c.SetPermissionError(model.PermissionSysconsoleWritePlugins) @@ -326,7 +326,7 @@ func enablePlugin(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("enablePlugin", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("plugin_id", c.Params.PluginId) + auditRec.AddEventParameter("plugin_id", c.Params.PluginId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWritePlugins) { c.SetPermissionError(model.PermissionSysconsoleWritePlugins) @@ -355,7 +355,7 @@ func disablePlugin(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("disablePlugin", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("plugin_id", c.Params.PluginId) + auditRec.AddEventParameter("plugin_id", c.Params.PluginId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWritePlugins) { c.SetPermissionError(model.PermissionSysconsoleWritePlugins) diff --git a/api4/post.go b/api4/post.go index 6698e8d924..b5c33488fa 100644 --- a/api4/post.go +++ b/api4/post.go @@ -52,7 +52,7 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createPost", audit.Fail) defer c.LogAuditRecWithLevel(auditRec, app.LevelContent) - auditRec.AddMeta("post", &post) + auditRec.AddEventParameter("post", &post) hasPermission := false if c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), post.ChannelId, model.PermissionCreatePost) { @@ -90,7 +90,8 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) { return } auditRec.Success() - auditRec.AddMeta("post", rp) // overwrite meta + auditRec.AddEventResultState(rp) + auditRec.AddEventObjectType("post") if setOnlineBool { c.App.SetStatusOnline(c.AppContext.Session().UserId, false) @@ -485,14 +486,15 @@ func deletePost(c *Context, w http.ResponseWriter, _ *http.Request) { auditRec := c.MakeAuditRecord("deletePost", audit.Fail) defer c.LogAuditRecWithLevel(auditRec, app.LevelContent) - auditRec.AddMeta("post_id", c.Params.PostId) + auditRec.AddEventParameter("post_id", c.Params.PostId) post, err := c.App.GetSinglePost(c.Params.PostId, false) if err != nil { c.SetPermissionError(model.PermissionDeletePost) return } - auditRec.AddMeta("post", post) + auditRec.AddEventPriorState(post) + auditRec.AddEventObjectType("post") if c.AppContext.Session().UserId == post.UserId { if !c.App.SessionHasPermissionToChannel(c.AppContext, *c.AppContext.Session(), post.ChannelId, model.PermissionDeletePost) { @@ -711,6 +713,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updatePost", audit.Fail) + auditRec.AddEventParameter("post", post.Auditable()) defer c.LogAuditRecWithLevel(auditRec, app.LevelContent) // The post being updated in the payload must be the same one as indicated in the URL. @@ -729,7 +732,8 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) { c.SetPermissionError(model.PermissionEditPost) return } - auditRec.AddMeta("post", originalPost) + auditRec.AddEventPriorState(originalPost) + auditRec.AddEventObjectType("post") // Updating the file_ids of a post is not a supported operation and will be ignored post.FileIds = originalPost.FileIds @@ -750,7 +754,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("update", rpost) + auditRec.AddEventResultState(rpost) if err := rpost.EncodeJSON(w); err != nil { mlog.Warn("Error while writing response", mlog.Err(err)) @@ -770,6 +774,7 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("patchPost", audit.Fail) + auditRec.AddEventParameter("patch", post) defer c.LogAuditRecWithLevel(auditRec, app.LevelContent) // Updating the file_ids of a post is not a supported operation and will be ignored @@ -780,7 +785,8 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) { c.SetPermissionError(model.PermissionEditPost) return } - auditRec.AddMeta("post", originalPost) + auditRec.AddEventPriorState(originalPost) + auditRec.AddEventObjectType("post") var permission *model.Permission if c.AppContext.Session().UserId == originalPost.UserId { @@ -801,7 +807,7 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("patch", patchedPost) + auditRec.AddEventResultState(patchedPost) if err := patchedPost.EncodeJSON(w); err != nil { mlog.Warn("Error while writing response", mlog.Err(err)) @@ -843,6 +849,7 @@ func saveIsPinnedPost(c *Context, w http.ResponseWriter, isPinned bool) { } auditRec := c.MakeAuditRecord("saveIsPinnedPost", audit.Fail) + auditRec.AddEventParameter("post_id", c.Params.PostId) defer c.LogAuditRecWithLevel(auditRec, app.LevelContent) if !c.App.SessionHasPermissionToChannelByPost(*c.AppContext.Session(), c.Params.PostId, model.PermissionReadChannel) { @@ -855,7 +862,8 @@ func saveIsPinnedPost(c *Context, w http.ResponseWriter, isPinned bool) { c.Err = err return } - auditRec.AddMeta("post", post) + auditRec.AddEventPriorState(post) + auditRec.AddEventObjectType("post") patch := &model.PostPatch{} patch.IsPinned = model.NewBool(isPinned) @@ -865,7 +873,7 @@ func saveIsPinnedPost(c *Context, w http.ResponseWriter, isPinned bool) { c.Err = err return } - auditRec.AddMeta("patch", patchedPost) + auditRec.AddEventResultState(patchedPost) auditRec.Success() ReturnStatusOK(w) diff --git a/api4/remote_cluster.go b/api4/remote_cluster.go index 62565a20a7..f05889b60f 100644 --- a/api4/remote_cluster.go +++ b/api4/remote_cluster.go @@ -89,6 +89,7 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque } auditRec := c.MakeAuditRecord("remoteClusterAcceptMessage", audit.Fail) + auditRec.AddEventParameter("remote_cluster_frame", frame) defer c.LogAuditRec(auditRec) remoteId := c.GetRemoteID(r) @@ -134,6 +135,7 @@ func remoteClusterConfirmInvite(c *Context, w http.ResponseWriter, r *http.Reque } auditRec := c.MakeAuditRecord("remoteClusterAcceptInvite", audit.Fail) + auditRec.AddEventParameter("remote_cluster_frame", frame) defer c.LogAuditRec(auditRec) remoteId := c.GetRemoteID(r) @@ -187,7 +189,7 @@ func uploadRemoteData(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("uploadRemoteData", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("upload_id", c.Params.UploadId) + auditRec.AddEventParameter("upload_id", c.Params.UploadId) us, err := c.App.GetUploadSession(c.Params.UploadId) if err != nil { @@ -257,7 +259,7 @@ func remoteSetProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("remoteUploadProfileImage", audit.Fail) defer c.LogAuditRec(auditRec) if imageArray[0] != nil { - auditRec.AddMeta("filename", imageArray[0].Filename) + auditRec.AddEventParameter("filename", imageArray[0].Filename) } user, err := c.App.GetUser(c.Params.UserId) diff --git a/api4/role.go b/api4/role.go index 523725642e..c9ebc5577d 100644 --- a/api4/role.go +++ b/api4/role.go @@ -122,6 +122,7 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("patchRole", audit.Fail) + auditRec.AddEventParameter("role_patch", patch) defer c.LogAuditRec(auditRec) oldRole, err := c.App.GetRole(c.Params.RoleId) @@ -129,7 +130,8 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("role", oldRole) + auditRec.AddEventPriorState(oldRole) + auditRec.AddEventObjectType("role") // manage_system permission is required to patch system_admin requiredPermission := model.PermissionSysconsoleWriteUserManagementPermissions @@ -207,8 +209,8 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(role) auditRec.Success() - auditRec.AddMeta("patch", role) c.LogAudit("") if err := json.NewEncoder(w).Encode(role); err != nil { diff --git a/api4/saml.go b/api4/saml.go index 03345a1516..9305550c79 100644 --- a/api4/saml.go +++ b/api4/saml.go @@ -83,7 +83,7 @@ func addSamlPublicCertificate(c *Context, w http.ResponseWriter, r *http.Request auditRec := c.MakeAuditRecord("addSamlPublicCertificate", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("filename", fileData.Filename) + auditRec.AddEventParameter("filename", fileData.Filename) if err := c.App.AddSamlPublicCertificate(fileData); err != nil { c.Err = err @@ -107,7 +107,7 @@ func addSamlPrivateCertificate(c *Context, w http.ResponseWriter, r *http.Reques auditRec := c.MakeAuditRecord("addSamlPrivateCertificate", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("filename", fileData.Filename) + auditRec.AddEventParameter("filename", fileData.Filename) if err := c.App.AddSamlPrivateCertificate(fileData); err != nil { c.Err = err @@ -155,7 +155,7 @@ func addSamlIdpCertificate(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("filename", fileData.Filename) + auditRec.AddEventParameter("filename", fileData.Filename) if err := c.App.AddSamlIdpCertificate(fileData); err != nil { c.Err = err diff --git a/api4/scheme.go b/api4/scheme.go index 468e65d1b3..210b83fbe1 100644 --- a/api4/scheme.go +++ b/api4/scheme.go @@ -31,7 +31,7 @@ func createScheme(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createScheme", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("scheme", scheme) + auditRec.AddEventParameter("scheme", scheme) if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.CustomPermissionsSchemes { c.Err = model.NewAppError("Api4.CreateScheme", "api.scheme.create_scheme.license.error", nil, "", http.StatusNotImplemented) @@ -50,7 +50,8 @@ func createScheme(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("scheme", returnedScheme) // overwrite meta + auditRec.AddEventResultState(returnedScheme) + auditRec.AddEventObjectType("scheme") w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(returnedScheme); err != nil { @@ -188,6 +189,7 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("patchScheme", audit.Fail) + auditRec.AddEventParameter("scheme_patch", patch) defer c.LogAuditRec(auditRec) if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.CustomPermissionsSchemes { @@ -195,12 +197,15 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventParameter("scheme_id", c.Params.SchemeId) + scheme, err := c.App.GetScheme(c.Params.SchemeId) if err != nil { c.Err = err return } - auditRec.AddMeta("scheme", scheme) + auditRec.AddEventPriorState(scheme) + auditRec.AddEventObjectType("scheme") if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionSysconsoleWriteUserManagementPermissions) { c.SetPermissionError(model.PermissionSysconsoleWriteUserManagementPermissions) @@ -212,7 +217,7 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("patch", scheme) + auditRec.AddEventResultState(scheme) auditRec.Success() c.LogAudit("") @@ -229,6 +234,7 @@ func deleteScheme(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("deleteScheme", audit.Fail) + auditRec.AddEventParameter("scheme_id", c.Params.SchemeId) defer c.LogAuditRec(auditRec) if c.App.Channels().License() == nil || !*c.App.Channels().License().Features.CustomPermissionsSchemes { @@ -247,8 +253,9 @@ func deleteScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(scheme) + auditRec.AddEventObjectType("scheme") auditRec.Success() - auditRec.AddMeta("scheme", scheme) ReturnStatusOK(w) } diff --git a/api4/system.go b/api4/system.go index 713b266d5b..09b765d8e7 100644 --- a/api4/system.go +++ b/api4/system.go @@ -268,8 +268,8 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("page", c.Params.Page) - auditRec.AddMeta("audits_per_page", c.Params.LogsPerPage) + auditRec.AddEventParameter("page", c.Params.Page) + auditRec.AddEventParameter("audits_per_page", c.Params.LogsPerPage) if err := json.NewEncoder(w).Encode(audits); err != nil { mlog.Warn("Error while writing response", mlog.Err(err)) @@ -342,8 +342,8 @@ func getLogs(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("page", c.Params.Page) - auditRec.AddMeta("logs_per_page", c.Params.LogsPerPage) + auditRec.AddEventParameter("page", c.Params.Page) + auditRec.AddEventParameter("logs_per_page", c.Params.LogsPerPage) w.Write([]byte(model.ArrayToJSON(lines))) } @@ -620,7 +620,7 @@ func setServerBusy(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("setServerBusy", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("seconds", i) + auditRec.AddEventParameter("seconds", i) c.App.Srv().Busy.Set(time.Second * time.Duration(i)) mlog.Warn("server busy state activated - non-critical services disabled", mlog.Int64("seconds", i)) @@ -935,7 +935,8 @@ func completeOnboarding(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("completeOnboarding", "app.system.complete_onboarding_request.app_error", nil, err.Error(), http.StatusBadRequest) return } - auditRec.AddMeta("install_plugin", onboardingRequest.InstallPlugins) + auditRec.AddEventParameter("install_plugin", onboardingRequest.InstallPlugins) + auditRec.AddEventParameter("onboarding_request", onboardingRequest) appErr := c.App.CompleteOnboarding(c.AppContext, onboardingRequest) if appErr != nil { diff --git a/api4/team.go b/api4/team.go index 52c651bca7..beb71703a4 100644 --- a/api4/team.go +++ b/api4/team.go @@ -88,7 +88,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createTeam", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team", team) + auditRec.AddEventParameter("team", team) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionCreateTeam) { c.Err = model.NewAppError("createTeam", "api.team.is_team_creation_allowed.disabled.app_error", nil, "", http.StatusForbidden) @@ -127,7 +127,8 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) { // Don't sanitize the team here since the user will be a team admin and their session won't reflect that yet auditRec.Success() - auditRec.AddMeta("team", team) // overwrite meta + auditRec.AddEventResultState(&team) + auditRec.AddEventObjectType("team") w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rteam); err != nil { @@ -203,7 +204,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("updateTeam", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team", team) + auditRec.AddEventParameter("team", team) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeam) { c.SetPermissionError(model.PermissionManageTeam) @@ -217,7 +218,8 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("update", updatedTeam) + auditRec.AddEventResultState(updatedTeam) + auditRec.AddEventObjectType("team") c.App.SanitizeTeam(*c.AppContext.Session(), updatedTeam) if err := json.NewEncoder(w).Encode(updatedTeam); err != nil { @@ -238,6 +240,7 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("patchTeam", audit.Fail) + auditRec.AddEventParameter("team_patch", team) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeam) { @@ -246,7 +249,8 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) { } if oldTeam, err := c.App.GetTeam(c.Params.TeamId); err == nil { - auditRec.AddMeta("team", oldTeam) + auditRec.AddEventPriorState(oldTeam) + auditRec.AddEventObjectType("team") } patchedTeam, err := c.App.PatchTeam(c.Params.TeamId, &team) @@ -259,7 +263,7 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeTeam(*c.AppContext.Session(), patchedTeam) auditRec.Success() - auditRec.AddMeta("patched", patchedTeam) + auditRec.AddEventResultState(patchedTeam) c.LogAudit("") if err := json.NewEncoder(w).Encode(patchedTeam); err != nil { @@ -275,7 +279,7 @@ func restoreTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("restoreTeam", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeam) { c.SetPermissionError(model.PermissionManageTeam) @@ -317,7 +321,8 @@ func restoreTeam(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("team", team) + auditRec.AddEventResultState(team) + auditRec.AddEventObjectType("team") auditRec.Success() if err := json.NewEncoder(w).Encode(team); err != nil { @@ -350,11 +355,11 @@ func updateTeamPrivacy(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updateTeamPrivacy", audit.Fail) + auditRec.AddEventParameter("props", props) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("privacy", privacy) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeam) { - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) c.SetPermissionError(model.PermissionManageTeam) return } @@ -371,7 +376,8 @@ func updateTeamPrivacy(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("team", team) + auditRec.AddEventResultState(team) + auditRec.AddEventObjectType("team") auditRec.Success() if err := json.NewEncoder(w).Encode(team); err != nil { @@ -391,6 +397,7 @@ func regenerateTeamInviteId(c *Context, w http.ResponseWriter, r *http.Request) } auditRec := c.MakeAuditRecord("regenerateTeamInviteId", audit.Fail) + auditRec.AddEventParameter("team_id", c.Params.TeamId) defer c.LogAuditRec(auditRec) patchedTeam, err := c.App.RegenerateTeamInviteId(c.Params.TeamId) @@ -402,7 +409,8 @@ func regenerateTeamInviteId(c *Context, w http.ResponseWriter, r *http.Request) c.App.SanitizeTeam(*c.AppContext.Session(), patchedTeam) auditRec.Success() - auditRec.AddMeta("team", patchedTeam) + auditRec.AddEventResultState(patchedTeam) + auditRec.AddEventObjectType("team") c.LogAudit("") if err := json.NewEncoder(w).Encode(patchedTeam); err != nil { @@ -425,7 +433,7 @@ func deleteTeam(c *Context, w http.ResponseWriter, r *http.Request) { defer c.LogAuditRec(auditRec) if team, err := c.App.GetTeam(c.Params.TeamId); err == nil { - auditRec.AddMeta("team", team) + auditRec.AddEventParameter("team", team) } var err *model.AppError @@ -694,8 +702,8 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("addTeamMember", audit.Fail) + auditRec.AddEventParameter("member", member) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("member", member) if member.UserId == c.AppContext.Session().UserId { var team *model.Team @@ -750,6 +758,8 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(tm) + auditRec.AddEventObjectType("team_member") // TODO verify this is the final state. should it be the team instead? auditRec.Success() w.WriteHeader(http.StatusCreated) @@ -767,7 +777,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("addUserToTeamFromInvite", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("invite_id", inviteId) + auditRec.AddEventParameter("invite_id", inviteId) if tokenId != "" { member, err = c.App.AddTeamMemberByToken(c.AppContext, c.AppContext.Session().UserId, tokenId) @@ -824,6 +834,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("addTeamMembers", audit.Fail) + auditRec.AddEventParameter("members", members) defer c.LogAuditRec(auditRec) auditRec.AddMeta("count", len(members)) @@ -927,6 +938,9 @@ func removeTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { } } + auditRec.AddEventParameter("team_id", c.Params.TeamId) + auditRec.AddEventParameter("user_id", c.Params.UserId) + team, err := c.App.GetTeam(c.Params.TeamId) if err != nil { c.Err = err @@ -1026,7 +1040,7 @@ func updateTeamMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("updateTeamMemberRoles", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("roles", newRoles) + auditRec.AddEventParameter("props", props) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeamRoles) { c.SetPermissionError(model.PermissionManageTeamRoles) @@ -1040,7 +1054,8 @@ func updateTeamMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("member", teamMember) + auditRec.AddEventResultState(teamMember) + auditRec.AddEventObjectType("team_member") ReturnStatusOK(w) } @@ -1059,7 +1074,7 @@ func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Requ auditRec := c.MakeAuditRecord("updateTeamMemberSchemeRoles", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("roles", schemeRoles) + auditRec.AddEventParameter("scheme_roles", schemeRoles) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeamRoles) { c.SetPermissionError(model.PermissionManageTeamRoles) @@ -1073,7 +1088,8 @@ func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Requ } auditRec.Success() - auditRec.AddMeta("member", teamMember) + auditRec.AddEventResultState(teamMember) + auditRec.AddEventObjectType("team_member") ReturnStatusOK(w) } @@ -1286,7 +1302,7 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("importTeam", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) fileInfo := fileInfoArray[0] @@ -1296,9 +1312,9 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) { return } defer fileData.Close() - auditRec.AddMeta("filename", fileInfo.Filename) - auditRec.AddMeta("filesize", fileSize) - auditRec.AddMeta("from", importFrom) + auditRec.AddEventParameter("filename", fileInfo.Filename) + auditRec.AddEventParameter("filesize", fileSize) + auditRec.AddEventParameter("from", importFrom) var log *bytes.Buffer data := map[string]string{} @@ -1364,7 +1380,8 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("inviteUsersToTeam", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("member_invite", memberInvite) + auditRec.AddEventParameter("team_id", c.Params.TeamId) auditRec.AddMeta("count", len(emailList)) auditRec.AddMeta("emails", emailList) @@ -1451,7 +1468,7 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("inviteGuestsToChannels", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionInviteGuest) { c.SetPermissionError(model.PermissionInviteGuest) @@ -1463,6 +1480,7 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, jsonErr.Error(), http.StatusBadRequest) return } + auditRec.AddEventParameter("guests_invite", guestsInvite) for i, email := range guestsInvite.Emails { guestsInvite.Emails[i] = strings.ToLower(email) @@ -1601,7 +1619,7 @@ func setTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("setTeamIcon", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeam) { c.SetPermissionError(model.PermissionManageTeam) @@ -1652,7 +1670,7 @@ func removeTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("removeTeamIcon", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), c.Params.TeamId, model.PermissionManageTeam) { c.SetPermissionError(model.PermissionManageTeam) @@ -1689,6 +1707,7 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updateTeamScheme", audit.Fail) + auditRec.AddEventParameter("scheme_id_patch", p) defer c.LogAuditRec(auditRec) if c.App.Channels().License() == nil { @@ -1724,12 +1743,14 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) { team.SchemeId = schemeID - _, err = c.App.UpdateTeamScheme(team) + team, err = c.App.UpdateTeamScheme(team) if err != nil { c.Err = err return } + auditRec.AddEventResultState(team) + auditRec.AddEventObjectType("team") auditRec.Success() ReturnStatusOK(w) } diff --git a/api4/team_local.go b/api4/team_local.go index ebde6bd68c..2f6aa488fa 100644 --- a/api4/team_local.go +++ b/api4/team_local.go @@ -44,10 +44,12 @@ func localDeleteTeam(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("localDeleteTeam", audit.Fail) + auditRec.AddEventParameter("team_id", c.Params.TeamId) defer c.LogAuditRec(auditRec) if team, err := c.App.GetTeam(c.Params.TeamId); err == nil { - auditRec.AddMeta("team", team) + auditRec.AddEventPriorState(team) + auditRec.AddEventObjectType("team") } var err *model.AppError @@ -104,8 +106,9 @@ func localInviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) } auditRec := c.MakeAuditRecord("localInviteUsersToTeam", audit.Fail) + auditRec.AddEventParameter("member_invite", memberInvite) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) auditRec.AddMeta("count", len(emailList)) auditRec.AddMeta("emails", emailList) @@ -249,7 +252,7 @@ func localCreateTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("localCreateTeam", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("team", team) + auditRec.AddEventParameter("team", team) rteam, err := c.App.CreateTeam(c.AppContext, &team) if err != nil { @@ -258,6 +261,8 @@ func localCreateTeam(c *Context, w http.ResponseWriter, r *http.Request) { } // Don't sanitize the team here since the user will be a team admin and their session won't reflect that yet + auditRec.AddEventResultState(rteam) + auditRec.AddEventObjectType("type") auditRec.Success() auditRec.AddMeta("team", team) // overwrite meta diff --git a/api4/upload.go b/api4/upload.go index bf0e270230..312f468b6d 100644 --- a/api4/upload.go +++ b/api4/upload.go @@ -41,7 +41,7 @@ func createUpload(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createUpload", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("upload", us) + auditRec.AddEventParameter("upload", us) if us.Type == model.UploadTypeImport { if !c.IsSystemAdmin() { @@ -114,7 +114,7 @@ func uploadData(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("uploadData", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("upload_id", c.Params.UploadId) + auditRec.AddEventParameter("upload_id", c.Params.UploadId) us, err := c.App.GetUploadSession(c.Params.UploadId) if err != nil { diff --git a/api4/user.go b/api4/user.go index c5a078433a..d65018e1f5 100644 --- a/api4/user.go +++ b/api4/user.go @@ -121,8 +121,9 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createUser", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("invite_id", inviteId) - auditRec.AddMeta("user", user) + auditRec.AddEventParameter("iid", inviteId) + auditRec.AddEventParameter("r", redirect) + auditRec.AddEventParameter("user", user) // No permission check required @@ -162,7 +163,8 @@ func createUser(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("user", ruser) // overwrite meta + auditRec.AddEventResultState(ruser) + auditRec.AddEventObjectType("user") w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(ruser); err != nil { @@ -459,7 +461,7 @@ func setProfileImage(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("setProfileImage", audit.Fail) defer c.LogAuditRec(auditRec) if imageArray[0] != nil { - auditRec.AddMeta("filename", imageArray[0].Filename) + auditRec.AddEventParameter("filename", imageArray[0].Filename) } user, err := c.App.GetUser(c.Params.UserId) @@ -506,6 +508,7 @@ func setDefaultProfileImage(c *Context, w http.ResponseWriter, r *http.Request) } auditRec := c.MakeAuditRecord("setDefaultProfileImage", audit.Fail) + auditRec.AddEventParameter("user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) user, err := c.App.GetUser(c.Params.UserId) @@ -1195,7 +1198,9 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("user", ouser) + auditRec.AddEventParameter("user", user) + auditRec.AddEventPriorState(ouser) + auditRec.AddEventObjectType("user") if c.AppContext.Session().IsOAuth { if ouser.Email != user.Email { @@ -1230,7 +1235,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("update", ruser) + auditRec.AddEventResultState(ruser) c.LogAudit("") if err := json.NewEncoder(w).Encode(ruser); err != nil { @@ -1251,6 +1256,7 @@ func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("patchUser", audit.Fail) + auditRec.AddEventParameter("user_patch", patch.Auditable()) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { @@ -1263,7 +1269,8 @@ func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { c.SetInvalidParam("user_id") return } - auditRec.AddMeta("user", ouser) + auditRec.AddEventPriorState(ouser) + auditRec.AddEventObjectType("user") // Cannot update a system admin unless user making request is a systemadmin also if ouser.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { @@ -1309,7 +1316,7 @@ func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SetAutoResponderStatus(ruser, ouser.NotifyProps) auditRec.Success() - auditRec.AddMeta("patch", ruser) + auditRec.AddEventResultState(ruser) c.LogAudit("") if err := json.NewEncoder(w).Encode(ruser); err != nil { @@ -1326,6 +1333,7 @@ func deleteUser(c *Context, w http.ResponseWriter, r *http.Request) { userId := c.Params.UserId auditRec := c.MakeAuditRecord("deleteUser", audit.Fail) + auditRec.AddEventParameter("user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), userId) { @@ -1344,7 +1352,8 @@ func deleteUser(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("user", user) + auditRec.AddEventPriorState(user) + auditRec.AddEventObjectType("user") // Cannot update a system admin unless user making request is a systemadmin also if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { @@ -1397,8 +1406,8 @@ func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updateUserRoles", audit.Fail) + auditRec.AddEventParameter("props", props) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("roles", newRoles) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageRoles) { c.SetPermissionError(model.PermissionManageRoles) @@ -1412,7 +1421,8 @@ func updateUserRoles(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("user", user) + auditRec.AddEventResultState(user) + auditRec.AddEventObjectType("user") c.LogAudit(fmt.Sprintf("user=%s roles=%s", c.Params.UserId, newRoles)) ReturnStatusOK(w) @@ -1434,7 +1444,8 @@ func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("updateUserActive", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("active", active) + auditRec.AddEventParameter("props", props) + auditRec.AddEventParameter("active", active) // true when you're trying to de-activate yourself isSelfDeactivate := !active && c.Params.UserId == c.AppContext.Session().UserId @@ -1455,7 +1466,8 @@ func updateUserActive(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("user", user) + auditRec.AddEventPriorState(user) + auditRec.AddEventObjectType("user") if user.IsSystemAdmin() && !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { c.SetPermissionError(model.PermissionManageSystem) @@ -1724,7 +1736,7 @@ func sendPasswordReset(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("sendPasswordReset", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("email", email) + auditRec.AddEventParameter("props", props) sent, err := c.App.SendPasswordReset(email, c.App.GetSiteURL()) if err != nil { @@ -1831,8 +1843,8 @@ func login(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("login", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("login_id", loginId) - auditRec.AddMeta("device_id", deviceId) + auditRec.AddEventParameter("login_id", loginId) + auditRec.AddEventParameter("device_id", deviceId) c.LogAuditWithUserId(id, "attempt - login_id="+loginId) @@ -1914,7 +1926,7 @@ func loginCWS(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("login", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("login_id", loginID) + auditRec.AddEventParameter("login_id", loginID) user, err := c.App.AuthenticateUserForLogin(c.AppContext, "", loginID, "", "", token, false) if err != nil { c.LogAuditWithUserId("", "failure - login_id="+loginID) @@ -2011,7 +2023,10 @@ func revokeSession(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("session", session) + + auditRec.AddEventParameter("props", props) + auditRec.AddEventPriorState(session) + auditRec.AddEventObjectType("session") if session.UserId != c.Params.UserId { c.SetInvalidURLParam("user_id") @@ -2037,7 +2052,7 @@ func revokeAllSessionsForUser(c *Context, w http.ResponseWriter, r *http.Request auditRec := c.MakeAuditRecord("revokeAllSessionsForUser", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("user_id", c.Params.UserId) + auditRec.AddEventParameter("user_id", c.Params.UserId) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { c.SetPermissionError(model.PermissionEditOtherUsers) @@ -2086,7 +2101,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("attachDeviceId", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("device_id", deviceId) + auditRec.AddEventParameter("props", props) // A special case where we logout of all other sessions with the same device id if err := c.App.RevokeSessionsForDeviceId(c.AppContext.Session().UserId, deviceId, c.AppContext.Session().Id); err != nil { @@ -2138,6 +2153,7 @@ func getUserAudits(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("getUserAudits", audit.Fail) + auditRec.AddEventParameter("user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) if user, err := c.App.GetUser(c.Params.UserId); err == nil { @@ -2200,7 +2216,8 @@ func sendVerificationEmail(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("sendVerificationEmail", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("email", email) + auditRec.AddEventParameter("props", props) + auditRec.AddEventParameter("r", redirect) user, err := c.App.GetUserForLogin("", email) if err != nil { @@ -2230,9 +2247,7 @@ func switchAccountType(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("switchAccountType", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("email", switchRequest.Email) - auditRec.AddMeta("new_service", switchRequest.NewService) - auditRec.AddMeta("old_service", switchRequest.CurrentService) + auditRec.AddEventParameter("switch_request", switchRequest) link := "" var err *model.AppError @@ -2273,6 +2288,7 @@ func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("createUserAccessToken", audit.Fail) + auditRec.AddEventParameter("user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) if user, err := c.App.GetUser(c.Params.UserId); err == nil { @@ -2447,7 +2463,7 @@ func revokeUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("revokeUserAccessToken", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("token_id", tokenId) + auditRec.AddEventParameter("props", props) c.LogAudit("") if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionRevokeUserAccessToken) { @@ -2490,8 +2506,8 @@ func disableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) } auditRec := c.MakeAuditRecord("disableUserAccessToken", audit.Fail) + auditRec.AddEventParameter("props", props) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("token_id", tokenId) c.LogAudit("") // No separate permission for this action for now @@ -2536,7 +2552,7 @@ func enableUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("enableUserAccessToken", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("token_id", tokenId) + auditRec.AddEventParameter("props", props) c.LogAudit("") // No separate permission for this action for now @@ -2588,8 +2604,7 @@ func saveUserTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("saveUserTermsOfService", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("terms_id", termsOfServiceId) - auditRec.AddMeta("accepted", accepted) + auditRec.AddEventParameter("props", props) if user, err := c.App.GetUser(userId); err == nil { auditRec.AddMeta("user", user) @@ -2631,6 +2646,7 @@ func promoteGuestToUser(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("promoteGuestToUser", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("user_id", c.Params.UserId) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionPromoteGuest) { c.SetPermissionError(model.PermissionPromoteGuest) @@ -2675,6 +2691,7 @@ func demoteUserToGuest(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("demoteUserToGuest", audit.Fail) + auditRec.AddEventParameter("user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionDemoteToGuest) { @@ -2752,6 +2769,7 @@ func verifyUserEmailWithoutToken(c *Context, w http.ResponseWriter, r *http.Requ } auditRec := c.MakeAuditRecord("verifyUserEmailWithoutToken", audit.Fail) + auditRec.AddEventParameter("user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) auditRec.AddMeta("user_id", user.Id) @@ -2786,6 +2804,7 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("convertUserToBot", audit.Fail) + auditRec.AddEventParameter("user_id", c.Params.UserId) defer c.LogAuditRec(auditRec) auditRec.AddMeta("user", user) @@ -2800,7 +2819,9 @@ func convertUserToBot(c *Context, w http.ResponseWriter, r *http.Request) { return } - auditRec.AddMeta("convertedTo", bot) + auditRec.AddEventPriorState(user) + auditRec.AddEventResultState(bot) + auditRec.AddEventObjectType("bot") js, jsonErr := json.Marshal(bot) if jsonErr != nil { @@ -2886,9 +2907,7 @@ func migrateAuthToLDAP(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("migrateAuthToLdap", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("from", from) - auditRec.AddMeta("match_field", matchField) - auditRec.AddMeta("force", force) + auditRec.AddEventParameter("props", props) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { c.SetPermissionError(model.PermissionManageSystem) @@ -2945,9 +2964,7 @@ func migrateAuthToSaml(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("migrateAuthToSaml", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("from", from) - auditRec.AddMeta("matches", matches) - auditRec.AddMeta("auto", auto) + auditRec.AddEventParameter("props", props) if !c.App.SessionHasPermissionTo(*c.AppContext.Session(), model.PermissionManageSystem) { c.SetPermissionError(model.PermissionManageSystem) @@ -3086,10 +3103,10 @@ func updateReadStateThreadByUser(c *Context, w http.ResponseWriter, r *http.Requ auditRec := c.MakeAuditRecord("updateReadStateThreadByUser", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("user_id", c.Params.UserId) - auditRec.AddMeta("thread_id", c.Params.ThreadId) - auditRec.AddMeta("team_id", c.Params.TeamId) - auditRec.AddMeta("timestamp", c.Params.Timestamp) + auditRec.AddEventParameter("user_id", c.Params.UserId) + auditRec.AddEventParameter("thread_id", c.Params.ThreadId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) + auditRec.AddEventParameter("timestamp", c.Params.Timestamp) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { c.SetPermissionError(model.PermissionEditOtherUsers) return @@ -3116,10 +3133,10 @@ func setUnreadThreadByPostId(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("setUnreadThreadByPostId", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("user_id", c.Params.UserId) - auditRec.AddMeta("thread_id", c.Params.ThreadId) - auditRec.AddMeta("team_id", c.Params.TeamId) - auditRec.AddMeta("post_id", c.Params.PostId) + auditRec.AddEventParameter("user_id", c.Params.UserId) + auditRec.AddEventParameter("thread_id", c.Params.ThreadId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) + auditRec.AddEventParameter("post_id", c.Params.PostId) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { c.SetPermissionError(model.PermissionEditOtherUsers) @@ -3152,9 +3169,9 @@ func unfollowThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("unfollowThreadByUser", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("user_id", c.Params.UserId) - auditRec.AddMeta("thread_id", c.Params.ThreadId) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("user_id", c.Params.UserId) + auditRec.AddEventParameter("thread_id", c.Params.ThreadId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { c.SetPermissionError(model.PermissionEditOtherUsers) @@ -3185,9 +3202,9 @@ func followThreadByUser(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("followThreadByUser", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("user_id", c.Params.UserId) - auditRec.AddMeta("thread_id", c.Params.ThreadId) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("user_id", c.Params.UserId) + auditRec.AddEventParameter("thread_id", c.Params.ThreadId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { c.SetPermissionError(model.PermissionEditOtherUsers) @@ -3217,8 +3234,8 @@ func updateReadStateAllThreadsByUser(c *Context, w http.ResponseWriter, r *http. auditRec := c.MakeAuditRecord("updateReadStateAllThreadsByUser", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("user_id", c.Params.UserId) - auditRec.AddMeta("team_id", c.Params.TeamId) + auditRec.AddEventParameter("user_id", c.Params.UserId) + auditRec.AddEventParameter("team_id", c.Params.TeamId) if !c.App.SessionHasPermissionToUser(*c.AppContext.Session(), c.Params.UserId) { c.SetPermissionError(model.PermissionEditOtherUsers) diff --git a/api4/user_local.go b/api4/user_local.go index a227fa137a..e093f2fdff 100644 --- a/api4/user_local.go +++ b/api4/user_local.go @@ -245,7 +245,9 @@ func localDeleteUser(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("user", user) + auditRec.AddEventParameter("user_id", c.Params.UserId) + auditRec.AddEventPriorState(user) + auditRec.AddEventObjectType("user") if c.Params.Permanent { err = c.App.PermanentDeleteUser(c.AppContext, user) diff --git a/api4/webhook.go b/api4/webhook.go index e6403e25c0..3f19313bf6 100644 --- a/api4/webhook.go +++ b/api4/webhook.go @@ -42,6 +42,7 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("createIncomingHook", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("incoming_webhook", hook) auditRec.AddMeta("channel", channel) c.LogAudit("attempt") @@ -79,7 +80,8 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("hook", incomingHook) + auditRec.AddEventResultState(incomingHook) + auditRec.AddEventObjectType("hook") c.LogAudit("success") w.WriteHeader(http.StatusCreated) @@ -107,8 +109,9 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("updateIncomingHook", audit.Fail) + auditRec.AddEventParameter("hook_id", c.Params.HookId) + auditRec.AddEventParameter("updated_hook", updatedHook) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("hook_id", c.Params.HookId) c.LogAudit("attempt") oldHook, err := c.App.GetIncomingWebhook(c.Params.HookId) @@ -116,7 +119,8 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = err return } - auditRec.AddMeta("team_id", oldHook.TeamId) + auditRec.AddEventPriorState(oldHook) + auditRec.AddEventObjectType("incoming_webhook") if updatedHook.TeamId == "" { updatedHook.TeamId = oldHook.TeamId @@ -163,6 +167,7 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventResultState(incomingHook) auditRec.Success() c.LogAudit("success") @@ -238,6 +243,7 @@ func getIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("getIncomingHook", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("hook_id", c.Params.HookId) auditRec.AddMeta("hook_id", hook.Id) auditRec.AddMeta("hook_display", hook.DisplayName) auditRec.AddMeta("channel_id", hook.ChannelId) @@ -297,6 +303,7 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("deleteIncomingHook", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("hook_id", c.Params.HookId) auditRec.AddMeta("hook_id", hook.Id) auditRec.AddMeta("hook_display", hook.DisplayName) auditRec.AddMeta("channel_id", channel.Id) @@ -321,6 +328,8 @@ func deleteIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { return } + auditRec.AddEventPriorState(hook) + auditRec.AddEventObjectType("incoming_webhook") auditRec.Success() ReturnStatusOK(w) } @@ -345,10 +354,7 @@ func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("updateOutgoingHook", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("hook_id", updatedHook.Id) - auditRec.AddMeta("hook_display", updatedHook.DisplayName) - auditRec.AddMeta("channel_id", updatedHook.ChannelId) - auditRec.AddMeta("team_id", updatedHook.TeamId) + auditRec.AddEventParameter("updated_hook", updatedHook) c.LogAudit("attempt") oldHook, err := c.App.GetOutgoingWebhook(c.Params.HookId) @@ -401,8 +407,8 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec := c.MakeAuditRecord("createOutgoingHook", audit.Fail) + auditRec.AddEventParameter("hook", hook) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("hook_id", hook.Id) c.LogAudit("attempt") if !c.App.SessionHasPermissionToTeam(*c.AppContext.Session(), hook.TeamId, model.PermissionManageOutgoingWebhooks) { @@ -434,9 +440,8 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { } auditRec.Success() - auditRec.AddMeta("hook_display", rhook.DisplayName) - auditRec.AddMeta("channel_id", rhook.ChannelId) - auditRec.AddMeta("team_id", rhook.TeamId) + auditRec.AddEventResultState(rhook) + auditRec.AddEventObjectType("outgoing_webhook") c.LogAudit("success") w.WriteHeader(http.StatusCreated) @@ -518,6 +523,7 @@ func getOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("getOutgoingHook", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("hook_id", c.Params.HookId) auditRec.AddMeta("hook_id", hook.Id) auditRec.AddMeta("hook_display", hook.DisplayName) auditRec.AddMeta("channel_id", hook.ChannelId) @@ -580,6 +586,8 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request) return } + auditRec.AddEventResultState(rhook) + auditRec.AddEventObjectType("outgoing_webhook") auditRec.Success() c.LogAudit("success") @@ -602,6 +610,7 @@ func deleteOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { auditRec := c.MakeAuditRecord("deleteOutgoingHook", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("hook_id", c.Params.HookId) auditRec.AddMeta("hook_id", hook.Id) auditRec.AddMeta("hook_display", hook.DisplayName) auditRec.AddMeta("channel_id", hook.ChannelId) diff --git a/api4/webhook_local.go b/api4/webhook_local.go index 93c02a35b6..ae42ee4355 100644 --- a/api4/webhook_local.go +++ b/api4/webhook_local.go @@ -51,6 +51,7 @@ func localCreateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("localCreateIncomingHook", audit.Fail) defer c.LogAuditRec(auditRec) + auditRec.AddEventParameter("hook", hook) auditRec.AddMeta("channel", channel) c.LogAudit("attempt") @@ -61,7 +62,8 @@ func localCreateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) } auditRec.Success() - auditRec.AddMeta("hook", incomingHook) + auditRec.AddEventResultState(incomingHook) + auditRec.AddEventObjectType("incoming_webhook") c.LogAudit("success") w.WriteHeader(http.StatusCreated) @@ -79,7 +81,7 @@ func localCreateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) auditRec := c.MakeAuditRecord("createOutgoingHook", audit.Fail) defer c.LogAuditRec(auditRec) - auditRec.AddMeta("hook_id", hook.Id) + auditRec.AddEventParameter("hook", hook) c.LogAudit("attempt") if hook.CreatorId == "" { @@ -101,9 +103,8 @@ func localCreateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) } auditRec.Success() - auditRec.AddMeta("hook_display", rhook.DisplayName) - auditRec.AddMeta("channel_id", rhook.ChannelId) - auditRec.AddMeta("team_id", rhook.TeamId) + auditRec.AddEventResultState(rhook) + auditRec.AddEventObjectType("outgoing_webhook") c.LogAudit("success") w.WriteHeader(http.StatusCreated) diff --git a/audit/audit.go b/audit/audit.go index 274411daaa..1847889cf4 100644 --- a/audit/audit.go +++ b/audit/audit.go @@ -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...) diff --git a/audit/audit_test.go b/audit/audit_test.go index b4e581e599..cc3ce3d676 100644 --- a/audit/audit_test.go +++ b/audit/audit_test.go @@ -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), }, }, } diff --git a/audit/const.go b/audit/const.go index 23cf07376a..d2a4fa5cdc 100644 --- a/audit/const.go +++ b/audit/const.go @@ -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" diff --git a/audit/record.go b/audit/record.go index cdceb0c015..e5fbafa3ae 100644 --- a/audit/record.go +++ b/audit/record.go @@ -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 diff --git a/config/diff.go b/config/diff.go index ce2f706046..ac418ec8a6 100644 --- a/config/diff.go +++ b/config/diff.go @@ -18,6 +18,24 @@ type ConfigDiff struct { ActualVal any `json:"actual_val"` } +func (c *ConfigDiff) Auditable() map[string]interface{} { + return map[string]interface{}{ + "path": c.Path, + "base_val": c.BaseVal, + "actual_val": c.ActualVal, + } +} + +func (cd *ConfigDiffs) Auditable() map[string]interface{} { + var s []interface{} + for _, d := range cd.Sanitize() { + s = append(s, d.Auditable()) + } + return map[string]interface{}{ + "config_diffs": s, + } +} + var configSensitivePaths = map[string]bool{ "LdapSettings.BindPassword": true, "FileSettings.PublicLinkSalt": true, diff --git a/model/bot.go b/model/bot.go index 8e177cfec4..bea54a4327 100644 --- a/model/bot.go +++ b/model/bot.go @@ -33,6 +33,20 @@ type Bot struct { DeleteAt int64 `json:"delete_at"` } +func (b *Bot) Auditable() map[string]interface{} { + return map[string]interface{}{ + "user_id": b.UserId, + "username": b.Username, + "display_name": b.DisplayName, + "description": b.Description, + "owner_id": b.OwnerId, + "last_icon_update": b.LastIconUpdate, + "create_at": b.CreateAt, + "update_at": b.UpdateAt, + "delete_at": b.DeleteAt, + } +} + // BotPatch is a description of what fields to update on an existing bot. type BotPatch struct { Username *string `json:"username"` diff --git a/model/channel.go b/model/channel.go index be5f9fa203..8c86c53763 100644 --- a/model/channel.go +++ b/model/channel.go @@ -61,6 +61,27 @@ type Channel struct { LastRootPostAt int64 `json:"last_root_post_at"` } +func (o *Channel) Auditable() map[string]interface{} { + return map[string]interface{}{ + "create_at": o.CreateAt, + "creator_id": o.CreatorId, + "delete_at": o.DeleteAt, + "extra_group_at": o.ExtraUpdateAt, + "group_constrained": o.GroupConstrained, + "id": o.Id, + "last_post_at": o.LastPostAt, + "last_root_post_at": o.LastRootPostAt, + "policy_id": o.PolicyID, + "props": o.Props, + "scheme_id": o.SchemeId, + "shared": o.Shared, + "team_id": o.TeamId, + "total_msg_count_root": o.TotalMsgCountRoot, + "type": o.Type, + "update_at": o.UpdateAt, + } +} + type ChannelWithTeamData struct { Channel TeamDisplayName string `json:"team_display_name"` @@ -81,6 +102,14 @@ type ChannelPatch struct { GroupConstrained *bool `json:"group_constrained"` } +func (c *ChannelPatch) Auditable() map[string]interface{} { + return map[string]interface{}{ + "header": c.Header, + "group_constrained": c.GroupConstrained, + "purpose": c.Purpose, + } +} + type ChannelForExport struct { Channel TeamName string diff --git a/model/channel_member.go b/model/channel_member.go index c9c1b0a057..d79695ada5 100644 --- a/model/channel_member.go +++ b/model/channel_member.go @@ -60,6 +60,25 @@ type ChannelMember struct { ExplicitRoles string `json:"explicit_roles"` } +func (o *ChannelMember) Auditable() map[string]interface{} { + return map[string]interface{}{ + "channel_id": o.ChannelId, + "user_id": o.UserId, + "roles": o.Roles, + "last_viewed_at": o.LastViewedAt, + "msg_count": o.MsgCount, + "mention_count": o.MentionCount, + "mention_count_root": o.MentionCountRoot, + "msg_count_root": o.MsgCountRoot, + "notify_props": o.NotifyProps, + "last_update_at": o.LastUpdateAt, + "scheme_guest": o.SchemeGuest, + "scheme_user": o.SchemeUser, + "scheme_admin": o.SchemeAdmin, + "explicit_roles": o.ExplicitRoles, + } +} + // The following are some GraphQL methods necessary to return the // data in float64 type. The spec doesn't support 64 bit integers, // so we have to pass the data in float64. The _ at the end is diff --git a/model/command.go b/model/command.go index 4bb9529820..9742812f94 100644 --- a/model/command.go +++ b/model/command.go @@ -41,6 +41,26 @@ type Command struct { AutocompleteIconData string `db:"-" json:"autocomplete_icon_data,omitempty"` } +func (o *Command) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": o.Id, + "create_at": o.CreateAt, + "update_at": o.UpdateAt, + "delete_at": o.DeleteAt, + "creator_id": o.CreatorId, + "team_id": o.TeamId, + "trigger": o.Trigger, + "username": o.Username, + "icon_url": o.IconURL, + "auto_complete": o.AutoComplete, + "auto_complete_desc": o.AutoCompleteDesc, + "auto_complete_hint": o.AutoCompleteHint, + "display_name": o.DisplayName, + "description": o.Description, + "url": o.URL, + } +} + func (o *Command) IsValid() *AppError { if !IsValidId(o.Id) { return NewAppError("Command.IsValid", "model.command.is_valid.id.app_error", nil, "", http.StatusBadRequest) diff --git a/model/command_args.go b/model/command_args.go index c8333acbde..672405df16 100644 --- a/model/command_args.go +++ b/model/command_args.go @@ -24,6 +24,19 @@ type CommandArgs struct { Session Session `json:"-"` } +func (o *CommandArgs) Auditable() map[string]interface{} { + return map[string]interface{}{ + "user_id": o.UserId, + "channel_id": o.ChannelId, + "team_id": o.TeamId, + "root_id": o.RootId, + "parent_id": o.ParentId, + "trigger_id": o.TriggerId, + "command": o.Command, + "site_url": o.SiteURL, + } +} + // AddUserMention adds or overrides an entry in UserMentions with name username // and identifier userId func (o *CommandArgs) AddUserMention(username, userId string) { diff --git a/model/compliance.go b/model/compliance.go index b46a0d1038..7129701e2e 100644 --- a/model/compliance.go +++ b/model/compliance.go @@ -33,6 +33,22 @@ type Compliance struct { Emails string `json:"emails"` } +func (c *Compliance) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": c.Id, + "create_at": c.CreateAt, + "user_id": c.UserId, + "status": c.Status, + "count": c.Count, + "desc": c.Desc, + "type": c.Type, + "start_at": c.StartAt, + "end_at": c.EndAt, + "keywords": c.Keywords, + "emails": c.Emails, + } +} + type Compliances []Compliance // ComplianceExportCursor is used for paginated iteration of posts diff --git a/model/config.go b/model/config.go index 7f8d0ebaca..b051c25fa4 100644 --- a/model/config.go +++ b/model/config.go @@ -3129,6 +3129,12 @@ type Config struct { ExportSettings ExportSettings } +func (o *Config) Auditable() map[string]interface{} { + return map[string]interface{}{ + // TODO + } +} + func (o *Config) Clone() *Config { buf, err := json.Marshal(o) if err != nil { diff --git a/model/data_retention_policy.go b/model/data_retention_policy.go index 549b98012d..1e2817c28a 100644 --- a/model/data_retention_policy.go +++ b/model/data_retention_policy.go @@ -24,12 +24,28 @@ type RetentionPolicyWithTeamAndChannelIDs struct { ChannelIDs []string `json:"channel_ids"` } +func (o *RetentionPolicyWithTeamAndChannelIDs) Auditable() map[string]interface{} { + return map[string]interface{}{ + "retention_policy": o.RetentionPolicy, + "team_ids": o.TeamIDs, + "channel_ids": o.ChannelIDs, + } +} + type RetentionPolicyWithTeamAndChannelCounts struct { RetentionPolicy ChannelCount int64 `json:"channel_count"` TeamCount int64 `json:"team_count"` } +func (o *RetentionPolicyWithTeamAndChannelCounts) Auditable() map[string]interface{} { + return map[string]interface{}{ + "retention_policy": o.RetentionPolicy, + "channel_count": o.ChannelCount, + "team_count": o.TeamCount, + } +} + type RetentionPolicyChannel struct { PolicyID string `db:"PolicyId"` ChannelID string `db:"ChannelId"` diff --git a/model/emoji.go b/model/emoji.go index 4b30ee4364..9b12dbdafe 100644 --- a/model/emoji.go +++ b/model/emoji.go @@ -25,6 +25,17 @@ type Emoji struct { Name string `json:"name"` } +func (emoji *Emoji) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": emoji.Id, + "create_at": emoji.CreateAt, + "update_at": emoji.UpdateAt, + "delete_at": emoji.CreateAt, + "creator_id": emoji.CreatorId, + "name": emoji.Name, + } +} + func inSystemEmoji(emojiName string) bool { _, ok := SystemEmojis[emojiName] return ok diff --git a/model/group.go b/model/group.go index 612299ea35..f72bf1d584 100644 --- a/model/group.go +++ b/model/group.go @@ -45,6 +45,20 @@ type Group struct { AllowReference bool `json:"allow_reference"` } +func (group *Group) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": group.Id, + "source": group.Source, + "remote_id": group.RemoteId, + "create_at": group.CreateAt, + "update_at": group.UpdateAt, + "delete_at": group.DeleteAt, + "has_syncables": group.HasSyncables, + "member_count": group.MemberCount, + "allow_reference": group.AllowReference, + } +} + type GroupWithUserIds struct { Group UserIds []string `json:"user_ids"` diff --git a/model/group_syncable.go b/model/group_syncable.go index aebcd142c6..afad357a10 100644 --- a/model/group_syncable.go +++ b/model/group_syncable.go @@ -42,6 +42,24 @@ type GroupSyncable struct { TeamID string `db:"-" json:"-"` } +func (syncable *GroupSyncable) Auditable() map[string]interface{} { + return map[string]interface{}{ + "group_id": syncable.GroupId, + "syncable_id": syncable.SyncableId, + "auto_add": syncable.AutoAdd, + "scheme_admin": syncable.SchemeAdmin, + "create_at": syncable.CreateAt, + "delete_at": syncable.DeleteAt, + "update_at": syncable.UpdateAt, + "type": syncable.Type, + "channel_display_name": syncable.ChannelDisplayName, + "team_display_name": syncable.TeamDisplayName, + "team_type": syncable.TeamType, + "channel_type": syncable.ChannelType, + "team_id": syncable.TeamID, + } +} + func (syncable *GroupSyncable) IsValid() *AppError { if !IsValidId(syncable.GroupId) { return NewAppError("GroupSyncable.SyncableIsValid", "model.group_syncable.group_id.app_error", nil, "", http.StatusBadRequest) diff --git a/model/incoming_webhook.go b/model/incoming_webhook.go index ce7828e4bc..cd020c90dc 100644 --- a/model/incoming_webhook.go +++ b/model/incoming_webhook.go @@ -30,6 +30,23 @@ type IncomingWebhook struct { ChannelLocked bool `json:"channel_locked"` } +func (o *IncomingWebhook) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": o.Id, + "create_at": o.CreateAt, + "update_at": o.UpdateAt, + "delete_at": o.DeleteAt, + "user_id": o.UserId, + "channel_id": o.ChannelId, + "team_id": o.TeamId, + "display_name": o.DisplayName, + "description": o.Description, + "username": o.Username, + "icon_url:": o.IconURL, + "channel_locked": o.ChannelLocked, + } +} + type IncomingWebhookRequest struct { Text string `json:"text"` Username string `json:"username"` diff --git a/model/job.go b/model/job.go index d12c2245b7..b6cdbd5ee3 100644 --- a/model/job.go +++ b/model/job.go @@ -71,6 +71,20 @@ type Job struct { Data StringMap `json:"data"` } +func (j *Job) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": j.Id, + "type": j.Type, + "priority": j.Priority, + "create_at": j.CreateAt, + "start_at": j.StartAt, + "last_activity_at": j.LastActivityAt, + "status": j.Status, + "progress": j.Progress, + "data": j.Data, // TODO do we want this here + } +} + func (j *Job) IsValid() *AppError { if !IsValidId(j.Id) { return NewAppError("Job.IsValid", "model.job.is_valid.id.app_error", nil, "id="+j.Id, http.StatusBadRequest) diff --git a/model/oauth.go b/model/oauth.go index 82dd8fb2f9..911e484321 100644 --- a/model/oauth.go +++ b/model/oauth.go @@ -32,6 +32,22 @@ type OAuthApp struct { MattermostAppID string `json:"mattermost_app_id"` } +func (a *OAuthApp) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": a.Id, + "creator_id": a.CreatorId, + "create_at": a.CreateAt, + "update_at": a.UpdateAt, + "name": a.Name, + "description": a.Description, + "icon_url": a.IconURL, + "callback_urls:": a.CallbackUrls, + "homepage": a.Homepage, + "is_trusted": a.IsTrusted, + "mattermost_app_id": a.MattermostAppID, + } +} + // IsValid validates the app and returns an error if it isn't configured // correctly. func (a *OAuthApp) IsValid() *AppError { diff --git a/model/outgoing_webhook.go b/model/outgoing_webhook.go index b24aed67e1..794b79e175 100644 --- a/model/outgoing_webhook.go +++ b/model/outgoing_webhook.go @@ -30,6 +30,26 @@ type OutgoingWebhook struct { IconURL string `json:"icon_url"` } +func (o *OutgoingWebhook) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": o.Id, + "create_at": o.CreateAt, + "update_at": o.UpdateAt, + "delete_at": o.DeleteAt, + "creator_id": o.CreatorId, + "channel_id": o.ChannelId, + "team_id": o.TeamId, + "trigger_words": o.TriggerWords, + "trigger_when": o.TriggerWhen, + "callback_urls": o.CallbackURLs, + "display_name": o.DisplayName, + "description": o.Description, + "content_type": o.ContentType, + "username": o.Username, + "icon_url": o.IconURL, + } +} + type OutgoingWebhookPayload struct { Token string `json:"token"` TeamId string `json:"team_id"` diff --git a/model/post.go b/model/post.go index e394f68e56..29ac05b263 100644 --- a/model/post.go +++ b/model/post.go @@ -112,6 +112,30 @@ type Post struct { Metadata *PostMetadata `json:"metadata,omitempty"` } +func (o *Post) Auditable() map[string]interface{} { + return map[string]interface{}{ // TODO check this + "id": o.Id, + "create_at": o.CreateAt, + "update_at": o.UpdateAt, + "edit_at": o.EditAt, + "delete_at": o.DeleteAt, + "is_pinned": o.IsPinned, + "user_id": o.UserId, + "channel_id": o.ChannelId, + "root_id": o.RootId, + "original_id": o.OriginalId, + "type": o.Type, + "props": o.GetProps(), + "file_ids": o.FileIds, + "pending_post_id": o.PendingPostId, + "remote_id": o.RemoteId, + "reply_count": o.ReplyCount, + "last_reply_at": o.LastReplyAt, + "is_following": o.IsFollowing, + "metadata": o.Metadata, + } +} + type PostEphemeral struct { UserID string `json:"user_id"` Post *Post `json:"post"` diff --git a/model/role.go b/model/role.go index 82d07fb075..c87e6ca303 100644 --- a/model/role.go +++ b/model/role.go @@ -414,6 +414,21 @@ type Role struct { BuiltIn bool `json:"built_in"` } +func (r *Role) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": r.Id, + "name": r.Name, + "display_name": r.DisplayName, + "description": r.Description, + "create_at": r.CreateAt, + "update_at": r.UpdateAt, + "delete_at": r.DeleteAt, + "permissions": r.Permissions, + "scheme_managed": r.SchemeManaged, + "built_in": r.BuiltIn, + } +} + type RolePatch struct { Permissions *[]string `json:"permissions"` } diff --git a/model/scheme.go b/model/scheme.go index b2bc713c6d..c48621980b 100644 --- a/model/scheme.go +++ b/model/scheme.go @@ -39,6 +39,29 @@ type Scheme struct { DefaultRunMemberRole string `json:"default_run_member_role"` } +func (scheme *Scheme) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": scheme.Id, + "name": scheme.Name, + "display_name": scheme.DisplayName, + "description": scheme.Description, + "create_at": scheme.CreateAt, + "update_at": scheme.UpdateAt, + "delete_at": scheme.DeleteAt, + "scope": scheme.Scope, + "default_team_admin_role": scheme.DefaultTeamAdminRole, + "default_team_user_role": scheme.DefaultTeamUserRole, + "default_channel_admin_role": scheme.DefaultChannelAdminRole, + "default_channel_user_role": scheme.DefaultChannelUserRole, + "default_team_guest_role": scheme.DefaultTeamGuestRole, + "default_channel_guest_role": scheme.DefaultChannelGuestRole, + "default_playbook_admin_role": scheme.DefaultPlaybookAdminRole, + "default_playbook_member_role": scheme.DefaultPlaybookMemberRole, + "default_run_admin_role": scheme.DefaultRunAdminRole, + "default_run_member_role": scheme.DefaultRunMemberRole, + } +} + type SchemePatch struct { Name *string `json:"name"` DisplayName *string `json:"display_name"` @@ -93,6 +116,10 @@ type SchemeRoles struct { SchemeGuest bool `json:"scheme_guest"` } +func (s *SchemeRoles) Auditable() map[string]interface{} { + return map[string]interface{}{} +} + func (scheme *Scheme) IsValid() bool { if !IsValidId(scheme.Id) { return false diff --git a/model/session.go b/model/session.go index c880b9884f..d19c310f2e 100644 --- a/model/session.go +++ b/model/session.go @@ -58,6 +58,22 @@ type Session struct { Local bool `json:"local" db:"-"` } +func (s *Session) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": s.Id, + "create_at": s.CreateAt, + "expires_at": s.ExpiresAt, + "last_activity_at": s.LastActivityAt, + "user_id": s.UserId, + "device_id": s.DeviceId, + "roles": s.Roles, + "is_oauth": s.IsOAuth, + "expired_notify": s.ExpiredNotify, + "local": s.Local, + // TODO: props and members? + } +} + // Returns true if the session is unrestricted, which should grant it // with all permissions. This is used for local mode sessions func (s *Session) IsUnrestricted() bool { diff --git a/model/team.go b/model/team.go index b5b67a03c8..07b0d061aa 100644 --- a/model/team.go +++ b/model/team.go @@ -44,6 +44,22 @@ type Team struct { CloudLimitsArchived bool `json:"cloud_limits_archived"` } +func (o *Team) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": o.Id, + "create_at": o.CreateAt, + "update_at": o.UpdateAt, + "delete_at": o.DeleteAt, + "type": o.Type, + "invite_id": o.InviteId, + "allow_open_invite": o.AllowOpenInvite, + "scheme_id": o.SchemeId, + "group_constrained": o.GroupConstrained, + "policy_id": o.PolicyID, + "cloud_limits_archived": o.CloudLimitsArchived, + } +} + type TeamPatch struct { DisplayName *string `json:"display_name"` Description *string `json:"description"` diff --git a/model/team_member.go b/model/team_member.go index 7782080ef2..bbd317369f 100644 --- a/model/team_member.go +++ b/model/team_member.go @@ -27,6 +27,19 @@ type TeamMember struct { ExplicitRoles string `json:"explicit_roles"` } +func (o *TeamMember) Auditable() map[string]interface{} { + return map[string]interface{}{ + "team_id": o.TeamId, + "user_id": o.UserId, + "roles": o.Roles, + "delete_at": o.DeleteAt, + "scheme_guest": o.SchemeGuest, + "scheme_user": o.SchemeUser, + "scheme_admin": o.SchemeAdmin, + "explicit_roles": o.ExplicitRoles, + } +} + //msgp:ignore TeamUnread type TeamUnread struct { TeamId string `json:"team_id"` diff --git a/model/user.go b/model/user.go index d4250692b9..39163d168d 100644 --- a/model/user.go +++ b/model/user.go @@ -105,6 +105,38 @@ type User struct { DisableWelcomeEmail bool `json:"disable_welcome_email"` } +func (u *User) Auditable() map[string]interface{} { + return map[string]interface{}{ + "id": u.Id, + "create_at": u.CreateAt, + "update_at": u.UpdateAt, + "delete_at": u.DeleteAt, + "username": u.Username, + "auth_service": u.AuthService, + "email": u.Email, + "email_verified": u.EmailVerified, + "position": u.Position, + "roles": u.Roles, + "allow_marketing": u.AllowMarketing, + "props": u.Props, + "notify_props": u.NotifyProps, + "last_password_update": u.LastPasswordUpdate, + "last_picture_update": u.LastPictureUpdate, + "failed_attempts": u.FailedAttempts, + "locale": u.Locale, + "timezone": u.Timezone, + "mfa_active": u.MfaActive, + "remote_id": u.RemoteId, + "last_activity_at": u.LastActivityAt, + "is_bot": u.IsBot, + "bot_description": u.BotDescription, + "bot_last_icon_update": u.BotLastIconUpdate, + "terms_of_service_id": u.TermsOfServiceId, + "terms_of_service_create_at": u.TermsOfServiceCreateAt, + "disable_welcome_email": u.DisableWelcomeEmail, + } +} + //msgp UserMap // UserMap is a map from a userId to a user object. @@ -133,6 +165,22 @@ type UserPatch struct { RemoteId *string `json:"remote_id"` } +func (u *UserPatch) Auditable() map[string]interface{} { + return map[string]interface{}{ + "username": u.Username, + "nickname": u.Nickname, + "first_name": u.FirstName, + "last_name": u.LastName, + "position": u.Position, + "email": u.Email, + "props": u.Props, + "notify_props": u.NotifyProps, + "locale": u.Locale, + "timezone": u.Timezone, + "remote_id": u.RemoteId, + } +} + //msgp:ignore UserAuth type UserAuth struct { Password string `json:"password,omitempty"` // DEPRECATED: It is not used. @@ -835,13 +883,6 @@ func (u *User) ToPatch() *UserPatch { } } -func (u *User) Auditable() map[string]interface{} { - return map[string]interface{}{ - "id": u.Id, - "username": u.Username, - } -} - func (u *UserPatch) SetField(fieldName string, fieldValue string) { switch fieldName { case "FirstName":