diff --git a/handlers/application/menuhandler.go b/handlers/application/menuhandler.go index c9a1103..2796231 100644 --- a/handlers/application/menuhandler.go +++ b/handlers/application/menuhandler.go @@ -18,17 +18,17 @@ import ( "git.defalsify.org/vise.git/persist" "git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/state" - dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" + "git.grassecon.net/grassrootseconomics/common/hex" + "git.grassecon.net/grassrootseconomics/common/identity" + commonlang "git.grassecon.net/grassrootseconomics/common/lang" + "git.grassecon.net/grassrootseconomics/common/person" + "git.grassecon.net/grassrootseconomics/common/phone" + "git.grassecon.net/grassrootseconomics/common/pin" + "git.grassecon.net/grassrootseconomics/sarafu-api/remote" "git.grassecon.net/grassrootseconomics/sarafu-vise/profile" "git.grassecon.net/grassrootseconomics/sarafu-vise/store" storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db" - "git.grassecon.net/grassrootseconomics/sarafu-api/remote" - "git.grassecon.net/grassrootseconomics/common/hex" - commonlang "git.grassecon.net/grassrootseconomics/common/lang" - "git.grassecon.net/grassrootseconomics/common/pin" - "git.grassecon.net/grassrootseconomics/common/person" - "git.grassecon.net/grassrootseconomics/common/phone" - "git.grassecon.net/grassrootseconomics/common/identity" + dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" ) var ( @@ -99,7 +99,7 @@ func NewMenuHandlers(appFlags *asm.FlagParser, userdataStore db.Db, adminstore * } // WithPersister sets persister instance to the handlers. -//func (h *MenuHandlers) WithPersister(pe *persist.Persister) *MenuHandlers { +// func (h *MenuHandlers) WithPersister(pe *persist.Persister) *MenuHandlers { func (h *MenuHandlers) SetPersister(pe *persist.Persister) { if h.pe != nil { panic("persister already set") @@ -108,7 +108,6 @@ func (h *MenuHandlers) SetPersister(pe *persist.Persister) { //return h } - // Init initializes the handler for a new session. func (h *MenuHandlers) Init(ctx context.Context, sym string, input []byte) (resource.Result, error) { var r resource.Result @@ -156,6 +155,70 @@ func (h *MenuHandlers) Exit() { h.pe = nil } +// SetAccountFlags queries the storage to check if the data exits +// it then sets the required flags to prevent a registered user from registering afresh +func (h *MenuHandlers) SetAccountFlags(ctx context.Context, sym string, input []byte) (resource.Result, error) { + var res resource.Result + + flag_language_set, _ := h.flagManager.GetFlag("flag_language_set") + flag_account_created, _ := h.flagManager.GetFlag("flag_account_created") + flag_account_blocked, _ := h.flagManager.GetFlag("flag_account_blocked") + flag_pin_set, _ := h.flagManager.GetFlag("flag_pin_set") + + sessionId, ok := ctx.Value("SessionId").(string) + if !ok { + return res, fmt.Errorf("missing session") + } + + store := h.userdataStore + + // check account creation status + _, err := store.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) + if err != nil { + logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err) + return res, nil + } + + res.FlagSet = append(res.FlagSet, flag_account_created) + + // check language status + code, err := store.ReadEntry(ctx, sessionId, storedb.DATA_SELECTED_LANGUAGE_CODE) + if err != nil { + logg.ErrorCtxf(ctx, "failed to read language code entry with", "key", storedb.DATA_SELECTED_LANGUAGE_CODE, "error", err) + return res, nil + } + + res.Content = string(code) + + res.FlagSet = append(res.FlagSet, state.FLAG_LANG) + res.FlagSet = append(res.FlagSet, flag_language_set) + + // check if the account is guarded by a PIN + _, err = store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_PIN) + if err != nil { + logg.ErrorCtxf(ctx, "failed to read account PIN entry with", "key", storedb.DATA_ACCOUNT_PIN, "error", err) + return res, nil + } + + res.FlagSet = append(res.FlagSet, flag_pin_set) + + // check PIN attempts + currentWrongPinAttempts, err := store.ReadEntry(ctx, sessionId, storedb.DATA_INCORRECT_PIN_ATTEMPTS) + if err != nil { + if !db.IsNotFound(err) { + return res, err + } + } + pinAttemptsValue, _ := strconv.ParseUint(string(currentWrongPinAttempts), 0, 64) + remainingPINAttempts := pin.AllowedPINAttempts - uint8(pinAttemptsValue) + if remainingPINAttempts == 0 { + res.FlagSet = append(res.FlagSet, flag_account_blocked) + return res, nil + } + + return res, nil +} + // SetLanguage sets the language across the menu. func (h *MenuHandlers) SetLanguage(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result diff --git a/handlers/local.go b/handlers/local.go index 5650cf0..e864b90 100644 --- a/handlers/local.go +++ b/handlers/local.go @@ -75,6 +75,7 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService) } //appHandlers = appHandlers.WithPersister(ls.Pe) appHandlers.SetPersister(ls.Pe) + ls.DbRs.AddLocalFunc("set_account_flags", appHandlers.SetAccountFlags) ls.DbRs.AddLocalFunc("set_language", appHandlers.SetLanguage) ls.DbRs.AddLocalFunc("create_account", appHandlers.CreateAccount) ls.DbRs.AddLocalFunc("save_temporary_pin", appHandlers.SaveTemporaryPin) diff --git a/services/registration/root.vis b/services/registration/root.vis index 102e6e5..a3d6eae 100644 --- a/services/registration/root.vis +++ b/services/registration/root.vis @@ -1,9 +1,10 @@ +LOAD set_account_flags 8 CATCH blocked_account flag_account_blocked 1 CATCH select_language flag_language_set 0 CATCH terms flag_account_created 0 LOAD check_account_status 0 RELOAD check_account_status -CATCH api_failure flag_api_call_error 1 +CATCH api_failure flag_api_call_error 1 CATCH account_pending flag_account_pending 1 CATCH create_pin flag_pin_set 0 CATCH main flag_account_success 1