From be5ced42878bc6e96f6c8d59d6db2fb6a0803f92 Mon Sep 17 00:00:00 2001 From: Karl Persson Date: Wed, 8 May 2024 14:03:53 +0200 Subject: [PATCH] Identity: Use typed version of namespace id (#87257) * Remove different constructors and only use NewNamespaceID * AdminUser: check typed namespace id * Identity: Add convinient function to parse valid user id when type is either user or service account * Annotations: Use typed namespace id instead --- pkg/api/admin_users.go | 13 ++----- pkg/api/annotations.go | 15 ++++---- .../accesscontrol/authorize_in_org_test.go | 2 +- pkg/services/auth/identity/namespace.go | 34 +++++++------------ pkg/services/authn/authnimpl/service_test.go | 12 +++---- .../authn/authnimpl/sync/rbac_sync_test.go | 10 +++--- .../authn/authnimpl/sync/user_sync.go | 2 +- .../authn/authnimpl/sync/user_sync_test.go | 6 ++-- pkg/services/authn/clients/api_key.go | 4 +-- pkg/services/authn/clients/grafana.go | 2 +- pkg/services/authn/clients/proxy.go | 2 +- pkg/services/authn/clients/proxy_test.go | 2 +- pkg/services/authn/clients/render.go | 4 +-- pkg/services/authn/clients/session.go | 2 +- pkg/services/authn/namespace.go | 12 +++---- .../contexthandler/contexthandler_test.go | 2 +- pkg/services/user/userimpl/verifier.go | 2 +- 17 files changed, 52 insertions(+), 74 deletions(-) diff --git a/pkg/api/admin_users.go b/pkg/api/admin_users.go index 3908900f8e6..81721a2d596 100644 --- a/pkg/api/admin_users.go +++ b/pkg/api/admin_users.go @@ -13,7 +13,7 @@ import ( "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/auth" - "github.com/grafana/grafana/pkg/services/auth/identity" + "github.com/grafana/grafana/pkg/services/authn" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/login" "github.com/grafana/grafana/pkg/services/org" @@ -366,15 +366,8 @@ func (hs *HTTPServer) AdminLogoutUser(c *contextmodel.ReqContext) response.Respo return response.Error(http.StatusBadRequest, "id is invalid", err) } - namespace, identifier := c.SignedInUser.GetNamespacedID() - if namespace == identity.NamespaceUser { - activeUserID, err := identity.IntIdentifier(namespace, identifier) - if err != nil { - return response.Error(http.StatusInternalServerError, "Failed to parse active user id", err) - } - if activeUserID == userID { - return response.Error(http.StatusBadRequest, "You cannot logout yourself", nil) - } + if c.SignedInUser.GetID() == authn.NewNamespaceID(authn.NamespaceUser, userID) { + return response.Error(http.StatusBadRequest, "You cannot logout yourself", nil) } return hs.logoutUserFromAllDevicesInternal(c.Req.Context(), userID) diff --git a/pkg/api/annotations.go b/pkg/api/annotations.go index 717d8601ca2..31e11eff73d 100644 --- a/pkg/api/annotations.go +++ b/pkg/api/annotations.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/annotations" - "github.com/grafana/grafana/pkg/services/auth/identity" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -141,7 +140,7 @@ func (hs *HTTPServer) PostAnnotation(c *contextmodel.ReqContext) response.Respon return response.Error(http.StatusBadRequest, "Failed to save annotation", err) } - userID, err := identity.UserIdentifier(c.SignedInUser.GetNamespacedID()) + userID, err := c.SignedInUser.GetID().UserID() if err != nil { return response.Error(http.StatusInternalServerError, "Failed to save annotation", err) } @@ -228,7 +227,7 @@ func (hs *HTTPServer) PostGraphiteAnnotation(c *contextmodel.ReqContext) respons return response.Error(http.StatusBadRequest, "Failed to save Graphite annotation", err) } - userID, err := identity.UserIdentifier(c.SignedInUser.GetNamespacedID()) + userID, err := c.SignedInUser.GetID().UserID() if err != nil { return response.Error(http.StatusInternalServerError, "Failed to save Graphite annotation", err) } @@ -285,10 +284,9 @@ func (hs *HTTPServer) UpdateAnnotation(c *contextmodel.ReqContext) response.Resp } } - userID, err := identity.UserIdentifier(c.SignedInUser.GetNamespacedID()) + userID, err := c.SignedInUser.GetID().UserID() if err != nil { - return response.Error(http.StatusInternalServerError, - "Failed to update annotation", err) + return response.Error(http.StatusInternalServerError, "Failed to update annotation", err) } item := annotations.Item{ @@ -348,10 +346,9 @@ func (hs *HTTPServer) PatchAnnotation(c *contextmodel.ReqContext) response.Respo } } - userID, err := identity.UserIdentifier(c.SignedInUser.GetNamespacedID()) + userID, err := c.SignedInUser.GetID().UserID() if err != nil { - return response.Error(http.StatusInternalServerError, - "Failed to update annotation", err) + return response.Error(http.StatusInternalServerError, "Failed to update annotation", err) } existing := annotations.Item{ diff --git a/pkg/services/accesscontrol/authorize_in_org_test.go b/pkg/services/accesscontrol/authorize_in_org_test.go index c0c91734cba..6b816fb679d 100644 --- a/pkg/services/accesscontrol/authorize_in_org_test.go +++ b/pkg/services/accesscontrol/authorize_in_org_test.go @@ -186,7 +186,7 @@ func TestAuthorizeInOrgMiddleware(t *testing.T) { req := httptest.NewRequest(http.MethodGet, "/api/endpoint", nil) expectedIdentity := &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, tc.ctxSignedInUser.UserID), + ID: authn.NewNamespaceID(authn.NamespaceUser, tc.ctxSignedInUser.UserID), OrgID: tc.targetOrgId, Permissions: map[int64]map[string][]string{}, } diff --git a/pkg/services/auth/identity/namespace.go b/pkg/services/auth/identity/namespace.go index 81ae0daa664..aa3a38d3994 100644 --- a/pkg/services/auth/identity/namespace.go +++ b/pkg/services/auth/identity/namespace.go @@ -41,7 +41,7 @@ func ParseNamespace(str string) (Namespace, error) { } } -var AnonymousNamespaceID = MustNewNamespaceID(NamespaceAnonymous, 0) +var AnonymousNamespaceID = NewNamespaceID(NamespaceAnonymous, 0) func ParseNamespaceID(str string) (NamespaceID, error) { var namespaceID NamespaceID @@ -72,27 +72,7 @@ func MustParseNamespaceID(str string) NamespaceID { return namespaceID } -// NewNamespaceID creates a new NamespaceID, will fail for invalid namespace. -func NewNamespaceID(namespace Namespace, id int64) (NamespaceID, error) { - return NamespaceID{ - id: strconv.FormatInt(id, 10), - namespace: namespace, - }, nil -} - -// MustNewNamespaceID creates a new NamespaceID, will panic for invalid namespace. -// Suitable to use in tests or when we can guarantee that we pass a correct format. -func MustNewNamespaceID(namespace Namespace, id int64) NamespaceID { - namespaceID, err := NewNamespaceID(namespace, id) - if err != nil { - panic(err) - } - return namespaceID -} - -// NewNamespaceIDUnchecked creates a new NamespaceID without checking if namespace is valid. -// It us up to the caller to ensure that namespace is valid. -func NewNamespaceIDUnchecked(namespace Namespace, id int64) NamespaceID { +func NewNamespaceID(namespace Namespace, id int64) NamespaceID { return NamespaceID{ id: strconv.FormatInt(id, 10), namespace: namespace, @@ -117,6 +97,16 @@ func (ni NamespaceID) ID() string { return ni.id } +// UserID will try to parse and int64 identifier if namespace is either user or service-account. +// For all other namespaces '0' will be returned. +func (ni NamespaceID) UserID() (int64, error) { + if ni.IsNamespace(NamespaceUser, NamespaceServiceAccount) { + return ni.ParseInt() + } + return 0, nil +} + +// ParseInt will try to parse the id as an int64 identifier. func (ni NamespaceID) ParseInt() (int64, error) { return strconv.ParseInt(ni.id, 10, 64) } diff --git a/pkg/services/authn/authnimpl/service_test.go b/pkg/services/authn/authnimpl/service_test.go index 01f82c6d134..2b673c8c85d 100644 --- a/pkg/services/authn/authnimpl/service_test.go +++ b/pkg/services/authn/authnimpl/service_test.go @@ -419,31 +419,31 @@ func TestService_Logout(t *testing.T) { tests := []TestCase{ { desc: "should redirect to default redirect url when identity is not a user", - identity: &authn.Identity{ID: authn.MustNewNamespaceID(authn.NamespaceServiceAccount, 1)}, + identity: &authn.Identity{ID: authn.NewNamespaceID(authn.NamespaceServiceAccount, 1)}, expectedRedirect: &authn.Redirect{URL: "http://localhost:3000/login"}, }, { desc: "should redirect to default redirect url when no external provider was used to authenticate", - identity: &authn.Identity{ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1)}, + identity: &authn.Identity{ID: authn.NewNamespaceID(authn.NamespaceUser, 1)}, expectedRedirect: &authn.Redirect{URL: "http://localhost:3000/login"}, expectedTokenRevoked: true, }, { desc: "should redirect to default redirect url when client is not found", - identity: &authn.Identity{ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), AuthenticatedBy: "notfound"}, + identity: &authn.Identity{ID: authn.NewNamespaceID(authn.NamespaceUser, 1), AuthenticatedBy: "notfound"}, expectedRedirect: &authn.Redirect{URL: "http://localhost:3000/login"}, expectedTokenRevoked: true, }, { desc: "should redirect to default redirect url when client do not implement logout extension", - identity: &authn.Identity{ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), AuthenticatedBy: "azuread"}, + identity: &authn.Identity{ID: authn.NewNamespaceID(authn.NamespaceUser, 1), AuthenticatedBy: "azuread"}, expectedRedirect: &authn.Redirect{URL: "http://localhost:3000/login"}, client: &authntest.FakeClient{ExpectedName: "auth.client.azuread"}, expectedTokenRevoked: true, }, { desc: "should redirect to client specific url", - identity: &authn.Identity{ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), AuthenticatedBy: "azuread"}, + identity: &authn.Identity{ID: authn.NewNamespaceID(authn.NamespaceUser, 1), AuthenticatedBy: "azuread"}, expectedRedirect: &authn.Redirect{URL: "http://idp.com/logout"}, client: &authntest.MockClient{ NameFunc: func() string { return "auth.client.azuread" }, @@ -487,7 +487,7 @@ func TestService_Logout(t *testing.T) { func TestService_ResolveIdentity(t *testing.T) { t.Run("should return error for for unknown namespace", func(t *testing.T) { svc := setupTests(t) - _, err := svc.ResolveIdentity(context.Background(), 1, authn.NewNamespaceIDUnchecked("some", 1)) + _, err := svc.ResolveIdentity(context.Background(), 1, authn.NewNamespaceID("some", 1)) assert.ErrorIs(t, err, authn.ErrUnsupportedIdentity) }) diff --git a/pkg/services/authn/authnimpl/sync/rbac_sync_test.go b/pkg/services/authn/authnimpl/sync/rbac_sync_test.go index a29c4c7c814..aab1b95097b 100644 --- a/pkg/services/authn/authnimpl/sync/rbac_sync_test.go +++ b/pkg/services/authn/authnimpl/sync/rbac_sync_test.go @@ -64,7 +64,7 @@ func TestRBACSync_SyncCloudRoles(t *testing.T) { desc: "should call sync when authenticated with grafana com and has viewer role", module: login.GrafanaComAuthModule, identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), + ID: authn.NewNamespaceID(authn.NamespaceUser, 1), OrgID: 1, OrgRoles: map[int64]org.RoleType{1: org.RoleViewer}, }, @@ -75,7 +75,7 @@ func TestRBACSync_SyncCloudRoles(t *testing.T) { desc: "should call sync when authenticated with grafana com and has editor role", module: login.GrafanaComAuthModule, identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), + ID: authn.NewNamespaceID(authn.NamespaceUser, 1), OrgID: 1, OrgRoles: map[int64]org.RoleType{1: org.RoleEditor}, }, @@ -86,7 +86,7 @@ func TestRBACSync_SyncCloudRoles(t *testing.T) { desc: "should call sync when authenticated with grafana com and has admin role", module: login.GrafanaComAuthModule, identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), + ID: authn.NewNamespaceID(authn.NamespaceUser, 1), OrgID: 1, OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin}, }, @@ -97,7 +97,7 @@ func TestRBACSync_SyncCloudRoles(t *testing.T) { desc: "should not call sync when authenticated with grafana com and has invalid role", module: login.GrafanaComAuthModule, identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), + ID: authn.NewNamespaceID(authn.NamespaceUser, 1), OrgID: 1, OrgRoles: map[int64]org.RoleType{1: org.RoleType("something else")}, }, @@ -108,7 +108,7 @@ func TestRBACSync_SyncCloudRoles(t *testing.T) { desc: "should not call sync when not authenticated with grafana com", module: login.LDAPAuthModule, identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), + ID: authn.NewNamespaceID(authn.NamespaceUser, 1), OrgID: 1, OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin}, }, diff --git a/pkg/services/authn/authnimpl/sync/user_sync.go b/pkg/services/authn/authnimpl/sync/user_sync.go index 864e0d57168..66dacaa85ca 100644 --- a/pkg/services/authn/authnimpl/sync/user_sync.go +++ b/pkg/services/authn/authnimpl/sync/user_sync.go @@ -389,7 +389,7 @@ func (s *UserSync) lookupByOneOf(ctx context.Context, params login.UserLookupPar // syncUserToIdentity syncs a user to an identity. // This is used to update the identity with the latest user information. func syncUserToIdentity(usr *user.User, id *authn.Identity) { - id.ID = authn.NewNamespaceIDUnchecked(authn.NamespaceUser, usr.ID) + id.ID = authn.NewNamespaceID(authn.NamespaceUser, usr.ID) id.Login = usr.Login id.Email = usr.Email id.Name = usr.Name diff --git a/pkg/services/authn/authnimpl/sync/user_sync_test.go b/pkg/services/authn/authnimpl/sync/user_sync_test.go index 4e861a6ad1f..d9470adaa8b 100644 --- a/pkg/services/authn/authnimpl/sync/user_sync_test.go +++ b/pkg/services/authn/authnimpl/sync/user_sync_test.go @@ -470,7 +470,7 @@ func TestUserSync_EnableDisabledUserHook(t *testing.T) { { desc: "should skip if correct flag is not set", identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), + ID: authn.NewNamespaceID(authn.NamespaceUser, 1), IsDisabled: true, ClientParams: authn.ClientParams{EnableUser: false}, }, @@ -479,7 +479,7 @@ func TestUserSync_EnableDisabledUserHook(t *testing.T) { { desc: "should skip if identity is not a user", identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceAPIKey, 1), + ID: authn.NewNamespaceID(authn.NamespaceAPIKey, 1), IsDisabled: true, ClientParams: authn.ClientParams{EnableUser: true}, }, @@ -488,7 +488,7 @@ func TestUserSync_EnableDisabledUserHook(t *testing.T) { { desc: "should enabled disabled user", identity: &authn.Identity{ - ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), + ID: authn.NewNamespaceID(authn.NamespaceUser, 1), IsDisabled: true, ClientParams: authn.ClientParams{EnableUser: true}, }, diff --git a/pkg/services/authn/clients/api_key.go b/pkg/services/authn/clients/api_key.go index b9d2e746f8a..5f549151b81 100644 --- a/pkg/services/authn/clients/api_key.go +++ b/pkg/services/authn/clients/api_key.go @@ -255,7 +255,7 @@ func validateApiKey(orgID int64, key *apikey.APIKey) error { func newAPIKeyIdentity(key *apikey.APIKey) *authn.Identity { return &authn.Identity{ - ID: authn.NewNamespaceIDUnchecked(authn.NamespaceAPIKey, key.ID), + ID: authn.NewNamespaceID(authn.NamespaceAPIKey, key.ID), OrgID: key.OrgID, OrgRoles: map[int64]org.RoleType{key.OrgID: key.Role}, ClientParams: authn.ClientParams{SyncPermissions: true}, @@ -265,7 +265,7 @@ func newAPIKeyIdentity(key *apikey.APIKey) *authn.Identity { func newServiceAccountIdentity(key *apikey.APIKey) *authn.Identity { return &authn.Identity{ - ID: authn.NewNamespaceIDUnchecked(authn.NamespaceServiceAccount, *key.ServiceAccountId), + ID: authn.NewNamespaceID(authn.NamespaceServiceAccount, *key.ServiceAccountId), OrgID: key.OrgID, AuthenticatedBy: login.APIKeyAuthModule, ClientParams: authn.ClientParams{FetchSyncedUser: true, SyncPermissions: true}, diff --git a/pkg/services/authn/clients/grafana.go b/pkg/services/authn/clients/grafana.go index e95fb2f5828..6d2a2747776 100644 --- a/pkg/services/authn/clients/grafana.go +++ b/pkg/services/authn/clients/grafana.go @@ -105,7 +105,7 @@ func (c *Grafana) AuthenticatePassword(ctx context.Context, r *authn.Request, us } return &authn.Identity{ - ID: authn.NewNamespaceIDUnchecked(authn.NamespaceUser, usr.ID), + ID: authn.NewNamespaceID(authn.NamespaceUser, usr.ID), OrgID: r.OrgID, ClientParams: authn.ClientParams{FetchSyncedUser: true, SyncPermissions: true}, AuthenticatedBy: login.PasswordAuthModule, diff --git a/pkg/services/authn/clients/proxy.go b/pkg/services/authn/clients/proxy.go index 92ebf0c2250..3878ba96f6f 100644 --- a/pkg/services/authn/clients/proxy.go +++ b/pkg/services/authn/clients/proxy.go @@ -124,7 +124,7 @@ func (c *Proxy) retrieveIDFromCache(ctx context.Context, cacheKey string, r *aut } return &authn.Identity{ - ID: authn.NewNamespaceIDUnchecked(authn.NamespaceUser, uid), + ID: authn.NewNamespaceID(authn.NamespaceUser, uid), OrgID: r.OrgID, // FIXME: This does not match the actual auth module used, but should not have any impact // Maybe caching the auth module used with the user ID would be a good idea diff --git a/pkg/services/authn/clients/proxy_test.go b/pkg/services/authn/clients/proxy_test.go index d55bd68484e..92086a6d87e 100644 --- a/pkg/services/authn/clients/proxy_test.go +++ b/pkg/services/authn/clients/proxy_test.go @@ -203,7 +203,7 @@ func TestProxy_Hook(t *testing.T) { } cache := &fakeCache{data: make(map[string][]byte)} userId := int64(1) - userID := authn.MustNewNamespaceID(authn.NamespaceUser, userId) + userID := authn.NewNamespaceID(authn.NamespaceUser, userId) // withRole creates a test case for a user with a specific role. withRole := func(role string) func(t *testing.T) { diff --git a/pkg/services/authn/clients/render.go b/pkg/services/authn/clients/render.go index 39f6922d258..9e7dccb1dee 100644 --- a/pkg/services/authn/clients/render.go +++ b/pkg/services/authn/clients/render.go @@ -42,7 +42,7 @@ func (c *Render) Authenticate(ctx context.Context, r *authn.Request) (*authn.Ide if renderUsr.UserID <= 0 { return &authn.Identity{ - ID: authn.NewNamespaceIDUnchecked(authn.NamespaceRenderService, 0), + ID: authn.NewNamespaceID(authn.NamespaceRenderService, 0), OrgID: renderUsr.OrgID, OrgRoles: map[int64]org.RoleType{renderUsr.OrgID: org.RoleType(renderUsr.OrgRole)}, ClientParams: authn.ClientParams{SyncPermissions: true}, @@ -52,7 +52,7 @@ func (c *Render) Authenticate(ctx context.Context, r *authn.Request) (*authn.Ide } return &authn.Identity{ - ID: authn.NewNamespaceIDUnchecked(authn.NamespaceUser, renderUsr.UserID), + ID: authn.NewNamespaceID(authn.NamespaceUser, renderUsr.UserID), LastSeenAt: time.Now(), AuthenticatedBy: login.RenderModule, ClientParams: authn.ClientParams{FetchSyncedUser: true, SyncPermissions: true}, diff --git a/pkg/services/authn/clients/session.go b/pkg/services/authn/clients/session.go index dc928107ba5..603a3bf64bc 100644 --- a/pkg/services/authn/clients/session.go +++ b/pkg/services/authn/clients/session.go @@ -57,7 +57,7 @@ func (s *Session) Authenticate(ctx context.Context, r *authn.Request) (*authn.Id } ident := &authn.Identity{ - ID: authn.NewNamespaceIDUnchecked(authn.NamespaceUser, token.UserId), + ID: authn.NewNamespaceID(authn.NamespaceUser, token.UserId), SessionToken: token, ClientParams: authn.ClientParams{ FetchSyncedUser: true, diff --git a/pkg/services/authn/namespace.go b/pkg/services/authn/namespace.go index 09d71052cc7..6c4c1220270 100644 --- a/pkg/services/authn/namespace.go +++ b/pkg/services/authn/namespace.go @@ -13,15 +13,13 @@ const ( NamespaceAccessPolicy = identity.NamespaceAccessPolicy ) -var AnonymousNamespaceID = MustNewNamespaceID(NamespaceAnonymous, 0) +var AnonymousNamespaceID = NewNamespaceID(NamespaceAnonymous, 0) type NamespaceID = identity.NamespaceID var ( - ParseNamespaceID = identity.ParseNamespaceID - MustParseNamespaceID = identity.MustParseNamespaceID - NewNamespaceID = identity.NewNamespaceID - MustNewNamespaceID = identity.MustNewNamespaceID - NewNamespaceIDUnchecked = identity.NewNamespaceIDUnchecked - ErrInvalidNamespaceID = identity.ErrInvalidNamespaceID + ParseNamespaceID = identity.ParseNamespaceID + MustParseNamespaceID = identity.MustParseNamespaceID + NewNamespaceID = identity.NewNamespaceID + ErrInvalidNamespaceID = identity.ErrInvalidNamespaceID ) diff --git a/pkg/services/contexthandler/contexthandler_test.go b/pkg/services/contexthandler/contexthandler_test.go index 3bdede4be3b..87a95be3cfe 100644 --- a/pkg/services/contexthandler/contexthandler_test.go +++ b/pkg/services/contexthandler/contexthandler_test.go @@ -44,7 +44,7 @@ func TestContextHandler(t *testing.T) { }) t.Run("should set identity on successful authentication", func(t *testing.T) { - identity := &authn.Identity{ID: authn.MustNewNamespaceID(authn.NamespaceUser, 1), OrgID: 1} + identity := &authn.Identity{ID: authn.NewNamespaceID(authn.NamespaceUser, 1), OrgID: 1} handler := contexthandler.ProvideService( setting.NewCfg(), tracing.InitializeTracerForTest(), diff --git a/pkg/services/user/userimpl/verifier.go b/pkg/services/user/userimpl/verifier.go index e4b62fa9d61..b9d3eb5775f 100644 --- a/pkg/services/user/userimpl/verifier.go +++ b/pkg/services/user/userimpl/verifier.go @@ -152,6 +152,6 @@ func (s *Verifier) Complete(ctx context.Context, cmd user.CompleteEmailVerifyCom // remove the current token, so a new one can be generated with correct values. return s.is.RemoveIDToken( ctx, - &authn.Identity{ID: authn.NewNamespaceIDUnchecked(authn.NamespaceUser, usr.ID), OrgID: usr.OrgID}, + &authn.Identity{ID: authn.NewNamespaceID(authn.NamespaceUser, usr.ID), OrgID: usr.OrgID}, ) }