summaryrefslogtreecommitdiffstats
path: root/api4
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2018-05-31 10:25:31 +0100
committerGeorge Goldberg <george@gberg.me>2018-05-31 10:25:31 +0100
commit27e7841a734e9c3ed71f988a653f5865d2ef6f91 (patch)
tree1ccc65246fb166c25a9923f4e05ad7d6223892d1 /api4
parente39f5f46f3f6cdcb7ab8aeef8c601047f5942f85 (diff)
parent994ccf475f96bcad668269fe25b0d22e975bc222 (diff)
downloadchat-27e7841a734e9c3ed71f988a653f5865d2ef6f91.tar.gz
chat-27e7841a734e9c3ed71f988a653f5865d2ef6f91.tar.bz2
chat-27e7841a734e9c3ed71f988a653f5865d2ef6f91.zip
Merge branch 'advanced-permissions-phase-2'
Diffstat (limited to 'api4')
-rw-r--r--api4/api.go5
-rw-r--r--api4/apitestlib.go25
-rw-r--r--api4/channel.go51
-rw-r--r--api4/channel_test.go78
-rw-r--r--api4/emoji.go66
-rw-r--r--api4/emoji_test.go124
-rw-r--r--api4/post.go41
-rw-r--r--api4/role.go1
-rw-r--r--api4/scheme.go211
-rw-r--r--api4/scheme_test.go737
-rw-r--r--api4/team.go53
-rw-r--r--api4/team_test.go76
12 files changed, 1442 insertions, 26 deletions
diff --git a/api4/api.go b/api4/api.go
index 918154c0d..02b884db7 100644
--- a/api4/api.go
+++ b/api4/api.go
@@ -97,7 +97,8 @@ type Routes struct {
Reactions *mux.Router // 'api/v4/reactions'
- Roles *mux.Router // 'api/v4/roles'
+ Roles *mux.Router // 'api/v4/roles'
+ Schemes *mux.Router // 'api/v4/schemes'
Emojis *mux.Router // 'api/v4/emoji'
Emoji *mux.Router // 'api/v4/emoji/{emoji_id:[A-Za-z0-9]+}'
@@ -198,6 +199,7 @@ func Init(a *app.App, root *mux.Router) *API {
api.BaseRoutes.OpenGraph = api.BaseRoutes.ApiRoot.PathPrefix("/opengraph").Subrouter()
api.BaseRoutes.Roles = api.BaseRoutes.ApiRoot.PathPrefix("/roles").Subrouter()
+ api.BaseRoutes.Schemes = api.BaseRoutes.ApiRoot.PathPrefix("/schemes").Subrouter()
api.BaseRoutes.Image = api.BaseRoutes.ApiRoot.PathPrefix("/image").Subrouter()
@@ -227,6 +229,7 @@ func Init(a *app.App, root *mux.Router) *API {
api.InitOpenGraph()
api.InitPlugin()
api.InitRole()
+ api.InitScheme()
api.InitImage()
root.Handle("/api/v4/{anything:.*}", http.HandlerFunc(api.Handle404))
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index 86150e05a..22084a1d6 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -125,6 +125,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
wsapi.Init(th.App, th.App.Srv.WebSocketRouter)
th.App.Srv.Store.MarkSystemRanUnitTests()
th.App.DoAdvancedPermissionsMigration()
+ th.App.DoEmojisPermissionsMigration()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
@@ -767,7 +768,7 @@ func (me *TestHelper) MakeUserChannelAdmin(user *model.User, channel *model.Chan
if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
cm := cmr.Data.(*model.ChannelMember)
- cm.Roles = "channel_admin channel_user"
+ cm.SchemeAdmin = true
if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil {
utils.EnableDebugLogForTest()
panic(sr.Err)
@@ -783,28 +784,42 @@ func (me *TestHelper) MakeUserChannelAdmin(user *model.User, channel *model.Chan
func (me *TestHelper) UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
- tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID + " " + model.TEAM_ADMIN_ROLE_ID}
- if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
+ if tmr := <-me.App.Srv.Store.Team().GetMember(team.Id, user.Id); tmr.Err == nil {
+ tm := tmr.Data.(*model.TeamMember)
+ tm.SchemeAdmin = true
+ if sr := <-me.App.Srv.Store.Team().UpdateMember(tm); sr.Err != nil {
+ utils.EnableDebugLogForTest()
+ panic(sr.Err)
+ }
+ } else {
utils.EnableDebugLogForTest()
mlog.Error(tmr.Err.Error())
time.Sleep(time.Second)
panic(tmr.Err)
}
+
utils.EnableDebugLogForTest()
}
func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Team) {
utils.DisableDebugLogForTest()
- tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID}
- if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
+ if tmr := <-me.App.Srv.Store.Team().GetMember(team.Id, user.Id); tmr.Err == nil {
+ tm := tmr.Data.(*model.TeamMember)
+ tm.SchemeAdmin = false
+ if sr := <-me.App.Srv.Store.Team().UpdateMember(tm); sr.Err != nil {
+ utils.EnableDebugLogForTest()
+ panic(sr.Err)
+ }
+ } else {
utils.EnableDebugLogForTest()
mlog.Error(tmr.Err.Error())
time.Sleep(time.Second)
panic(tmr.Err)
}
+
utils.EnableDebugLogForTest()
}
diff --git a/api4/channel.go b/api4/channel.go
index 1026a41ad..e5101ada8 100644
--- a/api4/channel.go
+++ b/api4/channel.go
@@ -15,6 +15,7 @@ func (api *API) InitChannel() {
api.BaseRoutes.Channels.Handle("/direct", api.ApiSessionRequired(createDirectChannel)).Methods("POST")
api.BaseRoutes.Channels.Handle("/group", api.ApiSessionRequired(createGroupChannel)).Methods("POST")
api.BaseRoutes.Channels.Handle("/members/{user_id:[A-Za-z0-9]+}/view", api.ApiSessionRequired(viewChannel)).Methods("POST")
+ api.BaseRoutes.Channels.Handle("/{channel_id:[A-Za-z0-9]+}/scheme", api.ApiSessionRequired(updateChannelScheme)).Methods("PUT")
api.BaseRoutes.ChannelsForTeam.Handle("", api.ApiSessionRequired(getPublicChannelsForTeam)).Methods("GET")
api.BaseRoutes.ChannelsForTeam.Handle("/deleted", api.ApiSessionRequired(getDeletedChannelsForTeam)).Methods("GET")
@@ -946,3 +947,53 @@ func removeChannelMember(c *Context, w http.ResponseWriter, r *http.Request) {
ReturnStatusOK(w)
}
+
+func updateChannelScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireChannelId()
+ if c.Err != nil {
+ return
+ }
+
+ schemeID := model.SchemeIDFromJson(r.Body)
+ if schemeID == nil || len(*schemeID) != 26 {
+ c.SetInvalidParam("scheme_id")
+ return
+ }
+
+ if c.App.License() == nil {
+ c.Err = model.NewAppError("Api4.UpdateChannelScheme", "api.channel.update_channel_scheme.license.error", nil, "", http.StatusNotImplemented)
+ return
+ }
+
+ if !c.App.SessionHasPermissionToChannel(c.Session, c.Params.ChannelId, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ scheme, err := c.App.GetScheme(*schemeID)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ if scheme.Scope != model.SCHEME_SCOPE_CHANNEL {
+ c.Err = model.NewAppError("Api4.UpdateChannelScheme", "api.channel.update_channel_scheme.scheme_scope.error", nil, "", http.StatusBadRequest)
+ return
+ }
+
+ channel, err := c.App.GetChannel(c.Params.ChannelId)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ channel.SchemeId = &scheme.Id
+
+ _, err = c.App.UpdateChannelScheme(channel)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ ReturnStatusOK(w)
+}
diff --git a/api4/channel_test.go b/api4/channel_test.go
index 2a1e78753..7b677f77f 100644
--- a/api4/channel_test.go
+++ b/api4/channel_test.go
@@ -1463,7 +1463,7 @@ func TestUpdateChannelRoles(t *testing.T) {
defer th.TearDown()
Client := th.Client
- const CHANNEL_ADMIN = "channel_admin channel_user"
+ const CHANNEL_ADMIN = "channel_user channel_admin"
const CHANNEL_MEMBER = "channel_user"
// User 1 creates a channel, making them channel admin by default.
@@ -1914,3 +1914,79 @@ func TestAutocompleteChannels(t *testing.T) {
}
}
}
+
+func TestUpdateChannelScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense(""))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ team := &model.Team{
+ DisplayName: "Name",
+ Description: "Some description",
+ CompanyName: "Some company name",
+ AllowOpenInvite: false,
+ InviteId: "inviteid0",
+ Name: "z-z-" + model.NewId() + "a",
+ Email: "success+" + model.NewId() + "@simulator.amazonses.com",
+ Type: model.TEAM_OPEN,
+ }
+ team, _ = th.SystemAdminClient.CreateTeam(team)
+
+ channel := &model.Channel{
+ DisplayName: "Name",
+ Name: "z-z-" + model.NewId() + "a",
+ Type: model.CHANNEL_OPEN,
+ TeamId: team.Id,
+ }
+ channel, _ = th.SystemAdminClient.CreateChannel(channel)
+
+ channelScheme := &model.Scheme{
+ DisplayName: "DisplayName",
+ Name: model.NewId(),
+ Description: "Some description",
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+ channelScheme, _ = th.SystemAdminClient.CreateScheme(channelScheme)
+ teamScheme := &model.Scheme{
+ DisplayName: "DisplayName",
+ Name: model.NewId(),
+ Description: "Some description",
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+ teamScheme, _ = th.SystemAdminClient.CreateScheme(teamScheme)
+
+ // Test the setup/base case.
+ _, resp := th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id)
+ CheckNoError(t, resp)
+
+ // Test various invalid channel and scheme id combinations.
+ _, resp = th.SystemAdminClient.UpdateChannelScheme(channel.Id, "x")
+ CheckBadRequestStatus(t, resp)
+ _, resp = th.SystemAdminClient.UpdateChannelScheme("x", channelScheme.Id)
+ CheckBadRequestStatus(t, resp)
+ _, resp = th.SystemAdminClient.UpdateChannelScheme("x", "x")
+ CheckBadRequestStatus(t, resp)
+
+ // Test that permissions are required.
+ _, resp = th.Client.UpdateChannelScheme(channel.Id, channelScheme.Id)
+ CheckForbiddenStatus(t, resp)
+
+ // Test that a license is requried.
+ th.App.SetLicense(nil)
+ _, resp = th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id)
+ CheckNotImplementedStatus(t, resp)
+ th.App.SetLicense(model.NewTestLicense(""))
+
+ // Test an invalid scheme scope.
+ _, resp = th.SystemAdminClient.UpdateChannelScheme(channel.Id, teamScheme.Id)
+ fmt.Printf("resp: %+v\n", resp)
+ CheckBadRequestStatus(t, resp)
+
+ // Test that an unauthenticated user gets rejected.
+ th.SystemAdminClient.Logout()
+ _, resp = th.SystemAdminClient.UpdateChannelScheme(channel.Id, channelScheme.Id)
+ CheckUnauthorizedStatus(t, resp)
+}
diff --git a/api4/emoji.go b/api4/emoji.go
index cfb5dd6ab..42f66a22a 100644
--- a/api4/emoji.go
+++ b/api4/emoji.go
@@ -33,12 +33,6 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if emojiInterface := c.App.Emoji; emojiInterface != nil &&
- !emojiInterface.CanUserCreateEmoji(c.Session.Roles, c.Session.TeamMembers) {
- c.Err = model.NewAppError("getEmoji", "api.emoji.disabled.app_error", nil, "user_id="+c.Session.UserId, http.StatusUnauthorized)
- return
- }
-
if len(*c.App.Config().FileSettings.DriverName) == 0 {
c.Err = model.NewAppError("createEmoji", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented)
return
@@ -54,6 +48,28 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
+ // Allow any user with MANAGE_EMOJIS permission at Team level to manage emojis at system level
+ memberships, err := c.App.GetTeamMembersForUser(c.Session.UserId)
+
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_EMOJIS) {
+ hasPermission := false
+ for _, membership := range memberships {
+ if c.App.SessionHasPermissionToTeam(c.Session, membership.TeamId, model.PERMISSION_MANAGE_EMOJIS) {
+ hasPermission = true
+ break
+ }
+ }
+ if !hasPermission {
+ c.SetPermissionError(model.PERMISSION_MANAGE_EMOJIS)
+ return
+ }
+ }
+
m := r.MultipartForm
props := m.Value
@@ -110,11 +126,45 @@ func deleteEmoji(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if c.Session.UserId != emoji.CreatorId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
- c.Err = model.NewAppError("deleteImage", "api.emoji.delete.permissions.app_error", nil, "user_id="+c.Session.UserId, http.StatusUnauthorized)
+ // Allow any user with MANAGE_EMOJIS permission at Team level to manage emojis at system level
+ memberships, err := c.App.GetTeamMembersForUser(c.Session.UserId)
+
+ if err != nil {
+ c.Err = err
return
}
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_EMOJIS) {
+ hasPermission := false
+ for _, membership := range memberships {
+ if c.App.SessionHasPermissionToTeam(c.Session, membership.TeamId, model.PERMISSION_MANAGE_EMOJIS) {
+ hasPermission = true
+ break
+ }
+ }
+ if !hasPermission {
+ c.SetPermissionError(model.PERMISSION_MANAGE_EMOJIS)
+ return
+ }
+ }
+
+ if c.Session.UserId != emoji.CreatorId {
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OTHERS_EMOJIS) {
+ hasPermission := false
+ for _, membership := range memberships {
+ if c.App.SessionHasPermissionToTeam(c.Session, membership.TeamId, model.PERMISSION_MANAGE_OTHERS_EMOJIS) {
+ hasPermission = true
+ break
+ }
+ }
+
+ if !hasPermission {
+ c.SetPermissionError(model.PERMISSION_MANAGE_OTHERS_EMOJIS)
+ return
+ }
+ }
+ }
+
err = c.App.DeleteEmoji(emoji)
if err != nil {
c.Err = err
diff --git a/api4/emoji_test.go b/api4/emoji_test.go
index 39da4aaef..cb6398312 100644
--- a/api4/emoji_test.go
+++ b/api4/emoji_test.go
@@ -26,6 +26,11 @@ func TestCreateEmoji(t *testing.T) {
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCustomEmoji = false })
+ defaultRolePermissions := th.SaveDefaultRolePermissions()
+ defer func() {
+ th.RestoreDefaultRolePermissions(defaultRolePermissions)
+ }()
+
emoji := &model.Emoji{
CreatorId: th.BasicUser.Id,
Name: model.NewId(),
@@ -141,6 +146,28 @@ func TestCreateEmoji(t *testing.T) {
_, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
CheckForbiddenStatus(t, resp)
+
+ // try to create an emoji without permissions
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+
+ emoji = &model.Emoji{
+ CreatorId: th.BasicUser.Id,
+ Name: model.NewId(),
+ }
+
+ _, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
+ CheckForbiddenStatus(t, resp)
+
+ // create an emoji with permissions in one team
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.TEAM_USER_ROLE_ID)
+
+ emoji = &model.Emoji{
+ CreatorId: th.BasicUser.Id,
+ Name: model.NewId(),
+ }
+
+ _, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
+ CheckNoError(t, resp)
}
func TestGetEmojiList(t *testing.T) {
@@ -186,7 +213,7 @@ func TestGetEmojiList(t *testing.T) {
}
}
if !found {
- t.Fatalf("failed to get emoji with id %v", emoji.Id)
+ t.Fatalf("failed to get emoji with id %v, %v", emoji.Id, len(listEmoji))
}
}
@@ -231,6 +258,11 @@ func TestDeleteEmoji(t *testing.T) {
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableCustomEmoji = true })
+ defaultRolePermissions := th.SaveDefaultRolePermissions()
+ defer func() {
+ th.RestoreDefaultRolePermissions(defaultRolePermissions)
+ }()
+
emoji := &model.Emoji{
CreatorId: th.BasicUser.Id,
Name: model.NewId(),
@@ -277,14 +309,100 @@ func TestDeleteEmoji(t *testing.T) {
_, resp = Client.DeleteEmoji("")
CheckNotFoundStatus(t, resp)
- //Try to delete other user's custom emoji
+ //Try to delete my custom emoji without permissions
+ newEmoji, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
+ CheckNoError(t, resp)
+
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ _, resp = Client.DeleteEmoji(newEmoji.Id)
+ CheckForbiddenStatus(t, resp)
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+
+ //Try to delete other user's custom emoji without MANAGE_EMOJIS permissions
+ emoji = &model.Emoji{
+ CreatorId: th.BasicUser.Id,
+ Name: model.NewId(),
+ }
+
newEmoji, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
CheckNoError(t, resp)
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
Client.Logout()
th.LoginBasic2()
ok, resp = Client.DeleteEmoji(newEmoji.Id)
- CheckUnauthorizedStatus(t, resp)
+ CheckForbiddenStatus(t, resp)
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OTHERS_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ Client.Logout()
+ th.LoginBasic()
+
+ //Try to delete other user's custom emoji without MANAGE_OTHERS_EMOJIS permissions
+ emoji = &model.Emoji{
+ CreatorId: th.BasicUser.Id,
+ Name: model.NewId(),
+ }
+
+ newEmoji, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
+ CheckNoError(t, resp)
+
+ Client.Logout()
+ th.LoginBasic2()
+ ok, resp = Client.DeleteEmoji(newEmoji.Id)
+ CheckForbiddenStatus(t, resp)
+ Client.Logout()
+ th.LoginBasic()
+
+ //Try to delete other user's custom emoji with permissions
+ emoji = &model.Emoji{
+ CreatorId: th.BasicUser.Id,
+ Name: model.NewId(),
+ }
+
+ newEmoji, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
+ CheckNoError(t, resp)
+
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ Client.Logout()
+ th.LoginBasic2()
+ ok, resp = Client.DeleteEmoji(newEmoji.Id)
+ CheckNoError(t, resp)
+
+ Client.Logout()
+ th.LoginBasic()
+
+ //Try to delete my custom emoji with permissions at team level
+ newEmoji, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
+ CheckNoError(t, resp)
+
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.TEAM_USER_ROLE_ID)
+ _, resp = Client.DeleteEmoji(newEmoji.Id)
+ CheckNoError(t, resp)
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.TEAM_USER_ROLE_ID)
+
+ //Try to delete other user's custom emoji with permissions at team level
+ emoji = &model.Emoji{
+ CreatorId: th.BasicUser.Id,
+ Name: model.NewId(),
+ }
+
+ newEmoji, resp = Client.CreateEmoji(emoji, utils.CreateTestGif(t, 10, 10), "image.gif")
+ CheckNoError(t, resp)
+
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+ th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OTHERS_EMOJIS.Id, model.SYSTEM_USER_ROLE_ID)
+
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_EMOJIS.Id, model.TEAM_USER_ROLE_ID)
+ th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_EMOJIS.Id, model.TEAM_USER_ROLE_ID)
+
+ Client.Logout()
+ th.LoginBasic2()
+ ok, resp = Client.DeleteEmoji(newEmoji.Id)
+ CheckNoError(t, resp)
}
func TestGetEmoji(t *testing.T) {
diff --git a/api4/post.go b/api4/post.go
index 189edfc20..b4392a74e 100644
--- a/api4/post.go
+++ b/api4/post.go
@@ -246,11 +246,24 @@ func deletePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if !c.App.SessionHasPermissionToPost(c.Session, c.Params.PostId, model.PERMISSION_DELETE_OTHERS_POSTS) {
- c.SetPermissionError(model.PERMISSION_DELETE_OTHERS_POSTS)
+ post, err := c.App.GetSinglePost(c.Params.PostId)
+ if err != nil {
+ c.SetPermissionError(model.PERMISSION_DELETE_POST)
return
}
+ if c.Session.UserId == post.UserId {
+ if !c.App.SessionHasPermissionToChannel(c.Session, post.ChannelId, model.PERMISSION_DELETE_POST) {
+ c.SetPermissionError(model.PERMISSION_DELETE_POST)
+ return
+ }
+ } else {
+ if !c.App.SessionHasPermissionToChannel(c.Session, post.ChannelId, model.PERMISSION_DELETE_OTHERS_POSTS) {
+ c.SetPermissionError(model.PERMISSION_DELETE_OTHERS_POSTS)
+ return
+ }
+ }
+
if _, err := c.App.DeletePost(c.Params.PostId); err != nil {
c.Err = err
return
@@ -364,11 +377,19 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if !c.App.SessionHasPermissionToPost(c.Session, c.Params.PostId, model.PERMISSION_EDIT_OTHERS_POSTS) {
- c.SetPermissionError(model.PERMISSION_EDIT_OTHERS_POSTS)
+ originalPost, err := c.App.GetSinglePost(c.Params.PostId)
+ if err != nil {
+ c.SetPermissionError(model.PERMISSION_EDIT_POST)
return
}
+ if c.Session.UserId != originalPost.UserId {
+ if !c.App.SessionHasPermissionToChannelByPost(c.Session, c.Params.PostId, model.PERMISSION_EDIT_OTHERS_POSTS) {
+ c.SetPermissionError(model.PERMISSION_EDIT_OTHERS_POSTS)
+ return
+ }
+ }
+
post.Id = c.Params.PostId
rpost, err := c.App.UpdatePost(c.App.PostWithProxyRemovedFromImageURLs(post), false)
@@ -398,11 +419,19 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- if !c.App.SessionHasPermissionToPost(c.Session, c.Params.PostId, model.PERMISSION_EDIT_OTHERS_POSTS) {
- c.SetPermissionError(model.PERMISSION_EDIT_OTHERS_POSTS)
+ originalPost, err := c.App.GetSinglePost(c.Params.PostId)
+ if err != nil {
+ c.SetPermissionError(model.PERMISSION_EDIT_POST)
return
}
+ if c.Session.UserId != originalPost.UserId {
+ if !c.App.SessionHasPermissionToChannelByPost(c.Session, c.Params.PostId, model.PERMISSION_EDIT_OTHERS_POSTS) {
+ c.SetPermissionError(model.PERMISSION_EDIT_OTHERS_POSTS)
+ return
+ }
+ }
+
patchedPost, err := c.App.PatchPost(c.Params.PostId, c.App.PostPatchWithProxyRemovedFromImageURLs(post))
if err != nil {
c.Err = err
diff --git a/api4/role.go b/api4/role.go
index c4203137b..2c0465891 100644
--- a/api4/role.go
+++ b/api4/role.go
@@ -100,6 +100,7 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) {
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
model.PERMISSION_MANAGE_OAUTH.Id,
model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
+ model.PERMISSION_MANAGE_EMOJIS.Id,
}
changedPermissions := model.PermissionsChangedByPatch(oldRole, patch)
diff --git a/api4/scheme.go b/api4/scheme.go
new file mode 100644
index 000000000..5070d1c4a
--- /dev/null
+++ b/api4/scheme.go
@@ -0,0 +1,211 @@
+// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package api4
+
+import (
+ "net/http"
+
+ "github.com/mattermost/mattermost-server/model"
+)
+
+func (api *API) InitScheme() {
+ api.BaseRoutes.Schemes.Handle("", api.ApiSessionRequired(getSchemes)).Methods("GET")
+ api.BaseRoutes.Schemes.Handle("", api.ApiSessionRequired(createScheme)).Methods("POST")
+ api.BaseRoutes.Schemes.Handle("/{scheme_id:[A-Za-z0-9]+}", api.ApiSessionRequired(deleteScheme)).Methods("DELETE")
+ api.BaseRoutes.Schemes.Handle("/{scheme_id:[A-Za-z0-9]+}", api.ApiSessionRequiredTrustRequester(getScheme)).Methods("GET")
+ api.BaseRoutes.Schemes.Handle("/{scheme_id:[A-Za-z0-9]+}/patch", api.ApiSessionRequired(patchScheme)).Methods("PUT")
+ api.BaseRoutes.Schemes.Handle("/{scheme_id:[A-Za-z0-9]+}/teams", api.ApiSessionRequiredTrustRequester(getTeamsForScheme)).Methods("GET")
+ api.BaseRoutes.Schemes.Handle("/{scheme_id:[A-Za-z0-9]+}/channels", api.ApiSessionRequiredTrustRequester(getChannelsForScheme)).Methods("GET")
+}
+
+func createScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ scheme := model.SchemeFromJson(r.Body)
+ if scheme == nil {
+ c.SetInvalidParam("scheme")
+ return
+ }
+
+ if c.App.License() == nil || !*c.App.License().Features.CustomPermissionsSchemes {
+ c.Err = model.NewAppError("Api4.CreateScheme", "api.scheme.create_scheme.license.error", nil, "", http.StatusNotImplemented)
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ var err *model.AppError
+ if scheme, err = c.App.CreateScheme(scheme); err != nil {
+ c.Err = err
+ return
+ } else {
+ w.WriteHeader(http.StatusCreated)
+ w.Write([]byte(scheme.ToJson()))
+ }
+}
+
+func getScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireSchemeId()
+ if c.Err != nil {
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ if scheme, err := c.App.GetScheme(c.Params.SchemeId); err != nil {
+ c.Err = err
+ return
+ } else {
+ w.Write([]byte(scheme.ToJson()))
+ }
+}
+
+func getSchemes(c *Context, w http.ResponseWriter, r *http.Request) {
+ if c.Err != nil {
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ scope := c.Params.Scope
+ if scope != "" && scope != model.SCHEME_SCOPE_TEAM && scope != model.SCHEME_SCOPE_CHANNEL {
+ c.SetInvalidParam("scope")
+ return
+ }
+
+ if schemes, err := c.App.GetSchemesPage(c.Params.Scope, c.Params.Page, c.Params.PerPage); err != nil {
+ c.Err = err
+ return
+ } else {
+ w.Write([]byte(model.SchemesToJson(schemes)))
+ }
+}
+
+func getTeamsForScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireSchemeId()
+ if c.Err != nil {
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ scheme, err := c.App.GetScheme(c.Params.SchemeId)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ if scheme.Scope != model.SCHEME_SCOPE_TEAM {
+ c.Err = model.NewAppError("Api4.GetTeamsForScheme", "api.scheme.get_teams_for_scheme.scope.error", nil, "", http.StatusBadRequest)
+ return
+ }
+
+ if teams, err := c.App.GetTeamsForSchemePage(scheme, c.Params.Page, c.Params.PerPage); err != nil {
+ c.Err = err
+ return
+ } else {
+ w.Write([]byte(model.TeamListToJson(teams)))
+ }
+}
+
+func getChannelsForScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireSchemeId()
+ if c.Err != nil {
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ scheme, err := c.App.GetScheme(c.Params.SchemeId)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ if scheme.Scope != model.SCHEME_SCOPE_CHANNEL {
+ c.Err = model.NewAppError("Api4.GetChannelsForScheme", "api.scheme.get_channels_for_scheme.scope.error", nil, "", http.StatusBadRequest)
+ return
+ }
+
+ if channels, err := c.App.GetChannelsForSchemePage(scheme, c.Params.Page, c.Params.PerPage); err != nil {
+ c.Err = err
+ return
+ } else {
+ w.Write([]byte(channels.ToJson()))
+ }
+}
+
+func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireSchemeId()
+ if c.Err != nil {
+ return
+ }
+
+ patch := model.SchemePatchFromJson(r.Body)
+ if patch == nil {
+ c.SetInvalidParam("scheme")
+ return
+ }
+
+ if c.App.License() == nil || !*c.App.License().Features.CustomPermissionsSchemes {
+ c.Err = model.NewAppError("Api4.PatchScheme", "api.scheme.patch_scheme.license.error", nil, "", http.StatusNotImplemented)
+ return
+ }
+
+ scheme, err := c.App.GetScheme(c.Params.SchemeId)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ if scheme, err = c.App.PatchScheme(scheme, patch); err != nil {
+ c.Err = err
+ return
+ } else {
+ c.LogAudit("")
+ w.Write([]byte(scheme.ToJson()))
+ }
+}
+
+func deleteScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireSchemeId()
+ if c.Err != nil {
+ return
+ }
+
+ if c.App.License() == nil || !*c.App.License().Features.CustomPermissionsSchemes {
+ c.Err = model.NewAppError("Api4.DeleteScheme", "api.scheme.delete_scheme.license.error", nil, "", http.StatusNotImplemented)
+ return
+ }
+
+ if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ if _, err := c.App.DeleteScheme(c.Params.SchemeId); err != nil {
+ c.Err = err
+ return
+ }
+
+ ReturnStatusOK(w)
+}
diff --git a/api4/scheme_test.go b/api4/scheme_test.go
new file mode 100644
index 000000000..67cfda4fc
--- /dev/null
+++ b/api4/scheme_test.go
@@ -0,0 +1,737 @@
+// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package api4
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "github.com/mattermost/mattermost-server/model"
+)
+
+func TestCreateScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ // Basic test of creating a team scheme.
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+
+ s1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ assert.Equal(t, s1.DisplayName, scheme1.DisplayName)
+ assert.Equal(t, s1.Name, scheme1.Name)
+ assert.Equal(t, s1.Description, scheme1.Description)
+ assert.NotZero(t, s1.CreateAt)
+ assert.Equal(t, s1.CreateAt, s1.UpdateAt)
+ assert.Zero(t, s1.DeleteAt)
+ assert.Equal(t, s1.Scope, scheme1.Scope)
+ assert.NotZero(t, len(s1.DefaultTeamAdminRole))
+ assert.NotZero(t, len(s1.DefaultTeamUserRole))
+ assert.NotZero(t, len(s1.DefaultChannelAdminRole))
+ assert.NotZero(t, len(s1.DefaultChannelUserRole))
+
+ // Check the default roles have been created.
+ _, roleRes1 := th.SystemAdminClient.GetRole(s1.DefaultTeamAdminRole)
+ CheckNoError(t, roleRes1)
+ _, roleRes2 := th.SystemAdminClient.GetRole(s1.DefaultTeamUserRole)
+ CheckNoError(t, roleRes2)
+ _, roleRes3 := th.SystemAdminClient.GetRole(s1.DefaultChannelAdminRole)
+ CheckNoError(t, roleRes3)
+ _, roleRes4 := th.SystemAdminClient.GetRole(s1.DefaultChannelUserRole)
+ CheckNoError(t, roleRes4)
+
+ // Basic Test of a Channel scheme.
+ scheme2 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+
+ s2, r2 := th.SystemAdminClient.CreateScheme(scheme2)
+ CheckNoError(t, r2)
+
+ assert.Equal(t, s2.DisplayName, scheme2.DisplayName)
+ assert.Equal(t, s2.Name, scheme2.Name)
+ assert.Equal(t, s2.Description, scheme2.Description)
+ assert.NotZero(t, s2.CreateAt)
+ assert.Equal(t, s2.CreateAt, s2.UpdateAt)
+ assert.Zero(t, s2.DeleteAt)
+ assert.Equal(t, s2.Scope, scheme2.Scope)
+ assert.Zero(t, len(s2.DefaultTeamAdminRole))
+ assert.Zero(t, len(s2.DefaultTeamUserRole))
+ assert.NotZero(t, len(s2.DefaultChannelAdminRole))
+ assert.NotZero(t, len(s2.DefaultChannelUserRole))
+
+ // Check the default roles have been created.
+ _, roleRes5 := th.SystemAdminClient.GetRole(s2.DefaultChannelAdminRole)
+ CheckNoError(t, roleRes5)
+ _, roleRes6 := th.SystemAdminClient.GetRole(s2.DefaultChannelUserRole)
+ CheckNoError(t, roleRes6)
+
+ // Try and create a scheme with an invalid scope.
+ scheme3 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.NewId(),
+ }
+
+ _, r3 := th.SystemAdminClient.CreateScheme(scheme3)
+ CheckBadRequestStatus(t, r3)
+
+ // Try and create a scheme with an invalid display name.
+ scheme4 := &model.Scheme{
+ DisplayName: strings.Repeat(model.NewId(), 100),
+ Name: "Name",
+ Description: model.NewId(),
+ Scope: model.NewId(),
+ }
+ _, r4 := th.SystemAdminClient.CreateScheme(scheme4)
+ CheckBadRequestStatus(t, r4)
+
+ // Try and create a scheme with an invalid name.
+ scheme8 := &model.Scheme{
+ DisplayName: "DisplayName",
+ Name: strings.Repeat(model.NewId(), 100),
+ Description: model.NewId(),
+ Scope: model.NewId(),
+ }
+ _, r8 := th.SystemAdminClient.CreateScheme(scheme8)
+ CheckBadRequestStatus(t, r8)
+
+ // Try and create a scheme without the appropriate permissions.
+ scheme5 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+ _, r5 := th.Client.CreateScheme(scheme5)
+ CheckForbiddenStatus(t, r5)
+
+ // Try and create a scheme without a license.
+ th.App.SetLicense(nil)
+ scheme6 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+ _, r6 := th.SystemAdminClient.CreateScheme(scheme6)
+ CheckNotImplementedStatus(t, r6)
+
+ th.App.SetPhase2PermissionsMigrationStatus(false)
+
+ th.LoginSystemAdmin()
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ scheme7 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+ _, r7 := th.SystemAdminClient.CreateScheme(scheme7)
+ CheckNotImplementedStatus(t, r7)
+}
+
+func TestGetScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ // Basic test of creating a team scheme.
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ s1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ assert.Equal(t, s1.DisplayName, scheme1.DisplayName)
+ assert.Equal(t, s1.Name, scheme1.Name)
+ assert.Equal(t, s1.Description, scheme1.Description)
+ assert.NotZero(t, s1.CreateAt)
+ assert.Equal(t, s1.CreateAt, s1.UpdateAt)
+ assert.Zero(t, s1.DeleteAt)
+ assert.Equal(t, s1.Scope, scheme1.Scope)
+ assert.NotZero(t, len(s1.DefaultTeamAdminRole))
+ assert.NotZero(t, len(s1.DefaultTeamUserRole))
+ assert.NotZero(t, len(s1.DefaultChannelAdminRole))
+ assert.NotZero(t, len(s1.DefaultChannelUserRole))
+
+ s2, r2 := th.SystemAdminClient.GetScheme(s1.Id)
+ CheckNoError(t, r2)
+
+ assert.Equal(t, s1, s2)
+
+ _, r3 := th.SystemAdminClient.GetScheme(model.NewId())
+ CheckNotFoundStatus(t, r3)
+
+ _, r4 := th.SystemAdminClient.GetScheme("12345")
+ CheckBadRequestStatus(t, r4)
+
+ th.SystemAdminClient.Logout()
+ _, r5 := th.SystemAdminClient.GetScheme(s1.Id)
+ CheckUnauthorizedStatus(t, r5)
+
+ th.SystemAdminClient.Login(th.SystemAdminUser.Username, th.SystemAdminUser.Password)
+ th.App.SetLicense(nil)
+ _, r6 := th.SystemAdminClient.GetScheme(s1.Id)
+ CheckNoError(t, r6)
+
+ _, r7 := th.Client.GetScheme(s1.Id)
+ CheckForbiddenStatus(t, r7)
+
+ th.App.SetPhase2PermissionsMigrationStatus(false)
+
+ _, r8 := th.SystemAdminClient.GetScheme(s1.Id)
+ CheckNotImplementedStatus(t, r8)
+}
+
+func TestGetSchemes(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+
+ scheme2 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ _, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+ _, r2 := th.SystemAdminClient.CreateScheme(scheme2)
+ CheckNoError(t, r2)
+
+ l3, r3 := th.SystemAdminClient.GetSchemes("", 0, 100)
+ CheckNoError(t, r3)
+
+ assert.NotZero(t, len(l3))
+
+ l4, r4 := th.SystemAdminClient.GetSchemes("team", 0, 100)
+ CheckNoError(t, r4)
+
+ for _, s := range l4 {
+ assert.Equal(t, "team", s.Scope)
+ }
+
+ l5, r5 := th.SystemAdminClient.GetSchemes("channel", 0, 100)
+ CheckNoError(t, r5)
+
+ for _, s := range l5 {
+ assert.Equal(t, "channel", s.Scope)
+ }
+
+ _, r6 := th.SystemAdminClient.GetSchemes("asdf", 0, 100)
+ CheckBadRequestStatus(t, r6)
+
+ th.Client.Logout()
+ _, r7 := th.Client.GetSchemes("", 0, 100)
+ CheckUnauthorizedStatus(t, r7)
+
+ th.Client.Login(th.BasicUser.Username, th.BasicUser.Password)
+ _, r8 := th.Client.GetSchemes("", 0, 100)
+ CheckForbiddenStatus(t, r8)
+
+ th.App.SetPhase2PermissionsMigrationStatus(false)
+
+ _, r9 := th.SystemAdminClient.GetSchemes("", 0, 100)
+ CheckNotImplementedStatus(t, r9)
+}
+
+func TestGetTeamsForScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+ scheme1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ team1 := &model.Team{
+ Name: GenerateTestUsername(),
+ DisplayName: "A Test Team",
+ Type: model.TEAM_OPEN,
+ }
+
+ result1 := <-th.App.Srv.Store.Team().Save(team1)
+ assert.Nil(t, result1.Err)
+ team1 = result1.Data.(*model.Team)
+
+ l2, r2 := th.SystemAdminClient.GetTeamsForScheme(scheme1.Id, 0, 100)
+ CheckNoError(t, r2)
+ assert.Zero(t, len(l2))
+
+ team1.SchemeId = &scheme1.Id
+ result2 := <-th.App.Srv.Store.Team().Update(team1)
+ assert.Nil(t, result2.Err)
+ team1 = result2.Data.(*model.Team)
+
+ l3, r3 := th.SystemAdminClient.GetTeamsForScheme(scheme1.Id, 0, 100)
+ CheckNoError(t, r3)
+ assert.Len(t, l3, 1)
+ assert.Equal(t, team1.Id, l3[0].Id)
+
+ team2 := &model.Team{
+ Name: GenerateTestUsername(),
+ DisplayName: "B Test Team",
+ Type: model.TEAM_OPEN,
+ SchemeId: &scheme1.Id,
+ }
+ result3 := <-th.App.Srv.Store.Team().Save(team2)
+ assert.Nil(t, result3.Err)
+ team2 = result3.Data.(*model.Team)
+
+ l4, r4 := th.SystemAdminClient.GetTeamsForScheme(scheme1.Id, 0, 100)
+ CheckNoError(t, r4)
+ assert.Len(t, l4, 2)
+ assert.Equal(t, team1.Id, l4[0].Id)
+ assert.Equal(t, team2.Id, l4[1].Id)
+
+ l5, r5 := th.SystemAdminClient.GetTeamsForScheme(scheme1.Id, 1, 1)
+ CheckNoError(t, r5)
+ assert.Len(t, l5, 1)
+ assert.Equal(t, team2.Id, l5[0].Id)
+
+ // Check various error cases.
+ _, ri1 := th.SystemAdminClient.GetTeamsForScheme(model.NewId(), 0, 100)
+ CheckNotFoundStatus(t, ri1)
+
+ _, ri2 := th.SystemAdminClient.GetTeamsForScheme("", 0, 100)
+ CheckBadRequestStatus(t, ri2)
+
+ th.Client.Logout()
+ _, ri3 := th.Client.GetTeamsForScheme(model.NewId(), 0, 100)
+ CheckUnauthorizedStatus(t, ri3)
+
+ th.Client.Login(th.BasicUser.Username, th.BasicUser.Password)
+ _, ri4 := th.Client.GetTeamsForScheme(model.NewId(), 0, 100)
+ CheckForbiddenStatus(t, ri4)
+
+ scheme2 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+ scheme2, rs2 := th.SystemAdminClient.CreateScheme(scheme2)
+ CheckNoError(t, rs2)
+
+ _, ri5 := th.SystemAdminClient.GetTeamsForScheme(scheme2.Id, 0, 100)
+ CheckBadRequestStatus(t, ri5)
+
+ th.App.SetPhase2PermissionsMigrationStatus(false)
+
+ _, ri6 := th.SystemAdminClient.GetTeamsForScheme(scheme1.Id, 0, 100)
+ CheckNotImplementedStatus(t, ri6)
+}
+
+func TestGetChannelsForScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+ scheme1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ channel1 := &model.Channel{
+ TeamId: model.NewId(),
+ DisplayName: "A Name",
+ Name: model.NewId(),
+ Type: model.CHANNEL_OPEN,
+ }
+
+ result1 := <-th.App.Srv.Store.Channel().Save(channel1, 1000000)
+ assert.Nil(t, result1.Err)
+ channel1 = result1.Data.(*model.Channel)
+
+ l2, r2 := th.SystemAdminClient.GetChannelsForScheme(scheme1.Id, 0, 100)
+ CheckNoError(t, r2)
+ assert.Zero(t, len(l2))
+
+ channel1.SchemeId = &scheme1.Id
+ result2 := <-th.App.Srv.Store.Channel().Update(channel1)
+ assert.Nil(t, result2.Err)
+ channel1 = result2.Data.(*model.Channel)
+
+ l3, r3 := th.SystemAdminClient.GetChannelsForScheme(scheme1.Id, 0, 100)
+ CheckNoError(t, r3)
+ assert.Len(t, l3, 1)
+ assert.Equal(t, channel1.Id, l3[0].Id)
+
+ channel2 := &model.Channel{
+ TeamId: model.NewId(),
+ DisplayName: "B Name",
+ Name: model.NewId(),
+ Type: model.CHANNEL_OPEN,
+ SchemeId: &scheme1.Id,
+ }
+ result3 := <-th.App.Srv.Store.Channel().Save(channel2, 1000000)
+ assert.Nil(t, result3.Err)
+ channel2 = result3.Data.(*model.Channel)
+
+ l4, r4 := th.SystemAdminClient.GetChannelsForScheme(scheme1.Id, 0, 100)
+ CheckNoError(t, r4)
+ assert.Len(t, l4, 2)
+ assert.Equal(t, channel1.Id, l4[0].Id)
+ assert.Equal(t, channel2.Id, l4[1].Id)
+
+ l5, r5 := th.SystemAdminClient.GetChannelsForScheme(scheme1.Id, 1, 1)
+ CheckNoError(t, r5)
+ assert.Len(t, l5, 1)
+ assert.Equal(t, channel2.Id, l5[0].Id)
+
+ // Check various error cases.
+ _, ri1 := th.SystemAdminClient.GetChannelsForScheme(model.NewId(), 0, 100)
+ CheckNotFoundStatus(t, ri1)
+
+ _, ri2 := th.SystemAdminClient.GetChannelsForScheme("", 0, 100)
+ CheckBadRequestStatus(t, ri2)
+
+ th.Client.Logout()
+ _, ri3 := th.Client.GetChannelsForScheme(model.NewId(), 0, 100)
+ CheckUnauthorizedStatus(t, ri3)
+
+ th.Client.Login(th.BasicUser.Username, th.BasicUser.Password)
+ _, ri4 := th.Client.GetChannelsForScheme(model.NewId(), 0, 100)
+ CheckForbiddenStatus(t, ri4)
+
+ scheme2 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+ scheme2, rs2 := th.SystemAdminClient.CreateScheme(scheme2)
+ CheckNoError(t, rs2)
+
+ _, ri5 := th.SystemAdminClient.GetChannelsForScheme(scheme2.Id, 0, 100)
+ CheckBadRequestStatus(t, ri5)
+
+ th.App.SetPhase2PermissionsMigrationStatus(false)
+
+ _, ri6 := th.SystemAdminClient.GetChannelsForScheme(scheme1.Id, 0, 100)
+ CheckNotImplementedStatus(t, ri6)
+}
+
+func TestPatchScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ // Basic test of creating a team scheme.
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+
+ s1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ assert.Equal(t, s1.DisplayName, scheme1.DisplayName)
+ assert.Equal(t, s1.Name, scheme1.Name)
+ assert.Equal(t, s1.Description, scheme1.Description)
+ assert.NotZero(t, s1.CreateAt)
+ assert.Equal(t, s1.CreateAt, s1.UpdateAt)
+ assert.Zero(t, s1.DeleteAt)
+ assert.Equal(t, s1.Scope, scheme1.Scope)
+ assert.NotZero(t, len(s1.DefaultTeamAdminRole))
+ assert.NotZero(t, len(s1.DefaultTeamUserRole))
+ assert.NotZero(t, len(s1.DefaultChannelAdminRole))
+ assert.NotZero(t, len(s1.DefaultChannelUserRole))
+
+ s2, r2 := th.SystemAdminClient.GetScheme(s1.Id)
+ CheckNoError(t, r2)
+
+ assert.Equal(t, s1, s2)
+
+ // Test with a valid patch.
+ schemePatch := &model.SchemePatch{
+ DisplayName: new(string),
+ Name: new(string),
+ Description: new(string),
+ }
+ *schemePatch.DisplayName = model.NewId()
+ *schemePatch.Name = model.NewId()
+ *schemePatch.Description = model.NewId()
+
+ s3, r3 := th.SystemAdminClient.PatchScheme(s2.Id, schemePatch)
+ CheckNoError(t, r3)
+ assert.Equal(t, s3.Id, s2.Id)
+ assert.Equal(t, s3.DisplayName, *schemePatch.DisplayName)
+ assert.Equal(t, s3.Name, *schemePatch.Name)
+ assert.Equal(t, s3.Description, *schemePatch.Description)
+
+ s4, r4 := th.SystemAdminClient.GetScheme(s3.Id)
+ CheckNoError(t, r4)
+ assert.Equal(t, s3, s4)
+
+ // Test with a partial patch.
+ *schemePatch.Name = model.NewId()
+ *schemePatch.DisplayName = model.NewId()
+ schemePatch.Description = nil
+
+ s5, r5 := th.SystemAdminClient.PatchScheme(s4.Id, schemePatch)
+ CheckNoError(t, r5)
+ assert.Equal(t, s5.Id, s4.Id)
+ assert.Equal(t, s5.DisplayName, *schemePatch.DisplayName)
+ assert.Equal(t, s5.Name, *schemePatch.Name)
+ assert.Equal(t, s5.Description, s4.Description)
+
+ s6, r6 := th.SystemAdminClient.GetScheme(s5.Id)
+ CheckNoError(t, r6)
+ assert.Equal(t, s5, s6)
+
+ // Test with invalid patch.
+ *schemePatch.Name = strings.Repeat(model.NewId(), 20)
+ _, r7 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch)
+ CheckBadRequestStatus(t, r7)
+
+ // Test with unknown ID.
+ *schemePatch.Name = model.NewId()
+ _, r8 := th.SystemAdminClient.PatchScheme(model.NewId(), schemePatch)
+ CheckNotFoundStatus(t, r8)
+
+ // Test with invalid ID.
+ _, r9 := th.SystemAdminClient.PatchScheme("12345", schemePatch)
+ CheckBadRequestStatus(t, r9)
+
+ // Test without required permissions.
+ _, r10 := th.Client.PatchScheme(s6.Id, schemePatch)
+ CheckForbiddenStatus(t, r10)
+
+ // Test without license.
+ th.App.SetLicense(nil)
+ _, r11 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch)
+ CheckNotImplementedStatus(t, r11)
+
+ th.App.SetPhase2PermissionsMigrationStatus(false)
+
+ th.LoginSystemAdmin()
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ _, r12 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch)
+ CheckNotImplementedStatus(t, r12)
+}
+
+func TestDeleteScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ t.Run("ValidTeamScheme", func(t *testing.T) {
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ // Create a team scheme.
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+
+ s1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ // Retrieve the roles and check they are not deleted.
+ role1, roleRes1 := th.SystemAdminClient.GetRole(s1.DefaultTeamAdminRole)
+ CheckNoError(t, roleRes1)
+ role2, roleRes2 := th.SystemAdminClient.GetRole(s1.DefaultTeamUserRole)
+ CheckNoError(t, roleRes2)
+ role3, roleRes3 := th.SystemAdminClient.GetRole(s1.DefaultChannelAdminRole)
+ CheckNoError(t, roleRes3)
+ role4, roleRes4 := th.SystemAdminClient.GetRole(s1.DefaultChannelUserRole)
+ CheckNoError(t, roleRes4)
+
+ assert.Zero(t, role1.DeleteAt)
+ assert.Zero(t, role2.DeleteAt)
+ assert.Zero(t, role3.DeleteAt)
+ assert.Zero(t, role4.DeleteAt)
+
+ // Make sure this scheme is in use by a team.
+ res := <-th.App.Srv.Store.Team().Save(&model.Team{
+ Name: model.NewId(),
+ DisplayName: model.NewId(),
+ Email: model.NewId() + "@nowhere.com",
+ Type: model.TEAM_OPEN,
+ SchemeId: &s1.Id,
+ })
+ assert.Nil(t, res.Err)
+ team := res.Data.(*model.Team)
+
+ // Delete the Scheme.
+ _, r3 := th.SystemAdminClient.DeleteScheme(s1.Id)
+ CheckNoError(t, r3)
+
+ // Check the roles were deleted.
+ role1, roleRes1 = th.SystemAdminClient.GetRole(s1.DefaultTeamAdminRole)
+ CheckNoError(t, roleRes1)
+ role2, roleRes2 = th.SystemAdminClient.GetRole(s1.DefaultTeamUserRole)
+ CheckNoError(t, roleRes2)
+ role3, roleRes3 = th.SystemAdminClient.GetRole(s1.DefaultChannelAdminRole)
+ CheckNoError(t, roleRes3)
+ role4, roleRes4 = th.SystemAdminClient.GetRole(s1.DefaultChannelUserRole)
+ CheckNoError(t, roleRes4)
+
+ assert.NotZero(t, role1.DeleteAt)
+ assert.NotZero(t, role2.DeleteAt)
+ assert.NotZero(t, role3.DeleteAt)
+ assert.NotZero(t, role4.DeleteAt)
+
+ // Check the team now uses the default scheme
+ c2, resp := th.SystemAdminClient.GetTeam(team.Id, "")
+ CheckNoError(t, resp)
+ assert.Equal(t, "", *c2.SchemeId)
+ })
+
+ t.Run("ValidChannelScheme", func(t *testing.T) {
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ // Create a channel scheme.
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+
+ s1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ // Retrieve the roles and check they are not deleted.
+ role3, roleRes3 := th.SystemAdminClient.GetRole(s1.DefaultChannelAdminRole)
+ CheckNoError(t, roleRes3)
+ role4, roleRes4 := th.SystemAdminClient.GetRole(s1.DefaultChannelUserRole)
+ CheckNoError(t, roleRes4)
+
+ assert.Zero(t, role3.DeleteAt)
+ assert.Zero(t, role4.DeleteAt)
+
+ // Make sure this scheme is in use by a team.
+ res := <-th.App.Srv.Store.Channel().Save(&model.Channel{
+ TeamId: model.NewId(),
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Type: model.CHANNEL_OPEN,
+ SchemeId: &s1.Id,
+ }, -1)
+ assert.Nil(t, res.Err)
+ channel := res.Data.(*model.Channel)
+
+ // Delete the Scheme.
+ _, r3 := th.SystemAdminClient.DeleteScheme(s1.Id)
+ CheckNoError(t, r3)
+
+ // Check the roles were deleted.
+ role3, roleRes3 = th.SystemAdminClient.GetRole(s1.DefaultChannelAdminRole)
+ CheckNoError(t, roleRes3)
+ role4, roleRes4 = th.SystemAdminClient.GetRole(s1.DefaultChannelUserRole)
+ CheckNoError(t, roleRes4)
+
+ assert.NotZero(t, role3.DeleteAt)
+ assert.NotZero(t, role4.DeleteAt)
+
+ // Check the channel now uses the default scheme
+ c2, resp := th.SystemAdminClient.GetChannelByName(channel.Name, channel.TeamId, "")
+ CheckNoError(t, resp)
+ assert.Equal(t, "", *c2.SchemeId)
+ })
+
+ t.Run("FailureCases", func(t *testing.T) {
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ scheme1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+
+ s1, r1 := th.SystemAdminClient.CreateScheme(scheme1)
+ CheckNoError(t, r1)
+
+ // Test with unknown ID.
+ _, r2 := th.SystemAdminClient.DeleteScheme(model.NewId())
+ CheckNotFoundStatus(t, r2)
+
+ // Test with invalid ID.
+ _, r3 := th.SystemAdminClient.DeleteScheme("12345")
+ CheckBadRequestStatus(t, r3)
+
+ // Test without required permissions.
+ _, r4 := th.Client.DeleteScheme(s1.Id)
+ CheckForbiddenStatus(t, r4)
+
+ // Test without license.
+ th.App.SetLicense(nil)
+ _, r5 := th.SystemAdminClient.DeleteScheme(s1.Id)
+ CheckNotImplementedStatus(t, r5)
+
+ th.App.SetPhase2PermissionsMigrationStatus(false)
+
+ th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes"))
+
+ _, r6 := th.SystemAdminClient.DeleteScheme(s1.Id)
+ CheckNotImplementedStatus(t, r6)
+ })
+}
diff --git a/api4/team.go b/api4/team.go
index 44771ae60..74b385122 100644
--- a/api4/team.go
+++ b/api4/team.go
@@ -20,6 +20,7 @@ const (
func (api *API) InitTeam() {
api.BaseRoutes.Teams.Handle("", api.ApiSessionRequired(createTeam)).Methods("POST")
api.BaseRoutes.Teams.Handle("", api.ApiSessionRequired(getAllTeams)).Methods("GET")
+ api.BaseRoutes.Teams.Handle("/{team_id:[A-Za-z0-9]+}/scheme", api.ApiSessionRequired(updateTeamScheme)).Methods("PUT")
api.BaseRoutes.Teams.Handle("/search", api.ApiSessionRequired(searchTeams)).Methods("POST")
api.BaseRoutes.TeamsForUser.Handle("", api.ApiSessionRequired(getTeamsForUser)).Methods("GET")
api.BaseRoutes.TeamsForUser.Handle("/unread", api.ApiSessionRequired(getTeamsUnreadForUser)).Methods("GET")
@@ -833,3 +834,55 @@ func removeTeamIcon(c *Context, w http.ResponseWriter, r *http.Request) {
c.LogAudit("")
ReturnStatusOK(w)
}
+
+func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) {
+ c.RequireTeamId()
+ if c.Err != nil {
+ return
+ }
+
+ schemeID := model.SchemeIDFromJson(r.Body)
+ if schemeID == nil || (len(*schemeID) != 26 && *schemeID != "") {
+ c.SetInvalidParam("scheme_id")
+ return
+ }
+
+ if c.App.License() == nil {
+ c.Err = model.NewAppError("Api4.UpdateTeamScheme", "api.team.update_team_scheme.license.error", nil, "", http.StatusNotImplemented)
+ return
+ }
+
+ if !c.App.SessionHasPermissionToTeam(c.Session, c.Params.TeamId, model.PERMISSION_MANAGE_SYSTEM) {
+ c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
+ return
+ }
+
+ if *schemeID != "" {
+ scheme, err := c.App.GetScheme(*schemeID)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ if scheme.Scope != model.SCHEME_SCOPE_TEAM {
+ c.Err = model.NewAppError("Api4.UpdateTeamScheme", "api.team.update_team_scheme.scheme_scope.error", nil, "", http.StatusBadRequest)
+ return
+ }
+ }
+
+ team, err := c.App.GetTeam(c.Params.TeamId)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ team.SchemeId = schemeID
+
+ _, err = c.App.UpdateTeamScheme(team)
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ ReturnStatusOK(w)
+}
diff --git a/api4/team_test.go b/api4/team_test.go
index bf67d8fde..079ba37ec 100644
--- a/api4/team_test.go
+++ b/api4/team_test.go
@@ -1675,7 +1675,7 @@ func TestUpdateTeamMemberRoles(t *testing.T) {
// user 1 (team admin) tries to demote system admin (not member of a team)
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, TEAM_MEMBER)
- CheckBadRequestStatus(t, resp)
+ CheckNotFoundStatus(t, resp)
// user 1 (team admin) demotes system admin (member of a team)
th.LinkUserToTeam(th.SystemAdminUser, th.BasicTeam)
@@ -1701,7 +1701,7 @@ func TestUpdateTeamMemberRoles(t *testing.T) {
// user 1 (team admin) tries to promote a random user
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, model.NewId(), TEAM_ADMIN)
- CheckBadRequestStatus(t, resp)
+ CheckNotFoundStatus(t, resp)
// user 1 (team admin) tries to promote invalid team permission
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, "junk")
@@ -2055,3 +2055,75 @@ func TestRemoveTeamIcon(t *testing.T) {
_, resp = Client.RemoveTeamIcon(team.Id)
CheckForbiddenStatus(t, resp)
}
+
+func TestUpdateTeamScheme(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+ defer th.TearDown()
+
+ th.App.SetLicense(model.NewTestLicense(""))
+
+ th.App.SetPhase2PermissionsMigrationStatus(true)
+
+ team := &model.Team{
+ DisplayName: "Name",
+ Description: "Some description",
+ CompanyName: "Some company name",
+ AllowOpenInvite: false,
+ InviteId: "inviteid0",
+ Name: "z-z-" + model.NewId() + "a",
+ Email: "success+" + model.NewId() + "@simulator.amazonses.com",
+ Type: model.TEAM_OPEN,
+ }
+ team, _ = th.SystemAdminClient.CreateTeam(team)
+
+ teamScheme := &model.Scheme{
+ DisplayName: "DisplayName",
+ Name: model.NewId(),
+ Description: "Some description",
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+ teamScheme, _ = th.SystemAdminClient.CreateScheme(teamScheme)
+ channelScheme := &model.Scheme{
+ DisplayName: "DisplayName",
+ Name: model.NewId(),
+ Description: "Some description",
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+ channelScheme, _ = th.SystemAdminClient.CreateScheme(channelScheme)
+
+ // Test the setup/base case.
+ _, resp := th.SystemAdminClient.UpdateTeamScheme(team.Id, teamScheme.Id)
+ CheckNoError(t, resp)
+
+ // Test the return to default scheme
+ _, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, "")
+ CheckNoError(t, resp)
+
+ // Test various invalid team and scheme id combinations.
+ _, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, "x")
+ CheckBadRequestStatus(t, resp)
+ _, resp = th.SystemAdminClient.UpdateTeamScheme("x", teamScheme.Id)
+ CheckBadRequestStatus(t, resp)
+ _, resp = th.SystemAdminClient.UpdateTeamScheme("x", "x")
+ CheckBadRequestStatus(t, resp)
+
+ // Test that permissions are required.
+ _, resp = th.Client.UpdateTeamScheme(team.Id, teamScheme.Id)
+ CheckForbiddenStatus(t, resp)
+
+ // Test that a license is requried.
+ th.App.SetLicense(nil)
+ _, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, teamScheme.Id)
+ CheckNotImplementedStatus(t, resp)
+ th.App.SetLicense(model.NewTestLicense(""))
+
+ // Test an invalid scheme scope.
+ _, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, channelScheme.Id)
+ fmt.Printf("resp: %+v\n", resp)
+ CheckBadRequestStatus(t, resp)
+
+ // Test that an unauthenticated user gets rejected.
+ th.SystemAdminClient.Logout()
+ _, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, teamScheme.Id)
+ CheckUnauthorizedStatus(t, resp)
+}