diff --git a/internal/handlers/handlerservice.go b/internal/handlers/handlerservice.go index 3dffe16..1a556cc 100644 --- a/internal/handlers/handlerservice.go +++ b/internal/handlers/handlerservice.go @@ -60,8 +60,8 @@ func (ls *LocalHandlerService) GetHandler() (*ussd.Handlers, error) { ussdHandlers = ussdHandlers.WithPersister(ls.Pe) ls.DbRs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) ls.DbRs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) - ls.DbRs.AddLocalFunc("save_pin", ussdHandlers.SavePin) - ls.DbRs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) + ls.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) + ls.DbRs.AddLocalFunc("verify_create_pin", ussdHandlers.VerifyCreatePin) ls.DbRs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) ls.DbRs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) ls.DbRs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) @@ -89,11 +89,10 @@ func (ls *LocalHandlerService) GetHandler() (*ussd.Handlers, error) { ls.DbRs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) ls.DbRs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) ls.DbRs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) - ls.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) ls.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) ls.DbRs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) ls.DbRs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp) - ls.DbRs.AddLocalFunc("get_vouchers",ussdHandlers.GetVoucherList) + ls.DbRs.AddLocalFunc("get_vouchers", ussdHandlers.GetVoucherList) return ussdHandlers, nil } diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 5ebdaa5..165a456 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -180,34 +180,6 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) return res, nil } -// SavePin persists the user's PIN choice into the filesystem -func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) { - var res resource.Result - var err error - - sessionId, ok := ctx.Value("SessionId").(string) - if !ok { - return res, fmt.Errorf("missing session") - } - - flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") - - accountPIN := string(input) - // Validate that the PIN is a 4-digit number - if !isValidPIN(accountPIN) { - res.FlagSet = append(res.FlagSet, flag_incorrect_pin) - return res, nil - } - - res.FlagReset = append(res.FlagReset, flag_incorrect_pin) - store := h.userdataStore - err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN)) - if err != nil { - return res, err - } - return res, nil -} - func (h *Handlers) VerifyNewPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { res := resource.Result{} _, ok := ctx.Value("SessionId").(string) @@ -226,6 +198,9 @@ func (h *Handlers) VerifyNewPin(ctx context.Context, sym string, input []byte) ( return res, nil } +// SaveTemporaryPin saves the valid PIN input to the DATA_TEMPORARY_PIN +// during the account creation process +// and during the change PIN process func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result var err error @@ -234,6 +209,7 @@ func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byt if !ok { return res, fmt.Errorf("missing session") } + flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") accountPIN := string(input) @@ -243,16 +219,19 @@ func (h *Handlers) SaveTemporaryPin(ctx context.Context, sym string, input []byt res.FlagSet = append(res.FlagSet, flag_incorrect_pin) return res, nil } + + res.FlagReset = append(res.FlagReset, flag_incorrect_pin) + store := h.userdataStore err = store.WriteEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN, []byte(accountPIN)) if err != nil { return res, err } + return res, nil } - -func (h *Handlers) GetVoucherList(ctx context.Context,sym string,input []byte) (resource.Result,error){ +func (h *Handlers) GetVoucherList(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result vouchers := []string{ "SRF", @@ -283,9 +262,9 @@ func (h *Handlers) GetVoucherList(ctx context.Context,sym string,input []byte) ( for i, voucher := range vouchers { numberedVouchers = append(numberedVouchers, fmt.Sprintf("%d:%s", i+1, voucher)) } - res.Content = strings.Join(numberedVouchers,"\n") + res.Content = strings.Join(numberedVouchers, "\n") - return res,nil + return res, nil } func (h *Handlers) ConfirmPinChange(ctx context.Context, sym string, input []byte) (resource.Result, error) { @@ -313,10 +292,10 @@ func (h *Handlers) ConfirmPinChange(ctx context.Context, sym string, input []byt return res, nil } -// VerifyPin checks whether the confirmation PIN is similar to the account PIN -// If similar, it sets the USERFLAG_PIN_SET flag allowing the user +// VerifyCreatePin checks whether the confirmation PIN is similar to the temporary PIN +// If similar, it sets the USERFLAG_PIN_SET flag and writes the account PIN allowing the user // to access the main menu -func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { +func (h *Handlers) VerifyCreatePin(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result flag_valid_pin, _ := h.flagManager.GetFlag("flag_valid_pin") @@ -328,14 +307,13 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res return res, fmt.Errorf("missing session") } - //AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN) store := h.userdataStore - AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN) + temporaryPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_TEMPORARY_PIN) if err != nil { return res, err } - if bytes.Equal(input, AccountPin) { + if bytes.Equal(input, temporaryPin) { res.FlagSet = []uint32{flag_valid_pin} res.FlagReset = []uint32{flag_pin_mismatch} res.FlagSet = append(res.FlagSet, flag_pin_set) @@ -343,6 +321,11 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res res.FlagSet = []uint32{flag_pin_mismatch} } + err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(temporaryPin)) + if err != nil { + return res, err + } + return res, nil } diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index 83e6f0c..1ce8b51 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -171,7 +171,7 @@ func TestSaveFamilyname(t *testing.T) { mockStore.AssertExpectations(t) } -func TestSavePin(t *testing.T) { +func TestSaveTemporaryPIn(t *testing.T) { fm, err := NewFlagManager(flagsPath) mockStore := new(mocks.MockUserDataStore) if err != nil { @@ -213,10 +213,10 @@ func TestSavePin(t *testing.T) { t.Run(tt.name, func(t *testing.T) { // Set up the expected behavior of the mock - mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(tt.input)).Return(nil) + mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_TEMPORARY_PIN, []byte(tt.input)).Return(nil) // Call the method - res, err := h.SavePin(ctx, "save_pin", tt.input) + res, err := h.SaveTemporaryPin(ctx, "save_pin", tt.input) if err != nil { t.Error(err) @@ -937,7 +937,7 @@ func TestVerifyYob(t *testing.T) { } } -func TestVerifyPin(t *testing.T) { +func TestVerifyCreatePin(t *testing.T) { fm, err := NewFlagManager(flagsPath) if err != nil { @@ -986,7 +986,7 @@ func TestVerifyPin(t *testing.T) { }, } - typ := utils.DATA_ACCOUNT_PIN + typ := utils.DATA_TEMPORARY_PIN for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -994,8 +994,11 @@ func TestVerifyPin(t *testing.T) { // Define expected interactions with the mock mockDataStore.On("ReadEntry", ctx, sessionId, typ).Return([]byte(firstSetPin), nil) + // Set up the expected behavior of the mock + mockDataStore.On("WriteEntry", ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(firstSetPin)).Return(nil) + // Call the method under test - res, err := h.VerifyPin(ctx, "verify_pin", []byte(tt.input)) + res, err := h.VerifyCreatePin(ctx, "verify_create_pin", []byte(tt.input)) // Assert that no errors occurred assert.NoError(t, err) @@ -1693,42 +1696,6 @@ func TestVerifyNewPin(t *testing.T) { } -func TestSaveTemporaryPIn(t *testing.T) { - - fm, err := NewFlagManager(flagsPath) - - if err != nil { - t.Logf(err.Error()) - } - - // Create a new instance of UserDataStore - mockStore := new(mocks.MockUserDataStore) - - // Define test data - sessionId := "session123" - PIN := "1234" - ctx := context.WithValue(context.Background(), "SessionId", sessionId) - - // Set up the expected behavior of the mock - mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_TEMPORARY_PIN, []byte(PIN)).Return(nil) - - // Create the Handlers instance with the mock store - h := &Handlers{ - userdataStore: mockStore, - flagManager: fm.parser, - } - - // Call the method - res, err := h.SaveTemporaryPin(ctx, "save_temporary_pin", []byte(PIN)) - - // Assert results - assert.NoError(t, err) - assert.Equal(t, resource.Result{}, res) - - // Assert all expectations were met - mockStore.AssertExpectations(t) -} - func TestConfirmPin(t *testing.T) { sessionId := "session123" diff --git a/services/registration/account_creation.vis b/services/registration/account_creation.vis index f4f326b..380fe6d 100644 --- a/services/registration/account_creation.vis +++ b/services/registration/account_creation.vis @@ -1,4 +1,4 @@ -RELOAD verify_pin +RELOAD verify_create_pin CATCH create_pin_mismatch flag_pin_mismatch 1 LOAD quit 0 HALT diff --git a/services/registration/confirm_create_pin.vis b/services/registration/confirm_create_pin.vis index 1235916..1a3173c 100644 --- a/services/registration/confirm_create_pin.vis +++ b/services/registration/confirm_create_pin.vis @@ -1,4 +1,4 @@ -LOAD save_pin 0 +LOAD save_temporary_pin 0 HALT -LOAD verify_pin 8 +LOAD verify_create_pin 8 INCMP account_creation * diff --git a/services/registration/create_pin.vis b/services/registration/create_pin.vis index e0e330f..c76e1bf 100644 --- a/services/registration/create_pin.vis +++ b/services/registration/create_pin.vis @@ -2,8 +2,8 @@ LOAD create_account 0 CATCH account_creation_failed flag_account_creation_failed 1 MOUT exit 0 HALT -LOAD save_pin 0 -RELOAD save_pin +LOAD save_temporary_pin 0 +RELOAD save_temporary_pin CATCH . flag_incorrect_pin 1 INCMP quit 0 INCMP confirm_create_pin *