From cd55c44c8fd8f61cdb7cbfb57a588be82c7aa0ab Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Fri, 20 Apr 2018 19:49:13 +0100 Subject: MM-8796: Full implementation of "Schemes" in Store/Model/App layers. (#8357) * Add Scheme model and stub store. * Port ChannelStore to be Scheme aware. * Make almost all the API/APP layer work with ChannelSchemes. Only thing still hacky is UpdateChannelMemberRoles(). * Add basic SchemeStore implementation. * Migrate UpdateChannelMemberRoles properly and fix tests. * Update store tests and mocks so they work. * Include creating default roles in Scheme create store function. * Implement role deletion and start scheme deletion. * Only use non-deleted roles for authorization. * Add GetByScheme method to Team store. * Add GetChannelsByScheme. * Update store mocks. * Implement scheme deletion in the store. * Rename is valid function. * Add offset and limit to queries to fetch teams and channels by scheme. * Fix queries. * Implement scheme awareness in Team store and add a migration. * Tidy up ChannelStore mapping functions and add exhaustive unit tests. * Add all missing i18n. * Proper tests for TeamStore internal functions and fix them. * Make additional TeamMember fields nullable. * Make new ChannelMember fields nullable. * Create new nullable columns without defaults. * Make new fields in large tables nullalble. * Fix empty list of TeamMembers. * Deduplicate SQL queries. * Fix spelling. * Fix review comment. * More review fixes. * More review fixes. --- api4/apitestlib.go | 30 +++++++++++++++++++----------- api4/channel_test.go | 2 +- api4/team_test.go | 4 ++-- 3 files changed, 22 insertions(+), 14 deletions(-) (limited to 'api4') diff --git a/api4/apitestlib.go b/api4/apitestlib.go index 4620c5f4e..b56934c0a 100644 --- a/api4/apitestlib.go +++ b/api4/apitestlib.go @@ -765,7 +765,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) @@ -781,28 +781,36 @@ 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() - l4g.Error(tmr.Err.Error()) - l4g.Close() - 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() - l4g.Error(tmr.Err.Error()) - l4g.Close() - time.Sleep(time.Second) panic(tmr.Err) } + utils.EnableDebugLogForTest() } diff --git a/api4/channel_test.go b/api4/channel_test.go index 4c27e040a..0603afe74 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -1388,7 +1388,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. diff --git a/api4/team_test.go b/api4/team_test.go index cdf201771..3cd9d7d93 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -1672,7 +1672,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) @@ -1698,7 +1698,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") -- cgit v1.2.3-1-g7c22 From f4dcb4edf2aafca85c9af631131a77888da24bc7 Mon Sep 17 00:00:00 2001 From: Martin Kraft Date: Wed, 2 May 2018 07:31:14 -0400 Subject: MM-10182 & MM-10183: Adds channel scheme and team scheme API endpoint. (#8680) * MM-10183: Adds channel scheme API endpoint. MM-10182: Adds team scheme API endpoint. MM-10182_3: Switch from scheme_id in path to body. * MM-10182/MM-10183: Changes path from 'schemes' to 'scheme'. * MM-10182: Fix merge error. --- api4/channel.go | 51 +++++++++++++++++++++++++++++++++++++ api4/channel_test.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ api4/team.go | 51 +++++++++++++++++++++++++++++++++++++ api4/team_test.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 238 insertions(+) (limited to 'api4') diff --git a/api4/channel.go b/api4/channel.go index 83fa8eb18..a19a1b094 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") @@ -948,3 +949,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 c3d8c8039..7618b22d9 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -1879,3 +1879,75 @@ func TestAutocompleteChannels(t *testing.T) { } } } + +func TestUpdateChannelScheme(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + + th.App.SetLicense(model.NewTestLicense("")) + + 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{ + Name: "Name", + Description: "Some description", + Scope: model.SCHEME_SCOPE_CHANNEL, + } + channelScheme, _ = th.SystemAdminClient.CreateScheme(channelScheme) + teamScheme := &model.Scheme{ + Name: "Name", + 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/team.go b/api4/team.go index 023289579..1c2e9514e 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,53 @@ 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 { + 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 + } + + 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 = &scheme.Id + + _, 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 6540457b0..6df56f754 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -2052,3 +2052,67 @@ 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("")) + + 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{ + Name: "Name", + Description: "Some description", + Scope: model.SCHEME_SCOPE_TEAM, + } + teamScheme, _ = th.SystemAdminClient.CreateScheme(teamScheme) + channelScheme := &model.Scheme{ + Name: "Name", + 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 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) +} -- cgit v1.2.3-1-g7c22 From 60cf74352f13874a7d07c609c03b1c763af19cea Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Thu, 3 May 2018 14:00:26 +0100 Subject: MM-10140: API Implementation for Schemes related Endpoints (#8615) * Implement basic scheme CRUD endpoints. * Get All Schemes (Paged) Endpoint and store plumbing. * Add get teams/channels for schemes. * Fix unit tests. * Review fixes. * More review fixes. --- api4/api.go | 5 +- api4/context.go | 11 + api4/params.go | 8 + api4/scheme.go | 211 +++++++++++++++++ api4/scheme_test.go | 664 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 898 insertions(+), 1 deletion(-) create mode 100644 api4/scheme.go create mode 100644 api4/scheme_test.go (limited to 'api4') diff --git a/api4/api.go b/api4/api.go index d36c3e3ee..f2821b42e 100644 --- a/api4/api.go +++ b/api4/api.go @@ -99,7 +99,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]+}' @@ -200,6 +201,7 @@ func Init(a *app.App, root *mux.Router, full bool) *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() @@ -229,6 +231,7 @@ func Init(a *app.App, root *mux.Router, full bool) *API { api.InitOpenGraph() api.InitPlugin() api.InitRole() + api.InitScheme() api.InitImage() root.Handle("/api/v4/{anything:.*}", http.HandlerFunc(Handle404)) diff --git a/api4/context.go b/api4/context.go index c965e1d80..6afb964ce 100644 --- a/api4/context.go +++ b/api4/context.go @@ -650,6 +650,17 @@ func (c *Context) RequireRoleId() *Context { return c } +func (c *Context) RequireSchemeId() *Context { + if c.Err != nil { + return c + } + + if len(c.Params.SchemeId) != 26 { + c.SetInvalidUrlParam("scheme_id") + } + return c +} + func (c *Context) RequireRoleName() *Context { if c.Err != nil { return c diff --git a/api4/params.go b/api4/params.go index e8e3f25e7..35f21e0ec 100644 --- a/api4/params.go +++ b/api4/params.go @@ -47,6 +47,8 @@ type ApiParams struct { ActionId string RoleId string RoleName string + SchemeId string + Scope string Page int PerPage int LogsPerPage int @@ -167,6 +169,12 @@ func ApiParamsFromRequest(r *http.Request) *ApiParams { params.RoleName = val } + if val, ok := props["scheme_id"]; ok { + params.SchemeId = val + } + + params.Scope = query.Get("scope") + if val, err := strconv.Atoi(query.Get("page")); err != nil || val < 0 { params.Page = PAGE_DEFAULT } else { diff --git a/api4/scheme.go b/api4/scheme.go new file mode 100644 index 000000000..bdfe69870 --- /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.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.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.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..a0ea1e9b0 --- /dev/null +++ b/api4/scheme_test.go @@ -0,0 +1,664 @@ +// 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("")) + + // Basic test of creating a team scheme. + scheme1 := &model.Scheme{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_TEAM, + } + + s1, r1 := th.SystemAdminClient.CreateScheme(scheme1) + CheckNoError(t, r1) + + 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{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_CHANNEL, + } + + s2, r2 := th.SystemAdminClient.CreateScheme(scheme2) + CheckNoError(t, r2) + + 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{ + 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 name. + scheme4 := &model.Scheme{ + Name: strings.Repeat(model.NewId(), 100), + Description: model.NewId(), + Scope: model.NewId(), + } + _, r4 := th.SystemAdminClient.CreateScheme(scheme4) + CheckBadRequestStatus(t, r4) + + // Try and create a scheme without the appropriate permissions. + scheme5 := &model.Scheme{ + 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{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_TEAM, + } + _, r6 := th.SystemAdminClient.CreateScheme(scheme6) + CheckNotImplementedStatus(t, r6) +} + +func TestGetScheme(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + + th.App.SetLicense(model.NewTestLicense("")) + + // Basic test of creating a team scheme. + scheme1 := &model.Scheme{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_TEAM, + } + + s1, r1 := th.SystemAdminClient.CreateScheme(scheme1) + CheckNoError(t, r1) + + 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) +} + +func TestGetSchemes(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + + th.App.SetLicense(model.NewTestLicense("")) + + scheme1 := &model.Scheme{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_TEAM, + } + + scheme2 := &model.Scheme{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_CHANNEL, + } + + _, 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) +} + +func TestGetTeamsForScheme(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + + th.App.SetLicense(model.NewTestLicense("")) + + scheme1 := &model.Scheme{ + 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{ + 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) +} + +func TestGetChannelsForScheme(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + + th.App.SetLicense(model.NewTestLicense("")) + + scheme1 := &model.Scheme{ + 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{ + 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) +} + +func TestPatchScheme(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + + th.App.SetLicense(model.NewTestLicense("")) + + // Basic test of creating a team scheme. + scheme1 := &model.Scheme{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_TEAM, + } + + s1, r1 := th.SystemAdminClient.CreateScheme(scheme1) + CheckNoError(t, r1) + + 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{ + Name: new(string), + Description: new(string), + } + *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.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.Description = nil + + s5, r5 := th.SystemAdminClient.PatchScheme(s4.Id, schemePatch) + CheckNoError(t, r5) + assert.Equal(t, s5.Id, s4.Id) + 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) +} + +func TestDeleteScheme(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer th.TearDown() + + t.Run("ValidTeamScheme", func(t *testing.T) { + th.App.SetLicense(model.NewTestLicense("")) + + // Create a team scheme. + scheme1 := &model.Scheme{ + 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) + + // Try and fail to delete the scheme. + _, r2 := th.SystemAdminClient.DeleteScheme(s1.Id) + CheckInternalErrorStatus(t, r2) + + 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) + + // Change the team using it to a different scheme. + emptyString := "" + team.SchemeId = &emptyString + res = <-th.App.Srv.Store.Team().Update(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) + }) + + t.Run("ValidChannelScheme", func(t *testing.T) { + th.App.SetLicense(model.NewTestLicense("")) + + // Create a channel scheme. + scheme1 := &model.Scheme{ + 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) + + // Try and fail to delete the scheme. + _, r2 := th.SystemAdminClient.DeleteScheme(s1.Id) + CheckInternalErrorStatus(t, r2) + + 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) + + // Change the team using it to a different scheme. + emptyString := "" + channel.SchemeId = &emptyString + res = <-th.App.Srv.Store.Channel().Update(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) + }) + + t.Run("FailureCases", func(t *testing.T) { + th.App.SetLicense(model.NewTestLicense("")) + + scheme1 := &model.Scheme{ + 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) + }) +} -- cgit v1.2.3-1-g7c22 From 51bd710ecdca6628461c9fa2679737073e4d5059 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Mon, 14 May 2018 15:59:04 +0100 Subject: MM-9728: Online migration for advanced permissions phase 2 (#8744) * MM-9728: Online migration for advanced permissions phase 2 * Add unit tests for new store functions. * Move migration specific code to own file. * Add migration state function test. * Style fixes. * Add i18n strings. * Fix mocks. * Add TestMain to migrations package tests. * Fix typo. * Fix review comments. * Fix up the "Check if migration is done" check to actually work. --- api4/channel_test.go | 13 ++++++ api4/scheme_test.go | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++- api4/team_test.go | 11 +++++ 3 files changed, 143 insertions(+), 2 deletions(-) (limited to 'api4') diff --git a/api4/channel_test.go b/api4/channel_test.go index 11d313291..551a1a484 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -12,6 +12,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" ) @@ -1890,6 +1892,17 @@ func TestUpdateChannelScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + + // Un-mark the migration at the end of the test. + defer func() { + res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + }() + team := &model.Team{ DisplayName: "Name", Description: "Some description", diff --git a/api4/scheme_test.go b/api4/scheme_test.go index a0ea1e9b0..92cfa4d30 100644 --- a/api4/scheme_test.go +++ b/api4/scheme_test.go @@ -18,6 +18,11 @@ func TestCreateScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + // Basic test of creating a team scheme. scheme1 := &model.Scheme{ Name: model.NewId(), @@ -113,6 +118,21 @@ func TestCreateScheme(t *testing.T) { } _, r6 := th.SystemAdminClient.CreateScheme(scheme6) CheckNotImplementedStatus(t, r6) + + // Mark the migration as not done. + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + + th.LoginSystemAdmin() + th.App.SetLicense(model.NewTestLicense("")) + + scheme7 := &model.Scheme{ + Name: model.NewId(), + Description: model.NewId(), + Scope: model.SCHEME_SCOPE_TEAM, + } + _, r7 := th.SystemAdminClient.CreateScheme(scheme7) + CheckInternalErrorStatus(t, r7) } func TestGetScheme(t *testing.T) { @@ -128,9 +148,17 @@ func TestGetScheme(t *testing.T) { Scope: model.SCHEME_SCOPE_TEAM, } + // Mark the migration as done while we create the scheme. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + s1, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + assert.Equal(t, s1.Name, scheme1.Name) assert.Equal(t, s1.Description, scheme1.Description) assert.NotZero(t, s1.CreateAt) @@ -184,11 +212,19 @@ func TestGetSchemes(t *testing.T) { Scope: model.SCHEME_SCOPE_CHANNEL, } + // Mark the migration as done while we create the scheme. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + _, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) _, r2 := th.SystemAdminClient.CreateScheme(scheme2) CheckNoError(t, r2) + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + l3, r3 := th.SystemAdminClient.GetSchemes("", 0, 100) CheckNoError(t, r3) @@ -226,6 +262,11 @@ func TestGetTeamsForScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done while we create the scheme. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + scheme1 := &model.Scheme{ Name: model.NewId(), Description: model.NewId(), @@ -234,6 +275,9 @@ func TestGetTeamsForScheme(t *testing.T) { scheme1, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + team1 := &model.Team{ Name: GenerateTestUsername(), DisplayName: "A Test Team", @@ -294,6 +338,10 @@ func TestGetTeamsForScheme(t *testing.T) { _, ri4 := th.Client.GetTeamsForScheme(model.NewId(), 0, 100) CheckForbiddenStatus(t, ri4) + // Mark the migration as done again while we create a scheme. + res = <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + scheme2 := &model.Scheme{ Name: model.NewId(), Description: model.NewId(), @@ -302,6 +350,9 @@ func TestGetTeamsForScheme(t *testing.T) { scheme2, rs2 := th.SystemAdminClient.CreateScheme(scheme2) CheckNoError(t, rs2) + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + _, ri5 := th.SystemAdminClient.GetTeamsForScheme(scheme2.Id, 0, 100) CheckBadRequestStatus(t, ri5) } @@ -312,6 +363,11 @@ func TestGetChannelsForScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done while we create the scheme. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + scheme1 := &model.Scheme{ Name: model.NewId(), Description: model.NewId(), @@ -320,6 +376,9 @@ func TestGetChannelsForScheme(t *testing.T) { scheme1, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + channel1 := &model.Channel{ TeamId: model.NewId(), DisplayName: "A Name", @@ -382,6 +441,10 @@ func TestGetChannelsForScheme(t *testing.T) { _, ri4 := th.Client.GetChannelsForScheme(model.NewId(), 0, 100) CheckForbiddenStatus(t, ri4) + // Mark the migration as done again while we create a scheme. + res = <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + scheme2 := &model.Scheme{ Name: model.NewId(), Description: model.NewId(), @@ -390,6 +453,9 @@ func TestGetChannelsForScheme(t *testing.T) { scheme2, rs2 := th.SystemAdminClient.CreateScheme(scheme2) CheckNoError(t, rs2) + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + _, ri5 := th.SystemAdminClient.GetChannelsForScheme(scheme2.Id, 0, 100) CheckBadRequestStatus(t, ri5) } @@ -400,6 +466,11 @@ func TestPatchScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + // Basic test of creating a team scheme. scheme1 := &model.Scheme{ Name: model.NewId(), @@ -480,6 +551,16 @@ func TestPatchScheme(t *testing.T) { th.App.SetLicense(nil) _, r11 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch) CheckNotImplementedStatus(t, r11) + + // Mark the migration as not done. + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + + th.LoginSystemAdmin() + th.App.SetLicense(model.NewTestLicense("")) + + _, r12 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch) + CheckInternalErrorStatus(t, r12) } func TestDeleteScheme(t *testing.T) { @@ -489,6 +570,17 @@ func TestDeleteScheme(t *testing.T) { t.Run("ValidTeamScheme", func(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + + // Un-mark the migration at the end of the test. + defer func() { + res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + }() + // Create a team scheme. scheme1 := &model.Scheme{ Name: model.NewId(), @@ -515,7 +607,7 @@ func TestDeleteScheme(t *testing.T) { assert.Zero(t, role4.DeleteAt) // Make sure this scheme is in use by a team. - res := <-th.App.Srv.Store.Team().Save(&model.Team{ + res = <-th.App.Srv.Store.Team().Save(&model.Team{ Name: model.NewId(), DisplayName: model.NewId(), Email: model.NewId() + "@nowhere.com", @@ -571,6 +663,17 @@ func TestDeleteScheme(t *testing.T) { t.Run("ValidChannelScheme", func(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + + // Un-mark the migration at the end of the test. + defer func() { + res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + }() + // Create a channel scheme. scheme1 := &model.Scheme{ Name: model.NewId(), @@ -591,7 +694,7 @@ func TestDeleteScheme(t *testing.T) { assert.Zero(t, role4.DeleteAt) // Make sure this scheme is in use by a team. - res := <-th.App.Srv.Store.Channel().Save(&model.Channel{ + res = <-th.App.Srv.Store.Channel().Save(&model.Channel{ TeamId: model.NewId(), DisplayName: model.NewId(), Name: model.NewId(), @@ -635,6 +738,11 @@ func TestDeleteScheme(t *testing.T) { t.Run("FailureCases", func(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + scheme1 := &model.Scheme{ Name: model.NewId(), Description: model.NewId(), @@ -660,5 +768,14 @@ func TestDeleteScheme(t *testing.T) { th.App.SetLicense(nil) _, r5 := th.SystemAdminClient.DeleteScheme(s1.Id) CheckNotImplementedStatus(t, r5) + + // Test with migration not being done. + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + + th.App.SetLicense(model.NewTestLicense("")) + + _, r6 := th.SystemAdminClient.DeleteScheme(s1.Id) + CheckInternalErrorStatus(t, r6) }) } diff --git a/api4/team_test.go b/api4/team_test.go index 6df56f754..45d8e8f08 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -2059,6 +2059,17 @@ func TestUpdateTeamScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) + // Mark the migration as done. + <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) + assert.Nil(t, res.Err) + + // Un-mark the migration at the end of the test. + defer func() { + res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + }() + team := &model.Team{ DisplayName: "Name", Description: "Some description", -- cgit v1.2.3-1-g7c22 From c2ab85e0a36af24ee804c1d140cfe216022a4e45 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Thu, 17 May 2018 12:48:18 +0100 Subject: MM-10591: Well known error for all scheme endpoints pre-migration. (#8812) --- api4/scheme_test.go | 60 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 31 deletions(-) (limited to 'api4') diff --git a/api4/scheme_test.go b/api4/scheme_test.go index 92cfa4d30..2762ef92a 100644 --- a/api4/scheme_test.go +++ b/api4/scheme_test.go @@ -132,7 +132,7 @@ func TestCreateScheme(t *testing.T) { Scope: model.SCHEME_SCOPE_TEAM, } _, r7 := th.SystemAdminClient.CreateScheme(scheme7) - CheckInternalErrorStatus(t, r7) + CheckNotImplementedStatus(t, r7) } func TestGetScheme(t *testing.T) { @@ -148,7 +148,6 @@ func TestGetScheme(t *testing.T) { Scope: model.SCHEME_SCOPE_TEAM, } - // Mark the migration as done while we create the scheme. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) assert.Nil(t, res.Err) @@ -156,9 +155,6 @@ func TestGetScheme(t *testing.T) { s1, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - assert.Equal(t, s1.Name, scheme1.Name) assert.Equal(t, s1.Description, scheme1.Description) assert.NotZero(t, s1.CreateAt) @@ -192,6 +188,13 @@ func TestGetScheme(t *testing.T) { _, r7 := th.Client.GetScheme(s1.Id) CheckForbiddenStatus(t, r7) + + // Mark the migration as not done. + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + + _, r8 := th.SystemAdminClient.GetScheme(s1.Id) + CheckNotImplementedStatus(t, r8) } func TestGetSchemes(t *testing.T) { @@ -212,7 +215,6 @@ func TestGetSchemes(t *testing.T) { Scope: model.SCHEME_SCOPE_CHANNEL, } - // Mark the migration as done while we create the scheme. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) assert.Nil(t, res.Err) @@ -222,9 +224,6 @@ func TestGetSchemes(t *testing.T) { _, r2 := th.SystemAdminClient.CreateScheme(scheme2) CheckNoError(t, r2) - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - l3, r3 := th.SystemAdminClient.GetSchemes("", 0, 100) CheckNoError(t, r3) @@ -254,6 +253,13 @@ func TestGetSchemes(t *testing.T) { th.Client.Login(th.BasicUser.Username, th.BasicUser.Password) _, r8 := th.Client.GetSchemes("", 0, 100) CheckForbiddenStatus(t, r8) + + // Mark the migration as not done. + res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) + assert.Nil(t, res.Err) + + _, r9 := th.SystemAdminClient.GetSchemes("", 0, 100) + CheckNotImplementedStatus(t, r9) } func TestGetTeamsForScheme(t *testing.T) { @@ -262,7 +268,6 @@ func TestGetTeamsForScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) - // Mark the migration as done while we create the scheme. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) assert.Nil(t, res.Err) @@ -275,9 +280,6 @@ func TestGetTeamsForScheme(t *testing.T) { scheme1, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - team1 := &model.Team{ Name: GenerateTestUsername(), DisplayName: "A Test Team", @@ -338,10 +340,6 @@ func TestGetTeamsForScheme(t *testing.T) { _, ri4 := th.Client.GetTeamsForScheme(model.NewId(), 0, 100) CheckForbiddenStatus(t, ri4) - // Mark the migration as done again while we create a scheme. - res = <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) - scheme2 := &model.Scheme{ Name: model.NewId(), Description: model.NewId(), @@ -350,11 +348,15 @@ func TestGetTeamsForScheme(t *testing.T) { scheme2, rs2 := th.SystemAdminClient.CreateScheme(scheme2) CheckNoError(t, rs2) + _, ri5 := th.SystemAdminClient.GetTeamsForScheme(scheme2.Id, 0, 100) + CheckBadRequestStatus(t, ri5) + + // Mark the migration as not done. res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) assert.Nil(t, res.Err) - _, ri5 := th.SystemAdminClient.GetTeamsForScheme(scheme2.Id, 0, 100) - CheckBadRequestStatus(t, ri5) + _, ri6 := th.SystemAdminClient.GetTeamsForScheme(scheme1.Id, 0, 100) + CheckNotImplementedStatus(t, ri6) } func TestGetChannelsForScheme(t *testing.T) { @@ -363,7 +365,6 @@ func TestGetChannelsForScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) - // Mark the migration as done while we create the scheme. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) assert.Nil(t, res.Err) @@ -376,9 +377,6 @@ func TestGetChannelsForScheme(t *testing.T) { scheme1, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - channel1 := &model.Channel{ TeamId: model.NewId(), DisplayName: "A Name", @@ -441,10 +439,6 @@ func TestGetChannelsForScheme(t *testing.T) { _, ri4 := th.Client.GetChannelsForScheme(model.NewId(), 0, 100) CheckForbiddenStatus(t, ri4) - // Mark the migration as done again while we create a scheme. - res = <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) - scheme2 := &model.Scheme{ Name: model.NewId(), Description: model.NewId(), @@ -453,11 +447,15 @@ func TestGetChannelsForScheme(t *testing.T) { scheme2, rs2 := th.SystemAdminClient.CreateScheme(scheme2) CheckNoError(t, rs2) + _, ri5 := th.SystemAdminClient.GetChannelsForScheme(scheme2.Id, 0, 100) + CheckBadRequestStatus(t, ri5) + + // Mark the migration as not done. res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) assert.Nil(t, res.Err) - _, ri5 := th.SystemAdminClient.GetChannelsForScheme(scheme2.Id, 0, 100) - CheckBadRequestStatus(t, ri5) + _, ri6 := th.SystemAdminClient.GetChannelsForScheme(scheme1.Id, 0, 100) + CheckNotImplementedStatus(t, ri6) } func TestPatchScheme(t *testing.T) { @@ -560,7 +558,7 @@ func TestPatchScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) _, r12 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch) - CheckInternalErrorStatus(t, r12) + CheckNotImplementedStatus(t, r12) } func TestDeleteScheme(t *testing.T) { @@ -776,6 +774,6 @@ func TestDeleteScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) _, r6 := th.SystemAdminClient.DeleteScheme(s1.Id) - CheckInternalErrorStatus(t, r6) + CheckNotImplementedStatus(t, r6) }) } -- cgit v1.2.3-1-g7c22 From 319d61123a0418ea9caa9510b8ad1e9a302c7b93 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Thu, 17 May 2018 12:48:31 +0100 Subject: MM-10615: Reset teams/channels to default scheme on delete scheme. (#8811) --- api4/scheme_test.go | 50 ++++++++++---------------------------------------- 1 file changed, 10 insertions(+), 40 deletions(-) (limited to 'api4') diff --git a/api4/scheme_test.go b/api4/scheme_test.go index 2762ef92a..16c87cfac 100644 --- a/api4/scheme_test.go +++ b/api4/scheme_test.go @@ -615,29 +615,6 @@ func TestDeleteScheme(t *testing.T) { assert.Nil(t, res.Err) team := res.Data.(*model.Team) - // Try and fail to delete the scheme. - _, r2 := th.SystemAdminClient.DeleteScheme(s1.Id) - CheckInternalErrorStatus(t, r2) - - 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) - - // Change the team using it to a different scheme. - emptyString := "" - team.SchemeId = &emptyString - res = <-th.App.Srv.Store.Team().Update(team) - // Delete the Scheme. _, r3 := th.SystemAdminClient.DeleteScheme(s1.Id) CheckNoError(t, r3) @@ -656,6 +633,11 @@ func TestDeleteScheme(t *testing.T) { 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) { @@ -702,23 +684,6 @@ func TestDeleteScheme(t *testing.T) { assert.Nil(t, res.Err) channel := res.Data.(*model.Channel) - // Try and fail to delete the scheme. - _, r2 := th.SystemAdminClient.DeleteScheme(s1.Id) - CheckInternalErrorStatus(t, r2) - - 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) - - // Change the team using it to a different scheme. - emptyString := "" - channel.SchemeId = &emptyString - res = <-th.App.Srv.Store.Channel().Update(channel) - // Delete the Scheme. _, r3 := th.SystemAdminClient.DeleteScheme(s1.Id) CheckNoError(t, r3) @@ -731,6 +696,11 @@ func TestDeleteScheme(t *testing.T) { 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) { -- cgit v1.2.3-1-g7c22 From 463065c8ba4b4aece7fd9b7764ba917df3e73292 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Thu, 17 May 2018 16:29:31 +0100 Subject: MM-10606: License feature flag for custom schemes. (#8804) * MM-10606: Add new field to license for custom schemes. * Add feature flag to license check for Schemes. --- api4/scheme.go | 6 +++--- api4/scheme_test.go | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'api4') diff --git a/api4/scheme.go b/api4/scheme.go index bdfe69870..5070d1c4a 100644 --- a/api4/scheme.go +++ b/api4/scheme.go @@ -26,7 +26,7 @@ func createScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - if c.App.License() == nil { + 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 } @@ -161,7 +161,7 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - if c.App.License() == nil { + 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 } @@ -192,7 +192,7 @@ func deleteScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - if c.App.License() == nil { + 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 } diff --git a/api4/scheme_test.go b/api4/scheme_test.go index 16c87cfac..9e5ed1aca 100644 --- a/api4/scheme_test.go +++ b/api4/scheme_test.go @@ -16,7 +16,7 @@ func TestCreateScheme(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) // Mark the migration as done. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) @@ -124,7 +124,7 @@ func TestCreateScheme(t *testing.T) { assert.Nil(t, res.Err) th.LoginSystemAdmin() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) scheme7 := &model.Scheme{ Name: model.NewId(), @@ -139,7 +139,7 @@ func TestGetScheme(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) // Basic test of creating a team scheme. scheme1 := &model.Scheme{ @@ -201,7 +201,7 @@ func TestGetSchemes(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) scheme1 := &model.Scheme{ Name: model.NewId(), @@ -266,7 +266,7 @@ func TestGetTeamsForScheme(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) @@ -363,7 +363,7 @@ func TestGetChannelsForScheme(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) @@ -462,7 +462,7 @@ func TestPatchScheme(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer th.TearDown() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) // Mark the migration as done. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) @@ -555,7 +555,7 @@ func TestPatchScheme(t *testing.T) { assert.Nil(t, res.Err) th.LoginSystemAdmin() - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) _, r12 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch) CheckNotImplementedStatus(t, r12) @@ -566,7 +566,7 @@ func TestDeleteScheme(t *testing.T) { defer th.TearDown() t.Run("ValidTeamScheme", func(t *testing.T) { - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) // Mark the migration as done. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) @@ -641,7 +641,7 @@ func TestDeleteScheme(t *testing.T) { }) t.Run("ValidChannelScheme", func(t *testing.T) { - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) // Mark the migration as done. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) @@ -704,7 +704,7 @@ func TestDeleteScheme(t *testing.T) { }) t.Run("FailureCases", func(t *testing.T) { - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) // Mark the migration as done. <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) @@ -741,7 +741,7 @@ func TestDeleteScheme(t *testing.T) { res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) assert.Nil(t, res.Err) - th.App.SetLicense(model.NewTestLicense("")) + th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) _, r6 := th.SystemAdminClient.DeleteScheme(s1.Id) CheckNotImplementedStatus(t, r6) -- cgit v1.2.3-1-g7c22 From e0390632b3c941670671d968b8828bcefbf71581 Mon Sep 17 00:00:00 2001 From: Martin Kraft Date: Thu, 17 May 2018 11:37:00 -0400 Subject: MM-10264: Adds CLI command to import and export permissions. (#8787) * MM-10264: Adds CLI command to import and export permissions. * MM-10264: Changes Scheme Name to DisplayName and adds Name slug field. * MM-10264: Changes display name max size. * MM-10264: Another merge fix. * MM-10264: Changes for more Schemes methods checking for migration. * MM-10264: More updates for Schemes migration checking. --- api4/channel_test.go | 6 ++++-- api4/scheme_test.go | 41 +++++++++++++++++++++++++++++++++++++++-- api4/team_test.go | 6 ++++-- 3 files changed, 47 insertions(+), 6 deletions(-) (limited to 'api4') diff --git a/api4/channel_test.go b/api4/channel_test.go index 551a1a484..f871e66ea 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -1924,13 +1924,15 @@ func TestUpdateChannelScheme(t *testing.T) { channel, _ = th.SystemAdminClient.CreateChannel(channel) channelScheme := &model.Scheme{ - Name: "Name", + DisplayName: "DisplayName", + Name: model.NewId(), Description: "Some description", Scope: model.SCHEME_SCOPE_CHANNEL, } channelScheme, _ = th.SystemAdminClient.CreateScheme(channelScheme) teamScheme := &model.Scheme{ - Name: "Name", + DisplayName: "DisplayName", + Name: model.NewId(), Description: "Some description", Scope: model.SCHEME_SCOPE_TEAM, } diff --git a/api4/scheme_test.go b/api4/scheme_test.go index 9e5ed1aca..461b03421 100644 --- a/api4/scheme_test.go +++ b/api4/scheme_test.go @@ -25,6 +25,7 @@ func TestCreateScheme(t *testing.T) { // Basic test of creating a team scheme. scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_TEAM, @@ -33,6 +34,7 @@ func TestCreateScheme(t *testing.T) { 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) @@ -56,6 +58,7 @@ func TestCreateScheme(t *testing.T) { // Basic Test of a Channel scheme. scheme2 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_CHANNEL, @@ -64,6 +67,7 @@ func TestCreateScheme(t *testing.T) { 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) @@ -83,6 +87,7 @@ func TestCreateScheme(t *testing.T) { // Try and create a scheme with an invalid scope. scheme3 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.NewId(), @@ -91,17 +96,29 @@ func TestCreateScheme(t *testing.T) { _, r3 := th.SystemAdminClient.CreateScheme(scheme3) CheckBadRequestStatus(t, r3) - // Try and create a scheme with an invalid name. + // Try and create a scheme with an invalid display name. scheme4 := &model.Scheme{ - Name: strings.Repeat(model.NewId(), 100), + 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, @@ -112,6 +129,7 @@ func TestCreateScheme(t *testing.T) { // 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, @@ -127,6 +145,7 @@ func TestCreateScheme(t *testing.T) { 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, @@ -143,6 +162,7 @@ func TestGetScheme(t *testing.T) { // Basic test of creating a team scheme. scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_TEAM, @@ -155,6 +175,7 @@ func TestGetScheme(t *testing.T) { 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) @@ -204,12 +225,14 @@ func TestGetSchemes(t *testing.T) { 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, @@ -273,6 +296,7 @@ func TestGetTeamsForScheme(t *testing.T) { assert.Nil(t, res.Err) scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_TEAM, @@ -341,6 +365,7 @@ func TestGetTeamsForScheme(t *testing.T) { CheckForbiddenStatus(t, ri4) scheme2 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_CHANNEL, @@ -370,6 +395,7 @@ func TestGetChannelsForScheme(t *testing.T) { assert.Nil(t, res.Err) scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_CHANNEL, @@ -440,6 +466,7 @@ func TestGetChannelsForScheme(t *testing.T) { CheckForbiddenStatus(t, ri4) scheme2 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_TEAM, @@ -471,6 +498,7 @@ func TestPatchScheme(t *testing.T) { // Basic test of creating a team scheme. scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_TEAM, @@ -479,6 +507,7 @@ func TestPatchScheme(t *testing.T) { 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) @@ -497,15 +526,18 @@ func TestPatchScheme(t *testing.T) { // 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) @@ -515,11 +547,13 @@ func TestPatchScheme(t *testing.T) { // 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) @@ -581,6 +615,7 @@ func TestDeleteScheme(t *testing.T) { // Create a team scheme. scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_TEAM, @@ -656,6 +691,7 @@ func TestDeleteScheme(t *testing.T) { // Create a channel scheme. scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_CHANNEL, @@ -712,6 +748,7 @@ func TestDeleteScheme(t *testing.T) { assert.Nil(t, res.Err) scheme1 := &model.Scheme{ + DisplayName: model.NewId(), Name: model.NewId(), Description: model.NewId(), Scope: model.SCHEME_SCOPE_CHANNEL, diff --git a/api4/team_test.go b/api4/team_test.go index 45d8e8f08..a3f4af0cf 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -2083,13 +2083,15 @@ func TestUpdateTeamScheme(t *testing.T) { team, _ = th.SystemAdminClient.CreateTeam(team) teamScheme := &model.Scheme{ - Name: "Name", + DisplayName: "DisplayName", + Name: model.NewId(), Description: "Some description", Scope: model.SCHEME_SCOPE_TEAM, } teamScheme, _ = th.SystemAdminClient.CreateScheme(teamScheme) channelScheme := &model.Scheme{ - Name: "Name", + DisplayName: "DisplayName", + Name: model.NewId(), Description: "Some description", Scope: model.SCHEME_SCOPE_CHANNEL, } -- cgit v1.2.3-1-g7c22 From eb78d273f39202046fa71555a5a19b0ec8a95cb3 Mon Sep 17 00:00:00 2001 From: Martin Kraft Date: Mon, 21 May 2018 06:10:26 -0400 Subject: Refactors migrations check. (#8814) --- api4/channel_test.go | 13 +------- api4/scheme_test.go | 85 +++++++++++----------------------------------------- api4/team_test.go | 11 +------ 3 files changed, 20 insertions(+), 89 deletions(-) (limited to 'api4') diff --git a/api4/channel_test.go b/api4/channel_test.go index f871e66ea..8fd68fc08 100644 --- a/api4/channel_test.go +++ b/api4/channel_test.go @@ -12,8 +12,6 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" ) @@ -1892,16 +1890,7 @@ func TestUpdateChannelScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) - // Mark the migration as done. - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) - - // Un-mark the migration at the end of the test. - defer func() { - res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - }() + th.App.SetPhase2PermissionsMigrationStatus(true) team := &model.Team{ DisplayName: "Name", diff --git a/api4/scheme_test.go b/api4/scheme_test.go index 461b03421..67cfda4fc 100644 --- a/api4/scheme_test.go +++ b/api4/scheme_test.go @@ -18,10 +18,7 @@ func TestCreateScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) - // Mark the migration as done. - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(true) // Basic test of creating a team scheme. scheme1 := &model.Scheme{ @@ -137,9 +134,7 @@ func TestCreateScheme(t *testing.T) { _, r6 := th.SystemAdminClient.CreateScheme(scheme6) CheckNotImplementedStatus(t, r6) - // Mark the migration as not done. - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(false) th.LoginSystemAdmin() th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) @@ -168,9 +163,7 @@ func TestGetScheme(t *testing.T) { Scope: model.SCHEME_SCOPE_TEAM, } - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(true) s1, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) @@ -210,9 +203,7 @@ func TestGetScheme(t *testing.T) { _, r7 := th.Client.GetScheme(s1.Id) CheckForbiddenStatus(t, r7) - // Mark the migration as not done. - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(false) _, r8 := th.SystemAdminClient.GetScheme(s1.Id) CheckNotImplementedStatus(t, r8) @@ -238,9 +229,7 @@ func TestGetSchemes(t *testing.T) { Scope: model.SCHEME_SCOPE_CHANNEL, } - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(true) _, r1 := th.SystemAdminClient.CreateScheme(scheme1) CheckNoError(t, r1) @@ -277,9 +266,7 @@ func TestGetSchemes(t *testing.T) { _, r8 := th.Client.GetSchemes("", 0, 100) CheckForbiddenStatus(t, r8) - // Mark the migration as not done. - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(false) _, r9 := th.SystemAdminClient.GetSchemes("", 0, 100) CheckNotImplementedStatus(t, r9) @@ -291,9 +278,7 @@ func TestGetTeamsForScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(true) scheme1 := &model.Scheme{ DisplayName: model.NewId(), @@ -376,9 +361,7 @@ func TestGetTeamsForScheme(t *testing.T) { _, ri5 := th.SystemAdminClient.GetTeamsForScheme(scheme2.Id, 0, 100) CheckBadRequestStatus(t, ri5) - // Mark the migration as not done. - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(false) _, ri6 := th.SystemAdminClient.GetTeamsForScheme(scheme1.Id, 0, 100) CheckNotImplementedStatus(t, ri6) @@ -390,9 +373,7 @@ func TestGetChannelsForScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(true) scheme1 := &model.Scheme{ DisplayName: model.NewId(), @@ -477,9 +458,7 @@ func TestGetChannelsForScheme(t *testing.T) { _, ri5 := th.SystemAdminClient.GetChannelsForScheme(scheme2.Id, 0, 100) CheckBadRequestStatus(t, ri5) - // Mark the migration as not done. - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(false) _, ri6 := th.SystemAdminClient.GetChannelsForScheme(scheme1.Id, 0, 100) CheckNotImplementedStatus(t, ri6) @@ -491,10 +470,7 @@ func TestPatchScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) - // Mark the migration as done. - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(true) // Basic test of creating a team scheme. scheme1 := &model.Scheme{ @@ -584,9 +560,7 @@ func TestPatchScheme(t *testing.T) { _, r11 := th.SystemAdminClient.PatchScheme(s6.Id, schemePatch) CheckNotImplementedStatus(t, r11) - // Mark the migration as not done. - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(false) th.LoginSystemAdmin() th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) @@ -602,16 +576,7 @@ func TestDeleteScheme(t *testing.T) { t.Run("ValidTeamScheme", func(t *testing.T) { th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) - // Mark the migration as done. - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) - - // Un-mark the migration at the end of the test. - defer func() { - res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - }() + th.App.SetPhase2PermissionsMigrationStatus(true) // Create a team scheme. scheme1 := &model.Scheme{ @@ -640,7 +605,7 @@ func TestDeleteScheme(t *testing.T) { assert.Zero(t, role4.DeleteAt) // Make sure this scheme is in use by a team. - res = <-th.App.Srv.Store.Team().Save(&model.Team{ + res := <-th.App.Srv.Store.Team().Save(&model.Team{ Name: model.NewId(), DisplayName: model.NewId(), Email: model.NewId() + "@nowhere.com", @@ -678,16 +643,7 @@ func TestDeleteScheme(t *testing.T) { t.Run("ValidChannelScheme", func(t *testing.T) { th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) - // Mark the migration as done. - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) - - // Un-mark the migration at the end of the test. - defer func() { - res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - }() + th.App.SetPhase2PermissionsMigrationStatus(true) // Create a channel scheme. scheme1 := &model.Scheme{ @@ -710,7 +666,7 @@ func TestDeleteScheme(t *testing.T) { assert.Zero(t, role4.DeleteAt) // Make sure this scheme is in use by a team. - res = <-th.App.Srv.Store.Channel().Save(&model.Channel{ + res := <-th.App.Srv.Store.Channel().Save(&model.Channel{ TeamId: model.NewId(), DisplayName: model.NewId(), Name: model.NewId(), @@ -742,10 +698,7 @@ func TestDeleteScheme(t *testing.T) { t.Run("FailureCases", func(t *testing.T) { th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) - // Mark the migration as done. - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(true) scheme1 := &model.Scheme{ DisplayName: model.NewId(), @@ -774,9 +727,7 @@ func TestDeleteScheme(t *testing.T) { _, r5 := th.SystemAdminClient.DeleteScheme(s1.Id) CheckNotImplementedStatus(t, r5) - // Test with migration not being done. - res = <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) + th.App.SetPhase2PermissionsMigrationStatus(false) th.App.SetLicense(model.NewTestLicense("custom_permissions_schemes")) diff --git a/api4/team_test.go b/api4/team_test.go index a3f4af0cf..f08aa6ba9 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -2059,16 +2059,7 @@ func TestUpdateTeamScheme(t *testing.T) { th.App.SetLicense(model.NewTestLicense("")) - // Mark the migration as done. - <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - res := <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"}) - assert.Nil(t, res.Err) - - // Un-mark the migration at the end of the test. - defer func() { - res := <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2) - assert.Nil(t, res.Err) - }() + th.App.SetPhase2PermissionsMigrationStatus(true) team := &model.Team{ DisplayName: "Name", -- cgit v1.2.3-1-g7c22 From 7225abddeefb569f1f2da739211d7797b63814a2 Mon Sep 17 00:00:00 2001 From: George Goldberg Date: Mon, 28 May 2018 14:46:52 +0100 Subject: MM-8814: Remove implicit permission grants from post ownership. (#8391) --- api4/post.go | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) (limited to 'api4') 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 -- cgit v1.2.3-1-g7c22 From bf4cefc3496686850757b2d44219ea2425871dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Tue, 29 May 2018 10:32:07 +0200 Subject: Allow to update the teams scheme to default scheme (#8855) --- api4/team.go | 22 ++++++++++++---------- api4/team_test.go | 4 ++++ 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'api4') diff --git a/api4/team.go b/api4/team.go index 508602d0e..74b385122 100644 --- a/api4/team.go +++ b/api4/team.go @@ -842,7 +842,7 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) { } schemeID := model.SchemeIDFromJson(r.Body) - if schemeID == nil || len(*schemeID) != 26 { + if schemeID == nil || (len(*schemeID) != 26 && *schemeID != "") { c.SetInvalidParam("scheme_id") return } @@ -857,15 +857,17 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - scheme, err := c.App.GetScheme(*schemeID) - if err != nil { - c.Err = err - 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 + 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) @@ -874,7 +876,7 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) { return } - team.SchemeId = &scheme.Id + team.SchemeId = schemeID _, err = c.App.UpdateTeamScheme(team) if err != nil { diff --git a/api4/team_test.go b/api4/team_test.go index b47a8b650..079ba37ec 100644 --- a/api4/team_test.go +++ b/api4/team_test.go @@ -2095,6 +2095,10 @@ func TestUpdateTeamScheme(t *testing.T) { _, 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) -- cgit v1.2.3-1-g7c22 From e88fe4bb1dea4918284ee3c6e5aee5a8497ff2b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Tue, 29 May 2018 16:58:12 +0200 Subject: MM-8853: Adding MANAGE_EMOJIS and MANAGE_OTHERS_EMOJIS permissions (#8860) * MM-8853: Adding MANAGE_EMOJIS and MANAGE_OTHERS_EMOJIS permissions * MM-8853: Removing unnecesary emoji enterprise feature * Create emojis migration * Adding MANAGE_EMOJIS and MANAGE_OTHERS_EMOJIS always to system admins * Simplifing permissions checks * Revert "Simplifing permissions checks" This reverts commit e2cafc1905fc9e20125dd9a1552d2d0c7340ae59. --- api4/apitestlib.go | 1 + api4/emoji.go | 66 ++++++++++++++++++++++++---- api4/emoji_test.go | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++-- api4/role.go | 1 + 4 files changed, 181 insertions(+), 11 deletions(-) (limited to 'api4') diff --git a/api4/apitestlib.go b/api4/apitestlib.go index 952c21df3..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 }) 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/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) -- cgit v1.2.3-1-g7c22