2020-12-11 11:44:44 +01:00
|
|
|
package contexthandler
|
2020-06-17 18:43:16 +02:00
|
|
|
|
|
|
|
|
import (
|
2021-05-18 18:24:42 +02:00
|
|
|
"context"
|
2020-06-17 18:43:16 +02:00
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
|
|
|
|
"testing"
|
|
|
|
|
|
2022-09-27 07:58:49 -04:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
2022-10-19 09:02:15 -04:00
|
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
2020-06-17 18:43:16 +02:00
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/remotecache"
|
2022-01-20 11:10:12 +01:00
|
|
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
2020-06-17 18:43:16 +02:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2022-11-18 09:56:06 +01:00
|
|
|
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
2020-12-11 11:44:44 +01:00
|
|
|
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
|
2022-03-30 17:01:24 +02:00
|
|
|
"github.com/grafana/grafana/pkg/services/login/loginservice"
|
2022-10-04 14:48:02 -04:00
|
|
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
2020-12-11 11:44:44 +01:00
|
|
|
"github.com/grafana/grafana/pkg/services/rendering"
|
2022-06-28 14:32:25 +02:00
|
|
|
"github.com/grafana/grafana/pkg/services/user"
|
2022-08-04 15:44:14 +02:00
|
|
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
2020-06-17 18:43:16 +02:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2021-10-11 14:30:59 +02:00
|
|
|
"github.com/grafana/grafana/pkg/web"
|
2020-06-17 18:43:16 +02:00
|
|
|
)
|
|
|
|
|
|
2022-03-30 17:01:24 +02:00
|
|
|
const userID = int64(1)
|
|
|
|
|
const orgID = int64(4)
|
|
|
|
|
|
2020-06-17 18:43:16 +02:00
|
|
|
// 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"
|
|
|
|
|
|
2021-08-25 15:11:22 +02:00
|
|
|
svc := getContextHandler(t)
|
|
|
|
|
|
2020-06-17 18:43:16 +02:00
|
|
|
req, err := http.NewRequest("POST", "http://example.com", nil)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
ctx := &models.ReqContext{
|
2021-10-11 14:30:59 +02:00
|
|
|
Context: &web.Context{Req: req},
|
2021-09-13 16:41:03 +03:00
|
|
|
Logger: log.New("Test"),
|
2020-06-17 18:43:16 +02:00
|
|
|
}
|
2020-12-11 11:44:44 +01:00
|
|
|
req.Header.Set(svc.Cfg.AuthProxyHeaderName, name)
|
2020-12-15 09:32:06 +01:00
|
|
|
h, err := authproxy.HashCacheKey(name)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
key := fmt.Sprintf(authproxy.CachePrefix, h)
|
2020-06-17 18:43:16 +02:00
|
|
|
|
|
|
|
|
t.Logf("Injecting stale user ID in cache with key %q", key)
|
2021-12-22 11:02:42 +01:00
|
|
|
err = svc.RemoteCache.Set(context.Background(), key, int64(33), 0)
|
2020-06-17 18:43:16 +02:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2020-12-11 11:44:44 +01:00
|
|
|
authEnabled := svc.initContextWithAuthProxy(ctx, orgID)
|
2020-06-17 18:43:16 +02:00
|
|
|
require.True(t, authEnabled)
|
|
|
|
|
|
2022-08-11 13:28:55 +02:00
|
|
|
require.Equal(t, userID, ctx.SignedInUser.UserID)
|
2020-06-17 18:43:16 +02:00
|
|
|
require.True(t, ctx.IsSignedIn)
|
|
|
|
|
|
2021-12-22 11:02:42 +01:00
|
|
|
i, err := svc.RemoteCache.Get(context.Background(), key)
|
2020-06-17 18:43:16 +02:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, userID, i.(int64))
|
|
|
|
|
}
|
2020-12-11 11:44:44 +01:00
|
|
|
|
|
|
|
|
type fakeRenderService struct {
|
|
|
|
|
rendering.Service
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getContextHandler(t *testing.T) *ContextHandler {
|
|
|
|
|
t.Helper()
|
|
|
|
|
|
2022-10-19 09:02:15 -04:00
|
|
|
sqlStore := db.InitTestDB(t)
|
2020-12-11 11:44:44 +01:00
|
|
|
|
|
|
|
|
cfg := setting.NewCfg()
|
|
|
|
|
cfg.RemoteCacheOptions = &setting.RemoteCacheOptions{
|
|
|
|
|
Name: "database",
|
|
|
|
|
}
|
|
|
|
|
cfg.AuthProxyHeaderName = "X-Killa"
|
|
|
|
|
cfg.AuthProxyEnabled = true
|
|
|
|
|
cfg.AuthProxyHeaderProperty = "username"
|
2021-08-25 15:11:22 +02:00
|
|
|
remoteCacheSvc, err := remotecache.ProvideService(cfg, sqlStore)
|
|
|
|
|
require.NoError(t, err)
|
2022-11-18 09:56:06 +01:00
|
|
|
userAuthTokenSvc := authtest.NewFakeUserAuthTokenService()
|
2020-12-11 11:44:44 +01:00
|
|
|
renderSvc := &fakeRenderService{}
|
2021-03-31 15:40:44 +00:00
|
|
|
authJWTSvc := models.NewFakeJWTService()
|
2022-06-15 12:40:41 +02:00
|
|
|
tracer := tracing.InitializeTracerForTest()
|
2020-12-11 11:44:44 +01:00
|
|
|
|
2022-06-28 14:32:25 +02:00
|
|
|
loginService := loginservice.LoginServiceMock{ExpectedUser: &user.User{ID: userID}}
|
2022-09-27 07:58:49 -04:00
|
|
|
userService := usertest.FakeUserService{
|
|
|
|
|
GetSignedInUserFn: func(ctx context.Context, query *user.GetSignedInUserQuery) (*user.SignedInUser, error) {
|
|
|
|
|
if query.UserID != userID {
|
|
|
|
|
return &user.SignedInUser{}, user.ErrUserNotFound
|
|
|
|
|
}
|
|
|
|
|
return &user.SignedInUser{
|
|
|
|
|
UserID: userID,
|
|
|
|
|
OrgID: orgID,
|
|
|
|
|
}, nil
|
|
|
|
|
},
|
|
|
|
|
}
|
2022-10-04 14:48:02 -04:00
|
|
|
orgService := orgtest.NewOrgServiceFake()
|
2022-09-27 07:58:49 -04:00
|
|
|
|
|
|
|
|
authProxy := authproxy.ProvideAuthProxy(cfg, remoteCacheSvc, loginService, &userService, &FakeGetSignUserStore{})
|
2022-04-08 10:33:19 +02:00
|
|
|
authenticator := &fakeAuthenticator{}
|
2022-03-30 17:01:24 +02:00
|
|
|
|
2022-09-27 07:58:49 -04:00
|
|
|
return ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc,
|
2022-10-04 14:48:02 -04:00
|
|
|
renderSvc, sqlStore, tracer, authProxy, loginService, nil, authenticator,
|
2022-11-22 10:58:59 +01:00
|
|
|
&userService, orgService, nil, nil)
|
2022-03-30 17:01:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type FakeGetSignUserStore struct {
|
2022-10-19 09:02:15 -04:00
|
|
|
db.DB
|
2022-03-30 17:01:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f *FakeGetSignUserStore) GetSignedInUser(ctx context.Context, query *models.GetSignedInUserQuery) error {
|
|
|
|
|
if query.UserId != userID {
|
2022-07-20 14:50:06 +02:00
|
|
|
return user.ErrUserNotFound
|
2022-03-30 17:01:24 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-10 11:56:48 +02:00
|
|
|
query.Result = &user.SignedInUser{
|
2022-08-11 13:28:55 +02:00
|
|
|
UserID: userID,
|
|
|
|
|
OrgID: orgID,
|
2022-03-30 17:01:24 +02:00
|
|
|
}
|
|
|
|
|
return nil
|
2020-12-11 11:44:44 +01:00
|
|
|
}
|
2022-04-08 10:33:19 +02:00
|
|
|
|
|
|
|
|
type fakeAuthenticator struct{}
|
|
|
|
|
|
|
|
|
|
func (fa *fakeAuthenticator) AuthenticateUser(c context.Context, query *models.LoginUserQuery) error {
|
|
|
|
|
return nil
|
|
|
|
|
}
|