mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-09-01 05:08:33 +00:00
fix: consent screen skip status should get checked after auth (#1099)
This commit is contained in:
@@ -18,3 +18,8 @@ type RedirectQuery struct {
|
||||
RedirectURI string `url:"redirect_uri"`
|
||||
LoginFor FrontendLoginFor `url:"login_for"`
|
||||
}
|
||||
|
||||
type SimpleResponse struct {
|
||||
Status int `json:"status"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
@@ -62,15 +62,19 @@ type ErrorScreen struct {
|
||||
Error string `url:"error"`
|
||||
}
|
||||
|
||||
type ClientRequest struct {
|
||||
ClientID string `uri:"id" binding:"required"`
|
||||
}
|
||||
|
||||
type ClientCredentials struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
}
|
||||
|
||||
type SkipConsentRequest struct {
|
||||
OIDCTicket string `form:"oidc_ticket" binding:"required"`
|
||||
}
|
||||
|
||||
type SkipConsentResponse struct {
|
||||
SkipConsent bool `json:"skipConsent"`
|
||||
}
|
||||
|
||||
type AuthorizeScreenParams struct {
|
||||
LoginFor FrontendLoginFor `url:"login_for"`
|
||||
OIDCTicket string `url:"oidc_ticket"`
|
||||
@@ -105,6 +109,7 @@ func NewOIDCController(i OIDCControllerInput) *OIDCController {
|
||||
|
||||
oidcGroup := i.RouterGroup.Group("/oidc")
|
||||
oidcGroup.POST("/authorize-complete", controller.authorizeComplete)
|
||||
oidcGroup.GET("/skip-consent", controller.skipConsent)
|
||||
oidcGroup.POST("/token", controller.Token)
|
||||
oidcGroup.GET("/userinfo", controller.Userinfo)
|
||||
oidcGroup.POST("/userinfo", controller.Userinfo)
|
||||
@@ -242,16 +247,6 @@ func (controller *OIDCController) authorize(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
if userContext != nil && userContext.Authenticated && values.OIDCPrompt != service.OIDCPromptLogin {
|
||||
consent, err := controller.oidc.GetOIDCConsent(c, userContext.GetUsername(), req.ClientID)
|
||||
|
||||
if err != nil {
|
||||
controller.log.App.Warn().Err(err).Msg("Failed to get OIDC consent")
|
||||
} else if consent != nil && scopesGranted(consent.Scope, req.Scope) {
|
||||
values.OIDCPrompt = service.OIDCPromptNone
|
||||
}
|
||||
}
|
||||
|
||||
queries, err := query.Values(values)
|
||||
|
||||
if err != nil {
|
||||
@@ -270,6 +265,90 @@ func (controller *OIDCController) authorize(c *gin.Context) {
|
||||
c.Redirect(http.StatusFound, redirectUrl)
|
||||
}
|
||||
|
||||
func (controller *OIDCController) skipConsent(c *gin.Context) {
|
||||
c.Header("cache-control", "no-store")
|
||||
c.Header("pragma", "no-cache")
|
||||
|
||||
if controller.oidc == nil {
|
||||
c.JSON(500, SimpleResponse{
|
||||
Status: 500,
|
||||
Message: "OIDC not configured",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
userContext, err := new(model.UserContext).NewFromGin(c)
|
||||
|
||||
if err != nil {
|
||||
if !errors.Is(err, model.ErrUserContextNotFound) {
|
||||
controller.log.App.Warn().Err(err).Msg("Failed to get user context")
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil || !userContext.Authenticated {
|
||||
c.JSON(401, SimpleResponse{
|
||||
Status: 401,
|
||||
Message: "User not logged in",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var req SkipConsentRequest
|
||||
|
||||
err = c.BindQuery(&req)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(400, SimpleResponse{
|
||||
Status: 400,
|
||||
Message: "Bad request",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
controller.log.App.Debug().Interface("req", req).Msg("Received skip consent request")
|
||||
|
||||
authorizeReq, ok := controller.oidc.GetAuthorizeRequestByTicket(req.OIDCTicket)
|
||||
|
||||
if !ok {
|
||||
c.JSON(200, SkipConsentResponse{
|
||||
SkipConsent: false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
controller.log.App.Debug().Str("client", authorizeReq.ClientID).Str("user", userContext.GetUsername()).Msg("User consented to OIDC")
|
||||
|
||||
if authorizeReq.Prompt == service.OIDCPromptLogin.String() {
|
||||
c.JSON(200, SkipConsentResponse{
|
||||
SkipConsent: false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
consent, err := controller.oidc.GetOIDCConsent(c, userContext.GetUsername(), authorizeReq.ClientID)
|
||||
|
||||
if err != nil || consent == nil {
|
||||
if err != nil {
|
||||
controller.log.App.Warn().Err(err).Msg("Failed to get OIDC consent")
|
||||
}
|
||||
c.JSON(200, SkipConsentResponse{
|
||||
SkipConsent: false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if !scopesGranted(consent.Scope, authorizeReq.Scope) {
|
||||
c.JSON(200, SkipConsentResponse{
|
||||
SkipConsent: false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, SkipConsentResponse{
|
||||
SkipConsent: true,
|
||||
})
|
||||
}
|
||||
|
||||
// The actual **internal** endpoint that actually creates the code and session.
|
||||
// It is called by the frontend after the user has logged in and given consent.
|
||||
func (controller *OIDCController) authorizeComplete(c *gin.Context) {
|
||||
@@ -330,6 +409,9 @@ func (controller *OIDCController) authorizeComplete(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// We no longer need the ticket
|
||||
controller.oidc.DeleteAuthorizeRequestTicket(req.Ticket)
|
||||
|
||||
// Get the client
|
||||
client, ok := controller.oidc.GetClient(authorizeReq.ClientID)
|
||||
|
||||
@@ -343,9 +425,6 @@ func (controller *OIDCController) authorizeComplete(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// We no longer need the ticket
|
||||
controller.oidc.DeleteAuthorizeRequestTicket(req.Ticket)
|
||||
|
||||
// Create the sub to find and delete old sessions
|
||||
sub := controller.oidc.CreateSub(*userContext, authorizeReq.ClientID)
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ func TestOIDCController(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Authorize skips the consent screen when all requested scopes were already granted",
|
||||
description: "Authorize does not skip the consent screen even when consent was already granted",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
@@ -189,77 +189,9 @@ func TestOIDCController(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/authorize?"+q.Encode(), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusFound, recorder.Code)
|
||||
location := recorder.Header().Get("Location")
|
||||
assert.True(t, strings.HasPrefix(location, oidcService.GetIssuer()+"/oidc/authorize?"))
|
||||
assert.Contains(t, location, "oidc_prompt=none")
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Authorize shows the consent screen when a new scope is requested",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
Username: "testuser", ClientID: "some-client-id",
|
||||
Scope: "openid", CreatedAt: time.Now().Unix(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
q := url.Values{}
|
||||
q.Set("scope", "openid profile")
|
||||
q.Set("response_type", "code")
|
||||
q.Set("client_id", "some-client-id")
|
||||
q.Set("redirect_uri", "https://test.example.com/callback")
|
||||
|
||||
req := httptest.NewRequest("GET", "/authorize?"+q.Encode(), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusFound, recorder.Code)
|
||||
location := recorder.Header().Get("Location")
|
||||
assert.True(t, strings.HasPrefix(location, oidcService.GetIssuer()+"/oidc/authorize?"))
|
||||
assert.NotContains(t, location, "oidc_prompt=none")
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Authorize skips the consent screen for a subset of already granted scopes",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
Username: "testuser", ClientID: "some-client-id",
|
||||
Scope: "openid profile email", CreatedAt: time.Now().Unix(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
q := url.Values{}
|
||||
q.Set("scope", "openid profile")
|
||||
q.Set("response_type", "code")
|
||||
q.Set("client_id", "some-client-id")
|
||||
q.Set("redirect_uri", "https://test.example.com/callback")
|
||||
|
||||
req := httptest.NewRequest("GET", "/authorize?"+q.Encode(), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusFound, recorder.Code)
|
||||
location := recorder.Header().Get("Location")
|
||||
assert.True(t, strings.HasPrefix(location, oidcService.GetIssuer()+"/oidc/authorize?"))
|
||||
assert.Contains(t, location, "oidc_prompt=none")
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Authorize shows the consent screen when no consent was granted yet",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
require.NoError(t, store.DeleteOIDCConsentByClientID(ctx, "some-client-id"))
|
||||
|
||||
q := url.Values{}
|
||||
q.Set("scope", "openid profile")
|
||||
q.Set("response_type", "code")
|
||||
q.Set("client_id", "some-client-id")
|
||||
q.Set("redirect_uri", "https://test.example.com/callback")
|
||||
|
||||
req := httptest.NewRequest("GET", "/authorize?"+q.Encode(), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
// The consent skip check now happens after auth via the
|
||||
// skip-consent endpoint, so authorize should never set
|
||||
// prompt=none on its own.
|
||||
assert.Equal(t, http.StatusFound, recorder.Code)
|
||||
location := recorder.Header().Get("Location")
|
||||
assert.True(t, strings.HasPrefix(location, oidcService.GetIssuer()+"/oidc/authorize?"))
|
||||
@@ -304,6 +236,232 @@ func TestOIDCController(t *testing.T) {
|
||||
},
|
||||
},
|
||||
|
||||
// --- skip-consent ---
|
||||
{
|
||||
description: "Skip consent returns 500 when OIDC is not configured",
|
||||
oidcDisabled: true,
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket=some-ticket", nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, recorder.Code)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns 401 when the user context is missing",
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket=some-ticket", nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusUnauthorized, recorder.Code)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns 401 when the user is not authenticated",
|
||||
middlewares: []gin.HandlerFunc{
|
||||
func(c *gin.Context) {
|
||||
c.Set("context", &model.UserContext{
|
||||
Authenticated: false,
|
||||
Provider: model.ProviderLocal,
|
||||
Local: &model.LocalContext{
|
||||
BaseContext: model.BaseContext{Username: "testuser"},
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket=some-ticket", nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusUnauthorized, recorder.Code)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns 400 when the ticket is missing",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent", nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, recorder.Code)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns false when the ticket is unknown",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket=nonexistent-ticket", nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res SkipConsentResponse
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
assert.False(t, res.SkipConsent)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns true when the authorize request has prompt none",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
Username: "testuser", ClientID: "some-client-id",
|
||||
Scope: "openid profile", CreatedAt: time.Now().Unix(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid profile",
|
||||
ResponseType: "code",
|
||||
ClientID: "some-client-id",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
Prompt: "none",
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket="+url.QueryEscape(ticket), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res SkipConsentResponse
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
assert.True(t, res.SkipConsent)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns false when no consent was granted yet",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
require.NoError(t, store.DeleteOIDCConsentByClientID(ctx, "some-client-id"))
|
||||
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid profile",
|
||||
ResponseType: "code",
|
||||
ClientID: "some-client-id",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket="+url.QueryEscape(ticket), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res SkipConsentResponse
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
assert.False(t, res.SkipConsent)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns false when a new scope is requested",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
Username: "testuser", ClientID: "some-client-id",
|
||||
Scope: "openid", CreatedAt: time.Now().Unix(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid profile",
|
||||
ResponseType: "code",
|
||||
ClientID: "some-client-id",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket="+url.QueryEscape(ticket), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res SkipConsentResponse
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
assert.False(t, res.SkipConsent)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns true when all requested scopes were already granted",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
Username: "testuser", ClientID: "some-client-id",
|
||||
Scope: "openid profile", CreatedAt: time.Now().Unix(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid profile",
|
||||
ResponseType: "code",
|
||||
ClientID: "some-client-id",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket="+url.QueryEscape(ticket), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res SkipConsentResponse
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
assert.True(t, res.SkipConsent)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns true for a subset of already granted scopes",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
Username: "testuser", ClientID: "some-client-id",
|
||||
Scope: "openid profile email", CreatedAt: time.Now().Unix(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid profile",
|
||||
ResponseType: "code",
|
||||
ClientID: "some-client-id",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket="+url.QueryEscape(ticket), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res SkipConsentResponse
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
assert.True(t, res.SkipConsent)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Skip consent returns false when the consent belongs to another user",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
require.NoError(t, store.DeleteOIDCConsentByClientID(ctx, "some-client-id"))
|
||||
|
||||
_, err := store.UpsertOIDCConsent(ctx, repository.UpsertOIDCConsentParams{
|
||||
Username: "otheruser", ClientID: "some-client-id",
|
||||
Scope: "openid profile", CreatedAt: time.Now().Unix(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid profile",
|
||||
ResponseType: "code",
|
||||
ClientID: "some-client-id",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/oidc/skip-consent?oidc_ticket="+url.QueryEscape(ticket), nil)
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res SkipConsentResponse
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
assert.False(t, res.SkipConsent)
|
||||
},
|
||||
},
|
||||
|
||||
// --- authorize-complete ---
|
||||
{
|
||||
description: "Should fail if oidc is disabled",
|
||||
@@ -423,6 +581,60 @@ func TestOIDCController(t *testing.T) {
|
||||
assert.Contains(t, redirectURI, "state=state-123")
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Authorize complete deletes the ticket on success",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid",
|
||||
ResponseType: "code",
|
||||
ClientID: "some-client-id",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
})
|
||||
|
||||
body, err := json.Marshal(AuthorizeCompleteRequest{Ticket: ticket})
|
||||
require.NoError(t, err)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/oidc/authorize-complete", strings.NewReader(string(body)))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
_, ok := oidcService.GetAuthorizeRequestByTicket(ticket)
|
||||
assert.False(t, ok)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Authorize complete deletes the ticket even when the client is unknown",
|
||||
middlewares: []gin.HandlerFunc{authedUser},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
ticket := oidcService.CreateAuthorizeRequestTicket(service.AuthorizeRequest{
|
||||
Scope: "openid",
|
||||
ResponseType: "code",
|
||||
ClientID: "unknown-client",
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
})
|
||||
|
||||
body, err := json.Marshal(AuthorizeCompleteRequest{Ticket: ticket})
|
||||
require.NoError(t, err)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/oidc/authorize-complete", strings.NewReader(string(body)))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, recorder.Code)
|
||||
|
||||
var res map[string]any
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &res))
|
||||
redirectURI, ok := res["redirect_uri"].(string)
|
||||
require.True(t, ok)
|
||||
assert.Contains(t, redirectURI, oidcService.GetIssuer()+"/error")
|
||||
|
||||
_, ok = oidcService.GetAuthorizeRequestByTicket(ticket)
|
||||
assert.False(t, ok)
|
||||
},
|
||||
},
|
||||
|
||||
// --- token ---
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user