From 3c5280119357e3742811fd724601d0bef01bcb29 Mon Sep 17 00:00:00 2001 From: David Meza Date: Fri, 1 Sep 2017 08:53:55 -0500 Subject: Config to make town square read only (#7140) * Be able to make Town Square read-only (Disable typing messages for non admins). * Do not emit UserTypingEvent when TownSquareIsReadOnly and is Town Square. * Add unit tests for TownSquareIsReadOnly config value and logic. * Add TownSquareIsReadOnly to System console>Policy. Added Telemetry. * Add control for TownSquareIsReadOnly=true only for License Enterprise Edition E10 & E20. * Update en.json * Update en.json * Update policy_settings.jsx * Change config value from TownSquareIsReadOnly to ExperimentalTownSquareIsReadOnly. * Refactored to simplify. Avoid code repeat and multiple db calls. --- api/context.go | 2 +- api/post_test.go | 39 +++++++++++++++++++++++++++++++++++++++ api/webhook_test.go | 25 ++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) (limited to 'api') diff --git a/api/context.go b/api/context.go index fe3448ebd..9f09540e6 100644 --- a/api/context.go +++ b/api/context.go @@ -282,7 +282,7 @@ func (c *Context) LogError(err *model.AppError) { // filter out endless reconnects if c.Path == "/api/v3/users/websocket" && err.StatusCode == 401 || err.Id == "web.check_browser_compatibility.app_error" { c.LogDebug(err) - } else { + } else if err.Id != "api.post.create_post.town_square_read_only" { l4g.Error(utils.TDefault("api.context.log.error"), c.Path, err.Where, err.StatusCode, c.RequestId, c.Session.UserId, c.IpAddress, err.SystemMessage(utils.TDefault), err.DetailedError) } diff --git a/api/post_test.go b/api/post_test.go index c31439c82..18bf22f5c 100644 --- a/api/post_test.go +++ b/api/post_test.go @@ -22,6 +22,12 @@ import ( ) func TestCreatePost(t *testing.T) { + adm := Setup().InitSystemAdmin() + AdminClient := adm.SystemAdminClient + adminTeam := adm.SystemAdminTeam + adminUser := adm.CreateUser(adm.SystemAdminClient) + LinkUserToTeam(adminUser, adminTeam) + th := Setup().InitBasic() Client := th.BasicClient team := th.BasicTeam @@ -142,6 +148,39 @@ func TestCreatePost(t *testing.T) { t.Fatal("should've attached all 3 files to post") } } + + isLicensed := utils.IsLicensed() + license := utils.License() + disableTownSquareReadOnly := utils.Cfg.TeamSettings.ExperimentalTownSquareIsReadOnly + defer func() { + utils.Cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = disableTownSquareReadOnly + utils.SetIsLicensed(isLicensed) + utils.SetLicense(license) + utils.SetDefaultRolesBasedOnConfig() + }() + *utils.Cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true + utils.SetDefaultRolesBasedOnConfig() + utils.SetIsLicensed(true) + utils.SetLicense(&model.License{Features: &model.Features{}}) + utils.License().Features.SetDefaults() + + defaultChannel := store.Must(app.Srv.Store.Channel().GetByName(team.Id, model.DEFAULT_CHANNEL, true)).(*model.Channel) + defaultPost := &model.Post{ + ChannelId: defaultChannel.Id, + Message: "Default Channel Post", + } + if _, err = Client.CreatePost(defaultPost); err == nil { + t.Fatal("should have failed -- ExperimentalTownSquareIsReadOnly is true and it's a read only channel") + } + + adminDefaultChannel := store.Must(app.Srv.Store.Channel().GetByName(adminTeam.Id, model.DEFAULT_CHANNEL, true)).(*model.Channel) + adminDefaultPost := &model.Post{ + ChannelId: adminDefaultChannel.Id, + Message: "Admin Default Channel Post", + } + if _, err = AdminClient.CreatePost(adminDefaultPost); err != nil { + t.Fatal("should not have failed -- ExperimentalTownSquareIsReadOnly is true and admin can post to channel") + } } func TestCreatePostWithCreateAt(t *testing.T) { diff --git a/api/webhook_test.go b/api/webhook_test.go index 93d596bb1..c84aee992 100644 --- a/api/webhook_test.go +++ b/api/webhook_test.go @@ -956,7 +956,7 @@ func TestRegenOutgoingHookToken(t *testing.T) { } func TestIncomingWebhooks(t *testing.T) { - th := Setup().InitSystemAdmin() + th := Setup().InitBasic().InitSystemAdmin() Client := th.SystemAdminClient team := th.SystemAdminTeam channel1 := th.CreateChannel(Client, team) @@ -1004,6 +1004,29 @@ func TestIncomingWebhooks(t *testing.T) { t.Fatal(err) } + if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err != nil { + t.Fatal("should not have failed -- ExperimentalTownSquareIsReadOnly is false and it's not a read only channel") + } + + isLicensed := utils.IsLicensed() + license := utils.License() + disableTownSquareReadOnly := utils.Cfg.TeamSettings.ExperimentalTownSquareIsReadOnly + defer func() { + utils.Cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = disableTownSquareReadOnly + utils.SetIsLicensed(isLicensed) + utils.SetLicense(license) + utils.SetDefaultRolesBasedOnConfig() + }() + *utils.Cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true + utils.SetDefaultRolesBasedOnConfig() + utils.SetIsLicensed(true) + utils.SetLicense(&model.License{Features: &model.Features{}}) + utils.License().Features.SetDefaults() + + if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err == nil { + t.Fatal("should have failed -- ExperimentalTownSquareIsReadOnly is true and it's a read only channel") + } + attachmentPayload := `{ "text": "this is a test", "attachments": [ -- cgit v1.2.3-1-g7c22