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.
Этот коммит содержится в:
George Goldberg
2018-04-18 10:18:07 +01:00
коммит произвёл GitHub
родитель a1882d4004
Коммит b13a228b04
17 изменённых файлов: 320 добавлений и 15 удалений

Просмотреть файл

@@ -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)
}