Auth: Refactor auth package (#58920)

* Auth: move interface to its own file

* Auth: move to test package

* Auth: move quota consts to auth file

* Auth: move service to impl package

* Auth: move interfaces and related models to auth package

* Auth: Create sub package and type alias to avoid circular dependency
This commit is contained in:
Karl Persson
2022-11-18 09:56:06 +01:00
committed by GitHub
parent ea27eca147
commit fef1e1d5bc
35 changed files with 245 additions and 221 deletions
+4 -3
View File
@@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@@ -416,7 +417,7 @@ func (hs *HTTPServer) AdminGetUserAuthTokens(c *models.ReqContext) response.Resp
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) AdminRevokeUserAuthToken(c *models.ReqContext) response.Response {
cmd := models.RevokeAuthTokenCmd{}
cmd := auth.RevokeAuthTokenCmd{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
@@ -476,7 +477,7 @@ type AdminLogoutUserParams struct {
type AdminRevokeUserAuthTokenParams struct {
// in:body
// required:true
Body models.RevokeAuthTokenCmd `json:"body"`
Body auth.RevokeAuthTokenCmd `json:"body"`
// in:path
// required:true
UserID int64 `json:"user_id"`
@@ -508,5 +509,5 @@ type AdminCreateUserResponseResponse struct {
// swagger:response adminGetUserAuthTokensResponse
type AdminGetUserAuthTokensResponse struct {
// in:body
Body []*models.UserToken `json:"body"`
Body []*auth.UserToken `json:"body"`
}
+7 -6
View File
@@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/auth/authtest"
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/org"
@@ -65,7 +66,7 @@ func TestAdminAPIEndpoint(t *testing.T) {
})
t.Run("When a server admin attempts to revoke an auth token for a non-existing user", func(t *testing.T) {
cmd := models.RevokeAuthTokenCmd{AuthTokenId: 2}
cmd := auth.RevokeAuthTokenCmd{AuthTokenId: 2}
mockUser := usertest.NewUserServiceFake()
mockUser.ExpectedError = user.ErrUserNotFound
adminRevokeUserAuthTokenScenario(t, "Should return not found when calling POST on",
@@ -263,7 +264,7 @@ func putAdminScenario(t *testing.T, desc string, url string, routePattern string
func adminLogoutUserScenario(t *testing.T, desc string, url string, routePattern string, fn scenarioFunc, userService *usertest.FakeUserService) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
hs := HTTPServer{
AuthTokenService: auth.NewFakeUserAuthTokenService(),
AuthTokenService: authtest.NewFakeUserAuthTokenService(),
userService: userService,
}
@@ -285,9 +286,9 @@ func adminLogoutUserScenario(t *testing.T, desc string, url string, routePattern
})
}
func adminRevokeUserAuthTokenScenario(t *testing.T, desc string, url string, routePattern string, cmd models.RevokeAuthTokenCmd, fn scenarioFunc, userService user.Service) {
func adminRevokeUserAuthTokenScenario(t *testing.T, desc string, url string, routePattern string, cmd auth.RevokeAuthTokenCmd, fn scenarioFunc, userService user.Service) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
hs := HTTPServer{
AuthTokenService: fakeAuthTokenService,
@@ -315,7 +316,7 @@ func adminRevokeUserAuthTokenScenario(t *testing.T, desc string, url string, rou
func adminGetUserAuthTokensScenario(t *testing.T, desc string, url string, routePattern string, fn scenarioFunc, userService *usertest.FakeUserService) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
hs := HTTPServer{
AuthTokenService: fakeAuthTokenService,
@@ -341,7 +342,7 @@ func adminGetUserAuthTokensScenario(t *testing.T, desc string, url string, route
func adminDisableUserScenario(t *testing.T, desc string, action string, url string, routePattern string, fn scenarioFunc) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
authInfoService := &logintest.AuthInfoServiceFake{}
+3 -3
View File
@@ -28,7 +28,7 @@ import (
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/auth/authtest"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
@@ -181,7 +181,7 @@ type scenarioContext struct {
defaultHandler web.Handler
req *http.Request
url string
userAuthTokenService *auth.FakeUserAuthTokenService
userAuthTokenService *authtest.FakeUserAuthTokenService
sqlStore sqlstore.Store
authInfoService *logintest.AuthInfoServiceFake
dashboardVersionService dashver.Service
@@ -207,7 +207,7 @@ func getContextHandler(t *testing.T, cfg *setting.Cfg) *contexthandler.ContextHa
cfg.RemoteCacheOptions = &setting.RemoteCacheOptions{
Name: "database",
}
userAuthTokenSvc := auth.NewFakeUserAuthTokenService()
userAuthTokenSvc := authtest.NewFakeUserAuthTokenService()
renderSvc := &fakeRenderService{}
authJWTSvc := models.NewFakeJWTService()
tracer := tracing.InitializeTracerForTest()
+3 -2
View File
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/middleware/csrf"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/services/querylibrary"
@@ -120,7 +121,7 @@ type HTTPServer struct {
navTreeService navtree.Service
CacheService *localcache.CacheService
DataSourceCache datasources.CacheService
AuthTokenService models.UserTokenService
AuthTokenService auth.UserTokenService
QuotaService quota.Service
RemoteCacheService *remotecache.RemoteCache
ProvisioningService provisioning.ProvisioningService
@@ -220,7 +221,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
pluginRequestValidator models.PluginRequestValidator, pluginStaticRouteResolver plugins.StaticRouteResolver,
pluginDashboardService plugindashboards.Service, pluginStore plugins.Store, pluginClient plugins.Client,
pluginErrorResolver plugins.ErrorResolver, pluginInstaller plugins.Installer, settingsProvider setting.Provider,
dataSourceCache datasources.CacheService, userTokenService models.UserTokenService,
dataSourceCache datasources.CacheService, userTokenService auth.UserTokenService,
cleanUpService *cleanup.CleanUpService, shortURLService shorturls.Service, queryHistoryService queryhistory.Service, correlationsService correlations.Service,
thumbService thumbs.Service, remoteCache *remotecache.RemoteCache, provisioningService provisioning.ProvisioningService,
loginService login.Service, authenticator loginpkg.Authenticator, accessControl accesscontrol.AccessControl,
+2 -2
View File
@@ -15,7 +15,7 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/auth/authtest"
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/login/logintest"
@@ -379,7 +379,7 @@ func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(*
hs := &HTTPServer{
Cfg: sc.cfg,
AuthTokenService: auth.NewFakeUserAuthTokenService(),
AuthTokenService: authtest.NewFakeUserAuthTokenService(),
Login: loginservice.LoginServiceMock{},
authInfoService: sc.authInfoService,
userService: userService,
+4 -3
View File
@@ -16,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/login"
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
loginService "github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/user"
@@ -227,7 +228,7 @@ func (hs *HTTPServer) LoginPost(c *models.ReqContext) response.Response {
err = hs.loginUserWithUser(usr, c)
if err != nil {
var createTokenErr *models.CreateTokenErr
var createTokenErr *auth.CreateTokenErr
if errors.As(err, &createTokenErr) {
resp = response.Error(createTokenErr.StatusCode, createTokenErr.ExternalErr, createTokenErr.InternalErr)
} else {
@@ -299,7 +300,7 @@ func (hs *HTTPServer) Logout(c *models.ReqContext) {
}
err := hs.AuthTokenService.RevokeToken(c.Req.Context(), c.UserToken, false)
if err != nil && !errors.Is(err, models.ErrUserTokenNotFound) {
if err != nil && !errors.Is(err, auth.ErrUserTokenNotFound) {
hs.log.Error("failed to revoke auth token", "error", err)
}
@@ -370,7 +371,7 @@ func (hs *HTTPServer) samlSingleLogoutEnabled() bool {
}
func getLoginExternalError(err error) string {
var createTokenErr *models.CreateTokenErr
var createTokenErr *auth.CreateTokenErr
if errors.As(err, &createTokenErr) {
return createTokenErr.ExternalErr
}
+6 -6
View File
@@ -12,8 +12,6 @@ import (
"strings"
"testing"
loginservice "github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/navtree"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,9 +23,11 @@ import (
"github.com/grafana/grafana/pkg/login"
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/auth/authtest"
"github.com/grafana/grafana/pkg/services/hooks"
"github.com/grafana/grafana/pkg/services/licensing"
loginservice "github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/navtree"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
@@ -323,7 +323,7 @@ func TestLoginPostRedirect(t *testing.T) {
Cfg: setting.NewCfg(),
HooksService: &hooks.HooksService{},
License: &licensing.OSSLicensingService{},
AuthTokenService: auth.NewFakeUserAuthTokenService(),
AuthTokenService: authtest.NewFakeUserAuthTokenService(),
}
hs.Cfg.CookieSecure = true
@@ -564,7 +564,7 @@ func setupAuthProxyLoginTest(t *testing.T, enableLoginToken bool) *scenarioConte
Cfg: sc.cfg,
SettingsProvider: &setting.OSSImpl{Cfg: sc.cfg},
License: &licensing.OSSLicensingService{},
AuthTokenService: auth.NewFakeUserAuthTokenService(),
AuthTokenService: authtest.NewFakeUserAuthTokenService(),
log: log.New("hello"),
SocialService: &mockSocialService{},
}
@@ -602,7 +602,7 @@ func TestLoginPostRunLokingHook(t *testing.T) {
log: log.New("test"),
Cfg: setting.NewCfg(),
License: &licensing.OSSLicensingService{},
AuthTokenService: auth.NewFakeUserAuthTokenService(),
AuthTokenService: authtest.NewFakeUserAuthTokenService(),
HooksService: hookService,
}
+7 -6
View File
@@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@@ -43,7 +44,7 @@ func (hs *HTTPServer) GetUserAuthTokens(c *models.ReqContext) response.Response
// 403: forbiddenError
// 500: internalServerError
func (hs *HTTPServer) RevokeUserAuthToken(c *models.ReqContext) response.Response {
cmd := models.RevokeAuthTokenCmd{}
cmd := auth.RevokeAuthTokenCmd{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
@@ -143,7 +144,7 @@ func (hs *HTTPServer) getUserAuthTokensInternal(c *models.ReqContext, userID int
return response.JSON(http.StatusOK, result)
}
func (hs *HTTPServer) revokeUserAuthTokenInternal(c *models.ReqContext, userID int64, cmd models.RevokeAuthTokenCmd) response.Response {
func (hs *HTTPServer) revokeUserAuthTokenInternal(c *models.ReqContext, userID int64, cmd auth.RevokeAuthTokenCmd) response.Response {
userQuery := user.GetUserByIDQuery{ID: userID}
_, err := hs.userService.GetByID(c.Req.Context(), &userQuery)
if err != nil {
@@ -155,7 +156,7 @@ func (hs *HTTPServer) revokeUserAuthTokenInternal(c *models.ReqContext, userID i
token, err := hs.AuthTokenService.GetUserToken(c.Req.Context(), userID, cmd.AuthTokenId)
if err != nil {
if errors.Is(err, models.ErrUserTokenNotFound) {
if errors.Is(err, auth.ErrUserTokenNotFound) {
return response.Error(404, "User auth token not found", err)
}
return response.Error(500, "Failed to get user auth token", err)
@@ -167,7 +168,7 @@ func (hs *HTTPServer) revokeUserAuthTokenInternal(c *models.ReqContext, userID i
err = hs.AuthTokenService.RevokeToken(c.Req.Context(), token, false)
if err != nil {
if errors.Is(err, models.ErrUserTokenNotFound) {
if errors.Is(err, auth.ErrUserTokenNotFound) {
return response.Error(404, "User auth token not found", err)
}
return response.Error(500, "Failed to revoke user auth token", err)
@@ -182,11 +183,11 @@ func (hs *HTTPServer) revokeUserAuthTokenInternal(c *models.ReqContext, userID i
type RevokeUserAuthTokenParams struct {
// in:body
// required:true
Body models.RevokeAuthTokenCmd `json:"body"`
Body auth.RevokeAuthTokenCmd `json:"body"`
}
// swagger:response getUserAuthTokensResponse
type GetUserAuthTokensResponse struct {
// in:body
Body []*models.UserToken `json:"body"`
Body []*auth.UserToken `json:"body"`
}
+21 -20
View File
@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/auth/authtest"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/usertest"
@@ -20,7 +21,7 @@ import (
func TestUserTokenAPIEndpoint(t *testing.T) {
userMock := usertest.NewUserServiceFake()
t.Run("When current user attempts to revoke an auth token for a non-existing user", func(t *testing.T) {
cmd := models.RevokeAuthTokenCmd{AuthTokenId: 2}
cmd := auth.RevokeAuthTokenCmd{AuthTokenId: 2}
userMock.ExpectedError = user.ErrUserNotFound
revokeUserAuthTokenScenario(t, "Should return not found when calling POST on", "/api/user/revoke-auth-token",
"/api/user/revoke-auth-token", cmd, 200, func(sc *scenarioContext) {
@@ -59,15 +60,15 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
})
t.Run("When revoke an auth token for a user", func(t *testing.T) {
cmd := models.RevokeAuthTokenCmd{AuthTokenId: 2}
token := &models.UserToken{Id: 1}
cmd := auth.RevokeAuthTokenCmd{AuthTokenId: 2}
token := &auth.UserToken{Id: 1}
mockUser := &usertest.FakeUserService{
ExpectedUser: &user.User{ID: 200},
}
revokeUserAuthTokenInternalScenario(t, "Should be successful", cmd, 200, token, func(sc *scenarioContext) {
sc.userAuthTokenService.GetUserTokenProvider = func(ctx context.Context, userId, userTokenId int64) (*models.UserToken, error) {
return &models.UserToken{Id: 2}, nil
sc.userAuthTokenService.GetUserTokenProvider = func(ctx context.Context, userId, userTokenId int64) (*auth.UserToken, error) {
return &auth.UserToken{Id: 2}, nil
}
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
assert.Equal(t, 200, sc.resp.Code)
@@ -75,11 +76,11 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
})
t.Run("When revoke the active auth token used by himself", func(t *testing.T) {
cmd := models.RevokeAuthTokenCmd{AuthTokenId: 2}
token := &models.UserToken{Id: 2}
cmd := auth.RevokeAuthTokenCmd{AuthTokenId: 2}
token := &auth.UserToken{Id: 2}
mockUser := usertest.NewUserServiceFake()
revokeUserAuthTokenInternalScenario(t, "Should not be successful", cmd, testUserID, token, func(sc *scenarioContext) {
sc.userAuthTokenService.GetUserTokenProvider = func(ctx context.Context, userId, userTokenId int64) (*models.UserToken, error) {
sc.userAuthTokenService.GetUserTokenProvider = func(ctx context.Context, userId, userTokenId int64) (*auth.UserToken, error) {
return token, nil
}
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
@@ -88,10 +89,10 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
})
t.Run("When gets auth tokens for a user", func(t *testing.T) {
currentToken := &models.UserToken{Id: 1}
currentToken := &auth.UserToken{Id: 1}
mockUser := usertest.NewUserServiceFake()
getUserAuthTokensInternalScenario(t, "Should be successful", currentToken, func(sc *scenarioContext) {
tokens := []*models.UserToken{
tokens := []*auth.UserToken{
{
Id: 1,
ClientIp: "127.0.0.1",
@@ -107,7 +108,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
SeenAt: 0,
},
}
sc.userAuthTokenService.GetUserTokensProvider = func(ctx context.Context, userId int64) ([]*models.UserToken, error) {
sc.userAuthTokenService.GetUserTokensProvider = func(ctx context.Context, userId int64) ([]*auth.UserToken, error) {
return tokens, nil
}
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
@@ -145,10 +146,10 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
})
}
func revokeUserAuthTokenScenario(t *testing.T, desc string, url string, routePattern string, cmd models.RevokeAuthTokenCmd,
func revokeUserAuthTokenScenario(t *testing.T, desc string, url string, routePattern string, cmd auth.RevokeAuthTokenCmd,
userId int64, fn scenarioFunc, userService user.Service) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
hs := HTTPServer{
AuthTokenService: fakeAuthTokenService,
@@ -175,7 +176,7 @@ func revokeUserAuthTokenScenario(t *testing.T, desc string, url string, routePat
func getUserAuthTokensScenario(t *testing.T, desc string, url string, routePattern string, userId int64, fn scenarioFunc, userService user.Service) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
hs := HTTPServer{
AuthTokenService: fakeAuthTokenService,
@@ -202,7 +203,7 @@ func getUserAuthTokensScenario(t *testing.T, desc string, url string, routePatte
func logoutUserFromAllDevicesInternalScenario(t *testing.T, desc string, userId int64, fn scenarioFunc, userService user.Service) {
t.Run(desc, func(t *testing.T) {
hs := HTTPServer{
AuthTokenService: auth.NewFakeUserAuthTokenService(),
AuthTokenService: authtest.NewFakeUserAuthTokenService(),
userService: userService,
}
@@ -222,10 +223,10 @@ func logoutUserFromAllDevicesInternalScenario(t *testing.T, desc string, userId
})
}
func revokeUserAuthTokenInternalScenario(t *testing.T, desc string, cmd models.RevokeAuthTokenCmd, userId int64,
token *models.UserToken, fn scenarioFunc, userService user.Service) {
func revokeUserAuthTokenInternalScenario(t *testing.T, desc string, cmd auth.RevokeAuthTokenCmd, userId int64,
token *auth.UserToken, fn scenarioFunc, userService user.Service) {
t.Run(desc, func(t *testing.T) {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
hs := HTTPServer{
AuthTokenService: fakeAuthTokenService,
@@ -248,9 +249,9 @@ func revokeUserAuthTokenInternalScenario(t *testing.T, desc string, cmd models.R
})
}
func getUserAuthTokensInternalScenario(t *testing.T, desc string, token *models.UserToken, fn scenarioFunc, userService user.Service) {
func getUserAuthTokensInternalScenario(t *testing.T, desc string, token *auth.UserToken, fn scenarioFunc, userService user.Service) {
t.Run(desc, func(t *testing.T) {
fakeAuthTokenService := auth.NewFakeUserAuthTokenService()
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
hs := HTTPServer{
AuthTokenService: fakeAuthTokenService,