From fe1e2d53ac0134f3278809b4428e53808f165f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 27 Jun 2024 21:46:16 +0200 Subject: [PATCH] pam/gdmmodel: Add test for regenerating Qr code --- pam/internal/adapter/gdmmodel_test.go | 90 ++++++++++++++++++- pam/internal/adapter/gdmmodel_uimodel_test.go | 4 +- pam/internal/gdm_test/gdm_utils.go | 10 +++ 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/pam/internal/adapter/gdmmodel_test.go b/pam/internal/adapter/gdmmodel_test.go index cd9b4bc65..54e263066 100644 --- a/pam/internal/adapter/gdmmodel_test.go +++ b/pam/internal/adapter/gdmmodel_test.go @@ -83,6 +83,7 @@ func TestGdmModel(t *testing.T) { pamUser string protoVersion uint32 convError map[string]error + timeout time.Duration wantExitStatus PamReturnStatus wantGdmRequests []gdm.RequestType @@ -914,6 +915,7 @@ func TestGdmModel(t *testing.T) { gdm.EventType_uiLayoutReceived, gdm.EventType_startAuthentication, gdm.EventType_authEvent, + gdm.EventType_authEvent, }, wantStage: pam_proto.Stage_challenge, wantGdmAuthRes: []*authd.IAResponse{ @@ -995,6 +997,88 @@ func TestGdmModel(t *testing.T) { }, wantExitStatus: PamSuccess{BrokerID: firstBrokerInfo.Id}, }, + "Authenticated with qrcode regenerated after auth selection stage from client after client-side broker and auth mode selection": { + timeout: 10 * time.Second, + supportedLayouts: []*authd.UILayout{ + pam_test.FormUILayout(), + pam_test.QrCodeUILayout(), + }, + clientOptions: append(slices.Clone(singleBrokerClientOptions), + pam_test.WithUILayout("qrcode", "Hello QR!", pam_test.QrCodeUILayout()), + pam_test.WithIsAuthenticatedWantWait(time.Millisecond*500), + ), + gdmEvents: []*gdm.EventData{ + gdm_test.SelectUserEvent("gdm-selected-user-broker-and-auth-mode"), + }, + messages: []tea.Msg{ + gdmTestWaitForStage{ + stage: pam_proto.Stage_brokerSelection, + events: []*gdm.EventData{ + gdm_test.SelectBrokerEvent(firstBrokerInfo.Id), + }, + }, + gdmTestWaitForStage{ + stage: pam_proto.Stage_challenge, + events: []*gdm.EventData{ + gdm_test.ChangeStageEvent(pam_proto.Stage_authModeSelection), + }, + commands: []tea.Cmd{ + sendEvent(gdmTestWaitForStage{ + stage: pam_proto.Stage_authModeSelection, + events: []*gdm.EventData{ + gdm_test.AuthModeSelectedEvent("qrcode"), + }, + commands: []tea.Cmd{ + sendEvent(gdmTestSendAuthDataWhenReady{}), + sendEvent(gdmTestWaitForStage{ + stage: pam_proto.Stage_challenge, + events: []*gdm.EventData{ + gdm_test.ReselectAuthMode(), + }, + }), + sendEvent(gdmTestSendAuthDataWhenReady{&authd.IARequest_AuthenticationData_Wait{ + Wait: "true", + }}), + }, + }), + }, + }, + }, + wantUsername: "gdm-selected-user-broker-and-auth-mode", + wantSelectedBroker: firstBrokerInfo.Id, + wantGdmRequests: []gdm.RequestType{ + gdm.RequestType_uiLayoutCapabilities, + gdm.RequestType_changeStage, // -> broker Selection + gdm.RequestType_changeStage, // -> authMode Selection + gdm.RequestType_changeStage, // -> challenge + gdm.RequestType_changeStage, // -> authMode Selection + gdm.RequestType_changeStage, // -> challenge + }, + wantMessages: []tea.Msg{ + startAuthentication{}, + startAuthentication{}, + startAuthentication{}, + }, + wantGdmEvents: []gdm.EventType{ + gdm.EventType_userSelected, + gdm.EventType_brokersReceived, + gdm.EventType_brokerSelected, + gdm.EventType_authModeSelected, + gdm.EventType_uiLayoutReceived, + gdm.EventType_startAuthentication, + gdm.EventType_authModeSelected, + gdm.EventType_authEvent, + gdm.EventType_uiLayoutReceived, + gdm.EventType_startAuthentication, + gdm.EventType_authEvent, + }, + wantStage: pam_proto.Stage_challenge, + wantGdmAuthRes: []*authd.IAResponse{ + {Access: brokers.AuthCancelled}, + {Access: brokers.AuthGranted}, + }, + wantExitStatus: PamSuccess{BrokerID: firstBrokerInfo.Id}, + }, "Broker selection stage from client after client-side broker and auth mode selection if there is only one auth mode": { gdmEvents: []*gdm.EventData{ gdm_test.SelectUserEvent("gdm-selected-user-broker-and-auth-mode"), @@ -1924,7 +2008,6 @@ func TestGdmModel(t *testing.T) { p := tea.NewProgram(&appState, teaOpts...) appState.program = p - // testHadTimeout := false controlDone := make(chan struct{}) go func() { wg := sync.WaitGroup{} @@ -1970,13 +2053,16 @@ func TestGdmModel(t *testing.T) { } t.Log("Waiting for expected events") + if tc.timeout == 0 { + tc.timeout = 5 * time.Second + } waitChan := make(chan struct{}) go func() { wg.Wait() close(waitChan) }() select { - case <-time.After(5 * time.Second): + case <-time.After(tc.timeout): case <-waitChan: } t.Log("Waiting for events done...") diff --git a/pam/internal/adapter/gdmmodel_uimodel_test.go b/pam/internal/adapter/gdmmodel_uimodel_test.go index 38360c322..8860fbda1 100644 --- a/pam/internal/adapter/gdmmodel_uimodel_test.go +++ b/pam/internal/adapter/gdmmodel_uimodel_test.go @@ -141,7 +141,9 @@ func (m *gdmTestUIModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { go func() { m.gdmHandler.waitForAuthenticationStarted() - m.gdmHandler.appendPollResultEvents(gdm_test.IsAuthenticatedEvent(msg.item)) + if msg.item != nil { + m.gdmHandler.appendPollResultEvents(gdm_test.IsAuthenticatedEvent(msg.item)) + } m.program.Send(tea.Sequence(tea.Tick(gdmPollFrequency, func(t time.Time) tea.Msg { return sendEvent(doneMsg) }), sendEvent(doneMsg))()) diff --git a/pam/internal/gdm_test/gdm_utils.go b/pam/internal/gdm_test/gdm_utils.go index f95f8a5d1..7bfa17273 100644 --- a/pam/internal/gdm_test/gdm_utils.go +++ b/pam/internal/gdm_test/gdm_utils.go @@ -91,6 +91,16 @@ func AuthModeSelectedEvent(authModeID string) *gdm.EventData { } } +// ReselectAuthMode generates a ReselectAuthMode event. +func ReselectAuthMode() *gdm.EventData { + return &gdm.EventData{ + Type: gdm.EventType_reselectAuthMode, + Data: &gdm.EventData_ReselectAuthMode{ + ReselectAuthMode: &gdm.Events_ReselectAuthMode{}, + }, + } +} + // IsAuthenticatedEvent generates a IsAuthenticated event. func IsAuthenticatedEvent(item authd.IARequestAuthenticationDataItem) *gdm.EventData { return &gdm.EventData{