mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Auth: Add OrgRoleMapper service (#86973)
* Add OrgRoleMapper * Address feedback, add more tests * Prevent resetting assignments when global org mapping fails * Provide a parsing function instead of recalculating the org_mapping on every mapping * Introduce strict role parsing/mapping * Introduce MappingConfiguration * Handle other edge case * Add tests * lint * Apply documentation update suggestions * Apply GetDefaultOrgMapping suggestions from code review * Apply suggestions for cleaning up unnecessary err in ParseOrgMappingSettings * Apply suggestions from code review * Address feedback suggestions * Cleanup * Reduce cognitive complexity of ParseOrgMappingSettings --------- Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
This commit is contained in:
parent
333ed377d6
commit
9236c5a5cf
255
pkg/login/social/connectors/org_role_mapper.go
Normal file
255
pkg/login/social/connectors/org_role_mapper.go
Normal file
@ -0,0 +1,255 @@
|
||||
package connectors
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
const mapperMatchAllOrgID = -1
|
||||
|
||||
// OrgRoleMapper maps external orgs/groups to Grafana orgs and basic roles.
|
||||
type OrgRoleMapper struct {
|
||||
cfg *setting.Cfg
|
||||
logger log.Logger
|
||||
orgService org.Service
|
||||
}
|
||||
|
||||
// MappingConfiguration represents the mapping configuration from external orgs to Grafana orgs and roles.
|
||||
// orgMapping: mapping from external orgs to Grafana orgs and roles
|
||||
// strictRoleMapping: if true, the mapper ensures that the evaluated role from orgMapping or the directlyMappedRole is a valid role, otherwise it will return nil.
|
||||
type MappingConfiguration struct {
|
||||
orgMapping map[string]map[int64]org.RoleType
|
||||
strictRoleMapping bool
|
||||
}
|
||||
|
||||
func ProvideOrgRoleMapper(cfg *setting.Cfg, orgService org.Service) *OrgRoleMapper {
|
||||
return &OrgRoleMapper{
|
||||
cfg: cfg,
|
||||
logger: log.New("orgrole.mapper"),
|
||||
orgService: orgService,
|
||||
}
|
||||
}
|
||||
|
||||
// MapOrgRoles maps the external orgs/groups to Grafana orgs and roles. It returns a map or orgID to role.
|
||||
//
|
||||
// mappingCfg: mapping configuration from external orgs to Grafana orgs and roles. Use `ParseOrgMappingSettings` to convert the raw setting to this format.
|
||||
//
|
||||
// externalOrgs: list of orgs/groups from the provider
|
||||
//
|
||||
// directlyMappedRole: role that is directly mapped to the user (ex: through `role_attribute_path`)
|
||||
func (m *OrgRoleMapper) MapOrgRoles(
|
||||
mappingCfg *MappingConfiguration,
|
||||
externalOrgs []string,
|
||||
directlyMappedRole org.RoleType,
|
||||
) map[int64]org.RoleType {
|
||||
if len(mappingCfg.orgMapping) == 0 {
|
||||
// Org mapping is not configured
|
||||
return m.getDefaultOrgMapping(mappingCfg.strictRoleMapping, directlyMappedRole)
|
||||
}
|
||||
|
||||
userOrgRoles := getMappedOrgRoles(externalOrgs, mappingCfg.orgMapping)
|
||||
|
||||
if err := m.handleGlobalOrgMapping(userOrgRoles); err != nil {
|
||||
// Cannot map global org roles, return nil (prevent resetting asignments)
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(userOrgRoles) == 0 {
|
||||
return m.getDefaultOrgMapping(mappingCfg.strictRoleMapping, directlyMappedRole)
|
||||
}
|
||||
|
||||
if directlyMappedRole == "" {
|
||||
m.logger.Debug("No direct role mapping found")
|
||||
return userOrgRoles
|
||||
}
|
||||
|
||||
m.logger.Debug("Direct role mapping found", "role", directlyMappedRole)
|
||||
|
||||
// Merge roles from org mapping `org_mapping` with role from direct mapping
|
||||
for orgID, role := range userOrgRoles {
|
||||
userOrgRoles[orgID] = getTopRole(directlyMappedRole, role)
|
||||
}
|
||||
|
||||
return userOrgRoles
|
||||
}
|
||||
|
||||
func (m *OrgRoleMapper) getDefaultOrgMapping(strictRoleMapping bool, directlyMappedRole org.RoleType) map[int64]org.RoleType {
|
||||
if strictRoleMapping && !directlyMappedRole.IsValid() {
|
||||
m.logger.Debug("Prevent default org role mapping, role attribute strict requested")
|
||||
return nil
|
||||
}
|
||||
orgRoles := make(map[int64]org.RoleType, 0)
|
||||
|
||||
orgID := int64(1)
|
||||
if m.cfg.AutoAssignOrg && m.cfg.AutoAssignOrgId > 0 {
|
||||
orgID = int64(m.cfg.AutoAssignOrgId)
|
||||
}
|
||||
|
||||
orgRoles[orgID] = directlyMappedRole
|
||||
if !directlyMappedRole.IsValid() {
|
||||
orgRoles[orgID] = org.RoleType(m.cfg.AutoAssignOrgRole)
|
||||
}
|
||||
|
||||
return orgRoles
|
||||
}
|
||||
|
||||
func (m *OrgRoleMapper) handleGlobalOrgMapping(orgRoles map[int64]org.RoleType) error {
|
||||
// No global role mapping => return
|
||||
globalRole, ok := orgRoles[mapperMatchAllOrgID]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
allOrgIDs, err := m.getAllOrgs()
|
||||
if err != nil {
|
||||
// Prevent resetting assignments
|
||||
clear(orgRoles)
|
||||
m.logger.Warn("error fetching all orgs, removing org mapping to prevent org sync")
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove the global role mapping
|
||||
delete(orgRoles, mapperMatchAllOrgID)
|
||||
|
||||
// Global mapping => for all orgs get top role mapping
|
||||
for orgID := range allOrgIDs {
|
||||
orgRoles[orgID] = getTopRole(orgRoles[orgID], globalRole)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseOrgMappingSettings parses the `org_mapping` setting and returns an internal representation of the mapping.
|
||||
// If the roleStrict is enabled, the mapping should contain a valid role for each org.
|
||||
// FIXME: Consider introducing a struct to represent the org mapping settings
|
||||
func (m *OrgRoleMapper) ParseOrgMappingSettings(ctx context.Context, mappings []string, roleStrict bool) *MappingConfiguration {
|
||||
res := map[string]map[int64]org.RoleType{}
|
||||
|
||||
for _, v := range mappings {
|
||||
kv := strings.Split(v, ":")
|
||||
if !isValidOrgMappingFormat(kv) {
|
||||
m.logger.Error("Skipping org mapping due to invalid format.", "mapping", fmt.Sprintf("%v", v))
|
||||
if roleStrict {
|
||||
// Return empty mapping if the mapping format is invalied and roleStrict is enabled
|
||||
return &MappingConfiguration{orgMapping: map[string]map[int64]org.RoleType{}, strictRoleMapping: roleStrict}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
orgID, err := m.getOrgIDForInternalMapping(ctx, kv[1])
|
||||
if err != nil {
|
||||
m.logger.Warn("Could not fetch OrgID. Skipping.", "err", err, "mapping", fmt.Sprintf("%v", v), "org", kv[1])
|
||||
if roleStrict {
|
||||
// Return empty mapping if at least one org name cannot be resolved when roleStrict is enabled
|
||||
return &MappingConfiguration{orgMapping: map[string]map[int64]org.RoleType{}, strictRoleMapping: roleStrict}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if roleStrict && (len(kv) < 3 || !org.RoleType(kv[2]).IsValid()) {
|
||||
// Return empty mapping if at least one org mapping is invalid (missing role, invalid role)
|
||||
m.logger.Warn("Skipping org mapping due to missing or invalid role in mapping when roleStrict is enabled.", "mapping", fmt.Sprintf("%v", v))
|
||||
return &MappingConfiguration{orgMapping: map[string]map[int64]org.RoleType{}, strictRoleMapping: roleStrict}
|
||||
}
|
||||
|
||||
orga := kv[0]
|
||||
if res[orga] == nil {
|
||||
res[orga] = map[int64]org.RoleType{}
|
||||
}
|
||||
|
||||
res[orga][int64(orgID)] = getRoleForInternalOrgMapping(kv)
|
||||
}
|
||||
|
||||
return &MappingConfiguration{orgMapping: res, strictRoleMapping: roleStrict}
|
||||
}
|
||||
|
||||
func (m *OrgRoleMapper) getOrgIDForInternalMapping(ctx context.Context, orgIdCfg string) (int, error) {
|
||||
if orgIdCfg == "*" {
|
||||
return mapperMatchAllOrgID, nil
|
||||
}
|
||||
|
||||
orgID, err := strconv.Atoi(orgIdCfg)
|
||||
if err != nil {
|
||||
res, getErr := m.orgService.GetByName(ctx, &org.GetOrgByNameQuery{Name: orgIdCfg})
|
||||
|
||||
if getErr != nil {
|
||||
// skip in case of error
|
||||
m.logger.Warn("Could not fetch organization. Skipping.", "err", err, "org", orgIdCfg)
|
||||
return 0, getErr
|
||||
}
|
||||
orgID = int(res.ID)
|
||||
}
|
||||
|
||||
return orgID, nil
|
||||
}
|
||||
|
||||
func (m *OrgRoleMapper) getAllOrgs() (map[int64]bool, error) {
|
||||
allOrgIDs := map[int64]bool{}
|
||||
allOrgs, err := m.orgService.Search(context.Background(), &org.SearchOrgsQuery{})
|
||||
if err != nil {
|
||||
// In case of error, return no orgs
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, org := range allOrgs {
|
||||
allOrgIDs[org.ID] = true
|
||||
}
|
||||
return allOrgIDs, nil
|
||||
}
|
||||
|
||||
func getRoleForInternalOrgMapping(kv []string) org.RoleType {
|
||||
if len(kv) > 2 && org.RoleType(kv[2]).IsValid() {
|
||||
return org.RoleType(kv[2])
|
||||
}
|
||||
|
||||
return org.RoleViewer
|
||||
}
|
||||
|
||||
func isValidOrgMappingFormat(kv []string) bool {
|
||||
return len(kv) > 1 && len(kv) < 4
|
||||
}
|
||||
|
||||
func getMappedOrgRoles(externalOrgs []string, orgMapping map[string]map[int64]org.RoleType) map[int64]org.RoleType {
|
||||
userOrgRoles := map[int64]org.RoleType{}
|
||||
|
||||
if len(orgMapping) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if orgRoles, ok := orgMapping["*"]; ok {
|
||||
for orgID, role := range orgRoles {
|
||||
userOrgRoles[orgID] = role
|
||||
}
|
||||
}
|
||||
|
||||
for _, org := range externalOrgs {
|
||||
orgRoles, ok := orgMapping[org]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for orgID, role := range orgRoles {
|
||||
userOrgRoles[orgID] = getTopRole(userOrgRoles[orgID], role)
|
||||
}
|
||||
}
|
||||
|
||||
return userOrgRoles
|
||||
}
|
||||
|
||||
func getTopRole(currRole org.RoleType, otherRole org.RoleType) org.RoleType {
|
||||
if currRole == "" {
|
||||
return otherRole
|
||||
}
|
||||
|
||||
if currRole.Includes(otherRole) {
|
||||
return currRole
|
||||
}
|
||||
|
||||
return otherRole
|
||||
}
|
342
pkg/login/social/connectors/org_role_mapper_test.go
Normal file
342
pkg/login/social/connectors/org_role_mapper_test.go
Normal file
@ -0,0 +1,342 @@
|
||||
package connectors
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestOrgRoleMapper_MapOrgRoles(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
externalOrgs []string
|
||||
orgMappingSettings []string
|
||||
directlyMappedRole org.RoleType
|
||||
strictRoleMapping bool
|
||||
getAllOrgsError error
|
||||
expected map[int64]org.RoleType
|
||||
}{
|
||||
{
|
||||
name: "should return the default mapping when no org mapping settings are provided and directly mapped role is not set",
|
||||
externalOrgs: []string{},
|
||||
orgMappingSettings: []string{},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{2: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should return the default mapping when no org mapping settings are provided and direcly mapped role is set",
|
||||
externalOrgs: []string{},
|
||||
orgMappingSettings: []string{},
|
||||
directlyMappedRole: org.RoleEditor,
|
||||
expected: map[int64]org.RoleType{2: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should return the default mapping when org mapping doesn't match any of the external orgs and no directly mapped role is provided",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"Second:1:Editor"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{2: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should return Viewer role for the org if the specified role is invalid",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:1:SuperEditor"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{1: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should return nil when no org mapping settings are provided and directly mapped role is not set and strict role mapping is enabled",
|
||||
externalOrgs: []string{},
|
||||
orgMappingSettings: []string{},
|
||||
directlyMappedRole: "",
|
||||
strictRoleMapping: true,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "should return nil when org mapping doesn't match any of the external orgs and no directly mapped role is provided and strict role mapping is enabled",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"Second:1:Editor"},
|
||||
directlyMappedRole: "",
|
||||
strictRoleMapping: true,
|
||||
expected: nil,
|
||||
},
|
||||
// In this case the parsed org mapping will be empty because the role is invalid
|
||||
{
|
||||
name: "should return nil for the org if the specified role is invalid and strict role mapping is enabled",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:1:SuperEditor"},
|
||||
directlyMappedRole: "",
|
||||
strictRoleMapping: true,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "should map the directly mapped role to default org if the org mapping is invalid and strict role mapping is enabled",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:1:SuperEditor"},
|
||||
directlyMappedRole: "Editor",
|
||||
strictRoleMapping: true,
|
||||
expected: map[int64]org.RoleType{2: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should return nil if the org mapping contains at least one invalid setting and directly mapped role is empty and strict role mapping is enabled",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:1:SuperEditor", "First:1:Admin"},
|
||||
directlyMappedRole: "",
|
||||
strictRoleMapping: true,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "should map the higher role if directly mapped role is lower than the role found in the org mapping",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:1:Editor"},
|
||||
directlyMappedRole: org.RoleViewer,
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should map the directly mapped role if it is higher than the role found in the org mapping",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:1:Viewer"},
|
||||
directlyMappedRole: org.RoleEditor,
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should map to multiple organizations and set the directly mapped role for those if it is higher than the role found in the org mapping",
|
||||
externalOrgs: []string{"First", "Second"},
|
||||
orgMappingSettings: []string{"First:1:Viewer", "Second:2:Viewer"},
|
||||
directlyMappedRole: org.RoleEditor,
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor, 2: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should map to multiple organizations and set the directly mapped role for those if the directly mapped role is not set",
|
||||
externalOrgs: []string{"First", "Second"},
|
||||
orgMappingSettings: []string{"First:1:Viewer", "Second:2:Viewer"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{1: org.RoleViewer, 2: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should map to all of the organizations if global org mapping is provided and the directly mapped role is set",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:*:Editor"},
|
||||
directlyMappedRole: org.RoleViewer,
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor, 2: org.RoleEditor, 3: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should map to all of the organizations if global org mapping is provided and the directly mapped role is not set",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:*:Editor"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor, 2: org.RoleEditor, 3: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should map to all of the organizations if global org mapping is provided and the directly mapped role is higher than the role found in the org mappings",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:*:Viewer"},
|
||||
directlyMappedRole: org.RoleEditor,
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor, 2: org.RoleEditor, 3: org.RoleEditor},
|
||||
},
|
||||
{
|
||||
name: "should map correctly when fallback org mapping is provided and fallback has a higher role",
|
||||
externalOrgs: []string{"First", "Second", "Third"},
|
||||
orgMappingSettings: []string{"First:1:Viewer", "*:1:Editor", "Second:2:Viewer"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor, 2: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should map correctly when fallback org mapping is provided and fallback has a lower role",
|
||||
externalOrgs: []string{"First", "Second", "Third"},
|
||||
orgMappingSettings: []string{"First:1:Editor", "*:1:Viewer", "Second:2:Viewer"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor, 2: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should map correctly and respect wildcard precedence when global org mapping is provided",
|
||||
externalOrgs: []string{"First", "Second"},
|
||||
orgMappingSettings: []string{"*:1:Editor", "First:1:Viewer", "Second:2:Viewer"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{1: org.RoleEditor, 2: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should map directly mapped role when global org mapping is provided and the directly mapped role is higher than the role found in the org mappings",
|
||||
externalOrgs: []string{"First", "Second", "Third"},
|
||||
orgMappingSettings: []string{"First:1:Viewer", "*:1:Editor", "Second:2:Viewer"},
|
||||
directlyMappedRole: org.RoleAdmin,
|
||||
expected: map[int64]org.RoleType{1: org.RoleAdmin, 2: org.RoleAdmin},
|
||||
},
|
||||
{
|
||||
name: "should map correctly and respect the mapping precedence when multiple org mappings are provided for the same org",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:1:Editor", "First:1:Viewer"},
|
||||
directlyMappedRole: "",
|
||||
expected: map[int64]org.RoleType{1: org.RoleViewer},
|
||||
},
|
||||
{
|
||||
name: "should map to all organizations when global org mapping is provided and the directly mapped role is higher than the role found in the org mappings",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:*:Editor"},
|
||||
directlyMappedRole: org.RoleAdmin,
|
||||
expected: map[int64]org.RoleType{1: org.RoleAdmin, 2: org.RoleAdmin, 3: org.RoleAdmin},
|
||||
},
|
||||
{
|
||||
name: "should skip map to all organizations if org service returns an error",
|
||||
externalOrgs: []string{"First"},
|
||||
orgMappingSettings: []string{"First:*:Editor"},
|
||||
getAllOrgsError: assert.AnError,
|
||||
directlyMappedRole: org.RoleAdmin,
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
orgService := orgtest.NewOrgServiceFake()
|
||||
cfg := setting.NewCfg()
|
||||
cfg.AutoAssignOrg = true
|
||||
cfg.AutoAssignOrgId = 2
|
||||
cfg.AutoAssignOrgRole = string(org.RoleViewer)
|
||||
mapper := ProvideOrgRoleMapper(cfg, orgService)
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.getAllOrgsError != nil {
|
||||
orgService.ExpectedError = tc.getAllOrgsError
|
||||
} else {
|
||||
orgService.ExpectedOrgs = []*org.OrgDTO{
|
||||
{Name: "First", ID: 1},
|
||||
{Name: "Second", ID: 2},
|
||||
{Name: "Third", ID: 3},
|
||||
}
|
||||
}
|
||||
mappingCfg := mapper.ParseOrgMappingSettings(context.Background(), tc.orgMappingSettings, tc.strictRoleMapping)
|
||||
actual := mapper.MapOrgRoles(mappingCfg, tc.externalOrgs, tc.directlyMappedRole)
|
||||
|
||||
assert.EqualValues(t, tc.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrgRoleMapper_ParseOrgMappingSettings(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawMapping []string
|
||||
roleStrict bool
|
||||
setupMock func(*orgtest.MockService)
|
||||
expected *MappingConfiguration
|
||||
}{
|
||||
{
|
||||
name: "should return empty mapping when no org mapping settings are provided",
|
||||
rawMapping: []string{},
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{},
|
||||
strictRoleMapping: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return empty mapping when role is invalid and role strict is enabled",
|
||||
rawMapping: []string{"Second:1:SuperEditor"},
|
||||
roleStrict: true,
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{},
|
||||
strictRoleMapping: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return default mapping when role is invalid and strict role mapping is disabled",
|
||||
rawMapping: []string{"Second:1:SuperEditor"},
|
||||
roleStrict: false,
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{"Second": {1: org.RoleViewer}},
|
||||
strictRoleMapping: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return empty mapping when org mapping doesn't contain any role and strict role mapping is enabled",
|
||||
rawMapping: []string{"Second:1"},
|
||||
roleStrict: true,
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{},
|
||||
strictRoleMapping: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return default mapping when org mapping doesn't contain any role and strict is disabled",
|
||||
rawMapping: []string{"Second:1"},
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{"Second": {1: org.RoleViewer}},
|
||||
strictRoleMapping: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return empty mapping when org mapping is nil",
|
||||
rawMapping: nil,
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{},
|
||||
strictRoleMapping: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return empty mapping when the org mapping format is invalid and strict role mapping is enabled",
|
||||
rawMapping: []string{"External:Org1:First:Organization:Editor"},
|
||||
roleStrict: true,
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{},
|
||||
strictRoleMapping: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return only the valid mappings from the raw mappings when strict role mapping is disabled",
|
||||
rawMapping: []string{"External:Org1:First:Organization:Editor", "Second:1:Editor"},
|
||||
roleStrict: false,
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{"Second": {1: org.RoleEditor}},
|
||||
strictRoleMapping: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should return empty mapping if at least one org was not found or the resolution failed and strict role mapping is enabled",
|
||||
rawMapping: []string{"ExternalOrg1:First:Editor", "ExternalOrg1:NonExistent:Viewer"},
|
||||
roleStrict: true,
|
||||
setupMock: func(orgService *orgtest.MockService) {
|
||||
orgService.On("GetByName", mock.Anything, mock.MatchedBy(func(query *org.GetOrgByNameQuery) bool {
|
||||
return query.Name == "First"
|
||||
})).Return(&org.Org{ID: 1}, nil)
|
||||
orgService.On("GetByName", mock.Anything, mock.Anything).Return(nil, assert.AnError)
|
||||
},
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{},
|
||||
strictRoleMapping: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should skip org mapping if org was not found or the resolution fails and strict role mapping is disabled",
|
||||
rawMapping: []string{"ExternalOrg1:First:Editor", "ExternalOrg1:NonExistent:Viewer"},
|
||||
roleStrict: false,
|
||||
setupMock: func(orgService *orgtest.MockService) {
|
||||
orgService.On("GetByName", mock.Anything, mock.MatchedBy(func(query *org.GetOrgByNameQuery) bool {
|
||||
return query.Name == "First"
|
||||
})).Return(&org.Org{ID: 1}, nil)
|
||||
orgService.On("GetByName", mock.Anything, mock.Anything).Return(nil, assert.AnError)
|
||||
},
|
||||
expected: &MappingConfiguration{
|
||||
orgMapping: map[string]map[int64]org.RoleType{"ExternalOrg1": {1: org.RoleEditor}},
|
||||
strictRoleMapping: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
orgService := orgtest.NewMockService(t)
|
||||
if tc.setupMock != nil {
|
||||
tc.setupMock(orgService)
|
||||
}
|
||||
mapper := ProvideOrgRoleMapper(cfg, orgService)
|
||||
|
||||
actual := mapper.ParseOrgMappingSettings(context.Background(), tc.rawMapping, tc.roleStrict)
|
||||
|
||||
assert.EqualValues(t, tc.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
)
|
||||
|
||||
//go:generate mockery --name Service --structname MockService --outpkg orgtest --filename mock.go --output ./orgtest/
|
||||
type Service interface {
|
||||
GetIDForNewUser(context.Context, GetOrgIDForNewUserCommand) (int64, error)
|
||||
InsertOrgUser(context.Context, *OrgUser) (int64, error)
|
||||
|
454
pkg/services/org/orgtest/mock.go
Normal file
454
pkg/services/org/orgtest/mock.go
Normal file
@ -0,0 +1,454 @@
|
||||
// Code generated by mockery v2.42.1. DO NOT EDIT.
|
||||
|
||||
package orgtest
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
org "github.com/grafana/grafana/pkg/services/org"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockService is an autogenerated mock type for the Service type
|
||||
type MockService struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// AddOrgUser provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) AddOrgUser(_a0 context.Context, _a1 *org.AddOrgUserCommand) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddOrgUser")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.AddOrgUserCommand) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// CreateWithMember provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) CreateWithMember(_a0 context.Context, _a1 *org.CreateOrgCommand) (*org.Org, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CreateWithMember")
|
||||
}
|
||||
|
||||
var r0 *org.Org
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.CreateOrgCommand) (*org.Org, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.CreateOrgCommand) *org.Org); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*org.Org)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.CreateOrgCommand) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) Delete(_a0 context.Context, _a1 *org.DeleteOrgCommand) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Delete")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.DeleteOrgCommand) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteUserFromAll provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) DeleteUserFromAll(_a0 context.Context, _a1 int64) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DeleteUserFromAll")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetByID provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) GetByID(_a0 context.Context, _a1 *org.GetOrgByIDQuery) (*org.Org, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetByID")
|
||||
}
|
||||
|
||||
var r0 *org.Org
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetOrgByIDQuery) (*org.Org, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetOrgByIDQuery) *org.Org); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*org.Org)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.GetOrgByIDQuery) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetByName provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) GetByName(_a0 context.Context, _a1 *org.GetOrgByNameQuery) (*org.Org, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetByName")
|
||||
}
|
||||
|
||||
var r0 *org.Org
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetOrgByNameQuery) (*org.Org, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetOrgByNameQuery) *org.Org); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*org.Org)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.GetOrgByNameQuery) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetIDForNewUser provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) GetIDForNewUser(_a0 context.Context, _a1 org.GetOrgIDForNewUserCommand) (int64, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetIDForNewUser")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, org.GetOrgIDForNewUserCommand) (int64, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, org.GetOrgIDForNewUserCommand) int64); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, org.GetOrgIDForNewUserCommand) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetOrCreate provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) GetOrCreate(_a0 context.Context, _a1 string) (int64, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetOrCreate")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (int64, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) int64); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetOrgUsers provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) GetOrgUsers(_a0 context.Context, _a1 *org.GetOrgUsersQuery) ([]*org.OrgUserDTO, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetOrgUsers")
|
||||
}
|
||||
|
||||
var r0 []*org.OrgUserDTO
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetOrgUsersQuery) ([]*org.OrgUserDTO, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetOrgUsersQuery) []*org.OrgUserDTO); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*org.OrgUserDTO)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.GetOrgUsersQuery) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUserOrgList provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) GetUserOrgList(_a0 context.Context, _a1 *org.GetUserOrgListQuery) ([]*org.UserOrgDTO, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for GetUserOrgList")
|
||||
}
|
||||
|
||||
var r0 []*org.UserOrgDTO
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetUserOrgListQuery) ([]*org.UserOrgDTO, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.GetUserOrgListQuery) []*org.UserOrgDTO); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*org.UserOrgDTO)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.GetUserOrgListQuery) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// InsertOrgUser provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) InsertOrgUser(_a0 context.Context, _a1 *org.OrgUser) (int64, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for InsertOrgUser")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.OrgUser) (int64, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.OrgUser) int64); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.OrgUser) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// RegisterDelete provides a mock function with given fields: query
|
||||
func (_m *MockService) RegisterDelete(query string) {
|
||||
_m.Called(query)
|
||||
}
|
||||
|
||||
// RemoveOrgUser provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) RemoveOrgUser(_a0 context.Context, _a1 *org.RemoveOrgUserCommand) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for RemoveOrgUser")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.RemoveOrgUserCommand) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Search provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) Search(_a0 context.Context, _a1 *org.SearchOrgsQuery) ([]*org.OrgDTO, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Search")
|
||||
}
|
||||
|
||||
var r0 []*org.OrgDTO
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.SearchOrgsQuery) ([]*org.OrgDTO, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.SearchOrgsQuery) []*org.OrgDTO); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*org.OrgDTO)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.SearchOrgsQuery) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SearchOrgUsers provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) SearchOrgUsers(_a0 context.Context, _a1 *org.SearchOrgUsersQuery) (*org.SearchOrgUsersQueryResult, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for SearchOrgUsers")
|
||||
}
|
||||
|
||||
var r0 *org.SearchOrgUsersQueryResult
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.SearchOrgUsersQuery) (*org.SearchOrgUsersQueryResult, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.SearchOrgUsersQuery) *org.SearchOrgUsersQueryResult); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*org.SearchOrgUsersQueryResult)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *org.SearchOrgUsersQuery) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateAddress provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) UpdateAddress(_a0 context.Context, _a1 *org.UpdateOrgAddressCommand) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for UpdateAddress")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.UpdateOrgAddressCommand) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// UpdateOrg provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) UpdateOrg(_a0 context.Context, _a1 *org.UpdateOrgCommand) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for UpdateOrg")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.UpdateOrgCommand) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// UpdateOrgUser provides a mock function with given fields: _a0, _a1
|
||||
func (_m *MockService) UpdateOrgUser(_a0 context.Context, _a1 *org.UpdateOrgUserCommand) error {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for UpdateOrgUser")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *org.UpdateOrgUserCommand) error); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewMockService creates a new instance of MockService. 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 NewMockService(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockService {
|
||||
mock := &MockService{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
Loading…
Reference in New Issue
Block a user