Compare commits

...

32 Commits

Author SHA1 Message Date
2b9c6d641e
Merge branch 'master' into copy-language-code 2025-01-10 11:06:32 +03:00
1f0568df32 Merge pull request 'Implement connstring handling' (#247) from lash/purify-more into master
Reviewed-on: #247
2025-01-09 13:03:28 +01:00
lash
24c513d4f0 Merge branch 'master' into lash/purify-more 2025-01-09 12:02:17 +00:00
b3fd6f5c1a Merge pull request 'Rename handler/ussd package' (#254) from konstantinmds/ussd:refactor/24-rename-ussd-to-application into master
Reviewed-on: #254
2025-01-09 13:01:19 +01:00
5734011f96 refactor: rename ussd package to application (#24)
- Rename internal/handlers/ussd directory to application
- Update all imports and references to use new package name
2025-01-08 13:40:00 +01:00
lash
379d98ccd5 Merge branch 'master' into lash/purify-more 2025-01-08 12:32:11 +00:00
4d7589ad95 Merge branch 'master' into lash/purify-more 2025-01-08 13:07:50 +01:00
lash
721f80d0f2
Repalce missing context 2025-01-08 07:34:22 +00:00
6339f0c2e5 Merge branch 'master' into lash/purify-more 2025-01-07 17:58:19 +01:00
lash
1fa830f286
Add auth conn string to ssh, use connstr for execs 2025-01-07 13:51:26 +00:00
lash
599815c343
Fix remaining conflict in cmd cli 2025-01-06 09:00:41 +00:00
lash
462c0d7677 Merge branch 'master' into lash/purify-more 2025-01-06 08:59:42 +00:00
lash
02823fd64e Merge branch 'lash/ssh-fixes' into lash/purify-more 2025-01-06 08:47:49 +00:00
lash
cd575c2edb Merge remote-tracking branch 'urdt' into lash/purify-more 2025-01-06 08:46:01 +00:00
lash
52fd1eced2
Enable env, config, db in ssh 2025-01-06 08:11:37 +00:00
lash
5c7a535288 Merge branch 'lash/purify-more' into lash/ssh-fixes 2025-01-06 07:55:40 +00:00
lash
cc2f7b41df Merge branch 'master' into lash/purify-more 2025-01-06 07:50:55 +00:00
lash
d39740a09a
Edit ssh cli help text 2025-01-06 07:41:24 +00:00
lash
51b6fc0dde
Remove unused methods in storage interfaces, improve logs 2025-01-04 21:13:39 +00:00
lash
cc9760125a
Remove unnecessary connection chain step 2025-01-04 21:02:08 +00:00
lash
3a9f3fa373
Update env example 2025-01-04 20:54:51 +00:00
lash
89c21847b9
Improve error message 2025-01-04 20:52:49 +00:00
lash
450dfa02cc
Refactor to use conndata as menustorageservice conn arg 2025-01-04 20:36:18 +00:00
lash
f61e65f4fe
Rename accountservice testservice source file 2025-01-04 13:24:14 +00:00
lash
a4d6cef9c0
Remove commented code 2025-01-04 13:21:31 +00:00
lash
2992f7ae8e
Update executables with new conn str 2025-01-04 13:19:30 +00:00
lash
dc61d05584
WIP revert connstr gdbm to dir only, add file as table spec 2025-01-04 12:16:28 +00:00
lash
e92e498726 Merge branch 'lash/purify' into lash/purify-more 2025-01-04 09:46:18 +00:00
lash
c3cbe1cd92
Add connstr to last executable 2025-01-04 09:41:24 +00:00
lash
418080d093 Merge branch 'lash/purify' into lash/purify-more 2025-01-04 09:38:23 +00:00
lash
2e30739ec9
Implement connstr 2025-01-04 09:37:12 +00:00
lash
dc1674ec55
WIP add connection string parser 2025-01-04 08:40:43 +00:00
22 changed files with 433 additions and 250 deletions

View File

@ -6,13 +6,9 @@ HOST=127.0.0.1
AT_ENDPOINT=/ussd/africastalking
#PostgreSQL
DB_HOST=localhost
DB_USER=postgres
DB_PASSWORD=strongpass
DB_NAME=urdt_ussd
DB_PORT=5432
DB_SSLMODE=disable
DB_TIMEZONE=Africa/Nairobi
DB_CONN=postgres://postgres:strongpass@localhost:5432/urdt_ussd
#DB_TIMEZONE=Africa/Nairobi
#DB_SCHEMA=vise
#External API Calls
CUSTODIAL_URL_BASE=http://localhost:5003

View File

@ -20,7 +20,6 @@ import (
"git.grassecon.net/urdt/ussd/initializers"
"git.grassecon.net/urdt/ussd/internal/handlers"
"git.grassecon.net/urdt/ussd/internal/http/at"
httpserver "git.grassecon.net/urdt/ussd/internal/http/at"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/remote"
"git.grassecon.net/urdt/ussd/internal/args"
@ -36,21 +35,23 @@ var (
func init() {
initializers.LoadEnvVariables()
}
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
var err error
var gettextDir string
var langs args.LangVar
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&connStr, "c", "", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
@ -59,7 +60,16 @@ func main() {
flag.Var(&langs, "language", "add symbol resolution for language")
flag.Parse()
logg.Infof("start command", "build", build, "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
if connStr != "" {
connStr = config.DbConn
}
connData, err := storage.ToConnData(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
logg.Infof("start command", "build", build, "conn", connData, "resourcedir", resourceDir, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -83,14 +93,13 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
rs, err := menuStorageService.GetResource(ctx)
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
@ -136,7 +145,7 @@ func main() {
rp := &at.ATRequestParser{}
bsh := handlers.NewBaseSessionHandler(cfg, rs, stateStore, userdataStore, rp, hl)
sh := httpserver.NewATSessionHandler(bsh)
sh := at.NewATSessionHandler(bsh)
mux := http.NewServeMux()
mux.Handle(initializers.GetEnv("AT_ENDPOINT", "/"), sh)

View File

@ -48,20 +48,21 @@ func (p *asyncRequestParser) GetInput(r any) ([]byte, error) {
func main() {
config.LoadConfig()
var connStr string
var sessionId string
var dbDir string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
var err error
var gettextDir string
var langs args.LangVar
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.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&connStr, "c", "", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
@ -70,7 +71,16 @@ func main() {
flag.Var(&langs, "language", "add symbol resolution for language")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId)
if connStr != "" {
connStr = config.DbConn
}
connData, err := storage.ToConnData(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
logg.Infof("start command", "conn", connData, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -95,18 +105,18 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
userdataStore, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -38,18 +38,19 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var resourceDir string
var size uint
var database string
var engineDebug bool
var host string
var port uint
var err error
var gettextDir string
var langs args.LangVar
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&connStr, "c", "", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", initializers.GetEnv("HOST", "127.0.0.1"), "http host")
@ -58,7 +59,16 @@ func main() {
flag.Var(&langs, "language", "add symbol resolution for language")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
if connStr != "" {
connStr = config.DbConn
}
connData, err := storage.ToConnData(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
logg.Infof("start command", "conn", connData, "resourcedir", resourceDir, "outputsize", size)
ctx := context.Background()
ctx = context.WithValue(ctx, "Database", database)
@ -83,19 +93,14 @@ func main() {
cfg.EngineDebug = true
}
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = menuStorageService.EnsureDbDir()
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
userdataStore, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())

View File

@ -33,23 +33,35 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var size uint
var sessionId string
var database string
var engineDebug bool
var resourceDir string
var err error
var gettextDir string
var langs args.LangVar
flag.StringVar(&resourceDir, "resourcedir", scriptDir, "resource dir")
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", "", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory")
flag.Var(&langs, "language", "add symbol resolution for language")
flag.Parse()
logg.Infof("start command", "dbdir", dbDir, "outputsize", size)
if connStr != "" {
connStr = config.DbConn
}
connData, err := storage.ToConnData(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
logg.Infof("start command", "conn", connData, "outputsize", size)
if len(langs.Langs()) == 0 {
langs.Set(config.DefaultLanguage)
@ -76,18 +88,12 @@ func main() {
MenuSeparator: menuSeparator,
}
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
if gettextDir != "" {
menuStorageService = menuStorageService.WithGettext(gettextDir, langs.Langs())
}
err = menuStorageService.EnsureDbDir()
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())

View File

@ -14,7 +14,10 @@ import (
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/urdt/ussd/config"
"git.grassecon.net/urdt/ussd/initializers"
"git.grassecon.net/urdt/ussd/internal/ssh"
"git.grassecon.net/urdt/ussd/internal/storage"
)
var (
@ -26,25 +29,49 @@ var (
build = "dev"
)
func init() {
initializers.LoadEnvVariables()
}
func main() {
var dbDir string
config.LoadConfig()
var connStr string
var authConnStr string
var resourceDir string
var size uint
var engineDebug bool
var stateDebug bool
var host string
var port uint
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", "", "connection string")
flag.StringVar(&authConnStr, "authdb", "", "auth connection string")
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
flag.BoolVar(&engineDebug, "engine-debug", false, "use engine debug output")
flag.BoolVar(&stateDebug, "state-debug", false, "use engine debug output")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.UintVar(&size, "s", 160, "max size of output")
flag.StringVar(&host, "h", "127.0.0.1", "http host")
flag.UintVar(&port, "p", 7122, "http port")
flag.StringVar(&host, "h", "127.0.0.1", "socket host")
flag.UintVar(&port, "p", 7122, "socket port")
flag.Parse()
if connStr == "" {
connStr = config.DbConn
}
if authConnStr == "" {
authConnStr = connStr
}
connData, err := storage.ToConnData(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
authConnData, err := storage.ToConnData(authConnStr)
if err != nil {
fmt.Fprintf(os.Stderr, "auth connstr err: %v", err)
os.Exit(1)
}
sshKeyFile := flag.Arg(0)
_, err := os.Stat(sshKeyFile)
_, err = os.Stat(sshKeyFile)
if err != nil {
fmt.Fprintf(os.Stderr, "cannot open ssh server private key file: %v\n", err)
os.Exit(1)
@ -57,7 +84,7 @@ func main() {
logg.WarnCtxf(ctx, "!!!!! Do not expose to internet and only use with tunnel!")
logg.WarnCtxf(ctx, "!!!!! (See ssh -L <...>)")
logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size, "keyfile", sshKeyFile, "host", host, "port", port)
logg.Infof("start command", "conn", connData, "authconn", authConnData, "resourcedir", resourceDir, "outputsize", size, "keyfile", sshKeyFile, "host", host, "port", port)
pfp := path.Join(scriptDir, "pp.csv")
@ -73,7 +100,7 @@ func main() {
cfg.EngineDebug = true
}
authKeyStore, err := ssh.NewSshKeyStore(ctx, dbDir)
authKeyStore, err := ssh.NewSshKeyStore(ctx, authConnData.String())
if err != nil {
fmt.Fprintf(os.Stderr, "keystore file open error: %v", err)
os.Exit(1)
@ -92,10 +119,10 @@ func main() {
signal.Notify(cterm, os.Interrupt, syscall.SIGTERM)
runner := &ssh.SshRunner{
Cfg: cfg,
Debug: engineDebug,
FlagFile: pfp,
DbDir: dbDir,
Cfg: cfg,
Debug: engineDebug,
FlagFile: pfp,
Conn: connData,
ResourceDir: resourceDir,
SrvKeyFile: sshKeyFile,
Host: host,

View File

@ -23,17 +23,17 @@ type StorageServices interface {
GetPersister(ctx context.Context) (*persist.Persister, error)
GetUserdataDb(ctx context.Context) (db.Db, error)
GetResource(ctx context.Context) (resource.Resource, error)
EnsureDbDir() error
}
type StorageService struct {
svc *storage.MenuStorageService
}
func NewStorageService(dbDir string) *StorageService {
return &StorageService{
svc: storage.NewMenuStorageService(dbDir, ""),
func NewStorageService(conn storage.ConnData) (*StorageService, error) {
svc := &StorageService{
svc: storage.NewMenuStorageService(conn, ""),
}
return svc, nil
}
func(ss *StorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
@ -47,7 +47,3 @@ func(ss *StorageService) GetUserdataDb(ctx context.Context) (db.Db, error) {
func(ss *StorageService) GetResource(ctx context.Context) (resource.Resource, error) {
return nil, errors.New("not implemented")
}
func(ss *StorageService) EnsureDbDir() error {
return ss.svc.EnsureDbDir()
}

View File

@ -40,6 +40,7 @@ var (
VoucherTransfersURL string
VoucherDataURL string
CheckAliasURL string
DbConn string
DefaultLanguage string
Languages []string
)
@ -69,14 +70,20 @@ func setBase() error {
dataURLBase = initializers.GetEnv("DATA_URL_BASE", "http://localhost:5006")
BearerToken = initializers.GetEnv("BEARER_TOKEN", "")
_, err = url.JoinPath(custodialURLBase, "/foo")
_, err = url.Parse(custodialURLBase)
if err != nil {
return err
}
_, err = url.JoinPath(dataURLBase, "/bar")
_, err = url.Parse(dataURLBase)
if err != nil {
return err
}
return nil
}
func setConn() error {
DbConn = initializers.GetEnv("DB_CONN", "")
return nil
}
@ -86,6 +93,10 @@ func LoadConfig() error {
if err != nil {
return err
}
err = setConn()
if err != nil {
return err
}
err = setLanguage()
if err != nil {
return err

View File

@ -37,23 +37,34 @@ func formatItem(k []byte, v []byte) (string, error) {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", ".state", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.Parse()
if connStr != "" {
connStr = config.DbConn
}
connData, err := storage.ToConnData(config.DbConn)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
logg.Infof("start command", "conn", connData)
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", database)
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
store, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {

View File

@ -28,24 +28,35 @@ func init() {
func main() {
config.LoadConfig()
var dbDir string
var connStr string
var sessionId string
var database string
var engineDebug bool
var err error
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.StringVar(&connStr, "c", "", "connection string")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.Parse()
if connStr != "" {
connStr = config.DbConn
}
connData, err := storage.ToConnData(config.DbConn)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
logg.Infof("start command", "conn", connData)
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", database)
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
store, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())

View File

@ -1,4 +1,4 @@
package ussd
package application
import (
"bytes"

View File

@ -1,4 +1,4 @@
package ussd
package application
import (
"context"

View File

@ -6,46 +6,46 @@ import (
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/internal/handlers/ussd"
"git.grassecon.net/urdt/ussd/internal/handlers/application"
"git.grassecon.net/urdt/ussd/internal/storage"
)
type BaseSessionHandler struct {
cfgTemplate engine.Config
rp RequestParser
rs resource.Resource
hn *ussd.Handlers
provider storage.StorageProvider
rp RequestParser
rs resource.Resource
hn *application.Handlers
provider storage.StorageProvider
}
func NewBaseSessionHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp RequestParser, hn *ussd.Handlers) *BaseSessionHandler {
func NewBaseSessionHandler(cfg engine.Config, rs resource.Resource, stateDb db.Db, userdataDb db.Db, rp RequestParser, hn *application.Handlers) *BaseSessionHandler {
return &BaseSessionHandler{
cfgTemplate: cfg,
rs: rs,
hn: hn,
rp: rp,
provider: storage.NewSimpleStorageProvider(stateDb, userdataDb),
rs: rs,
hn: hn,
rp: rp,
provider: storage.NewSimpleStorageProvider(stateDb, userdataDb),
}
}
func(f* BaseSessionHandler) Shutdown() {
func (f *BaseSessionHandler) Shutdown() {
err := f.provider.Close()
if err != nil {
logg.Errorf("handler shutdown error", "err", err)
}
}
func(f *BaseSessionHandler) GetEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
func (f *BaseSessionHandler) GetEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
en := engine.NewEngine(cfg, rs)
en = en.WithPersister(pr)
return en
}
func(f *BaseSessionHandler) Process(rqs RequestSession) (RequestSession, error) {
func (f *BaseSessionHandler) Process(rqs RequestSession) (RequestSession, error) {
var r bool
var err error
var ok bool
logg.InfoCtxf(rqs.Ctx, "new request", "data", rqs)
rqs.Storage, err = f.provider.Get(rqs.Config.SessionId)
@ -84,25 +84,25 @@ func(f *BaseSessionHandler) Process(rqs RequestSession) (RequestSession, error)
return rqs, err
}
rqs.Continue = r
rqs.Continue = r
return rqs, nil
}
func(f *BaseSessionHandler) Output(rqs RequestSession) (RequestSession, error) {
func (f *BaseSessionHandler) Output(rqs RequestSession) (RequestSession, error) {
var err error
_, err = rqs.Engine.Flush(rqs.Ctx, rqs.Writer)
return rqs, err
}
func(f *BaseSessionHandler) Reset(rqs RequestSession) (RequestSession, error) {
func (f *BaseSessionHandler) Reset(rqs RequestSession) (RequestSession, error) {
defer f.provider.Put(rqs.Config.SessionId, rqs.Storage)
return rqs, rqs.Engine.Finish()
}
func(f *BaseSessionHandler) GetConfig() engine.Config {
func (f *BaseSessionHandler) GetConfig() engine.Config {
return f.cfgTemplate
}
func(f *BaseSessionHandler) GetRequestParser() RequestParser {
func (f *BaseSessionHandler) GetRequestParser() RequestParser {
return f.rp
}

View File

@ -10,13 +10,13 @@ import (
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/internal/handlers/ussd"
"git.grassecon.net/urdt/ussd/internal/handlers/application"
"git.grassecon.net/urdt/ussd/internal/utils"
"git.grassecon.net/urdt/ussd/remote"
)
type HandlerService interface {
GetHandler() (*ussd.Handlers, error)
GetHandler() (*application.Handlers, error)
}
func getParser(fp string, debug bool) (*asm.FlagParser, error) {
@ -64,73 +64,73 @@ func (ls *LocalHandlerService) SetDataStore(db *db.Db) {
ls.UserdataStore = db
}
func (ls *LocalHandlerService) GetHandler(accountService remote.AccountServiceInterface) (*ussd.Handlers, error) {
func (ls *LocalHandlerService) GetHandler(accountService remote.AccountServiceInterface) (*application.Handlers, error) {
replaceSeparatorFunc := func(input string) string {
return strings.ReplaceAll(input, ":", ls.Cfg.MenuSeparator)
}
ussdHandlers, err := ussd.NewHandlers(ls.Parser, *ls.UserdataStore, ls.AdminStore, accountService, replaceSeparatorFunc)
appHandlers, err := application.NewHandlers(ls.Parser, *ls.UserdataStore, ls.AdminStore, accountService, replaceSeparatorFunc)
if err != nil {
return nil, err
}
ussdHandlers = ussdHandlers.WithPersister(ls.Pe)
ls.DbRs.AddLocalFunc("set_language", ussdHandlers.SetLanguage)
ls.DbRs.AddLocalFunc("create_account", ussdHandlers.CreateAccount)
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)
ls.DbRs.AddLocalFunc("quit", ussdHandlers.Quit)
ls.DbRs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance)
ls.DbRs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient)
ls.DbRs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset)
ls.DbRs.AddLocalFunc("invite_valid_recipient", ussdHandlers.InviteValidRecipient)
ls.DbRs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount)
ls.DbRs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount)
ls.DbRs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount)
ls.DbRs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient)
ls.DbRs.AddLocalFunc("get_sender", ussdHandlers.GetSender)
ls.DbRs.AddLocalFunc("get_amount", ussdHandlers.GetAmount)
ls.DbRs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin)
ls.DbRs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname)
ls.DbRs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname)
ls.DbRs.AddLocalFunc("save_gender", ussdHandlers.SaveGender)
ls.DbRs.AddLocalFunc("save_location", ussdHandlers.SaveLocation)
ls.DbRs.AddLocalFunc("save_yob", ussdHandlers.SaveYob)
ls.DbRs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings)
ls.DbRs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized)
ls.DbRs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate)
ls.DbRs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo)
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("verify_new_pin", ussdHandlers.VerifyNewPin)
ls.DbRs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange)
ls.DbRs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp)
ls.DbRs.AddLocalFunc("fetch_community_balance", ussdHandlers.FetchCommunityBalance)
ls.DbRs.AddLocalFunc("set_default_voucher", ussdHandlers.SetDefaultVoucher)
ls.DbRs.AddLocalFunc("check_vouchers", ussdHandlers.CheckVouchers)
ls.DbRs.AddLocalFunc("get_vouchers", ussdHandlers.GetVoucherList)
ls.DbRs.AddLocalFunc("view_voucher", ussdHandlers.ViewVoucher)
ls.DbRs.AddLocalFunc("set_voucher", ussdHandlers.SetVoucher)
ls.DbRs.AddLocalFunc("get_voucher_details", ussdHandlers.GetVoucherDetails)
ls.DbRs.AddLocalFunc("reset_valid_pin", ussdHandlers.ResetValidPin)
ls.DbRs.AddLocalFunc("check_pin_mismatch", ussdHandlers.CheckBlockedNumPinMisMatch)
ls.DbRs.AddLocalFunc("validate_blocked_number", ussdHandlers.ValidateBlockedNumber)
ls.DbRs.AddLocalFunc("retrieve_blocked_number", ussdHandlers.RetrieveBlockedNumber)
ls.DbRs.AddLocalFunc("reset_unregistered_number", ussdHandlers.ResetUnregisteredNumber)
ls.DbRs.AddLocalFunc("reset_others_pin", ussdHandlers.ResetOthersPin)
ls.DbRs.AddLocalFunc("save_others_temporary_pin", ussdHandlers.SaveOthersTemporaryPin)
ls.DbRs.AddLocalFunc("get_current_profile_info", ussdHandlers.GetCurrentProfileInfo)
ls.DbRs.AddLocalFunc("check_transactions", ussdHandlers.CheckTransactions)
ls.DbRs.AddLocalFunc("get_transactions", ussdHandlers.GetTransactionsList)
ls.DbRs.AddLocalFunc("view_statement", ussdHandlers.ViewTransactionStatement)
ls.DbRs.AddLocalFunc("update_all_profile_items", ussdHandlers.UpdateAllProfileItems)
ls.DbRs.AddLocalFunc("set_back", ussdHandlers.SetBack)
ls.DbRs.AddLocalFunc("show_blocked_account", ussdHandlers.ShowBlockedAccount)
appHandlers = appHandlers.WithPersister(ls.Pe)
ls.DbRs.AddLocalFunc("set_language", appHandlers.SetLanguage)
ls.DbRs.AddLocalFunc("create_account", appHandlers.CreateAccount)
ls.DbRs.AddLocalFunc("save_temporary_pin", appHandlers.SaveTemporaryPin)
ls.DbRs.AddLocalFunc("verify_create_pin", appHandlers.VerifyCreatePin)
ls.DbRs.AddLocalFunc("check_identifier", appHandlers.CheckIdentifier)
ls.DbRs.AddLocalFunc("check_account_status", appHandlers.CheckAccountStatus)
ls.DbRs.AddLocalFunc("authorize_account", appHandlers.Authorize)
ls.DbRs.AddLocalFunc("quit", appHandlers.Quit)
ls.DbRs.AddLocalFunc("check_balance", appHandlers.CheckBalance)
ls.DbRs.AddLocalFunc("validate_recipient", appHandlers.ValidateRecipient)
ls.DbRs.AddLocalFunc("transaction_reset", appHandlers.TransactionReset)
ls.DbRs.AddLocalFunc("invite_valid_recipient", appHandlers.InviteValidRecipient)
ls.DbRs.AddLocalFunc("max_amount", appHandlers.MaxAmount)
ls.DbRs.AddLocalFunc("validate_amount", appHandlers.ValidateAmount)
ls.DbRs.AddLocalFunc("reset_transaction_amount", appHandlers.ResetTransactionAmount)
ls.DbRs.AddLocalFunc("get_recipient", appHandlers.GetRecipient)
ls.DbRs.AddLocalFunc("get_sender", appHandlers.GetSender)
ls.DbRs.AddLocalFunc("get_amount", appHandlers.GetAmount)
ls.DbRs.AddLocalFunc("reset_incorrect", appHandlers.ResetIncorrectPin)
ls.DbRs.AddLocalFunc("save_firstname", appHandlers.SaveFirstname)
ls.DbRs.AddLocalFunc("save_familyname", appHandlers.SaveFamilyname)
ls.DbRs.AddLocalFunc("save_gender", appHandlers.SaveGender)
ls.DbRs.AddLocalFunc("save_location", appHandlers.SaveLocation)
ls.DbRs.AddLocalFunc("save_yob", appHandlers.SaveYob)
ls.DbRs.AddLocalFunc("save_offerings", appHandlers.SaveOfferings)
ls.DbRs.AddLocalFunc("reset_account_authorized", appHandlers.ResetAccountAuthorized)
ls.DbRs.AddLocalFunc("reset_allow_update", appHandlers.ResetAllowUpdate)
ls.DbRs.AddLocalFunc("get_profile_info", appHandlers.GetProfileInfo)
ls.DbRs.AddLocalFunc("verify_yob", appHandlers.VerifyYob)
ls.DbRs.AddLocalFunc("reset_incorrect_date_format", appHandlers.ResetIncorrectYob)
ls.DbRs.AddLocalFunc("initiate_transaction", appHandlers.InitiateTransaction)
ls.DbRs.AddLocalFunc("verify_new_pin", appHandlers.VerifyNewPin)
ls.DbRs.AddLocalFunc("confirm_pin_change", appHandlers.ConfirmPinChange)
ls.DbRs.AddLocalFunc("quit_with_help", appHandlers.QuitWithHelp)
ls.DbRs.AddLocalFunc("fetch_community_balance", appHandlers.FetchCommunityBalance)
ls.DbRs.AddLocalFunc("set_default_voucher", appHandlers.SetDefaultVoucher)
ls.DbRs.AddLocalFunc("check_vouchers", appHandlers.CheckVouchers)
ls.DbRs.AddLocalFunc("get_vouchers", appHandlers.GetVoucherList)
ls.DbRs.AddLocalFunc("view_voucher", appHandlers.ViewVoucher)
ls.DbRs.AddLocalFunc("set_voucher", appHandlers.SetVoucher)
ls.DbRs.AddLocalFunc("get_voucher_details", appHandlers.GetVoucherDetails)
ls.DbRs.AddLocalFunc("reset_valid_pin", appHandlers.ResetValidPin)
ls.DbRs.AddLocalFunc("check_pin_mismatch", appHandlers.CheckBlockedNumPinMisMatch)
ls.DbRs.AddLocalFunc("validate_blocked_number", appHandlers.ValidateBlockedNumber)
ls.DbRs.AddLocalFunc("retrieve_blocked_number", appHandlers.RetrieveBlockedNumber)
ls.DbRs.AddLocalFunc("reset_unregistered_number", appHandlers.ResetUnregisteredNumber)
ls.DbRs.AddLocalFunc("reset_others_pin", appHandlers.ResetOthersPin)
ls.DbRs.AddLocalFunc("save_others_temporary_pin", appHandlers.SaveOthersTemporaryPin)
ls.DbRs.AddLocalFunc("get_current_profile_info", appHandlers.GetCurrentProfileInfo)
ls.DbRs.AddLocalFunc("check_transactions", appHandlers.CheckTransactions)
ls.DbRs.AddLocalFunc("get_transactions", appHandlers.GetTransactionsList)
ls.DbRs.AddLocalFunc("view_statement", appHandlers.ViewTransactionStatement)
ls.DbRs.AddLocalFunc("update_all_profile_items", appHandlers.UpdateAllProfileItems)
ls.DbRs.AddLocalFunc("set_back", appHandlers.SetBack)
ls.DbRs.AddLocalFunc("show_blocked_account", appHandlers.ShowBlockedAccount)
return ussdHandlers, nil
return appHandlers, nil
}
// TODO: enable setting of sessionId on engine init time

View File

@ -41,6 +41,7 @@ func NewAuther(ctx context.Context, keyStore *SshKeyStore) *auther {
}
func(a *auther) Check(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
logg.TraceCtxf(a.Ctx, "looking for publickey", "pubkey", fmt.Sprintf("%x", pubKey))
va, err := a.keyStore.Get(a.Ctx, pubKey)
if err != nil {
return nil, err
@ -71,6 +72,20 @@ func(a *auther) Get(k []byte) (string, error) {
return v, nil
}
type SshRunner struct {
Ctx context.Context
Cfg engine.Config
FlagFile string
Conn storage.ConnData
ResourceDir string
Debug bool
SrvKeyFile string
Host string
Port uint
wg sync.WaitGroup
lst net.Listener
}
func(s *SshRunner) serve(ctx context.Context, sessionId string, ch ssh.NewChannel, en engine.Engine) error {
if ch == nil {
return errors.New("nil channel")
@ -128,32 +143,13 @@ func(s *SshRunner) serve(ctx context.Context, sessionId string, ch ssh.NewChanne
return nil
}
type SshRunner struct {
Ctx context.Context
Cfg engine.Config
FlagFile string
DbDir string
ResourceDir string
Debug bool
SrvKeyFile string
Host string
Port uint
wg sync.WaitGroup
lst net.Listener
}
func(s *SshRunner) Stop() error {
return s.lst.Close()
}
func(s *SshRunner) GetEngine(sessionId string) (engine.Engine, func(), error) {
ctx := s.Ctx
menuStorageService := storage.NewMenuStorageService(s.DbDir, s.ResourceDir)
err := menuStorageService.EnsureDbDir()
if err != nil {
return nil, nil, err
}
menuStorageService := storage.NewMenuStorageService(s.Conn, s.ResourceDir)
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
@ -208,6 +204,7 @@ func(s *SshRunner) GetEngine(sessionId string) (engine.Engine, func(), error) {
// adapted example from crypto/ssh package, NewServerConn doc
func(s *SshRunner) Run(ctx context.Context, keyStore *SshKeyStore) {
s.Ctx = ctx
running := true
// TODO: waitgroup should probably not be global

69
internal/storage/parse.go Normal file
View File

@ -0,0 +1,69 @@
package storage
import (
"fmt"
"net/url"
"path"
)
const (
DBTYPE_MEM = iota
DBTYPE_GDBM
DBTYPE_POSTGRES
)
type ConnData struct {
typ int
str string
}
func (cd *ConnData) DbType() int {
return cd.typ
}
func (cd *ConnData) String() string {
return cd.str
}
func probePostgres(s string) (string, bool) {
v, err := url.Parse(s)
if err != nil {
return "", false
}
if v.Scheme != "postgres" {
return "", false
}
return s, true
}
func probeGdbm(s string) (string, bool) {
if !path.IsAbs(s) {
return "", false
}
s = path.Clean(s)
return s, true
}
func ToConnData(connStr string) (ConnData, error) {
var o ConnData
if connStr == "" {
return o, nil
}
v, ok := probePostgres(connStr)
if ok {
o.typ = DBTYPE_POSTGRES
o.str = v
return o, nil
}
v, ok = probeGdbm(connStr)
if ok {
o.typ = DBTYPE_GDBM
o.str = v
return o, nil
}
return o, fmt.Errorf("invalid connection string: %s", connStr)
}

View File

@ -0,0 +1,28 @@
package storage
import (
"testing"
)
func TestParseConnStr(t *testing.T) {
_, err := ToConnData("postgres://foo:bar@localhost:5432/baz")
if err != nil {
t.Fatal(err)
}
_, err = ToConnData("/foo/bar")
if err != nil {
t.Fatal(err)
}
_, err = ToConnData("/foo/bar/")
if err != nil {
t.Fatal(err)
}
_, err = ToConnData("foo/bar")
if err == nil {
t.Fatalf("expected error")
}
_, err = ToConnData("http://foo/bar")
if err == nil {
t.Fatalf("expected error")
}
}

View File

@ -13,7 +13,6 @@ import (
"git.defalsify.org/vise.git/logging"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/urdt/ussd/initializers"
gdbmstorage "git.grassecon.net/urdt/ussd/internal/storage/db/gdbm"
)
@ -25,11 +24,10 @@ type StorageService interface {
GetPersister(ctx context.Context) (*persist.Persister, error)
GetUserdataDb(ctx context.Context) db.Db
GetResource(ctx context.Context) (resource.Resource, error)
EnsureDbDir() error
}
type MenuStorageService struct {
dbDir string
conn ConnData
resourceDir string
poResource resource.Resource
resourceStore db.Db
@ -37,29 +35,45 @@ type MenuStorageService struct {
userDataStore db.Db
}
func buildConnStr() string {
host := initializers.GetEnv("DB_HOST", "localhost")
user := initializers.GetEnv("DB_USER", "postgres")
password := initializers.GetEnv("DB_PASSWORD", "")
dbName := initializers.GetEnv("DB_NAME", "")
port := initializers.GetEnv("DB_PORT", "5432")
connString := fmt.Sprintf(
"postgres://%s:%s@%s:%s/%s",
user, password, host, port, dbName,
)
logg.Debugf("pg conn string", "conn", connString)
return connString
}
func NewMenuStorageService(dbDir string, resourceDir string) *MenuStorageService {
func NewMenuStorageService(conn ConnData, resourceDir string) *MenuStorageService {
return &MenuStorageService{
dbDir: dbDir,
conn: conn,
resourceDir: resourceDir,
}
}
func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, section string) (db.Db, error) {
var newDb db.Db
var err error
if existingDb != nil {
return existingDb, nil
}
connStr := ms.conn.String()
dbTyp := ms.conn.DbType()
if dbTyp == DBTYPE_POSTGRES {
newDb = postgres.NewPgDb()
} else if dbTyp == DBTYPE_GDBM {
err = ms.ensureDbDir()
if err != nil {
return nil, err
}
connStr = path.Join(connStr, section)
newDb = gdbmstorage.NewThreadGdbmDb()
} else {
return nil, fmt.Errorf("unsupported connection string: '%s'\n", ms.conn.String())
}
logg.DebugCtxf(ctx, "connecting to db", "conn", connStr)
err = newDb.Connect(ctx, connStr)
if err != nil {
return nil, err
}
return newDb, nil
}
// WithGettext triggers use of gettext for translation of templates and menus.
//
// The first language in `lns` will be used as default language, to resolve node keys to
@ -82,36 +96,6 @@ func (ms *MenuStorageService) WithGettext(path string, lns []lang.Language) *Men
return ms
}
func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.Db, fileName string) (db.Db, error) {
database, ok := ctx.Value("Database").(string)
if !ok {
return nil, fmt.Errorf("failed to select the database")
}
if existingDb != nil {
return existingDb, nil
}
var newDb db.Db
var err error
if database == "postgres" {
newDb = postgres.NewPgDb()
connStr := buildConnStr()
err = newDb.Connect(ctx, connStr)
} else {
newDb = gdbmstorage.NewThreadGdbmDb()
storeFile := path.Join(ms.dbDir, fileName)
err = newDb.Connect(ctx, storeFile)
}
if err != nil {
return nil, err
}
return newDb, nil
}
func (ms *MenuStorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
stateStore, err := ms.GetStateStore(ctx)
if err != nil {
@ -166,8 +150,8 @@ func (ms *MenuStorageService) GetStateStore(ctx context.Context) (db.Db, error)
return ms.stateStore, nil
}
func (ms *MenuStorageService) EnsureDbDir() error {
err := os.MkdirAll(ms.dbDir, 0700)
func (ms *MenuStorageService) ensureDbDir() error {
err := os.MkdirAll(ms.conn.String(), 0700)
if err != nil {
return fmt.Errorf("state dir create exited with error: %v\n", err)
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"time"
"git.defalsify.org/vise.git/engine"
@ -27,7 +28,6 @@ var (
func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", "gdbm")
pfp := path.Join(scriptDir, "pp.csv")
var eventChannel = make(chan bool)
@ -39,37 +39,40 @@ func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
FlagCount: uint32(128),
}
dbDir := ".test_state"
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
err := menuStorageService.EnsureDbDir()
connStr, err := filepath.Abs(".test_state/state.gdbm")
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
os.Exit(1)
}
conn, err := storage.ToConnData(connStr)
if err != nil {
fmt.Fprintf(os.Stderr, "connstr parse err: %v", err)
os.Exit(1)
}
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(conn, resourceDir)
rs, err := menuStorageService.GetResource(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
fmt.Fprintf(os.Stderr, "resource error: %v", err)
os.Exit(1)
}
pe, err := menuStorageService.GetPersister(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
fmt.Fprintf(os.Stderr, "persister error: %v", err)
os.Exit(1)
}
userDataStore, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
fmt.Fprintf(os.Stderr, "userdb error: %v", err)
os.Exit(1)
}
dbResource, ok := rs.(*resource.DbResource)
if !ok {
fmt.Fprintf(os.Stderr, err.Error())
fmt.Fprintf(os.Stderr, "dbresource cast error")
os.Exit(1)
}

View File

@ -0,0 +1,15 @@
package testutil
import (
"testing"
)
func TestCreateEngine(t *testing.T) {
o, clean, eventC := TestEngine("foo")
defer clean()
defer func() {
<-eventC
close(eventC)
}()
_ = o
}

View File

@ -7,6 +7,7 @@ import (
"log"
"math/rand"
"os"
"path/filepath"
"regexp"
"testing"
@ -17,7 +18,6 @@ import (
var (
testData = driver.ReadData()
testStore = ".test_state"
sessionID string
src = rand.NewSource(42)
g = rand.New(src)
@ -25,6 +25,11 @@ var (
var groupTestFile = flag.String("test-file", "group_test.json", "The test file to use for running the group tests")
func testStore() string {
v, _ := filepath.Abs(".test_state/state.gdbm")
return v
}
func GenerateSessionId() string {
uu := uuid.NewGenWithOptions(uuid.WithRandomReader(g))
v, err := uu.NewV4()
@ -81,8 +86,8 @@ func extractSendAmount(response []byte) string {
func TestMain(m *testing.M) {
sessionID = GenerateSessionId()
defer func() {
if err := os.RemoveAll(testStore); err != nil {
log.Fatalf("Failed to delete state store %s: %v", testStore, err)
if err := os.RemoveAll(testStore()); err != nil {
log.Fatalf("Failed to delete state store %s: %v", testStore(), err)
}
}()
m.Run()