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.
Этот коммит содержится в:
коммит произвёл
Martin Kraft
родитель
853445dc2e
Коммит
cd55c44c8f
@@ -4,11 +4,378 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/store/storetest"
|
||||
)
|
||||
|
||||
func TestTeamStore(t *testing.T) {
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user