[MM-61756] Attribute Based Access Control - Phase 1 (#30785)
Attribute Based Access Control - Base * MM-63662 * MM-63919 * MM-63954 * MM-63955 * MM-63425 * MM-63426 * MM-63458 * MM-63459 * MM-63603 * MM-63845 * MM-64146 * MM-64199 * MM-64201 * MM-64233 * MM-64247 * MM-64268 --------- Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com> Co-authored-by: Pablo Andrés Vélez Vidal <pablovv2012@gmail.com> Co-authored-by: abhijit-singh <abhijitsingh0702@gmail.com> Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
4b445cbf16
Коммит
a344b3225b
@@ -290,24 +290,51 @@ func testAccessControlPolicyStoreGetAll(t *testing.T, rctx request.CTX, ss store
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
id3 := "zzz" + model.NewId()[3:] // ensure the order of the ID
|
||||
parentPolicy2 := &model.AccessControlPolicy{
|
||||
ID: id3,
|
||||
Name: "Name",
|
||||
Type: model.AccessControlPolicyTypeParent,
|
||||
Active: true,
|
||||
Revision: 1,
|
||||
Version: model.AccessControlPolicyVersionV0_1,
|
||||
Imports: []string{},
|
||||
Rules: []model.AccessControlPolicyRule{
|
||||
{
|
||||
Actions: []string{"action"},
|
||||
Expression: "user.properties.program == \"engineering\"",
|
||||
},
|
||||
},
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
err = ss.AccessControlPolicy().Delete(rctx, id)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
_, err = ss.AccessControlPolicy().Save(rctx, parentPolicy2)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, parentPolicy)
|
||||
|
||||
resourcePolicy, err = ss.AccessControlPolicy().Save(rctx, resourcePolicy)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resourcePolicy)
|
||||
t.Run("GetAll", func(t *testing.T) {
|
||||
policies, err := ss.AccessControlPolicy().GetAll(rctx, store.GetPolicyOptions{})
|
||||
policies, _, err := ss.AccessControlPolicy().SearchPolicies(rctx, model.AccessControlPolicySearch{})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, policies)
|
||||
require.Len(t, policies, 2)
|
||||
require.Len(t, policies, 3)
|
||||
})
|
||||
|
||||
t.Run("GetAll by type", func(t *testing.T) {
|
||||
policies, err := ss.AccessControlPolicy().GetAll(rctx, store.GetPolicyOptions{Type: model.AccessControlPolicyTypeParent})
|
||||
policies, _, err := ss.AccessControlPolicy().SearchPolicies(rctx, model.AccessControlPolicySearch{Type: model.AccessControlPolicyTypeParent, IncludeChildren: true})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, policies)
|
||||
require.Len(t, policies, 1)
|
||||
require.Len(t, policies, 2)
|
||||
require.Equal(t, parentPolicy.ID, policies[0].ID)
|
||||
require.Equal(t, map[string]any{"child_ids": []string{resourcePolicy.ID}}, policies[0].Props)
|
||||
require.Equal(t, map[string]any{"child_ids": []string{}}, policies[1].Props)
|
||||
|
||||
policies, err = ss.AccessControlPolicy().GetAll(rctx, store.GetPolicyOptions{Type: model.AccessControlPolicyTypeChannel})
|
||||
policies, _, err = ss.AccessControlPolicy().SearchPolicies(rctx, model.AccessControlPolicySearch{Type: model.AccessControlPolicyTypeChannel})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, policies)
|
||||
require.Len(t, policies, 1)
|
||||
@@ -315,13 +342,13 @@ func testAccessControlPolicyStoreGetAll(t *testing.T, rctx request.CTX, ss store
|
||||
})
|
||||
|
||||
t.Run("GetAll by parent", func(t *testing.T) {
|
||||
policies, err := ss.AccessControlPolicy().GetAll(rctx, store.GetPolicyOptions{ParentID: parentPolicy.ID})
|
||||
policies, _, err := ss.AccessControlPolicy().SearchPolicies(rctx, model.AccessControlPolicySearch{ParentID: parentPolicy.ID})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, policies)
|
||||
require.Len(t, policies, 1)
|
||||
require.Equal(t, resourcePolicy.ID, policies[0].ID)
|
||||
|
||||
policies, err = ss.AccessControlPolicy().GetAll(rctx, store.GetPolicyOptions{ParentID: model.NewId()})
|
||||
policies, _, err = ss.AccessControlPolicy().SearchPolicies(rctx, model.AccessControlPolicySearch{ParentID: model.NewId()})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, policies)
|
||||
require.Len(t, policies, 0)
|
||||
|
||||
282
server/channels/store/storetest/attributes_store.go
Обычный файл
282
server/channels/store/storetest/attributes_store.go
Обычный файл
@@ -0,0 +1,282 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package storetest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
testPropertyGroupName = "test_property_group"
|
||||
testPropertyA = "test_property_a"
|
||||
testPropertyB = "test_property_b"
|
||||
testPropertyValueA1 = "value_a1"
|
||||
testPropertyValueA2 = "value_a2"
|
||||
testPropertyValueB1 = "value_b1"
|
||||
)
|
||||
|
||||
var (
|
||||
testTeamID = model.NewId()
|
||||
)
|
||||
|
||||
func TestAttributesStore(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
t.Run("RefreshAndGet", func(t *testing.T) { testAttributesStoreRefresh(t, rctx, ss) })
|
||||
t.Run("SearchUsers", func(t *testing.T) { testAttributesStoreSearchUsers(t, rctx, ss, s) })
|
||||
}
|
||||
|
||||
func createTestUsers(t *testing.T, rctx request.CTX, ss store.Store) ([]*model.User, string, func()) {
|
||||
maxUsersPerTeam := 50
|
||||
|
||||
u1 := model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewUsername(),
|
||||
}
|
||||
|
||||
_, err := ss.User().Save(rctx, &u1)
|
||||
require.NoError(t, err, "couldn't save user")
|
||||
|
||||
_, nErr := ss.Team().SaveMember(rctx, &model.TeamMember{TeamId: testTeamID, UserId: u1.Id}, maxUsersPerTeam)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
u2 := model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewUsername(),
|
||||
}
|
||||
_, err = ss.User().Save(rctx, &u2)
|
||||
require.NoError(t, err, "couldn't save user")
|
||||
|
||||
_, nErr = ss.Team().SaveMember(rctx, &model.TeamMember{TeamId: testTeamID, UserId: u2.Id}, maxUsersPerTeam)
|
||||
require.NoError(t, nErr)
|
||||
|
||||
// user3 does not have any attributes
|
||||
u3 := model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewUsername(),
|
||||
}
|
||||
|
||||
_, err = ss.User().Save(rctx, &u3)
|
||||
require.NoError(t, err, "couldn't save user")
|
||||
|
||||
// user3 does not have any attributes
|
||||
u4 := model.User{
|
||||
Email: MakeEmail(),
|
||||
Username: model.NewUsername(),
|
||||
}
|
||||
|
||||
_, err = ss.User().Save(rctx, &u4)
|
||||
require.NoError(t, err, "couldn't save user")
|
||||
|
||||
group, err := ss.PropertyGroup().Register(testPropertyGroupName)
|
||||
require.NoError(t, err)
|
||||
require.NotZero(t, group.ID)
|
||||
require.Equal(t, testPropertyGroupName, group.Name)
|
||||
groupID := group.ID
|
||||
|
||||
fieldA, err := ss.PropertyField().Create(&model.PropertyField{
|
||||
GroupID: groupID,
|
||||
Name: testPropertyA,
|
||||
Type: model.PropertyFieldTypeText,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
fieldB, err := ss.PropertyField().Create(&model.PropertyField{
|
||||
GroupID: groupID,
|
||||
Name: testPropertyB,
|
||||
Type: model.PropertyFieldTypeText,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
vala1, err := json.Marshal(testPropertyValueA1)
|
||||
require.NoError(t, err)
|
||||
vala2, err := json.Marshal(testPropertyValueA2)
|
||||
require.NoError(t, err)
|
||||
valab1, err := json.Marshal(testPropertyValueB1)
|
||||
require.NoError(t, err)
|
||||
|
||||
pva1, err := ss.PropertyValue().Create(&model.PropertyValue{
|
||||
TargetID: u1.Id,
|
||||
TargetType: "user",
|
||||
GroupID: groupID,
|
||||
FieldID: fieldA.ID,
|
||||
Value: vala1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
pvb1, err := ss.PropertyValue().Create(&model.PropertyValue{
|
||||
TargetID: u1.Id,
|
||||
TargetType: "user",
|
||||
GroupID: groupID,
|
||||
FieldID: fieldB.ID,
|
||||
Value: valab1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
pva2, err := ss.PropertyValue().Create(&model.PropertyValue{
|
||||
TargetID: u2.Id,
|
||||
TargetType: "user",
|
||||
GroupID: groupID,
|
||||
FieldID: fieldA.ID,
|
||||
Value: vala2,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
pva3, err := ss.PropertyValue().Create(&model.PropertyValue{
|
||||
TargetID: u3.Id,
|
||||
TargetType: "user",
|
||||
GroupID: groupID,
|
||||
FieldID: fieldA.ID,
|
||||
Value: vala1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
return []*model.User{&u1, &u2, &u3}, groupID, func() {
|
||||
for _, pv := range []*model.PropertyValue{pva1, pvb1, pva2, pva3} {
|
||||
dErr := ss.PropertyValue().Delete(groupID, pv.ID)
|
||||
require.NoError(t, dErr, "couldn't delete property value")
|
||||
}
|
||||
for _, field := range []*model.PropertyField{fieldA, fieldB} {
|
||||
dErr := ss.PropertyField().Delete(groupID, field.ID)
|
||||
require.NoError(t, dErr, "couldn't delete property field")
|
||||
}
|
||||
for _, u := range []*model.User{&u1, &u2, &u3, &u4} {
|
||||
dErr := ss.User().PermanentDelete(rctx, u.Id)
|
||||
require.NoError(t, dErr, "couldn't delete user")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testAttributesStoreRefresh(t *testing.T, rctx request.CTX, ss store.Store) {
|
||||
users, groupID, cleanup := createTestUsers(t, rctx, ss)
|
||||
t.Cleanup(cleanup)
|
||||
|
||||
t.Run("Refresh attributes", func(t *testing.T) {
|
||||
err := ss.Attributes().RefreshAttributes()
|
||||
require.NoError(t, err, "couldn't refresh attributes")
|
||||
|
||||
// Check if the attributes are set correctly
|
||||
for _, user := range users {
|
||||
subject, err := ss.Attributes().GetSubject(rctx, user.Id, groupID)
|
||||
require.NoError(t, err, "couldn't get subject")
|
||||
|
||||
require.Equal(t, user.Id, subject.ID)
|
||||
require.Equal(t, "user", subject.Type)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Get non-existing subject", func(t *testing.T) {
|
||||
subject, err := ss.Attributes().GetSubject(rctx, "non-existing-id", groupID)
|
||||
require.Error(t, err, "expected error when getting non-existing subject")
|
||||
require.IsType(t, &store.ErrNotFound{}, err, "expected not found error")
|
||||
require.Nil(t, subject, "expected nil subject for non-existing ID")
|
||||
})
|
||||
}
|
||||
|
||||
func testAttributesStoreSearchUsers(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore) {
|
||||
users, _, cleanup := createTestUsers(t, rctx, ss)
|
||||
t.Cleanup(cleanup)
|
||||
require.Len(t, users, 3, "expected 3 users")
|
||||
|
||||
err := ss.Attributes().RefreshAttributes()
|
||||
require.NoError(t, err, "couldn't refresh attributes")
|
||||
|
||||
t.Run("Search users without query", func(t *testing.T) {
|
||||
subjects, count, err := ss.Attributes().SearchUsers(rctx, model.SubjectSearchOptions{})
|
||||
require.NoError(t, err, "couldn't search users")
|
||||
require.Len(t, subjects, 4, "expected 4 users")
|
||||
require.Equal(t, int64(4), count, "expected count 4 users")
|
||||
})
|
||||
|
||||
t.Run("Search users without query, limit by team", func(t *testing.T) {
|
||||
subjects, count, err := ss.Attributes().SearchUsers(rctx, model.SubjectSearchOptions{
|
||||
TeamID: testTeamID,
|
||||
})
|
||||
require.NoError(t, err, "couldn't search users")
|
||||
require.Len(t, subjects, 2, "expected 2 users")
|
||||
require.Equal(t, int64(2), count, "expected count 2 users")
|
||||
})
|
||||
|
||||
t.Run("Search users with a random value query", func(t *testing.T) {
|
||||
subjects, count, err := ss.Attributes().SearchUsers(rctx, model.SubjectSearchOptions{
|
||||
Query: "Attributes ->> '$." + testPropertyA + "' = ?",
|
||||
Args: []any{"random_value"},
|
||||
})
|
||||
require.NoError(t, err, "couldn't search users")
|
||||
require.Empty(t, subjects, "expected no users with the query")
|
||||
require.Equal(t, int64(0), count, "expected count 0 users")
|
||||
})
|
||||
|
||||
t.Run("Search users with a valid value query", func(t *testing.T) {
|
||||
var query string
|
||||
if s.DriverName() == model.DatabaseDriverMysql {
|
||||
query = "Attributes ->> '$." + testPropertyB + "' = ?"
|
||||
} else {
|
||||
query = "Attributes ->> '" + testPropertyB + "' = $1::text"
|
||||
}
|
||||
subjects, count, err := ss.Attributes().SearchUsers(rctx, model.SubjectSearchOptions{
|
||||
Query: query,
|
||||
Args: []any{testPropertyValueB1},
|
||||
})
|
||||
require.NoError(t, err, "couldn't search users")
|
||||
require.Len(t, subjects, 1, "expected 1 user with the query")
|
||||
require.Equal(t, subjects[0].Id, users[0].Id, "expected user ID to match")
|
||||
require.Equal(t, int64(1), count, "expected count 1 user")
|
||||
})
|
||||
|
||||
t.Run("Search users with a valid value query and limit", func(t *testing.T) {
|
||||
var query string
|
||||
if s.DriverName() == model.DatabaseDriverMysql {
|
||||
query = "Attributes ->> '$." + testPropertyA + "' = ?"
|
||||
} else {
|
||||
query = "Attributes ->> '" + testPropertyA + "' = $1::text"
|
||||
}
|
||||
subjects, count, err := ss.Attributes().SearchUsers(rctx, model.SubjectSearchOptions{
|
||||
Query: query,
|
||||
Args: []any{testPropertyValueA1},
|
||||
Limit: 1,
|
||||
})
|
||||
require.NoError(t, err, "couldn't search users")
|
||||
require.Len(t, subjects, 1, "expected 1 user with the query")
|
||||
if users[0].Id < users[2].Id {
|
||||
require.Equal(t, subjects[0].Id, users[0].Id, "expected user ID to match")
|
||||
} else {
|
||||
require.Equal(t, subjects[0].Id, users[2].Id, "expected user ID to match")
|
||||
}
|
||||
require.Equal(t, int64(2), count, "expected count 1 user")
|
||||
})
|
||||
|
||||
t.Run("Search users with pagination", func(t *testing.T) {
|
||||
var query string
|
||||
if s.DriverName() == model.DatabaseDriverMysql {
|
||||
query = "Attributes ->> '$." + testPropertyA + "' = ?"
|
||||
} else {
|
||||
query = "Attributes ->> '" + testPropertyA + "' = $1::text"
|
||||
}
|
||||
|
||||
cursor := strings.Repeat("0", 26)
|
||||
for i := 0; i < 5; i++ {
|
||||
subjects, count, err := ss.Attributes().SearchUsers(rctx, model.SubjectSearchOptions{
|
||||
Query: query,
|
||||
Args: []any{testPropertyValueA1},
|
||||
Limit: 1,
|
||||
Cursor: model.SubjectCursor{
|
||||
TargetID: cursor,
|
||||
},
|
||||
})
|
||||
if len(subjects) == 0 {
|
||||
break
|
||||
}
|
||||
cursor = subjects[0].Id
|
||||
|
||||
require.NoError(t, err, "couldn't search users")
|
||||
require.Len(t, subjects, 1, "expected 1 user with the query")
|
||||
require.Equal(t, int64(2), count, "expected count 2 user with the query")
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
model "github.com/mattermost/mattermost/server/public/model"
|
||||
request "github.com/mattermost/mattermost/server/public/shared/request"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
store "github.com/mattermost/mattermost/server/v8/channels/store"
|
||||
)
|
||||
|
||||
// AccessControlPolicyStore is an autogenerated mock type for the AccessControlPolicyStore type
|
||||
@@ -65,36 +63,6 @@ func (_m *AccessControlPolicyStore) Get(c request.CTX, id string) (*model.Access
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetAll provides a mock function with given fields: rctxc, opts
|
||||
func (_m *AccessControlPolicyStore) GetAll(rctxc request.CTX, opts store.GetPolicyOptions) ([]*model.AccessControlPolicy, error) {
|
||||
ret := _m.Called(rctxc, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetAll")
|
||||
}
|
||||
|
||||
var r0 []*model.AccessControlPolicy
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, store.GetPolicyOptions) ([]*model.AccessControlPolicy, error)); ok {
|
||||
return rf(rctxc, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, store.GetPolicyOptions) []*model.AccessControlPolicy); ok {
|
||||
r0 = rf(rctxc, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.AccessControlPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(request.CTX, store.GetPolicyOptions) error); ok {
|
||||
r1 = rf(rctxc, opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Save provides a mock function with given fields: c, policy
|
||||
func (_m *AccessControlPolicyStore) Save(c request.CTX, policy *model.AccessControlPolicy) (*model.AccessControlPolicy, error) {
|
||||
ret := _m.Called(c, policy)
|
||||
@@ -125,6 +93,43 @@ func (_m *AccessControlPolicyStore) Save(c request.CTX, policy *model.AccessCont
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SearchPolicies provides a mock function with given fields: rctx, opts
|
||||
func (_m *AccessControlPolicyStore) SearchPolicies(rctx request.CTX, opts model.AccessControlPolicySearch) ([]*model.AccessControlPolicy, int64, error) {
|
||||
ret := _m.Called(rctx, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SearchPolicies")
|
||||
}
|
||||
|
||||
var r0 []*model.AccessControlPolicy
|
||||
var r1 int64
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, model.AccessControlPolicySearch) ([]*model.AccessControlPolicy, int64, error)); ok {
|
||||
return rf(rctx, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, model.AccessControlPolicySearch) []*model.AccessControlPolicy); ok {
|
||||
r0 = rf(rctx, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.AccessControlPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(request.CTX, model.AccessControlPolicySearch) int64); ok {
|
||||
r1 = rf(rctx, opts)
|
||||
} else {
|
||||
r1 = ret.Get(1).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func(request.CTX, model.AccessControlPolicySearch) error); ok {
|
||||
r2 = rf(rctx, opts)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// SetActiveStatus provides a mock function with given fields: c, id, active
|
||||
func (_m *AccessControlPolicyStore) SetActiveStatus(c request.CTX, id string, active bool) (*model.AccessControlPolicy, error) {
|
||||
ret := _m.Called(c, id, active)
|
||||
|
||||
145
server/channels/store/storetest/mocks/AttributesStore.go
Обычный файл
145
server/channels/store/storetest/mocks/AttributesStore.go
Обычный файл
@@ -0,0 +1,145 @@
|
||||
// Code generated by mockery v2.42.2. DO NOT EDIT.
|
||||
|
||||
// Regenerate this file using `make store-mocks`.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
model "github.com/mattermost/mattermost/server/public/model"
|
||||
request "github.com/mattermost/mattermost/server/public/shared/request"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// AttributesStore is an autogenerated mock type for the AttributesStore type
|
||||
type AttributesStore struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// GetChannelMembersToRemove provides a mock function with given fields: rctx, channelID, opts
|
||||
func (_m *AttributesStore) GetChannelMembersToRemove(rctx request.CTX, channelID string, opts model.SubjectSearchOptions) ([]*model.ChannelMember, error) {
|
||||
ret := _m.Called(rctx, channelID, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetChannelMembersToRemove")
|
||||
}
|
||||
|
||||
var r0 []*model.ChannelMember
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, string, model.SubjectSearchOptions) ([]*model.ChannelMember, error)); ok {
|
||||
return rf(rctx, channelID, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, string, model.SubjectSearchOptions) []*model.ChannelMember); ok {
|
||||
r0 = rf(rctx, channelID, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.ChannelMember)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(request.CTX, string, model.SubjectSearchOptions) error); ok {
|
||||
r1 = rf(rctx, channelID, opts)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetSubject provides a mock function with given fields: rctx, ID, groupID
|
||||
func (_m *AttributesStore) GetSubject(rctx request.CTX, ID string, groupID string) (*model.Subject, error) {
|
||||
ret := _m.Called(rctx, ID, groupID)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetSubject")
|
||||
}
|
||||
|
||||
var r0 *model.Subject
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, string, string) (*model.Subject, error)); ok {
|
||||
return rf(rctx, ID, groupID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, string, string) *model.Subject); ok {
|
||||
r0 = rf(rctx, ID, groupID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Subject)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(request.CTX, string, string) error); ok {
|
||||
r1 = rf(rctx, ID, groupID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// RefreshAttributes provides a mock function with given fields:
|
||||
func (_m *AttributesStore) RefreshAttributes() error {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for RefreshAttributes")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SearchUsers provides a mock function with given fields: rctx, opts
|
||||
func (_m *AttributesStore) SearchUsers(rctx request.CTX, opts model.SubjectSearchOptions) ([]*model.User, int64, error) {
|
||||
ret := _m.Called(rctx, opts)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SearchUsers")
|
||||
}
|
||||
|
||||
var r0 []*model.User
|
||||
var r1 int64
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, model.SubjectSearchOptions) ([]*model.User, int64, error)); ok {
|
||||
return rf(rctx, opts)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(request.CTX, model.SubjectSearchOptions) []*model.User); ok {
|
||||
r0 = rf(rctx, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.User)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(request.CTX, model.SubjectSearchOptions) int64); ok {
|
||||
r1 = rf(rctx, opts)
|
||||
} else {
|
||||
r1 = ret.Get(1).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func(request.CTX, model.SubjectSearchOptions) error); ok {
|
||||
r2 = rf(rctx, opts)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// NewAttributesStore creates a new instance of AttributesStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewAttributesStore(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *AttributesStore {
|
||||
mock := &AttributesStore{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
@@ -44,6 +44,26 @@ func (_m *Store) AccessControlPolicy() store.AccessControlPolicyStore {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Attributes provides a mock function with given fields:
|
||||
func (_m *Store) Attributes() store.AttributesStore {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Attributes")
|
||||
}
|
||||
|
||||
var r0 store.AttributesStore
|
||||
if rf, ok := ret.Get(0).(func() store.AttributesStore); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.AttributesStore)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Audit provides a mock function with given fields:
|
||||
func (_m *Store) Audit() store.AuditStore {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -70,6 +70,7 @@ type Store struct {
|
||||
PropertyFieldStore mocks.PropertyFieldStore
|
||||
PropertyValueStore mocks.PropertyValueStore
|
||||
AccessControlPolicyStore mocks.AccessControlPolicyStore
|
||||
AttributesStore mocks.AttributesStore
|
||||
}
|
||||
|
||||
func (s *Store) SetContext(context context.Context) { s.context = context }
|
||||
@@ -158,6 +159,9 @@ func (s *Store) ReplicaLagTime() error { return nil }
|
||||
func (s *Store) AccessControlPolicy() store.AccessControlPolicyStore {
|
||||
return &s.AccessControlPolicyStore
|
||||
}
|
||||
func (s *Store) Attributes() store.AttributesStore {
|
||||
return &s.AttributesStore
|
||||
}
|
||||
|
||||
func (s *Store) AssertExpectations(t mock.TestingT) bool {
|
||||
return mock.AssertExpectationsForObjects(t,
|
||||
@@ -202,5 +206,6 @@ func (s *Store) AssertExpectations(t mock.TestingT) bool {
|
||||
&s.ChannelBookmarkStore,
|
||||
&s.ScheduledPostStore,
|
||||
&s.AccessControlPolicyStore,
|
||||
&s.AttributesStore,
|
||||
)
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user