Compare commits

..

1 Commits

Author SHA1 Message Date
Vinícius Lourenço
b0bc515cf4 fix(member-settings): sidenav button not redirecting to correct invite members modal 2026-06-26 11:52:55 -03:00
21 changed files with 87 additions and 310 deletions

View File

@@ -374,7 +374,7 @@ func (provider *provider) Delete(ctx context.Context, orgID valuer.UUID, id valu
}
for _, cb := range provider.onBeforeRoleDelete {
if err := cb(ctx, orgID, id, role.Name); err != nil {
if err := cb(ctx, orgID, id); err != nil {
return err
}
}

View File

@@ -9,6 +9,7 @@ import EditMemberDrawer from 'components/EditMemberDrawer/EditMemberDrawer';
import InviteMembersModal from 'components/InviteMembersModal/InviteMembersModal';
import MembersTable, { MemberRow } from 'components/MembersTable/MembersTable';
import useUrlQuery from 'hooks/useUrlQuery';
import { parseAsBoolean, useQueryState } from 'nuqs';
import { toISOString } from 'utils/app';
import { FilterMode, MemberStatus, toMemberStatus } from './utils';
@@ -26,7 +27,10 @@ function MembersSettings(): JSX.Element {
// TODO(nuqs): Replace with nuqs once the nuqs setup and integration is done - for search
const [searchQuery, setSearchQuery] = useState('');
const [filterMode, setFilterMode] = useState<FilterMode>(FilterMode.All);
const [isInviteModalOpen, setIsInviteModalOpen] = useState(false);
const [isInviteModalOpen, setIsInviteModalOpen] = useQueryState(
'invite',
parseAsBoolean.withDefault(false),
);
const [selectedMember, setSelectedMember] = useState<MemberRow | null>(null);
const { data: usersData, isLoading, refetch: refetchUsers } = useListUsers();
@@ -201,7 +205,7 @@ function MembersSettings(): JSX.Element {
<Button
variant="solid"
color="primary"
onClick={(): void => setIsInviteModalOpen(true)}
onClick={(): void => void setIsInviteModalOpen(true)}
>
<Plus size={12} />
Invite member
@@ -221,7 +225,7 @@ function MembersSettings(): JSX.Element {
<InviteMembersModal
open={isInviteModalOpen}
onClose={(): void => setIsInviteModalOpen(false)}
onClose={(): void => void setIsInviteModalOpen(null)}
onComplete={handleInviteComplete}
/>

View File

@@ -130,4 +130,14 @@ describe('MembersSettings (integration)', () => {
screen.findAllByPlaceholderText('john@signoz.io'),
).resolves.toHaveLength(3);
});
it('opens InviteMembersModal when invite=true query param is present', async () => {
render(<MembersSettings />, undefined, {
initialRoute: '/settings/members?invite=true',
});
await expect(
screen.findAllByPlaceholderText('john@signoz.io'),
).resolves.toHaveLength(3);
});
});

View File

@@ -58,7 +58,6 @@
}
.metrics-table-container {
padding-bottom: 48px;
.ant-table {
margin-left: -16px;
margin-right: -16px;

View File

@@ -885,9 +885,9 @@ function SideNav({ isPinned }: { isPinned: boolean }): JSX.Element {
break;
case 'invite-collaborators':
if (event && isModifierKeyPressed(event)) {
openInNewTab(`${ROUTES.ORG_SETTINGS}#invite-team-members`);
openInNewTab(`${ROUTES.MEMBERS_SETTINGS}?invite=true`);
} else {
history.push(`${ROUTES.ORG_SETTINGS}#invite-team-members`);
history.push(`${ROUTES.MEMBERS_SETTINGS}?invite=true`);
}
break;
case 'chat-support':

View File

@@ -66,7 +66,7 @@ export const homeMenuItem = {
};
export const inviteMemberMenuItem = {
key: `${ROUTES.ORG_SETTINGS}#invite-team-members`,
key: `${ROUTES.MEMBERS_SETTINGS}?invite=true`,
label: 'Invite Team Member',
icon: <UserPlus size={16} />,
};

View File

@@ -95,7 +95,7 @@ type AuthZ interface {
}
// OnBeforeRoleDelete is a callback invoked before a role is deleted.
type OnBeforeRoleDelete func(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID, roleName string) error
type OnBeforeRoleDelete func(context.Context, valuer.UUID, valuer.UUID) error
type Handler interface {
Create(http.ResponseWriter, *http.Request)

View File

@@ -44,7 +44,3 @@ type Handler interface {
Update(http.ResponseWriter, *http.Request)
Delete(http.ResponseWriter, *http.Request)
}
type Getter interface {
OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID, roleName string) error
}

View File

@@ -1,45 +0,0 @@
package implauthdomain
import (
"context"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
type getter struct {
store authtypes.AuthDomainStore
}
func NewGetter(store authtypes.AuthDomainStore) authdomain.Getter {
return &getter{store: store}
}
func (getter *getter) OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID, roleName string) error {
domains, err := getter.store.ListByOrgID(ctx, orgID)
if err != nil {
return err
}
referencedBy := make([]string, 0)
for _, domain := range domains {
for _, mappedRole := range domain.AuthDomainConfig().RoleMapping.RoleNames() {
if mappedRole == roleName {
referencedBy = append(referencedBy, domain.StorableAuthDomain().Name)
break
}
}
}
if len(referencedBy) > 0 {
return errors.WithAdditionalf(
errors.New(errors.TypeInvalidInput, authtypes.ErrCodeRoleHasAuthDomainMappings, "role is referenced by an SSO role mapping, remove it before deleting"),
"referenced by auth domain(s): %s", strings.Join(referencedBy, ", "),
)
}
return nil
}

View File

@@ -4,7 +4,6 @@ import (
"context"
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/modules/authdomain"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/valuer"
@@ -13,18 +12,13 @@ import (
type module struct {
store authtypes.AuthDomainStore
authNs map[authtypes.AuthNProvider]authn.AuthN
authz authz.AuthZ
}
func NewModule(store authtypes.AuthDomainStore, authNs map[authtypes.AuthNProvider]authn.AuthN, authz authz.AuthZ) authdomain.Module {
return &module{store: store, authNs: authNs, authz: authz}
func NewModule(store authtypes.AuthDomainStore, authNs map[authtypes.AuthNProvider]authn.AuthN) authdomain.Module {
return &module{store: store, authNs: authNs}
}
func (module *module) Create(ctx context.Context, domain *authtypes.AuthDomain) error {
if err := module.validateRoleMapping(ctx, domain); err != nil {
return err
}
return module.store.Create(ctx, domain)
}
@@ -56,10 +50,6 @@ func (module *module) ListByOrgID(ctx context.Context, orgID valuer.UUID) ([]*au
}
func (module *module) Update(ctx context.Context, domain *authtypes.AuthDomain) error {
if err := module.validateRoleMapping(ctx, domain); err != nil {
return err
}
return module.store.Update(ctx, domain)
}
@@ -84,13 +74,3 @@ func (module *module) Collect(ctx context.Context, orgID valuer.UUID) (map[strin
return stats, nil
}
func (module *module) validateRoleMapping(ctx context.Context, domain *authtypes.AuthDomain) error {
roleNames := domain.AuthDomainConfig().RoleMapping.RoleNames()
if len(roleNames) == 0 {
return nil
}
_, err := module.authz.ListByOrgIDAndNames(ctx, domain.StorableAuthDomain().OrgID, roleNames)
return err
}

View File

@@ -18,7 +18,7 @@ func NewGetter(store serviceaccounttypes.Store) serviceaccount.Getter {
return &getter{store: store}
}
func (getter *getter) OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID, _ string) error {
func (getter *getter) OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID) error {
serviceAccounts, err := getter.store.GetServiceAccountsByOrgIDAndRoleID(ctx, orgID, roleID)
if err != nil {
return err

View File

@@ -13,7 +13,7 @@ import (
type Getter interface {
// OnBeforeRoleDelete checks if any service accounts are assigned to the role and rejects deletion if so.
OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID, roleName string) error
OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID) error
}
type Module interface {

View File

@@ -9,7 +9,6 @@ import (
"time"
"github.com/SigNoz/signoz/pkg/authn"
"github.com/SigNoz/signoz/pkg/authz"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/modules/authdomain"
@@ -30,10 +29,9 @@ type module struct {
authDomain authdomain.Module
tokenizer tokenizer.Tokenizer
orgGetter organization.Getter
authz authz.AuthZ
}
func NewModule(providerSettings factory.ProviderSettings, authNs map[authtypes.AuthNProvider]authn.AuthN, userSetter user.Setter, userGetter user.Getter, authDomain authdomain.Module, tokenizer tokenizer.Tokenizer, orgGetter organization.Getter, authz authz.AuthZ) session.Module {
func NewModule(providerSettings factory.ProviderSettings, authNs map[authtypes.AuthNProvider]authn.AuthN, userSetter user.Setter, userGetter user.Getter, authDomain authdomain.Module, tokenizer tokenizer.Tokenizer, orgGetter organization.Getter) session.Module {
return &module{
settings: factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/modules/session/implsession"),
authNs: authNs,
@@ -42,7 +40,6 @@ func NewModule(providerSettings factory.ProviderSettings, authNs map[authtypes.A
authDomain: authDomain,
tokenizer: tokenizer,
orgGetter: orgGetter,
authz: authz,
}
}
@@ -146,23 +143,15 @@ func (module *module) CreateCallbackAuthNSession(ctx context.Context, authNProvi
}
roleMapping := authDomain.AuthDomainConfig().RoleMapping
roleAttributeExists := false
if roleMapping != nil && roleMapping.UseRoleAttribute && callbackIdentity.Role != "" {
_, err := module.authz.GetByOrgIDAndName(ctx, callbackIdentity.OrgID, authtypes.NormalizeRoleName(callbackIdentity.Role))
if err == nil {
roleAttributeExists = true
}
}
roleNames := roleMapping.NewRolesFromCallbackIdentity(callbackIdentity, roleAttributeExists)
role := roleMapping.NewRoleFromCallbackIdentity(callbackIdentity)
signozManagedRole := authtypes.MustGetSigNozManagedRoleFromExistingRole(role)
newUser, err := types.NewUser(callbackIdentity.Name, callbackIdentity.Email, callbackIdentity.OrgID, types.UserStatusActive)
if err != nil {
return "", err
}
newUser, err = module.userSetter.GetOrCreateUser(ctx, newUser, user.WithRoleNames(roleNames))
newUser, err = module.userSetter.GetOrCreateUser(ctx, newUser, user.WithRoleNames([]string{signozManagedRole}))
if err != nil {
return "", err
}

View File

@@ -239,7 +239,7 @@ func (module *getter) VerifyResetPasswordToken(ctx context.Context, token string
return nil
}
func (module *getter) OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID, _ string) error {
func (module *getter) OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID) error {
users, err := module.GetUsersByOrgIDAndRoleID(ctx, orgID, roleID)
if err != nil {
return err

View File

@@ -96,7 +96,7 @@ type Getter interface {
GetUsersByOrgIDAndRoleID(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID) ([]*types.User, error)
// OnBeforeRoleDelete checks if any users are assigned to the role and rejects deletion if so.
OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID, roleName string) error
OnBeforeRoleDelete(ctx context.Context, orgID valuer.UUID, roleID valuer.UUID) error
// VerifyResetPasswordToken checks if a reset password token exists and is not expired.
VerifyResetPasswordToken(ctx context.Context, token string) error

View File

@@ -128,7 +128,6 @@ func NewModules(
}
userSetter := impluser.NewSetter(impluser.NewStore(sqlstore, providerSettings), tokenizer, emailing, providerSettings, orgSetter, authz, analytics, config.User, userRoleStore, userGetter, onDeleteUser)
ruleStore := sqlrulestore.NewRuleStore(sqlstore, queryParser, providerSettings)
authDomainModule := implauthdomain.NewModule(implauthdomain.NewStore(sqlstore), authNs, authz)
return Modules{
OrgGetter: orgGetter,
@@ -143,8 +142,8 @@ func NewModules(
QuickFilter: quickfilter,
TraceFunnel: impltracefunnel.NewModule(impltracefunnel.NewStore(sqlstore)),
RawDataExport: implrawdataexport.NewModule(querier),
AuthDomain: authDomainModule,
Session: implsession.NewModule(providerSettings, authNs, userSetter, userGetter, authDomainModule, tokenizer, orgGetter, authz),
AuthDomain: implauthdomain.NewModule(implauthdomain.NewStore(sqlstore), authNs),
Session: implsession.NewModule(providerSettings, authNs, userSetter, userGetter, implauthdomain.NewModule(implauthdomain.NewStore(sqlstore), authNs), tokenizer, orgGetter),
SpanPercentile: implspanpercentile.NewModule(querier, providerSettings),
Services: implservices.NewModule(querier, telemetryStore),
MetricsExplorer: implmetricsexplorer.NewModule(telemetryStore, telemetryMetadataStore, cache, ruleStore, dashboard, providerSettings, config.MetricsExplorer),

View File

@@ -215,7 +215,6 @@ func NewSQLMigrationProviderFactories(
sqlmigration.NewRecreateUserDashboardPreferenceFactory(sqlstore, sqlschema),
sqlmigration.NewMigrateRecurrenceBoundsFactory(sqlstore),
sqlmigration.NewAddDashboardViewFactory(sqlstore, sqlschema),
sqlmigration.NewMigrateSSORoleMappingNamesFactory(sqlstore),
)
}

View File

@@ -24,7 +24,6 @@ import (
"github.com/SigNoz/signoz/pkg/instrumentation"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/meterreporter"
"github.com/SigNoz/signoz/pkg/modules/authdomain/implauthdomain"
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
"github.com/SigNoz/signoz/pkg/modules/dashboard"
"github.com/SigNoz/signoz/pkg/modules/organization"
@@ -350,13 +349,10 @@ func New(
// Initialize service account getter
serviceAccountGetter := implserviceaccount.NewGetter(implserviceaccount.NewStore(sqlstore))
authDomainGetter := implauthdomain.NewGetter(implauthdomain.NewStore(sqlstore))
// Build pre-delete callbacks from modules
onBeforeRoleDelete := []authz.OnBeforeRoleDelete{
userGetter.OnBeforeRoleDelete,
serviceAccountGetter.OnBeforeRoleDelete,
authDomainGetter.OnBeforeRoleDelete,
}
// Initialize authz

View File

@@ -1,127 +0,0 @@
package sqlmigration
import (
"context"
"encoding/json"
"log/slog"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/factory"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/uptrace/bun"
"github.com/uptrace/bun/migrate"
)
type migrateSSORoleMappingNames struct {
sqlstore sqlstore.SQLStore
logger *slog.Logger
}
type authDomainRow struct {
bun.BaseModel `bun:"table:auth_domain"`
ID string `bun:"id"`
Data string `bun:"data"`
}
var legacyRoleToManagedRoleName = map[string]string{
"ADMIN": "signoz-admin",
"EDITOR": "signoz-editor",
"VIEWER": "signoz-viewer",
}
type ssoRoleMapping struct {
DefaultRole string `json:"defaultRole"`
GroupMappings map[string]string `json:"groupMappings"`
UseRoleAttribute bool `json:"useRoleAttribute"`
}
func NewMigrateSSORoleMappingNamesFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
return factory.NewProviderFactory(
factory.MustNewName("migrate_sso_role_mapping_names"),
func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
return &migrateSSORoleMappingNames{sqlstore: sqlstore, logger: ps.Logger}, nil
},
)
}
func (migration *migrateSSORoleMappingNames) Register(migrations *migrate.Migrations) error {
return migrations.Register(migration.Up, migration.Down)
}
func (migration *migrateSSORoleMappingNames) Up(ctx context.Context, db *bun.DB) error {
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer func() {
_ = tx.Rollback()
}()
rows := make([]*authDomainRow, 0)
if err := tx.NewSelect().Model(&rows).Scan(ctx); err != nil {
return err
}
for _, row := range rows {
config := make(map[string]json.RawMessage)
if err := json.Unmarshal([]byte(row.Data), &config); err != nil {
migration.logger.WarnContext(ctx, "skipping auth domain with unreadable data", slog.String("auth_domain_id", row.ID), errors.Attr(err))
continue
}
roleMappingRaw, ok := config["roleMapping"]
if !ok || string(roleMappingRaw) == "null" {
continue
}
var roleMapping ssoRoleMapping
if err := json.Unmarshal(roleMappingRaw, &roleMapping); err != nil {
migration.logger.WarnContext(ctx, "skipping auth domain with unreadable role mapping", slog.String("auth_domain_id", row.ID), errors.Attr(err))
continue
}
changed := false
if managed, ok := legacyRoleToManagedRoleName[strings.ToUpper(roleMapping.DefaultRole)]; ok {
roleMapping.DefaultRole = managed
changed = true
}
for group, role := range roleMapping.GroupMappings {
if managed, ok := legacyRoleToManagedRoleName[strings.ToUpper(role)]; ok {
roleMapping.GroupMappings[group] = managed
changed = true
}
}
if !changed {
continue
}
newRoleMapping, err := json.Marshal(roleMapping)
if err != nil {
return err
}
config["roleMapping"] = newRoleMapping
newData, err := json.Marshal(config)
if err != nil {
return err
}
if _, err := tx.NewUpdate().
Model((*authDomainRow)(nil)).
Set("data = ?", string(newData)).
Where("id = ?", row.ID).
Exec(ctx); err != nil {
return err
}
}
return tx.Commit()
}
func (migration *migrateSSORoleMappingNames) Down(context.Context, *bun.DB) error {
return nil
}

View File

@@ -2,6 +2,10 @@ package authtypes
import (
"encoding/json"
"strings"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/types"
)
type AttributeMapping struct {
@@ -47,95 +51,83 @@ func (attr *AttributeMapping) UnmarshalJSON(data []byte) error {
}
type RoleMapping struct {
// Default role assigned to new SSO users when no group mapping applies.
// Default role any new SSO users. Defaults to "VIEWER"
DefaultRole string `json:"defaultRole"`
// Map of IDP group name to SigNoz role name.
// Map of IDP group names to SigNoz roles. Key is group name, value is SigNoz role
GroupMappings map[string]string `json:"groupMappings"`
// If true, use the role claim directly from IDP instead of group mappings.
// If true, use the role claim directly from IDP instead of group mappings
UseRoleAttribute bool `json:"useRoleAttribute"`
}
func (roleMapping *RoleMapping) UnmarshalJSON(data []byte) error {
type alias RoleMapping
func (typ *RoleMapping) UnmarshalJSON(data []byte) error {
type Alias RoleMapping
var temp alias
var temp Alias
if err := json.Unmarshal(data, &temp); err != nil {
return err
}
temp.DefaultRole = NormalizeRoleName(temp.DefaultRole)
for group, role := range temp.GroupMappings {
temp.GroupMappings[group] = NormalizeRoleName(role)
if temp.DefaultRole != "" {
if _, err := types.NewRole(strings.ToUpper(temp.DefaultRole)); err != nil {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "invalid default role %s", temp.DefaultRole)
}
}
*roleMapping = RoleMapping(temp)
for group, role := range temp.GroupMappings {
if _, err := types.NewRole(strings.ToUpper(role)); err != nil {
return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "invalid role %s for group %s", role, group)
}
}
*typ = RoleMapping(temp)
return nil
}
func (roleMapping *RoleMapping) NewRolesFromCallbackIdentity(callbackIdentity *CallbackIdentity, roleAttributeExists bool) []string {
func (roleMapping *RoleMapping) NewRoleFromCallbackIdentity(callbackIdentity *CallbackIdentity) types.Role {
if roleMapping == nil {
return []string{SigNozViewerRoleName}
return types.RoleViewer
}
if roleAttributeExists {
return []string{NormalizeRoleName(callbackIdentity.Role)}
if roleMapping.UseRoleAttribute && callbackIdentity.Role != "" {
if role, err := types.NewRole(strings.ToUpper(callbackIdentity.Role)); err == nil {
return role
}
}
if len(roleMapping.GroupMappings) > 0 && len(callbackIdentity.Groups) > 0 {
roleNames := make([]string, 0)
seen := make(map[string]struct{})
highestRole := types.RoleViewer
found := false
for _, group := range callbackIdentity.Groups {
roleName, exists := roleMapping.GroupMappings[group]
if !exists {
continue
if mappedRole, exists := roleMapping.GroupMappings[group]; exists {
found = true
if role, err := types.NewRole(strings.ToUpper(mappedRole)); err == nil {
if compareRoles(role, highestRole) > 0 {
highestRole = role
}
}
}
if _, duplicate := seen[roleName]; duplicate {
continue
}
seen[roleName] = struct{}{}
roleNames = append(roleNames, roleName)
}
if len(roleNames) > 0 {
return roleNames
if found {
return highestRole
}
}
return []string{roleMapping.DefaultRoleName()}
}
func (roleMapping *RoleMapping) DefaultRoleName() string {
if roleMapping.DefaultRole != "" {
return roleMapping.DefaultRole
}
return SigNozViewerRoleName
}
func (roleMapping *RoleMapping) RoleNames() []string {
if roleMapping == nil {
return nil
}
seen := make(map[string]struct{})
roleNames := make([]string, 0, len(roleMapping.GroupMappings)+1)
if roleMapping.DefaultRole != "" {
seen[roleMapping.DefaultRole] = struct{}{}
roleNames = append(roleNames, roleMapping.DefaultRole)
if role, err := types.NewRole(strings.ToUpper(roleMapping.DefaultRole)); err == nil {
return role
}
}
for _, roleName := range roleMapping.GroupMappings {
if roleName == "" {
continue
}
if _, duplicate := seen[roleName]; duplicate {
continue
}
seen[roleName] = struct{}{}
roleNames = append(roleNames, roleName)
}
return roleNames
return types.RoleViewer
}
func compareRoles(a, b types.Role) int {
order := map[types.Role]int{
types.RoleViewer: 0,
types.RoleEditor: 1,
types.RoleAdmin: 2,
}
return order[a] - order[b]
}

View File

@@ -25,7 +25,6 @@ var (
ErrCodeRoleUnsupported = errors.MustNewCode("role_unsupported")
ErrCodeRoleHasUserAssignees = errors.MustNewCode("role_has_user_assignees")
ErrCodeRoleHasServiceAccountAssignees = errors.MustNewCode("role_has_service_account_assignees")
ErrCodeRoleHasAuthDomainMappings = errors.MustNewCode("role_has_auth_domain_mappings")
)
var (
@@ -318,20 +317,6 @@ func MustGetSigNozManagedRoleFromExistingRole(role types.Role) string {
return managedRole
}
func NormalizeRoleName(role string) string {
legacyRole, err := types.NewRole(strings.ToUpper(role))
if err != nil {
return role
}
managedRole, ok := ExistingRoleToSigNozManagedRoleMap[legacyRole]
if !ok {
return role
}
return managedRole
}
type RoleStore interface {
Create(context.Context, *Role) error
Get(context.Context, valuer.UUID, valuer.UUID) (*Role, error)