hydra/oauth2/refresh_hook.go

103 lines
2.9 KiB
Go

// Copyright © 2022 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package oauth2
import (
"context"
"encoding/json"
"github.com/ory/hydra/v2/x"
"github.com/ory/x/errorsx"
"github.com/ory/fosite"
"github.com/ory/hydra/v2/driver/config"
)
// Requester is a token endpoint's request context.
//
// swagger:ignore
type Requester struct {
// ClientID is the identifier of the OAuth 2.0 client.
ClientID string `json:"client_id"`
// GrantedScopes is the list of scopes granted to the OAuth 2.0 client.
GrantedScopes []string `json:"granted_scopes"`
// GrantedAudience is the list of audiences granted to the OAuth 2.0 client.
GrantedAudience []string `json:"granted_audience"`
// GrantTypes is the requests grant types.
GrantTypes []string `json:"grant_types"`
}
// RefreshTokenHookRequest is the request body sent to the refresh token hook.
//
// swagger:ignore
type RefreshTokenHookRequest struct {
// Subject is the identifier of the authenticated end-user.
Subject string `json:"subject"`
// Session is the request's session..
Session *Session `json:"session"`
// Requester is a token endpoint's request context.
Requester Requester `json:"requester"`
// ClientID is the identifier of the OAuth 2.0 client.
ClientID string `json:"client_id"`
// GrantedScopes is the list of scopes granted to the OAuth 2.0 client.
GrantedScopes []string `json:"granted_scopes"`
// GrantedAudience is the list of audiences granted to the OAuth 2.0 client.
GrantedAudience []string `json:"granted_audience"`
}
// RefreshTokenHook is an AccessRequestHook called for `refresh_token` grant type.
func RefreshTokenHook(reg interface {
config.Provider
x.HTTPClientProvider
}) AccessRequestHook {
return func(ctx context.Context, requester fosite.AccessRequester) error {
hookConfig := reg.Config().TokenRefreshHookConfig(ctx)
if hookConfig == nil {
return nil
}
if !requester.GetGrantTypes().ExactOne("refresh_token") {
return nil
}
session, ok := requester.GetSession().(*Session)
if !ok {
return nil
}
requesterInfo := Requester{
ClientID: requester.GetClient().GetID(),
GrantedScopes: requester.GetGrantedScopes(),
GrantedAudience: requester.GetGrantedAudience(),
GrantTypes: requester.GetGrantTypes(),
}
reqBody := RefreshTokenHookRequest{
Session: session,
Requester: requesterInfo,
Subject: session.GetSubject(),
ClientID: requester.GetClient().GetID(),
GrantedScopes: requester.GetGrantedScopes(),
GrantedAudience: requester.GetGrantedAudience(),
}
reqBodyBytes, err := json.Marshal(&reqBody)
if err != nil {
return errorsx.WithStack(
fosite.ErrServerError.
WithWrap(err).
WithDescription("An error occurred while encoding the token hook.").
WithDebugf("Unable to encode the token hook body: %s", err),
)
}
err = executeHookAndUpdateSession(ctx, reg, hookConfig, reqBodyBytes, session)
if err != nil {
return err
}
return nil
}
}