MM-10121: CLI command to reset permissions system to default state. (#8637)
* MM-10121: CLI command to reset permissions system to default state. * Review comment.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
a1882d4004
Коммит
b13a228b04
@@ -252,3 +252,9 @@ func (s *LayeredRoleStore) GetByNames(names []string) StoreChannel {
|
||||
return supplier.RoleGetByNames(s.TmpContext, names)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *LayeredRoleStore) PermanentDeleteAll() StoreChannel {
|
||||
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
|
||||
return supplier.RolePermanentDeleteAll(s.TmpContext)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -35,4 +35,5 @@ type LayeredStoreSupplier interface {
|
||||
RoleGet(ctx context.Context, roleId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||
RoleGetByName(ctx context.Context, name string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||
RoleGetByNames(ctx context.Context, names []string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||
RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
|
||||
}
|
||||
|
||||
@@ -68,3 +68,10 @@ func (s *LocalCacheSupplier) RoleGetByNames(ctx context.Context, roleNames []str
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *LocalCacheSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||
defer s.roleCache.Purge()
|
||||
defer s.doClearCacheCluster(s.roleCache)
|
||||
|
||||
return s.Next().RolePermanentDeleteAll(ctx, hints...)
|
||||
}
|
||||
|
||||
@@ -84,6 +84,20 @@ func (s *RedisSupplier) RoleGetByNames(ctx context.Context, roleNames []string,
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *RedisSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
|
||||
defer func() {
|
||||
if keys, err := s.client.Keys("roles:*").Result(); err != nil {
|
||||
l4g.Error("Redis encountered an error on read: " + err.Error())
|
||||
} else {
|
||||
if err := s.client.Del(keys...).Err(); err != nil {
|
||||
l4g.Error("Redis encountered an error on delete: " + err.Error())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return s.Next().RolePermanentDeleteAll(ctx, hints...)
|
||||
}
|
||||
|
||||
func buildRedisKeyForRoleName(roleName string) string {
|
||||
return fmt.Sprintf("roles:%s", roleName)
|
||||
}
|
||||
|
||||
@@ -174,3 +174,13 @@ func (s *SqlSupplier) RoleGetByNames(ctx context.Context, names []string, hints
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *SqlSupplier) RolePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||
result := store.NewSupplierResult()
|
||||
|
||||
if _, err := s.GetMaster().Exec("DELETE FROM Roles"); err != nil {
|
||||
result.Err = model.NewAppError("SqlRoleStore.PermanentDeleteAll", "store.sql_role.permanent_delete_all.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -85,3 +85,14 @@ func (s SqlSystemStore) GetByName(name string) store.StoreChannel {
|
||||
result.Data = &system
|
||||
})
|
||||
}
|
||||
|
||||
func (s SqlSystemStore) PermanentDeleteByName(name string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
var system model.System
|
||||
if _, err := s.GetReplica().Exec("DELETE FROM Systems WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil {
|
||||
result.Err = model.NewAppError("SqlSystemStore.PermanentDeleteByName", "store.sql_system.permanent_delete_by_name.app_error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
result.Data = &system
|
||||
})
|
||||
}
|
||||
|
||||
@@ -322,6 +322,7 @@ type SystemStore interface {
|
||||
Update(system *model.System) StoreChannel
|
||||
Get() StoreChannel
|
||||
GetByName(name string) StoreChannel
|
||||
PermanentDeleteByName(name string) StoreChannel
|
||||
}
|
||||
|
||||
type WebhookStore interface {
|
||||
@@ -476,4 +477,5 @@ type RoleStore interface {
|
||||
Get(roleId string) StoreChannel
|
||||
GetByName(name string) StoreChannel
|
||||
GetByNames(names []string) StoreChannel
|
||||
PermanentDeleteAll() StoreChannel
|
||||
}
|
||||
|
||||
@@ -501,6 +501,29 @@ func (_m *LayeredStoreDatabaseLayer) RoleGetByNames(ctx context.Context, names [
|
||||
return r0
|
||||
}
|
||||
|
||||
// RolePermanentDeleteAll provides a mock function with given fields: ctx, hints
|
||||
func (_m *LayeredStoreDatabaseLayer) RolePermanentDeleteAll(ctx context.Context, 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)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *store.LayeredStoreSupplierResult
|
||||
if rf, ok := ret.Get(0).(func(context.Context, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||
r0 = rf(ctx, hints...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// RoleSave provides a mock function with given fields: ctx, role, hints
|
||||
func (_m *LayeredStoreDatabaseLayer) RoleSave(ctx context.Context, role *model.Role, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||
_va := make([]interface{}, len(hints))
|
||||
|
||||
@@ -214,6 +214,29 @@ func (_m *LayeredStoreSupplier) RoleGetByNames(ctx context.Context, names []stri
|
||||
return r0
|
||||
}
|
||||
|
||||
// RolePermanentDeleteAll provides a mock function with given fields: ctx, hints
|
||||
func (_m *LayeredStoreSupplier) RolePermanentDeleteAll(ctx context.Context, 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)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *store.LayeredStoreSupplierResult
|
||||
if rf, ok := ret.Get(0).(func(context.Context, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
|
||||
r0 = rf(ctx, hints...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// RoleSave provides a mock function with given fields: ctx, role, hints
|
||||
func (_m *LayeredStoreSupplier) RoleSave(ctx context.Context, role *model.Role, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
|
||||
_va := make([]interface{}, len(hints))
|
||||
|
||||
@@ -162,6 +162,22 @@ func (_m *PostStore) GetFlaggedPostsForTeam(userId string, teamId string, offset
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetMaxPostSize provides a mock function with given fields:
|
||||
func (_m *PostStore) GetMaxPostSize() store.StoreChannel {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func() store.StoreChannel); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetOldest provides a mock function with given fields:
|
||||
func (_m *PostStore) GetOldest() store.StoreChannel {
|
||||
ret := _m.Called()
|
||||
@@ -422,18 +438,3 @@ func (_m *PostStore) Update(newPost *model.Post, oldPost *model.Post) store.Stor
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
func (_m *PostStore) GetMaxPostSize() store.StoreChannel {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func() store.StoreChannel); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
@@ -61,6 +61,22 @@ func (_m *RoleStore) GetByNames(names []string) store.StoreChannel {
|
||||
return r0
|
||||
}
|
||||
|
||||
// PermanentDeleteAll provides a mock function with given fields:
|
||||
func (_m *RoleStore) PermanentDeleteAll() store.StoreChannel {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func() store.StoreChannel); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Save provides a mock function with given fields: role
|
||||
func (_m *RoleStore) Save(role *model.Role) store.StoreChannel {
|
||||
ret := _m.Called(role)
|
||||
|
||||
@@ -45,6 +45,22 @@ func (_m *SystemStore) GetByName(name string) store.StoreChannel {
|
||||
return r0
|
||||
}
|
||||
|
||||
// PermanentDeleteByName provides a mock function with given fields: name
|
||||
func (_m *SystemStore) PermanentDeleteByName(name string) store.StoreChannel {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Save provides a mock function with given fields: system
|
||||
func (_m *SystemStore) Save(system *model.System) store.StoreChannel {
|
||||
ret := _m.Called(system)
|
||||
|
||||
@@ -17,6 +17,7 @@ func TestRoleStore(t *testing.T, ss store.Store) {
|
||||
t.Run("Get", func(t *testing.T) { testRoleStoreGet(t, ss) })
|
||||
t.Run("GetByName", func(t *testing.T) { testRoleStoreGetByName(t, ss) })
|
||||
t.Run("GetNames", func(t *testing.T) { testRoleStoreGetByNames(t, ss) })
|
||||
t.Run("PermanentDeleteAll", func(t *testing.T) { testRoleStorePermanentDeleteAll(t, ss) })
|
||||
}
|
||||
|
||||
func testRoleStoreSave(t *testing.T, ss store.Store) {
|
||||
@@ -242,3 +243,42 @@ func testRoleStoreGetByNames(t *testing.T, ss store.Store) {
|
||||
assert.NotContains(t, roles6, d2)
|
||||
assert.NotContains(t, roles6, d3)
|
||||
}
|
||||
|
||||
func testRoleStorePermanentDeleteAll(t *testing.T, ss store.Store) {
|
||||
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,
|
||||
}
|
||||
r2 := &model.Role{
|
||||
Name: model.NewId(),
|
||||
DisplayName: model.NewId(),
|
||||
Description: model.NewId(),
|
||||
Permissions: []string{
|
||||
"read_channel",
|
||||
"create_public_channel",
|
||||
"add_user_to_team",
|
||||
},
|
||||
SchemeManaged: false,
|
||||
}
|
||||
|
||||
store.Must(ss.Role().Save(r1))
|
||||
store.Must(ss.Role().Save(r2))
|
||||
|
||||
res1 := <-ss.Role().GetByNames([]string{r1.Name, r2.Name})
|
||||
assert.Nil(t, res1.Err)
|
||||
assert.Len(t, res1.Data.([]*model.Role), 2)
|
||||
|
||||
res2 := <-ss.Role().PermanentDeleteAll()
|
||||
assert.Nil(t, res2.Err)
|
||||
|
||||
res3 := <-ss.Role().GetByNames([]string{r1.Name, r2.Name})
|
||||
assert.Nil(t, res3.Err)
|
||||
assert.Len(t, res3.Data.([]*model.Role), 0)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ package storetest
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/store"
|
||||
)
|
||||
@@ -13,6 +15,7 @@ import (
|
||||
func TestSystemStore(t *testing.T, ss store.Store) {
|
||||
t.Run("", func(t *testing.T) { testSystemStore(t, ss) })
|
||||
t.Run("SaveOrUpdate", func(t *testing.T) { testSystemStoreSaveOrUpdate(t, ss) })
|
||||
t.Run("PermanentDeleteByName", func(t *testing.T) { testSystemStorePermanentDeleteByName(t, ss) })
|
||||
}
|
||||
|
||||
func testSystemStore(t *testing.T, ss store.Store) {
|
||||
@@ -56,3 +59,36 @@ func testSystemStoreSaveOrUpdate(t *testing.T, ss store.Store) {
|
||||
t.Fatal(r.Err)
|
||||
}
|
||||
}
|
||||
|
||||
func testSystemStorePermanentDeleteByName(t *testing.T, ss store.Store) {
|
||||
s1 := &model.System{Name: model.NewId(), Value: "value"}
|
||||
s2 := &model.System{Name: model.NewId(), Value: "value"}
|
||||
|
||||
store.Must(ss.System().Save(s1))
|
||||
store.Must(ss.System().Save(s2))
|
||||
|
||||
res1 := <-ss.System().GetByName(s1.Name)
|
||||
assert.Nil(t, res1.Err)
|
||||
|
||||
res2 := <-ss.System().GetByName(s2.Name)
|
||||
assert.Nil(t, res2.Err)
|
||||
|
||||
res3 := <-ss.System().PermanentDeleteByName(s1.Name)
|
||||
assert.Nil(t, res3.Err)
|
||||
|
||||
res4 := <-ss.System().GetByName(s1.Name)
|
||||
assert.NotNil(t, res4.Err)
|
||||
|
||||
res5 := <-ss.System().GetByName(s2.Name)
|
||||
assert.Nil(t, res5.Err)
|
||||
|
||||
res6 := <-ss.System().PermanentDeleteByName(s2.Name)
|
||||
assert.Nil(t, res6.Err)
|
||||
|
||||
res7 := <-ss.System().GetByName(s1.Name)
|
||||
assert.NotNil(t, res7.Err)
|
||||
|
||||
res8 := <-ss.System().GetByName(s2.Name)
|
||||
assert.NotNil(t, res8.Err)
|
||||
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user