grafana/pkg/services/contexthandler/auth_proxy_test.go
Serge Zaitsev 57fcfd578d
Chore: replace macaron with web package (#40136)
* replace macaron with web package

* add web.go
2021-10-11 14:30:59 +02:00

108 lines
3.1 KiB
Go

package contexthandler
import (
"context"
"fmt"
"net/http"
"testing"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
)
// Test initContextWithAuthProxy with a cached user ID that is no longer valid.
//
// In this case, the cache entry should be ignored/cleared and another attempt should be done to sign the user
// in without cache.
func TestInitContextWithAuthProxy_CachedInvalidUserID(t *testing.T) {
const name = "markelog"
const userID = int64(1)
const orgID = int64(4)
svc := getContextHandler(t)
// XXX: These handlers have to be injected AFTER calling getContextHandler, since the latter
// creates a SQLStore which installs its own handlers.
upsertHandler := func(cmd *models.UpsertUserCommand) error {
require.Equal(t, name, cmd.ExternalUser.Login)
cmd.Result = &models.User{Id: userID}
return nil
}
getUserHandler := func(ctx context.Context, query *models.GetSignedInUserQuery) error {
// Simulate that the cached user ID is stale
if query.UserId != userID {
return models.ErrUserNotFound
}
query.Result = &models.SignedInUser{
UserId: userID,
OrgId: orgID,
}
return nil
}
bus.AddHandler("", upsertHandler)
bus.AddHandlerCtx("", getUserHandler)
t.Cleanup(func() {
bus.ClearBusHandlers()
})
req, err := http.NewRequest("POST", "http://example.com", nil)
require.NoError(t, err)
ctx := &models.ReqContext{
Context: &web.Context{Req: req},
Logger: log.New("Test"),
}
req.Header.Set(svc.Cfg.AuthProxyHeaderName, name)
h, err := authproxy.HashCacheKey(name)
require.NoError(t, err)
key := fmt.Sprintf(authproxy.CachePrefix, h)
t.Logf("Injecting stale user ID in cache with key %q", key)
err = svc.RemoteCache.Set(key, int64(33), 0)
require.NoError(t, err)
authEnabled := svc.initContextWithAuthProxy(ctx, orgID)
require.True(t, authEnabled)
require.Equal(t, userID, ctx.SignedInUser.UserId)
require.True(t, ctx.IsSignedIn)
i, err := svc.RemoteCache.Get(key)
require.NoError(t, err)
require.Equal(t, userID, i.(int64))
}
type fakeRenderService struct {
rendering.Service
}
func getContextHandler(t *testing.T) *ContextHandler {
t.Helper()
sqlStore := sqlstore.InitTestDB(t)
cfg := setting.NewCfg()
cfg.RemoteCacheOptions = &setting.RemoteCacheOptions{
Name: "database",
}
cfg.AuthProxyHeaderName = "X-Killa"
cfg.AuthProxyEnabled = true
cfg.AuthProxyHeaderProperty = "username"
remoteCacheSvc, err := remotecache.ProvideService(cfg, sqlStore)
require.NoError(t, err)
userAuthTokenSvc := auth.NewFakeUserAuthTokenService()
renderSvc := &fakeRenderService{}
authJWTSvc := models.NewFakeJWTService()
return ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc, renderSvc, sqlStore)
}