2019-03-08 22:15:38 +08:00
package api
import (
2019-04-30 20:42:01 +08:00
"context"
2020-11-13 16:52:38 +08:00
"fmt"
2023-03-23 21:39:04 +08:00
"net/http"
2025-07-18 23:06:26 +08:00
"net/url"
2019-03-08 22:15:38 +08:00
"testing"
"time"
2022-08-02 22:58:05 +08:00
"github.com/stretchr/testify/assert"
2023-03-23 21:39:04 +08:00
"github.com/stretchr/testify/require"
2022-08-02 22:58:05 +08:00
2021-01-15 21:43:20 +08:00
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
2023-03-23 21:39:04 +08:00
"github.com/grafana/grafana/pkg/infra/log"
2019-03-08 22:15:38 +08:00
"github.com/grafana/grafana/pkg/services/auth"
2022-11-18 16:56:06 +08:00
"github.com/grafana/grafana/pkg/services/auth/authtest"
2023-01-27 15:50:36 +08:00
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
2022-08-10 17:56:48 +08:00
"github.com/grafana/grafana/pkg/services/org"
2022-06-28 20:32:25 +08:00
"github.com/grafana/grafana/pkg/services/user"
2022-08-02 22:58:05 +08:00
"github.com/grafana/grafana/pkg/services/user/usertest"
2023-03-23 21:39:04 +08:00
"github.com/grafana/grafana/pkg/setting"
2025-07-18 23:06:26 +08:00
"github.com/grafana/grafana/pkg/web/webtest"
2019-03-08 22:15:38 +08:00
)
2020-11-13 16:52:38 +08:00
func TestUserTokenAPIEndpoint ( t * testing . T ) {
2022-08-02 22:58:05 +08:00
userMock := usertest . NewUserServiceFake ( )
2020-11-13 16:52:38 +08:00
t . Run ( "When current user attempts to revoke an auth token for a non-existing user" , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
cmd := auth . RevokeAuthTokenCmd { AuthTokenId : 2 }
2022-08-02 22:58:05 +08:00
userMock . ExpectedError = user . ErrUserNotFound
2020-11-13 16:52:38 +08:00
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 ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
assert . Equal ( t , 404 , sc . resp . Code )
2022-08-02 22:58:05 +08:00
} , userMock )
2019-03-08 22:15:38 +08:00
} )
2020-11-13 16:52:38 +08:00
t . Run ( "When current user gets auth tokens for a non-existing user" , func ( t * testing . T ) {
2022-08-02 22:58:05 +08:00
mockUser := & usertest . FakeUserService {
2022-06-28 20:32:25 +08:00
ExpectedUser : & user . User { ID : 200 } ,
2022-07-20 20:50:06 +08:00
ExpectedError : user . ErrUserNotFound ,
2022-02-03 16:20:20 +08:00
}
2020-11-13 16:52:38 +08:00
getUserAuthTokensScenario ( t , "Should return not found when calling GET on" , "/api/user/auth-tokens" , "/api/user/auth-tokens" , 200 , func ( sc * scenarioContext ) {
2019-03-08 22:15:38 +08:00
sc . fakeReqWithParams ( "GET" , sc . url , map [ string ] string { } ) . exec ( )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , 404 , sc . resp . Code )
2022-08-02 22:58:05 +08:00
} , mockUser )
2019-03-08 22:15:38 +08:00
} )
2020-11-13 16:52:38 +08:00
t . Run ( "When logging out an existing user from all devices" , func ( t * testing . T ) {
2022-08-02 22:58:05 +08:00
userMock := & usertest . FakeUserService {
2022-06-28 20:32:25 +08:00
ExpectedUser : & user . User { ID : 200 } ,
2022-02-03 16:20:20 +08:00
}
2020-11-13 16:52:38 +08:00
logoutUserFromAllDevicesInternalScenario ( t , "Should be successful" , 1 , func ( sc * scenarioContext ) {
2019-03-08 22:15:38 +08:00
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , 200 , sc . resp . Code )
2022-08-02 22:58:05 +08:00
} , userMock )
2019-03-08 22:15:38 +08:00
} )
2020-11-13 16:52:38 +08:00
t . Run ( "When logout a non-existing user from all devices" , func ( t * testing . T ) {
logoutUserFromAllDevicesInternalScenario ( t , "Should return not found" , testUserID , func ( sc * scenarioContext ) {
2022-08-02 22:58:05 +08:00
userMock . ExpectedError = user . ErrUserNotFound
2019-03-08 22:15:38 +08:00
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , 404 , sc . resp . Code )
2022-08-02 22:58:05 +08:00
} , userMock )
2019-03-08 22:15:38 +08:00
} )
2020-11-13 16:52:38 +08:00
t . Run ( "When revoke an auth token for a user" , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
cmd := auth . RevokeAuthTokenCmd { AuthTokenId : 2 }
token := & auth . UserToken { Id : 1 }
2022-08-02 22:58:05 +08:00
mockUser := & usertest . FakeUserService {
2022-06-28 20:32:25 +08:00
ExpectedUser : & user . User { ID : 200 } ,
2022-02-03 16:20:20 +08:00
}
2019-03-08 22:15:38 +08:00
2020-11-13 16:52:38 +08:00
revokeUserAuthTokenInternalScenario ( t , "Should be successful" , cmd , 200 , token , func ( sc * scenarioContext ) {
2022-11-18 16:56:06 +08:00
sc . userAuthTokenService . GetUserTokenProvider = func ( ctx context . Context , userId , userTokenId int64 ) ( * auth . UserToken , error ) {
return & auth . UserToken { Id : 2 } , nil
2019-03-08 22:15:38 +08:00
}
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , 200 , sc . resp . Code )
2022-08-02 22:58:05 +08:00
} , mockUser )
2019-03-08 22:15:38 +08:00
} )
2020-11-13 16:52:38 +08:00
t . Run ( "When revoke the active auth token used by himself" , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
cmd := auth . RevokeAuthTokenCmd { AuthTokenId : 2 }
token := & auth . UserToken { Id : 2 }
2022-08-02 22:58:05 +08:00
mockUser := usertest . NewUserServiceFake ( )
2020-11-13 16:52:38 +08:00
revokeUserAuthTokenInternalScenario ( t , "Should not be successful" , cmd , testUserID , token , func ( sc * scenarioContext ) {
2022-11-18 16:56:06 +08:00
sc . userAuthTokenService . GetUserTokenProvider = func ( ctx context . Context , userId , userTokenId int64 ) ( * auth . UserToken , error ) {
2019-03-08 22:15:38 +08:00
return token , nil
}
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , 400 , sc . resp . Code )
2022-08-02 22:58:05 +08:00
} , mockUser )
2019-03-08 22:15:38 +08:00
} )
2020-11-13 16:52:38 +08:00
t . Run ( "When gets auth tokens for a user" , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
currentToken := & auth . UserToken { Id : 1 }
2022-08-02 22:58:05 +08:00
mockUser := usertest . NewUserServiceFake ( )
2020-11-13 16:52:38 +08:00
getUserAuthTokensInternalScenario ( t , "Should be successful" , currentToken , func ( sc * scenarioContext ) {
2022-11-18 16:56:06 +08:00
tokens := [ ] * auth . UserToken {
2019-03-08 22:15:38 +08:00
{
Id : 1 ,
ClientIp : "127.0.0.1" ,
UserAgent : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36" ,
CreatedAt : time . Now ( ) . Unix ( ) ,
SeenAt : time . Now ( ) . Unix ( ) ,
} ,
{
Id : 2 ,
ClientIp : "127.0.0.2" ,
UserAgent : "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1" ,
CreatedAt : time . Now ( ) . Unix ( ) ,
2019-07-08 20:30:02 +08:00
SeenAt : 0 ,
2019-03-08 22:15:38 +08:00
} ,
}
2022-11-18 16:56:06 +08:00
sc . userAuthTokenService . GetUserTokensProvider = func ( ctx context . Context , userId int64 ) ( [ ] * auth . UserToken , error ) {
2019-03-08 22:15:38 +08:00
return tokens , nil
}
sc . fakeReqWithParams ( "GET" , sc . url , map [ string ] string { } ) . exec ( )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , 200 , sc . resp . Code )
2019-03-08 22:15:38 +08:00
result := sc . ToJSON ( )
2020-11-13 16:52:38 +08:00
assert . Len ( t , result . MustArray ( ) , 2 )
2019-03-08 22:15:38 +08:00
resultOne := result . GetIndex ( 0 )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , tokens [ 0 ] . Id , resultOne . Get ( "id" ) . MustInt64 ( ) )
assert . True ( t , resultOne . Get ( "isActive" ) . MustBool ( ) )
assert . Equal ( t , "127.0.0.1" , resultOne . Get ( "clientIp" ) . MustString ( ) )
assert . Equal ( t , time . Unix ( tokens [ 0 ] . CreatedAt , 0 ) . Format ( time . RFC3339 ) , resultOne . Get ( "createdAt" ) . MustString ( ) )
assert . Equal ( t , time . Unix ( tokens [ 0 ] . SeenAt , 0 ) . Format ( time . RFC3339 ) , resultOne . Get ( "seenAt" ) . MustString ( ) )
assert . Equal ( t , "Other" , resultOne . Get ( "device" ) . MustString ( ) )
assert . Equal ( t , "Chrome" , resultOne . Get ( "browser" ) . MustString ( ) )
assert . Equal ( t , "72.0" , resultOne . Get ( "browserVersion" ) . MustString ( ) )
assert . Equal ( t , "Linux" , resultOne . Get ( "os" ) . MustString ( ) )
assert . Empty ( t , resultOne . Get ( "osVersion" ) . MustString ( ) )
2019-06-11 20:12:52 +08:00
2019-03-08 22:15:38 +08:00
resultTwo := result . GetIndex ( 1 )
2020-11-13 16:52:38 +08:00
assert . Equal ( t , tokens [ 1 ] . Id , resultTwo . Get ( "id" ) . MustInt64 ( ) )
assert . False ( t , resultTwo . Get ( "isActive" ) . MustBool ( ) )
assert . Equal ( t , "127.0.0.2" , resultTwo . Get ( "clientIp" ) . MustString ( ) )
assert . Equal ( t , time . Unix ( tokens [ 1 ] . CreatedAt , 0 ) . Format ( time . RFC3339 ) , resultTwo . Get ( "createdAt" ) . MustString ( ) )
assert . Equal ( t , time . Unix ( tokens [ 1 ] . CreatedAt , 0 ) . Format ( time . RFC3339 ) , resultTwo . Get ( "seenAt" ) . MustString ( ) )
assert . Equal ( t , "iPhone" , resultTwo . Get ( "device" ) . MustString ( ) )
assert . Equal ( t , "Mobile Safari" , resultTwo . Get ( "browser" ) . MustString ( ) )
assert . Equal ( t , "11.0" , resultTwo . Get ( "browserVersion" ) . MustString ( ) )
assert . Equal ( t , "iOS" , resultTwo . Get ( "os" ) . MustString ( ) )
assert . Equal ( t , "11.0" , resultTwo . Get ( "osVersion" ) . MustString ( ) )
2022-08-02 22:58:05 +08:00
} , mockUser )
2019-03-08 22:15:38 +08:00
} )
}
2025-07-18 23:06:26 +08:00
func TestHTTPServer_RotateUserAuthTokenRedirect ( t * testing . T ) {
redirectTestCases := [ ] struct {
name string
redirectUrl string
expectedUrl string
} {
// Valid redirects should be preserved
{ "valid root path" , "/" , "/" } ,
{ "valid simple path" , "/hello" , "/hello" } ,
{ "valid single char path" , "/a" , "/a" } ,
{ "valid nested path" , "/asd/hello" , "/asd/hello" } ,
// Invalid redirects should be converted to root
{ "backslash domain" , ` /\grafana.com ` , "/" } ,
2025-09-02 22:12:39 +08:00
{ "backslash domain at the start of the path" , ` /\grafana.com/../a ` , "/" } ,
2025-07-18 23:06:26 +08:00
{ "traversal backslash domain" , ` /a/../\grafana.com ` , "/" } ,
{ "double slash" , "//grafana" , "/" } ,
{ "missing initial slash" , "missingInitialSlash" , "/" } ,
{ "parent directory" , "/../" , "/" } ,
}
sessionTestCases := [ ] struct {
name string
useSessionStorageRedirect bool
} {
{ "when useSessionStorageRedirect is enabled" , true } ,
{ "when useSessionStorageRedirect is disabled" , false } ,
}
for _ , sessionCase := range sessionTestCases {
t . Run ( sessionCase . name , func ( t * testing . T ) {
for _ , redirectCase := range redirectTestCases {
t . Run ( redirectCase . name , func ( t * testing . T ) {
server := SetupAPITestServer ( t , func ( hs * HTTPServer ) {
cfg := setting . NewCfg ( )
cfg . LoginCookieName = "grafana_session"
cfg . LoginMaxLifetime = 10 * time . Hour
hs . Cfg = cfg
hs . log = log . New ( )
hs . AuthTokenService = & authtest . FakeUserAuthTokenService {
RotateTokenProvider : func ( ctx context . Context , cmd auth . RotateCommand ) ( * auth . UserToken , error ) {
return & auth . UserToken { UnhashedToken : "new" } , nil
} ,
}
} )
redirectToQuery := url . QueryEscape ( redirectCase . redirectUrl )
urlString := "/user/auth-tokens/rotate"
if sessionCase . useSessionStorageRedirect {
urlString = urlString + "?redirectTo=" + redirectToQuery
}
req := server . NewGetRequest ( urlString )
req . AddCookie ( & http . Cookie { Name : "grafana_session" , Value : "123" , Path : "/" } )
if sessionCase . useSessionStorageRedirect {
req = webtest . RequestWithWebContext ( req , & contextmodel . ReqContext { UseSessionStorageRedirect : true } )
} else {
req . AddCookie ( & http . Cookie { Name : "redirect_to" , Value : redirectToQuery , Path : "/" } )
}
var redirectStatusCode int
var redirectLocation string
server . HttpClient . CheckRedirect = func ( req * http . Request , via [ ] * http . Request ) error {
if len ( via ) > 1 {
// Stop after first redirect
return http . ErrUseLastResponse
}
if req . Response == nil {
return nil
}
redirectStatusCode = req . Response . StatusCode
redirectLocation = req . Response . Header . Get ( "Location" )
return nil
}
res , err := server . Send ( req )
require . NoError ( t , err )
assert . Equal ( t , 302 , redirectStatusCode )
2025-09-02 22:12:39 +08:00
assert . Equal ( t , redirectCase . expectedUrl , redirectLocation , "redirectTo=%s" , redirectCase . redirectUrl )
2025-07-18 23:06:26 +08:00
require . NoError ( t , res . Body . Close ( ) )
} )
}
} )
}
}
2023-03-23 21:39:04 +08:00
func TestHTTPServer_RotateUserAuthToken ( t * testing . T ) {
type testCase struct {
desc string
cookie * http . Cookie
rotatedToken * auth . UserToken
rotatedErr error
expectedStatus int
expectNewSession bool
expectSessionDeleted bool
}
tests := [ ] testCase {
{
desc : "Should return 401 and delete cookie if the token is invalid" ,
cookie : & http . Cookie { Name : "grafana_session" , Value : "123" , Path : "/" } ,
rotatedErr : auth . ErrInvalidSessionToken ,
expectSessionDeleted : true ,
expectedStatus : http . StatusUnauthorized ,
} ,
{
2023-03-31 22:44:08 +08:00
desc : "Should return 401 and when token not found" ,
2023-03-23 21:39:04 +08:00
cookie : & http . Cookie { Name : "grafana_session" , Value : "123" , Path : "/" } ,
rotatedErr : auth . ErrUserTokenNotFound ,
2023-03-31 22:44:08 +08:00
expectedStatus : http . StatusUnauthorized ,
2023-03-23 21:39:04 +08:00
} ,
{
desc : "Should return 200 and but not set new cookie if token was not rotated" ,
cookie : & http . Cookie { Name : "grafana_session" , Value : "123" , Path : "/" } ,
rotatedToken : & auth . UserToken { UnhashedToken : "123" } ,
expectedStatus : http . StatusOK ,
} ,
{
desc : "Should return 200 and set new session and expiry cookies" ,
cookie : & http . Cookie { Name : "grafana_session" , Value : "123" , Path : "/" } ,
rotatedToken : & auth . UserToken { UnhashedToken : "new" } ,
expectNewSession : true ,
expectedStatus : http . StatusOK ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . desc , func ( t * testing . T ) {
server := SetupAPITestServer ( t , func ( hs * HTTPServer ) {
cfg := setting . NewCfg ( )
cfg . LoginCookieName = "grafana_session"
cfg . LoginMaxLifetime = 10 * time . Hour
hs . Cfg = cfg
hs . log = log . New ( )
hs . Cfg . LoginCookieName = "grafana_session"
hs . AuthTokenService = & authtest . FakeUserAuthTokenService {
RotateTokenProvider : func ( ctx context . Context , cmd auth . RotateCommand ) ( * auth . UserToken , error ) {
return tt . rotatedToken , tt . rotatedErr
} ,
}
} )
req := server . NewPostRequest ( "/api/user/auth-tokens/rotate" , nil )
if tt . cookie != nil {
req . AddCookie ( tt . cookie )
}
res , err := server . Send ( req )
require . NoError ( t , err )
assert . Equal ( t , tt . expectedStatus , res . StatusCode )
if tt . expectedStatus != http . StatusOK {
if tt . expectSessionDeleted {
cookies := res . Header . Values ( "Set-Cookie" )
require . Len ( t , cookies , 2 )
assert . Equal ( t , "grafana_session=; Path=/; Max-Age=0; HttpOnly" , cookies [ 0 ] )
assert . Equal ( t , "grafana_session_expiry=; Path=/; Max-Age=0" , cookies [ 1 ] )
} else {
assert . Empty ( t , res . Header . Get ( "Set-Cookie" ) )
}
} else {
if tt . expectNewSession {
cookies := res . Header . Values ( "Set-Cookie" )
require . Len ( t , cookies , 2 )
assert . Equal ( t , "grafana_session=new; Path=/; Max-Age=36000; HttpOnly" , cookies [ 0 ] )
assert . Equal ( t , "grafana_session_expiry=-5; Path=/; Max-Age=36000" , cookies [ 1 ] )
} else {
assert . Empty ( t , res . Header . Get ( "Set-Cookie" ) )
}
}
require . NoError ( t , res . Body . Close ( ) )
} )
}
}
2022-11-18 16:56:06 +08:00
func revokeUserAuthTokenScenario ( t * testing . T , desc string , url string , routePattern string , cmd auth . RevokeAuthTokenCmd ,
2022-08-02 22:58:05 +08:00
userId int64 , fn scenarioFunc , userService user . Service ) {
2020-11-13 16:52:38 +08:00
t . Run ( fmt . Sprintf ( "%s %s" , desc , url ) , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
fakeAuthTokenService := authtest . NewFakeUserAuthTokenService ( )
2019-03-08 22:15:38 +08:00
hs := HTTPServer {
AuthTokenService : fakeAuthTokenService ,
2022-08-02 22:58:05 +08:00
userService : userService ,
2019-03-08 22:15:38 +08:00
}
2020-11-13 16:52:38 +08:00
sc := setupScenarioContext ( t , url )
2019-03-08 22:15:38 +08:00
sc . userAuthTokenService = fakeAuthTokenService
2023-01-27 15:50:36 +08:00
sc . defaultHandler = routing . Wrap ( func ( c * contextmodel . ReqContext ) response . Response {
2021-11-29 17:18:01 +08:00
c . Req . Body = mockRequestBody ( cmd )
2019-03-08 22:15:38 +08:00
sc . context = c
2022-08-11 19:28:55 +08:00
sc . context . UserID = userId
sc . context . OrgID = testOrgID
2022-08-10 17:56:48 +08:00
sc . context . OrgRole = org . RoleAdmin
2019-03-08 22:15:38 +08:00
2021-11-29 17:18:01 +08:00
return hs . RevokeUserAuthToken ( c )
2019-03-08 22:15:38 +08:00
} )
sc . m . Post ( routePattern , sc . defaultHandler )
fn ( sc )
} )
}
2022-08-02 22:58:05 +08:00
func getUserAuthTokensScenario ( t * testing . T , desc string , url string , routePattern string , userId int64 , fn scenarioFunc , userService user . Service ) {
2020-11-13 16:52:38 +08:00
t . Run ( fmt . Sprintf ( "%s %s" , desc , url ) , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
fakeAuthTokenService := authtest . NewFakeUserAuthTokenService ( )
2019-03-08 22:15:38 +08:00
hs := HTTPServer {
AuthTokenService : fakeAuthTokenService ,
2022-08-02 22:58:05 +08:00
userService : userService ,
2019-03-08 22:15:38 +08:00
}
2020-11-13 16:52:38 +08:00
sc := setupScenarioContext ( t , url )
2019-03-08 22:15:38 +08:00
sc . userAuthTokenService = fakeAuthTokenService
2023-01-27 15:50:36 +08:00
sc . defaultHandler = routing . Wrap ( func ( c * contextmodel . ReqContext ) response . Response {
2019-03-08 22:15:38 +08:00
sc . context = c
2022-08-11 19:28:55 +08:00
sc . context . UserID = userId
sc . context . OrgID = testOrgID
2022-08-10 17:56:48 +08:00
sc . context . OrgRole = org . RoleAdmin
2019-03-08 22:15:38 +08:00
return hs . GetUserAuthTokens ( c )
} )
sc . m . Get ( routePattern , sc . defaultHandler )
fn ( sc )
} )
}
2022-08-02 22:58:05 +08:00
func logoutUserFromAllDevicesInternalScenario ( t * testing . T , desc string , userId int64 , fn scenarioFunc , userService user . Service ) {
2020-11-13 16:52:38 +08:00
t . Run ( desc , func ( t * testing . T ) {
2019-03-08 22:15:38 +08:00
hs := HTTPServer {
2022-11-18 16:56:06 +08:00
AuthTokenService : authtest . NewFakeUserAuthTokenService ( ) ,
2022-08-02 22:58:05 +08:00
userService : userService ,
2019-03-08 22:15:38 +08:00
}
2020-11-13 16:52:38 +08:00
sc := setupScenarioContext ( t , "/" )
2023-01-27 15:50:36 +08:00
sc . defaultHandler = routing . Wrap ( func ( c * contextmodel . ReqContext ) response . Response {
2019-03-08 22:15:38 +08:00
sc . context = c
2022-08-11 19:28:55 +08:00
sc . context . UserID = testUserID
sc . context . OrgID = testOrgID
2022-08-10 17:56:48 +08:00
sc . context . OrgRole = org . RoleAdmin
2019-03-08 22:15:38 +08:00
2019-04-30 20:42:01 +08:00
return hs . logoutUserFromAllDevicesInternal ( context . Background ( ) , userId )
2019-03-08 22:15:38 +08:00
} )
sc . m . Post ( "/" , sc . defaultHandler )
fn ( sc )
} )
}
2022-11-18 16:56:06 +08:00
func revokeUserAuthTokenInternalScenario ( t * testing . T , desc string , cmd auth . RevokeAuthTokenCmd , userId int64 ,
token * auth . UserToken , fn scenarioFunc , userService user . Service ) {
2020-11-13 16:52:38 +08:00
t . Run ( desc , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
fakeAuthTokenService := authtest . NewFakeUserAuthTokenService ( )
2019-03-08 22:15:38 +08:00
hs := HTTPServer {
AuthTokenService : fakeAuthTokenService ,
2022-08-02 22:58:05 +08:00
userService : userService ,
2019-03-08 22:15:38 +08:00
}
2020-11-13 16:52:38 +08:00
sc := setupScenarioContext ( t , "/" )
2019-03-08 22:15:38 +08:00
sc . userAuthTokenService = fakeAuthTokenService
2023-01-27 15:50:36 +08:00
sc . defaultHandler = routing . Wrap ( func ( c * contextmodel . ReqContext ) response . Response {
2019-03-08 22:15:38 +08:00
sc . context = c
2022-08-11 19:28:55 +08:00
sc . context . UserID = testUserID
sc . context . OrgID = testOrgID
2022-08-10 17:56:48 +08:00
sc . context . OrgRole = org . RoleAdmin
2019-03-08 22:15:38 +08:00
sc . context . UserToken = token
return hs . revokeUserAuthTokenInternal ( c , userId , cmd )
} )
sc . m . Post ( "/" , sc . defaultHandler )
fn ( sc )
} )
}
2022-11-18 16:56:06 +08:00
func getUserAuthTokensInternalScenario ( t * testing . T , desc string , token * auth . UserToken , fn scenarioFunc , userService user . Service ) {
2020-11-13 16:52:38 +08:00
t . Run ( desc , func ( t * testing . T ) {
2022-11-18 16:56:06 +08:00
fakeAuthTokenService := authtest . NewFakeUserAuthTokenService ( )
2019-03-08 22:15:38 +08:00
hs := HTTPServer {
AuthTokenService : fakeAuthTokenService ,
2022-08-02 22:58:05 +08:00
userService : userService ,
2019-03-08 22:15:38 +08:00
}
2020-11-13 16:52:38 +08:00
sc := setupScenarioContext ( t , "/" )
2019-03-08 22:15:38 +08:00
sc . userAuthTokenService = fakeAuthTokenService
2023-01-27 15:50:36 +08:00
sc . defaultHandler = routing . Wrap ( func ( c * contextmodel . ReqContext ) response . Response {
2019-03-08 22:15:38 +08:00
sc . context = c
2022-08-11 19:28:55 +08:00
sc . context . UserID = testUserID
sc . context . OrgID = testOrgID
2022-08-10 17:56:48 +08:00
sc . context . OrgRole = org . RoleAdmin
2019-03-08 22:15:38 +08:00
sc . context . UserToken = token
2020-11-13 16:52:38 +08:00
return hs . getUserAuthTokensInternal ( c , testUserID )
2019-03-08 22:15:38 +08:00
} )
sc . m . Get ( "/" , sc . defaultHandler )
fn ( sc )
} )
}