mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-08 07:05:12 +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:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user