mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 18:44:54 +08:00
AuthN: Fix namespaces for anonymous and render (#75661)
* AuthN: remove IsAnonymous from identity struct and set correct namespace for anonymous and render * Don't parse user id for render namespace
This commit is contained in:
@ -188,7 +188,7 @@ func getContextHandler(t *testing.T, cfg *setting.Cfg) *contexthandler.ContextHa
|
|||||||
cfg,
|
cfg,
|
||||||
tracing.InitializeTracerForTest(),
|
tracing.InitializeTracerForTest(),
|
||||||
featuremgmt.WithFeatures(),
|
featuremgmt.WithFeatures(),
|
||||||
&authntest.FakeService{ExpectedIdentity: &authn.Identity{IsAnonymous: true, SessionToken: &usertoken.UserToken{}}},
|
&authntest.FakeService{ExpectedIdentity: &authn.Identity{ID: authn.AnonymousNamespaceID, SessionToken: &usertoken.UserToken{}}},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func TestAuth_Middleware(t *testing.T) {
|
|||||||
desc: "ReqSignedIn should return 200 for anonymous user",
|
desc: "ReqSignedIn should return 200 for anonymous user",
|
||||||
path: "/api/secure",
|
path: "/api/secure",
|
||||||
authMiddleware: ReqSignedIn,
|
authMiddleware: ReqSignedIn,
|
||||||
identity: &authn.Identity{IsAnonymous: true},
|
identity: &authn.Identity{ID: authn.AnonymousNamespaceID},
|
||||||
expecedReached: true,
|
expecedReached: true,
|
||||||
expectedCode: http.StatusOK,
|
expectedCode: http.StatusOK,
|
||||||
},
|
},
|
||||||
@ -65,7 +65,7 @@ func TestAuth_Middleware(t *testing.T) {
|
|||||||
desc: "ReqSignedIn should return redirect anonymous user with forceLogin query string",
|
desc: "ReqSignedIn should return redirect anonymous user with forceLogin query string",
|
||||||
path: "/secure?forceLogin=true",
|
path: "/secure?forceLogin=true",
|
||||||
authMiddleware: ReqSignedIn,
|
authMiddleware: ReqSignedIn,
|
||||||
identity: &authn.Identity{IsAnonymous: true},
|
identity: &authn.Identity{ID: authn.AnonymousNamespaceID},
|
||||||
expecedReached: false,
|
expecedReached: false,
|
||||||
expectedCode: http.StatusFound,
|
expectedCode: http.StatusFound,
|
||||||
},
|
},
|
||||||
@ -73,7 +73,7 @@ func TestAuth_Middleware(t *testing.T) {
|
|||||||
desc: "ReqSignedIn should return redirect anonymous user when orgId in query string is different from currently used",
|
desc: "ReqSignedIn should return redirect anonymous user when orgId in query string is different from currently used",
|
||||||
path: "/secure?orgId=2",
|
path: "/secure?orgId=2",
|
||||||
authMiddleware: ReqSignedIn,
|
authMiddleware: ReqSignedIn,
|
||||||
identity: &authn.Identity{IsAnonymous: true, OrgID: 1},
|
identity: &authn.Identity{ID: authn.AnonymousNamespaceID, OrgID: 1},
|
||||||
expecedReached: false,
|
expecedReached: false,
|
||||||
expectedCode: http.StatusFound,
|
expectedCode: http.StatusFound,
|
||||||
},
|
},
|
||||||
@ -81,7 +81,7 @@ func TestAuth_Middleware(t *testing.T) {
|
|||||||
desc: "ReqSignedInNoAnonymous should return 401 for anonymous user",
|
desc: "ReqSignedInNoAnonymous should return 401 for anonymous user",
|
||||||
path: "/api/secure",
|
path: "/api/secure",
|
||||||
authMiddleware: ReqSignedInNoAnonymous,
|
authMiddleware: ReqSignedInNoAnonymous,
|
||||||
identity: &authn.Identity{IsAnonymous: true},
|
identity: &authn.Identity{ID: authn.AnonymousNamespaceID},
|
||||||
expecedReached: false,
|
expecedReached: false,
|
||||||
expectedCode: http.StatusUnauthorized,
|
expectedCode: http.StatusUnauthorized,
|
||||||
},
|
},
|
||||||
|
@ -120,7 +120,7 @@ func (s *Service) getUserPermissions(ctx context.Context, user identity.Requeste
|
|||||||
|
|
||||||
var userID int64
|
var userID int64
|
||||||
switch namespace {
|
switch namespace {
|
||||||
case authn.NamespaceUser, authn.NamespaceServiceAccount, identity.NamespaceRenderService:
|
case authn.NamespaceUser, authn.NamespaceServiceAccount:
|
||||||
var err error
|
var err error
|
||||||
userID, err = strconv.ParseInt(identifier, 10, 64)
|
userID, err = strconv.ParseInt(identifier, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,7 +57,7 @@ func (a *Anonymous) Authenticate(ctx context.Context, r *authn.Request) (*authn.
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
return &authn.Identity{
|
return &authn.Identity{
|
||||||
IsAnonymous: true,
|
ID: authn.AnonymousNamespaceID,
|
||||||
OrgID: o.ID,
|
OrgID: o.ID,
|
||||||
OrgName: o.Name,
|
OrgName: o.Name,
|
||||||
OrgRoles: map[int64]org.RoleType{o.ID: org.RoleType(a.cfg.AnonymousOrgRole)},
|
OrgRoles: map[int64]org.RoleType{o.ID: org.RoleType(a.cfg.AnonymousOrgRole)},
|
||||||
|
@ -59,7 +59,7 @@ func TestAnonymous_Authenticate(t *testing.T) {
|
|||||||
} else {
|
} else {
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
assert.Equal(t, true, identity.ID == "")
|
assert.Equal(t, authn.AnonymousNamespaceID, identity.ID)
|
||||||
assert.Equal(t, tt.org.ID, identity.OrgID)
|
assert.Equal(t, tt.org.ID, identity.OrgID)
|
||||||
assert.Equal(t, tt.org.Name, identity.OrgName)
|
assert.Equal(t, tt.org.Name, identity.OrgName)
|
||||||
assert.Equal(t, tt.cfg.AnonymousOrgRole, string(identity.GetOrgRole()))
|
assert.Equal(t, tt.cfg.AnonymousOrgRole, string(identity.GetOrgRole()))
|
||||||
|
@ -45,7 +45,7 @@ func (c *Render) Authenticate(ctx context.Context, r *authn.Request) (*authn.Ide
|
|||||||
var identity *authn.Identity
|
var identity *authn.Identity
|
||||||
if renderUsr.UserID <= 0 {
|
if renderUsr.UserID <= 0 {
|
||||||
identity = &authn.Identity{
|
identity = &authn.Identity{
|
||||||
ID: authn.NamespacedID(authn.NamespaceUser, 0),
|
ID: authn.NamespacedID(authn.NamespaceRenderService, 0),
|
||||||
OrgID: renderUsr.OrgID,
|
OrgID: renderUsr.OrgID,
|
||||||
OrgRoles: map[int64]org.RoleType{renderUsr.OrgID: org.RoleType(renderUsr.OrgRole)},
|
OrgRoles: map[int64]org.RoleType{renderUsr.OrgID: org.RoleType(renderUsr.OrgRole)},
|
||||||
ClientParams: authn.ClientParams{SyncPermissions: true},
|
ClientParams: authn.ClientParams{SyncPermissions: true},
|
||||||
|
@ -38,7 +38,7 @@ func TestRender_Authenticate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedIdentity: &authn.Identity{
|
expectedIdentity: &authn.Identity{
|
||||||
ID: "user:0",
|
ID: "render:0",
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
OrgRoles: map[int64]org.RoleType{1: org.RoleViewer},
|
OrgRoles: map[int64]org.RoleType{1: org.RoleViewer},
|
||||||
AuthenticatedBy: login.RenderModule,
|
AuthenticatedBy: login.RenderModule,
|
||||||
|
@ -29,6 +29,10 @@ const (
|
|||||||
NamespaceRenderService = identity.NamespaceRenderService
|
NamespaceRenderService = identity.NamespaceRenderService
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AnonymousNamespaceID = NamespaceAnonymous + ":0"
|
||||||
|
)
|
||||||
|
|
||||||
var _ identity.Requester = (*Identity)(nil)
|
var _ identity.Requester = (*Identity)(nil)
|
||||||
|
|
||||||
type Identity struct {
|
type Identity struct {
|
||||||
@ -43,8 +47,6 @@ type Identity struct {
|
|||||||
// Namespace* constants. For example, "user:1" or "api-key:1".
|
// Namespace* constants. For example, "user:1" or "api-key:1".
|
||||||
// If the entity is not found in the DB or this entity is non-persistent, this field will be empty.
|
// If the entity is not found in the DB or this entity is non-persistent, this field will be empty.
|
||||||
ID string
|
ID string
|
||||||
// IsAnonymous
|
|
||||||
IsAnonymous bool
|
|
||||||
// Login is the shorthand identifier of the entity. Should be unique.
|
// Login is the shorthand identifier of the entity. Should be unique.
|
||||||
Login string
|
Login string
|
||||||
// Name is the display name of the entity. It is not guaranteed to be unique.
|
// Name is the display name of the entity. It is not guaranteed to be unique.
|
||||||
@ -202,6 +204,8 @@ func (i *Identity) NamespacedID() (string, int64) {
|
|||||||
|
|
||||||
// SignedInUser returns a SignedInUser from the identity.
|
// SignedInUser returns a SignedInUser from the identity.
|
||||||
func (i *Identity) SignedInUser() *user.SignedInUser {
|
func (i *Identity) SignedInUser() *user.SignedInUser {
|
||||||
|
namespace, id := i.GetNamespacedID()
|
||||||
|
|
||||||
u := &user.SignedInUser{
|
u := &user.SignedInUser{
|
||||||
OrgID: i.OrgID,
|
OrgID: i.OrgID,
|
||||||
OrgName: i.OrgName,
|
OrgName: i.OrgName,
|
||||||
@ -211,7 +215,7 @@ func (i *Identity) SignedInUser() *user.SignedInUser {
|
|||||||
Email: i.Email,
|
Email: i.Email,
|
||||||
AuthenticatedBy: i.AuthenticatedBy,
|
AuthenticatedBy: i.AuthenticatedBy,
|
||||||
IsGrafanaAdmin: i.GetIsGrafanaAdmin(),
|
IsGrafanaAdmin: i.GetIsGrafanaAdmin(),
|
||||||
IsAnonymous: i.IsAnonymous,
|
IsAnonymous: namespace == NamespaceAnonymous,
|
||||||
IsDisabled: i.IsDisabled,
|
IsDisabled: i.IsDisabled,
|
||||||
HelpFlags1: i.HelpFlags1,
|
HelpFlags1: i.HelpFlags1,
|
||||||
LastSeenAt: i.LastSeenAt,
|
LastSeenAt: i.LastSeenAt,
|
||||||
@ -220,7 +224,6 @@ func (i *Identity) SignedInUser() *user.SignedInUser {
|
|||||||
IDToken: i.IDToken,
|
IDToken: i.IDToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace, id := i.GetNamespacedID()
|
|
||||||
if namespace == NamespaceAPIKey {
|
if namespace == NamespaceAPIKey {
|
||||||
u.ApiKeyID = intIdentifier(id)
|
u.ApiKeyID = intIdentifier(id)
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,8 +119,8 @@ func (h *ContextHandler) Middleware(next http.Handler) http.Handler {
|
|||||||
} else {
|
} else {
|
||||||
reqContext.SignedInUser = identity.SignedInUser()
|
reqContext.SignedInUser = identity.SignedInUser()
|
||||||
reqContext.UserToken = identity.SessionToken
|
reqContext.UserToken = identity.SessionToken
|
||||||
reqContext.IsSignedIn = !identity.IsAnonymous
|
reqContext.IsSignedIn = !reqContext.SignedInUser.IsAnonymous
|
||||||
reqContext.AllowAnonymous = identity.IsAnonymous
|
reqContext.AllowAnonymous = reqContext.SignedInUser.IsAnonymous
|
||||||
reqContext.IsRenderCall = identity.AuthenticatedBy == login.RenderModule
|
reqContext.IsRenderCall = identity.AuthenticatedBy == login.RenderModule
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func TestContextHandler(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("should not set IsSignedIn on anonymous identity", func(t *testing.T) {
|
t.Run("should not set IsSignedIn on anonymous identity", func(t *testing.T) {
|
||||||
identity := &authn.Identity{IsAnonymous: true, OrgID: 1}
|
identity := &authn.Identity{ID: authn.AnonymousNamespaceID, OrgID: 1}
|
||||||
handler := contexthandler.ProvideService(
|
handler := contexthandler.ProvideService(
|
||||||
setting.NewCfg(),
|
setting.NewCfg(),
|
||||||
tracing.InitializeTracerForTest(),
|
tracing.InitializeTracerForTest(),
|
||||||
|
Reference in New Issue
Block a user