mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Auth: Add anonymous authn client (#59637)
* Authn: Add Client interface and Reqeust and Identity structures * Authn: Implement Authenticate method in service * Authn: Add tracing * Authn: Add logger * AuthN: Implement Anonymous client
This commit is contained in:
parent
c52d4e2a64
commit
22be025284
@ -30,6 +30,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
|
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
|
||||||
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
||||||
@ -217,7 +218,7 @@ func getContextHandler(t *testing.T, cfg *setting.Cfg) *contexthandler.ContextHa
|
|||||||
authProxy := authproxy.ProvideAuthProxy(cfg, remoteCacheSvc, loginservice.LoginServiceMock{}, &usertest.FakeUserService{}, sqlStore)
|
authProxy := authproxy.ProvideAuthProxy(cfg, remoteCacheSvc, loginservice.LoginServiceMock{}, &usertest.FakeUserService{}, sqlStore)
|
||||||
loginService := &logintest.LoginServiceFake{}
|
loginService := &logintest.LoginServiceFake{}
|
||||||
authenticator := &logintest.AuthenticatorFake{}
|
authenticator := &logintest.AuthenticatorFake{}
|
||||||
ctxHdlr := contexthandler.ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc, renderSvc, sqlStore, tracer, authProxy, loginService, nil, authenticator, usertest.NewUserServiceFake(), orgtest.NewOrgServiceFake(), nil, featuremgmt.WithFeatures())
|
ctxHdlr := contexthandler.ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc, renderSvc, sqlStore, tracer, authProxy, loginService, nil, authenticator, usertest.NewUserServiceFake(), orgtest.NewOrgServiceFake(), nil, featuremgmt.WithFeatures(), &authntest.FakeService{})
|
||||||
|
|
||||||
return ctxHdlr
|
return ctxHdlr
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/apikey/apikeytest"
|
"github.com/grafana/grafana/pkg/services/apikey/apikeytest"
|
||||||
"github.com/grafana/grafana/pkg/services/auth"
|
"github.com/grafana/grafana/pkg/services/auth"
|
||||||
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
@ -887,7 +888,7 @@ func getContextHandler(t *testing.T, cfg *setting.Cfg, mockSQLStore *dbtest.Fake
|
|||||||
tracer := tracing.InitializeTracerForTest()
|
tracer := tracing.InitializeTracerForTest()
|
||||||
authProxy := authproxy.ProvideAuthProxy(cfg, remoteCacheSvc, loginService, userService, mockSQLStore)
|
authProxy := authproxy.ProvideAuthProxy(cfg, remoteCacheSvc, loginService, userService, mockSQLStore)
|
||||||
authenticator := &logintest.AuthenticatorFake{ExpectedUser: &user.User{}}
|
authenticator := &logintest.AuthenticatorFake{ExpectedUser: &user.User{}}
|
||||||
return contexthandler.ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc, renderSvc, mockSQLStore, tracer, authProxy, loginService, apiKeyService, authenticator, userService, orgService, oauthTokenService, featuremgmt.WithFeatures(featuremgmt.FlagAccessTokenExpirationCheck))
|
return contexthandler.ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc, renderSvc, mockSQLStore, tracer, authProxy, loginService, apiKeyService, authenticator, userService, orgService, oauthTokenService, featuremgmt.WithFeatures(featuremgmt.FlagAccessTokenExpirationCheck), &authntest.FakeService{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeRenderService struct {
|
type fakeRenderService struct {
|
||||||
|
@ -38,6 +38,8 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey/apikeyimpl"
|
"github.com/grafana/grafana/pkg/services/apikey/apikeyimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/auth/jwt"
|
"github.com/grafana/grafana/pkg/services/auth/jwt"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn/authnimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/cleanup"
|
"github.com/grafana/grafana/pkg/services/cleanup"
|
||||||
"github.com/grafana/grafana/pkg/services/comments"
|
"github.com/grafana/grafana/pkg/services/comments"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||||
@ -348,6 +350,8 @@ var wireBasicSet = wire.NewSet(
|
|||||||
wire.Bind(new(notifications.TempUserStore), new(tempuser.Service)),
|
wire.Bind(new(notifications.TempUserStore), new(tempuser.Service)),
|
||||||
tagimpl.ProvideService,
|
tagimpl.ProvideService,
|
||||||
wire.Bind(new(tag.Service), new(*tagimpl.Service)),
|
wire.Bind(new(tag.Service), new(*tagimpl.Service)),
|
||||||
|
authnimpl.ProvideService,
|
||||||
|
wire.Bind(new(authn.Service), new(*authnimpl.Service)),
|
||||||
)
|
)
|
||||||
|
|
||||||
var wireSet = wire.NewSet(
|
var wireSet = wire.NewSet(
|
||||||
|
@ -1,4 +1,45 @@
|
|||||||
package authn
|
package authn
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ClientAnonymous = "auth.anonymous"
|
||||||
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
|
Authenticate(ctx context.Context, client string, r *Request) (*Identity, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Client interface {
|
||||||
|
Authenticate(ctx context.Context, r *Request) (*Identity, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
HTTPRequest *http.Request
|
||||||
|
}
|
||||||
|
|
||||||
|
type Identity struct {
|
||||||
|
OrgID int64
|
||||||
|
OrgName string
|
||||||
|
IsAnonymous bool
|
||||||
|
OrgRoles map[int64]org.RoleType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Identity) Role() org.RoleType {
|
||||||
|
return i.OrgRoles[i.OrgID]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Identity) SignedInUser() *user.SignedInUser {
|
||||||
|
return &user.SignedInUser{
|
||||||
|
OrgID: i.OrgID,
|
||||||
|
OrgName: i.OrgName,
|
||||||
|
OrgRole: i.Role(),
|
||||||
|
IsAnonymous: i.IsAnonymous,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,62 @@
|
|||||||
package authnimpl
|
package authnimpl
|
||||||
|
|
||||||
import "github.com/grafana/grafana/pkg/services/authn"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn/clients"
|
||||||
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
)
|
||||||
|
|
||||||
var _ authn.Service = new(Service)
|
var _ authn.Service = new(Service)
|
||||||
|
|
||||||
type Service struct {
|
func ProvideService(cfg *setting.Cfg, tracer tracing.Tracer, orgService org.Service) *Service {
|
||||||
|
s := &Service{
|
||||||
|
log: log.New("authn.service"),
|
||||||
|
cfg: cfg,
|
||||||
|
clients: make(map[string]authn.Client),
|
||||||
|
tracer: tracer,
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.cfg.AnonymousEnabled {
|
||||||
|
s.clients[authn.ClientAnonymous] = clients.ProvideAnonymous(cfg, orgService)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
log log.Logger
|
||||||
|
cfg *setting.Cfg
|
||||||
|
clients map[string]authn.Client
|
||||||
|
|
||||||
|
tracer tracing.Tracer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Authenticate(ctx context.Context, clientName string, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.Authenticate")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
span.SetAttributes("authn.client", clientName, attribute.Key("authn.client").String(clientName))
|
||||||
|
|
||||||
|
client, ok := s.clients[clientName]
|
||||||
|
if !ok {
|
||||||
|
s.log.FromContext(ctx).Warn("auth client not found", "client", clientName)
|
||||||
|
span.AddEvents([]string{"message"}, []tracing.EventValue{{Str: "auth client is not configured"}})
|
||||||
|
return nil, authn.ErrClientNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: We want to perform common authentication operations here.
|
||||||
|
// We will add them as we start to implement clients that requires them.
|
||||||
|
// Those operations can be Syncing user, syncing teams, create a session etc.
|
||||||
|
// We would need to check what operations a client support and also if they are requested
|
||||||
|
// because for e.g. basic auth we want to create a session if the call is coming from the
|
||||||
|
// login handler, but if we want to perform basic auth during a request (called from contexthandler) we don't
|
||||||
|
// want a session to be created.
|
||||||
|
|
||||||
|
return client.Authenticate(ctx, r)
|
||||||
}
|
}
|
||||||
|
62
pkg/services/authn/authnimpl/service_test.go
Normal file
62
pkg/services/authn/authnimpl/service_test.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package authnimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestService_Authenticate(t *testing.T) {
|
||||||
|
type TestCase struct {
|
||||||
|
desc string
|
||||||
|
clientName string
|
||||||
|
expectedErr error
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []TestCase{
|
||||||
|
{
|
||||||
|
desc: "should succeed with authentication for configured client",
|
||||||
|
clientName: "fake",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "should fail when client is not configured",
|
||||||
|
clientName: "gitlab",
|
||||||
|
expectedErr: authn.ErrClientNotFound,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
|
svc := setupTests(t, func(svc *Service) {
|
||||||
|
svc.clients["fake"] = &authntest.FakeClient{}
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := svc.Authenticate(context.Background(), tt.clientName, &authn.Request{})
|
||||||
|
assert.ErrorIs(t, tt.expectedErr, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupTests(t *testing.T, opts ...func(svc *Service)) *Service {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
s := &Service{
|
||||||
|
log: log.NewNopLogger(),
|
||||||
|
cfg: setting.NewCfg(),
|
||||||
|
clients: map[string]authn.Client{},
|
||||||
|
tracer: tracing.InitializeTracerForTest(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
@ -1,7 +1,22 @@
|
|||||||
package authntest
|
package authntest
|
||||||
|
|
||||||
import "github.com/grafana/grafana/pkg/services/authn"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
|
)
|
||||||
|
|
||||||
type FakeService struct {
|
type FakeService struct {
|
||||||
authn.Service
|
authn.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ authn.Client = new(FakeClient)
|
||||||
|
|
||||||
|
type FakeClient struct {
|
||||||
|
ExpectedErr error
|
||||||
|
ExpectedIdentity *authn.Identity
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeClient) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
return f.ExpectedIdentity, f.ExpectedErr
|
||||||
|
}
|
||||||
|
41
pkg/services/authn/clients/anonymous.go
Normal file
41
pkg/services/authn/clients/anonymous.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package clients
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ authn.Client = new(Anonymous)
|
||||||
|
|
||||||
|
func ProvideAnonymous(cfg *setting.Cfg, orgService org.Service) *Anonymous {
|
||||||
|
return &Anonymous{
|
||||||
|
cfg: cfg,
|
||||||
|
log: log.New("authn.anonymous"),
|
||||||
|
orgService: orgService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Anonymous struct {
|
||||||
|
cfg *setting.Cfg
|
||||||
|
log log.Logger
|
||||||
|
orgService org.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Anonymous) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
o, err := a.orgService.GetByName(ctx, &org.GetOrgByNameQuery{Name: a.cfg.AnonymousOrgName})
|
||||||
|
if err != nil {
|
||||||
|
a.log.FromContext(ctx).Error("failed to find organization", "name", a.cfg.AnonymousOrgName, "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &authn.Identity{
|
||||||
|
OrgID: o.ID,
|
||||||
|
OrgName: o.Name,
|
||||||
|
OrgRoles: map[int64]org.RoleType{o.ID: org.RoleType(a.cfg.AnonymousOrgRole)},
|
||||||
|
IsAnonymous: true,
|
||||||
|
}, nil
|
||||||
|
}
|
66
pkg/services/authn/clients/anonymous_test.go
Normal file
66
pkg/services/authn/clients/anonymous_test.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package clients
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAnonymous_Authenticate(t *testing.T) {
|
||||||
|
type TestCase struct {
|
||||||
|
desc string
|
||||||
|
org *org.Org
|
||||||
|
cfg *setting.Cfg
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []TestCase{
|
||||||
|
{
|
||||||
|
desc: "should success with valid org configured",
|
||||||
|
org: &org.Org{ID: 1, Name: "some org"},
|
||||||
|
cfg: &setting.Cfg{
|
||||||
|
AnonymousOrgName: "some org",
|
||||||
|
AnonymousOrgRole: "Viewer",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "should return error if any error occurs during org lookup",
|
||||||
|
err: fmt.Errorf("some error"),
|
||||||
|
cfg: &setting.Cfg{
|
||||||
|
AnonymousOrgName: "some org",
|
||||||
|
AnonymousOrgRole: "Viewer",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
|
c := Anonymous{
|
||||||
|
cfg: tt.cfg,
|
||||||
|
log: log.NewNopLogger(),
|
||||||
|
orgService: &orgtest.FakeOrgService{ExpectedOrg: tt.org, ExpectedError: tt.err},
|
||||||
|
}
|
||||||
|
|
||||||
|
identity, err := c.Authenticate(context.Background(), &authn.Request{})
|
||||||
|
if err != nil {
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Nil(t, identity)
|
||||||
|
} else {
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, true, identity.IsAnonymous)
|
||||||
|
assert.Equal(t, tt.org.ID, identity.OrgID)
|
||||||
|
assert.Equal(t, tt.org.Name, identity.OrgName)
|
||||||
|
assert.Equal(t, tt.cfg.AnonymousOrgRole, string(identity.Role()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
5
pkg/services/authn/error.go
Normal file
5
pkg/services/authn/error.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package authn
|
||||||
|
|
||||||
|
import "github.com/grafana/grafana/pkg/util/errutil"
|
||||||
|
|
||||||
|
var ErrClientNotFound = errutil.NewBase(errutil.StatusNotFound, "auth.client.notConfigured")
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
||||||
"github.com/grafana/grafana/pkg/services/login/loginservice"
|
"github.com/grafana/grafana/pkg/services/login/loginservice"
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||||
@ -104,7 +105,7 @@ func getContextHandler(t *testing.T) *ContextHandler {
|
|||||||
|
|
||||||
return ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc,
|
return ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc,
|
||||||
renderSvc, sqlStore, tracer, authProxy, loginService, nil, authenticator,
|
renderSvc, sqlStore, tracer, authProxy, loginService, nil, authenticator,
|
||||||
&userService, orgService, nil, nil)
|
&userService, orgService, nil, nil, &authntest.FakeService{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type FakeGetSignUserStore struct {
|
type FakeGetSignUserStore struct {
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey"
|
"github.com/grafana/grafana/pkg/services/apikey"
|
||||||
"github.com/grafana/grafana/pkg/services/auth"
|
"github.com/grafana/grafana/pkg/services/auth"
|
||||||
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
||||||
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
@ -49,6 +50,7 @@ func ProvideService(cfg *setting.Cfg, tokenService auth.UserTokenService, jwtSer
|
|||||||
tracer tracing.Tracer, authProxy *authproxy.AuthProxy, loginService login.Service,
|
tracer tracing.Tracer, authProxy *authproxy.AuthProxy, loginService login.Service,
|
||||||
apiKeyService apikey.Service, authenticator loginpkg.Authenticator, userService user.Service,
|
apiKeyService apikey.Service, authenticator loginpkg.Authenticator, userService user.Service,
|
||||||
orgService org.Service, oauthTokenService oauthtoken.OAuthTokenService, features *featuremgmt.FeatureManager,
|
orgService org.Service, oauthTokenService oauthtoken.OAuthTokenService, features *featuremgmt.FeatureManager,
|
||||||
|
authnService authn.Service,
|
||||||
) *ContextHandler {
|
) *ContextHandler {
|
||||||
return &ContextHandler{
|
return &ContextHandler{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
@ -86,6 +88,7 @@ type ContextHandler struct {
|
|||||||
orgService org.Service
|
orgService org.Service
|
||||||
oauthTokenService oauthtoken.OAuthTokenService
|
oauthTokenService oauthtoken.OAuthTokenService
|
||||||
features *featuremgmt.FeatureManager
|
features *featuremgmt.FeatureManager
|
||||||
|
authnService authn.Service
|
||||||
// GetTime returns the current time.
|
// GetTime returns the current time.
|
||||||
// Stubbable by tests.
|
// Stubbable by tests.
|
||||||
GetTime func() time.Time
|
GetTime func() time.Time
|
||||||
@ -188,13 +191,24 @@ func (h *ContextHandler) Middleware(next http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *ContextHandler) initContextWithAnonymousUser(reqContext *models.ReqContext) bool {
|
func (h *ContextHandler) initContextWithAnonymousUser(reqContext *models.ReqContext) bool {
|
||||||
|
ctx, span := h.tracer.Start(reqContext.Req.Context(), "initContextWithAnonymousUser")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
if h.features.IsEnabled(featuremgmt.FlagAuthnService) {
|
||||||
|
identity, err := h.authnService.Authenticate(ctx, authn.ClientAnonymous, &authn.Request{HTTPRequest: reqContext.Req})
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
reqContext.SignedInUser = identity.SignedInUser()
|
||||||
|
reqContext.IsSignedIn = false
|
||||||
|
reqContext.AllowAnonymous = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
if !h.Cfg.AnonymousEnabled {
|
if !h.Cfg.AnonymousEnabled {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
_, span := h.tracer.Start(reqContext.Req.Context(), "initContextWithAnonymousUser")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
getOrg := org.GetOrgByNameQuery{Name: h.Cfg.AnonymousOrgName}
|
getOrg := org.GetOrgByNameQuery{Name: h.Cfg.AnonymousOrgName}
|
||||||
|
|
||||||
orga, err := h.orgService.GetByName(reqContext.Req.Context(), &getOrg)
|
orga, err := h.orgService.GetByName(reqContext.Req.Context(), &getOrg)
|
||||||
|
Loading…
Reference in New Issue
Block a user