Compare commits

..

4 Commits

Author SHA1 Message Date
lash
c4c3d6c998
Set upstream go-vise dependency version in go.mod 2024-09-07 21:14:03 +01:00
lash
4accb847b9
Successfully executed account regisration using http 2024-09-06 03:05:18 +01:00
lash
350b040a59
Add storage retrieval solution for http handler 2024-09-06 01:28:51 +01:00
lash
e6754a1e92
WIP http server harness 2024-09-06 00:40:57 +01:00
11 changed files with 1243 additions and 661 deletions

View File

@ -12,18 +12,18 @@ import (
fsdb "git.defalsify.org/vise.git/db/fs"
gdbmdb "git.defalsify.org/vise.git/db/gdbm"
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/urdt/ussd/internal/handlers/ussd"
)
var (
logg = logging.NewVanilla()
logg = logging.NewVanilla()
scriptDir = path.Join("services", "registration")
)
func getParser(fp string, debug bool) (*asm.FlagParser, error) {
func getFlags(fp string, debug bool) (*asm.FlagParser, error) {
flagParser := asm.NewFlagParser().WithDebug()
_, err := flagParser.Load(fp)
if err != nil {
@ -91,7 +91,7 @@ func getUserdataDb(dbDir string, ctx context.Context) db.Db {
store := gdbmdb.NewGdbmDb()
storeFile := path.Join(dbDir, "userdata.gdbm")
store.Connect(ctx, storeFile)
return store
}
@ -113,21 +113,23 @@ func getEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) *
func main() {
var dbDir string
var resourceDir string
var size uint
var sessionId string
var debug bool
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.BoolVar(&debug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "outputsize", size)
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "SessionId",sessionId)
pfp := path.Join(scriptDir, "pp.csv")
flagParser, err := getParser(pfp, true)
flagParser, err := getFlags(pfp, true)
if err != nil {
os.Exit(1)
@ -140,7 +142,7 @@ func main() {
FlagCount: uint32(16),
}
rs, err := getResource(scriptDir, ctx)
rs, err := getResource(resourceDir, ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)

1
go-vise Submodule

@ -0,0 +1 @@
Subproject commit 2bddc363f20210ab019eec29d8ba4104d147e9b7

View File

@ -29,6 +29,23 @@ var (
translationDir = path.Join(scriptDir, "locale")
)
const (
TrackingIdKey = "TRACKINGID"
PublicKeyKey = "PUBLICKEY"
CustodialIdKey = "CUSTODIALID"
AccountPin = "ACCOUNTPIN"
AccountStatus = "ACCOUNTSTATUS"
FirstName = "FIRSTNAME"
FamilyName = "FAMILYNAME"
YearOfBirth = "YOB"
Location = "LOCATION"
Gender = "GENDER"
Offerings = "OFFERINGS"
Recipient = "RECIPIENT"
Amount = "AMOUNT"
AccountCreated = "ACCOUNTCREATED"
)
type FSData struct {
Path string
St *state.State
@ -58,24 +75,23 @@ func (fm *FlagManager) GetFlag(label string) (uint32, error) {
}
type Handlers struct {
pe *persist.Persister
st *state.State
ca cache.Memory
userdataStore utils.DataStore
flagManager *asm.FlagParser
accountService server.AccountServiceInterface
pe *persist.Persister
st *state.State
ca cache.Memory
userdataStore db.Db
flagManager *asm.FlagParser
accountFileHandler *utils.AccountFileHandler
accountService server.AccountServiceInterface
}
func NewHandlers(appFlags *asm.FlagParser, userdataStore db.Db) (*Handlers, error) {
if userdataStore == nil {
return nil, fmt.Errorf("cannot create handler with nil userdata store")
}
userDb := &utils.UserDataStore{
Db: userdataStore,
}
h := &Handlers{
userdataStore: userDb,
userdataStore: userdataStore,
flagManager: appFlags,
accountFileHandler: utils.NewAccountFileHandler(userdataStore),
accountService: &server.AccountService{},
}
return h, nil
@ -110,7 +126,7 @@ func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource
if h.st == nil || h.ca == nil {
logg.ErrorCtxf(ctx, "perister fail in handler", "state", h.st, "cache", h.ca)
return r, fmt.Errorf("cannot get state and memory for handler")
}
}
h.pe = nil
logg.DebugCtxf(ctx, "handler has been initialized", "state", h.st, "cache", h.ca)
@ -152,8 +168,7 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
}
for key, value := range data {
store := h.userdataStore
err := store.WriteEntry(ctx, sessionId, key, []byte(value))
err := utils.WriteEntry(ctx, h.userdataStore, sessionId, key, []byte(value))
if err != nil {
return err
}
@ -170,15 +185,20 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
func (h *Handlers) CreateAccount(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")
}
store := h.userdataStore
_, err = store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_CREATED)
_, err = utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_CREATED)
if err != nil {
if db.IsNotFound(err) {
logg.Printf(logging.LVL_INFO, "Creating an account because it doesn't exist")
fmt.Println("Creating an account because it doesn't exist")
err = h.createAccountNoExist(ctx, sessionId, &res)
if err != nil {
return res, err
}
} else {
err = h.createAccountNoExist(ctx, sessionId, &res)
if err != nil {
return res, err
@ -192,7 +212,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
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")
@ -208,18 +228,19 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
}
res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
if err != nil {
return res, err
return res, nil
}
return res, nil
}
// SetResetSingleEdit sets and resets flags to allow gradual editing of profile information.
func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
menuOption := string(input)
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
@ -257,12 +278,7 @@ 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)
if err != nil {
return res, err
}
AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
if bytes.Equal(input, AccountPin) {
res.FlagSet = []uint32{flag_valid_pin}
@ -285,103 +301,67 @@ func codeFromCtx(ctx context.Context) string {
return code
}
// SaveFirstname updates the first name in the gdbm with the provided input.
// SaveFirstname updates the first name in a JSON data file with the provided input.
func (h *Handlers) SaveFirstname(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")
}
if len(input) > 0 {
firstName := string(input)
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_FIRST_NAME, []byte(firstName))
if err != nil {
return res, err
}
//name := string(input)
//key := []byte(FirstName)
//value := []byte(name)
//h.db.Store(key, value, true)
}
return res, nil
}
// SaveFamilyname updates the family name in the gdbm with the provided input.
// SaveFamilyname updates the family name in a JSON data file with the provided input.
func (h *Handlers) SaveFamilyname(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")
}
if len(input) > 0 {
familyName := string(input)
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_FAMILY_NAME, []byte(familyName))
if err != nil {
return res, err
}
if err != nil {
return res, nil
}
} else {
return res, fmt.Errorf("a family name cannot be less than one character")
//secondname := string(input)
//key := []byte(FamilyName)
//value := []byte(secondname)
//h.db.Store(key, value, true)
}
return res, nil
}
// SaveYOB updates the Year of Birth(YOB) in the gdbm with the provided input.
// SaveYOB updates the Year of Birth(YOB) in a JSON data file with the provided input.
func (h *Handlers) SaveYob(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")
}
if len(input) == 4 {
yob := string(input)
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_YOB, []byte(yob))
if err != nil {
return res, err
}
yob := string(input)
if len(yob) == 4 {
//yob := string(input)
//key := []byte(YearOfBirth)
//value := []byte(yob)
//h.db.Store(key, value, true)
}
return res, nil
}
// SaveLocation updates the location in the gdbm with the provided input.
// SaveLocation updates the location in a JSON data file with the provided input.
func (h *Handlers) SaveLocation(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")
}
if len(input) > 0 {
location := string(input)
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_LOCATION, []byte(location))
if err != nil {
return res, err
}
//location := string(input)
//key := []byte(Location)
//value := []byte(location)
//h.db.Store(key, value, true)
}
return res, nil
}
// SaveGender updates the gender in the gdbm with the provided input.
// SaveGender updates the gender in a JSON data file with the provided input.
func (h *Handlers) SaveGender(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")
}
if len(input) > 0 {
gender := string(input)
@ -393,34 +373,23 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
case "3":
gender = "Unspecified"
}
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(gender))
if err != nil {
return res, nil
}
//key := []byte(Gender)
//value := []byte(gender)
//h.db.Store(key, value, true)
}
return res, nil
}
// SaveOfferings updates the offerings(goods and services provided by the user) in the gdbm with the provided input.
// SaveOfferings updates the offerings(goods and services provided by the user) in a JSON data file with the provided input.
func (h *Handlers) SaveOfferings(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")
}
if len(input) > 0 {
offerings := string(input)
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_OFFERINGS, []byte(offerings))
if err != nil {
return res, nil
}
//offerings := string(input)
//key := []byte(Offerings)
//value := []byte(offerings)
//h.db.Store(key, value, true)
}
return res, nil
}
@ -448,16 +417,11 @@ func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input
func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
store := h.userdataStore
publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
res.Content = string(publicKey)
//publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
// if err != nil {
// return res, err
// }
res.Content = "string(publicKey)"
return res, nil
}
@ -467,20 +431,14 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
var res resource.Result
var err error
flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
store := h.userdataStore
AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
if err != nil {
return res, err
}
AccountPin, err := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
if err == nil {
if len(input) == 4 {
@ -527,22 +485,26 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
if !ok {
return res, fmt.Errorf("missing session")
}
store := h.userdataStore
trackingId, err := store.ReadEntry(ctx, sessionId, utils.DATA_TRACKING_ID)
if err != nil {
return res, err
}
trackingId, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_TRACKING_ID)
status, err := h.accountService.CheckAccountStatus(string(trackingId))
if err != nil {
fmt.Println("Error checking account status:", err)
return res, err
}
err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status))
if err != nil {
return res, nil
}
// err = h.db.Store(toBytes(AccountStatus), toBytes(status), true)
// if err != nil {
// return res, nil
// }
// err = h.db.Store(toBytes(TrackingIdKey), toBytes(status), true)
// if err != nil {
// return res, nil
// }
if status == "SUCCESS" {
res.FlagSet = append(res.FlagSet, flag_account_success)
@ -609,16 +571,14 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
var res resource.Result
var err error
// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
store := h.userdataStore
publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
if err != nil {
return res, err
}
publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
balance, err := h.accountService.CheckBalance(string(publicKey))
if err != nil {
@ -632,12 +592,6 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
// ValidateRecipient validates that the given input is a valid phone number.
func (h *Handlers) ValidateRecipient(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")
}
recipient := string(input)
@ -651,11 +605,12 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
return res, nil
}
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_RECIPIENT, []byte(recipient))
if err != nil {
return res, nil
}
// accountData["Recipient"] = recipient
// key := []byte(Recipient)
// value := []byte(recipient)
// h.db.Store(key, value, true)
}
return res, nil
@ -665,25 +620,18 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
// as well as the invalid flags
func (h *Handlers) TransactionReset(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_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(""))
if err != nil {
return res, nil
}
err = store.WriteEntry(ctx, sessionId, utils.DATA_RECIPIENT, []byte(""))
if err != nil {
return res, nil
}
// err := h.db.Delete([]byte(Amount))
// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
// return res, err
// }
// err = h.db.Delete([]byte(Recipient))
// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
// return res, err
// }
res.FlagReset = append(res.FlagReset, flag_invalid_recipient, flag_invalid_recipient_with_invite)
@ -693,19 +641,13 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
// ResetTransactionAmount resets the transaction amount and invalid flag
func (h *Handlers) ResetTransactionAmount(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_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(""))
if err != nil {
return res, nil
}
// err := h.db.Delete([]byte(Amount))
// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
// return res, err
// }
res.FlagReset = append(res.FlagReset, flag_invalid_amount)
@ -718,14 +660,12 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res
var res resource.Result
var err error
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
store := h.userdataStore
publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
// if err != nil {
// return res, err
// }
balance, err := h.accountService.CheckBalance(string(publicKey))
balance, err := h.accountService.CheckBalance(string("publicKey"))
if err != nil {
return res, nil
}
@ -741,18 +681,16 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
var res resource.Result
var err error
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
amountStr := string(input)
// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
balanceStr, err := h.accountService.CheckBalance(string(publicKey))
// if err != nil {
// return res, err
// }
balanceStr, err := h.accountService.CheckBalance(string("publicKey"))
if err != nil {
return res, err
@ -792,8 +730,10 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
}
res.Content = fmt.Sprintf("%.3f", inputAmount) // Format to 3 decimal places
store := h.userdataStore
err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(amountStr))
// key := []byte(Amount)
// value := []byte(res.Content)
// h.db.Store(key, value, true)
if err != nil {
return res, err
}
@ -801,18 +741,16 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
return res, nil
}
// GetRecipient returns the transaction recipient from the gdbm.
// GetRecipient returns the transaction recipient from a JSON data file.
func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
store := h.userdataStore
recipient, _ := store.ReadEntry(ctx, sessionId, utils.DATA_RECIPIENT)
// recipient, err := h.db.Fetch([]byte(Recipient))
// if err != nil {
// return res, err
// }
res.Content = string(recipient)
res.Content = string("recipient")
return res, nil
}
@ -821,15 +759,12 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (
func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
// if err != nil {
// return res, err
// }
store := h.userdataStore
publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
res.Content = string(publicKey)
res.Content = string("publicKey")
return res, nil
}
@ -838,14 +773,11 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res
func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
store := h.userdataStore
amount, _ := store.ReadEntry(ctx, sessionId, utils.DATA_AMOUNT)
res.Content = string(amount)
// amount, err := h.db.Fetch([]byte(Amount))
// if err != nil {
// return res, err
// }
res.Content = string("amount")
return res, nil
}
@ -855,23 +787,17 @@ func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (res
func (h *Handlers) QuitWithBalance(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_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
store := h.userdataStore
publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
if err != nil {
return res, err
}
balance, err := h.accountService.CheckBalance(string(publicKey))
// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
// if err != nil {
// return res, err
// }
balance, err := h.accountService.CheckBalance(string("publicKey"))
if err != nil {
return res, nil
}
@ -881,28 +807,31 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
}
// InitiateTransaction returns a confirmation and resets the transaction data
// on the gdbm store.
// on the JSON file.
func (h *Handlers) InitiateTransaction(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")
}
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
// TODO
// Use the amount, recipient and sender to call the API and initialize the transaction
store := h.userdataStore
publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
amount, _ := store.ReadEntry(ctx, sessionId, utils.DATA_AMOUNT)
// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
// if err != nil {
// return res, err
// }
// amount, err := h.db.Fetch([]byte(Amount))
// if err != nil {
// return res, err
// }
// recipient, err := h.db.Fetch([]byte(Recipient))
// if err != nil {
// return res, err
// }
recipient, _ := store.ReadEntry(ctx, sessionId, utils.DATA_RECIPIENT)
res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey))
//res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey))
account_authorized_flag, err := h.flagManager.GetFlag("flag_account_authorized")
if err != nil {
@ -916,55 +845,62 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
// GetProfileInfo retrieves and formats the profile information of a user from a Gdbm backed storage.
func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
// Default value when an entry is not found
defaultValue := "Not Provided"
// Define default values
defaultValue := "Not provided"
name := defaultValue
familyName := defaultValue
yob := defaultValue
gender := defaultValue
location := defaultValue
offerings := defaultValue
// Helper function to handle nil byte slices and convert them to string
getEntryOrDefault := func(entry []byte, err error) string {
if err != nil || entry == nil {
return defaultValue
}
return string(entry)
}
store := h.userdataStore
// Retrieve user data as strings with fallback to defaultValue
firstName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_FIRST_NAME))
familyName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_FAMILY_NAME))
yob := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_YOB))
gender := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_GENDER))
location := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_LOCATION))
offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_OFFERINGS))
// Fetch data using a map for better organization
// dataKeys := map[string]*string{
// FirstName: &name,
// FamilyName: &familyName,
// YearOfBirth: &yob,
// Location: &location,
// Gender: &gender,
// Offerings: &offerings,
// }
// Iterate over keys and fetch values
//iter := h.db.Iterator()
// next := h.db.Iterator()
// //defer iter.Close() // Ensure the iterator is closed
// for key, err := next(); err == nil; key, err = next() {
// if valuePointer, ok := dataKeys[string(key)]; ok {
// // value, fetchErr := h.db.Fetch(key)
// // if fetchErr == nil {
// // *valuePointer = string(value)
// // }
// }
// }
// Construct the full name
name := defaultValue
if familyName != defaultValue {
if firstName == defaultValue {
if name == defaultValue {
name = familyName
} else {
name = firstName + " " + familyName
name = name + " " + familyName
}
}
// Calculate age from year of birth
age := defaultValue
var age string
if yob != defaultValue {
if yobInt, err := strconv.Atoi(yob); err == nil {
age = strconv.Itoa(utils.CalculateAgeWithYOB(yobInt))
} else {
yobInt, err := strconv.Atoi(yob)
if err != nil {
return res, fmt.Errorf("invalid year of birth: %v", err)
}
age = strconv.Itoa(utils.CalculateAgeWithYOB(yobInt))
} else {
age = defaultValue
}
// Format the result
res.Content = fmt.Sprintf(
"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n",
name, gender, age, location, offerings,
)
formattedData := fmt.Sprintf("Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n", name, gender, age, location, offerings)
res.Content = formattedData
return res, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -1,59 +0,0 @@
package mocks
import (
"context"
"git.defalsify.org/vise.git/lang"
"github.com/stretchr/testify/mock"
)
type MockDb struct {
mock.Mock
}
func (m *MockDb) SetPrefix(prefix uint8) {
m.Called(prefix)
}
func (m *MockDb) Prefix() uint8 {
args := m.Called()
return args.Get(0).(uint8)
}
func (m *MockDb) Safe() bool {
args := m.Called()
return args.Get(0).(bool)
}
func (m *MockDb) SetLanguage(language *lang.Language) {
m.Called(language)
}
func (m *MockDb) SetLock(uint8, bool) error {
args := m.Called()
return args.Error(0)
}
func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
args := m.Called(ctx, connectionStr)
return args.Error(0)
}
func (m *MockDb) SetSession(sessionId string) {
m.Called(sessionId)
}
func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
args := m.Called(ctx, key, value)
return args.Error(0)
}
func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
args := m.Called(ctx, key)
return nil, args.Error(0)
}
func (m *MockDb) Close() error {
args := m.Called(nil)
return args.Error(0)
}

View File

@ -0,0 +1,44 @@
package mocks
import (
"git.grassecon.net/urdt/ussd/internal/models"
"github.com/stretchr/testify/mock"
)
type MockAccountFileHandler struct {
mock.Mock
}
func (m *MockAccountFileHandler) EnsureFileExists() error {
args := m.Called()
return args.Error(0)
}
func (m *MockAccountFileHandler) ReadAccountData() (map[string]string, error) {
args := m.Called()
return args.Get(0).(map[string]string), args.Error(1)
}
func (m *MockAccountFileHandler) WriteAccountData(data map[string]string) error {
args := m.Called(data)
return args.Error(0)
}
type MockAccountService struct {
mock.Mock
}
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
args := m.Called()
return args.Get(0).(*models.AccountResponse), args.Error(1)
}
func (m *MockAccountService) CheckAccountStatus(TrackingId string) (string, error) {
args := m.Called()
return args.Get(0).(string), args.Error(1)
}
func (m *MockAccountService) CheckBalance(PublicKey string) (string, error) {
args := m.Called()
return args.Get(0).(string), args.Error(1)
}

View File

@ -1,26 +0,0 @@
package mocks
import (
"git.grassecon.net/urdt/ussd/internal/models"
"github.com/stretchr/testify/mock"
)
// MockAccountService implements AccountServiceInterface for testing
type MockAccountService struct {
mock.Mock
}
func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
args := m.Called()
return args.Get(0).(*models.AccountResponse), args.Error(1)
}
func (m *MockAccountService) CheckBalance(publicKey string) (string, error) {
args := m.Called(publicKey)
return args.String(0), args.Error(1)
}
func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, error) {
args := m.Called(trackingId)
return args.String(0), args.Error(1)
}

View File

@ -1,24 +0,0 @@
package mocks
import (
"context"
"git.defalsify.org/vise.git/db"
"git.grassecon.net/urdt/ussd/internal/utils"
"github.com/stretchr/testify/mock"
)
type MockUserDataStore struct {
db.Db
mock.Mock
}
func (m *MockUserDataStore) ReadEntry(ctx context.Context, sessionId string, typ utils.DataTyp) ([]byte, error) {
args := m.Called(ctx, sessionId, typ)
return args.Get(0).([]byte), args.Error(1)
}
func (m *MockUserDataStore) WriteEntry(ctx context.Context, sessionId string, typ utils.DataTyp, value []byte) error {
args := m.Called(ctx, sessionId, typ, value)
return args.Error(0)
}

View File

@ -0,0 +1,77 @@
package utils
import (
"context"
"encoding/json"
"git.defalsify.org/vise.git/db"
)
type AccountFileHandler struct {
//FilePath string
store db.Db
}
// func NewAccountFileHandler(path string) *AccountFileHandler {
// return &AccountFileHandler{FilePath: path}
// }
func NewAccountFileHandler(store db.Db) *AccountFileHandler {
return &AccountFileHandler{
store: store,
}
}
// func (afh *AccountFileHandler) ReadAccountData() (map[string]string, error) {
// jsonData, err := os.ReadFile(afh.FilePath)
// if err != nil {
// return nil, err
// }
// var accountData map[string]string
// err = json.Unmarshal(jsonData, &accountData)
// if err != nil {
// return nil, err
// }
// return accountData, nil
// }
func (afh *AccountFileHandler) ReadAccountData(ctx context.Context, sessionId string) (map[string]string, error) {
var accountData map[string]string
jsonData, err := ReadEntry(ctx, afh.store, sessionId, DATA_ACCOUNT)
err = json.Unmarshal(jsonData, &accountData)
if err != nil {
return nil, err
}
return accountData, nil
}
// func (afh *AccountFileHandler) WriteAccountData(accountData map[string]string) error {
// jsonData, err := json.Marshal(accountData)
// if err != nil {
// return err
// }
// return os.WriteFile(afh.FilePath, jsonData, 0644)
// }
func (afh *AccountFileHandler) WriteAccountData(ctx context.Context, sessionId string, accountData map[string]string) error {
_, err := json.Marshal(accountData)
if err != nil {
return err
}
return nil
}
// func (afh *AccountFileHandler) EnsureFileExists() error {
// f, err := os.OpenFile(afh.FilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
// if err != nil {
// return err
// }
// return f.Close()
// }
func (afh *AccountFileHandler) EnsureFileExists() error {
return nil
}

View File

@ -16,15 +16,6 @@ const (
DATA_PUBLIC_KEY
DATA_CUSTODIAL_ID
DATA_ACCOUNT_PIN
DATA_ACCOUNT_STATUS
DATA_FIRST_NAME
DATA_FAMILY_NAME
DATA_YOB
DATA_LOCATION
DATA_GENDER
DATA_OFFERINGS
DATA_RECIPIENT
DATA_AMOUNT
)
func typToBytes(typ DataTyp) []byte {
@ -33,16 +24,15 @@ func typToBytes(typ DataTyp) []byte {
return b[:]
}
func PackKey(typ DataTyp, data []byte) []byte {
func packKey(typ DataTyp, data []byte) []byte {
v := typToBytes(typ)
return append(v, data...)
}
func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp) ([]byte, error) {
store.SetPrefix(db.DATATYPE_USERDATA)
store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId))
k := packKey(typ, []byte(sessionId))
b, err := store.Get(ctx, k)
if err != nil {
return nil, err
@ -53,6 +43,6 @@ func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp)
func WriteEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp, value []byte) error {
store.SetPrefix(db.DATATYPE_USERDATA)
store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId))
k := packKey(typ, []byte(sessionId))
return store.Put(ctx, k, value)
}

View File

@ -1,32 +0,0 @@
package utils
import (
"context"
"git.defalsify.org/vise.git/db"
)
type DataStore interface {
db.Db
ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error)
WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error
}
type UserDataStore struct {
db.Db
}
// ReadEntry retrieves an entry from the store based on the provided parameters.
func (store *UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error) {
store.SetPrefix(db.DATATYPE_USERDATA)
store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId))
return store.Get(ctx, k)
}
func (store *UserDataStore) WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error {
store.SetPrefix(db.DATATYPE_USERDATA)
store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId))
return store.Put(ctx, k, value)
}