mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:47:32 +00:00
fix: prevent intent token reuse and add expiry
(cherry picked from commit b1e60e7398
)
This commit is contained in:
@@ -354,7 +354,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId())
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId())
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Hour))
|
||||
require.NoError(t, err)
|
||||
updateResp, err := Client.SetSession(LoginCTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
@@ -372,7 +372,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
||||
func TestServer_CreateSession_successfulIntent_instant(t *testing.T) {
|
||||
idpID := Instance.AddGenericOAuthProvider(IAMOwnerCTX, gofakeit.AppName()).GetId()
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId())
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Hour))
|
||||
require.NoError(t, err)
|
||||
createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{
|
||||
Checks: &session.Checks{
|
||||
@@ -396,7 +396,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
|
||||
|
||||
// successful intent without known / linked user
|
||||
idpUserID := "id"
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, idpUserID, "")
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, idpUserID, "", time.Now().Add(time.Hour))
|
||||
|
||||
// link the user (with info from intent)
|
||||
Instance.CreateUserIDPlink(CTX, User.GetUserId(), idpUserID, idpID, User.GetUserId())
|
||||
@@ -447,6 +447,80 @@ func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestServer_CreateSession_reuseIntent(t *testing.T) {
|
||||
idpID := Instance.AddGenericOAuthProvider(IAMOwnerCTX, gofakeit.AppName()).GetId()
|
||||
createResp, err := Client.CreateSession(LoginCTX, &session.CreateSessionRequest{
|
||||
Checks: &session.Checks{
|
||||
User: &session.CheckUser{
|
||||
Search: &session.CheckUser_UserId{
|
||||
UserId: User.GetUserId(),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId())
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Hour))
|
||||
require.NoError(t, err)
|
||||
updateResp, err := Client.SetSession(LoginCTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
Checks: &session.Checks{
|
||||
IdpIntent: &session.CheckIDPIntent{
|
||||
IdpIntentId: intentID,
|
||||
IdpIntentToken: token,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId(), wantUserFactor, wantIntentFactor)
|
||||
|
||||
// the reuse of the intent token is not allowed, not even on the same session
|
||||
session2, err := Client.SetSession(LoginCTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
Checks: &session.Checks{
|
||||
IdpIntent: &session.CheckIDPIntent{
|
||||
IdpIntentId: intentID,
|
||||
IdpIntentToken: token,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
_ = session2
|
||||
}
|
||||
|
||||
func TestServer_CreateSession_expiredIntent(t *testing.T) {
|
||||
idpID := Instance.AddGenericOAuthProvider(IAMOwnerCTX, gofakeit.AppName()).GetId()
|
||||
createResp, err := Client.CreateSession(LoginCTX, &session.CreateSessionRequest{
|
||||
Checks: &session.Checks{
|
||||
User: &session.CheckUser{
|
||||
Search: &session.CheckUser_UserId{
|
||||
UserId: User.GetUserId(),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId())
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Second))
|
||||
require.NoError(t, err)
|
||||
|
||||
// wait for the intent to expire
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
_, err = Client.SetSession(LoginCTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
Checks: &session.Checks{
|
||||
IdpIntent: &session.CheckIDPIntent{
|
||||
IdpIntentId: intentID,
|
||||
IdpIntentToken: token,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func registerTOTP(ctx context.Context, t *testing.T, userID string) (secret string) {
|
||||
resp, err := Instance.Client.UserV2.RegisterTOTP(ctx, &user.RegisterTOTPRequest{
|
||||
UserId: userID,
|
||||
|
@@ -354,7 +354,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId())
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId())
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Hour))
|
||||
require.NoError(t, err)
|
||||
updateResp, err := Client.SetSession(CTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
@@ -372,7 +372,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
||||
func TestServer_CreateSession_successfulIntent_instant(t *testing.T) {
|
||||
idpID := Instance.AddGenericOAuthProvider(IAMOwnerCTX, gofakeit.AppName()).GetId()
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId())
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Hour))
|
||||
require.NoError(t, err)
|
||||
createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{
|
||||
Checks: &session.Checks{
|
||||
@@ -396,7 +396,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
|
||||
|
||||
// successful intent without known / linked user
|
||||
idpUserID := "id"
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId())
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Hour))
|
||||
require.NoError(t, err)
|
||||
|
||||
// link the user (with info from intent)
|
||||
@@ -448,6 +448,80 @@ func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestServer_CreateSession_reuseIntent(t *testing.T) {
|
||||
idpID := Instance.AddGenericOAuthProvider(IAMOwnerCTX, gofakeit.AppName()).GetId()
|
||||
createResp, err := Client.CreateSession(IAMOwnerCTX, &session.CreateSessionRequest{
|
||||
Checks: &session.Checks{
|
||||
User: &session.CheckUser{
|
||||
Search: &session.CheckUser_UserId{
|
||||
UserId: User.GetUserId(),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId())
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Hour))
|
||||
require.NoError(t, err)
|
||||
updateResp, err := Client.SetSession(IAMOwnerCTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
Checks: &session.Checks{
|
||||
IdpIntent: &session.CheckIDPIntent{
|
||||
IdpIntentId: intentID,
|
||||
IdpIntentToken: token,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId(), wantUserFactor, wantIntentFactor)
|
||||
|
||||
// the reuse of the intent token is not allowed, not even on the same session
|
||||
session2, err := Client.SetSession(IAMOwnerCTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
Checks: &session.Checks{
|
||||
IdpIntent: &session.CheckIDPIntent{
|
||||
IdpIntentId: intentID,
|
||||
IdpIntentToken: token,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
_ = session2
|
||||
}
|
||||
|
||||
func TestServer_CreateSession_expiredIntent(t *testing.T) {
|
||||
idpID := Instance.AddGenericOAuthProvider(IAMOwnerCTX, gofakeit.AppName()).GetId()
|
||||
createResp, err := Client.CreateSession(IAMOwnerCTX, &session.CreateSessionRequest{
|
||||
Checks: &session.Checks{
|
||||
User: &session.CheckUser{
|
||||
Search: &session.CheckUser_UserId{
|
||||
UserId: User.GetUserId(),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil, 0, User.GetUserId())
|
||||
|
||||
intentID, token, _, _, err := sink.SuccessfulOAuthIntent(Instance.ID(), idpID, "id", User.GetUserId(), time.Now().Add(time.Second))
|
||||
require.NoError(t, err)
|
||||
|
||||
// wait for the intent to expire
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
_, err = Client.SetSession(IAMOwnerCTX, &session.SetSessionRequest{
|
||||
SessionId: createResp.GetSessionId(),
|
||||
Checks: &session.Checks{
|
||||
IdpIntent: &session.CheckIDPIntent{
|
||||
IdpIntentId: intentID,
|
||||
IdpIntentToken: token,
|
||||
},
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func registerTOTP(ctx context.Context, t *testing.T, userID string) (secret string) {
|
||||
resp, err := Instance.Client.UserV2.RegisterTOTP(ctx, &user.RegisterTOTPRequest{
|
||||
UserId: userID,
|
||||
|
Reference in New Issue
Block a user