summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2018-04-18 10:18:07 +0100
committerGitHub <noreply@github.com>2018-04-18 10:18:07 +0100
commitb13a228b0451098ea32933a36fe64566e366583d (patch)
tree569aa0c6c5f273b806b4c3e0c59801204916492c /store
parenta1882d4004ce624dad1b8624804e974f209efe8d (diff)
downloadchat-b13a228b0451098ea32933a36fe64566e366583d.tar.gz
chat-b13a228b0451098ea32933a36fe64566e366583d.tar.bz2
chat-b13a228b0451098ea32933a36fe64566e366583d.zip
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.
Diffstat (limited to 'store')
-rw-r--r--store/layered_store.go6
-rw-r--r--store/layered_store_supplier.go1
-rw-r--r--store/local_cache_supplier_roles.go7
-rw-r--r--store/redis_supplier_roles.go14
-rw-r--r--store/sqlstore/role_supplier.go10
-rw-r--r--store/sqlstore/system_store.go11
-rw-r--r--store/store.go2
-rw-r--r--store/storetest/mocks/LayeredStoreDatabaseLayer.go23
-rw-r--r--store/storetest/mocks/LayeredStoreSupplier.go23
-rw-r--r--store/storetest/mocks/PostStore.go31
-rw-r--r--store/storetest/mocks/RoleStore.go16
-rw-r--r--store/storetest/mocks/SystemStore.go16
-rw-r--r--store/storetest/role_store.go40
-rw-r--r--store/storetest/system_store.go36
14 files changed, 221 insertions, 15 deletions
diff --git a/store/layered_store.go b/store/layered_store.go
index cac0f61d3..5ef907260 100644
--- a/store/layered_store.go
+++ b/store/layered_store.go
@@ -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)
+ })
+}
diff --git a/store/layered_store_supplier.go b/store/layered_store_supplier.go
index 80fe3cb24..9a7604b20 100644
--- a/store/layered_store_supplier.go
+++ b/store/layered_store_supplier.go
@@ -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
}
diff --git a/store/local_cache_supplier_roles.go b/store/local_cache_supplier_roles.go
index 8cbde0a23..7c82f60eb 100644
--- a/store/local_cache_supplier_roles.go
+++ b/store/local_cache_supplier_roles.go
@@ -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...)
+}
diff --git a/store/redis_supplier_roles.go b/store/redis_supplier_roles.go
index 170420f1f..232a8c040 100644
--- a/store/redis_supplier_roles.go
+++ b/store/redis_supplier_roles.go
@@ -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)
}
diff --git a/store/sqlstore/role_supplier.go b/store/sqlstore/role_supplier.go
index 828f4484e..ddbdaca52 100644
--- a/store/sqlstore/role_supplier.go
+++ b/store/sqlstore/role_supplier.go
@@ -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
+}
diff --git a/store/sqlstore/system_store.go b/store/sqlstore/system_store.go
index 496ff2ced..4065bb955 100644
--- a/store/sqlstore/system_store.go
+++ b/store/sqlstore/system_store.go
@@ -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
+ })
+}
diff --git a/store/store.go b/store/store.go
index 79a14baba..e64089068 100644
--- a/store/store.go
+++ b/store/store.go
@@ -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
}
diff --git a/store/storetest/mocks/LayeredStoreDatabaseLayer.go b/store/storetest/mocks/LayeredStoreDatabaseLayer.go
index d0162a01e..6fa31bb1b 100644
--- a/store/storetest/mocks/LayeredStoreDatabaseLayer.go
+++ b/store/storetest/mocks/LayeredStoreDatabaseLayer.go
@@ -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))
diff --git a/store/storetest/mocks/LayeredStoreSupplier.go b/store/storetest/mocks/LayeredStoreSupplier.go
index 59fd31cb8..d4242708b 100644
--- a/store/storetest/mocks/LayeredStoreSupplier.go
+++ b/store/storetest/mocks/LayeredStoreSupplier.go
@@ -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))
diff --git a/store/storetest/mocks/PostStore.go b/store/storetest/mocks/PostStore.go
index bdd0d1d16..bdfbb3321 100644
--- a/store/storetest/mocks/PostStore.go
+++ b/store/storetest/mocks/PostStore.go
@@ -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
-}
diff --git a/store/storetest/mocks/RoleStore.go b/store/storetest/mocks/RoleStore.go
index 8150460ae..3c01ee341 100644
--- a/store/storetest/mocks/RoleStore.go
+++ b/store/storetest/mocks/RoleStore.go
@@ -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)
diff --git a/store/storetest/mocks/SystemStore.go b/store/storetest/mocks/SystemStore.go
index 2c5774fcf..b31e4646d 100644
--- a/store/storetest/mocks/SystemStore.go
+++ b/store/storetest/mocks/SystemStore.go
@@ -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)
diff --git a/store/storetest/role_store.go b/store/storetest/role_store.go
index 499e36e1e..e51c32622 100644
--- a/store/storetest/role_store.go
+++ b/store/storetest/role_store.go
@@ -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)
+}
diff --git a/store/storetest/system_store.go b/store/storetest/system_store.go
index 32c39ee41..a06b72a83 100644
--- a/store/storetest/system_store.go
+++ b/store/storetest/system_store.go
@@ -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)
+
+}