mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
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.
This commit is contained in:
committed by
Martin Kraft
parent
853445dc2e
commit
cd55c44c8f
@@ -245,28 +245,36 @@ func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) {
|
|||||||
func (me *TestHelper) UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
|
func (me *TestHelper) UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
|
||||||
utils.DisableDebugLogForTest()
|
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().GetMember(team.Id, user.Id); tmr.Err == nil {
|
||||||
if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); 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()
|
utils.EnableDebugLogForTest()
|
||||||
l4g.Error(tmr.Err.Error())
|
|
||||||
l4g.Close()
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
panic(tmr.Err)
|
panic(tmr.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.EnableDebugLogForTest()
|
utils.EnableDebugLogForTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Team) {
|
func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Team) {
|
||||||
utils.DisableDebugLogForTest()
|
utils.DisableDebugLogForTest()
|
||||||
|
|
||||||
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID}
|
if tmr := <-me.App.Srv.Store.Team().GetMember(team.Id, user.Id); tmr.Err == nil {
|
||||||
if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); 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()
|
utils.EnableDebugLogForTest()
|
||||||
l4g.Error(tmr.Err.Error())
|
|
||||||
l4g.Close()
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
panic(tmr.Err)
|
panic(tmr.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.EnableDebugLogForTest()
|
utils.EnableDebugLogForTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +283,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 {
|
if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
|
||||||
cm := cmr.Data.(*model.ChannelMember)
|
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 {
|
if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil {
|
||||||
utils.EnableDebugLogForTest()
|
utils.EnableDebugLogForTest()
|
||||||
panic(sr.Err)
|
panic(sr.Err)
|
||||||
@@ -293,7 +301,7 @@ func (me *TestHelper) MakeUserChannelUser(user *model.User, channel *model.Chann
|
|||||||
|
|
||||||
if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
|
if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
|
||||||
cm := cmr.Data.(*model.ChannelMember)
|
cm := cmr.Data.(*model.ChannelMember)
|
||||||
cm.Roles = "channel_user"
|
cm.SchemeAdmin = false
|
||||||
if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil {
|
if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil {
|
||||||
utils.EnableDebugLogForTest()
|
utils.EnableDebugLogForTest()
|
||||||
panic(sr.Err)
|
panic(sr.Err)
|
||||||
|
|||||||
@@ -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 {
|
if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
|
||||||
cm := cmr.Data.(*model.ChannelMember)
|
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 {
|
if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil {
|
||||||
utils.EnableDebugLogForTest()
|
utils.EnableDebugLogForTest()
|
||||||
panic(sr.Err)
|
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) {
|
func (me *TestHelper) UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
|
||||||
utils.DisableDebugLogForTest()
|
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().GetMember(team.Id, user.Id); tmr.Err == nil {
|
||||||
if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); 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()
|
utils.EnableDebugLogForTest()
|
||||||
l4g.Error(tmr.Err.Error())
|
|
||||||
l4g.Close()
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
panic(tmr.Err)
|
panic(tmr.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.EnableDebugLogForTest()
|
utils.EnableDebugLogForTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Team) {
|
func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Team) {
|
||||||
utils.DisableDebugLogForTest()
|
utils.DisableDebugLogForTest()
|
||||||
|
|
||||||
tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID}
|
if tmr := <-me.App.Srv.Store.Team().GetMember(team.Id, user.Id); tmr.Err == nil {
|
||||||
if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); 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()
|
utils.EnableDebugLogForTest()
|
||||||
l4g.Error(tmr.Err.Error())
|
|
||||||
l4g.Close()
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
panic(tmr.Err)
|
panic(tmr.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.EnableDebugLogForTest()
|
utils.EnableDebugLogForTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1388,7 +1388,7 @@ func TestUpdateChannelRoles(t *testing.T) {
|
|||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
Client := th.Client
|
Client := th.Client
|
||||||
|
|
||||||
const CHANNEL_ADMIN = "channel_admin channel_user"
|
const CHANNEL_ADMIN = "channel_user channel_admin"
|
||||||
const CHANNEL_MEMBER = "channel_user"
|
const CHANNEL_MEMBER = "channel_user"
|
||||||
|
|
||||||
// User 1 creates a channel, making them channel admin by default.
|
// User 1 creates a channel, making them channel admin by default.
|
||||||
|
|||||||
@@ -1672,7 +1672,7 @@ func TestUpdateTeamMemberRoles(t *testing.T) {
|
|||||||
|
|
||||||
// user 1 (team admin) tries to demote system admin (not member of a team)
|
// 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)
|
_, 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)
|
// user 1 (team admin) demotes system admin (member of a team)
|
||||||
th.LinkUserToTeam(th.SystemAdminUser, th.BasicTeam)
|
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
|
// user 1 (team admin) tries to promote a random user
|
||||||
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, model.NewId(), TEAM_ADMIN)
|
_, 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
|
// user 1 (team admin) tries to promote invalid team permission
|
||||||
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, "junk")
|
_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, "junk")
|
||||||
|
|||||||
@@ -199,6 +199,10 @@ func (a *App) RolesGrantPermission(roleNames []string, permissionId string) bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, role := range roles {
|
for _, role := range roles {
|
||||||
|
if role.DeleteAt != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
permissions := role.Permissions
|
permissions := role.Permissions
|
||||||
for _, permission := range permissions {
|
for _, permission := range permissions {
|
||||||
if permission == permissionId {
|
if permission == permissionId {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func (a *App) CreateDefaultChannels(teamId string) ([]*model.Channel, *model.App
|
|||||||
return channels, nil
|
return channels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) JoinDefaultChannels(teamId string, user *model.User, channelRole string, userRequestorId string) *model.AppError {
|
func (a *App) JoinDefaultChannels(teamId string, user *model.User, shouldBeAdmin bool, userRequestorId string) *model.AppError {
|
||||||
var err *model.AppError = nil
|
var err *model.AppError = nil
|
||||||
|
|
||||||
var requestor *model.User
|
var requestor *model.User
|
||||||
@@ -52,7 +52,8 @@ func (a *App) JoinDefaultChannels(teamId string, user *model.User, channelRole s
|
|||||||
cm := &model.ChannelMember{
|
cm := &model.ChannelMember{
|
||||||
ChannelId: townSquare.Id,
|
ChannelId: townSquare.Id,
|
||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
Roles: channelRole,
|
SchemeUser: true,
|
||||||
|
SchemeAdmin: shouldBeAdmin,
|
||||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +86,8 @@ func (a *App) JoinDefaultChannels(teamId string, user *model.User, channelRole s
|
|||||||
cm := &model.ChannelMember{
|
cm := &model.ChannelMember{
|
||||||
ChannelId: offTopic.Id,
|
ChannelId: offTopic.Id,
|
||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
Roles: channelRole,
|
SchemeUser: true,
|
||||||
|
SchemeAdmin: shouldBeAdmin,
|
||||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +168,8 @@ func (a *App) CreateChannel(channel *model.Channel, addMember bool) (*model.Chan
|
|||||||
cm := &model.ChannelMember{
|
cm := &model.ChannelMember{
|
||||||
ChannelId: sc.Id,
|
ChannelId: sc.Id,
|
||||||
UserId: channel.CreatorId,
|
UserId: channel.CreatorId,
|
||||||
Roles: model.CHANNEL_USER_ROLE_ID + " " + model.CHANNEL_ADMIN_ROLE_ID,
|
SchemeUser: true,
|
||||||
|
SchemeAdmin: true,
|
||||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +325,7 @@ func (a *App) createGroupChannel(userIds []string, creatorId string) (*model.Cha
|
|||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
ChannelId: group.Id,
|
ChannelId: group.Id,
|
||||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||||
Roles: model.CHANNEL_USER_ROLE_ID,
|
SchemeUser: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if result := <-a.Srv.Store.Channel().SaveMember(cm); result.Err != nil {
|
if result := <-a.Srv.Store.Channel().SaveMember(cm); result.Err != nil {
|
||||||
@@ -432,6 +435,39 @@ func (a *App) PatchChannel(channel *model.Channel, patch *model.ChannelPatch, us
|
|||||||
return channel, err
|
return channel, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) GetSchemeRolesForChannel(channelId string) (string, string, *model.AppError) {
|
||||||
|
var channel *model.Channel
|
||||||
|
var err *model.AppError
|
||||||
|
|
||||||
|
if channel, err = a.GetChannel(channelId); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if channel.SchemeId != nil && len(*channel.SchemeId) != 0 {
|
||||||
|
if scheme, err := a.GetScheme(*channel.SchemeId); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
} else {
|
||||||
|
return scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var team *model.Team
|
||||||
|
|
||||||
|
if team, err = a.GetTeam(channel.TeamId); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if team.SchemeId != nil && len(*team.SchemeId) != 0 {
|
||||||
|
if scheme, err := a.GetScheme(*team.SchemeId); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
} else {
|
||||||
|
return scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.CHANNEL_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) UpdateChannelMemberRoles(channelId string, userId string, newRoles string) (*model.ChannelMember, *model.AppError) {
|
func (a *App) UpdateChannelMemberRoles(channelId string, userId string, newRoles string) (*model.ChannelMember, *model.AppError) {
|
||||||
var member *model.ChannelMember
|
var member *model.ChannelMember
|
||||||
var err *model.AppError
|
var err *model.AppError
|
||||||
@@ -439,14 +475,42 @@ func (a *App) UpdateChannelMemberRoles(channelId string, userId string, newRoles
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
|
schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForChannel(channelId)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
member.Roles = newRoles
|
var newExplicitRoles []string
|
||||||
|
member.SchemeUser = false
|
||||||
|
member.SchemeAdmin = false
|
||||||
|
|
||||||
|
for _, roleName := range strings.Fields(newRoles) {
|
||||||
|
if role, err := a.GetRoleByName(roleName); err != nil {
|
||||||
|
err.StatusCode = http.StatusBadRequest
|
||||||
|
return nil, err
|
||||||
|
} else if !role.SchemeManaged {
|
||||||
|
// The role is not scheme-managed, so it's OK to apply it to the explicit roles field.
|
||||||
|
newExplicitRoles = append(newExplicitRoles, roleName)
|
||||||
|
} else {
|
||||||
|
// The role is scheme-managed, so need to check if it is part of the scheme for this channel or not.
|
||||||
|
switch roleName {
|
||||||
|
case schemeAdminRole:
|
||||||
|
member.SchemeAdmin = true
|
||||||
|
case schemeUserRole:
|
||||||
|
member.SchemeUser = true
|
||||||
|
default:
|
||||||
|
// If not part of the scheme for this channel, then it is not allowed to apply it as an explicit role.
|
||||||
|
return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.scheme_role.app_error", nil, "role_name="+roleName, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
member.ExplicitRoles = strings.Join(newExplicitRoles, " ")
|
||||||
|
|
||||||
if result := <-a.Srv.Store.Channel().UpdateMember(member); result.Err != nil {
|
if result := <-a.Srv.Store.Channel().UpdateMember(member); result.Err != nil {
|
||||||
return nil, result.Err
|
return nil, result.Err
|
||||||
|
} else {
|
||||||
|
member = result.Data.(*model.ChannelMember)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.InvalidateCacheForUser(userId)
|
a.InvalidateCacheForUser(userId)
|
||||||
@@ -591,7 +655,7 @@ func (a *App) addUserToChannel(user *model.User, channel *model.Channel, teamMem
|
|||||||
ChannelId: channel.Id,
|
ChannelId: channel.Id,
|
||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||||
Roles: model.CHANNEL_USER_ROLE_ID,
|
SchemeUser: true,
|
||||||
}
|
}
|
||||||
if result := <-a.Srv.Store.Channel().SaveMember(newMember); result.Err != nil {
|
if result := <-a.Srv.Store.Channel().SaveMember(newMember); result.Err != nil {
|
||||||
l4g.Error("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, result.Err)
|
l4g.Error("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, result.Err)
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ func TestJoinDefaultChannelsCreatesChannelMemberHistoryRecordTownSquare(t *testi
|
|||||||
|
|
||||||
// create a new user that joins the default channels
|
// create a new user that joins the default channels
|
||||||
user := th.CreateUser()
|
user := th.CreateUser()
|
||||||
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, model.CHANNEL_USER_ROLE_ID, "")
|
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "")
|
||||||
|
|
||||||
// there should be a ChannelMemberHistory record for the user
|
// there should be a ChannelMemberHistory record for the user
|
||||||
histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistoryResult)
|
histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, townSquareChannelId)).([]*model.ChannelMemberHistoryResult)
|
||||||
@@ -146,7 +146,7 @@ func TestJoinDefaultChannelsCreatesChannelMemberHistoryRecordOffTopic(t *testing
|
|||||||
|
|
||||||
// create a new user that joins the default channels
|
// create a new user that joins the default channels
|
||||||
user := th.CreateUser()
|
user := th.CreateUser()
|
||||||
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, model.CHANNEL_USER_ROLE_ID, "")
|
th.App.JoinDefaultChannels(th.BasicTeam.Id, user, false, "")
|
||||||
|
|
||||||
// there should be a ChannelMemberHistory record for the user
|
// there should be a ChannelMemberHistory record for the user
|
||||||
histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistoryResult)
|
histories := store.Must(th.App.Srv.Store.ChannelMemberHistory().GetUsersInChannelDuring(model.GetMillis()-100, model.GetMillis()+100, offTopicChannelId)).([]*model.ChannelMemberHistoryResult)
|
||||||
|
|||||||
14
app/scheme.go
Normal file
14
app/scheme.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package app
|
||||||
|
|
||||||
|
import "github.com/mattermost/mattermost-server/model"
|
||||||
|
|
||||||
|
func (a *App) GetScheme(id string) (*model.Scheme, *model.AppError) {
|
||||||
|
if result := <-a.Srv.Store.Scheme().Get(id); result.Err != nil {
|
||||||
|
return nil, result.Err
|
||||||
|
} else {
|
||||||
|
return result.Data.(*model.Scheme), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
76
app/team.go
76
app/team.go
@@ -141,17 +141,31 @@ func (a *App) sendTeamEvent(team *model.Team, event string) {
|
|||||||
a.Publish(message)
|
a.Publish(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) GetSchemeRolesForTeam(teamId string) (string, string, *model.AppError) {
|
||||||
|
var team *model.Team
|
||||||
|
var err *model.AppError
|
||||||
|
|
||||||
|
if team, err = a.GetTeam(teamId); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if team.SchemeId != nil && len(*team.SchemeId) != 0 {
|
||||||
|
if scheme, err := a.GetScheme(*team.SchemeId); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
} else {
|
||||||
|
return scheme.DefaultTeamUserRole, scheme.DefaultTeamAdminRole, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.TEAM_USER_ROLE_ID, model.TEAM_ADMIN_ROLE_ID, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) UpdateTeamMemberRoles(teamId string, userId string, newRoles string) (*model.TeamMember, *model.AppError) {
|
func (a *App) UpdateTeamMemberRoles(teamId string, userId string, newRoles string) (*model.TeamMember, *model.AppError) {
|
||||||
var member *model.TeamMember
|
var member *model.TeamMember
|
||||||
if result := <-a.Srv.Store.Team().GetTeamsForUser(userId); result.Err != nil {
|
if result := <-a.Srv.Store.Team().GetMember(teamId, userId); result.Err != nil {
|
||||||
return nil, result.Err
|
return nil, result.Err
|
||||||
} else {
|
} else {
|
||||||
members := result.Data.([]*model.TeamMember)
|
member = result.Data.(*model.TeamMember)
|
||||||
for _, m := range members {
|
|
||||||
if m.TeamId == teamId {
|
|
||||||
member = m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if member == nil {
|
if member == nil {
|
||||||
@@ -159,14 +173,42 @@ func (a *App) UpdateTeamMemberRoles(teamId string, userId string, newRoles strin
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
|
schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForTeam(teamId)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
member.Roles = newRoles
|
var newExplicitRoles []string
|
||||||
|
member.SchemeUser = false
|
||||||
|
member.SchemeAdmin = false
|
||||||
|
|
||||||
|
for _, roleName := range strings.Fields(newRoles) {
|
||||||
|
if role, err := a.GetRoleByName(roleName); err != nil {
|
||||||
|
err.StatusCode = http.StatusBadRequest
|
||||||
|
return nil, err
|
||||||
|
} else if !role.SchemeManaged {
|
||||||
|
// The role is not scheme-managed, so it's OK to apply it to the explicit roles field.
|
||||||
|
newExplicitRoles = append(newExplicitRoles, roleName)
|
||||||
|
} else {
|
||||||
|
// The role is scheme-managed, so need to check if it is part of the scheme for this channel or not.
|
||||||
|
switch roleName {
|
||||||
|
case schemeAdminRole:
|
||||||
|
member.SchemeAdmin = true
|
||||||
|
case schemeUserRole:
|
||||||
|
member.SchemeUser = true
|
||||||
|
default:
|
||||||
|
// If not part of the scheme for this channel, then it is not allowed to apply it as an explicit role.
|
||||||
|
return nil, model.NewAppError("UpdateTeamMemberRoles", "api.channel.update_team_member_roles.scheme_role.app_error", nil, "role_name="+roleName, http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
member.ExplicitRoles = strings.Join(newExplicitRoles, " ")
|
||||||
|
|
||||||
if result := <-a.Srv.Store.Team().UpdateMember(member); result.Err != nil {
|
if result := <-a.Srv.Store.Team().UpdateMember(member); result.Err != nil {
|
||||||
return nil, result.Err
|
return nil, result.Err
|
||||||
|
} else {
|
||||||
|
member = result.Data.(*model.TeamMember)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.ClearSessionCacheForUser(userId)
|
a.ClearSessionCacheForUser(userId)
|
||||||
@@ -292,13 +334,13 @@ func (a *App) AddUserToTeamByInviteId(inviteId string, userId string) (*model.Te
|
|||||||
// 3. a pointer to an AppError if something went wrong.
|
// 3. a pointer to an AppError if something went wrong.
|
||||||
func (a *App) joinUserToTeam(team *model.Team, user *model.User) (*model.TeamMember, bool, *model.AppError) {
|
func (a *App) joinUserToTeam(team *model.Team, user *model.User) (*model.TeamMember, bool, *model.AppError) {
|
||||||
tm := &model.TeamMember{
|
tm := &model.TeamMember{
|
||||||
TeamId: team.Id,
|
TeamId: team.Id,
|
||||||
UserId: user.Id,
|
UserId: user.Id,
|
||||||
Roles: model.TEAM_USER_ROLE_ID,
|
SchemeUser: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if team.Email == user.Email {
|
if team.Email == user.Email {
|
||||||
tm.Roles = model.TEAM_USER_ROLE_ID + " " + model.TEAM_ADMIN_ROLE_ID
|
tm.SchemeAdmin = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if etmr := <-a.Srv.Store.Team().GetMember(team.Id, user.Id); etmr.Err == nil {
|
if etmr := <-a.Srv.Store.Team().GetMember(team.Id, user.Id); etmr.Err == nil {
|
||||||
@@ -342,14 +384,10 @@ func (a *App) JoinUserToTeam(team *model.Team, user *model.User, userRequestorId
|
|||||||
return uua.Err
|
return uua.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
channelRole := model.CHANNEL_USER_ROLE_ID
|
shouldBeAdmin := team.Email == user.Email
|
||||||
|
|
||||||
if team.Email == user.Email {
|
|
||||||
channelRole = model.CHANNEL_USER_ROLE_ID + " " + model.CHANNEL_ADMIN_ROLE_ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Soft error if there is an issue joining the default channels
|
// Soft error if there is an issue joining the default channels
|
||||||
if err := a.JoinDefaultChannels(team.Id, user, channelRole, userRequestorId); err != nil {
|
if err := a.JoinDefaultChannels(team.Id, user, shouldBeAdmin, userRequestorId); err != nil {
|
||||||
l4g.Error(utils.T("api.user.create_user.joining.error"), user.Id, team.Id, err)
|
l4g.Error(utils.T("api.user.create_user.joining.error"), user.Id, team.Id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
80
i18n/en.json
80
i18n/en.json
@@ -6690,6 +6690,86 @@
|
|||||||
"id": "store.sql_role.get_by_name.app_error",
|
"id": "store.sql_role.get_by_name.app_error",
|
||||||
"translation": "Unable to get role"
|
"translation": "Unable to get role"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.channel.update_channel_member_roles.scheme_role.app_error",
|
||||||
|
"translation": "The provided role is managed by a Scheme and therefore cannot be applied directly to a Channel Member"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.channel.update_team_member_roles.scheme_role.app_error",
|
||||||
|
"translation": "The provided role is managed by a Scheme and therefore cannot be applied directly to a Team Member"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_channel.get_by_scheme.app_error",
|
||||||
|
"translation": "Unable to get the channels for the provided scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_team.get_by_scheme.app_error",
|
||||||
|
"translation": "Unable to get the channels for the provided scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_role.save.open_transaction.app_error",
|
||||||
|
"translation": "Failed to open the transaction to save the role"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_role.save_role.commit_transaction.app_error",
|
||||||
|
"translation": "Failed to commit the transaction to save the role"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_role.save.invalid_role.app_error",
|
||||||
|
"translation": "The provided role is invalid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_role.delete.update.app_error",
|
||||||
|
"translation": "Unable to delete the role"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.save.open_transaction.app_error",
|
||||||
|
"translation": "Failed to open the transaction to save the scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.save_scheme.commit_transaction.app_error",
|
||||||
|
"translation": "Failed to commit the transaction to save the scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.save.invalid_scheme.app_error",
|
||||||
|
"translation": "The provided scheme is invalid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.save.update.app_error",
|
||||||
|
"translation": "Unable to update the scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.save.retrieve_default_scheme_roles.app_error",
|
||||||
|
"translation": "Unable to retrieve the default scheme roles"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.save.insert.app_error",
|
||||||
|
"translation": "Unable to create the scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.get.app_error",
|
||||||
|
"translation": "Unable to get the scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.team_count.app_error",
|
||||||
|
"translation": "Unable to count the number of teams using this scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.delete.scheme_in_use.app_error",
|
||||||
|
"translation": "Unable to delete the scheme as it in use by 1 or more teams or channels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.channel_count.app_error",
|
||||||
|
"translation": "Unable to count the number of channels using this scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.delete.role_update.app_error",
|
||||||
|
"translation": "Unable to delete the roles belonging to this scheme"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store.sql_scheme.delete.update.app_error",
|
||||||
|
"translation": "Unable to delete the scheme"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "store.sql_role.get_by_names.app_error",
|
"id": "store.sql_role.get_by_names.app_error",
|
||||||
"translation": "Unable to get roles"
|
"translation": "Unable to get roles"
|
||||||
|
|||||||
@@ -32,20 +32,21 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
CreateAt int64 `json:"create_at"`
|
CreateAt int64 `json:"create_at"`
|
||||||
UpdateAt int64 `json:"update_at"`
|
UpdateAt int64 `json:"update_at"`
|
||||||
DeleteAt int64 `json:"delete_at"`
|
DeleteAt int64 `json:"delete_at"`
|
||||||
TeamId string `json:"team_id"`
|
TeamId string `json:"team_id"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Header string `json:"header"`
|
Header string `json:"header"`
|
||||||
Purpose string `json:"purpose"`
|
Purpose string `json:"purpose"`
|
||||||
LastPostAt int64 `json:"last_post_at"`
|
LastPostAt int64 `json:"last_post_at"`
|
||||||
TotalMsgCount int64 `json:"total_msg_count"`
|
TotalMsgCount int64 `json:"total_msg_count"`
|
||||||
ExtraUpdateAt int64 `json:"extra_update_at"`
|
ExtraUpdateAt int64 `json:"extra_update_at"`
|
||||||
CreatorId string `json:"creator_id"`
|
CreatorId string `json:"creator_id"`
|
||||||
|
SchemeId *string `json:"scheme_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChannelPatch struct {
|
type ChannelPatch struct {
|
||||||
|
|||||||
@@ -28,14 +28,17 @@ type ChannelUnread struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ChannelMember struct {
|
type ChannelMember struct {
|
||||||
ChannelId string `json:"channel_id"`
|
ChannelId string `json:"channel_id"`
|
||||||
UserId string `json:"user_id"`
|
UserId string `json:"user_id"`
|
||||||
Roles string `json:"roles"`
|
Roles string `json:"roles"`
|
||||||
LastViewedAt int64 `json:"last_viewed_at"`
|
LastViewedAt int64 `json:"last_viewed_at"`
|
||||||
MsgCount int64 `json:"msg_count"`
|
MsgCount int64 `json:"msg_count"`
|
||||||
MentionCount int64 `json:"mention_count"`
|
MentionCount int64 `json:"mention_count"`
|
||||||
NotifyProps StringMap `json:"notify_props"`
|
NotifyProps StringMap `json:"notify_props"`
|
||||||
LastUpdateAt int64 `json:"last_update_at"`
|
LastUpdateAt int64 `json:"last_update_at"`
|
||||||
|
SchemeUser bool `json:"scheme_user"`
|
||||||
|
SchemeAdmin bool `json:"scheme_admin"`
|
||||||
|
ExplicitRoles string `json:"explicit_roles"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChannelMembers []ChannelMember
|
type ChannelMembers []ChannelMember
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const (
|
|||||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER = "inv_user"
|
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER = "inv_user"
|
||||||
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER = "clear_session_user"
|
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER = "clear_session_user"
|
||||||
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES = "inv_roles"
|
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES = "inv_roles"
|
||||||
|
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES = "inv_schemes"
|
||||||
|
|
||||||
CLUSTER_SEND_BEST_EFFORT = "best_effort"
|
CLUSTER_SEND_BEST_EFFORT = "best_effort"
|
||||||
CLUSTER_SEND_RELIABLE = "reliable"
|
CLUSTER_SEND_RELIABLE = "reliable"
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ type Role struct {
|
|||||||
DeleteAt int64 `json:"delete_at"`
|
DeleteAt int64 `json:"delete_at"`
|
||||||
Permissions []string `json:"permissions"`
|
Permissions []string `json:"permissions"`
|
||||||
SchemeManaged bool `json:"scheme_managed"`
|
SchemeManaged bool `json:"scheme_managed"`
|
||||||
|
BuiltIn bool `json:"built_in"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RolePatch struct {
|
type RolePatch struct {
|
||||||
@@ -187,6 +188,7 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
PERMISSION_USE_SLASH_COMMANDS.Id,
|
PERMISSION_USE_SLASH_COMMANDS.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: true,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[CHANNEL_ADMIN_ROLE_ID] = &Role{
|
roles[CHANNEL_ADMIN_ROLE_ID] = &Role{
|
||||||
@@ -197,6 +199,7 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
PERMISSION_MANAGE_CHANNEL_ROLES.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: true,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[TEAM_USER_ROLE_ID] = &Role{
|
roles[TEAM_USER_ROLE_ID] = &Role{
|
||||||
@@ -210,6 +213,7 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
PERMISSION_VIEW_TEAM.Id,
|
PERMISSION_VIEW_TEAM.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: true,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[TEAM_POST_ALL_ROLE_ID] = &Role{
|
roles[TEAM_POST_ALL_ROLE_ID] = &Role{
|
||||||
@@ -219,7 +223,8 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
Permissions: []string{
|
Permissions: []string{
|
||||||
PERMISSION_CREATE_POST.Id,
|
PERMISSION_CREATE_POST.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: false,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[TEAM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
|
roles[TEAM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
|
||||||
@@ -229,7 +234,8 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
Permissions: []string{
|
Permissions: []string{
|
||||||
PERMISSION_CREATE_POST_PUBLIC.Id,
|
PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: false,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[TEAM_ADMIN_ROLE_ID] = &Role{
|
roles[TEAM_ADMIN_ROLE_ID] = &Role{
|
||||||
@@ -249,6 +255,7 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
PERMISSION_MANAGE_WEBHOOKS.Id,
|
PERMISSION_MANAGE_WEBHOOKS.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: true,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[SYSTEM_USER_ROLE_ID] = &Role{
|
roles[SYSTEM_USER_ROLE_ID] = &Role{
|
||||||
@@ -261,6 +268,7 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
PERMISSION_PERMANENT_DELETE_USER.Id,
|
PERMISSION_PERMANENT_DELETE_USER.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: true,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[SYSTEM_POST_ALL_ROLE_ID] = &Role{
|
roles[SYSTEM_POST_ALL_ROLE_ID] = &Role{
|
||||||
@@ -270,7 +278,8 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
Permissions: []string{
|
Permissions: []string{
|
||||||
PERMISSION_CREATE_POST.Id,
|
PERMISSION_CREATE_POST.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: false,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[SYSTEM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
|
roles[SYSTEM_POST_ALL_PUBLIC_ROLE_ID] = &Role{
|
||||||
@@ -280,7 +289,8 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
Permissions: []string{
|
Permissions: []string{
|
||||||
PERMISSION_CREATE_POST_PUBLIC.Id,
|
PERMISSION_CREATE_POST_PUBLIC.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: false,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[SYSTEM_USER_ACCESS_TOKEN_ROLE_ID] = &Role{
|
roles[SYSTEM_USER_ACCESS_TOKEN_ROLE_ID] = &Role{
|
||||||
@@ -292,7 +302,8 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
PERMISSION_READ_USER_ACCESS_TOKEN.Id,
|
||||||
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id,
|
||||||
},
|
},
|
||||||
SchemeManaged: true,
|
SchemeManaged: false,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
roles[SYSTEM_ADMIN_ROLE_ID] = &Role{
|
roles[SYSTEM_ADMIN_ROLE_ID] = &Role{
|
||||||
@@ -345,6 +356,7 @@ func MakeDefaultRoles() map[string]*Role {
|
|||||||
roles[CHANNEL_ADMIN_ROLE_ID].Permissions...,
|
roles[CHANNEL_ADMIN_ROLE_ID].Permissions...,
|
||||||
),
|
),
|
||||||
SchemeManaged: true,
|
SchemeManaged: true,
|
||||||
|
BuiltIn: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
return roles
|
return roles
|
||||||
|
|||||||
95
model/scheme.go
Normal file
95
model/scheme.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SCHEME_NAME_MAX_LENGTH = 64
|
||||||
|
SCHEME_DESCRIPTION_MAX_LENGTH = 1024
|
||||||
|
SCHEME_SCOPE_TEAM = "team"
|
||||||
|
SCHEME_SCOPE_CHANNEL = "channel"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Scheme struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
CreateAt int64 `json:"create_at"`
|
||||||
|
UpdateAt int64 `json:"update_at"`
|
||||||
|
DeleteAt int64 `json:"delete_at"`
|
||||||
|
Scope string `json:"scope"`
|
||||||
|
DefaultTeamAdminRole string `json:"default_team_admin_role"`
|
||||||
|
DefaultTeamUserRole string `json:"default_team_user_role"`
|
||||||
|
DefaultChannelAdminRole string `json:"default_channel_admin_role"`
|
||||||
|
DefaultChannelUserRole string `json:"default_channel_user_role"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scheme *Scheme) ToJson() string {
|
||||||
|
b, _ := json.Marshal(scheme)
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SchemeFromJson(data io.Reader) *Scheme {
|
||||||
|
var scheme *Scheme
|
||||||
|
json.NewDecoder(data).Decode(&scheme)
|
||||||
|
return scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scheme *Scheme) IsValid() bool {
|
||||||
|
if len(scheme.Id) != 26 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return scheme.IsValidForCreate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scheme *Scheme) IsValidForCreate() bool {
|
||||||
|
if len(scheme.Name) == 0 || len(scheme.Name) > SCHEME_NAME_MAX_LENGTH {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(scheme.Description) > SCHEME_DESCRIPTION_MAX_LENGTH {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch scheme.Scope {
|
||||||
|
case SCHEME_SCOPE_TEAM, SCHEME_SCOPE_CHANNEL:
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsValidRoleName(scheme.DefaultChannelAdminRole) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsValidRoleName(scheme.DefaultChannelUserRole) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if scheme.Scope == SCHEME_SCOPE_TEAM {
|
||||||
|
if !IsValidRoleName(scheme.DefaultTeamAdminRole) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsValidRoleName(scheme.DefaultTeamUserRole) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if scheme.Scope == SCHEME_SCOPE_CHANNEL {
|
||||||
|
if len(scheme.DefaultTeamAdminRole) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(scheme.DefaultTeamUserRole) != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -26,20 +26,21 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Team struct {
|
type Team struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
CreateAt int64 `json:"create_at"`
|
CreateAt int64 `json:"create_at"`
|
||||||
UpdateAt int64 `json:"update_at"`
|
UpdateAt int64 `json:"update_at"`
|
||||||
DeleteAt int64 `json:"delete_at"`
|
DeleteAt int64 `json:"delete_at"`
|
||||||
DisplayName string `json:"display_name"`
|
DisplayName string `json:"display_name"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
CompanyName string `json:"company_name"`
|
CompanyName string `json:"company_name"`
|
||||||
AllowedDomains string `json:"allowed_domains"`
|
AllowedDomains string `json:"allowed_domains"`
|
||||||
InviteId string `json:"invite_id"`
|
InviteId string `json:"invite_id"`
|
||||||
AllowOpenInvite bool `json:"allow_open_invite"`
|
AllowOpenInvite bool `json:"allow_open_invite"`
|
||||||
LastTeamIconUpdate int64 `json:"last_team_icon_update,omitempty"`
|
LastTeamIconUpdate int64 `json:"last_team_icon_update,omitempty"`
|
||||||
|
SchemeId *string `json:"scheme_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TeamPatch struct {
|
type TeamPatch struct {
|
||||||
|
|||||||
@@ -11,10 +11,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TeamMember struct {
|
type TeamMember struct {
|
||||||
TeamId string `json:"team_id"`
|
TeamId string `json:"team_id"`
|
||||||
UserId string `json:"user_id"`
|
UserId string `json:"user_id"`
|
||||||
Roles string `json:"roles"`
|
Roles string `json:"roles"`
|
||||||
DeleteAt int64 `json:"delete_at"`
|
DeleteAt int64 `json:"delete_at"`
|
||||||
|
SchemeUser bool `json:"scheme_user"`
|
||||||
|
SchemeAdmin bool `json:"scheme_admin"`
|
||||||
|
ExplicitRoles string `json:"explicit_roles"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TeamUnread struct {
|
type TeamUnread struct {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type LayeredStore struct {
|
|||||||
TmpContext context.Context
|
TmpContext context.Context
|
||||||
ReactionStore ReactionStore
|
ReactionStore ReactionStore
|
||||||
RoleStore RoleStore
|
RoleStore RoleStore
|
||||||
|
SchemeStore SchemeStore
|
||||||
DatabaseLayer LayeredStoreDatabaseLayer
|
DatabaseLayer LayeredStoreDatabaseLayer
|
||||||
LocalCacheLayer *LocalCacheSupplier
|
LocalCacheLayer *LocalCacheSupplier
|
||||||
RedisLayer *RedisSupplier
|
RedisLayer *RedisSupplier
|
||||||
@@ -39,6 +40,7 @@ func NewLayeredStore(db LayeredStoreDatabaseLayer, metrics einterfaces.MetricsIn
|
|||||||
|
|
||||||
store.ReactionStore = &LayeredReactionStore{store}
|
store.ReactionStore = &LayeredReactionStore{store}
|
||||||
store.RoleStore = &LayeredRoleStore{store}
|
store.RoleStore = &LayeredRoleStore{store}
|
||||||
|
store.SchemeStore = &LayeredSchemeStore{store}
|
||||||
|
|
||||||
// Setup the chain
|
// Setup the chain
|
||||||
if ENABLE_EXPERIMENTAL_REDIS {
|
if ENABLE_EXPERIMENTAL_REDIS {
|
||||||
@@ -167,6 +169,10 @@ func (s *LayeredStore) Role() RoleStore {
|
|||||||
return s.RoleStore
|
return s.RoleStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *LayeredStore) Scheme() SchemeStore {
|
||||||
|
return s.SchemeStore
|
||||||
|
}
|
||||||
|
|
||||||
func (s *LayeredStore) MarkSystemRanUnitTests() {
|
func (s *LayeredStore) MarkSystemRanUnitTests() {
|
||||||
s.DatabaseLayer.MarkSystemRanUnitTests()
|
s.DatabaseLayer.MarkSystemRanUnitTests()
|
||||||
}
|
}
|
||||||
@@ -253,8 +259,36 @@ func (s *LayeredRoleStore) GetByNames(names []string) StoreChannel {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *LayeredRoleStore) Delete(roldId string) StoreChannel {
|
||||||
|
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
|
||||||
|
return supplier.RoleDelete(s.TmpContext, roldId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (s *LayeredRoleStore) PermanentDeleteAll() StoreChannel {
|
func (s *LayeredRoleStore) PermanentDeleteAll() StoreChannel {
|
||||||
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
|
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
|
||||||
return supplier.RolePermanentDeleteAll(s.TmpContext)
|
return supplier.RolePermanentDeleteAll(s.TmpContext)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LayeredSchemeStore struct {
|
||||||
|
*LayeredStore
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LayeredSchemeStore) Save(scheme *model.Scheme) StoreChannel {
|
||||||
|
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
|
||||||
|
return supplier.SchemeSave(s.TmpContext, scheme)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LayeredSchemeStore) Get(schemeId string) StoreChannel {
|
||||||
|
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
|
||||||
|
return supplier.SchemeGet(s.TmpContext, schemeId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LayeredSchemeStore) Delete(schemeId string) StoreChannel {
|
||||||
|
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
|
||||||
|
return supplier.SchemeDelete(s.TmpContext, schemeId)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,5 +35,11 @@ type LayeredStoreSupplier interface {
|
|||||||
RoleGet(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
RoleGet(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
RoleGetByName(ctx context.Context, name string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
RoleGetByName(ctx context.Context, name string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
RoleGetByNames(ctx context.Context, names []string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
RoleGetByNames(ctx context.Context, names []string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
|
RoleDelete(ctx context.Context, roldId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
|
|
||||||
|
// Schemes
|
||||||
|
SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
|
SchemeGet(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
|
SchemeDelete(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ const (
|
|||||||
ROLE_CACHE_SIZE = 20000
|
ROLE_CACHE_SIZE = 20000
|
||||||
ROLE_CACHE_SEC = 30 * 60
|
ROLE_CACHE_SEC = 30 * 60
|
||||||
|
|
||||||
|
SCHEME_CACHE_SIZE = 20000
|
||||||
|
SCHEME_CACHE_SEC = 30 * 60
|
||||||
|
|
||||||
CLEAR_CACHE_MESSAGE_DATA = ""
|
CLEAR_CACHE_MESSAGE_DATA = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -25,6 +28,7 @@ type LocalCacheSupplier struct {
|
|||||||
next LayeredStoreSupplier
|
next LayeredStoreSupplier
|
||||||
reactionCache *utils.Cache
|
reactionCache *utils.Cache
|
||||||
roleCache *utils.Cache
|
roleCache *utils.Cache
|
||||||
|
schemeCache *utils.Cache
|
||||||
metrics einterfaces.MetricsInterface
|
metrics einterfaces.MetricsInterface
|
||||||
cluster einterfaces.ClusterInterface
|
cluster einterfaces.ClusterInterface
|
||||||
}
|
}
|
||||||
@@ -33,6 +37,7 @@ func NewLocalCacheSupplier(metrics einterfaces.MetricsInterface, cluster einterf
|
|||||||
supplier := &LocalCacheSupplier{
|
supplier := &LocalCacheSupplier{
|
||||||
reactionCache: utils.NewLruWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS),
|
reactionCache: utils.NewLruWithParams(REACTION_CACHE_SIZE, "Reaction", REACTION_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS),
|
||||||
roleCache: utils.NewLruWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES),
|
roleCache: utils.NewLruWithParams(ROLE_CACHE_SIZE, "Role", ROLE_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES),
|
||||||
|
schemeCache: utils.NewLruWithParams(SCHEME_CACHE_SIZE, "Scheme", SCHEME_CACHE_SEC, model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_SCHEMES),
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
cluster: cluster,
|
cluster: cluster,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,17 @@ func (s *LocalCacheSupplier) RoleGetByNames(ctx context.Context, roleNames []str
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *LocalCacheSupplier) RoleDelete(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
result := s.Next().RoleDelete(ctx, roleId, hints...)
|
||||||
|
|
||||||
|
if result.Err == nil {
|
||||||
|
role := result.Data.(*model.Role)
|
||||||
|
s.doInvalidateCacheCluster(s.roleCache, role.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (s *LocalCacheSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
func (s *LocalCacheSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
defer s.roleCache.Purge()
|
defer s.roleCache.Purge()
|
||||||
defer s.doClearCacheCluster(s.roleCache)
|
defer s.doClearCacheCluster(s.roleCache)
|
||||||
|
|||||||
44
store/local_cache_supplier_schemes.go
Normal file
44
store/local_cache_supplier_schemes.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *LocalCacheSupplier) handleClusterInvalidateScheme(msg *model.ClusterMessage) {
|
||||||
|
if msg.Data == CLEAR_CACHE_MESSAGE_DATA {
|
||||||
|
s.schemeCache.Purge()
|
||||||
|
} else {
|
||||||
|
s.schemeCache.Remove(msg.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LocalCacheSupplier) SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
if len(scheme.Id) != 0 {
|
||||||
|
defer s.doInvalidateCacheCluster(s.schemeCache, scheme.Id)
|
||||||
|
}
|
||||||
|
return s.Next().SchemeSave(ctx, scheme, hints...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LocalCacheSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
if result := s.doStandardReadCache(ctx, s.schemeCache, schemeId, hints...); result != nil {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
result := s.Next().SchemeGet(ctx, schemeId, hints...)
|
||||||
|
|
||||||
|
s.doStandardAddToCache(ctx, s.schemeCache, schemeId, result, hints...)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *LocalCacheSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
defer s.doInvalidateCacheCluster(s.schemeCache, schemeId)
|
||||||
|
defer s.doClearCacheCluster(s.roleCache)
|
||||||
|
|
||||||
|
return s.Next().SchemeDelete(ctx, schemeId, hints...)
|
||||||
|
}
|
||||||
@@ -84,6 +84,21 @@ func (s *RedisSupplier) RoleGetByNames(ctx context.Context, roleNames []string,
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *RedisSupplier) RoleDelete(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
result := s.Next().RoleGet(ctx, roleId, hints...)
|
||||||
|
|
||||||
|
if result.Err == nil {
|
||||||
|
role := result.Data.(*model.Role)
|
||||||
|
key := buildRedisKeyForRoleName(role.Name)
|
||||||
|
|
||||||
|
if err := s.client.Del(key).Err(); err != nil {
|
||||||
|
l4g.Error("Redis failed to remove key " + key + " Error: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (s *RedisSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
func (s *RedisSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
defer func() {
|
defer func() {
|
||||||
if keys, err := s.client.Keys("roles:*").Result(); err != nil {
|
if keys, err := s.client.Keys("roles:*").Result(); err != nil {
|
||||||
|
|||||||
25
store/redis_supplier_schemes.go
Normal file
25
store/redis_supplier_schemes.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *RedisSupplier) SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
// TODO: Redis caching.
|
||||||
|
return s.Next().SchemeSave(ctx, scheme, hints...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RedisSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
// TODO: Redis caching.
|
||||||
|
return s.Next().SchemeGet(ctx, schemeId, hints...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RedisSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||||
|
// TODO: Redis caching.
|
||||||
|
return s.Next().SchemeDelete(ctx, schemeId, hints...)
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
l4g "github.com/alecthomas/log4go"
|
l4g "github.com/alecthomas/log4go"
|
||||||
"github.com/mattermost/gorp"
|
"github.com/mattermost/gorp"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/einterfaces"
|
"github.com/mattermost/mattermost-server/einterfaces"
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/mattermost/mattermost-server/store"
|
"github.com/mattermost/mattermost-server/store"
|
||||||
@@ -37,6 +38,200 @@ type SqlChannelStore struct {
|
|||||||
metrics einterfaces.MetricsInterface
|
metrics einterfaces.MetricsInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type channelMember struct {
|
||||||
|
ChannelId string
|
||||||
|
UserId string
|
||||||
|
Roles string
|
||||||
|
LastViewedAt int64
|
||||||
|
MsgCount int64
|
||||||
|
MentionCount int64
|
||||||
|
NotifyProps model.StringMap
|
||||||
|
LastUpdateAt int64
|
||||||
|
SchemeUser sql.NullBool
|
||||||
|
SchemeAdmin sql.NullBool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewChannelMemberFromModel(cm *model.ChannelMember) *channelMember {
|
||||||
|
return &channelMember{
|
||||||
|
ChannelId: cm.ChannelId,
|
||||||
|
UserId: cm.UserId,
|
||||||
|
Roles: cm.ExplicitRoles,
|
||||||
|
LastViewedAt: cm.LastViewedAt,
|
||||||
|
MsgCount: cm.MsgCount,
|
||||||
|
MentionCount: cm.MentionCount,
|
||||||
|
NotifyProps: cm.NotifyProps,
|
||||||
|
LastUpdateAt: cm.LastUpdateAt,
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: cm.SchemeUser},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: cm.SchemeAdmin},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type channelMemberWithSchemeRoles struct {
|
||||||
|
ChannelId string
|
||||||
|
UserId string
|
||||||
|
Roles string
|
||||||
|
LastViewedAt int64
|
||||||
|
MsgCount int64
|
||||||
|
MentionCount int64
|
||||||
|
NotifyProps model.StringMap
|
||||||
|
LastUpdateAt int64
|
||||||
|
SchemeUser sql.NullBool
|
||||||
|
SchemeAdmin sql.NullBool
|
||||||
|
TeamSchemeDefaultUserRole sql.NullString
|
||||||
|
TeamSchemeDefaultAdminRole sql.NullString
|
||||||
|
ChannelSchemeDefaultUserRole sql.NullString
|
||||||
|
ChannelSchemeDefaultAdminRole sql.NullString
|
||||||
|
}
|
||||||
|
|
||||||
|
type channelMemberWithSchemeRolesList []channelMemberWithSchemeRoles
|
||||||
|
|
||||||
|
func (db channelMemberWithSchemeRoles) ToModel() *model.ChannelMember {
|
||||||
|
var roles []string
|
||||||
|
var explicitRoles []string
|
||||||
|
|
||||||
|
// Identify any system-wide scheme derived roles that are in "Roles" field due to not yet being migrated,
|
||||||
|
// and exclude them from ExplicitRoles field.
|
||||||
|
schemeUser := db.SchemeUser.Valid && db.SchemeUser.Bool
|
||||||
|
schemeAdmin := db.SchemeAdmin.Valid && db.SchemeAdmin.Bool
|
||||||
|
for _, role := range strings.Fields(db.Roles) {
|
||||||
|
isImplicit := false
|
||||||
|
if role == model.CHANNEL_USER_ROLE_ID {
|
||||||
|
// We have an implicit role via the system scheme. Override the "schemeUser" field to true.
|
||||||
|
schemeUser = true
|
||||||
|
isImplicit = true
|
||||||
|
} else if role == model.CHANNEL_ADMIN_ROLE_ID {
|
||||||
|
// We have an implicit role via the system scheme.
|
||||||
|
schemeAdmin = true
|
||||||
|
isImplicit = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isImplicit {
|
||||||
|
explicitRoles = append(explicitRoles, role)
|
||||||
|
}
|
||||||
|
roles = append(roles, role)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any scheme derived roles that are not in the Roles field due to being Implicit from the Scheme, and add
|
||||||
|
// them to the Roles field for backwards compatibility reasons.
|
||||||
|
var schemeImpliedRoles []string
|
||||||
|
if db.SchemeUser.Valid && db.SchemeUser.Bool {
|
||||||
|
if db.ChannelSchemeDefaultUserRole.Valid && db.ChannelSchemeDefaultUserRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.ChannelSchemeDefaultUserRole.String)
|
||||||
|
} else if db.TeamSchemeDefaultUserRole.Valid && db.TeamSchemeDefaultUserRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultUserRole.String)
|
||||||
|
} else {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, model.CHANNEL_USER_ROLE_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if db.SchemeAdmin.Valid && db.SchemeAdmin.Bool {
|
||||||
|
if db.ChannelSchemeDefaultAdminRole.Valid && db.ChannelSchemeDefaultAdminRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.ChannelSchemeDefaultAdminRole.String)
|
||||||
|
} else if db.TeamSchemeDefaultAdminRole.Valid && db.TeamSchemeDefaultAdminRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultAdminRole.String)
|
||||||
|
} else {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, model.CHANNEL_ADMIN_ROLE_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, impliedRole := range schemeImpliedRoles {
|
||||||
|
alreadyThere := false
|
||||||
|
for _, role := range roles {
|
||||||
|
if role == impliedRole {
|
||||||
|
alreadyThere = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !alreadyThere {
|
||||||
|
roles = append(roles, impliedRole)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &model.ChannelMember{
|
||||||
|
ChannelId: db.ChannelId,
|
||||||
|
UserId: db.UserId,
|
||||||
|
Roles: strings.Join(roles, " "),
|
||||||
|
LastViewedAt: db.LastViewedAt,
|
||||||
|
MsgCount: db.MsgCount,
|
||||||
|
MentionCount: db.MentionCount,
|
||||||
|
NotifyProps: db.NotifyProps,
|
||||||
|
LastUpdateAt: db.LastUpdateAt,
|
||||||
|
SchemeAdmin: schemeAdmin,
|
||||||
|
SchemeUser: schemeUser,
|
||||||
|
ExplicitRoles: strings.Join(explicitRoles, " "),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db channelMemberWithSchemeRolesList) ToModel() *model.ChannelMembers {
|
||||||
|
cms := model.ChannelMembers{}
|
||||||
|
|
||||||
|
for _, cm := range db {
|
||||||
|
cms = append(cms, *cm.ToModel())
|
||||||
|
}
|
||||||
|
|
||||||
|
return &cms
|
||||||
|
}
|
||||||
|
|
||||||
|
type allChannelMember struct {
|
||||||
|
ChannelId string
|
||||||
|
Roles string
|
||||||
|
SchemeUser sql.NullBool
|
||||||
|
SchemeAdmin sql.NullBool
|
||||||
|
TeamSchemeDefaultUserRole sql.NullString
|
||||||
|
TeamSchemeDefaultAdminRole sql.NullString
|
||||||
|
ChannelSchemeDefaultUserRole sql.NullString
|
||||||
|
ChannelSchemeDefaultAdminRole sql.NullString
|
||||||
|
}
|
||||||
|
|
||||||
|
type allChannelMembers []allChannelMember
|
||||||
|
|
||||||
|
func (db allChannelMember) Process() (string, string) {
|
||||||
|
roles := strings.Fields(db.Roles)
|
||||||
|
|
||||||
|
// Add any scheme derived roles that are not in the Roles field due to being Implicit from the Scheme, and add
|
||||||
|
// them to the Roles field for backwards compatibility reasons.
|
||||||
|
var schemeImpliedRoles []string
|
||||||
|
if db.SchemeUser.Valid && db.SchemeUser.Bool {
|
||||||
|
if db.ChannelSchemeDefaultUserRole.Valid && db.ChannelSchemeDefaultUserRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.ChannelSchemeDefaultUserRole.String)
|
||||||
|
} else if db.TeamSchemeDefaultUserRole.Valid && db.TeamSchemeDefaultUserRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultUserRole.String)
|
||||||
|
} else {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, model.CHANNEL_USER_ROLE_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if db.SchemeAdmin.Valid && db.SchemeAdmin.Bool {
|
||||||
|
if db.ChannelSchemeDefaultAdminRole.Valid && db.ChannelSchemeDefaultAdminRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.ChannelSchemeDefaultAdminRole.String)
|
||||||
|
} else if db.TeamSchemeDefaultAdminRole.Valid && db.TeamSchemeDefaultAdminRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultAdminRole.String)
|
||||||
|
} else {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, model.CHANNEL_ADMIN_ROLE_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, impliedRole := range schemeImpliedRoles {
|
||||||
|
alreadyThere := false
|
||||||
|
for _, role := range roles {
|
||||||
|
if role == impliedRole {
|
||||||
|
alreadyThere = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !alreadyThere {
|
||||||
|
roles = append(roles, impliedRole)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.ChannelId, strings.Join(roles, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db allChannelMembers) ToMapStringString() map[string]string {
|
||||||
|
result := make(map[string]string)
|
||||||
|
|
||||||
|
for _, item := range db {
|
||||||
|
key, value := item.Process()
|
||||||
|
result[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
var channelMemberCountsCache = utils.NewLru(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE)
|
var channelMemberCountsCache = utils.NewLru(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE)
|
||||||
var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE)
|
var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE)
|
||||||
var allChannelMembersNotifyPropsForChannelCache = utils.NewLru(ALL_CHANNEL_MEMBERS_NOTIFY_PROPS_FOR_CHANNEL_CACHE_SIZE)
|
var allChannelMembersNotifyPropsForChannelCache = utils.NewLru(ALL_CHANNEL_MEMBERS_NOTIFY_PROPS_FOR_CHANNEL_CACHE_SIZE)
|
||||||
@@ -76,8 +271,9 @@ func NewSqlChannelStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface)
|
|||||||
table.ColMap("Header").SetMaxSize(1024)
|
table.ColMap("Header").SetMaxSize(1024)
|
||||||
table.ColMap("Purpose").SetMaxSize(250)
|
table.ColMap("Purpose").SetMaxSize(250)
|
||||||
table.ColMap("CreatorId").SetMaxSize(26)
|
table.ColMap("CreatorId").SetMaxSize(26)
|
||||||
|
table.ColMap("SchemeId").SetMaxSize(26)
|
||||||
|
|
||||||
tablem := db.AddTableWithName(model.ChannelMember{}, "ChannelMembers").SetKeys(false, "ChannelId", "UserId")
|
tablem := db.AddTableWithName(channelMember{}, "ChannelMembers").SetKeys(false, "ChannelId", "UserId")
|
||||||
tablem.ColMap("ChannelId").SetMaxSize(26)
|
tablem.ColMap("ChannelId").SetMaxSize(26)
|
||||||
tablem.ColMap("UserId").SetMaxSize(26)
|
tablem.ColMap("UserId").SetMaxSize(26)
|
||||||
tablem.ColMap("Roles").SetMaxSize(64)
|
tablem.ColMap("Roles").SetMaxSize(64)
|
||||||
@@ -138,12 +334,12 @@ func (s SqlChannelStore) CreateDirectChannel(userId string, otherUserId string)
|
|||||||
cm1 := &model.ChannelMember{
|
cm1 := &model.ChannelMember{
|
||||||
UserId: userId,
|
UserId: userId,
|
||||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||||
Roles: model.CHANNEL_USER_ROLE_ID,
|
SchemeUser: true,
|
||||||
}
|
}
|
||||||
cm2 := &model.ChannelMember{
|
cm2 := &model.ChannelMember{
|
||||||
UserId: otherUserId,
|
UserId: otherUserId,
|
||||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||||
Roles: model.CHANNEL_USER_ROLE_ID,
|
SchemeUser: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.SaveDirectChannel(channel, cm1, cm2)
|
return s.SaveDirectChannel(channel, cm1, cm2)
|
||||||
@@ -732,6 +928,25 @@ func (s SqlChannelStore) GetDeleted(teamId string, offset int, limit int) store.
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY = `
|
||||||
|
SELECT
|
||||||
|
ChannelMembers.*,
|
||||||
|
TeamScheme.DefaultChannelUserRole TeamSchemeDefaultUserRole,
|
||||||
|
TeamScheme.DefaultChannelAdminRole TeamSchemeDefaultAdminRole,
|
||||||
|
ChannelScheme.DefaultChannelUserRole ChannelSchemeDefaultUserRole,
|
||||||
|
ChannelScheme.DefaultChannelAdminRole ChannelSchemeDefaultAdminRole
|
||||||
|
FROM
|
||||||
|
ChannelMembers
|
||||||
|
INNER JOIN
|
||||||
|
Channels ON ChannelMembers.ChannelId = Channels.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Schemes ChannelScheme ON Channels.SchemeId = ChannelScheme.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Teams ON Channels.TeamId = Teams.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
|
||||||
|
`
|
||||||
|
|
||||||
func (s SqlChannelStore) SaveMember(member *model.ChannelMember) store.StoreChannel {
|
func (s SqlChannelStore) SaveMember(member *model.ChannelMember) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
// Grab the channel we are saving this member to
|
// Grab the channel we are saving this member to
|
||||||
@@ -750,7 +965,7 @@ func (s SqlChannelStore) SaveMember(member *model.ChannelMember) store.StoreChan
|
|||||||
if err := transaction.Commit(); err != nil {
|
if err := transaction.Commit(); err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "store.sql_channel.save_member.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "store.sql_channel.save_member.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
// If successfull record members have changed in channel
|
// If successful record members have changed in channel
|
||||||
if mu := <-s.extraUpdated(channel); mu.Err != nil {
|
if mu := <-s.extraUpdated(channel); mu.Err != nil {
|
||||||
result.Err = mu.Err
|
result.Err = mu.Err
|
||||||
}
|
}
|
||||||
@@ -770,14 +985,25 @@ func (s SqlChannelStore) saveMemberT(transaction *gorp.Transaction, member *mode
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := transaction.Insert(member); err != nil {
|
dbMember := NewChannelMemberFromModel(member)
|
||||||
|
|
||||||
|
if err := transaction.Insert(dbMember); err != nil {
|
||||||
if IsUniqueConstraintError(err, []string{"ChannelId", "channelmembers_pkey"}) {
|
if IsUniqueConstraintError(err, []string{"ChannelId", "channelmembers_pkey"}) {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "store.sql_channel.save_member.exists.app_error", nil, "channel_id="+member.ChannelId+", user_id="+member.UserId+", "+err.Error(), http.StatusBadRequest)
|
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "store.sql_channel.save_member.exists.app_error", nil, "channel_id="+member.ChannelId+", user_id="+member.UserId+", "+err.Error(), http.StatusBadRequest)
|
||||||
} else {
|
} else {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "store.sql_channel.save_member.save.app_error", nil, "channel_id="+member.ChannelId+", user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.SaveMember", "store.sql_channel.save_member.save.app_error", nil, "channel_id="+member.ChannelId+", user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.Data = member
|
var retrievedMember channelMemberWithSchemeRoles
|
||||||
|
if err := transaction.SelectOne(&retrievedMember, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelMembers.ChannelId = :ChannelId AND ChannelMembers.UserId = :UserId", map[string]interface{}{"ChannelId": dbMember.ChannelId, "UserId": dbMember.UserId}); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
result.Err = model.NewAppError("SqlChannelStore.GetMember", store.MISSING_CHANNEL_MEMBER_ERROR, nil, "channel_id="+dbMember.ChannelId+"user_id="+dbMember.UserId+","+err.Error(), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
result.Err = model.NewAppError("SqlChannelStore.GetMember", "store.sql_channel.get_member.app_error", nil, "channel_id="+dbMember.ChannelId+"user_id="+dbMember.UserId+","+err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.Data = retrievedMember.ToModel()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -791,38 +1017,48 @@ func (s SqlChannelStore) UpdateMember(member *model.ChannelMember) store.StoreCh
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.GetMaster().Update(member); err != nil {
|
if _, err := s.GetMaster().Update(NewChannelMemberFromModel(member)); err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.UpdateMember", "store.sql_channel.update_member.app_error", nil, "channel_id="+member.ChannelId+", "+"user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.UpdateMember", "store.sql_channel.update_member.app_error", nil, "channel_id="+member.ChannelId+", "+"user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = member
|
var dbMember channelMemberWithSchemeRoles
|
||||||
|
|
||||||
|
if err := s.GetReplica().SelectOne(&dbMember, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelMembers.ChannelId = :ChannelId AND ChannelMembers.UserId = :UserId", map[string]interface{}{"ChannelId": member.ChannelId, "UserId": member.UserId}); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
result.Err = model.NewAppError("SqlChannelStore.GetMember", store.MISSING_CHANNEL_MEMBER_ERROR, nil, "channel_id="+member.ChannelId+"user_id="+member.UserId+","+err.Error(), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
result.Err = model.NewAppError("SqlChannelStore.GetMember", "store.sql_channel.get_member.app_error", nil, "channel_id="+member.ChannelId+"user_id="+member.UserId+","+err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.Data = dbMember.ToModel()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) GetMembers(channelId string, offset, limit int) store.StoreChannel {
|
func (s SqlChannelStore) GetMembers(channelId string, offset, limit int) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var members model.ChannelMembers
|
var dbMembers channelMemberWithSchemeRolesList
|
||||||
_, err := s.GetReplica().Select(&members, "SELECT * FROM ChannelMembers WHERE ChannelId = :ChannelId LIMIT :Limit OFFSET :Offset", map[string]interface{}{"ChannelId": channelId, "Limit": limit, "Offset": offset})
|
_, err := s.GetReplica().Select(&dbMembers, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelId = :ChannelId LIMIT :Limit OFFSET :Offset", map[string]interface{}{"ChannelId": channelId, "Limit": limit, "Offset": offset})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetMembers", "store.sql_channel.get_members.app_error", nil, "channel_id="+channelId+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.GetMembers", "store.sql_channel.get_members.app_error", nil, "channel_id="+channelId+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = &members
|
result.Data = dbMembers.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlChannelStore) GetMember(channelId string, userId string) store.StoreChannel {
|
func (s SqlChannelStore) GetMember(channelId string, userId string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var member model.ChannelMember
|
var dbMember channelMemberWithSchemeRoles
|
||||||
|
|
||||||
if err := s.GetReplica().SelectOne(&member, "SELECT * FROM ChannelMembers WHERE ChannelId = :ChannelId AND UserId = :UserId", map[string]interface{}{"ChannelId": channelId, "UserId": userId}); err != nil {
|
if err := s.GetReplica().SelectOne(&dbMember, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelMembers.ChannelId = :ChannelId AND ChannelMembers.UserId = :UserId", map[string]interface{}{"ChannelId": channelId, "UserId": userId}); err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetMember", store.MISSING_CHANNEL_MEMBER_ERROR, nil, "channel_id="+channelId+"user_id="+userId+","+err.Error(), http.StatusNotFound)
|
result.Err = model.NewAppError("SqlChannelStore.GetMember", store.MISSING_CHANNEL_MEMBER_ERROR, nil, "channel_id="+channelId+"user_id="+userId+","+err.Error(), http.StatusNotFound)
|
||||||
} else {
|
} else {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetMember", "store.sql_channel.get_member.app_error", nil, "channel_id="+channelId+"user_id="+userId+","+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.GetMember", "store.sql_channel.get_member.app_error", nil, "channel_id="+channelId+"user_id="+userId+","+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.Data = &member
|
result.Data = dbMember.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -866,30 +1102,37 @@ func (s SqlChannelStore) IsUserInChannelUseCache(userId string, channelId string
|
|||||||
|
|
||||||
func (s SqlChannelStore) GetMemberForPost(postId string, userId string) store.StoreChannel {
|
func (s SqlChannelStore) GetMemberForPost(postId string, userId string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
member := &model.ChannelMember{}
|
var dbMember channelMemberWithSchemeRoles
|
||||||
if err := s.GetReplica().SelectOne(
|
if err := s.GetReplica().SelectOne(&dbMember,
|
||||||
member,
|
`
|
||||||
`SELECT
|
SELECT
|
||||||
ChannelMembers.*
|
ChannelMembers.*,
|
||||||
FROM
|
TeamScheme.DefaultChannelUserRole TeamSchemeDefaultUserRole,
|
||||||
ChannelMembers,
|
TeamScheme.DefaultChannelAdminRole TeamSchemeDefaultAdminRole,
|
||||||
Posts
|
ChannelScheme.DefaultChannelUserRole ChannelSchemeDefaultUserRole,
|
||||||
|
ChannelScheme.DefaultChannelAdminRole ChannelSchemeDefaultAdminRole
|
||||||
|
FROM
|
||||||
|
ChannelMembers
|
||||||
|
INNER JOIN
|
||||||
|
Posts ON ChannelMembers.ChannelId = Posts.ChannelId
|
||||||
|
INNER JOIN
|
||||||
|
Channels ON ChannelMembers.ChannelId = Channels.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Schemes ChannelScheme ON Channels.SchemeId = ChannelScheme.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Teams ON Channels.TeamId = Teams.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
|
||||||
WHERE
|
WHERE
|
||||||
ChannelMembers.ChannelId = Posts.ChannelId
|
ChannelMembers.UserId = :UserId
|
||||||
AND ChannelMembers.UserId = :UserId
|
|
||||||
AND Posts.Id = :PostId`, map[string]interface{}{"UserId": userId, "PostId": postId}); err != nil {
|
AND Posts.Id = :PostId`, map[string]interface{}{"UserId": userId, "PostId": postId}); err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetMemberForPost", "store.sql_channel.get_member_for_post.app_error", nil, "postId="+postId+", err="+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.GetMemberForPost", "store.sql_channel.get_member_for_post.app_error", nil, "postId="+postId+", err="+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = member
|
result.Data = dbMember.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type allChannelMember struct {
|
|
||||||
ChannelId string
|
|
||||||
Roles string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCache bool) store.StoreChannel {
|
func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCache bool) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
if allowFromCache {
|
if allowFromCache {
|
||||||
@@ -910,17 +1153,32 @@ func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var data []allChannelMember
|
var data allChannelMembers
|
||||||
_, err := s.GetReplica().Select(&data, "SELECT ChannelId, Roles FROM Channels, ChannelMembers WHERE Channels.Id = ChannelMembers.ChannelId AND ChannelMembers.UserId = :UserId AND Channels.DeleteAt = 0", map[string]interface{}{"UserId": userId})
|
_, err := s.GetReplica().Select(&data, `
|
||||||
|
SELECT
|
||||||
|
ChannelMembers.ChannelId, ChannelMembers.Roles, ChannelMembers.SchemeUser, ChannelMembers.SchemeAdmin,
|
||||||
|
TeamScheme.DefaultChannelUserRole TeamSchemeDefaultUserRole,
|
||||||
|
TeamScheme.DefaultChannelAdminRole TeamSchemeDefaultAdminRole,
|
||||||
|
ChannelScheme.DefaultChannelUserRole ChannelSchemeDefaultUserRole,
|
||||||
|
ChannelScheme.DefaultChannelAdminRole ChannelSchemeDefaultAdminRole
|
||||||
|
FROM
|
||||||
|
ChannelMembers
|
||||||
|
INNER JOIN
|
||||||
|
Channels ON ChannelMembers.ChannelId = Channels.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Schemes ChannelScheme ON Channels.SchemeId = ChannelScheme.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Teams ON Channels.TeamId = Teams.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
|
||||||
|
WHERE
|
||||||
|
Channels.DeleteAt = 0
|
||||||
|
AND ChannelMembers.UserId = :UserId`, map[string]interface{}{"UserId": userId})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetAllChannelMembersForUser", "store.sql_channel.get_channels.get.app_error", nil, "userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.GetAllChannelMembersForUser", "store.sql_channel.get_channels.get.app_error", nil, "userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
|
ids := data.ToMapStringString()
|
||||||
ids := make(map[string]string)
|
|
||||||
for i := range data {
|
|
||||||
ids[data[i].ChannelId] = data[i].Roles
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Data = ids
|
result.Data = ids
|
||||||
|
|
||||||
@@ -1249,21 +1507,13 @@ func (s SqlChannelStore) AnalyticsDeletedTypeCount(teamId string, channelType st
|
|||||||
|
|
||||||
func (s SqlChannelStore) GetMembersForUser(teamId string, userId string) store.StoreChannel {
|
func (s SqlChannelStore) GetMembersForUser(teamId string, userId string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
members := &model.ChannelMembers{}
|
var dbMembers channelMemberWithSchemeRolesList
|
||||||
_, err := s.GetReplica().Select(members, `
|
_, err := s.GetReplica().Select(&dbMembers, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelMembers.UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||||
SELECT cm.*
|
|
||||||
FROM ChannelMembers cm
|
|
||||||
INNER JOIN Channels c
|
|
||||||
ON c.Id = cm.ChannelId
|
|
||||||
AND (c.TeamId = :TeamId OR c.TeamId = '')
|
|
||||||
AND c.DeleteAt = 0
|
|
||||||
WHERE cm.UserId = :UserId
|
|
||||||
`, map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetMembersForUser", "store.sql_channel.get_members.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.GetMembersForUser", "store.sql_channel.get_members.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = members
|
result.Data = dbMembers.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1455,7 +1705,7 @@ func (s SqlChannelStore) performSearch(searchQuery string, term string, paramete
|
|||||||
|
|
||||||
func (s SqlChannelStore) GetMembersByIds(channelId string, userIds []string) store.StoreChannel {
|
func (s SqlChannelStore) GetMembersByIds(channelId string, userIds []string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var members model.ChannelMembers
|
var dbMembers channelMemberWithSchemeRolesList
|
||||||
props := make(map[string]interface{})
|
props := make(map[string]interface{})
|
||||||
idQuery := ""
|
idQuery := ""
|
||||||
|
|
||||||
@@ -1470,11 +1720,22 @@ func (s SqlChannelStore) GetMembersByIds(channelId string, userIds []string) sto
|
|||||||
|
|
||||||
props["ChannelId"] = channelId
|
props["ChannelId"] = channelId
|
||||||
|
|
||||||
if _, err := s.GetReplica().Select(&members, "SELECT * FROM ChannelMembers WHERE ChannelId = :ChannelId AND UserId IN ("+idQuery+")", props); err != nil {
|
if _, err := s.GetReplica().Select(&dbMembers, CHANNEL_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE ChannelMembers.ChannelId = :ChannelId AND ChannelMembers.UserId IN ("+idQuery+")", props); err != nil {
|
||||||
result.Err = model.NewAppError("SqlChannelStore.GetMembersByIds", "store.sql_channel.get_members_by_ids.app_error", nil, "channelId="+channelId+" "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlChannelStore.GetMembersByIds", "store.sql_channel.get_members_by_ids.app_error", nil, "channelId="+channelId+" "+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = &members
|
result.Data = dbMembers.ToModel()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SqlChannelStore) GetChannelsByScheme(schemeId string, offset int, limit int) store.StoreChannel {
|
||||||
|
return store.Do(func(result *store.StoreResult) {
|
||||||
|
var channels []*model.Channel
|
||||||
|
_, err := s.GetReplica().Select(&channels, "SELECT * FROM Channels WHERE SchemeId = :SchemeId ORDER BY DisplayName LIMIT :Limit OFFSET :Offset", map[string]interface{}{"SchemeId": schemeId, "Offset": offset, "Limit": limit})
|
||||||
|
if err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlChannelStore.GetChannelsByScheme", "store.sql_channel.get_by_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
result.Data = channels
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,937 @@
|
|||||||
package sqlstore
|
package sqlstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/mattermost/mattermost-server/store/storetest"
|
"github.com/mattermost/mattermost-server/store/storetest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChannelStore(t *testing.T) {
|
func TestChannelStore(t *testing.T) {
|
||||||
StoreTest(t, storetest.TestChannelStore)
|
StoreTest(t, storetest.TestChannelStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestChannelStoreInternalDataTypes(t *testing.T) {
|
||||||
|
t.Run("NewChannelMemberFromModel", func(t *testing.T) { testNewChannelMemberFromModel(t) })
|
||||||
|
t.Run("ChannelMemberWithSchemeRolesToModel", func(t *testing.T) { testChannelMemberWithSchemeRolesToModel(t) })
|
||||||
|
t.Run("AllChannelMemberProcess", func(t *testing.T) { testAllChannelMemberProcess(t) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func testNewChannelMemberFromModel(t *testing.T) {
|
||||||
|
m := model.ChannelMember{
|
||||||
|
ChannelId: model.NewId(),
|
||||||
|
UserId: model.NewId(),
|
||||||
|
Roles: "channel_user channel_admin custom_role",
|
||||||
|
LastViewedAt: 12345,
|
||||||
|
MsgCount: 2,
|
||||||
|
MentionCount: 1,
|
||||||
|
NotifyProps: model.StringMap{"key": "value"},
|
||||||
|
LastUpdateAt: 54321,
|
||||||
|
SchemeUser: true,
|
||||||
|
SchemeAdmin: true,
|
||||||
|
ExplicitRoles: "custom_role",
|
||||||
|
}
|
||||||
|
|
||||||
|
db := NewChannelMemberFromModel(&m)
|
||||||
|
|
||||||
|
assert.Equal(t, m.ChannelId, db.ChannelId)
|
||||||
|
assert.Equal(t, m.UserId, db.UserId)
|
||||||
|
assert.Equal(t, m.LastViewedAt, db.LastViewedAt)
|
||||||
|
assert.Equal(t, m.MsgCount, db.MsgCount)
|
||||||
|
assert.Equal(t, m.MentionCount, db.MentionCount)
|
||||||
|
assert.Equal(t, m.NotifyProps, db.NotifyProps)
|
||||||
|
assert.Equal(t, m.LastUpdateAt, db.LastUpdateAt)
|
||||||
|
assert.Equal(t, true, db.SchemeUser.Valid)
|
||||||
|
assert.Equal(t, true, db.SchemeAdmin.Valid)
|
||||||
|
assert.Equal(t, m.SchemeUser, db.SchemeUser.Bool)
|
||||||
|
assert.Equal(t, m.SchemeAdmin, db.SchemeAdmin.Bool)
|
||||||
|
assert.Equal(t, m.ExplicitRoles, db.Roles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testChannelMemberWithSchemeRolesToModel(t *testing.T) {
|
||||||
|
t.Run("BasicProperties", func(t *testing.T) {
|
||||||
|
// Test all the non-roles properties here.
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
ChannelId: model.NewId(),
|
||||||
|
UserId: model.NewId(),
|
||||||
|
Roles: "custom_role",
|
||||||
|
LastViewedAt: 12345,
|
||||||
|
MsgCount: 2,
|
||||||
|
MentionCount: 1,
|
||||||
|
NotifyProps: model.StringMap{"key": "value"},
|
||||||
|
LastUpdateAt: 54321,
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, db.ChannelId, m.ChannelId)
|
||||||
|
assert.Equal(t, db.UserId, m.UserId)
|
||||||
|
assert.Equal(t, "custom_role channel_user channel_admin", m.Roles)
|
||||||
|
assert.Equal(t, db.LastViewedAt, m.LastViewedAt)
|
||||||
|
assert.Equal(t, db.MsgCount, m.MsgCount)
|
||||||
|
assert.Equal(t, db.MentionCount, m.MentionCount)
|
||||||
|
assert.Equal(t, db.NotifyProps, m.NotifyProps)
|
||||||
|
assert.Equal(t, db.LastUpdateAt, m.LastUpdateAt)
|
||||||
|
assert.Equal(t, db.SchemeUser.Bool, m.SchemeUser)
|
||||||
|
assert.Equal(t, db.SchemeAdmin.Bool, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, db.Roles, m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data *before* the Phase 2 migration has taken place.
|
||||||
|
t.Run("Unmigrated_NoScheme_User", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "channel_user",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_Admin", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "channel_admin channel_user",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_admin channel_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "channel_user custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user custom_role", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "channel_user channel_admin custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user channel_admin custom_role", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data *after* the Phase 2 migration has taken place.
|
||||||
|
t.Run("Migrated_NoScheme_User", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_Admin", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user channel_admin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role channel_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role channel_user channel_admin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data with a channel scheme.
|
||||||
|
t.Run("Migrated_ChannelScheme_User", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_ChannelScheme_Admin", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user cscheme_admin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_ChannelScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_ChannelScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role cscheme_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_ChannelScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role cscheme_user cscheme_admin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_ChannelScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data with a team scheme.
|
||||||
|
t.Run("Migrated_TeamScheme_User", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "tscheme_channeluser", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_Admin", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "tscheme_channeluser tscheme_channeladmin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role tscheme_channeluser", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role tscheme_channeluser tscheme_channeladmin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data with a team and channel scheme.
|
||||||
|
t.Run("Migrated_TeamAndChannelScheme_User", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamAndChannelScheme_Admin", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user cscheme_admin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamAndChannelScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamAndChannelScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role cscheme_user", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamAndChannelScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role cscheme_user cscheme_admin", cm.Roles)
|
||||||
|
assert.Equal(t, true, cm.SchemeUser)
|
||||||
|
assert.Equal(t, true, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamAndChannelScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := channelMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
cm := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", cm.Roles)
|
||||||
|
assert.Equal(t, false, cm.SchemeUser)
|
||||||
|
assert.Equal(t, false, cm.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", cm.ExplicitRoles)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAllChannelMemberProcess(t *testing.T) {
|
||||||
|
t.Run("Unmigrated_User", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "channel_user",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_Admin", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "channel_user channel_admin",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user channel_admin", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_Neither", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_Custom", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "custom",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedNoScheme_User", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedNoScheme_Admin", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user channel_admin", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedNoScheme_Neither", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedChannelScheme_User", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedChannelScheme_Admin", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user cscheme_admin", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedChannelScheme_Neither", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedTeamScheme_User", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "tscheme_channeluser", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedTeamScheme_Admin", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "tscheme_channeluser tscheme_channeladmin", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedTeamScheme_Neither", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedTeamAndChannelScheme_User", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedTeamAndChannelScheme_Admin", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "cscheme_user cscheme_admin", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("MigratedTeamAndChannelScheme_Neither", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_channeluser"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_channeladmin"},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: true, String: "cscheme_user"},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "cscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "", roles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("DeduplicationCheck", func(t *testing.T) {
|
||||||
|
db := allChannelMember{
|
||||||
|
Roles: "channel_user",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
ChannelSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, roles := db.Process()
|
||||||
|
|
||||||
|
assert.Equal(t, "channel_user", roles)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mattermost/gorp"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/mattermost/mattermost-server/store"
|
"github.com/mattermost/mattermost-server/store"
|
||||||
)
|
)
|
||||||
@@ -24,6 +26,7 @@ type Role struct {
|
|||||||
DeleteAt int64
|
DeleteAt int64
|
||||||
Permissions string
|
Permissions string
|
||||||
SchemeManaged bool
|
SchemeManaged bool
|
||||||
|
BuiltIn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRoleFromModel(role *model.Role) *Role {
|
func NewRoleFromModel(role *model.Role) *Role {
|
||||||
@@ -47,6 +50,7 @@ func NewRoleFromModel(role *model.Role) *Role {
|
|||||||
DeleteAt: role.DeleteAt,
|
DeleteAt: role.DeleteAt,
|
||||||
Permissions: permissions,
|
Permissions: permissions,
|
||||||
SchemeManaged: role.SchemeManaged,
|
SchemeManaged: role.SchemeManaged,
|
||||||
|
BuiltIn: role.BuiltIn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +65,7 @@ func (role Role) ToModel() *model.Role {
|
|||||||
DeleteAt: role.DeleteAt,
|
DeleteAt: role.DeleteAt,
|
||||||
Permissions: strings.Fields(role.Permissions),
|
Permissions: strings.Fields(role.Permissions),
|
||||||
SchemeManaged: role.SchemeManaged,
|
SchemeManaged: role.SchemeManaged,
|
||||||
|
BuiltIn: role.BuiltIn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,21 +89,52 @@ func (s *SqlSupplier) RoleSave(ctx context.Context, role *model.Role, hints ...s
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
dbRole := NewRoleFromModel(role)
|
if len(role.Id) == 0 {
|
||||||
if len(dbRole.Id) == 0 {
|
if transaction, err := s.GetMaster().Begin(); err != nil {
|
||||||
dbRole.Id = model.NewId()
|
result.Err = model.NewAppError("SqlRoleStore.RoleSave", "store.sql_role.save.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
dbRole.CreateAt = model.GetMillis()
|
return result
|
||||||
dbRole.UpdateAt = dbRole.CreateAt
|
} else {
|
||||||
if err := s.GetMaster().Insert(dbRole); err != nil {
|
result = s.createRole(ctx, role, transaction, hints...)
|
||||||
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError)
|
|
||||||
|
if result.Err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
} else if err := transaction.Commit(); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlRoleStore.RoleSave", "store.sql_role.save_role.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
dbRole := NewRoleFromModel(role)
|
||||||
|
|
||||||
dbRole.UpdateAt = model.GetMillis()
|
dbRole.UpdateAt = model.GetMillis()
|
||||||
if rowsChanged, err := s.GetMaster().Update(dbRole); err != nil {
|
if rowsChanged, err := s.GetMaster().Update(dbRole); err != nil {
|
||||||
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
} else if rowsChanged != 1 {
|
} else if rowsChanged != 1 {
|
||||||
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, "no record to update", http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.update.app_error", nil, "no record to update", http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.Data = dbRole.ToModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SqlSupplier) createRole(ctx context.Context, role *model.Role, transaction *gorp.Transaction, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
result := store.NewSupplierResult()
|
||||||
|
|
||||||
|
// Check the role is valid before proceeding.
|
||||||
|
if !role.IsValidWithoutId() {
|
||||||
|
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.invalid_role.app_error", nil, "", http.StatusBadRequest)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
dbRole := NewRoleFromModel(role)
|
||||||
|
|
||||||
|
dbRole.Id = model.NewId()
|
||||||
|
dbRole.CreateAt = model.GetMillis()
|
||||||
|
dbRole.UpdateAt = dbRole.CreateAt
|
||||||
|
|
||||||
|
if err := transaction.Insert(dbRole); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlRoleStore.Save", "store.sql_role.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Data = dbRole.ToModel()
|
result.Data = dbRole.ToModel()
|
||||||
@@ -175,6 +211,36 @@ func (s *SqlSupplier) RoleGetByNames(ctx context.Context, names []string, hints
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SqlSupplier) RoleDelete(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
result := store.NewSupplierResult()
|
||||||
|
|
||||||
|
// Get the role.
|
||||||
|
var role *Role
|
||||||
|
if err := s.GetReplica().SelectOne(&role, "SELECT * from Roles WHERE Id = :Id", map[string]interface{}{"Id": roleId}); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
result.Err = model.NewAppError("SqlRoleStore.Delete", "store.sql_role.get.app_error", nil, "Id="+roleId+", "+err.Error(), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
result.Err = model.NewAppError("SqlRoleStore.Delete", "store.sql_role.get.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
time := model.GetMillis()
|
||||||
|
role.DeleteAt = time
|
||||||
|
role.UpdateAt = time
|
||||||
|
|
||||||
|
if rowsChanged, err := s.GetMaster().Update(role); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlRoleStore.Delete", "store.sql_role.delete.update.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
} else if rowsChanged != 1 {
|
||||||
|
result.Err = model.NewAppError("SqlRoleStore.Delete", "store.sql_role.delete.update.app_error", nil, "no record to update", http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
result.Data = role.ToModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SqlSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
func (s *SqlSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
result := store.NewSupplierResult()
|
result := store.NewSupplierResult()
|
||||||
|
|
||||||
|
|||||||
14
store/sqlstore/scheme_store_test.go
Normal file
14
store/sqlstore/scheme_store_test.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package sqlstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/store/storetest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSchemeStore(t *testing.T) {
|
||||||
|
StoreTest(t, storetest.TestSchemeStore)
|
||||||
|
}
|
||||||
272
store/sqlstore/scheme_supplier.go
Normal file
272
store/sqlstore/scheme_supplier.go
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package sqlstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mattermost/gorp"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
"github.com/mattermost/mattermost-server/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func initSqlSupplierSchemes(sqlStore SqlStore) {
|
||||||
|
for _, db := range sqlStore.GetAllConns() {
|
||||||
|
table := db.AddTableWithName(model.Scheme{}, "Schemes").SetKeys(false, "Id")
|
||||||
|
table.ColMap("Id").SetMaxSize(26)
|
||||||
|
table.ColMap("Name").SetMaxSize(64)
|
||||||
|
table.ColMap("Description").SetMaxSize(1024)
|
||||||
|
table.ColMap("Scope").SetMaxSize(32)
|
||||||
|
table.ColMap("DefaultTeamAdminRole").SetMaxSize(64)
|
||||||
|
table.ColMap("DefaultTeamUserRole").SetMaxSize(64)
|
||||||
|
table.ColMap("DefaultChannelAdminRole").SetMaxSize(64)
|
||||||
|
table.ColMap("DefaultChannelUserRole").SetMaxSize(64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SqlSupplier) SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
result := store.NewSupplierResult()
|
||||||
|
|
||||||
|
if len(scheme.Id) == 0 {
|
||||||
|
if transaction, err := s.GetMaster().Begin(); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.SaveScheme", "store.sql_scheme.save.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
result = s.createScheme(ctx, scheme, transaction, hints...)
|
||||||
|
|
||||||
|
if result.Err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
} else if err := transaction.Commit(); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.SchemeSave", "store.sql_scheme.save_scheme.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !scheme.IsValid() {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "", http.StatusBadRequest)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
scheme.UpdateAt = model.GetMillis()
|
||||||
|
|
||||||
|
if rowsChanged, err := s.GetMaster().Update(scheme); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
} else if rowsChanged != 1 {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.update.app_error", nil, "no record to update", http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Data = scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SqlSupplier) createScheme(ctx context.Context, scheme *model.Scheme, transaction *gorp.Transaction, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
result := store.NewSupplierResult()
|
||||||
|
|
||||||
|
// Fetch the default system scheme roles to populate default permissions.
|
||||||
|
defaultRoleNames := []string{model.TEAM_ADMIN_ROLE_ID, model.TEAM_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, model.CHANNEL_USER_ROLE_ID}
|
||||||
|
defaultRoles := make(map[string]*model.Role)
|
||||||
|
if rolesResult := s.RoleGetByNames(ctx, defaultRoleNames); rolesResult.Err != nil {
|
||||||
|
result.Err = rolesResult.Err
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
for _, role := range rolesResult.Data.([]*model.Role) {
|
||||||
|
switch role.Name {
|
||||||
|
case model.TEAM_ADMIN_ROLE_ID:
|
||||||
|
defaultRoles[model.TEAM_ADMIN_ROLE_ID] = role
|
||||||
|
case model.TEAM_USER_ROLE_ID:
|
||||||
|
defaultRoles[model.TEAM_USER_ROLE_ID] = role
|
||||||
|
case model.CHANNEL_ADMIN_ROLE_ID:
|
||||||
|
defaultRoles[model.CHANNEL_ADMIN_ROLE_ID] = role
|
||||||
|
case model.CHANNEL_USER_ROLE_ID:
|
||||||
|
defaultRoles[model.CHANNEL_USER_ROLE_ID] = role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(defaultRoles) != 4 {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.SaveScheme", "store.sql_scheme.save.retrieve_default_scheme_roles.app_error", nil, "", http.StatusInternalServerError)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the appropriate default roles for the scheme.
|
||||||
|
if scheme.Scope == model.SCHEME_SCOPE_TEAM {
|
||||||
|
// Team Admin Role
|
||||||
|
teamAdminRole := &model.Role{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: fmt.Sprintf("Team Admin Role for Scheme %s", scheme.Name),
|
||||||
|
Permissions: defaultRoles[model.TEAM_ADMIN_ROLE_ID].Permissions,
|
||||||
|
SchemeManaged: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if saveRoleResult := s.createRole(ctx, teamAdminRole, transaction); saveRoleResult.Err != nil {
|
||||||
|
result.Err = saveRoleResult.Err
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
scheme.DefaultTeamAdminRole = saveRoleResult.Data.(*model.Role).Id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Team User Role
|
||||||
|
teamUserRole := &model.Role{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: fmt.Sprintf("Team User Role for Scheme %s", scheme.Name),
|
||||||
|
Permissions: defaultRoles[model.TEAM_USER_ROLE_ID].Permissions,
|
||||||
|
SchemeManaged: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if saveRoleResult := s.createRole(ctx, teamUserRole, transaction); saveRoleResult.Err != nil {
|
||||||
|
result.Err = saveRoleResult.Err
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
scheme.DefaultTeamUserRole = saveRoleResult.Data.(*model.Role).Id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if scheme.Scope == model.SCHEME_SCOPE_TEAM || scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
|
||||||
|
// Channel Admin Role
|
||||||
|
channelAdminRole := &model.Role{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: fmt.Sprintf("Channel Admin Role for Scheme %s", scheme.Name),
|
||||||
|
Permissions: defaultRoles[model.CHANNEL_ADMIN_ROLE_ID].Permissions,
|
||||||
|
SchemeManaged: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if saveRoleResult := s.createRole(ctx, channelAdminRole, transaction); saveRoleResult.Err != nil {
|
||||||
|
result.Err = saveRoleResult.Err
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
scheme.DefaultChannelAdminRole = saveRoleResult.Data.(*model.Role).Id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel User Role
|
||||||
|
channelUserRole := &model.Role{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: fmt.Sprintf("Channel User Role for Scheme %s", scheme.Name),
|
||||||
|
Permissions: defaultRoles[model.CHANNEL_USER_ROLE_ID].Permissions,
|
||||||
|
SchemeManaged: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if saveRoleResult := s.createRole(ctx, channelUserRole, transaction); saveRoleResult.Err != nil {
|
||||||
|
result.Err = saveRoleResult.Err
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
scheme.DefaultChannelUserRole = saveRoleResult.Data.(*model.Role).Id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scheme.Id = model.NewId()
|
||||||
|
scheme.CreateAt = model.GetMillis()
|
||||||
|
scheme.UpdateAt = scheme.CreateAt
|
||||||
|
|
||||||
|
// Validate the scheme
|
||||||
|
if !scheme.IsValidForCreate() {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "", http.StatusBadRequest)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := transaction.Insert(scheme); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.insert.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Data = scheme
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SqlSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
result := store.NewSupplierResult()
|
||||||
|
|
||||||
|
var scheme model.Scheme
|
||||||
|
|
||||||
|
if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Get", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Data = &scheme
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SqlSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
result := store.NewSupplierResult()
|
||||||
|
|
||||||
|
// Get the scheme
|
||||||
|
var scheme model.Scheme
|
||||||
|
if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Id = :Id", map[string]interface{}{"Id": schemeId}); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.get.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the scheme isn't being used on any Teams or Channels.
|
||||||
|
if scheme.Scope == model.SCHEME_SCOPE_TEAM {
|
||||||
|
if c, err := s.GetReplica().SelectInt("SELECT COUNT(*) FROM Teams WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.team_count.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
if c > 0 {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.scheme_in_use.app_error", nil, "Id="+schemeId, http.StatusInternalServerError)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
|
||||||
|
if c, err := s.GetReplica().SelectInt("SELECT COUNT(*) FROM Channels WHERE SchemeId = :SchemeId", map[string]interface{}{"SchemeId": schemeId}); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.channel_count.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
if c > 0 {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.scheme_in_use.app_error", nil, "Id="+schemeId, http.StatusInternalServerError)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the roles belonging to the scheme.
|
||||||
|
roleIds := []string{scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole}
|
||||||
|
if scheme.Scope == model.SCHEME_SCOPE_TEAM {
|
||||||
|
roleIds = append(roleIds, scheme.DefaultTeamUserRole, scheme.DefaultTeamAdminRole)
|
||||||
|
}
|
||||||
|
|
||||||
|
var inQueryList []string
|
||||||
|
queryArgs := make(map[string]interface{})
|
||||||
|
for i, roleId := range roleIds {
|
||||||
|
inQueryList = append(inQueryList, fmt.Sprintf(":RoleId%v", i))
|
||||||
|
queryArgs[fmt.Sprintf("RoleId%v", i)] = roleId
|
||||||
|
}
|
||||||
|
inQuery := strings.Join(inQueryList, ", ")
|
||||||
|
|
||||||
|
time := model.GetMillis()
|
||||||
|
queryArgs["UpdateAt"] = time
|
||||||
|
queryArgs["DeleteAt"] = time
|
||||||
|
|
||||||
|
if _, err := s.GetMaster().Exec("UPDATE Roles SET UpdateAt = :UpdateAt, DeleteAt = :DeleteAt WHERE Id IN ("+inQuery+")", queryArgs); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.role_update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the scheme itself.
|
||||||
|
scheme.UpdateAt = time
|
||||||
|
scheme.DeleteAt = time
|
||||||
|
|
||||||
|
if rowsChanged, err := s.GetMaster().Update(&scheme); err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "Id="+schemeId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
|
} else if rowsChanged != 1 {
|
||||||
|
result.Err = model.NewAppError("SqlSchemeStore.Delete", "store.sql_scheme.delete.update.app_error", nil, "no record to update", http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
result.Data = &scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -52,6 +52,7 @@ type SqlStore interface {
|
|||||||
DoesTableExist(tablename string) bool
|
DoesTableExist(tablename string) bool
|
||||||
DoesColumnExist(tableName string, columName string) bool
|
DoesColumnExist(tableName string, columName string) bool
|
||||||
CreateColumnIfNotExists(tableName string, columnName string, mySqlColType string, postgresColType string, defaultValue string) bool
|
CreateColumnIfNotExists(tableName string, columnName string, mySqlColType string, postgresColType string, defaultValue string) bool
|
||||||
|
CreateColumnIfNotExistsNoDefault(tableName string, columnName string, mySqlColType string, postgresColType string) bool
|
||||||
RemoveColumnIfExists(tableName string, columnName string) bool
|
RemoveColumnIfExists(tableName string, columnName string) bool
|
||||||
RemoveTableIfExists(tableName string) bool
|
RemoveTableIfExists(tableName string) bool
|
||||||
RenameColumnIfExists(tableName string, oldColumnName string, newColumnName string, colType string) bool
|
RenameColumnIfExists(tableName string, oldColumnName string, newColumnName string, colType string) bool
|
||||||
@@ -88,4 +89,5 @@ type SqlStore interface {
|
|||||||
Plugin() store.PluginStore
|
Plugin() store.PluginStore
|
||||||
UserAccessToken() store.UserAccessTokenStore
|
UserAccessToken() store.UserAccessTokenStore
|
||||||
Role() store.RoleStore
|
Role() store.RoleStore
|
||||||
|
Scheme() store.SchemeStore
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ type SqlSupplierOldStores struct {
|
|||||||
plugin store.PluginStore
|
plugin store.PluginStore
|
||||||
channelMemberHistory store.ChannelMemberHistoryStore
|
channelMemberHistory store.ChannelMemberHistoryStore
|
||||||
role store.RoleStore
|
role store.RoleStore
|
||||||
|
scheme store.SchemeStore
|
||||||
}
|
}
|
||||||
|
|
||||||
type SqlSupplier struct {
|
type SqlSupplier struct {
|
||||||
@@ -139,6 +140,7 @@ func NewSqlSupplier(settings model.SqlSettings, metrics einterfaces.MetricsInter
|
|||||||
|
|
||||||
initSqlSupplierReactions(supplier)
|
initSqlSupplierReactions(supplier)
|
||||||
initSqlSupplierRoles(supplier)
|
initSqlSupplierRoles(supplier)
|
||||||
|
initSqlSupplierSchemes(supplier)
|
||||||
|
|
||||||
err := supplier.GetMaster().CreateTablesIfNotExists()
|
err := supplier.GetMaster().CreateTablesIfNotExists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -462,6 +464,40 @@ func (ss *SqlSupplier) CreateColumnIfNotExists(tableName string, columnName stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *SqlSupplier) CreateColumnIfNotExistsNoDefault(tableName string, columnName string, mySqlColType string, postgresColType string) bool {
|
||||||
|
|
||||||
|
if ss.DoesColumnExist(tableName, columnName) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if ss.DriverName() == model.DATABASE_DRIVER_POSTGRES {
|
||||||
|
_, err := ss.GetMaster().ExecNoTimeout("ALTER TABLE " + tableName + " ADD " + columnName + " " + postgresColType)
|
||||||
|
if err != nil {
|
||||||
|
l4g.Critical(utils.T("store.sql.create_column.critical"), err)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
os.Exit(EXIT_CREATE_COLUMN_POSTGRES)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
} else if ss.DriverName() == model.DATABASE_DRIVER_MYSQL {
|
||||||
|
_, err := ss.GetMaster().ExecNoTimeout("ALTER TABLE " + tableName + " ADD " + columnName + " " + mySqlColType)
|
||||||
|
if err != nil {
|
||||||
|
l4g.Critical(utils.T("store.sql.create_column.critical"), err)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
os.Exit(EXIT_CREATE_COLUMN_MYSQL)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
} else {
|
||||||
|
l4g.Critical(utils.T("store.sql.create_column_missing_driver.critical"))
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
os.Exit(EXIT_CREATE_COLUMN_MISSING)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) RemoveColumnIfExists(tableName string, columnName string) bool {
|
func (ss *SqlSupplier) RemoveColumnIfExists(tableName string, columnName string) bool {
|
||||||
|
|
||||||
if !ss.DoesColumnExist(tableName, columnName) {
|
if !ss.DoesColumnExist(tableName, columnName) {
|
||||||
@@ -834,6 +870,10 @@ func (ss *SqlSupplier) Role() store.RoleStore {
|
|||||||
return ss.oldStores.role
|
return ss.oldStores.role
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *SqlSupplier) Scheme() store.SchemeStore {
|
||||||
|
return ss.oldStores.scheme
|
||||||
|
}
|
||||||
|
|
||||||
func (ss *SqlSupplier) DropAllTables() {
|
func (ss *SqlSupplier) DropAllTables() {
|
||||||
ss.master.TruncateTables()
|
ss.master.TruncateTables()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/mattermost/mattermost-server/store"
|
"github.com/mattermost/mattermost-server/store"
|
||||||
@@ -20,6 +21,116 @@ type SqlTeamStore struct {
|
|||||||
SqlStore
|
SqlStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type teamMember struct {
|
||||||
|
TeamId string
|
||||||
|
UserId string
|
||||||
|
Roles string
|
||||||
|
DeleteAt int64
|
||||||
|
SchemeUser sql.NullBool
|
||||||
|
SchemeAdmin sql.NullBool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTeamMemberFromModel(tm *model.TeamMember) *teamMember {
|
||||||
|
return &teamMember{
|
||||||
|
TeamId: tm.TeamId,
|
||||||
|
UserId: tm.UserId,
|
||||||
|
Roles: tm.ExplicitRoles,
|
||||||
|
DeleteAt: tm.DeleteAt,
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: tm.SchemeUser},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: tm.SchemeAdmin},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type teamMemberWithSchemeRoles struct {
|
||||||
|
TeamId string
|
||||||
|
UserId string
|
||||||
|
Roles string
|
||||||
|
DeleteAt int64
|
||||||
|
SchemeUser sql.NullBool
|
||||||
|
SchemeAdmin sql.NullBool
|
||||||
|
TeamSchemeDefaultUserRole sql.NullString
|
||||||
|
TeamSchemeDefaultAdminRole sql.NullString
|
||||||
|
}
|
||||||
|
|
||||||
|
type teamMemberWithSchemeRolesList []teamMemberWithSchemeRoles
|
||||||
|
|
||||||
|
func (db teamMemberWithSchemeRoles) ToModel() *model.TeamMember {
|
||||||
|
var roles []string
|
||||||
|
var explicitRoles []string
|
||||||
|
|
||||||
|
// Identify any scheme derived roles that are in "Roles" field due to not yet being migrated, and exclude
|
||||||
|
// them from ExplicitRoles field.
|
||||||
|
schemeUser := db.SchemeUser.Valid && db.SchemeUser.Bool
|
||||||
|
schemeAdmin := db.SchemeAdmin.Valid && db.SchemeAdmin.Bool
|
||||||
|
for _, role := range strings.Fields(db.Roles) {
|
||||||
|
isImplicit := false
|
||||||
|
if role == model.TEAM_USER_ROLE_ID {
|
||||||
|
// We have an implicit role via the system scheme. Override the "schemeUser" field to true.
|
||||||
|
schemeUser = true
|
||||||
|
isImplicit = true
|
||||||
|
} else if role == model.TEAM_ADMIN_ROLE_ID {
|
||||||
|
// We have an implicit role via the system scheme.
|
||||||
|
schemeAdmin = true
|
||||||
|
isImplicit = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isImplicit {
|
||||||
|
explicitRoles = append(explicitRoles, role)
|
||||||
|
}
|
||||||
|
roles = append(roles, role)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any scheme derived roles that are not in the Roles field due to being Implicit from the Scheme, and add
|
||||||
|
// them to the Roles field for backwards compatibility reasons.
|
||||||
|
var schemeImpliedRoles []string
|
||||||
|
if db.SchemeUser.Valid && db.SchemeUser.Bool {
|
||||||
|
if db.TeamSchemeDefaultUserRole.Valid && db.TeamSchemeDefaultUserRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultUserRole.String)
|
||||||
|
} else {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_USER_ROLE_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if db.SchemeAdmin.Valid && db.SchemeAdmin.Bool {
|
||||||
|
if db.TeamSchemeDefaultAdminRole.Valid && db.TeamSchemeDefaultAdminRole.String != "" {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, db.TeamSchemeDefaultAdminRole.String)
|
||||||
|
} else {
|
||||||
|
schemeImpliedRoles = append(schemeImpliedRoles, model.TEAM_ADMIN_ROLE_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, impliedRole := range schemeImpliedRoles {
|
||||||
|
alreadyThere := false
|
||||||
|
for _, role := range roles {
|
||||||
|
if role == impliedRole {
|
||||||
|
alreadyThere = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !alreadyThere {
|
||||||
|
roles = append(roles, impliedRole)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tm := &model.TeamMember{
|
||||||
|
TeamId: db.TeamId,
|
||||||
|
UserId: db.UserId,
|
||||||
|
Roles: strings.Join(roles, " "),
|
||||||
|
DeleteAt: db.DeleteAt,
|
||||||
|
SchemeUser: schemeUser,
|
||||||
|
SchemeAdmin: schemeAdmin,
|
||||||
|
ExplicitRoles: strings.Join(explicitRoles, " "),
|
||||||
|
}
|
||||||
|
return tm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db teamMemberWithSchemeRolesList) ToModel() []*model.TeamMember {
|
||||||
|
tms := make([]*model.TeamMember, 0)
|
||||||
|
|
||||||
|
for _, tm := range db {
|
||||||
|
tms = append(tms, tm.ToModel())
|
||||||
|
}
|
||||||
|
|
||||||
|
return tms
|
||||||
|
}
|
||||||
|
|
||||||
func NewSqlTeamStore(sqlStore SqlStore) store.TeamStore {
|
func NewSqlTeamStore(sqlStore SqlStore) store.TeamStore {
|
||||||
s := &SqlTeamStore{sqlStore}
|
s := &SqlTeamStore{sqlStore}
|
||||||
|
|
||||||
@@ -34,7 +145,7 @@ func NewSqlTeamStore(sqlStore SqlStore) store.TeamStore {
|
|||||||
table.ColMap("AllowedDomains").SetMaxSize(500)
|
table.ColMap("AllowedDomains").SetMaxSize(500)
|
||||||
table.ColMap("InviteId").SetMaxSize(32)
|
table.ColMap("InviteId").SetMaxSize(32)
|
||||||
|
|
||||||
tablem := db.AddTableWithName(model.TeamMember{}, "TeamMembers").SetKeys(false, "TeamId", "UserId")
|
tablem := db.AddTableWithName(teamMember{}, "TeamMembers").SetKeys(false, "TeamId", "UserId")
|
||||||
tablem.ColMap("TeamId").SetMaxSize(26)
|
tablem.ColMap("TeamId").SetMaxSize(26)
|
||||||
tablem.ColMap("UserId").SetMaxSize(26)
|
tablem.ColMap("UserId").SetMaxSize(26)
|
||||||
tablem.ColMap("Roles").SetMaxSize(64)
|
tablem.ColMap("Roles").SetMaxSize(64)
|
||||||
@@ -326,12 +437,27 @@ func (s SqlTeamStore) AnalyticsTeamCount() store.StoreChannel {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY = `
|
||||||
|
SELECT
|
||||||
|
TeamMembers.*,
|
||||||
|
TeamScheme.DefaultChannelUserRole TeamSchemeDefaultUserRole,
|
||||||
|
TeamScheme.DefaultChannelAdminRole TeamSchemeDefaultAdminRole
|
||||||
|
FROM
|
||||||
|
TeamMembers
|
||||||
|
LEFT JOIN
|
||||||
|
Teams ON TeamMembers.TeamId = Teams.Id
|
||||||
|
LEFT JOIN
|
||||||
|
Schemes TeamScheme ON Teams.SchemeId = TeamScheme.Id
|
||||||
|
`
|
||||||
|
|
||||||
func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int) store.StoreChannel {
|
func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
if result.Err = member.IsValid(); result.Err != nil {
|
if result.Err = member.IsValid(); result.Err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbMember := NewTeamMemberFromModel(member)
|
||||||
|
|
||||||
if maxUsersPerTeam >= 0 {
|
if maxUsersPerTeam >= 0 {
|
||||||
if count, err := s.GetMaster().SelectInt(
|
if count, err := s.GetMaster().SelectInt(
|
||||||
`SELECT
|
`SELECT
|
||||||
@@ -354,14 +480,23 @@ func (s SqlTeamStore) SaveMember(member *model.TeamMember, maxUsersPerTeam int)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.GetMaster().Insert(member); err != nil {
|
if err := s.GetMaster().Insert(dbMember); err != nil {
|
||||||
if IsUniqueConstraintError(err, []string{"TeamId", "teammembers_pkey", "PRIMARY"}) {
|
if IsUniqueConstraintError(err, []string{"TeamId", "teammembers_pkey", "PRIMARY"}) {
|
||||||
result.Err = model.NewAppError("SqlTeamStore.SaveMember", TEAM_MEMBER_EXISTS_ERROR, nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error(), http.StatusBadRequest)
|
result.Err = model.NewAppError("SqlTeamStore.SaveMember", TEAM_MEMBER_EXISTS_ERROR, nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error(), http.StatusBadRequest)
|
||||||
} else {
|
} else {
|
||||||
result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.save_member.save.app_error", nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.save_member.save.app_error", nil, "team_id="+member.TeamId+", user_id="+member.UserId+", "+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.Data = member
|
var retrievedMember teamMemberWithSchemeRoles
|
||||||
|
if err := s.GetMaster().SelectOne(&retrievedMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": dbMember.TeamId, "UserId": dbMember.UserId}); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.get_member.missing.app_error", nil, "team_id="+dbMember.TeamId+"user_id="+dbMember.UserId+","+err.Error(), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
result.Err = model.NewAppError("SqlTeamStore.SaveMember", "store.sql_team.get_member.app_error", nil, "team_id="+dbMember.TeamId+"user_id="+dbMember.UserId+","+err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.Data = retrievedMember.ToModel()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -374,18 +509,27 @@ func (s SqlTeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := s.GetMaster().Update(member); err != nil {
|
if _, err := s.GetMaster().Update(NewTeamMemberFromModel(member)); err != nil {
|
||||||
result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.save_member.save.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = member
|
var retrievedMember teamMemberWithSchemeRoles
|
||||||
|
if err := s.GetMaster().SelectOne(&retrievedMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": member.TeamId, "UserId": member.UserId}); err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.missing.app_error", nil, "team_id="+member.TeamId+"user_id="+member.UserId+","+err.Error(), http.StatusNotFound)
|
||||||
|
} else {
|
||||||
|
result.Err = model.NewAppError("SqlTeamStore.UpdateMember", "store.sql_team.get_member.app_error", nil, "team_id="+member.TeamId+"user_id="+member.UserId+","+err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.Data = retrievedMember.ToModel()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlTeamStore) GetMember(teamId string, userId string) store.StoreChannel {
|
func (s SqlTeamStore) GetMember(teamId string, userId string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var member model.TeamMember
|
var dbMember teamMemberWithSchemeRoles
|
||||||
err := s.GetReplica().SelectOne(&member, "SELECT * FROM TeamMembers WHERE TeamId = :TeamId AND UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
err := s.GetReplica().SelectOne(&dbMember, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId = :UserId", map[string]interface{}{"TeamId": teamId, "UserId": userId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.missing.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusNotFound)
|
result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.missing.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusNotFound)
|
||||||
@@ -393,19 +537,19 @@ func (s SqlTeamStore) GetMember(teamId string, userId string) store.StoreChannel
|
|||||||
result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlTeamStore.GetMember", "store.sql_team.get_member.app_error", nil, "teamId="+teamId+" userId="+userId+" "+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.Data = &member
|
result.Data = dbMember.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int) store.StoreChannel {
|
func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var members []*model.TeamMember
|
var dbMembers teamMemberWithSchemeRolesList
|
||||||
_, err := s.GetReplica().Select(&members, "SELECT * FROM TeamMembers WHERE TeamId = :TeamId AND DeleteAt = 0 LIMIT :Limit OFFSET :Offset", map[string]interface{}{"TeamId": teamId, "Offset": offset, "Limit": limit})
|
_, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.DeleteAt = 0 LIMIT :Limit OFFSET :Offset", map[string]interface{}{"TeamId": teamId, "Limit": limit, "Offset": offset})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = members
|
result.Data = dbMembers.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -453,7 +597,7 @@ func (s SqlTeamStore) GetActiveMemberCount(teamId string) store.StoreChannel {
|
|||||||
|
|
||||||
func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string) store.StoreChannel {
|
func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var members []*model.TeamMember
|
var dbMembers teamMemberWithSchemeRolesList
|
||||||
props := make(map[string]interface{})
|
props := make(map[string]interface{})
|
||||||
idQuery := ""
|
idQuery := ""
|
||||||
|
|
||||||
@@ -468,22 +612,22 @@ func (s SqlTeamStore) GetMembersByIds(teamId string, userIds []string) store.Sto
|
|||||||
|
|
||||||
props["TeamId"] = teamId
|
props["TeamId"] = teamId
|
||||||
|
|
||||||
if _, err := s.GetReplica().Select(&members, "SELECT * FROM TeamMembers WHERE TeamId = :TeamId AND UserId IN ("+idQuery+") AND DeleteAt = 0", props); err != nil {
|
if _, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.TeamId = :TeamId AND TeamMembers.UserId IN ("+idQuery+") AND TeamMembers.DeleteAt = 0", props); err != nil {
|
||||||
result.Err = model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlTeamStore.GetMembersByIds", "store.sql_team.get_members_by_ids.app_error", nil, "teamId="+teamId+" "+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = members
|
result.Data = dbMembers.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SqlTeamStore) GetTeamsForUser(userId string) store.StoreChannel {
|
func (s SqlTeamStore) GetTeamsForUser(userId string) store.StoreChannel {
|
||||||
return store.Do(func(result *store.StoreResult) {
|
return store.Do(func(result *store.StoreResult) {
|
||||||
var members []*model.TeamMember
|
var dbMembers teamMemberWithSchemeRolesList
|
||||||
_, err := s.GetReplica().Select(&members, "SELECT * FROM TeamMembers WHERE UserId = :UserId", map[string]interface{}{"UserId": userId})
|
_, err := s.GetReplica().Select(&dbMembers, TEAM_MEMBERS_WITH_SCHEME_SELECT_QUERY+"WHERE TeamMembers.UserId = :UserId", map[string]interface{}{"UserId": userId})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
|
result.Err = model.NewAppError("SqlTeamStore.GetMembers", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
|
||||||
} else {
|
} else {
|
||||||
result.Data = members
|
result.Data = dbMembers.ToModel()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -570,3 +714,15 @@ func (us SqlTeamStore) UpdateLastTeamIconUpdate(teamId string, curTime int64) st
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s SqlTeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) store.StoreChannel {
|
||||||
|
return store.Do(func(result *store.StoreResult) {
|
||||||
|
var teams []*model.Team
|
||||||
|
_, err := s.GetReplica().Select(&teams, "SELECT * FROM Teams WHERE SchemeId = :SchemeId ORDER BY DisplayName LIMIT :Limit OFFSET :Offset", map[string]interface{}{"SchemeId": schemeId, "Offset": offset, "Limit": limit})
|
||||||
|
if err != nil {
|
||||||
|
result.Err = model.NewAppError("SqlTeamStore.GetTeamsByScheme", "store.sql_team.get_by_scheme.app_error", nil, "schemeId="+schemeId+" "+err.Error(), http.StatusInternalServerError)
|
||||||
|
} else {
|
||||||
|
result.Data = teams
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,11 +4,378 @@
|
|||||||
package sqlstore
|
package sqlstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/mattermost/mattermost-server/store/storetest"
|
"github.com/mattermost/mattermost-server/store/storetest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTeamStore(t *testing.T) {
|
func TestTeamStore(t *testing.T) {
|
||||||
StoreTest(t, storetest.TestTeamStore)
|
StoreTest(t, storetest.TestTeamStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTeamStoreInternalDataTypes(t *testing.T) {
|
||||||
|
t.Run("NewTeamMemberFromModel", func(t *testing.T) { testNewTeamMemberFromModel(t) })
|
||||||
|
t.Run("TeamMemberWithSchemeRolesToModel", func(t *testing.T) { testTeamMemberWithSchemeRolesToModel(t) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func testNewTeamMemberFromModel(t *testing.T) {
|
||||||
|
m := model.TeamMember{
|
||||||
|
TeamId: model.NewId(),
|
||||||
|
UserId: model.NewId(),
|
||||||
|
Roles: "team_user team_admin custom_role",
|
||||||
|
DeleteAt: 12345,
|
||||||
|
SchemeUser: true,
|
||||||
|
SchemeAdmin: true,
|
||||||
|
ExplicitRoles: "custom_role",
|
||||||
|
}
|
||||||
|
|
||||||
|
db := NewTeamMemberFromModel(&m)
|
||||||
|
|
||||||
|
assert.Equal(t, m.TeamId, db.TeamId)
|
||||||
|
assert.Equal(t, m.UserId, db.UserId)
|
||||||
|
assert.Equal(t, m.DeleteAt, db.DeleteAt)
|
||||||
|
assert.Equal(t, true, db.SchemeUser.Valid)
|
||||||
|
assert.Equal(t, true, db.SchemeAdmin.Valid)
|
||||||
|
assert.Equal(t, m.SchemeUser, db.SchemeUser.Bool)
|
||||||
|
assert.Equal(t, m.SchemeAdmin, db.SchemeAdmin.Bool)
|
||||||
|
assert.Equal(t, m.ExplicitRoles, db.Roles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTeamMemberWithSchemeRolesToModel(t *testing.T) {
|
||||||
|
// Test all the non-role-related properties here.
|
||||||
|
t.Run("BasicProperties", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
TeamId: model.NewId(),
|
||||||
|
UserId: model.NewId(),
|
||||||
|
Roles: "custom_role",
|
||||||
|
DeleteAt: 12345,
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, db.TeamId, m.TeamId)
|
||||||
|
assert.Equal(t, db.UserId, m.UserId)
|
||||||
|
assert.Equal(t, "custom_role team_user team_admin", m.Roles)
|
||||||
|
assert.Equal(t, db.DeleteAt, m.DeleteAt)
|
||||||
|
assert.Equal(t, db.SchemeUser.Bool, m.SchemeUser)
|
||||||
|
assert.Equal(t, db.SchemeAdmin.Bool, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, db.Roles, m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data *before* the Phase 2 migration has taken place.
|
||||||
|
t.Run("Unmigrated_NoScheme_User", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "team_user",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "team_user", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_Admin", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "team_user team_admin",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "team_user team_admin", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, true, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", m.Roles)
|
||||||
|
assert.Equal(t, false, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "team_user custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "team_user custom_role", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "team_user team_admin custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "team_user team_admin custom_role", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, true, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unmigrated_NoScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: false, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", m.Roles)
|
||||||
|
assert.Equal(t, false, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data *after* the Phase 2 migration has taken place.
|
||||||
|
t.Run("Migrated_NoScheme_User", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "team_user", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_Admin", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "team_user team_admin", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, true, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", m.Roles)
|
||||||
|
assert.Equal(t, false, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role team_user", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role team_user team_admin", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, true, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_NoScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: false},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: false},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", m.Roles)
|
||||||
|
assert.Equal(t, false, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Example data with a team scheme.
|
||||||
|
t.Run("Migrated_TeamScheme_User", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_user"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "tscheme_user", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_Admin", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_user"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "tscheme_user tscheme_admin", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, true, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_CustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_user"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role", m.Roles)
|
||||||
|
assert.Equal(t, false, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_UserAndCustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_user"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role tscheme_user", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_AdminAndCustomRole", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "custom_role",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: true},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_user"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "custom_role tscheme_user tscheme_admin", m.Roles)
|
||||||
|
assert.Equal(t, true, m.SchemeUser)
|
||||||
|
assert.Equal(t, true, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "custom_role", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Migrated_TeamScheme_NoRoles", func(t *testing.T) {
|
||||||
|
db := teamMemberWithSchemeRoles{
|
||||||
|
Roles: "",
|
||||||
|
SchemeUser: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
SchemeAdmin: sql.NullBool{Valid: true, Bool: false},
|
||||||
|
TeamSchemeDefaultUserRole: sql.NullString{Valid: true, String: "tscheme_user"},
|
||||||
|
TeamSchemeDefaultAdminRole: sql.NullString{Valid: true, String: "tscheme_admin"},
|
||||||
|
}
|
||||||
|
|
||||||
|
m := db.ToModel()
|
||||||
|
|
||||||
|
assert.Equal(t, "", m.Roles)
|
||||||
|
assert.Equal(t, false, m.SchemeUser)
|
||||||
|
assert.Equal(t, false, m.SchemeAdmin)
|
||||||
|
assert.Equal(t, "", m.ExplicitRoles)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -420,5 +420,18 @@ func UpgradeDatabaseToVersion410(sqlStore SqlStore) {
|
|||||||
sqlStore.RemoveIndexIfExists("ClientId_2", "OAuthAccessData")
|
sqlStore.RemoveIndexIfExists("ClientId_2", "OAuthAccessData")
|
||||||
|
|
||||||
// saveSchemaVersion(sqlStore, VERSION_4_10_0)
|
// saveSchemaVersion(sqlStore, VERSION_4_10_0)
|
||||||
|
sqlStore.CreateColumnIfNotExistsNoDefault("Teams", "SchemeId", "varchar(26)", "varchar(26)")
|
||||||
|
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "SchemeId", "varchar(26)", "varchar(26)")
|
||||||
|
|
||||||
|
sqlStore.CreateColumnIfNotExistsNoDefault("TeamMembers", "SchemeUser", "boolean", "boolean")
|
||||||
|
sqlStore.CreateColumnIfNotExistsNoDefault("TeamMembers", "SchemeAdmin", "boolean", "boolean")
|
||||||
|
sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeUser", "boolean", "boolean")
|
||||||
|
sqlStore.CreateColumnIfNotExistsNoDefault("ChannelMembers", "SchemeAdmin", "boolean", "boolean")
|
||||||
|
|
||||||
|
sqlStore.CreateColumnIfNotExists("Roles", "BuiltIn", "boolean", "boolean", "0")
|
||||||
|
sqlStore.GetMaster().Exec("UPDATE Roles SET BuiltIn=true")
|
||||||
|
sqlStore.GetMaster().Exec("UPDATE Roles SET SchemeManaged=false WHERE Name NOT IN ('system_user', 'system_admin', 'team_user', 'team_admin', 'channel_user', 'channel_admin')")
|
||||||
|
|
||||||
|
// saveSchemaVersion(sqlStore, VERSION_4_9_0)
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ type Store interface {
|
|||||||
FileInfo() FileInfoStore
|
FileInfo() FileInfoStore
|
||||||
Reaction() ReactionStore
|
Reaction() ReactionStore
|
||||||
Role() RoleStore
|
Role() RoleStore
|
||||||
|
Scheme() SchemeStore
|
||||||
Job() JobStore
|
Job() JobStore
|
||||||
UserAccessToken() UserAccessTokenStore
|
UserAccessToken() UserAccessTokenStore
|
||||||
ChannelMemberHistory() ChannelMemberHistoryStore
|
ChannelMemberHistory() ChannelMemberHistoryStore
|
||||||
@@ -105,6 +106,7 @@ type TeamStore interface {
|
|||||||
RemoveAllMembersByTeam(teamId string) StoreChannel
|
RemoveAllMembersByTeam(teamId string) StoreChannel
|
||||||
RemoveAllMembersByUser(userId string) StoreChannel
|
RemoveAllMembersByUser(userId string) StoreChannel
|
||||||
UpdateLastTeamIconUpdate(teamId string, curTime int64) StoreChannel
|
UpdateLastTeamIconUpdate(teamId string, curTime int64) StoreChannel
|
||||||
|
GetTeamsByScheme(schemeId string, offset int, limit int) StoreChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChannelStore interface {
|
type ChannelStore interface {
|
||||||
@@ -162,6 +164,7 @@ type ChannelStore interface {
|
|||||||
AnalyticsDeletedTypeCount(teamId string, channelType string) StoreChannel
|
AnalyticsDeletedTypeCount(teamId string, channelType string) StoreChannel
|
||||||
GetChannelUnread(channelId, userId string) StoreChannel
|
GetChannelUnread(channelId, userId string) StoreChannel
|
||||||
ClearCaches()
|
ClearCaches()
|
||||||
|
GetChannelsByScheme(schemeId string, offset int, limit int) StoreChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChannelMemberHistoryStore interface {
|
type ChannelMemberHistoryStore interface {
|
||||||
@@ -477,5 +480,12 @@ type RoleStore interface {
|
|||||||
Get(roleId string) StoreChannel
|
Get(roleId string) StoreChannel
|
||||||
GetByName(name string) StoreChannel
|
GetByName(name string) StoreChannel
|
||||||
GetByNames(names []string) StoreChannel
|
GetByNames(names []string) StoreChannel
|
||||||
|
Delete(roldId string) StoreChannel
|
||||||
PermanentDeleteAll() StoreChannel
|
PermanentDeleteAll() StoreChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SchemeStore interface {
|
||||||
|
Save(scheme *model.Scheme) StoreChannel
|
||||||
|
Get(schemeId string) StoreChannel
|
||||||
|
Delete(schemeId string) StoreChannel
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestChannelStore(t *testing.T, ss store.Store) {
|
func TestChannelStore(t *testing.T, ss store.Store) {
|
||||||
|
createDefaultRoles(t, ss)
|
||||||
|
|
||||||
t.Run("Save", func(t *testing.T) { testChannelStoreSave(t, ss) })
|
t.Run("Save", func(t *testing.T) { testChannelStoreSave(t, ss) })
|
||||||
t.Run("SaveDirectChannel", func(t *testing.T) { testChannelStoreSaveDirectChannel(t, ss) })
|
t.Run("SaveDirectChannel", func(t *testing.T) { testChannelStoreSaveDirectChannel(t, ss) })
|
||||||
t.Run("CreateDirectChannel", func(t *testing.T) { testChannelStoreCreateDirectChannel(t, ss) })
|
t.Run("CreateDirectChannel", func(t *testing.T) { testChannelStoreCreateDirectChannel(t, ss) })
|
||||||
@@ -49,6 +51,8 @@ func TestChannelStore(t *testing.T, ss store.Store) {
|
|||||||
t.Run("AnalyticsDeletedTypeCount", func(t *testing.T) { testChannelStoreAnalyticsDeletedTypeCount(t, ss) })
|
t.Run("AnalyticsDeletedTypeCount", func(t *testing.T) { testChannelStoreAnalyticsDeletedTypeCount(t, ss) })
|
||||||
t.Run("GetPinnedPosts", func(t *testing.T) { testChannelStoreGetPinnedPosts(t, ss) })
|
t.Run("GetPinnedPosts", func(t *testing.T) { testChannelStoreGetPinnedPosts(t, ss) })
|
||||||
t.Run("MaxChannelsPerTeam", func(t *testing.T) { testChannelStoreMaxChannelsPerTeam(t, ss) })
|
t.Run("MaxChannelsPerTeam", func(t *testing.T) { testChannelStoreMaxChannelsPerTeam(t, ss) })
|
||||||
|
t.Run("GetChannelsByScheme", func(t *testing.T) { testChannelStoreGetChannelsByScheme(t, ss) })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testChannelStoreSave(t *testing.T, ss store.Store) {
|
func testChannelStoreSave(t *testing.T, ss store.Store) {
|
||||||
@@ -2186,3 +2190,67 @@ func testChannelStoreMaxChannelsPerTeam(t *testing.T, ss store.Store) {
|
|||||||
result = <-ss.Channel().Save(channel, 1)
|
result = <-ss.Channel().Save(channel, 1)
|
||||||
assert.Nil(t, result.Err)
|
assert.Nil(t, result.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testChannelStoreGetChannelsByScheme(t *testing.T, ss store.Store) {
|
||||||
|
// Create some schemes.
|
||||||
|
s1 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_CHANNEL,
|
||||||
|
}
|
||||||
|
|
||||||
|
s2 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_CHANNEL,
|
||||||
|
}
|
||||||
|
|
||||||
|
s1 = (<-ss.Scheme().Save(s1)).Data.(*model.Scheme)
|
||||||
|
s2 = (<-ss.Scheme().Save(s2)).Data.(*model.Scheme)
|
||||||
|
|
||||||
|
// Create and save some teams.
|
||||||
|
c1 := &model.Channel{
|
||||||
|
TeamId: model.NewId(),
|
||||||
|
DisplayName: "Name",
|
||||||
|
Name: model.NewId(),
|
||||||
|
Type: model.CHANNEL_OPEN,
|
||||||
|
SchemeId: &s1.Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
c2 := &model.Channel{
|
||||||
|
TeamId: model.NewId(),
|
||||||
|
DisplayName: "Name",
|
||||||
|
Name: model.NewId(),
|
||||||
|
Type: model.CHANNEL_OPEN,
|
||||||
|
SchemeId: &s1.Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
c3 := &model.Channel{
|
||||||
|
TeamId: model.NewId(),
|
||||||
|
DisplayName: "Name",
|
||||||
|
Name: model.NewId(),
|
||||||
|
Type: model.CHANNEL_OPEN,
|
||||||
|
}
|
||||||
|
|
||||||
|
c1 = (<-ss.Channel().Save(c1, 100)).Data.(*model.Channel)
|
||||||
|
c2 = (<-ss.Channel().Save(c2, 100)).Data.(*model.Channel)
|
||||||
|
c3 = (<-ss.Channel().Save(c3, 100)).Data.(*model.Channel)
|
||||||
|
|
||||||
|
// Get the channels by a valid Scheme ID.
|
||||||
|
res1 := <-ss.Channel().GetChannelsByScheme(s1.Id, 0, 100)
|
||||||
|
assert.Nil(t, res1.Err)
|
||||||
|
d1 := res1.Data.([]*model.Channel)
|
||||||
|
assert.Len(t, d1, 2)
|
||||||
|
|
||||||
|
// Get the channels by a valid Scheme ID where there aren't any matching Channel.
|
||||||
|
res2 := <-ss.Channel().GetChannelsByScheme(s2.Id, 0, 100)
|
||||||
|
assert.Nil(t, res2.Err)
|
||||||
|
d2 := res2.Data.([]*model.Channel)
|
||||||
|
assert.Len(t, d2, 0)
|
||||||
|
|
||||||
|
// Get the channels by an invalid Scheme ID.
|
||||||
|
res3 := <-ss.Channel().GetChannelsByScheme(model.NewId(), 0, 100)
|
||||||
|
assert.Nil(t, res3.Err)
|
||||||
|
d3 := res3.Data.([]*model.Channel)
|
||||||
|
assert.Len(t, d3, 0)
|
||||||
|
}
|
||||||
|
|||||||
@@ -258,6 +258,22 @@ func (_m *ChannelStore) GetChannels(teamId string, userId string) store.StoreCha
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetChannelsByScheme provides a mock function with given fields: schemeId, offset, limit
|
||||||
|
func (_m *ChannelStore) GetChannelsByScheme(schemeId string, offset int, limit int) store.StoreChannel {
|
||||||
|
ret := _m.Called(schemeId, offset, limit)
|
||||||
|
|
||||||
|
var r0 store.StoreChannel
|
||||||
|
if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
|
||||||
|
r0 = rf(schemeId, offset, limit)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.StoreChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// GetDeleted provides a mock function with given fields: team_id, offset, limit
|
// GetDeleted provides a mock function with given fields: team_id, offset, limit
|
||||||
func (_m *ChannelStore) GetDeleted(team_id string, offset int, limit int) store.StoreChannel {
|
func (_m *ChannelStore) GetDeleted(team_id string, offset int, limit int) store.StoreChannel {
|
||||||
ret := _m.Called(team_id, offset, limit)
|
ret := _m.Called(team_id, offset, limit)
|
||||||
|
|||||||
@@ -432,6 +432,29 @@ func (_m *LayeredStoreDatabaseLayer) Role() store.RoleStore {
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RoleDelete provides a mock function with given fields: ctx, roldId, hints
|
||||||
|
func (_m *LayeredStoreDatabaseLayer) RoleDelete(ctx context.Context, roldId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, roldId)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, roldId, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// RoleGet provides a mock function with given fields: ctx, roleId, hints
|
// RoleGet provides a mock function with given fields: ctx, roleId, hints
|
||||||
func (_m *LayeredStoreDatabaseLayer) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
func (_m *LayeredStoreDatabaseLayer) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
_va := make([]interface{}, len(hints))
|
_va := make([]interface{}, len(hints))
|
||||||
@@ -547,6 +570,91 @@ func (_m *LayeredStoreDatabaseLayer) RoleSave(ctx context.Context, role *model.R
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scheme provides a mock function with given fields:
|
||||||
|
func (_m *LayeredStoreDatabaseLayer) Scheme() store.SchemeStore {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
var r0 store.SchemeStore
|
||||||
|
if rf, ok := ret.Get(0).(func() store.SchemeStore); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.SchemeStore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SchemeDelete provides a mock function with given fields: ctx, schemeId, hints
|
||||||
|
func (_m *LayeredStoreDatabaseLayer) SchemeDelete(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, schemeId)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, schemeId, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SchemeGet provides a mock function with given fields: ctx, schemeId, hints
|
||||||
|
func (_m *LayeredStoreDatabaseLayer) SchemeGet(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, schemeId)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, schemeId, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SchemeSave provides a mock function with given fields: ctx, scheme, hints
|
||||||
|
func (_m *LayeredStoreDatabaseLayer) SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, scheme)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *model.Scheme, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, scheme, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// Session provides a mock function with given fields:
|
// Session provides a mock function with given fields:
|
||||||
func (_m *LayeredStoreDatabaseLayer) Session() store.SessionStore {
|
func (_m *LayeredStoreDatabaseLayer) Session() store.SessionStore {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|||||||
@@ -145,6 +145,29 @@ func (_m *LayeredStoreSupplier) ReactionSave(ctx context.Context, reaction *mode
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RoleDelete provides a mock function with given fields: ctx, roldId, hints
|
||||||
|
func (_m *LayeredStoreSupplier) RoleDelete(ctx context.Context, roldId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, roldId)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, roldId, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// RoleGet provides a mock function with given fields: ctx, roleId, hints
|
// RoleGet provides a mock function with given fields: ctx, roleId, hints
|
||||||
func (_m *LayeredStoreSupplier) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
func (_m *LayeredStoreSupplier) RoleGet(ctx context.Context, roleId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
_va := make([]interface{}, len(hints))
|
_va := make([]interface{}, len(hints))
|
||||||
@@ -260,6 +283,75 @@ func (_m *LayeredStoreSupplier) RoleSave(ctx context.Context, role *model.Role,
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SchemeDelete provides a mock function with given fields: ctx, schemeId, hints
|
||||||
|
func (_m *LayeredStoreSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, schemeId)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, schemeId, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SchemeGet provides a mock function with given fields: ctx, schemeId, hints
|
||||||
|
func (_m *LayeredStoreSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, schemeId)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, schemeId, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SchemeSave provides a mock function with given fields: ctx, scheme, hints
|
||||||
|
func (_m *LayeredStoreSupplier) SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||||
|
_va := make([]interface{}, len(hints))
|
||||||
|
for _i := range hints {
|
||||||
|
_va[_i] = hints[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, scheme)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *store.LayeredStoreSupplierResult
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *model.Scheme, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||||
|
r0 = rf(ctx, scheme, hints...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// SetChainNext provides a mock function with given fields: _a0
|
// SetChainNext provides a mock function with given fields: _a0
|
||||||
func (_m *LayeredStoreSupplier) SetChainNext(_a0 store.LayeredStoreSupplier) {
|
func (_m *LayeredStoreSupplier) SetChainNext(_a0 store.LayeredStoreSupplier) {
|
||||||
_m.Called(_a0)
|
_m.Called(_a0)
|
||||||
|
|||||||
@@ -13,6 +13,22 @@ type RoleStore struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete provides a mock function with given fields: roldId
|
||||||
|
func (_m *RoleStore) Delete(roldId string) store.StoreChannel {
|
||||||
|
ret := _m.Called(roldId)
|
||||||
|
|
||||||
|
var r0 store.StoreChannel
|
||||||
|
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
|
||||||
|
r0 = rf(roldId)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.StoreChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// Get provides a mock function with given fields: roleId
|
// Get provides a mock function with given fields: roleId
|
||||||
func (_m *RoleStore) Get(roleId string) store.StoreChannel {
|
func (_m *RoleStore) Get(roleId string) store.StoreChannel {
|
||||||
ret := _m.Called(roleId)
|
ret := _m.Called(roleId)
|
||||||
|
|||||||
62
store/storetest/mocks/SchemeStore.go
Normal file
62
store/storetest/mocks/SchemeStore.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// Code generated by mockery v1.0.0
|
||||||
|
|
||||||
|
// Regenerate this file using `make store-mocks`.
|
||||||
|
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import mock "github.com/stretchr/testify/mock"
|
||||||
|
import model "github.com/mattermost/mattermost-server/model"
|
||||||
|
import store "github.com/mattermost/mattermost-server/store"
|
||||||
|
|
||||||
|
// SchemeStore is an autogenerated mock type for the SchemeStore type
|
||||||
|
type SchemeStore struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete provides a mock function with given fields: schemeId
|
||||||
|
func (_m *SchemeStore) Delete(schemeId string) store.StoreChannel {
|
||||||
|
ret := _m.Called(schemeId)
|
||||||
|
|
||||||
|
var r0 store.StoreChannel
|
||||||
|
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
|
||||||
|
r0 = rf(schemeId)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.StoreChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get provides a mock function with given fields: schemeId
|
||||||
|
func (_m *SchemeStore) Get(schemeId string) store.StoreChannel {
|
||||||
|
ret := _m.Called(schemeId)
|
||||||
|
|
||||||
|
var r0 store.StoreChannel
|
||||||
|
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
|
||||||
|
r0 = rf(schemeId)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.StoreChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save provides a mock function with given fields: scheme
|
||||||
|
func (_m *SchemeStore) Save(scheme *model.Scheme) store.StoreChannel {
|
||||||
|
ret := _m.Called(scheme)
|
||||||
|
|
||||||
|
var r0 store.StoreChannel
|
||||||
|
if rf, ok := ret.Get(0).(func(*model.Scheme) store.StoreChannel); ok {
|
||||||
|
r0 = rf(scheme)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.StoreChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
@@ -554,6 +554,22 @@ func (_m *SqlStore) Role() store.RoleStore {
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scheme provides a mock function with given fields:
|
||||||
|
func (_m *SqlStore) Scheme() store.SchemeStore {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
var r0 store.SchemeStore
|
||||||
|
if rf, ok := ret.Get(0).(func() store.SchemeStore); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.SchemeStore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// Session provides a mock function with given fields:
|
// Session provides a mock function with given fields:
|
||||||
func (_m *SqlStore) Session() store.SessionStore {
|
func (_m *SqlStore) Session() store.SessionStore {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|||||||
@@ -299,6 +299,22 @@ func (_m *Store) Role() store.RoleStore {
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scheme provides a mock function with given fields:
|
||||||
|
func (_m *Store) Scheme() store.SchemeStore {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
var r0 store.SchemeStore
|
||||||
|
if rf, ok := ret.Get(0).(func() store.SchemeStore); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.SchemeStore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// Session provides a mock function with given fields:
|
// Session provides a mock function with given fields:
|
||||||
func (_m *Store) Session() store.SessionStore {
|
func (_m *Store) Session() store.SessionStore {
|
||||||
ret := _m.Called()
|
ret := _m.Called()
|
||||||
|
|||||||
@@ -237,6 +237,22 @@ func (_m *TeamStore) GetMembersByIds(teamId string, userIds []string) store.Stor
|
|||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTeamsByScheme provides a mock function with given fields: schemeId, offset, limit
|
||||||
|
func (_m *TeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) store.StoreChannel {
|
||||||
|
ret := _m.Called(schemeId, offset, limit)
|
||||||
|
|
||||||
|
var r0 store.StoreChannel
|
||||||
|
if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
|
||||||
|
r0 = rf(schemeId, offset, limit)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(store.StoreChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
// GetTeamsByUserId provides a mock function with given fields: userId
|
// GetTeamsByUserId provides a mock function with given fields: userId
|
||||||
func (_m *TeamStore) GetTeamsByUserId(userId string) store.StoreChannel {
|
func (_m *TeamStore) GetTeamsByUserId(userId string) store.StoreChannel {
|
||||||
ret := _m.Called(userId)
|
ret := _m.Called(userId)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func TestRoleStore(t *testing.T, ss store.Store) {
|
|||||||
t.Run("Get", func(t *testing.T) { testRoleStoreGet(t, ss) })
|
t.Run("Get", func(t *testing.T) { testRoleStoreGet(t, ss) })
|
||||||
t.Run("GetByName", func(t *testing.T) { testRoleStoreGetByName(t, ss) })
|
t.Run("GetByName", func(t *testing.T) { testRoleStoreGetByName(t, ss) })
|
||||||
t.Run("GetNames", func(t *testing.T) { testRoleStoreGetByNames(t, ss) })
|
t.Run("GetNames", func(t *testing.T) { testRoleStoreGetByNames(t, ss) })
|
||||||
|
t.Run("Delete", func(t *testing.T) { testRoleStoreDelete(t, ss) })
|
||||||
t.Run("PermanentDeleteAll", func(t *testing.T) { testRoleStorePermanentDeleteAll(t, ss) })
|
t.Run("PermanentDeleteAll", func(t *testing.T) { testRoleStorePermanentDeleteAll(t, ss) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +245,49 @@ func testRoleStoreGetByNames(t *testing.T, ss store.Store) {
|
|||||||
assert.NotContains(t, roles6, d3)
|
assert.NotContains(t, roles6, d3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testRoleStoreDelete(t *testing.T, ss store.Store) {
|
||||||
|
// Save a role to test with.
|
||||||
|
r1 := &model.Role{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Permissions: []string{
|
||||||
|
"invite_user",
|
||||||
|
"create_public_channel",
|
||||||
|
"add_user_to_team",
|
||||||
|
},
|
||||||
|
SchemeManaged: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
res1 := <-ss.Role().Save(r1)
|
||||||
|
assert.Nil(t, res1.Err)
|
||||||
|
d1 := res1.Data.(*model.Role)
|
||||||
|
assert.Len(t, d1.Id, 26)
|
||||||
|
|
||||||
|
// Check the role is there.
|
||||||
|
res2 := <-ss.Role().Get(d1.Id)
|
||||||
|
assert.Nil(t, res2.Err)
|
||||||
|
|
||||||
|
// Delete the role.
|
||||||
|
res3 := <-ss.Role().Delete(d1.Id)
|
||||||
|
assert.Nil(t, res3.Err)
|
||||||
|
|
||||||
|
// Check the role is deleted there.
|
||||||
|
res4 := <-ss.Role().Get(d1.Id)
|
||||||
|
assert.Nil(t, res4.Err)
|
||||||
|
d2 := res4.Data.(*model.Role)
|
||||||
|
assert.NotZero(t, d2.DeleteAt)
|
||||||
|
|
||||||
|
res5 := <-ss.Role().GetByName(d1.Name)
|
||||||
|
assert.Nil(t, res5.Err)
|
||||||
|
d3 := res5.Data.(*model.Role)
|
||||||
|
assert.NotZero(t, d3.DeleteAt)
|
||||||
|
|
||||||
|
// Try and delete a role that does not exist.
|
||||||
|
res6 := <-ss.Role().Delete(model.NewId())
|
||||||
|
assert.NotNil(t, res6.Err)
|
||||||
|
}
|
||||||
|
|
||||||
func testRoleStorePermanentDeleteAll(t *testing.T, ss store.Store) {
|
func testRoleStorePermanentDeleteAll(t *testing.T, ss store.Store) {
|
||||||
r1 := &model.Role{
|
r1 := &model.Role{
|
||||||
Name: model.NewId(),
|
Name: model.NewId(),
|
||||||
@@ -256,6 +300,7 @@ func testRoleStorePermanentDeleteAll(t *testing.T, ss store.Store) {
|
|||||||
},
|
},
|
||||||
SchemeManaged: false,
|
SchemeManaged: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
r2 := &model.Role{
|
r2 := &model.Role{
|
||||||
Name: model.NewId(),
|
Name: model.NewId(),
|
||||||
DisplayName: model.NewId(),
|
DisplayName: model.NewId(),
|
||||||
|
|||||||
303
store/storetest/scheme_store.go
Normal file
303
store/storetest/scheme_store.go
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package storetest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/mattermost/mattermost-server/model"
|
||||||
|
"github.com/mattermost/mattermost-server/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSchemeStore(t *testing.T, ss store.Store) {
|
||||||
|
createDefaultRoles(t, ss)
|
||||||
|
|
||||||
|
t.Run("Save", func(t *testing.T) { testSchemeStoreSave(t, ss) })
|
||||||
|
t.Run("Get", func(t *testing.T) { testSchemeStoreGet(t, ss) })
|
||||||
|
t.Run("Delete", func(t *testing.T) { testSchemeStoreDelete(t, ss) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDefaultRoles(t *testing.T, ss store.Store) {
|
||||||
|
<-ss.Role().Save(&model.Role{
|
||||||
|
Name: model.TEAM_ADMIN_ROLE_ID,
|
||||||
|
DisplayName: model.TEAM_ADMIN_ROLE_ID,
|
||||||
|
Permissions: []string{
|
||||||
|
model.PERMISSION_EDIT_OTHERS_POSTS.Id,
|
||||||
|
model.PERMISSION_DELETE_OTHERS_POSTS.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
<-ss.Role().Save(&model.Role{
|
||||||
|
Name: model.TEAM_USER_ROLE_ID,
|
||||||
|
DisplayName: model.TEAM_USER_ROLE_ID,
|
||||||
|
Permissions: []string{
|
||||||
|
model.PERMISSION_VIEW_TEAM.Id,
|
||||||
|
model.PERMISSION_ADD_USER_TO_TEAM.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
<-ss.Role().Save(&model.Role{
|
||||||
|
Name: model.CHANNEL_ADMIN_ROLE_ID,
|
||||||
|
DisplayName: model.CHANNEL_ADMIN_ROLE_ID,
|
||||||
|
Permissions: []string{
|
||||||
|
model.PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id,
|
||||||
|
model.PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
<-ss.Role().Save(&model.Role{
|
||||||
|
Name: model.CHANNEL_USER_ROLE_ID,
|
||||||
|
DisplayName: model.CHANNEL_USER_ROLE_ID,
|
||||||
|
Permissions: []string{
|
||||||
|
model.PERMISSION_READ_CHANNEL.Id,
|
||||||
|
model.PERMISSION_CREATE_POST.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSchemeStoreSave(t *testing.T, ss store.Store) {
|
||||||
|
// Save a new scheme.
|
||||||
|
s1 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_TEAM,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check all fields saved correctly.
|
||||||
|
res1 := <-ss.Scheme().Save(s1)
|
||||||
|
assert.Nil(t, res1.Err)
|
||||||
|
d1 := res1.Data.(*model.Scheme)
|
||||||
|
assert.Len(t, d1.Id, 26)
|
||||||
|
assert.Equal(t, s1.Name, d1.Name)
|
||||||
|
assert.Equal(t, s1.Description, d1.Description)
|
||||||
|
assert.NotZero(t, d1.CreateAt)
|
||||||
|
assert.NotZero(t, d1.UpdateAt)
|
||||||
|
assert.Zero(t, d1.DeleteAt)
|
||||||
|
assert.Equal(t, s1.Scope, d1.Scope)
|
||||||
|
assert.Len(t, d1.DefaultTeamAdminRole, 26)
|
||||||
|
assert.Len(t, d1.DefaultTeamUserRole, 26)
|
||||||
|
assert.Len(t, d1.DefaultChannelAdminRole, 26)
|
||||||
|
assert.Len(t, d1.DefaultChannelUserRole, 26)
|
||||||
|
|
||||||
|
// Check the default roles were created correctly.
|
||||||
|
roleRes1 := <-ss.Role().Get(d1.DefaultTeamAdminRole)
|
||||||
|
assert.Nil(t, roleRes1.Err)
|
||||||
|
role1 := roleRes1.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role1.Permissions, []string{"edit_others_posts", "delete_others_posts"})
|
||||||
|
assert.True(t, role1.SchemeManaged)
|
||||||
|
|
||||||
|
roleRes2 := <-ss.Role().Get(d1.DefaultTeamUserRole)
|
||||||
|
assert.Nil(t, roleRes2.Err)
|
||||||
|
role2 := roleRes2.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role2.Permissions, []string{"view_team", "add_user_to_team"})
|
||||||
|
assert.True(t, role2.SchemeManaged)
|
||||||
|
|
||||||
|
roleRes3 := <-ss.Role().Get(d1.DefaultChannelAdminRole)
|
||||||
|
assert.Nil(t, roleRes3.Err)
|
||||||
|
role3 := roleRes3.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role3.Permissions, []string{"manage_public_channel_members", "manage_private_channel_members"})
|
||||||
|
assert.True(t, role3.SchemeManaged)
|
||||||
|
|
||||||
|
roleRes4 := <-ss.Role().Get(d1.DefaultChannelUserRole)
|
||||||
|
assert.Nil(t, roleRes4.Err)
|
||||||
|
role4 := roleRes4.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role4.Permissions, []string{"read_channel", "create_post"})
|
||||||
|
assert.True(t, role4.SchemeManaged)
|
||||||
|
|
||||||
|
// Change the scheme description and update.
|
||||||
|
d1.Description = model.NewId()
|
||||||
|
|
||||||
|
res2 := <-ss.Scheme().Save(d1)
|
||||||
|
assert.Nil(t, res2.Err)
|
||||||
|
d2 := res2.Data.(*model.Scheme)
|
||||||
|
assert.Equal(t, d1.Id, d2.Id)
|
||||||
|
assert.Equal(t, s1.Name, d2.Name)
|
||||||
|
assert.Equal(t, d1.Description, d2.Description)
|
||||||
|
assert.NotZero(t, d2.CreateAt)
|
||||||
|
assert.NotZero(t, d2.UpdateAt)
|
||||||
|
assert.Zero(t, d2.DeleteAt)
|
||||||
|
assert.Equal(t, s1.Scope, d2.Scope)
|
||||||
|
assert.Equal(t, d1.DefaultTeamAdminRole, d2.DefaultTeamAdminRole)
|
||||||
|
assert.Equal(t, d1.DefaultTeamUserRole, d2.DefaultTeamUserRole)
|
||||||
|
assert.Equal(t, d1.DefaultChannelAdminRole, d2.DefaultChannelAdminRole)
|
||||||
|
assert.Equal(t, d1.DefaultChannelUserRole, d2.DefaultChannelUserRole)
|
||||||
|
|
||||||
|
// Try saving one with an invalid ID set.
|
||||||
|
s3 := &model.Scheme{
|
||||||
|
Id: model.NewId(),
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_TEAM,
|
||||||
|
}
|
||||||
|
|
||||||
|
res3 := <-ss.Scheme().Save(s3)
|
||||||
|
assert.NotNil(t, res3.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSchemeStoreGet(t *testing.T, ss store.Store) {
|
||||||
|
// Save a scheme to test with.
|
||||||
|
s1 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_TEAM,
|
||||||
|
}
|
||||||
|
|
||||||
|
res1 := <-ss.Scheme().Save(s1)
|
||||||
|
assert.Nil(t, res1.Err)
|
||||||
|
d1 := res1.Data.(*model.Scheme)
|
||||||
|
assert.Len(t, d1.Id, 26)
|
||||||
|
|
||||||
|
// Get a valid scheme
|
||||||
|
res2 := <-ss.Scheme().Get(d1.Id)
|
||||||
|
assert.Nil(t, res2.Err)
|
||||||
|
d2 := res1.Data.(*model.Scheme)
|
||||||
|
assert.Equal(t, d1.Id, d2.Id)
|
||||||
|
assert.Equal(t, s1.Name, d2.Name)
|
||||||
|
assert.Equal(t, d1.Description, d2.Description)
|
||||||
|
assert.NotZero(t, d2.CreateAt)
|
||||||
|
assert.NotZero(t, d2.UpdateAt)
|
||||||
|
assert.Zero(t, d2.DeleteAt)
|
||||||
|
assert.Equal(t, s1.Scope, d2.Scope)
|
||||||
|
assert.Equal(t, d1.DefaultTeamAdminRole, d2.DefaultTeamAdminRole)
|
||||||
|
assert.Equal(t, d1.DefaultTeamUserRole, d2.DefaultTeamUserRole)
|
||||||
|
assert.Equal(t, d1.DefaultChannelAdminRole, d2.DefaultChannelAdminRole)
|
||||||
|
assert.Equal(t, d1.DefaultChannelUserRole, d2.DefaultChannelUserRole)
|
||||||
|
|
||||||
|
// Get an invalid scheme
|
||||||
|
res3 := <-ss.Scheme().Get(model.NewId())
|
||||||
|
assert.NotNil(t, res3.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSchemeStoreDelete(t *testing.T, ss store.Store) {
|
||||||
|
// Save a new scheme.
|
||||||
|
s1 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_TEAM,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check all fields saved correctly.
|
||||||
|
res1 := <-ss.Scheme().Save(s1)
|
||||||
|
assert.Nil(t, res1.Err)
|
||||||
|
d1 := res1.Data.(*model.Scheme)
|
||||||
|
assert.Len(t, d1.Id, 26)
|
||||||
|
assert.Equal(t, s1.Name, d1.Name)
|
||||||
|
assert.Equal(t, s1.Description, d1.Description)
|
||||||
|
assert.NotZero(t, d1.CreateAt)
|
||||||
|
assert.NotZero(t, d1.UpdateAt)
|
||||||
|
assert.Zero(t, d1.DeleteAt)
|
||||||
|
assert.Equal(t, s1.Scope, d1.Scope)
|
||||||
|
assert.Len(t, d1.DefaultTeamAdminRole, 26)
|
||||||
|
assert.Len(t, d1.DefaultTeamUserRole, 26)
|
||||||
|
assert.Len(t, d1.DefaultChannelAdminRole, 26)
|
||||||
|
assert.Len(t, d1.DefaultChannelUserRole, 26)
|
||||||
|
|
||||||
|
// Check the default roles were created correctly.
|
||||||
|
roleRes1 := <-ss.Role().Get(d1.DefaultTeamAdminRole)
|
||||||
|
assert.Nil(t, roleRes1.Err)
|
||||||
|
role1 := roleRes1.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role1.Permissions, []string{"edit_others_posts", "delete_others_posts"})
|
||||||
|
assert.True(t, role1.SchemeManaged)
|
||||||
|
|
||||||
|
roleRes2 := <-ss.Role().Get(d1.DefaultTeamUserRole)
|
||||||
|
assert.Nil(t, roleRes2.Err)
|
||||||
|
role2 := roleRes2.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role2.Permissions, []string{"view_team", "add_user_to_team"})
|
||||||
|
assert.True(t, role2.SchemeManaged)
|
||||||
|
|
||||||
|
roleRes3 := <-ss.Role().Get(d1.DefaultChannelAdminRole)
|
||||||
|
assert.Nil(t, roleRes3.Err)
|
||||||
|
role3 := roleRes3.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role3.Permissions, []string{"manage_public_channel_members", "manage_private_channel_members"})
|
||||||
|
assert.True(t, role3.SchemeManaged)
|
||||||
|
|
||||||
|
roleRes4 := <-ss.Role().Get(d1.DefaultChannelUserRole)
|
||||||
|
assert.Nil(t, roleRes4.Err)
|
||||||
|
role4 := roleRes4.Data.(*model.Role)
|
||||||
|
assert.Equal(t, role4.Permissions, []string{"read_channel", "create_post"})
|
||||||
|
assert.True(t, role4.SchemeManaged)
|
||||||
|
|
||||||
|
// Delete the scheme.
|
||||||
|
res2 := <-ss.Scheme().Delete(d1.Id)
|
||||||
|
if !assert.Nil(t, res2.Err) {
|
||||||
|
t.Fatal(res2.Err)
|
||||||
|
}
|
||||||
|
d2 := res2.Data.(*model.Scheme)
|
||||||
|
assert.NotZero(t, d2.DeleteAt)
|
||||||
|
|
||||||
|
// Check that the roles are deleted too.
|
||||||
|
roleRes5 := <-ss.Role().Get(d1.DefaultTeamAdminRole)
|
||||||
|
assert.Nil(t, roleRes5.Err)
|
||||||
|
role5 := roleRes5.Data.(*model.Role)
|
||||||
|
assert.NotZero(t, role5.DeleteAt)
|
||||||
|
|
||||||
|
roleRes6 := <-ss.Role().Get(d1.DefaultTeamUserRole)
|
||||||
|
assert.Nil(t, roleRes6.Err)
|
||||||
|
role6 := roleRes6.Data.(*model.Role)
|
||||||
|
assert.NotZero(t, role6.DeleteAt)
|
||||||
|
|
||||||
|
roleRes7 := <-ss.Role().Get(d1.DefaultChannelAdminRole)
|
||||||
|
assert.Nil(t, roleRes7.Err)
|
||||||
|
role7 := roleRes7.Data.(*model.Role)
|
||||||
|
assert.NotZero(t, role7.DeleteAt)
|
||||||
|
|
||||||
|
roleRes8 := <-ss.Role().Get(d1.DefaultChannelUserRole)
|
||||||
|
assert.Nil(t, roleRes8.Err)
|
||||||
|
role8 := roleRes8.Data.(*model.Role)
|
||||||
|
assert.NotZero(t, role8.DeleteAt)
|
||||||
|
|
||||||
|
// Try deleting a scheme that does not exist.
|
||||||
|
res3 := <-ss.Scheme().Delete(model.NewId())
|
||||||
|
assert.NotNil(t, res3.Err)
|
||||||
|
|
||||||
|
// Try deleting a team scheme that's in use.
|
||||||
|
s4 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_TEAM,
|
||||||
|
}
|
||||||
|
res4 := <-ss.Scheme().Save(s4)
|
||||||
|
assert.Nil(t, res4.Err)
|
||||||
|
d4 := res4.Data.(*model.Scheme)
|
||||||
|
|
||||||
|
t4 := &model.Team{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: model.NewId(),
|
||||||
|
Email: model.NewId() + "@nowhere.com",
|
||||||
|
Type: model.TEAM_OPEN,
|
||||||
|
SchemeId: &d4.Id,
|
||||||
|
}
|
||||||
|
tres4 := <-ss.Team().Save(t4)
|
||||||
|
assert.Nil(t, tres4.Err)
|
||||||
|
t4 = tres4.Data.(*model.Team)
|
||||||
|
|
||||||
|
sres4 := <-ss.Scheme().Delete(d4.Id)
|
||||||
|
assert.NotNil(t, sres4.Err)
|
||||||
|
|
||||||
|
// Try deleting a channel scheme that's in use.
|
||||||
|
s5 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_CHANNEL,
|
||||||
|
}
|
||||||
|
res5 := <-ss.Scheme().Save(s5)
|
||||||
|
assert.Nil(t, res5.Err)
|
||||||
|
d5 := res5.Data.(*model.Scheme)
|
||||||
|
|
||||||
|
c5 := &model.Channel{
|
||||||
|
TeamId: model.NewId(),
|
||||||
|
DisplayName: model.NewId(),
|
||||||
|
Name: model.NewId(),
|
||||||
|
Type: model.CHANNEL_OPEN,
|
||||||
|
SchemeId: &d5.Id,
|
||||||
|
}
|
||||||
|
cres5 := <-ss.Channel().Save(c5, -1)
|
||||||
|
assert.Nil(t, cres5.Err)
|
||||||
|
c5 = cres5.Data.(*model.Channel)
|
||||||
|
|
||||||
|
sres5 := <-ss.Scheme().Delete(d5.Id)
|
||||||
|
assert.NotNil(t, sres5.Err)
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@ type Store struct {
|
|||||||
PluginStore mocks.PluginStore
|
PluginStore mocks.PluginStore
|
||||||
ChannelMemberHistoryStore mocks.ChannelMemberHistoryStore
|
ChannelMemberHistoryStore mocks.ChannelMemberHistoryStore
|
||||||
RoleStore mocks.RoleStore
|
RoleStore mocks.RoleStore
|
||||||
|
SchemeStore mocks.SchemeStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) Team() store.TeamStore { return &s.TeamStore }
|
func (s *Store) Team() store.TeamStore { return &s.TeamStore }
|
||||||
@@ -70,6 +71,7 @@ func (s *Store) Job() store.JobStore { return &s.JobSt
|
|||||||
func (s *Store) UserAccessToken() store.UserAccessTokenStore { return &s.UserAccessTokenStore }
|
func (s *Store) UserAccessToken() store.UserAccessTokenStore { return &s.UserAccessTokenStore }
|
||||||
func (s *Store) Plugin() store.PluginStore { return &s.PluginStore }
|
func (s *Store) Plugin() store.PluginStore { return &s.PluginStore }
|
||||||
func (s *Store) Role() store.RoleStore { return &s.RoleStore }
|
func (s *Store) Role() store.RoleStore { return &s.RoleStore }
|
||||||
|
func (s *Store) Scheme() store.SchemeStore { return &s.SchemeStore }
|
||||||
func (s *Store) ChannelMemberHistory() store.ChannelMemberHistoryStore {
|
func (s *Store) ChannelMemberHistory() store.ChannelMemberHistoryStore {
|
||||||
return &s.ChannelMemberHistoryStore
|
return &s.ChannelMemberHistoryStore
|
||||||
}
|
}
|
||||||
@@ -107,5 +109,6 @@ func (s *Store) AssertExpectations(t mock.TestingT) bool {
|
|||||||
&s.ChannelMemberHistoryStore,
|
&s.ChannelMemberHistoryStore,
|
||||||
&s.PluginStore,
|
&s.PluginStore,
|
||||||
&s.RoleStore,
|
&s.RoleStore,
|
||||||
|
&s.SchemeStore,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,15 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/mattermost/mattermost-server/store"
|
"github.com/mattermost/mattermost-server/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTeamStore(t *testing.T, ss store.Store) {
|
func TestTeamStore(t *testing.T, ss store.Store) {
|
||||||
|
createDefaultRoles(t, ss)
|
||||||
|
|
||||||
t.Run("Save", func(t *testing.T) { testTeamStoreSave(t, ss) })
|
t.Run("Save", func(t *testing.T) { testTeamStoreSave(t, ss) })
|
||||||
t.Run("Update", func(t *testing.T) { testTeamStoreUpdate(t, ss) })
|
t.Run("Update", func(t *testing.T) { testTeamStoreUpdate(t, ss) })
|
||||||
t.Run("UpdateDisplayName", func(t *testing.T) { testTeamStoreUpdateDisplayName(t, ss) })
|
t.Run("UpdateDisplayName", func(t *testing.T) { testTeamStoreUpdateDisplayName(t, ss) })
|
||||||
@@ -34,6 +38,7 @@ func TestTeamStore(t *testing.T, ss store.Store) {
|
|||||||
t.Run("GetChannelUnreadsForAllTeams", func(t *testing.T) { testGetChannelUnreadsForAllTeams(t, ss) })
|
t.Run("GetChannelUnreadsForAllTeams", func(t *testing.T) { testGetChannelUnreadsForAllTeams(t, ss) })
|
||||||
t.Run("GetChannelUnreadsForTeam", func(t *testing.T) { testGetChannelUnreadsForTeam(t, ss) })
|
t.Run("GetChannelUnreadsForTeam", func(t *testing.T) { testGetChannelUnreadsForTeam(t, ss) })
|
||||||
t.Run("UpdateLastTeamIconUpdate", func(t *testing.T) { testUpdateLastTeamIconUpdate(t, ss) })
|
t.Run("UpdateLastTeamIconUpdate", func(t *testing.T) { testUpdateLastTeamIconUpdate(t, ss) })
|
||||||
|
t.Run("GetTeamsByScheme", func(t *testing.T) { testGetTeamsByScheme(t, ss) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTeamStoreSave(t *testing.T, ss store.Store) {
|
func testTeamStoreSave(t *testing.T, ss store.Store) {
|
||||||
@@ -1029,3 +1034,67 @@ func testUpdateLastTeamIconUpdate(t *testing.T, ss store.Store) {
|
|||||||
t.Fatal("LastTeamIconUpdate not updated")
|
t.Fatal("LastTeamIconUpdate not updated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testGetTeamsByScheme(t *testing.T, ss store.Store) {
|
||||||
|
// Create some schemes.
|
||||||
|
s1 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_TEAM,
|
||||||
|
}
|
||||||
|
|
||||||
|
s2 := &model.Scheme{
|
||||||
|
Name: model.NewId(),
|
||||||
|
Description: model.NewId(),
|
||||||
|
Scope: model.SCHEME_SCOPE_TEAM,
|
||||||
|
}
|
||||||
|
|
||||||
|
s1 = (<-ss.Scheme().Save(s1)).Data.(*model.Scheme)
|
||||||
|
s2 = (<-ss.Scheme().Save(s2)).Data.(*model.Scheme)
|
||||||
|
|
||||||
|
// Create and save some teams.
|
||||||
|
t1 := &model.Team{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: model.NewId(),
|
||||||
|
Email: model.NewId() + "@nowhere.com",
|
||||||
|
Type: model.TEAM_OPEN,
|
||||||
|
SchemeId: &s1.Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
t2 := &model.Team{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: model.NewId(),
|
||||||
|
Email: model.NewId() + "@nowhere.com",
|
||||||
|
Type: model.TEAM_OPEN,
|
||||||
|
SchemeId: &s1.Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
t3 := &model.Team{
|
||||||
|
Name: model.NewId(),
|
||||||
|
DisplayName: model.NewId(),
|
||||||
|
Email: model.NewId() + "@nowhere.com",
|
||||||
|
Type: model.TEAM_OPEN,
|
||||||
|
}
|
||||||
|
|
||||||
|
t1 = (<-ss.Team().Save(t1)).Data.(*model.Team)
|
||||||
|
t2 = (<-ss.Team().Save(t2)).Data.(*model.Team)
|
||||||
|
t3 = (<-ss.Team().Save(t3)).Data.(*model.Team)
|
||||||
|
|
||||||
|
// Get the teams by a valid Scheme ID.
|
||||||
|
res1 := <-ss.Team().GetTeamsByScheme(s1.Id, 0, 100)
|
||||||
|
assert.Nil(t, res1.Err)
|
||||||
|
d1 := res1.Data.([]*model.Team)
|
||||||
|
assert.Len(t, d1, 2)
|
||||||
|
|
||||||
|
// Get the teams by a valid Scheme ID where there aren't any matching Teams.
|
||||||
|
res2 := <-ss.Team().GetTeamsByScheme(s2.Id, 0, 100)
|
||||||
|
assert.Nil(t, res2.Err)
|
||||||
|
d2 := res2.Data.([]*model.Team)
|
||||||
|
assert.Len(t, d2, 0)
|
||||||
|
|
||||||
|
// Get the teams by an invalid Scheme ID.
|
||||||
|
res3 := <-ss.Team().GetTeamsByScheme(model.NewId(), 0, 100)
|
||||||
|
assert.Nil(t, res3.Err)
|
||||||
|
d3 := res3.Data.([]*model.Team)
|
||||||
|
assert.Len(t, d3, 0)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user