mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-09 15:45:12 +00:00
fix: added login_hint to the idp intent (#11552)
# Which Problems Are Solved In login V2, when the user started the login flow of an external IDP, there was no login_hint passed to the external provider. This required the user to enter their username again. Whilst they already entered it in Zitadel. By adding the `login_hint` parameter, the username should already be filled in on the external idp. # How the Problems Are Solved Pass the `login_hint` parameter to the external idp. # Additional Changes Also added the `login_hint` to the event-store for audit trailing. # Additional Context - Closes #11392 --------- Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -49,6 +49,7 @@ func TestCommands_CreateIntent(t *testing.T) {
|
||||
successURL string
|
||||
failureURL string
|
||||
instanceID string
|
||||
loginHint string
|
||||
idpArguments map[string]any
|
||||
}
|
||||
type res struct {
|
||||
@@ -202,6 +203,7 @@ func TestCommands_CreateIntent(t *testing.T) {
|
||||
success,
|
||||
failure,
|
||||
"idp",
|
||||
"",
|
||||
nil,
|
||||
)
|
||||
}(),
|
||||
@@ -257,6 +259,7 @@ func TestCommands_CreateIntent(t *testing.T) {
|
||||
success,
|
||||
failure,
|
||||
"idp",
|
||||
"",
|
||||
map[string]interface{}{
|
||||
"verifier": "pkceOAuthVerifier",
|
||||
},
|
||||
@@ -317,6 +320,7 @@ func TestCommands_CreateIntent(t *testing.T) {
|
||||
success,
|
||||
failure,
|
||||
"idp",
|
||||
"",
|
||||
map[string]interface{}{
|
||||
"verifier": "pkceOAuthVerifier",
|
||||
},
|
||||
@@ -377,6 +381,7 @@ func TestCommands_CreateIntent(t *testing.T) {
|
||||
success,
|
||||
failure,
|
||||
"idp",
|
||||
"",
|
||||
map[string]interface{}{
|
||||
"verifier": "pkceOAuthVerifier",
|
||||
},
|
||||
@@ -408,7 +413,7 @@ func TestCommands_CreateIntent(t *testing.T) {
|
||||
eventstore: tt.fields.eventstore(t),
|
||||
idGenerator: tt.fields.idGenerator,
|
||||
}
|
||||
intentWriteModel, details, err := c.CreateIntent(tt.args.ctx, tt.args.intentID, tt.args.idpID, tt.args.successURL, tt.args.failureURL, tt.args.instanceID, tt.args.idpArguments)
|
||||
intentWriteModel, details, err := c.CreateIntent(tt.args.ctx, tt.args.intentID, tt.args.idpID, tt.args.successURL, tt.args.failureURL, tt.args.instanceID, tt.args.loginHint, tt.args.idpArguments)
|
||||
require.ErrorIs(t, err, tt.res.err)
|
||||
if intentWriteModel != nil {
|
||||
assert.Equal(t, tt.res.intentID, intentWriteModel.AggregateID)
|
||||
@@ -429,6 +434,7 @@ func TestCommands_AuthFromProvider(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
idpID string
|
||||
loginHint string
|
||||
callbackURL string
|
||||
samlRootURL string
|
||||
}
|
||||
@@ -582,6 +588,68 @@ func TestCommands_AuthFromProvider(t *testing.T) {
|
||||
auth: &idp.RedirectAuth{RedirectURL: "auth?client_id=clientID&prompt=select_account&redirect_uri=url&response_type=code&state=id"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"oauth auth redirect with login_hint",
|
||||
fields{
|
||||
secretCrypto: crypto.CreateMockEncryptionAlg(gomock.NewController(t)),
|
||||
eventstore: expectEventstore(
|
||||
expectFilter(
|
||||
eventFromEventPusherWithInstanceID(
|
||||
"instance",
|
||||
instance.NewOAuthIDPAddedEvent(context.Background(), &instance.NewAggregate("instance").Aggregate,
|
||||
"idp",
|
||||
"name",
|
||||
"clientID",
|
||||
&crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("clientSecret"),
|
||||
},
|
||||
"auth",
|
||||
"token",
|
||||
"user",
|
||||
"idAttribute",
|
||||
nil,
|
||||
true,
|
||||
rep_idp.Options{},
|
||||
)),
|
||||
),
|
||||
expectFilter(
|
||||
eventFromEventPusherWithInstanceID(
|
||||
"instance",
|
||||
instance.NewOAuthIDPAddedEvent(context.Background(), &instance.NewAggregate("instance").Aggregate,
|
||||
"idp",
|
||||
"name",
|
||||
"clientID",
|
||||
&crypto.CryptoValue{
|
||||
CryptoType: crypto.TypeEncryption,
|
||||
Algorithm: "enc",
|
||||
KeyID: "id",
|
||||
Crypted: []byte("clientSecret"),
|
||||
},
|
||||
"auth",
|
||||
"token",
|
||||
"user",
|
||||
"idAttribute",
|
||||
nil,
|
||||
true,
|
||||
rep_idp.Options{},
|
||||
)),
|
||||
),
|
||||
),
|
||||
idGenerator: mock.ExpectID(t, "id"),
|
||||
},
|
||||
args{
|
||||
ctx: authz.SetCtxData(context.Background(), authz.CtxData{OrgID: "ro"}),
|
||||
idpID: "idp",
|
||||
callbackURL: "url",
|
||||
loginHint: "[email protected]",
|
||||
},
|
||||
res{
|
||||
auth: &idp.RedirectAuth{RedirectURL: "auth?client_id=clientID&login_hint=user%40example.com&redirect_uri=url&response_type=code&state=id"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"migrated and push",
|
||||
fields{
|
||||
@@ -681,7 +749,7 @@ func TestCommands_AuthFromProvider(t *testing.T) {
|
||||
idpConfigEncryption: tt.fields.secretCrypto,
|
||||
idGenerator: tt.fields.idGenerator,
|
||||
}
|
||||
_, session, err := c.AuthFromProvider(tt.args.ctx, tt.args.idpID, tt.args.callbackURL, tt.args.samlRootURL)
|
||||
_, session, err := c.AuthFromProvider(tt.args.ctx, tt.args.idpID, tt.args.callbackURL, tt.args.samlRootURL, tt.args.loginHint)
|
||||
require.ErrorIs(t, err, tt.res.err)
|
||||
|
||||
var got idp.Auth
|
||||
@@ -705,6 +773,7 @@ func TestCommands_AuthFromProvider_SAML(t *testing.T) {
|
||||
idpID string
|
||||
callbackURL string
|
||||
samlRootURL string
|
||||
loginHint string
|
||||
}
|
||||
type res struct {
|
||||
url string
|
||||
@@ -779,6 +848,7 @@ func TestCommands_AuthFromProvider_SAML(t *testing.T) {
|
||||
success,
|
||||
failure,
|
||||
"idp",
|
||||
"[email protected]",
|
||||
nil,
|
||||
)
|
||||
}(),
|
||||
@@ -801,6 +871,7 @@ func TestCommands_AuthFromProvider_SAML(t *testing.T) {
|
||||
idpID: "idp",
|
||||
callbackURL: "url",
|
||||
samlRootURL: "samlurl",
|
||||
loginHint: "[email protected]",
|
||||
},
|
||||
res{
|
||||
url: "http://localhost:8000/sso",
|
||||
@@ -872,6 +943,7 @@ func TestCommands_AuthFromProvider_SAML(t *testing.T) {
|
||||
success,
|
||||
failure,
|
||||
"idp",
|
||||
"user123",
|
||||
nil,
|
||||
)
|
||||
}(),
|
||||
@@ -894,6 +966,7 @@ func TestCommands_AuthFromProvider_SAML(t *testing.T) {
|
||||
idpID: "idp",
|
||||
callbackURL: "url",
|
||||
samlRootURL: "samlurl",
|
||||
loginHint: "user123",
|
||||
},
|
||||
res{
|
||||
url: "http://localhost:8000/sso",
|
||||
@@ -911,7 +984,7 @@ func TestCommands_AuthFromProvider_SAML(t *testing.T) {
|
||||
idpConfigEncryption: tt.fields.secretCrypto,
|
||||
idGenerator: tt.fields.idGenerator,
|
||||
}
|
||||
_, session, err := c.AuthFromProvider(tt.args.ctx, tt.args.idpID, tt.args.callbackURL, tt.args.samlRootURL)
|
||||
_, session, err := c.AuthFromProvider(tt.args.ctx, tt.args.idpID, tt.args.callbackURL, tt.args.samlRootURL, tt.args.loginHint)
|
||||
require.ErrorIs(t, err, tt.res.err)
|
||||
|
||||
auth, err := session.GetAuth(tt.args.ctx)
|
||||
|
||||
Reference in New Issue
Block a user