mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 04:52:10 +08:00
Auth: Add tracing to auth clients and AuthToken service (#107878)
* Add tracing to auth clients + authtoken svc * Fix span names * Fix ext_jwt.go * Fix idimpl/service * Update wire_gen.go * Add tracing to JWT client * Lint
This commit is contained in:
@ -648,7 +648,7 @@ func Initialize(cfg *setting.Cfg, opts Options, apiOpts api.ServerOptions) (*Ser
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer)
|
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
||||||
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationService, idimplService)
|
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationService, idimplService)
|
||||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service12, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service13, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationService, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service11, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokenService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service12, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service13, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationService, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service11, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokenService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1161,7 +1161,7 @@ func InitializeForTest(t sqlutil.ITestDB, testingT interface {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer)
|
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
||||||
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationServiceMock, idimplService)
|
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationServiceMock, idimplService)
|
||||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service12, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service13, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationServiceMock, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service11, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokentestService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service12, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service13, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationServiceMock, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service11, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokentestService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -80,6 +80,9 @@ type UserAuthTokenService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) CreateToken(ctx context.Context, cmd *auth.CreateTokenCommand) (*auth.UserToken, error) {
|
func (s *UserAuthTokenService) CreateToken(ctx context.Context, cmd *auth.CreateTokenCommand) (*auth.UserToken, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.CreateToken")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
token, hashedToken, err := generateAndHashToken(s.cfg.SecretKey)
|
token, hashedToken, err := generateAndHashToken(s.cfg.SecretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -136,6 +139,9 @@ func (s *UserAuthTokenService) CreateToken(ctx context.Context, cmd *auth.Create
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) LookupToken(ctx context.Context, unhashedToken string) (*auth.UserToken, error) {
|
func (s *UserAuthTokenService) LookupToken(ctx context.Context, unhashedToken string) (*auth.UserToken, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.LookupToken")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
hashedToken := hashToken(s.cfg.SecretKey, unhashedToken)
|
hashedToken := hashToken(s.cfg.SecretKey, unhashedToken)
|
||||||
var model userAuthToken
|
var model userAuthToken
|
||||||
var exists bool
|
var exists bool
|
||||||
@ -234,6 +240,9 @@ func (s *UserAuthTokenService) LookupToken(ctx context.Context, unhashedToken st
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) GetTokenByExternalSessionID(ctx context.Context, externalSessionID int64) (*auth.UserToken, error) {
|
func (s *UserAuthTokenService) GetTokenByExternalSessionID(ctx context.Context, externalSessionID int64) (*auth.UserToken, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.GetTokenByExternalSessionID")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
var token userAuthToken
|
var token userAuthToken
|
||||||
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
||||||
exists, err := dbSession.Where("external_session_id = ?", externalSessionID).Get(&token)
|
exists, err := dbSession.Where("external_session_id = ?", externalSessionID).Get(&token)
|
||||||
@ -258,14 +267,23 @@ func (s *UserAuthTokenService) GetTokenByExternalSessionID(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) GetExternalSession(ctx context.Context, externalSessionID int64) (*auth.ExternalSession, error) {
|
func (s *UserAuthTokenService) GetExternalSession(ctx context.Context, externalSessionID int64) (*auth.ExternalSession, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.GetExternalSession")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
return s.externalSessionStore.Get(ctx, externalSessionID)
|
return s.externalSessionStore.Get(ctx, externalSessionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) FindExternalSessions(ctx context.Context, query *auth.ListExternalSessionQuery) ([]*auth.ExternalSession, error) {
|
func (s *UserAuthTokenService) FindExternalSessions(ctx context.Context, query *auth.ListExternalSessionQuery) ([]*auth.ExternalSession, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.FindExternalSessions")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
return s.externalSessionStore.List(ctx, query)
|
return s.externalSessionStore.List(ctx, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) UpdateExternalSession(ctx context.Context, externalSessionID int64, cmd *auth.UpdateExternalSessionCommand) error {
|
func (s *UserAuthTokenService) UpdateExternalSession(ctx context.Context, externalSessionID int64, cmd *auth.UpdateExternalSessionCommand) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.UpdateExternalSession")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
return s.externalSessionStore.Update(ctx, externalSessionID, cmd)
|
return s.externalSessionStore.Update(ctx, externalSessionID, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +347,9 @@ func (s *UserAuthTokenService) RotateToken(ctx context.Context, cmd auth.RotateC
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) rotateToken(ctx context.Context, token *auth.UserToken, clientIP net.IP, userAgent string) (*auth.UserToken, error) {
|
func (s *UserAuthTokenService) rotateToken(ctx context.Context, token *auth.UserToken, clientIP net.IP, userAgent string) (*auth.UserToken, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.rotateToken")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
var clientIPStr string
|
var clientIPStr string
|
||||||
if clientIP != nil {
|
if clientIP != nil {
|
||||||
clientIPStr = clientIP.String()
|
clientIPStr = clientIP.String()
|
||||||
@ -385,6 +406,9 @@ func (s *UserAuthTokenService) rotateToken(ctx context.Context, token *auth.User
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) RevokeToken(ctx context.Context, token *auth.UserToken, soft bool) error {
|
func (s *UserAuthTokenService) RevokeToken(ctx context.Context, token *auth.UserToken, soft bool) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.RevokeToken")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
if token == nil {
|
if token == nil {
|
||||||
return auth.ErrUserTokenNotFound
|
return auth.ErrUserTokenNotFound
|
||||||
}
|
}
|
||||||
@ -434,6 +458,9 @@ func (s *UserAuthTokenService) RevokeToken(ctx context.Context, token *auth.User
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) RevokeAllUserTokens(ctx context.Context, userId int64) error {
|
func (s *UserAuthTokenService) RevokeAllUserTokens(ctx context.Context, userId int64) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.RevokeAllUserTokens")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
return s.sqlStore.InTransaction(ctx, func(ctx context.Context) error {
|
return s.sqlStore.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
ctxLogger := s.log.FromContext(ctx)
|
ctxLogger := s.log.FromContext(ctx)
|
||||||
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
||||||
@ -466,6 +493,9 @@ func (s *UserAuthTokenService) RevokeAllUserTokens(ctx context.Context, userId i
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) BatchRevokeAllUserTokens(ctx context.Context, userIds []int64) error {
|
func (s *UserAuthTokenService) BatchRevokeAllUserTokens(ctx context.Context, userIds []int64) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.BatchRevokeAllUserTokens")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
return s.sqlStore.InTransaction(ctx, func(ctx context.Context) error {
|
return s.sqlStore.InTransaction(ctx, func(ctx context.Context) error {
|
||||||
ctxLogger := s.log.FromContext(ctx)
|
ctxLogger := s.log.FromContext(ctx)
|
||||||
if len(userIds) == 0 {
|
if len(userIds) == 0 {
|
||||||
@ -507,6 +537,9 @@ func (s *UserAuthTokenService) BatchRevokeAllUserTokens(ctx context.Context, use
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) GetUserToken(ctx context.Context, userId, userTokenId int64) (*auth.UserToken, error) {
|
func (s *UserAuthTokenService) GetUserToken(ctx context.Context, userId, userTokenId int64) (*auth.UserToken, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.GetUserToken")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
var result auth.UserToken
|
var result auth.UserToken
|
||||||
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
||||||
var token userAuthToken
|
var token userAuthToken
|
||||||
@ -526,6 +559,9 @@ func (s *UserAuthTokenService) GetUserToken(ctx context.Context, userId, userTok
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) GetUserTokens(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
|
func (s *UserAuthTokenService) GetUserTokens(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.GetUserTokens")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
result := []*auth.UserToken{}
|
result := []*auth.UserToken{}
|
||||||
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
||||||
var tokens []*userAuthToken
|
var tokens []*userAuthToken
|
||||||
@ -554,6 +590,9 @@ func (s *UserAuthTokenService) GetUserTokens(ctx context.Context, userId int64)
|
|||||||
|
|
||||||
// ActiveTokenCount returns the number of active tokens. If userID is nil, the count is for all users.
|
// ActiveTokenCount returns the number of active tokens. If userID is nil, the count is for all users.
|
||||||
func (s *UserAuthTokenService) ActiveTokenCount(ctx context.Context, userID *int64) (int64, error) {
|
func (s *UserAuthTokenService) ActiveTokenCount(ctx context.Context, userID *int64) (int64, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.ActiveTokenCount")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
if userID != nil && *userID < 1 {
|
if userID != nil && *userID < 1 {
|
||||||
return 0, errUserIDInvalid
|
return 0, errUserIDInvalid
|
||||||
}
|
}
|
||||||
@ -574,6 +613,9 @@ func (s *UserAuthTokenService) ActiveTokenCount(ctx context.Context, userID *int
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) DeleteUserRevokedTokens(ctx context.Context, userID int64, window time.Duration) error {
|
func (s *UserAuthTokenService) DeleteUserRevokedTokens(ctx context.Context, userID int64, window time.Duration) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.DeleteUserRevokedTokens")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
return s.sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
return s.sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
query := "DELETE FROM user_auth_token WHERE user_id = ? AND revoked_at > 0 AND revoked_at <= ?"
|
query := "DELETE FROM user_auth_token WHERE user_id = ? AND revoked_at > 0 AND revoked_at <= ?"
|
||||||
res, err := sess.Exec(query, userID, time.Now().Add(-window).Unix())
|
res, err := sess.Exec(query, userID, time.Now().Add(-window).Unix())
|
||||||
@ -592,6 +634,9 @@ func (s *UserAuthTokenService) DeleteUserRevokedTokens(ctx context.Context, user
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserAuthTokenService) GetUserRevokedTokens(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
|
func (s *UserAuthTokenService) GetUserRevokedTokens(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authtoken.GetUserRevokedTokens")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
result := []*auth.UserToken{}
|
result := []*auth.UserToken{}
|
||||||
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
err := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
||||||
var tokens []*userAuthToken
|
var tokens []*userAuthToken
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/jwt"
|
"github.com/go-jose/go-jose/v3/jwt"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
|
|
||||||
authnlib "github.com/grafana/authlib/authn"
|
authnlib "github.com/grafana/authlib/authn"
|
||||||
@ -32,18 +33,18 @@ var _ auth.IDService = (*Service)(nil)
|
|||||||
|
|
||||||
func ProvideService(
|
func ProvideService(
|
||||||
cfg *setting.Cfg, signer auth.IDSigner,
|
cfg *setting.Cfg, signer auth.IDSigner,
|
||||||
cache remotecache.CacheStorage,
|
cache remotecache.CacheStorage, authnService authn.Service,
|
||||||
authnService authn.Service,
|
reg prometheus.Registerer, tracer trace.Tracer,
|
||||||
reg prometheus.Registerer,
|
|
||||||
) *Service {
|
) *Service {
|
||||||
s := &Service{
|
s := &Service{
|
||||||
cfg: cfg, logger: log.New("id-service"),
|
cfg: cfg, logger: log.New("id-service"),
|
||||||
signer: signer, cache: cache,
|
signer: signer, cache: cache,
|
||||||
metrics: newMetrics(reg),
|
metrics: newMetrics(reg),
|
||||||
nsMapper: request.GetNamespaceMapper(cfg),
|
nsMapper: request.GetNamespaceMapper(cfg),
|
||||||
|
tracer: tracer,
|
||||||
}
|
}
|
||||||
|
|
||||||
authnService.RegisterPostAuthHook(s.hook, 140)
|
authnService.RegisterPostAuthHook(s.SyncIDToken, 140)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@ -55,10 +56,14 @@ type Service struct {
|
|||||||
cache remotecache.CacheStorage
|
cache remotecache.CacheStorage
|
||||||
si singleflight.Group
|
si singleflight.Group
|
||||||
metrics *metrics
|
metrics *metrics
|
||||||
|
tracer trace.Tracer
|
||||||
nsMapper request.NamespaceMapper
|
nsMapper request.NamespaceMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (string, *authnlib.Claims[authnlib.IDTokenClaims], error) {
|
func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (string, *authnlib.Claims[authnlib.IDTokenClaims], error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "user.sync.SignIdentity")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
defer func(t time.Time) {
|
defer func(t time.Time) {
|
||||||
s.metrics.tokenSigningDurationHistogram.Observe(time.Since(t).Seconds())
|
s.metrics.tokenSigningDurationHistogram.Observe(time.Since(t).Seconds())
|
||||||
}(time.Now())
|
}(time.Now())
|
||||||
@ -140,10 +145,15 @@ func (s *Service) SignIdentity(ctx context.Context, id identity.Requester) (stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) RemoveIDToken(ctx context.Context, id identity.Requester) error {
|
func (s *Service) RemoveIDToken(ctx context.Context, id identity.Requester) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "user.sync.RemoveIDToken")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
return s.cache.Delete(ctx, getCacheKey(id))
|
return s.cache.Delete(ctx, getCacheKey(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) hook(ctx context.Context, identity *authn.Identity, _ *authn.Request) error {
|
func (s *Service) SyncIDToken(ctx context.Context, identity *authn.Identity, _ *authn.Request) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "user.sync.SyncIDToken")
|
||||||
|
defer span.End()
|
||||||
// FIXME(kalleep): we should probably lazy load this
|
// FIXME(kalleep): we should probably lazy load this
|
||||||
token, idClaims, err := s.SignIdentity(ctx, identity)
|
token, idClaims, err := s.SignIdentity(ctx, identity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
"github.com/grafana/grafana/pkg/infra/remotecache"
|
"github.com/grafana/grafana/pkg/infra/remotecache"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/auth"
|
"github.com/grafana/grafana/pkg/services/auth"
|
||||||
"github.com/grafana/grafana/pkg/services/auth/idtest"
|
"github.com/grafana/grafana/pkg/services/auth/idtest"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
@ -29,7 +30,7 @@ func Test_ProvideService(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = ProvideService(setting.NewCfg(), nil, nil, authnService, nil)
|
_ = ProvideService(setting.NewCfg(), nil, nil, authnService, nil, tracing.InitializeTracerForTest())
|
||||||
assert.True(t, hookRegistered)
|
assert.True(t, hookRegistered)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -51,7 +52,7 @@ func TestService_SignIdentity(t *testing.T) {
|
|||||||
t.Run("should sign identity", func(t *testing.T) {
|
t.Run("should sign identity", func(t *testing.T) {
|
||||||
s := ProvideService(
|
s := ProvideService(
|
||||||
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
||||||
&authntest.FakeService{}, nil,
|
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
|
||||||
)
|
)
|
||||||
token, _, err := s.SignIdentity(context.Background(), &authn.Identity{ID: "1", Type: claims.TypeUser})
|
token, _, err := s.SignIdentity(context.Background(), &authn.Identity{ID: "1", Type: claims.TypeUser})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -61,7 +62,7 @@ func TestService_SignIdentity(t *testing.T) {
|
|||||||
t.Run("should sign identity with authenticated by if user is externally authenticated", func(t *testing.T) {
|
t.Run("should sign identity with authenticated by if user is externally authenticated", func(t *testing.T) {
|
||||||
s := ProvideService(
|
s := ProvideService(
|
||||||
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
||||||
&authntest.FakeService{}, nil,
|
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
|
||||||
)
|
)
|
||||||
token, _, err := s.SignIdentity(context.Background(), &authn.Identity{
|
token, _, err := s.SignIdentity(context.Background(), &authn.Identity{
|
||||||
ID: "1",
|
ID: "1",
|
||||||
@ -86,7 +87,7 @@ func TestService_SignIdentity(t *testing.T) {
|
|||||||
t.Run("should sign identity with authenticated by if user is externally authenticated", func(t *testing.T) {
|
t.Run("should sign identity with authenticated by if user is externally authenticated", func(t *testing.T) {
|
||||||
s := ProvideService(
|
s := ProvideService(
|
||||||
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
||||||
&authntest.FakeService{}, nil,
|
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
|
||||||
)
|
)
|
||||||
_, gotClaims, err := s.SignIdentity(context.Background(), &authn.Identity{
|
_, gotClaims, err := s.SignIdentity(context.Background(), &authn.Identity{
|
||||||
ID: "1",
|
ID: "1",
|
||||||
@ -106,7 +107,7 @@ func TestService_SignIdentity(t *testing.T) {
|
|||||||
t.Run("should sign new token if org role has changed", func(t *testing.T) {
|
t.Run("should sign new token if org role has changed", func(t *testing.T) {
|
||||||
s := ProvideService(
|
s := ProvideService(
|
||||||
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
setting.NewCfg(), signer, remotecache.NewFakeCacheStorage(),
|
||||||
&authntest.FakeService{}, nil,
|
&authntest.FakeService{}, nil, tracing.InitializeTracerForTest(),
|
||||||
)
|
)
|
||||||
|
|
||||||
ident := &authn.Identity{
|
ident := &authn.Identity{
|
||||||
|
@ -48,10 +48,10 @@ func ProvideRegistration(
|
|||||||
logger := log.New("authn.registration")
|
logger := log.New("authn.registration")
|
||||||
|
|
||||||
authnSvc.RegisterClient(clients.ProvideRender(renderService))
|
authnSvc.RegisterClient(clients.ProvideRender(renderService))
|
||||||
authnSvc.RegisterClient(clients.ProvideAPIKey(apikeyService))
|
authnSvc.RegisterClient(clients.ProvideAPIKey(apikeyService, tracer))
|
||||||
|
|
||||||
if cfg.LoginCookieName != "" {
|
if cfg.LoginCookieName != "" {
|
||||||
authnSvc.RegisterClient(clients.ProvideSession(cfg, sessionService, authInfoService))
|
authnSvc.RegisterClient(clients.ProvideSession(cfg, sessionService, authInfoService, tracer))
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxyClients []authn.ProxyClient
|
var proxyClients []authn.ProxyClient
|
||||||
@ -59,20 +59,20 @@ func ProvideRegistration(
|
|||||||
|
|
||||||
// always register LDAP if LDAP is enabled in SSO settings
|
// always register LDAP if LDAP is enabled in SSO settings
|
||||||
if cfg.LDAPAuthEnabled || features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsLDAP) {
|
if cfg.LDAPAuthEnabled || features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsLDAP) {
|
||||||
ldap := clients.ProvideLDAP(cfg, ldapService, userService, authInfoService)
|
ldap := clients.ProvideLDAP(cfg, ldapService, userService, authInfoService, tracer)
|
||||||
proxyClients = append(proxyClients, ldap)
|
proxyClients = append(proxyClients, ldap)
|
||||||
passwordClients = append(passwordClients, ldap)
|
passwordClients = append(passwordClients, ldap)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cfg.DisableLogin {
|
if !cfg.DisableLogin {
|
||||||
grafana := clients.ProvideGrafana(cfg, userService)
|
grafana := clients.ProvideGrafana(cfg, userService, tracer)
|
||||||
proxyClients = append(proxyClients, grafana)
|
proxyClients = append(proxyClients, grafana)
|
||||||
passwordClients = append(passwordClients, grafana)
|
passwordClients = append(passwordClients, grafana)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have password clients configure check if basic auth or form auth is enabled
|
// if we have password clients configure check if basic auth or form auth is enabled
|
||||||
if len(passwordClients) > 0 {
|
if len(passwordClients) > 0 {
|
||||||
passwordClient := clients.ProvidePassword(loginAttempts, passwordClients...)
|
passwordClient := clients.ProvidePassword(loginAttempts, tracer, passwordClients...)
|
||||||
if cfg.BasicAuthEnabled {
|
if cfg.BasicAuthEnabled {
|
||||||
authnSvc.RegisterClient(clients.ProvideBasic(passwordClient))
|
authnSvc.RegisterClient(clients.ProvideBasic(passwordClient))
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ func ProvideRegistration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.AuthProxy.Enabled && len(proxyClients) > 0 {
|
if cfg.AuthProxy.Enabled && len(proxyClients) > 0 {
|
||||||
proxy, err := clients.ProvideProxy(cfg, cache, proxyClients...)
|
proxy, err := clients.ProvideProxy(cfg, cache, tracer, proxyClients...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to configure auth proxy", "err", err)
|
logger.Error("Failed to configure auth proxy", "err", err)
|
||||||
} else {
|
} else {
|
||||||
@ -113,16 +113,16 @@ func ProvideRegistration(
|
|||||||
|
|
||||||
if cfg.JWTAuth.Enabled {
|
if cfg.JWTAuth.Enabled {
|
||||||
orgRoleMapper := connectors.ProvideOrgRoleMapper(cfg, orgService)
|
orgRoleMapper := connectors.ProvideOrgRoleMapper(cfg, orgService)
|
||||||
authnSvc.RegisterClient(clients.ProvideJWT(jwtService, orgRoleMapper, cfg))
|
authnSvc.RegisterClient(clients.ProvideJWT(jwtService, orgRoleMapper, cfg, tracer))
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.ExtJWTAuth.Enabled {
|
if cfg.ExtJWTAuth.Enabled {
|
||||||
authnSvc.RegisterClient(clients.ProvideExtendedJWT(cfg))
|
authnSvc.RegisterClient(clients.ProvideExtendedJWT(cfg, tracer))
|
||||||
}
|
}
|
||||||
|
|
||||||
for name := range socialService.GetOAuthProviders() {
|
for name := range socialService.GetOAuthProviders() {
|
||||||
clientName := authn.ClientWithPrefix(name)
|
clientName := authn.ClientWithPrefix(name)
|
||||||
authnSvc.RegisterClient(clients.ProvideOAuth(clientName, cfg, oauthTokenService, socialService, settingsProviderService, features))
|
authnSvc.RegisterClient(clients.ProvideOAuth(clientName, cfg, oauthTokenService, socialService, settingsProviderService, features, tracer))
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagProvisioning) {
|
if features.IsEnabledGlobally(featuremgmt.FlagProvisioning) {
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||||
"github.com/grafana/grafana/pkg/components/apikeygen"
|
"github.com/grafana/grafana/pkg/components/apikeygen"
|
||||||
@ -35,16 +37,18 @@ const (
|
|||||||
metaKeySkipLastUsed = "keySkipLastUsed"
|
metaKeySkipLastUsed = "keySkipLastUsed"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideAPIKey(apiKeyService apikey.Service) *APIKey {
|
func ProvideAPIKey(apiKeyService apikey.Service, tracer trace.Tracer) *APIKey {
|
||||||
return &APIKey{
|
return &APIKey{
|
||||||
log: log.New(authn.ClientAPIKey),
|
log: log.New(authn.ClientAPIKey),
|
||||||
apiKeyService: apiKeyService,
|
apiKeyService: apiKeyService,
|
||||||
|
tracer: tracer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type APIKey struct {
|
type APIKey struct {
|
||||||
log log.Logger
|
log log.Logger
|
||||||
apiKeyService apikey.Service
|
apiKeyService apikey.Service
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIKey) Name() string {
|
func (s *APIKey) Name() string {
|
||||||
@ -52,6 +56,8 @@ func (s *APIKey) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIKey) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
func (s *APIKey) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.apikey.Authenticate")
|
||||||
|
defer span.End()
|
||||||
key, err := s.getAPIKey(ctx, getTokenFromRequest(r))
|
key, err := s.getAPIKey(ctx, getTokenFromRequest(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, apikeygen.ErrInvalidApiKey) {
|
if errors.Is(err, apikeygen.ErrInvalidApiKey) {
|
||||||
@ -84,6 +90,8 @@ func (s *APIKey) IsEnabled() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIKey) getAPIKey(ctx context.Context, token string) (*apikey.APIKey, error) {
|
func (s *APIKey) getAPIKey(ctx context.Context, token string) (*apikey.APIKey, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.apikey.getAPIKey")
|
||||||
|
defer span.End()
|
||||||
fn := s.getFromToken
|
fn := s.getFromToken
|
||||||
if !strings.HasPrefix(token, satokengen.GrafanaPrefix) {
|
if !strings.HasPrefix(token, satokengen.GrafanaPrefix) {
|
||||||
fn = s.getFromTokenLegacy
|
fn = s.getFromTokenLegacy
|
||||||
@ -98,6 +106,8 @@ func (s *APIKey) getAPIKey(ctx context.Context, token string) (*apikey.APIKey, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIKey) getFromToken(ctx context.Context, token string) (*apikey.APIKey, error) {
|
func (s *APIKey) getFromToken(ctx context.Context, token string) (*apikey.APIKey, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.apikey.getFromToken")
|
||||||
|
defer span.End()
|
||||||
decoded, err := satokengen.Decode(token)
|
decoded, err := satokengen.Decode(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -112,6 +122,8 @@ func (s *APIKey) getFromToken(ctx context.Context, token string) (*apikey.APIKey
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIKey) getFromTokenLegacy(ctx context.Context, token string) (*apikey.APIKey, error) {
|
func (s *APIKey) getFromTokenLegacy(ctx context.Context, token string) (*apikey.APIKey, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.apikey.getFromTokenLegacy")
|
||||||
|
defer span.End()
|
||||||
decoded, err := apikeygen.Decode(token)
|
decoded, err := apikeygen.Decode(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -144,6 +156,9 @@ func (s *APIKey) Priority() uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIKey) Hook(ctx context.Context, identity *authn.Identity, r *authn.Request) error {
|
func (s *APIKey) Hook(ctx context.Context, identity *authn.Identity, r *authn.Request) error {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.apikey.Hook") //nolint:ineffassign,staticcheck
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
if r.GetMeta(metaKeySkipLastUsed) != "" {
|
if r.GetMeta(metaKeySkipLastUsed) != "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
"github.com/grafana/grafana/pkg/components/apikeygen"
|
"github.com/grafana/grafana/pkg/components/apikeygen"
|
||||||
"github.com/grafana/grafana/pkg/components/satokengen"
|
"github.com/grafana/grafana/pkg/components/satokengen"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey"
|
"github.com/grafana/grafana/pkg/services/apikey"
|
||||||
"github.com/grafana/grafana/pkg/services/apikey/apikeytest"
|
"github.com/grafana/grafana/pkg/services/apikey/apikeytest"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
@ -106,7 +107,7 @@ func TestAPIKey_Authenticate(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
c := ProvideAPIKey(&apikeytest.Service{ExpectedAPIKey: tt.expectedKey})
|
c := ProvideAPIKey(&apikeytest.Service{ExpectedAPIKey: tt.expectedKey}, tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
identity, err := c.Authenticate(context.Background(), tt.req)
|
identity, err := c.Authenticate(context.Background(), tt.req)
|
||||||
if tt.expectedErr != nil {
|
if tt.expectedErr != nil {
|
||||||
@ -173,7 +174,7 @@ func TestAPIKey_Test(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
c := ProvideAPIKey(&apikeytest.Service{})
|
c := ProvideAPIKey(&apikeytest.Service{}, tracing.InitializeTracerForTest())
|
||||||
assert.Equal(t, tt.expected, c.Test(context.Background(), tt.req))
|
assert.Equal(t, tt.expected, c.Test(context.Background(), tt.req))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v3/jwt"
|
"github.com/go-jose/go-jose/v3/jwt"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
authlib "github.com/grafana/authlib/authn"
|
authlib "github.com/grafana/authlib/authn"
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
@ -41,7 +42,7 @@ var (
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideExtendedJWT(cfg *setting.Cfg) *ExtendedJWT {
|
func ProvideExtendedJWT(cfg *setting.Cfg, tracer trace.Tracer) *ExtendedJWT {
|
||||||
keys := authlib.NewKeyRetriever(authlib.KeyRetrieverConfig{
|
keys := authlib.NewKeyRetriever(authlib.KeyRetrieverConfig{
|
||||||
SigningKeysURL: cfg.ExtJWTAuth.JWKSUrl,
|
SigningKeysURL: cfg.ExtJWTAuth.JWKSUrl,
|
||||||
})
|
})
|
||||||
@ -60,6 +61,7 @@ func ProvideExtendedJWT(cfg *setting.Cfg) *ExtendedJWT {
|
|||||||
namespaceMapper: request.GetNamespaceMapper(cfg),
|
namespaceMapper: request.GetNamespaceMapper(cfg),
|
||||||
accessTokenVerifier: accessTokenVerifier,
|
accessTokenVerifier: accessTokenVerifier,
|
||||||
idTokenVerifier: idTokenVerifier,
|
idTokenVerifier: idTokenVerifier,
|
||||||
|
tracer: tracer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +71,13 @@ type ExtendedJWT struct {
|
|||||||
accessTokenVerifier authlib.Verifier[authlib.AccessTokenClaims]
|
accessTokenVerifier authlib.Verifier[authlib.AccessTokenClaims]
|
||||||
idTokenVerifier authlib.Verifier[authlib.IDTokenClaims]
|
idTokenVerifier authlib.Verifier[authlib.IDTokenClaims]
|
||||||
namespaceMapper request.NamespaceMapper
|
namespaceMapper request.NamespaceMapper
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
func (s *ExtendedJWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.extjwt.Authenticate")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
jwtToken := s.retrieveAuthenticationToken(r.HTTPRequest)
|
jwtToken := s.retrieveAuthenticationToken(r.HTTPRequest)
|
||||||
|
|
||||||
accessTokenClaims, err := s.accessTokenVerifier.Verify(ctx, jwtToken)
|
accessTokenClaims, err := s.accessTokenVerifier.Verify(ctx, jwtToken)
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
authnlib "github.com/grafana/authlib/authn"
|
authnlib "github.com/grafana/authlib/authn"
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
@ -699,7 +700,7 @@ func setupTestCtx(cfg *setting.Cfg) *testEnv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extJwtClient := ProvideExtendedJWT(cfg)
|
extJwtClient := ProvideExtendedJWT(cfg, tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
return &testEnv{
|
return &testEnv{
|
||||||
s: extJwtClient,
|
s: extJwtClient,
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"net/mail"
|
"net/mail"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
@ -19,13 +21,14 @@ import (
|
|||||||
var _ authn.ProxyClient = new(Grafana)
|
var _ authn.ProxyClient = new(Grafana)
|
||||||
var _ authn.PasswordClient = new(Grafana)
|
var _ authn.PasswordClient = new(Grafana)
|
||||||
|
|
||||||
func ProvideGrafana(cfg *setting.Cfg, userService user.Service) *Grafana {
|
func ProvideGrafana(cfg *setting.Cfg, userService user.Service, tracer trace.Tracer) *Grafana {
|
||||||
return &Grafana{cfg, userService}
|
return &Grafana{cfg, userService, tracer}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Grafana struct {
|
type Grafana struct {
|
||||||
cfg *setting.Cfg
|
cfg *setting.Cfg
|
||||||
userService user.Service
|
userService user.Service
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Grafana) String() string {
|
func (c *Grafana) String() string {
|
||||||
@ -33,6 +36,9 @@ func (c *Grafana) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Grafana) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, additional map[string]string) (*authn.Identity, error) {
|
func (c *Grafana) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, additional map[string]string) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.grafana.AuthenticateProxy") //nolint:ineffassign,staticcheck
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
identity := &authn.Identity{
|
identity := &authn.Identity{
|
||||||
AuthenticatedBy: login.AuthProxyAuthModule,
|
AuthenticatedBy: login.AuthProxyAuthModule,
|
||||||
AuthID: username,
|
AuthID: username,
|
||||||
@ -91,6 +97,9 @@ func (c *Grafana) AuthenticateProxy(ctx context.Context, r *authn.Request, usern
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Grafana) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
|
func (c *Grafana) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.grafana.AuthenticatePassword")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
usr, err := c.userService.GetByLogin(ctx, &user.GetUserByLoginQuery{LoginOrEmail: username})
|
usr, err := c.userService.GetByLogin(ctx, &user.GetUserByLoginQuery{LoginOrEmail: username})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, user.ErrUserNotFound) {
|
if errors.Is(err, user.ErrUserNotFound) {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
@ -97,7 +98,7 @@ func TestGrafana_AuthenticateProxy(t *testing.T) {
|
|||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
cfg.AuthProxy.AutoSignUp = true
|
cfg.AuthProxy.AutoSignUp = true
|
||||||
cfg.AuthProxy.HeaderProperty = tt.proxyProperty
|
cfg.AuthProxy.HeaderProperty = tt.proxyProperty
|
||||||
c := ProvideGrafana(cfg, usertest.NewUserServiceFake())
|
c := ProvideGrafana(cfg, usertest.NewUserServiceFake(), tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
identity, err := c.AuthenticateProxy(context.Background(), tt.req, tt.username, tt.additional)
|
identity, err := c.AuthenticateProxy(context.Background(), tt.req, tt.username, tt.additional)
|
||||||
assert.ErrorIs(t, err, tt.expectedErr)
|
assert.ErrorIs(t, err, tt.expectedErr)
|
||||||
@ -175,7 +176,7 @@ func TestGrafana_AuthenticatePassword(t *testing.T) {
|
|||||||
userService.ExpectedError = user.ErrUserNotFound
|
userService.ExpectedError = user.ErrUserNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
c := ProvideGrafana(setting.NewCfg(), userService)
|
c := ProvideGrafana(setting.NewCfg(), userService, tracing.InitializeTracerForTest())
|
||||||
identity, err := c.AuthenticatePassword(context.Background(), &authn.Request{OrgID: 1}, tt.username, tt.password)
|
identity, err := c.AuthenticatePassword(context.Background(), &authn.Request{OrgID: 1}, tt.username, tt.password)
|
||||||
assert.ErrorIs(t, err, tt.expectedErr)
|
assert.ErrorIs(t, err, tt.expectedErr)
|
||||||
assert.EqualValues(t, tt.expectedIdentity, identity)
|
assert.EqualValues(t, tt.expectedIdentity, identity)
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/login/social/connectors"
|
"github.com/grafana/grafana/pkg/login/social/connectors"
|
||||||
@ -30,13 +32,14 @@ var (
|
|||||||
"jwt.invalid_role", errutil.WithPublicMessage("Invalid Role in claim"))
|
"jwt.invalid_role", errutil.WithPublicMessage("Invalid Role in claim"))
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideJWT(jwtService auth.JWTVerifierService, orgRoleMapper *connectors.OrgRoleMapper, cfg *setting.Cfg) *JWT {
|
func ProvideJWT(jwtService auth.JWTVerifierService, orgRoleMapper *connectors.OrgRoleMapper, cfg *setting.Cfg, tracer trace.Tracer) *JWT {
|
||||||
return &JWT{
|
return &JWT{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
log: log.New(authn.ClientJWT),
|
log: log.New(authn.ClientJWT),
|
||||||
jwtService: jwtService,
|
jwtService: jwtService,
|
||||||
orgRoleMapper: orgRoleMapper,
|
orgRoleMapper: orgRoleMapper,
|
||||||
orgMappingCfg: orgRoleMapper.ParseOrgMappingSettings(context.Background(), cfg.JWTAuth.OrgMapping, cfg.JWTAuth.RoleAttributeStrict),
|
orgMappingCfg: orgRoleMapper.ParseOrgMappingSettings(context.Background(), cfg.JWTAuth.OrgMapping, cfg.JWTAuth.RoleAttributeStrict),
|
||||||
|
tracer: tracer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +49,7 @@ type JWT struct {
|
|||||||
orgMappingCfg connectors.MappingConfiguration
|
orgMappingCfg connectors.MappingConfiguration
|
||||||
log log.Logger
|
log log.Logger
|
||||||
jwtService auth.JWTVerifierService
|
jwtService auth.JWTVerifierService
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *JWT) Name() string {
|
func (s *JWT) Name() string {
|
||||||
@ -53,6 +57,9 @@ func (s *JWT) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *JWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
func (s *JWT) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
ctx, span := s.tracer.Start(ctx, "authn.jwt.Authenticate")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
jwtToken := s.retrieveToken(r.HTTPRequest)
|
jwtToken := s.retrieveToken(r.HTTPRequest)
|
||||||
s.stripSensitiveParam(r.HTTPRequest)
|
s.stripSensitiveParam(r.HTTPRequest)
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/login/social/connectors"
|
"github.com/grafana/grafana/pkg/login/social/connectors"
|
||||||
"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"
|
||||||
@ -262,7 +263,7 @@ func TestAuthenticateJWT(t *testing.T) {
|
|||||||
jwtClient := ProvideJWT(jwtService,
|
jwtClient := ProvideJWT(jwtService,
|
||||||
connectors.ProvideOrgRoleMapper(tc.cfg,
|
connectors.ProvideOrgRoleMapper(tc.cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
tc.cfg)
|
tc.cfg, tracing.InitializeTracerForTest())
|
||||||
validHTTPReq := &http.Request{
|
validHTTPReq := &http.Request{
|
||||||
Header: map[string][]string{
|
Header: map[string][]string{
|
||||||
jwtHeaderName: {"sample-token"}},
|
jwtHeaderName: {"sample-token"}},
|
||||||
@ -380,7 +381,7 @@ func TestJWTClaimConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
jwtClient := ProvideJWT(jwtService, connectors.ProvideOrgRoleMapper(cfg,
|
jwtClient := ProvideJWT(jwtService, connectors.ProvideOrgRoleMapper(cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
cfg)
|
cfg, tracing.InitializeTracerForTest())
|
||||||
_, err := jwtClient.Authenticate(context.Background(), &authn.Request{
|
_, err := jwtClient.Authenticate(context.Background(), &authn.Request{
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
HTTPRequest: httpReq,
|
HTTPRequest: httpReq,
|
||||||
@ -493,7 +494,7 @@ func TestJWTTest(t *testing.T) {
|
|||||||
jwtClient := ProvideJWT(jwtService,
|
jwtClient := ProvideJWT(jwtService,
|
||||||
connectors.ProvideOrgRoleMapper(cfg,
|
connectors.ProvideOrgRoleMapper(cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
cfg)
|
cfg, tracing.InitializeTracerForTest())
|
||||||
httpReq := &http.Request{
|
httpReq := &http.Request{
|
||||||
URL: &url.URL{RawQuery: "auth_token=" + tc.token},
|
URL: &url.URL{RawQuery: "auth_token=" + tc.token},
|
||||||
Header: map[string][]string{
|
Header: map[string][]string{
|
||||||
@ -549,7 +550,7 @@ func TestJWTStripParam(t *testing.T) {
|
|||||||
jwtClient := ProvideJWT(jwtService,
|
jwtClient := ProvideJWT(jwtService,
|
||||||
connectors.ProvideOrgRoleMapper(cfg,
|
connectors.ProvideOrgRoleMapper(cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
cfg)
|
cfg, tracing.InitializeTracerForTest())
|
||||||
_, err := jwtClient.Authenticate(context.Background(), &authn.Request{
|
_, err := jwtClient.Authenticate(context.Background(), &authn.Request{
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
HTTPRequest: httpReq,
|
HTTPRequest: httpReq,
|
||||||
@ -608,7 +609,7 @@ func TestJWTSubClaimsConfig(t *testing.T) {
|
|||||||
jwtClient := ProvideJWT(jwtService,
|
jwtClient := ProvideJWT(jwtService,
|
||||||
connectors.ProvideOrgRoleMapper(cfg,
|
connectors.ProvideOrgRoleMapper(cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
cfg)
|
cfg, tracing.InitializeTracerForTest())
|
||||||
identity, err := jwtClient.Authenticate(context.Background(), &authn.Request{
|
identity, err := jwtClient.Authenticate(context.Background(), &authn.Request{
|
||||||
OrgID: 1,
|
OrgID: 1,
|
||||||
HTTPRequest: httpReq,
|
HTTPRequest: httpReq,
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
||||||
@ -20,8 +22,8 @@ type ldapService interface {
|
|||||||
User(username string) (*login.ExternalUserInfo, error)
|
User(username string) (*login.ExternalUserInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideLDAP(cfg *setting.Cfg, ldapService ldapService, userService user.Service, authInfoService login.AuthInfoService) *LDAP {
|
func ProvideLDAP(cfg *setting.Cfg, ldapService ldapService, userService user.Service, authInfoService login.AuthInfoService, tracer trace.Tracer) *LDAP {
|
||||||
return &LDAP{cfg, log.New("authn.ldap"), ldapService, userService, authInfoService}
|
return &LDAP{cfg, log.New("authn.ldap"), ldapService, userService, authInfoService, tracer}
|
||||||
}
|
}
|
||||||
|
|
||||||
type LDAP struct {
|
type LDAP struct {
|
||||||
@ -30,6 +32,7 @@ type LDAP struct {
|
|||||||
service ldapService
|
service ldapService
|
||||||
userService user.Service
|
userService user.Service
|
||||||
authInfoService login.AuthInfoService
|
authInfoService login.AuthInfoService
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *LDAP) String() string {
|
func (c *LDAP) String() string {
|
||||||
@ -37,6 +40,8 @@ func (c *LDAP) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *LDAP) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, _ map[string]string) (*authn.Identity, error) {
|
func (c *LDAP) AuthenticateProxy(ctx context.Context, r *authn.Request, username string, _ map[string]string) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.ldap.AuthenticateProxy")
|
||||||
|
defer span.End()
|
||||||
info, err := c.service.User(username)
|
info, err := c.service.User(username)
|
||||||
if errors.Is(err, multildap.ErrDidNotFindUser) {
|
if errors.Is(err, multildap.ErrDidNotFindUser) {
|
||||||
return c.disableUser(ctx, username)
|
return c.disableUser(ctx, username)
|
||||||
@ -50,6 +55,8 @@ func (c *LDAP) AuthenticateProxy(ctx context.Context, r *authn.Request, username
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *LDAP) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
|
func (c *LDAP) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.ldap.AuthenticatePassword")
|
||||||
|
defer span.End()
|
||||||
info, err := c.service.Login(&login.LoginUserQuery{
|
info, err := c.service.Login(&login.LoginUserQuery{
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: password,
|
Password: password,
|
||||||
@ -75,6 +82,8 @@ func (c *LDAP) AuthenticatePassword(ctx context.Context, r *authn.Request, usern
|
|||||||
|
|
||||||
// disableUser will disable users if they logged in via LDAP previously
|
// disableUser will disable users if they logged in via LDAP previously
|
||||||
func (c *LDAP) disableUser(ctx context.Context, username string) (*authn.Identity, error) {
|
func (c *LDAP) disableUser(ctx context.Context, username string) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.ldap.disableUser")
|
||||||
|
defer span.End()
|
||||||
c.logger.Debug("User was not found in the LDAP directory tree", "username", username)
|
c.logger.Debug("User was not found in the LDAP directory tree", "username", username)
|
||||||
retErr := errIdentityNotFound.Errorf("no user found: %w", multildap.ErrDidNotFindUser)
|
retErr := errIdentityNotFound.Errorf("no user found: %w", multildap.ErrDidNotFindUser)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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"
|
||||||
"github.com/grafana/grafana/pkg/services/ldap"
|
"github.com/grafana/grafana/pkg/services/ldap"
|
||||||
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
||||||
@ -197,13 +197,13 @@ func setupLDAPTestCase(tt *ldapTestCase) *LDAP {
|
|||||||
ExpectedError: tt.expectedAuthInfoErr,
|
ExpectedError: tt.expectedAuthInfoErr,
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &LDAP{
|
c := ProvideLDAP(
|
||||||
cfg: setting.NewCfg(),
|
setting.NewCfg(),
|
||||||
logger: log.New("authn.ldap.test"),
|
&service.LDAPFakeService{ExpectedUser: tt.expectedLDAPInfo, ExpectedError: tt.expectedLDAPErr},
|
||||||
service: &service.LDAPFakeService{ExpectedUser: tt.expectedLDAPInfo, ExpectedError: tt.expectedLDAPErr},
|
userService,
|
||||||
userService: userService,
|
authInfoService,
|
||||||
authInfoService: authInfoService,
|
tracing.InitializeTracerForTest(),
|
||||||
}
|
)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||||
@ -70,12 +71,14 @@ var (
|
|||||||
|
|
||||||
func ProvideOAuth(
|
func ProvideOAuth(
|
||||||
name string, cfg *setting.Cfg, oauthService oauthtoken.OAuthTokenService,
|
name string, cfg *setting.Cfg, oauthService oauthtoken.OAuthTokenService,
|
||||||
socialService social.Service, settingsProviderService setting.Provider, features featuremgmt.FeatureToggles,
|
socialService social.Service, settingsProviderService setting.Provider,
|
||||||
|
features featuremgmt.FeatureToggles, tracer trace.Tracer,
|
||||||
) *OAuth {
|
) *OAuth {
|
||||||
providerName := strings.TrimPrefix(name, "auth.client.")
|
providerName := strings.TrimPrefix(name, "auth.client.")
|
||||||
return &OAuth{
|
return &OAuth{
|
||||||
name, fmt.Sprintf("oauth_%s", providerName), providerName,
|
name, fmt.Sprintf("oauth_%s", providerName), providerName,
|
||||||
log.New(name), cfg, settingsProviderService, oauthService, socialService, features,
|
log.New(name), cfg, tracer, settingsProviderService, oauthService,
|
||||||
|
socialService, features,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +88,7 @@ type OAuth struct {
|
|||||||
providerName string
|
providerName string
|
||||||
log log.Logger
|
log log.Logger
|
||||||
cfg *setting.Cfg
|
cfg *setting.Cfg
|
||||||
|
tracer trace.Tracer
|
||||||
|
|
||||||
settingsProviderSvc setting.Provider
|
settingsProviderSvc setting.Provider
|
||||||
oauthService oauthtoken.OAuthTokenService
|
oauthService oauthtoken.OAuthTokenService
|
||||||
@ -97,6 +101,9 @@ func (c *OAuth) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *OAuth) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
func (c *OAuth) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.oauth.Authenticate")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
r.SetMeta(authn.MetaKeyAuthModule, c.moduleName)
|
r.SetMeta(authn.MetaKeyAuthModule, c.moduleName)
|
||||||
|
|
||||||
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
|
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
|
||||||
@ -232,6 +239,9 @@ func (c *OAuth) GetConfig() authn.SSOClientConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *OAuth) RedirectURL(ctx context.Context, r *authn.Request) (*authn.Redirect, error) {
|
func (c *OAuth) RedirectURL(ctx context.Context, r *authn.Request) (*authn.Redirect, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.oauth.RedirectURL") //nolint:ineffassign,staticcheck
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
var opts []oauth2.AuthCodeOption
|
var opts []oauth2.AuthCodeOption
|
||||||
|
|
||||||
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
|
oauthCfg := c.socialService.GetOAuthInfoProvider(c.providerName)
|
||||||
@ -274,6 +284,9 @@ func (c *OAuth) RedirectURL(ctx context.Context, r *authn.Request) (*authn.Redir
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *OAuth) Logout(ctx context.Context, user identity.Requester, sessionToken *auth.UserToken) (*authn.Redirect, bool) {
|
func (c *OAuth) Logout(ctx context.Context, user identity.Requester, sessionToken *auth.UserToken) (*authn.Redirect, bool) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.oauth.Logout")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
token := c.oauthService.GetCurrentOAuthToken(ctx, user, sessionToken)
|
token := c.oauthService.GetCurrentOAuthToken(ctx, user, sessionToken)
|
||||||
|
|
||||||
userID, err := identity.UserIdentifier(user.GetID())
|
userID, err := identity.UserIdentifier(user.GetID())
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/login/social"
|
"github.com/grafana/grafana/pkg/login/social"
|
||||||
"github.com/grafana/grafana/pkg/login/social/socialtest"
|
"github.com/grafana/grafana/pkg/login/social/socialtest"
|
||||||
"github.com/grafana/grafana/pkg/services/auth"
|
"github.com/grafana/grafana/pkg/services/auth"
|
||||||
@ -296,7 +297,7 @@ func TestOAuth_Authenticate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, settingsProvider, featuremgmt.WithFeatures(tt.features...))
|
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, settingsProvider, featuremgmt.WithFeatures(tt.features...), tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
identity, err := c.Authenticate(context.Background(), tt.req)
|
identity, err := c.Authenticate(context.Background(), tt.req)
|
||||||
assert.ErrorIs(t, err, tt.expectedErr)
|
assert.ErrorIs(t, err, tt.expectedErr)
|
||||||
@ -376,7 +377,7 @@ func TestOAuth_RedirectURL(t *testing.T) {
|
|||||||
|
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
|
|
||||||
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, &setting.OSSImpl{Cfg: cfg}, featuremgmt.WithFeatures())
|
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), cfg, nil, fakeSocialSvc, &setting.OSSImpl{Cfg: cfg}, featuremgmt.WithFeatures(), tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
redirect, err := c.RedirectURL(context.Background(), nil)
|
redirect, err := c.RedirectURL(context.Background(), nil)
|
||||||
assert.ErrorIs(t, err, tt.expectedErr)
|
assert.ErrorIs(t, err, tt.expectedErr)
|
||||||
@ -489,7 +490,7 @@ func TestOAuth_Logout(t *testing.T) {
|
|||||||
fakeSocialSvc := &socialtest.FakeSocialService{
|
fakeSocialSvc := &socialtest.FakeSocialService{
|
||||||
ExpectedAuthInfoProvider: tt.oauthCfg,
|
ExpectedAuthInfoProvider: tt.oauthCfg,
|
||||||
}
|
}
|
||||||
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc, &setting.OSSImpl{Cfg: tt.cfg}, featuremgmt.WithFeatures())
|
c := ProvideOAuth(authn.ClientWithPrefix("azuread"), tt.cfg, mockService, fakeSocialSvc, &setting.OSSImpl{Cfg: tt.cfg}, featuremgmt.WithFeatures(), tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
redirect, ok := c.Logout(context.Background(), &authn.Identity{ID: "1", Type: claims.TypeUser}, nil)
|
redirect, ok := c.Logout(context.Background(), &authn.Identity{ID: "1", Type: claims.TypeUser}, nil)
|
||||||
|
|
||||||
@ -549,7 +550,8 @@ func TestIsEnabled(t *testing.T) {
|
|||||||
nil,
|
nil,
|
||||||
fakeSocialSvc,
|
fakeSocialSvc,
|
||||||
&setting.OSSImpl{Cfg: cfg},
|
&setting.OSSImpl{Cfg: cfg},
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures(),
|
||||||
|
tracing.InitializeTracerForTest())
|
||||||
assert.Equal(t, tt.expected, c.IsEnabled())
|
assert.Equal(t, tt.expected, c.IsEnabled())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
@ -18,17 +20,20 @@ var (
|
|||||||
|
|
||||||
var _ authn.PasswordClient = new(Password)
|
var _ authn.PasswordClient = new(Password)
|
||||||
|
|
||||||
func ProvidePassword(loginAttempts loginattempt.Service, clients ...authn.PasswordClient) *Password {
|
func ProvidePassword(loginAttempts loginattempt.Service, tracer trace.Tracer, clients ...authn.PasswordClient) *Password {
|
||||||
return &Password{loginAttempts, clients, log.New("authn.password")}
|
return &Password{loginAttempts, clients, log.New("authn.password"), tracer}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Password struct {
|
type Password struct {
|
||||||
loginAttempts loginattempt.Service
|
loginAttempts loginattempt.Service
|
||||||
clients []authn.PasswordClient
|
clients []authn.PasswordClient
|
||||||
log log.Logger
|
log log.Logger
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Password) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
|
func (c *Password) AuthenticatePassword(ctx context.Context, r *authn.Request, username, password string) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.password.AuthenticatePassword")
|
||||||
|
defer span.End()
|
||||||
r.SetMeta(authn.MetaKeyUsername, username)
|
r.SetMeta(authn.MetaKeyUsername, username)
|
||||||
|
|
||||||
ok, err := c.loginAttempts.Validate(ctx, username)
|
ok, err := c.loginAttempts.Validate(ctx, username)
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
||||||
"github.com/grafana/grafana/pkg/services/loginattempt/loginattempttest"
|
"github.com/grafana/grafana/pkg/services/loginattempt/loginattempttest"
|
||||||
@ -65,7 +66,7 @@ func TestPassword_AuthenticatePassword(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
c := ProvidePassword(loginattempttest.FakeLoginAttemptService{ExpectedValid: !tt.blockLogin}, tt.clients...)
|
c := ProvidePassword(loginattempttest.FakeLoginAttemptService{ExpectedValid: !tt.blockLogin}, tracing.InitializeTracerForTest(), tt.clients...)
|
||||||
r := &authn.Request{
|
r := &authn.Request{
|
||||||
OrgID: 12345,
|
OrgID: 12345,
|
||||||
HTTPRequest: &http.Request{
|
HTTPRequest: &http.Request{
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
@ -45,12 +46,12 @@ var (
|
|||||||
_ authn.ContextAwareClient = new(Proxy)
|
_ authn.ContextAwareClient = new(Proxy)
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideProxy(cfg *setting.Cfg, cache proxyCache, clients ...authn.ProxyClient) (*Proxy, error) {
|
func ProvideProxy(cfg *setting.Cfg, cache proxyCache, tracer trace.Tracer, clients ...authn.ProxyClient) (*Proxy, error) {
|
||||||
list, err := parseAcceptList(cfg.AuthProxy.Whitelist)
|
list, err := parseAcceptList(cfg.AuthProxy.Whitelist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Proxy{log.New(authn.ClientProxy), cfg, cache, clients, list}, nil
|
return &Proxy{log.New(authn.ClientProxy), cfg, cache, clients, list, tracer}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type proxyCache interface {
|
type proxyCache interface {
|
||||||
@ -65,6 +66,7 @@ type Proxy struct {
|
|||||||
cache proxyCache
|
cache proxyCache
|
||||||
clients []authn.ProxyClient
|
clients []authn.ProxyClient
|
||||||
acceptedIPs []*net.IPNet
|
acceptedIPs []*net.IPNet
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Proxy) Name() string {
|
func (c *Proxy) Name() string {
|
||||||
@ -72,6 +74,8 @@ func (c *Proxy) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Proxy) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
func (c *Proxy) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.proxy.Authenticate")
|
||||||
|
defer span.End()
|
||||||
if !c.isAllowedIP(r) {
|
if !c.isAllowedIP(r) {
|
||||||
return nil, errNotAcceptedIP.Errorf("request ip is not in the configured accept list")
|
return nil, errNotAcceptedIP.Errorf("request ip is not in the configured accept list")
|
||||||
}
|
}
|
||||||
@ -115,6 +119,8 @@ func (c *Proxy) IsEnabled() bool {
|
|||||||
// See if we have cached the user id, in that case we can fetch the signed-in user and skip sync.
|
// See if we have cached the user id, in that case we can fetch the signed-in user and skip sync.
|
||||||
// Error here means that we could not find anything in cache, so we can proceed as usual
|
// Error here means that we could not find anything in cache, so we can proceed as usual
|
||||||
func (c *Proxy) retrieveIDFromCache(ctx context.Context, cacheKey string, r *authn.Request) (*authn.Identity, error) {
|
func (c *Proxy) retrieveIDFromCache(ctx context.Context, cacheKey string, r *authn.Request) (*authn.Identity, error) {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.proxy.retrieveIDFromCache")
|
||||||
|
defer span.End()
|
||||||
entry, err := c.cache.Get(ctx, cacheKey)
|
entry, err := c.cache.Get(ctx, cacheKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -148,6 +154,8 @@ func (c *Proxy) Priority() uint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Proxy) Hook(ctx context.Context, id *authn.Identity, r *authn.Request) error {
|
func (c *Proxy) Hook(ctx context.Context, id *authn.Identity, r *authn.Request) error {
|
||||||
|
ctx, span := c.tracer.Start(ctx, "authn.proxy.Hook")
|
||||||
|
defer span.End()
|
||||||
if id.ClientParams.CacheAuthProxyKey == "" {
|
if id.ClientParams.CacheAuthProxyKey == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
"github.com/grafana/grafana/pkg/services/authn/authntest"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@ -113,7 +114,7 @@ func TestProxy_Authenticate(t *testing.T) {
|
|||||||
calledAdditional = additional
|
calledAdditional = additional
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}}
|
}}
|
||||||
c, err := ProvideProxy(cfg, &fakeCache{expectedErr: errors.New("")}, proxyClient)
|
c, err := ProvideProxy(cfg, &fakeCache{expectedErr: errors.New("")}, tracing.InitializeTracerForTest(), proxyClient)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = c.Authenticate(context.Background(), tt.req)
|
_, err = c.Authenticate(context.Background(), tt.req)
|
||||||
@ -169,7 +170,7 @@ func TestProxy_Test(t *testing.T) {
|
|||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
cfg.AuthProxy.HeaderName = "Proxy-Header"
|
cfg.AuthProxy.HeaderName = "Proxy-Header"
|
||||||
|
|
||||||
c, _ := ProvideProxy(cfg, nil, nil, nil)
|
c, _ := ProvideProxy(cfg, nil, tracing.InitializeTracerForTest(), nil)
|
||||||
assert.Equal(t, tt.expectedOK, c.Test(context.Background(), tt.req))
|
assert.Equal(t, tt.expectedOK, c.Test(context.Background(), tt.req))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -208,7 +209,7 @@ func TestProxy_Hook(t *testing.T) {
|
|||||||
withRole := func(role string) func(t *testing.T) {
|
withRole := func(role string) func(t *testing.T) {
|
||||||
cacheKey := fmt.Sprintf("users:johndoe-%s", role)
|
cacheKey := fmt.Sprintf("users:johndoe-%s", role)
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
c, err := ProvideProxy(cfg, cache, authntest.MockProxyClient{})
|
c, err := ProvideProxy(cfg, cache, tracing.InitializeTracerForTest(), authntest.MockProxyClient{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
userIdentity := &authn.Identity{
|
userIdentity := &authn.Identity{
|
||||||
ID: "1",
|
ID: "1",
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/auth"
|
"github.com/grafana/grafana/pkg/services/auth"
|
||||||
@ -18,12 +20,14 @@ import (
|
|||||||
|
|
||||||
var _ authn.ContextAwareClient = new(Session)
|
var _ authn.ContextAwareClient = new(Session)
|
||||||
|
|
||||||
func ProvideSession(cfg *setting.Cfg, sessionService auth.UserTokenService, authInfoService login.AuthInfoService) *Session {
|
func ProvideSession(cfg *setting.Cfg, sessionService auth.UserTokenService,
|
||||||
|
authInfoService login.AuthInfoService, tracer trace.Tracer) *Session {
|
||||||
return &Session{
|
return &Session{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
log: log.New(authn.ClientSession),
|
log: log.New(authn.ClientSession),
|
||||||
sessionService: sessionService,
|
sessionService: sessionService,
|
||||||
authInfoService: authInfoService,
|
authInfoService: authInfoService,
|
||||||
|
tracer: tracer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +36,7 @@ type Session struct {
|
|||||||
log log.Logger
|
log log.Logger
|
||||||
sessionService auth.UserTokenService
|
sessionService auth.UserTokenService
|
||||||
authInfoService login.AuthInfoService
|
authInfoService login.AuthInfoService
|
||||||
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) Name() string {
|
func (s *Session) Name() string {
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
claims "github.com/grafana/authlib/types"
|
claims "github.com/grafana/authlib/types"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/models/usertoken"
|
"github.com/grafana/grafana/pkg/models/usertoken"
|
||||||
"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"
|
||||||
@ -31,7 +32,7 @@ func TestSession_Test(t *testing.T) {
|
|||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
cfg.LoginCookieName = ""
|
cfg.LoginCookieName = ""
|
||||||
cfg.LoginMaxLifetime = 20 * time.Second
|
cfg.LoginMaxLifetime = 20 * time.Second
|
||||||
s := ProvideSession(cfg, &authtest.FakeUserAuthTokenService{}, &authinfotest.FakeService{})
|
s := ProvideSession(cfg, &authtest.FakeUserAuthTokenService{}, &authinfotest.FakeService{}, tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
disabled := s.Test(context.Background(), &authn.Request{HTTPRequest: validHTTPReq})
|
disabled := s.Test(context.Background(), &authn.Request{HTTPRequest: validHTTPReq})
|
||||||
assert.False(t, disabled)
|
assert.False(t, disabled)
|
||||||
@ -194,7 +195,7 @@ func TestSession_Authenticate(t *testing.T) {
|
|||||||
cfg.LoginCookieName = cookieName
|
cfg.LoginCookieName = cookieName
|
||||||
cfg.TokenRotationIntervalMinutes = 10
|
cfg.TokenRotationIntervalMinutes = 10
|
||||||
cfg.LoginMaxLifetime = 20 * time.Second
|
cfg.LoginMaxLifetime = 20 * time.Second
|
||||||
s := ProvideSession(cfg, tt.fields.sessionService, tt.fields.authInfoService)
|
s := ProvideSession(cfg, tt.fields.sessionService, tt.fields.authInfoService, tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
got, err := s.Authenticate(context.Background(), tt.args.r)
|
got, err := s.Authenticate(context.Background(), tt.args.r)
|
||||||
require.True(t, (err != nil) == tt.wantErr, err)
|
require.True(t, (err != nil) == tt.wantErr, err)
|
||||||
|
Reference in New Issue
Block a user