Skip to content

Commit

Permalink
Fix grant_type=refresh_token does not record access events
Browse files Browse the repository at this point in the history
ref DEV-1364
  • Loading branch information
louischan-oursky committed Jul 2, 2024
2 parents 66aaefd + b309c1a commit ad738f6
Show file tree
Hide file tree
Showing 8 changed files with 822 additions and 22 deletions.
42 changes: 30 additions & 12 deletions pkg/auth/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions pkg/lib/deps/deps_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import (
"github.com/authgear/authgear-server/pkg/lib/messaging"
"github.com/authgear/authgear-server/pkg/lib/meter"
"github.com/authgear/authgear-server/pkg/lib/oauth"
"github.com/authgear/authgear-server/pkg/lib/oauth/handler"
oauthhandler "github.com/authgear/authgear-server/pkg/lib/oauth/handler"
"github.com/authgear/authgear-server/pkg/lib/oauth/oauthsession"
"github.com/authgear/authgear-server/pkg/lib/oauth/oidc"
Expand Down Expand Up @@ -324,13 +325,18 @@ var CommonDependencySet = wire.NewSet(
wire.Bind(new(oauth.AppSessionTokenStore), new(*oauthredis.Store)),
wire.Bind(new(oauth.AppSessionStore), new(*oauthredis.Store)),
wire.Bind(new(oauth.SettingsActionGrantStore), new(*oauthredis.Store)),
wire.Bind(new(handler.TokenHandlerCodeGrantStore), new(*oauthredis.Store)),
wire.Bind(new(handler.TokenHandlerSettingsActionGrantStore), new(*oauthredis.Store)),
wire.Bind(new(handler.TokenHandlerOfflineGrantStore), new(*oauthredis.Store)),
wire.Bind(new(handler.TokenHandlerAppSessionTokenStore), new(*oauthredis.Store)),

oauth.DependencySet,
wire.Bind(new(session.AccessTokenSessionResolver), new(*oauth.Resolver)),
wire.Bind(new(session.AccessTokenSessionManager), new(*oauth.SessionManager)),
wire.Bind(new(facade.OAuthSessionManager), new(*oauth.SessionManager)),
wire.Bind(new(oauthhandler.AppSessionTokenService), new(*oauth.AppSessionTokenService)),
wire.Bind(new(sessionlisting.OfflineGrantService), new(*oauth.OfflineGrantService)),
wire.Bind(new(handler.TokenHandlerOfflineGrantService), new(*oauth.OfflineGrantService)),
wire.Value(oauthhandler.TokenGenerator(oauth.GenerateToken)),
wire.Bind(new(oauthhandler.AuthorizationService), new(*oauth.AuthorizationService)),
wire.Bind(new(interaction.OfflineGrantStore), new(*oauthredis.Store)),
Expand Down
1 change: 1 addition & 0 deletions pkg/lib/oauth/handler/deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ var DependencySet = wire.NewSet(
wire.Struct(new(CodeGrantService), "*"),
wire.Struct(new(SettingsActionGrantService), "*"),
wire.Struct(new(ProxyRedirectHandler), "*"),
wire.Bind(new(TokenHandlerTokenService), new(*TokenService)),
)
74 changes: 66 additions & 8 deletions pkg/lib/oauth/handler/handler_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"net/http"
"strings"
"time"

"github.com/lestrrat-go/jwx/v2/jwk"

Expand All @@ -30,6 +31,7 @@ import (
"github.com/authgear/authgear-server/pkg/lib/oauth/oidc"
"github.com/authgear/authgear-server/pkg/lib/oauth/protocol"
"github.com/authgear/authgear-server/pkg/lib/session"
"github.com/authgear/authgear-server/pkg/lib/session/access"
"github.com/authgear/authgear-server/pkg/lib/uiparam"
"github.com/authgear/authgear-server/pkg/util/clock"
"github.com/authgear/authgear-server/pkg/util/duration"
Expand All @@ -41,6 +43,8 @@ import (
"github.com/authgear/authgear-server/pkg/util/slice"
)

//go:generate mockgen -source=handler_token.go -destination=handler_token_mock_test.go -package handler_test

const (
AnonymousRequestGrantType = "urn:authgear:params:oauth:grant-type:anonymous-request"
BiometricRequestGrantType = "urn:authgear:params:oauth:grant-type:biometric-request"
Expand Down Expand Up @@ -93,6 +97,54 @@ func NewTokenHandlerLogger(lf *log.Factory) TokenHandlerLogger {
return TokenHandlerLogger{lf.New("oauth-token")}
}

type TokenHandlerCodeGrantStore interface {
GetCodeGrant(codeHash string) (*oauth.CodeGrant, error)
DeleteCodeGrant(*oauth.CodeGrant) error
}

type TokenHandlerSettingsActionGrantStore interface {
GetSettingsActionGrant(codeHash string) (*oauth.SettingsActionGrant, error)
DeleteSettingsActionGrant(*oauth.SettingsActionGrant) error
}

type TokenHandlerOfflineGrantStore interface {
GetOfflineGrant(id string) (*oauth.OfflineGrant, error)
DeleteOfflineGrant(*oauth.OfflineGrant) error

AccessOfflineGrantAndUpdateDeviceInfo(id string, accessEvent access.Event, deviceInfo map[string]interface{}, expireAt time.Time) (*oauth.OfflineGrant, error)
UpdateOfflineGrantAuthenticatedAt(id string, authenticatedAt time.Time, expireAt time.Time) (*oauth.OfflineGrant, error)
UpdateOfflineGrantApp2AppDeviceKey(id string, newKey string, expireAt time.Time) (*oauth.OfflineGrant, error)

ListOfflineGrants(userID string) ([]*oauth.OfflineGrant, error)
ListClientOfflineGrants(clientID string, userID string) ([]*oauth.OfflineGrant, error)
}

type TokenHandlerAppSessionTokenStore interface {
CreateAppSessionToken(*oauth.AppSessionToken) error
}

type TokenHandlerOfflineGrantService interface {
ComputeOfflineGrantExpiry(session *oauth.OfflineGrant) (expiry time.Time, err error)
}

type TokenHandlerTokenService interface {
ParseRefreshToken(token string) (*oauth.Authorization, *oauth.OfflineGrant, error)
IssueAccessGrant(
client *config.OAuthClientConfig,
scopes []string,
authzID string,
userID string,
sessionID string,
sessionKind oauth.GrantSessionKind,
resp protocol.TokenResponse,
) error
IssueOfflineGrant(
client *config.OAuthClientConfig,
opts IssueOfflineGrantOptions,
resp protocol.TokenResponse,
) (*oauth.OfflineGrant, error)
}

type TokenHandler struct {
Context context.Context
AppID config.AppID
Expand All @@ -106,25 +158,27 @@ type TokenHandler struct {
Logger TokenHandlerLogger

Authorizations AuthorizationService
CodeGrants oauth.CodeGrantStore
SettingsActionGrantStore oauth.SettingsActionGrantStore
OfflineGrants oauth.OfflineGrantStore
AppSessionTokens oauth.AppSessionTokenStore
OfflineGrantService oauth.OfflineGrantService
CodeGrants TokenHandlerCodeGrantStore
SettingsActionGrantStore TokenHandlerSettingsActionGrantStore
OfflineGrants TokenHandlerOfflineGrantStore
AppSessionTokens TokenHandlerAppSessionTokenStore
OfflineGrantService TokenHandlerOfflineGrantService
Graphs GraphService
IDTokenIssuer IDTokenIssuer
Clock clock.Clock
TokenService TokenService
TokenService TokenHandlerTokenService
Events EventService
SessionManager SessionManager
App2App App2AppService
Challenges ChallengeProvider
CodeGrantService CodeGrantService
ClientResolver OAuthClientResolver
UIInfoResolver UIInfoResolver

RemoteIP httputil.RemoteIP
UserAgentString httputil.UserAgentString
}

// TODO: Write some tests
func (h *TokenHandler) Handle(rw http.ResponseWriter, req *http.Request, r protocol.TokenRequest) httputil.Result {
client := resolveClient(h.ClientResolver, r)
if client == nil {
Expand Down Expand Up @@ -438,6 +492,9 @@ func (h *TokenHandler) handleRefreshToken(
return nil, err
}

accessEvent := access.NewEvent(h.Clock.NowUTC(), h.RemoteIP, h.UserAgentString)
offlineGrant.AccessInfo.LastAccess = accessEvent

resp, err := h.issueTokensForRefreshToken(client, offlineGrant, authz)
if err != nil {
return nil, err
Expand All @@ -451,7 +508,8 @@ func (h *TokenHandler) handleRefreshToken(
if err != nil {
return nil, err
}
_, err = h.OfflineGrants.UpdateOfflineGrantDeviceInfo(offlineGrant.ID, deviceInfo, expiry)

_, err = h.OfflineGrants.AccessOfflineGrantAndUpdateDeviceInfo(offlineGrant.ID, accessEvent, deviceInfo, expiry)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit ad738f6

Please sign in to comment.