wip-account-creation #4

Merged
lash merged 143 commits from wip-account-creation into master 2024-08-30 14:37:58 +02:00
2 changed files with 96 additions and 238 deletions
Showing only changes of commit ded37ab515 - Show all commits

View File

@ -3,9 +3,7 @@ package ussd
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/json"
"fmt" "fmt"
"os"
"regexp" "regexp"
"time" "time"
@ -25,6 +23,7 @@ type FSData struct {
type Handlers struct { type Handlers struct {
fs *FSData fs *FSData
accountFileHandler *utils.AccountFileHandler
} }
func NewHandlers(path string, st *state.State) *Handlers { func NewHandlers(path string, st *state.State) *Handlers {
@ -33,6 +32,7 @@ func NewHandlers(path string, st *state.State) *Handlers {
Path: path, Path: path,
St: st, St: st,
}, },
accountFileHandler: utils.NewAccountFileHandler(path + "_data"),
} }
} }
@ -56,12 +56,12 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r
func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
f, err := os.OpenFile(fp, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) err := h.accountFileHandler.EnsureFileExists()
if err != nil { if err != nil {
return res, err return res, err
} }
f.Close()
accountResp, err := server.CreateAccount() accountResp, err := server.CreateAccount()
if err != nil { if err != nil {
fmt.Println("Failed to create account:", err) fmt.Println("Failed to create account:", err)
@ -75,15 +75,11 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
"Status": "PENDING", "Status": "PENDING",
} }
jsonData, err := json.Marshal(accountData) err = h.accountFileHandler.WriteAccountData(accountData)
Alfred-mk marked this conversation as resolved Outdated
Outdated
Review

should not be necessary to set the flag when it already has been set and persisted. That will reduce one file access call each run.

should not be necessary to set the flag when it already has been set and persisted. That will reduce one file access call each run.
if err != nil { if err != nil {
return res, err return res, err
} }
err = os.WriteFile(fp, jsonData, 0644)
if err != nil {
return res, err
}
res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATED) res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATED)
return res, err return res, err
} }
@ -93,27 +89,15 @@ 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) { func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
accountPIN := string(input) accountPIN := string(input)
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
accountData["AccountPIN"] = accountPIN accountData["AccountPIN"] = accountPIN
updatedJsonData, err := json.Marshal(accountData) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -123,15 +107,8 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -159,27 +136,16 @@ func codeFromCtx(ctx context.Context) string {
//SaveFirstname updates the first name in a JSON data file with the provided input. //SaveFirstname updates the first name in a JSON data file with the provided input.
func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
if len(input) > 0 { if len(input) > 0 {
name := string(input) name := string(input)
accountData["FirstName"] = name accountData["FirstName"] = name
updatedJsonData, err := json.Marshal(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -191,28 +157,16 @@ func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte)
//SaveFamilyname updates the family name in a JSON data file with the provided input. //SaveFamilyname updates the family name in a JSON data file with the provided input.
func (h *Handlers) SaveFamilyname(cxt context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) SaveFamilyname(cxt context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
if len(input) > 0 { if len(input) > 0 {
//Save name
secondname := string(input) secondname := string(input)
accountData["FamilyName"] = secondname accountData["FamilyName"] = secondname
updatedJsonData, err := json.Marshal(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -224,26 +178,18 @@ func (h *Handlers) SaveFamilyname(cxt context.Context, sym string, input []byte)
//SaveYOB updates the Year of Birth(YOB) in a JSON data file with the provided input. //SaveYOB updates the Year of Birth(YOB) in a JSON data file with the provided input.
func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil {
return res, err
}
yob := string(input)
if len(yob) > 4 {
yob := string(input)
accountData["YOB"] = yob
updatedJsonData, err := json.Marshal(accountData)
if err != nil { if err != nil {
Alfred-mk marked this conversation as resolved Outdated
Outdated
Review

I prefer putting regexes like this on top of the file as a const.

I prefer putting regexes like this on top of the file as a const.
return res, err return res, err
} }
err = os.WriteFile(fp, updatedJsonData, 0644) yob := string(input)
if len(yob) > 4 {
yob := string(input)
accountData["YOB"] = yob
err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -255,29 +201,20 @@ func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resou
//SaveLocation updates the location in a JSON data file with the provided input. //SaveLocation updates the location in a JSON data file with the provided input.
func (h *Handlers) SaveLocation(cxt context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) SaveLocation(cxt context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
if len(input) > 0 { if len(input) > 0 {
location := string(input) location := string(input)
accountData["Location"] = location accountData["Location"] = location
updatedJsonData, err := json.Marshal(accountData)
err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil {
return res, err
}
} }
return res, nil return res, nil
@ -286,16 +223,12 @@ func (h *Handlers) SaveLocation(cxt context.Context, sym string, input []byte) (
//SaveGender updates the gender in a JSON data file 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) { func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
if len(input) > 0 { if len(input) > 0 {
gender := string(input) gender := string(input)
@ -308,12 +241,8 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
gender = "Other" gender = "Other"
} }
accountData["Gender"] = gender accountData["Gender"] = gender
updatedJsonData, err := json.Marshal(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -324,24 +253,17 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
//SaveOfferings updates the offerings(goods and services provided by the user) in a JSON data file 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) { func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
if len(input) > 0 { if len(input) > 0 {
offerings := string(input) offerings := string(input)
accountData["Offerings"] = offerings accountData["Offerings"] = offerings
updatedJsonData, err := json.Marshal(accountData)
if err != nil { err = h.accountFileHandler.WriteAccountData(accountData)
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -363,15 +285,8 @@ func (h *Handlers) ResetAccountUnlocked(ctx context.Context, sym string, input [
func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -384,15 +299,8 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte
func (h *Handlers) Unlock(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) Unlock(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
pin := string(input) pin := string(input)
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
Outdated
Review

Please change to "Unspecified"

Please change to "Unspecified"
return res, err return res, err
} }
@ -422,18 +330,12 @@ func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []by
func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil { if err != nil {
return res, err return res, err
} }
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil {
return res, err
}
status, err := server.CheckAccountStatus(accountData["TrackingId"]) status, err := server.CheckAccountStatus(accountData["TrackingId"])
if err != nil { if err != nil {
@ -451,12 +353,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
res.FlagSet = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING) res.FlagSet = append(res.FlagReset, models.USERFLAG_ACCOUNT_PENDING)
} }
updatedJsonData, err := json.Marshal(accountData) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -500,16 +397,11 @@ func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []by
func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data" accountData, err := h.accountFileHandler.ReadAccountData()
jsonData, err := os.ReadFile(fp)
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
balance, err := server.CheckBalance(accountData["PublicKey"]) balance, err := server.CheckBalance(accountData["PublicKey"])
if err != nil { if err != nil {
return res, nil return res, nil
@ -523,15 +415,7 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
res := resource.Result{} res := resource.Result{}
recipient := string(input) recipient := string(input)
fp := h.fs.Path + "_data" accountData, err := h.accountFileHandler.ReadAccountData()
jsonData, err := os.ReadFile(fp)
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -547,12 +431,7 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
accountData["Recipient"] = recipient accountData["Recipient"] = recipient
updatedJsonData, err := json.Marshal(accountData) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -563,15 +442,7 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data" accountData, err := h.accountFileHandler.ReadAccountData()
jsonData, err := os.ReadFile(fp)
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -579,12 +450,7 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
// reset the recipient // reset the recipient
accountData["Recipient"] = "" accountData["Recipient"] = ""
updatedJsonData, err := json.Marshal(accountData) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -596,15 +462,7 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data" accountData, err := h.accountFileHandler.ReadAccountData()
jsonData, err := os.ReadFile(fp)
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -612,12 +470,7 @@ func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input
// reset the amount // reset the amount
accountData["Amount"] = "" accountData["Amount"] = ""
updatedJsonData, err := json.Marshal(accountData) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -640,15 +493,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
res := resource.Result{} res := resource.Result{}
amount := string(input) amount := string(input)
fp := h.fs.Path + "_data" accountData, err := h.accountFileHandler.ReadAccountData()
jsonData, err := os.ReadFile(fp)
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -666,12 +511,7 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
accountData["Amount"] = amount accountData["Amount"] = amount
updatedJsonData, err := json.Marshal(accountData) err = h.accountFileHandler.WriteAccountData(accountData)
if err != nil {
return res, err
}
err = os.WriteFile(fp, updatedJsonData, 0644)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -684,15 +524,8 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -705,15 +538,8 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (
// GetProfileInfo retrieves and formats the profile information of a user from a JSON data file. // GetProfileInfo retrieves and formats the profile information of a user from a JSON data file.
func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -748,15 +574,8 @@ func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte)
// GetSender retrieves the public key from a JSON data file. // GetSender retrieves the public key from a JSON data file.
func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -768,15 +587,8 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res
func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
res := resource.Result{} res := resource.Result{}
fp := h.fs.Path + "_data"
jsonData, err := os.ReadFile(fp) accountData, err := h.accountFileHandler.ReadAccountData()
if err != nil {
return res, err
}
var accountData map[string]string
err = json.Unmarshal(jsonData, &accountData)
if err != nil { if err != nil {
return res, err return res, err
} }

View File

@ -0,0 +1,46 @@
package utils
import (
"encoding/json"
"os"
)
type AccountFileHandler struct {
FilePath string
}
func NewAccountFileHandler(path string) *AccountFileHandler {
return &AccountFileHandler{FilePath: path}
}
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) 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) 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()
}