MM-22273 New auditing system (phase 1) (#13967)
* New auditing API outputting to syslog via TLS * New config section for specifying remote syslog server IP, port, and cert. * Legacy audit API retained for access history feature
Этот коммит содержится в:
162
api4/team.go
162
api4/team.go
@@ -15,6 +15,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/audit"
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
)
|
||||
|
||||
@@ -81,6 +82,11 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
team.Email = strings.ToLower(team.Email)
|
||||
|
||||
auditRec := c.MakeAuditRecord("createTeam", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_name", team.Name)
|
||||
auditRec.AddMeta("team_display", team.DisplayName)
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_CREATE_TEAM) {
|
||||
c.Err = model.NewAppError("createTeam", "api.team.is_team_creation_allowed.disabled.app_error", nil, "", http.StatusForbidden)
|
||||
return
|
||||
@@ -94,6 +100,9 @@ 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_id", rteam.Id)
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(rteam.ToJson()))
|
||||
}
|
||||
@@ -160,6 +169,12 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("updateTeam", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
auditRec.AddMeta("team_name", team.Name)
|
||||
auditRec.AddMeta("team_display", team.DisplayName)
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
|
||||
return
|
||||
@@ -171,6 +186,8 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
|
||||
c.App.SanitizeTeam(*c.App.Session(), updatedTeam)
|
||||
w.Write([]byte(updatedTeam.ToJson()))
|
||||
}
|
||||
@@ -188,6 +205,10 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("patchTeam", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
|
||||
return
|
||||
@@ -202,7 +223,11 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
c.App.SanitizeTeam(*c.App.Session(), patchedTeam)
|
||||
|
||||
auditRec.Success()
|
||||
auditRec.AddMeta("team_name", patchedTeam.Name)
|
||||
auditRec.AddMeta("team_display", patchedTeam.DisplayName)
|
||||
c.LogAudit("")
|
||||
|
||||
w.Write([]byte(patchedTeam.ToJson()))
|
||||
}
|
||||
|
||||
@@ -217,6 +242,10 @@ func regenerateTeamInviteId(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("regenerateTeamInviteId", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
patchedTeam, err := c.App.RegenerateTeamInviteId(c.Params.TeamId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
@@ -225,7 +254,11 @@ func regenerateTeamInviteId(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
|
||||
c.App.SanitizeTeam(*c.App.Session(), patchedTeam)
|
||||
|
||||
auditRec.Success()
|
||||
auditRec.AddMeta("team_name", patchedTeam.Name)
|
||||
auditRec.AddMeta("team_display", patchedTeam.DisplayName)
|
||||
c.LogAudit("")
|
||||
|
||||
w.Write([]byte(patchedTeam.ToJson()))
|
||||
}
|
||||
|
||||
@@ -240,6 +273,10 @@ func deleteTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("deleteTeam", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
var err *model.AppError
|
||||
if c.Params.Permanent && *c.App.Config().ServiceSettings.EnableAPITeamDeletion {
|
||||
err = c.App.PermanentDeleteTeamId(c.Params.TeamId)
|
||||
@@ -252,6 +289,7 @@ func deleteTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -438,6 +476,11 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("addTeamMember", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
auditRec.AddMeta("add_user_id", member.UserId)
|
||||
|
||||
if member.UserId == c.App.Session().UserId {
|
||||
var team *model.Team
|
||||
team, err = c.App.GetTeam(member.TeamId)
|
||||
@@ -466,6 +509,8 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
auditRec.AddMeta("team_name", team.Name)
|
||||
auditRec.AddMeta("team_display", team.DisplayName)
|
||||
|
||||
if team.IsGroupConstrained() {
|
||||
nonMembers, err := c.App.FilterNonGroupTeamMembers([]string{member.UserId}, team)
|
||||
@@ -490,6 +535,8 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(member.ToJson()))
|
||||
}
|
||||
@@ -501,6 +548,10 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
var member *model.TeamMember
|
||||
var err *model.AppError
|
||||
|
||||
auditRec := c.MakeAuditRecord("addUserToTeamFromInvite", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("invite_id", inviteId)
|
||||
|
||||
if len(tokenId) > 0 {
|
||||
member, err = c.App.AddTeamMemberByToken(c.App.Session().UserId, tokenId)
|
||||
} else if len(inviteId) > 0 {
|
||||
@@ -519,6 +570,11 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
if member != nil {
|
||||
auditRec.AddMeta("add_user_id", member.UserId)
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte(member.ToJson()))
|
||||
}
|
||||
@@ -544,16 +600,24 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("addTeamMembers", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
auditRec.AddMeta("count", len(members))
|
||||
|
||||
var memberIDs []string
|
||||
for _, member := range members {
|
||||
memberIDs = append(memberIDs, member.UserId)
|
||||
}
|
||||
auditRec.AddMeta("user_ids", memberIDs)
|
||||
|
||||
team, err := c.App.GetTeam(c.Params.TeamId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
auditRec.AddMeta("team_name", team.Name)
|
||||
auditRec.AddMeta("team_display", team.DisplayName)
|
||||
|
||||
if team.IsGroupConstrained() {
|
||||
nonMembers, err := c.App.FilterNonGroupTeamMembers(memberIDs, team)
|
||||
@@ -593,11 +657,22 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
membersWithErrors, err := c.App.AddTeamMembers(c.Params.TeamId, userIds, c.App.Session().UserId, graceful)
|
||||
|
||||
if membersWithErrors != nil {
|
||||
errList := make([]string, 0, len(membersWithErrors))
|
||||
for _, m := range membersWithErrors {
|
||||
if m.Error != nil {
|
||||
errList = append(errList, model.TeamMemberWithErrorToString(m))
|
||||
}
|
||||
}
|
||||
auditRec.AddMeta("errors", errList)
|
||||
}
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
|
||||
if graceful {
|
||||
@@ -615,6 +690,10 @@ func removeTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("removeTeamMember", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
if c.App.Session().UserId != c.Params.UserId {
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_REMOVE_USER_FROM_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_REMOVE_USER_FROM_TEAM)
|
||||
@@ -627,12 +706,15 @@ func removeTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
auditRec.AddMeta("team_name", team.Name)
|
||||
auditRec.AddMeta("team_display", team.DisplayName)
|
||||
|
||||
user, err := c.App.GetUser(c.Params.UserId)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
auditRec.AddMeta("remove_user_id", user.Id)
|
||||
|
||||
if team.IsGroupConstrained() && (c.Params.UserId != c.App.Session().UserId) && !user.IsBot {
|
||||
c.Err = model.NewAppError("removeTeamMember", "api.team.remove_member.group_constrained.app_error", nil, "", http.StatusBadRequest)
|
||||
@@ -644,6 +726,7 @@ func removeTeamMember(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -712,6 +795,11 @@ func updateTeamMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("updateTeamMemberRoles", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
auditRec.AddMeta("update_user_id", c.Params.UserId)
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_MANAGE_TEAM_ROLES) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM_ROLES)
|
||||
return
|
||||
@@ -722,6 +810,7 @@ func updateTeamMemberRoles(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -737,6 +826,14 @@ func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("updateTeamMemberSchemeRoles", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
auditRec.AddMeta("update_user_id", c.Params.UserId)
|
||||
auditRec.AddMeta("new_scheme_admin", schemeRoles.SchemeAdmin)
|
||||
auditRec.AddMeta("new_scheme_user", schemeRoles.SchemeUser)
|
||||
auditRec.AddMeta("new_scheme_guest", schemeRoles.SchemeGuest)
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_MANAGE_TEAM_ROLES) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM_ROLES)
|
||||
return
|
||||
@@ -747,6 +844,7 @@ func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Requ
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -925,6 +1023,10 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("importTeam", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
fileInfo := fileInfoArray[0]
|
||||
|
||||
fileData, err := fileInfo.Open()
|
||||
@@ -933,6 +1035,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)
|
||||
|
||||
var log *bytes.Buffer
|
||||
switch importFrom {
|
||||
@@ -949,6 +1054,7 @@ func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
if c.Err != nil {
|
||||
w.WriteHeader(c.Err.StatusCode)
|
||||
}
|
||||
auditRec.Success()
|
||||
w.Write([]byte(model.MapToJson(data)))
|
||||
}
|
||||
|
||||
@@ -980,8 +1086,23 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("inviteUsersToTeam", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
auditRec.AddMeta("count", len(emailList))
|
||||
auditRec.AddMeta("emails", emailList)
|
||||
|
||||
if graceful {
|
||||
invitesWithError, err := c.App.InviteNewUsersToTeamGracefully(emailList, c.Params.TeamId, c.App.Session().UserId)
|
||||
if invitesWithError != nil {
|
||||
errList := make([]string, 0, len(invitesWithError))
|
||||
for _, inv := range invitesWithError {
|
||||
if inv.Error != nil {
|
||||
errList = append(errList, model.EmailInviteWithErrorToString(inv))
|
||||
}
|
||||
}
|
||||
auditRec.AddMeta("errors", errList)
|
||||
}
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
@@ -996,6 +1117,7 @@ func inviteUsersToTeam(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
auditRec.Success()
|
||||
}
|
||||
|
||||
func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
@@ -1015,6 +1137,10 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("inviteGuestsToChannels", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_INVITE_GUEST) {
|
||||
c.SetPermissionError(model.PERMISSION_INVITE_GUEST)
|
||||
return
|
||||
@@ -1028,10 +1154,19 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
auditRec.AddMeta("email_count", len(guestsInvite.Emails))
|
||||
auditRec.AddMeta("emails", guestsInvite.Emails)
|
||||
auditRec.AddMeta("channel_count", len(guestsInvite.Channels))
|
||||
auditRec.AddMeta("channels", guestsInvite.Channels)
|
||||
|
||||
if graceful {
|
||||
invitesWithError, err := c.App.InviteGuestsToChannelsGracefully(c.Params.TeamId, guestsInvite, c.App.Session().UserId)
|
||||
if err != nil {
|
||||
errList := make([]string, 0, len(invitesWithError))
|
||||
for _, inv := range invitesWithError {
|
||||
errList = append(errList, model.EmailInviteWithErrorToString(inv))
|
||||
}
|
||||
auditRec.AddMeta("errors", errList)
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
@@ -1045,6 +1180,7 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
auditRec.Success()
|
||||
}
|
||||
|
||||
func getInviteInfo(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
@@ -1078,11 +1214,15 @@ func invalidateAllEmailInvites(c *Context, w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("invalidateAllEmailInvites", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
|
||||
if err := c.App.InvalidateAllEmailInvites(); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -1131,6 +1271,10 @@ func setTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("setTeamIcon", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
|
||||
return
|
||||
@@ -1166,7 +1310,9 @@ func setTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
c.LogAudit("")
|
||||
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -1176,6 +1322,10 @@ func removeTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("removeTeamIcon", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
if !c.App.SessionHasPermissionToTeam(*c.App.Session(), c.Params.TeamId, model.PERMISSION_MANAGE_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
|
||||
return
|
||||
@@ -1186,7 +1336,9 @@ func removeTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
c.LogAudit("")
|
||||
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
@@ -1202,6 +1354,10 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec := c.MakeAuditRecord("updateTeamScheme", audit.Fail)
|
||||
defer c.LogAuditRec(auditRec)
|
||||
auditRec.AddMeta("team_id", c.Params.TeamId)
|
||||
|
||||
if c.App.License() == nil {
|
||||
c.Err = model.NewAppError("Api4.UpdateTeamScheme", "api.team.update_team_scheme.license.error", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
@@ -1218,6 +1374,9 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
auditRec.AddMeta("scheme_id", scheme.Id)
|
||||
auditRec.AddMeta("scheme_name", scheme.Name)
|
||||
auditRec.AddMeta("scheme_display", scheme.DisplayName)
|
||||
|
||||
if scheme.Scope != model.SCHEME_SCOPE_TEAM {
|
||||
c.Err = model.NewAppError("Api4.UpdateTeamScheme", "api.team.update_team_scheme.scheme_scope.error", nil, "", http.StatusBadRequest)
|
||||
@@ -1230,6 +1389,8 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
auditRec.AddMeta("team_name", team.Name)
|
||||
auditRec.AddMeta("team_display", team.DisplayName)
|
||||
|
||||
team.SchemeId = schemeID
|
||||
|
||||
@@ -1239,6 +1400,7 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
auditRec.Success()
|
||||
ReturnStatusOK(w)
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user