mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
feat: add administrator role permission table (#11817)
This update introduces a new table for managing administrator role permissions, along with the necessary repository and projection logic to handle adding and removing permissions. It also includes tests to ensure the correct functionality of the permission management system. closes https://github.com/zitadel/zitadel/issues/10219 --------- Co-authored-by: Marco Ardizzone <[email protected]>
This commit is contained in:
co-authored by
Marco Ardizzone
parent
bb3b52dda3
commit
7b9d2b7d17
@@ -0,0 +1,32 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
)
|
||||
|
||||
type administratorRoleColumns interface {
|
||||
PrimaryKeyColumns() []database.Column
|
||||
InstanceIDColumn() database.Column
|
||||
RoleNameColumn() database.Column
|
||||
PermissionColumn() database.Column
|
||||
}
|
||||
|
||||
type administratorRoleConditions interface {
|
||||
PrimaryKeyCondition(instanceID, roleName, permission string) database.Condition
|
||||
InstanceIDCondition(instanceID string) database.Condition
|
||||
RoleNameCondition(op database.TextOperation, name string) database.Condition
|
||||
PermissionCondition(op database.TextOperation, permission string) database.Condition
|
||||
}
|
||||
|
||||
//go:generate mockgen -typed -package domainmock -destination ./mock/administrator_role.mock.go . AdministratorRoleRepository
|
||||
type AdministratorRoleRepository interface {
|
||||
Repository
|
||||
|
||||
administratorRoleColumns
|
||||
administratorRoleConditions
|
||||
|
||||
AddPermissions(ctx context.Context, client database.QueryExecutor, instanceID, role string, permissions ...string) (int64, error)
|
||||
RemovePermissions(ctx context.Context, client database.QueryExecutor, instanceID, role string, permissionsToRemove ...string) (int64, error)
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/zitadel/zitadel/backend/v3/domain (interfaces: AdministratorRoleRepository)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -typed -package domainmock -destination ./mock/administrator_role.mock.go . AdministratorRoleRepository
|
||||
//
|
||||
|
||||
// Package domainmock is a generated GoMock package.
|
||||
package domainmock
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
database "github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockAdministratorRoleRepository is a mock of AdministratorRoleRepository interface.
|
||||
type MockAdministratorRoleRepository struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockAdministratorRoleRepositoryMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryMockRecorder is the mock recorder for MockAdministratorRoleRepository.
|
||||
type MockAdministratorRoleRepositoryMockRecorder struct {
|
||||
mock *MockAdministratorRoleRepository
|
||||
}
|
||||
|
||||
// NewMockAdministratorRoleRepository creates a new mock instance.
|
||||
func NewMockAdministratorRoleRepository(ctrl *gomock.Controller) *MockAdministratorRoleRepository {
|
||||
mock := &MockAdministratorRoleRepository{ctrl: ctrl}
|
||||
mock.recorder = &MockAdministratorRoleRepositoryMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockAdministratorRoleRepository) EXPECT() *MockAdministratorRoleRepositoryMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AddPermissions mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) AddPermissions(ctx context.Context, client database.QueryExecutor, instanceID, role string, permissions ...string) (int64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []any{ctx, client, instanceID, role}
|
||||
for _, a := range permissions {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "AddPermissions", varargs...)
|
||||
ret0, _ := ret[0].(int64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AddPermissions indicates an expected call of AddPermissions.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) AddPermissions(ctx, client, instanceID, role any, permissions ...any) *MockAdministratorRoleRepositoryAddPermissionsCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]any{ctx, client, instanceID, role}, permissions...)
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPermissions", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).AddPermissions), varargs...)
|
||||
return &MockAdministratorRoleRepositoryAddPermissionsCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryAddPermissionsCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryAddPermissionsCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryAddPermissionsCall) Return(arg0 int64, arg1 error) *MockAdministratorRoleRepositoryAddPermissionsCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryAddPermissionsCall) Do(f func(context.Context, database.QueryExecutor, string, string, ...string) (int64, error)) *MockAdministratorRoleRepositoryAddPermissionsCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryAddPermissionsCall) DoAndReturn(f func(context.Context, database.QueryExecutor, string, string, ...string) (int64, error)) *MockAdministratorRoleRepositoryAddPermissionsCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// InstanceIDColumn mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) InstanceIDColumn() database.Column {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InstanceIDColumn")
|
||||
ret0, _ := ret[0].(database.Column)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// InstanceIDColumn indicates an expected call of InstanceIDColumn.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) InstanceIDColumn() *MockAdministratorRoleRepositoryInstanceIDColumnCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceIDColumn", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).InstanceIDColumn))
|
||||
return &MockAdministratorRoleRepositoryInstanceIDColumnCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryInstanceIDColumnCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryInstanceIDColumnCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryInstanceIDColumnCall) Return(arg0 database.Column) *MockAdministratorRoleRepositoryInstanceIDColumnCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryInstanceIDColumnCall) Do(f func() database.Column) *MockAdministratorRoleRepositoryInstanceIDColumnCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryInstanceIDColumnCall) DoAndReturn(f func() database.Column) *MockAdministratorRoleRepositoryInstanceIDColumnCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// InstanceIDCondition mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) InstanceIDCondition(instanceID string) database.Condition {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InstanceIDCondition", instanceID)
|
||||
ret0, _ := ret[0].(database.Condition)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// InstanceIDCondition indicates an expected call of InstanceIDCondition.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) InstanceIDCondition(instanceID any) *MockAdministratorRoleRepositoryInstanceIDConditionCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceIDCondition", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).InstanceIDCondition), instanceID)
|
||||
return &MockAdministratorRoleRepositoryInstanceIDConditionCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryInstanceIDConditionCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryInstanceIDConditionCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryInstanceIDConditionCall) Return(arg0 database.Condition) *MockAdministratorRoleRepositoryInstanceIDConditionCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryInstanceIDConditionCall) Do(f func(string) database.Condition) *MockAdministratorRoleRepositoryInstanceIDConditionCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryInstanceIDConditionCall) DoAndReturn(f func(string) database.Condition) *MockAdministratorRoleRepositoryInstanceIDConditionCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// PermissionColumn mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) PermissionColumn() database.Column {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PermissionColumn")
|
||||
ret0, _ := ret[0].(database.Column)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PermissionColumn indicates an expected call of PermissionColumn.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) PermissionColumn() *MockAdministratorRoleRepositoryPermissionColumnCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PermissionColumn", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).PermissionColumn))
|
||||
return &MockAdministratorRoleRepositoryPermissionColumnCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryPermissionColumnCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryPermissionColumnCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryPermissionColumnCall) Return(arg0 database.Column) *MockAdministratorRoleRepositoryPermissionColumnCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryPermissionColumnCall) Do(f func() database.Column) *MockAdministratorRoleRepositoryPermissionColumnCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryPermissionColumnCall) DoAndReturn(f func() database.Column) *MockAdministratorRoleRepositoryPermissionColumnCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// PermissionCondition mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) PermissionCondition(op database.TextOperation, permission string) database.Condition {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PermissionCondition", op, permission)
|
||||
ret0, _ := ret[0].(database.Condition)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PermissionCondition indicates an expected call of PermissionCondition.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) PermissionCondition(op, permission any) *MockAdministratorRoleRepositoryPermissionConditionCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PermissionCondition", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).PermissionCondition), op, permission)
|
||||
return &MockAdministratorRoleRepositoryPermissionConditionCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryPermissionConditionCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryPermissionConditionCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryPermissionConditionCall) Return(arg0 database.Condition) *MockAdministratorRoleRepositoryPermissionConditionCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryPermissionConditionCall) Do(f func(database.TextOperation, string) database.Condition) *MockAdministratorRoleRepositoryPermissionConditionCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryPermissionConditionCall) DoAndReturn(f func(database.TextOperation, string) database.Condition) *MockAdministratorRoleRepositoryPermissionConditionCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// PrimaryKeyColumns mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) PrimaryKeyColumns() []database.Column {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PrimaryKeyColumns")
|
||||
ret0, _ := ret[0].([]database.Column)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PrimaryKeyColumns indicates an expected call of PrimaryKeyColumns.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) PrimaryKeyColumns() *MockAdministratorRoleRepositoryPrimaryKeyColumnsCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyColumns", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).PrimaryKeyColumns))
|
||||
return &MockAdministratorRoleRepositoryPrimaryKeyColumnsCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryPrimaryKeyColumnsCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryPrimaryKeyColumnsCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryPrimaryKeyColumnsCall) Return(arg0 []database.Column) *MockAdministratorRoleRepositoryPrimaryKeyColumnsCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryPrimaryKeyColumnsCall) Do(f func() []database.Column) *MockAdministratorRoleRepositoryPrimaryKeyColumnsCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryPrimaryKeyColumnsCall) DoAndReturn(f func() []database.Column) *MockAdministratorRoleRepositoryPrimaryKeyColumnsCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// PrimaryKeyCondition mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) PrimaryKeyCondition(instanceID, roleName, permission string) database.Condition {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PrimaryKeyCondition", instanceID, roleName, permission)
|
||||
ret0, _ := ret[0].(database.Condition)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// PrimaryKeyCondition indicates an expected call of PrimaryKeyCondition.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) PrimaryKeyCondition(instanceID, roleName, permission any) *MockAdministratorRoleRepositoryPrimaryKeyConditionCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyCondition", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).PrimaryKeyCondition), instanceID, roleName, permission)
|
||||
return &MockAdministratorRoleRepositoryPrimaryKeyConditionCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryPrimaryKeyConditionCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryPrimaryKeyConditionCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryPrimaryKeyConditionCall) Return(arg0 database.Condition) *MockAdministratorRoleRepositoryPrimaryKeyConditionCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryPrimaryKeyConditionCall) Do(f func(string, string, string) database.Condition) *MockAdministratorRoleRepositoryPrimaryKeyConditionCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryPrimaryKeyConditionCall) DoAndReturn(f func(string, string, string) database.Condition) *MockAdministratorRoleRepositoryPrimaryKeyConditionCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// RemovePermissions mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) RemovePermissions(ctx context.Context, client database.QueryExecutor, instanceID, role string, permissionsToRemove ...string) (int64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []any{ctx, client, instanceID, role}
|
||||
for _, a := range permissionsToRemove {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "RemovePermissions", varargs...)
|
||||
ret0, _ := ret[0].(int64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// RemovePermissions indicates an expected call of RemovePermissions.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) RemovePermissions(ctx, client, instanceID, role any, permissionsToRemove ...any) *MockAdministratorRoleRepositoryRemovePermissionsCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]any{ctx, client, instanceID, role}, permissionsToRemove...)
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemovePermissions", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).RemovePermissions), varargs...)
|
||||
return &MockAdministratorRoleRepositoryRemovePermissionsCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryRemovePermissionsCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryRemovePermissionsCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryRemovePermissionsCall) Return(arg0 int64, arg1 error) *MockAdministratorRoleRepositoryRemovePermissionsCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryRemovePermissionsCall) Do(f func(context.Context, database.QueryExecutor, string, string, ...string) (int64, error)) *MockAdministratorRoleRepositoryRemovePermissionsCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryRemovePermissionsCall) DoAndReturn(f func(context.Context, database.QueryExecutor, string, string, ...string) (int64, error)) *MockAdministratorRoleRepositoryRemovePermissionsCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// RoleNameColumn mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) RoleNameColumn() database.Column {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "RoleNameColumn")
|
||||
ret0, _ := ret[0].(database.Column)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// RoleNameColumn indicates an expected call of RoleNameColumn.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) RoleNameColumn() *MockAdministratorRoleRepositoryRoleNameColumnCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RoleNameColumn", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).RoleNameColumn))
|
||||
return &MockAdministratorRoleRepositoryRoleNameColumnCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryRoleNameColumnCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryRoleNameColumnCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryRoleNameColumnCall) Return(arg0 database.Column) *MockAdministratorRoleRepositoryRoleNameColumnCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryRoleNameColumnCall) Do(f func() database.Column) *MockAdministratorRoleRepositoryRoleNameColumnCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryRoleNameColumnCall) DoAndReturn(f func() database.Column) *MockAdministratorRoleRepositoryRoleNameColumnCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// RoleNameCondition mocks base method.
|
||||
func (m *MockAdministratorRoleRepository) RoleNameCondition(op database.TextOperation, name string) database.Condition {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "RoleNameCondition", op, name)
|
||||
ret0, _ := ret[0].(database.Condition)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// RoleNameCondition indicates an expected call of RoleNameCondition.
|
||||
func (mr *MockAdministratorRoleRepositoryMockRecorder) RoleNameCondition(op, name any) *MockAdministratorRoleRepositoryRoleNameConditionCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RoleNameCondition", reflect.TypeOf((*MockAdministratorRoleRepository)(nil).RoleNameCondition), op, name)
|
||||
return &MockAdministratorRoleRepositoryRoleNameConditionCall{Call: call}
|
||||
}
|
||||
|
||||
// MockAdministratorRoleRepositoryRoleNameConditionCall wrap *gomock.Call
|
||||
type MockAdministratorRoleRepositoryRoleNameConditionCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockAdministratorRoleRepositoryRoleNameConditionCall) Return(arg0 database.Condition) *MockAdministratorRoleRepositoryRoleNameConditionCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockAdministratorRoleRepositoryRoleNameConditionCall) Do(f func(database.TextOperation, string) database.Condition) *MockAdministratorRoleRepositoryRoleNameConditionCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockAdministratorRoleRepositoryRoleNameConditionCall) DoAndReturn(f func(database.TextOperation, string) database.Condition) *MockAdministratorRoleRepositoryRoleNameConditionCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed 018_administrator_role_permissions_table/up.sql
|
||||
up018AdministratorRolePermissionsTable string
|
||||
//go:embed 018_administrator_role_permissions_table/down.sql
|
||||
down018AdministratorRolePermissionsTable string
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerSQLMigration(18, up018AdministratorRolePermissionsTable, down018AdministratorRolePermissionsTable)
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS zitadel.administrator_role_permissions;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE zitadel.administrator_role_permissions(
|
||||
instance_id TEXT NOT NULL
|
||||
, role_name TEXT NOT NULL CHECK (role_name <> '')
|
||||
, permission TEXT NOT NULL CHECK (permission <> '')
|
||||
|
||||
, PRIMARY KEY (instance_id, permission, role_name)
|
||||
, FOREIGN KEY (instance_id) REFERENCES zitadel.instances(id) ON DELETE CASCADE
|
||||
);
|
||||
@@ -0,0 +1,97 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
)
|
||||
|
||||
var _ domain.AdministratorRoleRepository = (*administratorRole)(nil)
|
||||
|
||||
type administratorRole struct{}
|
||||
|
||||
func AdministratorRoleRepository() domain.AdministratorRoleRepository {
|
||||
return new(administratorRole)
|
||||
}
|
||||
|
||||
func (administratorRole) unqualifiedTableName() string {
|
||||
return "administrator_role_permissions"
|
||||
}
|
||||
|
||||
func (a administratorRole) qualifiedTableName() string {
|
||||
return "zitadel." + a.unqualifiedTableName()
|
||||
}
|
||||
|
||||
// AddPermission implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) AddPermissions(ctx context.Context, client database.QueryExecutor, instanceID, role string, permissions ...string) (int64, error) {
|
||||
if len(permissions) == 0 {
|
||||
return 0, database.ErrNoChanges
|
||||
}
|
||||
builder := database.NewStatementBuilder(
|
||||
"INSERT INTO zitadel.administrator_role_permissions (instance_id, role_name, permission)"+
|
||||
" SELECT $1::text, $2::text, unnest($3::text[])"+
|
||||
" ON CONFLICT (instance_id, permission, role_name) DO NOTHING", instanceID, role, permissions,
|
||||
)
|
||||
return client.Exec(ctx, builder.String(), builder.Args()...)
|
||||
}
|
||||
|
||||
// RemovePermissions implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) RemovePermissions(ctx context.Context, client database.QueryExecutor, instanceID, role string, permissionsToRemove ...string) (int64, error) {
|
||||
if len(permissionsToRemove) == 0 {
|
||||
return 0, database.ErrNoChanges
|
||||
}
|
||||
builder := database.NewStatementBuilder(
|
||||
"DELETE FROM zitadel.administrator_role_permissions"+
|
||||
" WHERE instance_id = $1 AND role_name = $2 AND permission = ANY($3::text[])", instanceID, role, permissionsToRemove,
|
||||
)
|
||||
return client.Exec(ctx, builder.String(), builder.Args()...)
|
||||
}
|
||||
|
||||
// PrimaryKeyCondition implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) PrimaryKeyCondition(instanceID, roleName, permission string) database.Condition {
|
||||
return database.And(
|
||||
a.InstanceIDCondition(instanceID),
|
||||
a.RoleNameCondition(database.TextOperationEqual, roleName),
|
||||
a.PermissionCondition(database.TextOperationEqual, permission),
|
||||
)
|
||||
}
|
||||
|
||||
// InstanceIDCondition implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) InstanceIDCondition(instanceID string) database.Condition {
|
||||
return database.NewTextCondition(a.InstanceIDColumn(), database.TextOperationEqual, instanceID)
|
||||
}
|
||||
|
||||
// RoleNameCondition implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) RoleNameCondition(op database.TextOperation, name string) database.Condition {
|
||||
return database.NewTextCondition(a.RoleNameColumn(), op, name)
|
||||
}
|
||||
|
||||
// PermissionCondition implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) PermissionCondition(op database.TextOperation, permission string) database.Condition {
|
||||
return database.NewTextCondition(a.PermissionColumn(), op, permission)
|
||||
}
|
||||
|
||||
// PrimaryKeyColumns implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) PrimaryKeyColumns() []database.Column {
|
||||
return []database.Column{
|
||||
a.InstanceIDColumn(),
|
||||
a.PermissionColumn(),
|
||||
a.RoleNameColumn(),
|
||||
}
|
||||
}
|
||||
|
||||
// RoleNameColumn implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) RoleNameColumn() database.Column {
|
||||
return database.NewColumn(a.unqualifiedTableName(), "role_name")
|
||||
}
|
||||
|
||||
// PermissionColumn implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) PermissionColumn() database.Column {
|
||||
return database.NewColumn(a.unqualifiedTableName(), "permission")
|
||||
}
|
||||
|
||||
// InstanceIDColumn implements [domain.AdministratorRoleRepository].
|
||||
func (a administratorRole) InstanceIDColumn() database.Column {
|
||||
return database.NewColumn(a.unqualifiedTableName(), "instance_id")
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package repository_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
||||
)
|
||||
|
||||
type administratorRolePermissionRow struct {
|
||||
InstanceID string `db:"instance_id"`
|
||||
RoleName string `db:"role_name"`
|
||||
Permission string `db:"permission"`
|
||||
}
|
||||
|
||||
func TestAdministratorRoleRepository_AddPermissions(t *testing.T) {
|
||||
tx, rollback := transactionForRollback(t)
|
||||
defer rollback()
|
||||
|
||||
instanceID := createInstance(t, tx)
|
||||
repo := repository.AdministratorRoleRepository()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
role string
|
||||
permissions []string
|
||||
wantRows []administratorRolePermissionRow
|
||||
wantErr error
|
||||
wantCount int64
|
||||
}{
|
||||
{
|
||||
name: "add deduplicated permissions",
|
||||
role: "ORG_OWNER",
|
||||
permissions: []string{"org.read", "org.write", "org.read"},
|
||||
wantCount: 2,
|
||||
wantRows: []administratorRolePermissionRow{
|
||||
{InstanceID: instanceID, RoleName: "ORG_OWNER", Permission: "org.read"},
|
||||
{InstanceID: instanceID, RoleName: "ORG_OWNER", Permission: "org.write"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no permissions",
|
||||
role: "ORG_OWNER",
|
||||
wantErr: database.ErrNoChanges,
|
||||
wantCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
savepoint, rollbackSavepoint := savepointForRollback(t, tx)
|
||||
defer rollbackSavepoint()
|
||||
|
||||
count, err := repo.AddPermissions(t.Context(), savepoint, instanceID, tt.role, tt.permissions...)
|
||||
require.ErrorIs(t, err, tt.wantErr)
|
||||
assert.Equal(t, tt.wantCount, count)
|
||||
|
||||
if tt.wantErr == nil {
|
||||
assert.Equal(t,
|
||||
tt.wantRows,
|
||||
listAdministratorRolePermissions(t, savepoint, repo.RoleNameCondition(database.TextOperationEqual, tt.role)),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdministratorRoleRepository_RemovePermissions(t *testing.T) {
|
||||
tx, rollback := transactionForRollback(t)
|
||||
defer rollback()
|
||||
|
||||
instanceID := createInstance(t, tx)
|
||||
|
||||
repo := repository.AdministratorRoleRepository()
|
||||
count, err := repo.AddPermissions(t.Context(), tx, instanceID, "INSTANCE_OWNER", "instance.read", "instance.write")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(2), count)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
role string
|
||||
permissions []string
|
||||
wantRows []administratorRolePermissionRow
|
||||
wantErr error
|
||||
wantCount int64
|
||||
}{
|
||||
{
|
||||
name: "no permissions",
|
||||
role: "INSTANCE_OWNER",
|
||||
wantErr: database.ErrNoChanges,
|
||||
},
|
||||
{
|
||||
name: "remove permissions",
|
||||
role: "INSTANCE_OWNER",
|
||||
permissions: []string{"instance.read"},
|
||||
wantCount: 1,
|
||||
wantRows: []administratorRolePermissionRow{
|
||||
{InstanceID: instanceID, RoleName: "INSTANCE_OWNER", Permission: "instance.write"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remove exact pair and missing values",
|
||||
role: "INSTANCE_OWNER",
|
||||
permissions: []string{"instance.write", "missing"},
|
||||
wantCount: 1,
|
||||
wantRows: []administratorRolePermissionRow{{InstanceID: instanceID, RoleName: "INSTANCE_OWNER", Permission: "instance.read"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
savepoint, rollbackSavepoint := savepointForRollback(t, tx)
|
||||
defer rollbackSavepoint()
|
||||
|
||||
count, err = repo.RemovePermissions(t.Context(), savepoint, instanceID, tt.role, tt.permissions...)
|
||||
require.ErrorIs(t, err, tt.wantErr)
|
||||
assert.Equal(t, tt.wantCount, count)
|
||||
if tt.wantErr == nil {
|
||||
assert.Equal(t,
|
||||
tt.wantRows,
|
||||
listAdministratorRolePermissions(t, savepoint, repo.RoleNameCondition(database.TextOperationEqual, "INSTANCE_OWNER")),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdministratorRoleRepository_AddAndRemoveAcrossCalls(t *testing.T) {
|
||||
tx, rollback := transactionForRollback(t)
|
||||
defer rollback()
|
||||
|
||||
instanceID := createInstance(t, tx)
|
||||
|
||||
repo := repository.AdministratorRoleRepository()
|
||||
|
||||
count, err := repo.AddPermissions(t.Context(), tx, instanceID, "INSTANCE_OWNER", "instance.read", "instance.write")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(2), count)
|
||||
|
||||
count, err = repo.AddPermissions(t.Context(), tx, instanceID, "INSTANCE_OWNER", "instance.manage", "instance.audit", "instance.write")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(2), count)
|
||||
|
||||
count, err = repo.RemovePermissions(t.Context(), tx, instanceID, "INSTANCE_OWNER", "instance.read")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(1), count)
|
||||
|
||||
assert.Equal(t,
|
||||
[]administratorRolePermissionRow{
|
||||
{InstanceID: instanceID, RoleName: "INSTANCE_OWNER", Permission: "instance.audit"},
|
||||
{InstanceID: instanceID, RoleName: "INSTANCE_OWNER", Permission: "instance.manage"},
|
||||
{InstanceID: instanceID, RoleName: "INSTANCE_OWNER", Permission: "instance.write"},
|
||||
},
|
||||
listAdministratorRolePermissions(t, tx, repo.RoleNameCondition(database.TextOperationEqual, "INSTANCE_OWNER")),
|
||||
)
|
||||
}
|
||||
|
||||
func TestAdministratorRoleRepository_PrimaryKeyCondition(t *testing.T) {
|
||||
tx, rollback := transactionForRollback(t)
|
||||
defer rollback()
|
||||
|
||||
instanceID := createInstance(t, tx)
|
||||
|
||||
repo := repository.AdministratorRoleRepository()
|
||||
count, err := repo.AddPermissions(t.Context(), tx, instanceID, "PROJECT_OWNER", "project.read", "project.write")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(2), count)
|
||||
|
||||
rows := listAdministratorRolePermissions(t, tx, repo.PrimaryKeyCondition(instanceID, "PROJECT_OWNER", "project.read"))
|
||||
assert.Equal(t,
|
||||
[]administratorRolePermissionRow{{InstanceID: instanceID, RoleName: "PROJECT_OWNER", Permission: "project.read"}},
|
||||
rows,
|
||||
)
|
||||
}
|
||||
|
||||
func listAdministratorRolePermissions(t *testing.T, tx database.QueryExecutor, condition database.Condition) []administratorRolePermissionRow {
|
||||
t.Helper()
|
||||
|
||||
builder := database.NewStatementBuilder(`SELECT instance_id, role_name, permission FROM zitadel.administrator_role_permissions`)
|
||||
if condition != nil {
|
||||
builder.WriteString(" WHERE ")
|
||||
condition.Write(builder)
|
||||
}
|
||||
builder.WriteString(" ORDER BY instance_id, role_name, permission")
|
||||
|
||||
rows, err := tx.Query(t.Context(), builder.String(), builder.Args()...)
|
||||
require.NoError(t, err)
|
||||
|
||||
var result []*administratorRolePermissionRow
|
||||
require.NoError(t, rows.(database.CollectableRows).Collect(&result))
|
||||
|
||||
out := make([]administratorRolePermissionRow, len(result))
|
||||
for i, row := range result {
|
||||
out[i] = *row
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -43,6 +43,9 @@ func TestAddCustomDomain(t *testing.T) {
|
||||
relationalInst.Client.InstanceV2.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: relationalInst.ID()})
|
||||
})
|
||||
|
||||
// ugly fix to wait until instances are projected in all read models.
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
type instanceAndCtx struct {
|
||||
testType string
|
||||
instance *integration.Instance
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
v3_sql "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/sql"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||
"github.com/zitadel/zitadel/internal/repository/permission"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
func (p *relationalTablesProjection) reduceAdministratorRolePermissionAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, err := assertEvent[*permission.AddedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
||||
tx, ok := ex.(*sql.Tx)
|
||||
if !ok {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-v3ARP01", "reduce.wrong.db.pool %T", ex)
|
||||
}
|
||||
repo := repository.AdministratorRoleRepository()
|
||||
_, err := repo.AddPermissions(ctx, v3_sql.SQLTx(tx), e.Aggregate().InstanceID, e.Role, e.Permission)
|
||||
return err
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *relationalTablesProjection) reduceAdministratorRolePermissionRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, err := assertEvent[*permission.RemovedEvent](event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
||||
tx, ok := ex.(*sql.Tx)
|
||||
if !ok {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-v3ARP02", "reduce.wrong.db.pool %T", ex)
|
||||
}
|
||||
repo := repository.AdministratorRoleRepository()
|
||||
_, err := repo.RemovePermissions(ctx, v3_sql.SQLTx(tx), e.Aggregate().InstanceID, e.Role, e.Permission)
|
||||
return err
|
||||
}), nil
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
repoDomain "github.com/zitadel/zitadel/backend/v3/domain"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
||||
"github.com/zitadel/zitadel/internal/repository/permission"
|
||||
)
|
||||
|
||||
type administratorRolePermission struct {
|
||||
RoleName string `db:"role_name"`
|
||||
Permission string `db:"permission"`
|
||||
}
|
||||
|
||||
func TestAdministratorRolePermissionReducers(t *testing.T) {
|
||||
handler := &relationalTablesProjection{}
|
||||
rawTx, tx := getTransactions(t)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, rawTx.Rollback())
|
||||
})
|
||||
|
||||
instanceID := seedAdministratorRolePermissions(t, tx)
|
||||
|
||||
repo := repository.AdministratorRoleRepository()
|
||||
|
||||
t.Run("added event inserts a permission row", func(t *testing.T) {
|
||||
event := permission.NewAddedEvent(t.Context(), permission.NewAggregate(instanceID), "ORG_OWNER", "org.read")
|
||||
require.True(t, callReduce(t, rawTx, handler, event))
|
||||
assert.Equal(t,
|
||||
[]administratorRolePermission{{RoleName: "ORG_OWNER", Permission: "org.read"}},
|
||||
listReducedAdministratorRolePermissions(t, tx),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("removed event deletes only the matching permission row", func(t *testing.T) {
|
||||
_, err := repo.AddPermissions(t.Context(), tx, instanceID, "INSTANCE_OWNER", "instance.read", "instance.write")
|
||||
require.NoError(t, err)
|
||||
|
||||
event := permission.NewRemovedEvent(t.Context(), permission.NewAggregate(instanceID), "INSTANCE_OWNER", "instance.read")
|
||||
require.True(t, callReduce(t, rawTx, handler, event))
|
||||
assert.Equal(t,
|
||||
[]administratorRolePermission{{RoleName: "INSTANCE_OWNER", Permission: "instance.write"}},
|
||||
listReducedAdministratorRolePermissions(t, tx, repo.RoleNameCondition(database.TextOperationEqual, "INSTANCE_OWNER")),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func listReducedAdministratorRolePermissions(t *testing.T, tx database.QueryExecutor, conditions ...database.Condition) []administratorRolePermission {
|
||||
t.Helper()
|
||||
|
||||
builder := database.NewStatementBuilder(`SELECT role_name, permission FROM zitadel.administrator_role_permissions`)
|
||||
if len(conditions) > 0 {
|
||||
builder.WriteString(" WHERE ")
|
||||
database.And(conditions...).Write(builder)
|
||||
}
|
||||
builder.WriteString(" ORDER BY role_name, permission")
|
||||
|
||||
rows, err := tx.Query(t.Context(), builder.String(), builder.Args()...)
|
||||
require.NoError(t, err)
|
||||
|
||||
var result []*administratorRolePermission
|
||||
require.NoError(t, rows.(database.CollectableRows).Collect(&result))
|
||||
|
||||
out := make([]administratorRolePermission, len(result))
|
||||
for i, row := range result {
|
||||
out[i] = *row
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func seedAdministratorRolePermissions(t *testing.T, tx database.QueryExecutor) string {
|
||||
t.Helper()
|
||||
|
||||
instanceID := fmt.Sprintf("instance-%d", time.Now().UnixNano())
|
||||
err := repository.InstanceRepository().Create(t.Context(), tx, &repoDomain.Instance{
|
||||
ID: instanceID,
|
||||
Name: "instance",
|
||||
DefaultOrgID: "default-org",
|
||||
IAMProjectID: "iam-project",
|
||||
ConsoleClientID: "console-client",
|
||||
ConsoleAppID: "console-app",
|
||||
DefaultLanguage: "en",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
return instanceID
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||
"github.com/zitadel/zitadel/internal/repository/org"
|
||||
settings "github.com/zitadel/zitadel/internal/repository/organization_settings"
|
||||
"github.com/zitadel/zitadel/internal/repository/permission"
|
||||
"github.com/zitadel/zitadel/internal/repository/project"
|
||||
"github.com/zitadel/zitadel/internal/repository/session"
|
||||
"github.com/zitadel/zitadel/internal/repository/user"
|
||||
@@ -26,6 +27,19 @@ func (*relationalTablesProjection) Name() string {
|
||||
|
||||
func (p *relationalTablesProjection) Reducers() []handler.AggregateReducer {
|
||||
return []handler.AggregateReducer{
|
||||
{
|
||||
Aggregate: permission.AggregateType,
|
||||
EventReducers: []handler.EventReducer{
|
||||
{
|
||||
Event: permission.AddedType,
|
||||
Reduce: p.reduceAdministratorRolePermissionAdded,
|
||||
},
|
||||
{
|
||||
Event: permission.RemovedType,
|
||||
Reduce: p.reduceAdministratorRolePermissionRemoved,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Aggregate: instance.AggregateType,
|
||||
EventReducers: []handler.EventReducer{
|
||||
|
||||
Reference in New Issue
Block a user