mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
fix: set refresh token in the RetrieveIdentityIntentResponse (#11613)
# Which Problems Are Solved This PR adds support for storing and retrieving refresh tokens from external identity providers during the IDP intent flow. # How the Problems Are Solved * Updated `idp.proto` (v2 and v2beta): added an optional `refresh_token` field to `IDPOAuthAccessInformation`, which, in turn, is used in `RetrieveIdentityProviderIntentResponse` * Added the `IDPRefreshToken` field to the IDP intent `SucceededEvent` struct, and updated the corresponding constructor to set the refresh token * Added the `IDPRefreshToken` field to `IDPIntentWriteModel`, and updated `reduceOAuthSucceededEvent` to populate refresh token from events * Updated `tokensForSucceededIDPIntent` function to extract and encrypt the refresh token from IDP session, if set * Updated `idpOAuthTokensToPb` function to decrypt refresh token before returning to clients * Updated unit and integration tests # Additional Changes Updated the link to the JWT IDP docs linked in the Console # Additional Context - Closes https://github.com/zitadel/zitadel/issues/11047
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
[configureProvider]="(justCreated$ | async) === ''"
|
||||
[configureTitle]="'DESCRIPTIONS.SETTINGS.IDPS.JWT.TITLE' | translate"
|
||||
[configureDescription]="'DESCRIPTIONS.SETTINGS.IDPS.JWT.DESCRIPTION' | translate"
|
||||
configureLink="https://zitadel.com/docs/guides/integrate/identity-providers/jwt-idp"
|
||||
configureLink="https://zitadel.com/docs/guides/integrate/identity-providers/jwt_idp"
|
||||
[autofillLink]="autofillLink$ | async"
|
||||
[activateLink]="activateLink$ | async"
|
||||
[expanded]="!!(expandWhatNow$ | async)"
|
||||
|
||||
@@ -425,8 +425,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oauthIdpID,
|
||||
@@ -476,8 +477,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oauthIdpID,
|
||||
@@ -543,8 +545,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: azureIdpID,
|
||||
@@ -601,8 +604,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: azureIdpID,
|
||||
@@ -657,8 +661,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oidcIdpID,
|
||||
@@ -707,8 +712,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oidcIdpID,
|
||||
|
||||
@@ -250,7 +250,7 @@ func idpIntentToIDPIntentPb(intent *command.IDPIntentWriteModel, alg crypto.Encr
|
||||
information.Details = intentToDetailsPb(intent)
|
||||
// OAuth / OIDC
|
||||
if intent.IDPIDToken != "" || intent.IDPAccessToken != nil {
|
||||
information.IdpInformation.Access, err = idpOAuthTokensToPb(intent.IDPIDToken, intent.IDPAccessToken, alg)
|
||||
information.IdpInformation.Access, err = idpOAuthTokensToPb(intent.IDPIDToken, intent.IDPAccessToken, intent.IDPRefreshToken, alg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -274,7 +274,7 @@ func idpIntentToIDPIntentPb(intent *command.IDPIntentWriteModel, alg crypto.Encr
|
||||
return information, nil
|
||||
}
|
||||
|
||||
func idpOAuthTokensToPb(idpIDToken string, idpAccessToken *crypto.CryptoValue, alg crypto.EncryptionAlgorithm) (_ *user.IDPInformation_Oauth, err error) {
|
||||
func idpOAuthTokensToPb(idpIDToken string, idpAccessToken, idpRefreshToken *crypto.CryptoValue, alg crypto.EncryptionAlgorithm) (_ *user.IDPInformation_Oauth, err error) {
|
||||
var idToken *string
|
||||
if idpIDToken != "" {
|
||||
idToken = &idpIDToken
|
||||
@@ -286,10 +286,19 @@ func idpOAuthTokensToPb(idpIDToken string, idpAccessToken *crypto.CryptoValue, a
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var refreshToken *string
|
||||
if idpRefreshToken != nil {
|
||||
decryptedRefreshToken, err := crypto.DecryptString(idpRefreshToken, alg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refreshToken = &decryptedRefreshToken
|
||||
}
|
||||
return &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: accessToken,
|
||||
IdToken: idToken,
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
IdToken: idToken,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -2299,8 +2299,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oauthIdpID,
|
||||
@@ -2339,8 +2340,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oauthIdpID,
|
||||
@@ -2401,8 +2403,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oidcIdpID,
|
||||
@@ -2439,8 +2442,9 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
|
||||
IdpInformation: &user.IDPInformation{
|
||||
Access: &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: "accessToken",
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: gu.Ptr("refreshToken"),
|
||||
IdToken: gu.Ptr("idToken"),
|
||||
},
|
||||
},
|
||||
IdpId: oidcIdpID,
|
||||
|
||||
@@ -522,7 +522,7 @@ func idpIntentToIDPIntentPb(intent *command.IDPIntentWriteModel, alg crypto.Encr
|
||||
UserId: intent.UserID,
|
||||
}
|
||||
if intent.IDPIDToken != "" || intent.IDPAccessToken != nil {
|
||||
information.IdpInformation.Access, err = idpOAuthTokensToPb(intent.IDPIDToken, intent.IDPAccessToken, alg)
|
||||
information.IdpInformation.Access, err = idpOAuthTokensToPb(intent.IDPIDToken, intent.IDPAccessToken, intent.IDPRefreshToken, alg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -547,7 +547,7 @@ func idpIntentToIDPIntentPb(intent *command.IDPIntentWriteModel, alg crypto.Encr
|
||||
return connect.NewResponse(information), nil
|
||||
}
|
||||
|
||||
func idpOAuthTokensToPb(idpIDToken string, idpAccessToken *crypto.CryptoValue, alg crypto.EncryptionAlgorithm) (_ *user.IDPInformation_Oauth, err error) {
|
||||
func idpOAuthTokensToPb(idpIDToken string, idpAccessToken, idpRefreshToken *crypto.CryptoValue, alg crypto.EncryptionAlgorithm) (_ *user.IDPInformation_Oauth, err error) {
|
||||
var idToken *string
|
||||
if idpIDToken != "" {
|
||||
idToken = &idpIDToken
|
||||
@@ -559,10 +559,19 @@ func idpOAuthTokensToPb(idpIDToken string, idpAccessToken *crypto.CryptoValue, a
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var refreshToken *string
|
||||
if idpRefreshToken != nil {
|
||||
decryptedRefreshToken, err := crypto.DecryptString(idpRefreshToken, alg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refreshToken = &decryptedRefreshToken
|
||||
}
|
||||
return &user.IDPInformation_Oauth{
|
||||
Oauth: &user.IDPOAuthAccessInformation{
|
||||
AccessToken: accessToken,
|
||||
IdToken: idToken,
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
IdToken: idToken,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ func (c *Commands) SucceedIDPIntent(ctx context.Context, writeModel *IDPIntentWr
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
accessToken, idToken, err := tokensForSucceededIDPIntent(idpSession, c.idpConfigEncryption)
|
||||
accessToken, refreshToken, idToken, err := tokensForSucceededIDPIntent(idpSession, c.idpConfigEncryption)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -186,6 +186,7 @@ func (c *Commands) SucceedIDPIntent(ctx context.Context, writeModel *IDPIntentWr
|
||||
idpUser.GetPreferredUsername(),
|
||||
userID,
|
||||
accessToken,
|
||||
refreshToken,
|
||||
idToken,
|
||||
idpSession.ExpiresAt(),
|
||||
)
|
||||
@@ -295,8 +296,9 @@ func (c *Commands) GetIntentWriteModel(ctx context.Context, id, resourceOwner st
|
||||
return writeModel, err
|
||||
}
|
||||
|
||||
// tokensForSucceededIDPIntent extracts the oidc.Tokens if available (and encrypts the access_token) for the succeeded event payload
|
||||
func tokensForSucceededIDPIntent(session idp.Session, encryptionAlg crypto.EncryptionAlgorithm) (*crypto.CryptoValue, string, error) {
|
||||
// tokensForSucceededIDPIntent extracts the oidc.Tokens if available for the succeeded event payload.
|
||||
// It also encrypts the access token and refresh token (if set).
|
||||
func tokensForSucceededIDPIntent(session idp.Session, encryptionAlg crypto.EncryptionAlgorithm) (*crypto.CryptoValue, *crypto.CryptoValue, string, error) {
|
||||
var tokens *oidc.Tokens[*oidc.IDTokenClaims]
|
||||
switch s := session.(type) {
|
||||
case *oauth.Session:
|
||||
@@ -312,11 +314,25 @@ func tokensForSucceededIDPIntent(session idp.Session, encryptionAlg crypto.Encry
|
||||
case *apple.Session:
|
||||
tokens = s.Tokens
|
||||
default:
|
||||
return nil, "", nil
|
||||
return nil, nil, "", nil
|
||||
}
|
||||
if tokens == nil {
|
||||
return nil, nil, "", nil
|
||||
}
|
||||
if tokens.Token == nil || tokens.AccessToken == "" {
|
||||
return nil, tokens.IDToken, nil
|
||||
return nil, nil, tokens.IDToken, nil
|
||||
}
|
||||
accessToken, err := crypto.Encrypt([]byte(tokens.AccessToken), encryptionAlg)
|
||||
return accessToken, tokens.IDToken, err
|
||||
if err != nil {
|
||||
return nil, nil, tokens.IDToken, err
|
||||
}
|
||||
var refreshToken *crypto.CryptoValue
|
||||
if tokens.RefreshToken != "" {
|
||||
refreshToken, err = crypto.Encrypt([]byte(tokens.RefreshToken), encryptionAlg)
|
||||
if err != nil {
|
||||
return nil, nil, tokens.IDToken, err
|
||||
}
|
||||
}
|
||||
|
||||
return accessToken, refreshToken, tokens.IDToken, nil
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@ type IDPIntentWriteModel struct {
|
||||
UserID string
|
||||
LoginHint string
|
||||
|
||||
IDPAccessToken *crypto.CryptoValue
|
||||
IDPIDToken string
|
||||
IDPAccessToken *crypto.CryptoValue
|
||||
IDPRefreshToken *crypto.CryptoValue
|
||||
IDPIDToken string
|
||||
|
||||
IDPEntryAttributes map[string][]string
|
||||
|
||||
@@ -131,6 +132,7 @@ func (wm *IDPIntentWriteModel) reduceOAuthSucceededEvent(e *idpintent.SucceededE
|
||||
wm.IDPUserID = e.IDPUserID
|
||||
wm.IDPUserName = e.IDPUserName
|
||||
wm.IDPAccessToken = e.IDPAccessToken
|
||||
wm.IDPRefreshToken = e.IDPRefreshToken
|
||||
wm.IDPIDToken = e.IDPIDToken
|
||||
wm.State = domain.IDPIntentStateSucceeded
|
||||
wm.succeededAt = e.CreationDate()
|
||||
|
||||
@@ -1105,6 +1105,12 @@ func TestCommands_SucceedIDPIntent(t *testing.T) {
|
||||
KeyID: "id",
|
||||
Crypted: []byte("accessToken"),
|
||||
},
|
||||
&crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("refreshToken"),
|
||||
},
|
||||
"idToken",
|
||||
time.Time{},
|
||||
)
|
||||
@@ -1119,7 +1125,8 @@ func TestCommands_SucceedIDPIntent(t *testing.T) {
|
||||
idpSession: &openid.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "accessToken",
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: "refreshToken",
|
||||
},
|
||||
IDToken: "idToken",
|
||||
},
|
||||
@@ -1501,9 +1508,10 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
encryptionAlg crypto.EncryptionAlgorithm
|
||||
}
|
||||
type res struct {
|
||||
accessToken *crypto.CryptoValue
|
||||
idToken string
|
||||
err error
|
||||
accessToken *crypto.CryptoValue
|
||||
refreshToken *crypto.CryptoValue
|
||||
idToken string
|
||||
err error
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -1517,9 +1525,10 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
},
|
||||
res{
|
||||
accessToken: nil,
|
||||
idToken: "",
|
||||
err: nil,
|
||||
accessToken: nil,
|
||||
refreshToken: nil,
|
||||
idToken: "",
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1539,13 +1548,44 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
}(),
|
||||
},
|
||||
res{
|
||||
accessToken: nil,
|
||||
idToken: "",
|
||||
err: zerrors.ThrowInternal(nil, "id", "encryption failed"),
|
||||
accessToken: nil,
|
||||
refreshToken: nil,
|
||||
idToken: "",
|
||||
err: zerrors.ThrowInternal(nil, "id", "encryption failed"),
|
||||
},
|
||||
},
|
||||
{
|
||||
"oauth tokens",
|
||||
args{
|
||||
&oauth.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: "refreshToken",
|
||||
},
|
||||
},
|
||||
},
|
||||
crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
},
|
||||
res{
|
||||
accessToken: &crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("accessToken"),
|
||||
},
|
||||
refreshToken: &crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("refreshToken"),
|
||||
},
|
||||
idToken: "",
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
"oauth tokens - no refresh token",
|
||||
args{
|
||||
&oauth.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
@@ -1563,8 +1603,9 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
KeyID: "id",
|
||||
Crypted: []byte("accessToken"),
|
||||
},
|
||||
idToken: "",
|
||||
err: nil,
|
||||
refreshToken: nil,
|
||||
idToken: "",
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1573,7 +1614,8 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
&openid.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "accessToken",
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: "refreshToken",
|
||||
},
|
||||
IDToken: "idToken",
|
||||
},
|
||||
@@ -1587,6 +1629,12 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
KeyID: "id",
|
||||
Crypted: []byte("accessToken"),
|
||||
},
|
||||
refreshToken: &crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("refreshToken"),
|
||||
},
|
||||
idToken: "idToken",
|
||||
err: nil,
|
||||
},
|
||||
@@ -1602,9 +1650,10 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
},
|
||||
res{
|
||||
accessToken: nil,
|
||||
idToken: "idToken",
|
||||
err: nil,
|
||||
accessToken: nil,
|
||||
refreshToken: nil,
|
||||
idToken: "idToken",
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1628,8 +1677,9 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
KeyID: "id",
|
||||
Crypted: []byte("accessToken"),
|
||||
},
|
||||
idToken: "",
|
||||
err: nil,
|
||||
refreshToken: nil,
|
||||
idToken: "",
|
||||
err: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1639,7 +1689,8 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
OAuthSession: &oauth.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "accessToken",
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: "refreshToken",
|
||||
},
|
||||
IDToken: "idToken",
|
||||
},
|
||||
@@ -1654,6 +1705,12 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
KeyID: "id",
|
||||
Crypted: []byte("accessToken"),
|
||||
},
|
||||
refreshToken: &crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("refreshToken"),
|
||||
},
|
||||
idToken: "idToken",
|
||||
err: nil,
|
||||
},
|
||||
@@ -1661,9 +1718,10 @@ func Test_tokensForSucceededIDPIntent(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotAccessToken, gotIDToken, err := tokensForSucceededIDPIntent(tt.args.session, tt.args.encryptionAlg)
|
||||
gotAccessToken, refreshToken, gotIDToken, err := tokensForSucceededIDPIntent(tt.args.session, tt.args.encryptionAlg)
|
||||
require.ErrorIs(t, err, tt.res.err)
|
||||
assert.Equal(t, tt.res.accessToken, gotAccessToken)
|
||||
assert.Equal(t, tt.res.refreshToken, refreshToken)
|
||||
assert.Equal(t, tt.res.idToken, gotIDToken)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -742,6 +742,7 @@ func TestCommands_updateSession(t *testing.T) {
|
||||
"idpUserName",
|
||||
"userID2",
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
time.Now().Add(time.Hour),
|
||||
),
|
||||
@@ -823,6 +824,7 @@ func TestCommands_updateSession(t *testing.T) {
|
||||
"idpUsername",
|
||||
"userID",
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
time.Now().Add(time.Hour),
|
||||
),
|
||||
@@ -878,6 +880,7 @@ func TestCommands_updateSession(t *testing.T) {
|
||||
"idpUsername",
|
||||
"userID",
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
time.Now().Add(-time.Hour),
|
||||
),
|
||||
@@ -928,6 +931,7 @@ func TestCommands_updateSession(t *testing.T) {
|
||||
"idpUsername",
|
||||
"userID",
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
time.Now().Add(time.Hour),
|
||||
),
|
||||
@@ -1005,6 +1009,7 @@ func TestCommands_updateSession(t *testing.T) {
|
||||
"idpUsername",
|
||||
"",
|
||||
nil,
|
||||
nil,
|
||||
"",
|
||||
time.Now().Add(time.Hour),
|
||||
),
|
||||
|
||||
@@ -438,8 +438,9 @@ func createSuccessfulOAuthIntent(ctx context.Context, cmd *command.Commands, req
|
||||
idpSession := &oauth.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "accessToken",
|
||||
Expiry: req.Expiry,
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: "refreshToken",
|
||||
Expiry: req.Expiry,
|
||||
},
|
||||
IDToken: "idToken",
|
||||
},
|
||||
@@ -476,8 +477,9 @@ func createSuccessfulAzureADIntent(ctx context.Context, cmd *command.Commands, r
|
||||
idpSession := &oauth.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "accessToken",
|
||||
Expiry: req.Expiry,
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: "refreshToken",
|
||||
Expiry: req.Expiry,
|
||||
},
|
||||
IDToken: "idToken",
|
||||
},
|
||||
@@ -508,8 +510,9 @@ func createSuccessfulOIDCIntent(ctx context.Context, cmd *command.Commands, req
|
||||
idpSession := &openid.Session{
|
||||
Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
|
||||
Token: &oauth2.Token{
|
||||
AccessToken: "accessToken",
|
||||
Expiry: req.Expiry,
|
||||
AccessToken: "accessToken",
|
||||
RefreshToken: "refreshToken",
|
||||
Expiry: req.Expiry,
|
||||
},
|
||||
IDToken: "idToken",
|
||||
},
|
||||
|
||||
@@ -82,9 +82,10 @@ type SucceededEvent struct {
|
||||
IDPUserName string `json:"idpUserName,omitempty"`
|
||||
UserID string `json:"userId,omitempty"`
|
||||
|
||||
IDPAccessToken *crypto.CryptoValue `json:"idpAccessToken,omitempty"`
|
||||
IDPIDToken string `json:"idpIdToken,omitempty"`
|
||||
ExpiresAt time.Time `json:"expiresAt,omitempty"`
|
||||
IDPAccessToken *crypto.CryptoValue `json:"idpAccessToken,omitempty"`
|
||||
IDPRefreshToken *crypto.CryptoValue `json:"idpRefreshToken,omitempty"`
|
||||
IDPIDToken string `json:"idpIdToken,omitempty"`
|
||||
ExpiresAt time.Time `json:"expiresAt,omitempty"`
|
||||
}
|
||||
|
||||
func NewSucceededEvent(
|
||||
@@ -95,6 +96,7 @@ func NewSucceededEvent(
|
||||
idpUserName,
|
||||
userID string,
|
||||
idpAccessToken *crypto.CryptoValue,
|
||||
idpRefreshToken *crypto.CryptoValue,
|
||||
idpIDToken string,
|
||||
expiresAt time.Time,
|
||||
) *SucceededEvent {
|
||||
@@ -104,13 +106,14 @@ func NewSucceededEvent(
|
||||
aggregate,
|
||||
SucceededEventType,
|
||||
),
|
||||
IDPUser: idpUser,
|
||||
IDPUserID: idpUserID,
|
||||
IDPUserName: idpUserName,
|
||||
UserID: userID,
|
||||
IDPAccessToken: idpAccessToken,
|
||||
IDPIDToken: idpIDToken,
|
||||
ExpiresAt: expiresAt,
|
||||
IDPUser: idpUser,
|
||||
IDPUserID: idpUserID,
|
||||
IDPUserName: idpUserName,
|
||||
UserID: userID,
|
||||
IDPAccessToken: idpAccessToken,
|
||||
IDPRefreshToken: idpRefreshToken,
|
||||
IDPIDToken: idpIDToken,
|
||||
ExpiresAt: expiresAt,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -129,8 +129,24 @@ message IDPInformation{
|
||||
}
|
||||
|
||||
message IDPOAuthAccessInformation{
|
||||
string access_token = 1;
|
||||
optional string id_token = 2;
|
||||
// The access token returned by the external identity provider.
|
||||
string access_token = 1[
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Access token returned by the external identity provider"
|
||||
}
|
||||
];
|
||||
// The ID token is only set when it is returned by the external identity provider.
|
||||
optional string id_token = 2[
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "ID token returned by the external identity provider. Only set if the external identity provider returns an ID token."
|
||||
}
|
||||
];
|
||||
// The refresh token is only set when it is returned by the external identity provider.
|
||||
optional string refresh_token = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Refresh token returned by the external identity provider. Only set if the external identity provider returns a refresh token."
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message IDPLDAPAccessInformation{
|
||||
|
||||
@@ -129,8 +129,24 @@ message IDPInformation{
|
||||
}
|
||||
|
||||
message IDPOAuthAccessInformation{
|
||||
string access_token = 1;
|
||||
optional string id_token = 2;
|
||||
// The access token returned by the external identity provider.
|
||||
string access_token = 1[
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Access token returned by the external identity provider"
|
||||
}
|
||||
];
|
||||
// The ID token is only set when it is returned by the external identity provider.
|
||||
optional string id_token = 2[
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "ID token returned by the external identity provider. Only set if the external identity provider returns an ID token."
|
||||
}
|
||||
];
|
||||
// The refresh token is only set when it is returned by the external identity provider.
|
||||
optional string refresh_token = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Refresh token returned by the external identity provider. Only set if the external identity provider returns a refresh token."
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message IDPLDAPAccessInformation{
|
||||
|
||||
Reference in New Issue
Block a user