Compare commits
18 Commits
9ca5091692
...
a7ca280964
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7ca280964 | ||
| 8f5ed0cd4f | |||
|
|
f1664a43a8 | ||
| c29abfe21e | |||
| 9a6d8e5158 | |||
| 3fccfaab61 | |||
|
|
b50a51df9b | ||
|
|
df8c9aab0c | ||
|
|
ddefdd7fb3 | ||
| 4b5f08e25e | |||
| ea9cab930e | |||
| a37f6e6da3 | |||
| f59c3a53ef | |||
| 81c3378ea6 | |||
| 46a6d2bc6e | |||
| c12e867ac3 | |||
| 79de0a9092 | |||
| 3ee15497a5 |
@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/urdt/ussd/internal/utils"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/devtools/admin/commands"
|
"git.grassecon.net/grassrootseconomics/visedriver/devtools/admin/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -1,201 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"path"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
|
||||||
"git.defalsify.org/vise.git/lang"
|
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/config"
|
|
||||||
"git.grassecon.net/urdt/ussd/initializers"
|
|
||||||
"git.grassecon.net/urdt/ussd/handlers"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
|
||||||
"git.grassecon.net/urdt/ussd/remote"
|
|
||||||
"git.grassecon.net/urdt/ussd/request"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/args"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
logg = logging.NewVanilla()
|
|
||||||
scriptDir = path.Join("services", "registration")
|
|
||||||
menuSeparator = ": "
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
initializers.LoadEnvVariables()
|
|
||||||
}
|
|
||||||
|
|
||||||
type asyncRequestParser struct {
|
|
||||||
sessionId string
|
|
||||||
input []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *asyncRequestParser) GetSessionId(ctx context.Context, r any) (string, error) {
|
|
||||||
return p.sessionId, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *asyncRequestParser) GetInput(r any) ([]byte, error) {
|
|
||||||
return p.input, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
config.LoadConfig()
|
|
||||||
|
|
||||||
var connStr string
|
|
||||||
var sessionId 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(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
|
|
||||||
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")
|
|
||||||
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
|
|
||||||
flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory")
|
|
||||||
flag.Var(&langs, "language", "add symbol resolution for language")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
ln, err := lang.LanguageFromCode(config.DefaultLanguage)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "default language set error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
ctx = context.WithValue(ctx, "Language", ln)
|
|
||||||
|
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
|
||||||
|
|
||||||
cfg := engine.Config{
|
|
||||||
Root: "root",
|
|
||||||
OutputSize: uint32(size),
|
|
||||||
FlagCount: uint32(128),
|
|
||||||
MenuSeparator: menuSeparator,
|
|
||||||
}
|
|
||||||
|
|
||||||
if engineDebug {
|
|
||||||
cfg.EngineDebug = true
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
userdataStore, err := menuStorageService.GetUserdataDb(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer userdataStore.Close()
|
|
||||||
|
|
||||||
dbResource, ok := rs.(*resource.DbResource)
|
|
||||||
if !ok {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
|
|
||||||
lhs.SetDataStore(&userdataStore)
|
|
||||||
accountService := remote.AccountService{}
|
|
||||||
|
|
||||||
hl, err := lhs.GetHandler(&accountService)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
stateStore, err := menuStorageService.GetStateStore(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer stateStore.Close()
|
|
||||||
|
|
||||||
rp := &asyncRequestParser{
|
|
||||||
sessionId: sessionId,
|
|
||||||
}
|
|
||||||
sh := handlers.NewBaseSessionHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
|
||||||
cfg.SessionId = sessionId
|
|
||||||
rqs := request.RequestSession{
|
|
||||||
Ctx: ctx,
|
|
||||||
Writer: os.Stdout,
|
|
||||||
Config: cfg,
|
|
||||||
}
|
|
||||||
|
|
||||||
cint := make(chan os.Signal)
|
|
||||||
cterm := make(chan os.Signal)
|
|
||||||
signal.Notify(cint, os.Interrupt, syscall.SIGINT)
|
|
||||||
signal.Notify(cterm, os.Interrupt, syscall.SIGTERM)
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case _ = <-cint:
|
|
||||||
case _ = <-cterm:
|
|
||||||
}
|
|
||||||
sh.Shutdown()
|
|
||||||
}()
|
|
||||||
|
|
||||||
for true {
|
|
||||||
rqs, err = sh.Process(rqs)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "error in process: %v", "err", err)
|
|
||||||
fmt.Errorf("error in process: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
rqs, err = sh.Output(rqs)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "error in output: %v", "err", err)
|
|
||||||
fmt.Errorf("error in output: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
rqs, err = sh.Reset(rqs)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "error in reset: %v", "err", err)
|
|
||||||
fmt.Errorf("error in reset: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
fmt.Println("")
|
|
||||||
_, err = fmt.Scanln(&rqs.Input)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "error in input", "err", err)
|
|
||||||
fmt.Errorf("error in input: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
166
cmd/http/main.go
166
cmd/http/main.go
@ -1,166 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"path"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
|
||||||
"git.defalsify.org/vise.git/lang"
|
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/config"
|
|
||||||
"git.grassecon.net/urdt/ussd/initializers"
|
|
||||||
"git.grassecon.net/urdt/ussd/handlers"
|
|
||||||
httpserver "git.grassecon.net/urdt/ussd/internal/http"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
|
||||||
"git.grassecon.net/urdt/ussd/remote"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/args"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
logg = logging.NewVanilla()
|
|
||||||
scriptDir = path.Join("services", "registration")
|
|
||||||
menuSeparator = ": "
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
initializers.LoadEnvVariables()
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
config.LoadConfig()
|
|
||||||
|
|
||||||
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(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
|
|
||||||
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")
|
|
||||||
flag.UintVar(&port, "p", initializers.GetEnvUint("PORT", 7123), "http port")
|
|
||||||
flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory")
|
|
||||||
flag.Var(&langs, "language", "add symbol resolution for language")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
ln, err := lang.LanguageFromCode(config.DefaultLanguage)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "default language set error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
ctx = context.WithValue(ctx, "Language", ln)
|
|
||||||
|
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
|
||||||
|
|
||||||
cfg := engine.Config{
|
|
||||||
Root: "root",
|
|
||||||
OutputSize: uint32(size),
|
|
||||||
FlagCount: uint32(128),
|
|
||||||
MenuSeparator: menuSeparator,
|
|
||||||
}
|
|
||||||
|
|
||||||
if engineDebug {
|
|
||||||
cfg.EngineDebug = true
|
|
||||||
}
|
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
|
||||||
|
|
||||||
rs, err := menuStorageService.GetResource(ctx)
|
|
||||||
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())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer userdataStore.Close()
|
|
||||||
|
|
||||||
dbResource, ok := rs.(*resource.DbResource)
|
|
||||||
if !ok {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
|
|
||||||
lhs.SetDataStore(&userdataStore)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
accountService := remote.AccountService{}
|
|
||||||
hl, err := lhs.GetHandler(&accountService)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
stateStore, err := menuStorageService.GetStateStore(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer stateStore.Close()
|
|
||||||
|
|
||||||
rp := &httpserver.DefaultRequestParser{}
|
|
||||||
bsh := handlers.NewBaseSessionHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
|
||||||
// TODO: less hacky way of making session handler
|
|
||||||
//sh := request.ToSessionHandler(bsh)
|
|
||||||
sh := &httpserver.SessionHandler{
|
|
||||||
RequestHandler: bsh,
|
|
||||||
}
|
|
||||||
s := &http.Server{
|
|
||||||
Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))),
|
|
||||||
Handler: sh,
|
|
||||||
}
|
|
||||||
s.RegisterOnShutdown(sh.Shutdown)
|
|
||||||
|
|
||||||
cint := make(chan os.Signal)
|
|
||||||
cterm := make(chan os.Signal)
|
|
||||||
signal.Notify(cint, os.Interrupt, syscall.SIGINT)
|
|
||||||
signal.Notify(cterm, os.Interrupt, syscall.SIGTERM)
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case _ = <-cint:
|
|
||||||
case _ = <-cterm:
|
|
||||||
}
|
|
||||||
s.Shutdown(ctx)
|
|
||||||
}()
|
|
||||||
err = s.ListenAndServe()
|
|
||||||
if err != nil {
|
|
||||||
logg.Infof("Server closed with error", "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -10,8 +10,8 @@ import (
|
|||||||
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.defalsify.org/vise.git/lang"
|
"git.defalsify.org/vise.git/lang"
|
||||||
"git.grassecon.net/urdt/ussd/config"
|
"git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
"git.grassecon.net/urdt/ussd/initializers"
|
"git.grassecon.net/grassrootseconomics/visedriver/initializers"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
148
cmd/main.go
148
cmd/main.go
@ -1,148 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
|
||||||
"git.defalsify.org/vise.git/lang"
|
|
||||||
"git.grassecon.net/urdt/ussd/config"
|
|
||||||
"git.grassecon.net/urdt/ussd/handlers"
|
|
||||||
"git.grassecon.net/urdt/ussd/initializers"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/args"
|
|
||||||
"git.grassecon.net/urdt/ussd/remote"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
logg = logging.NewVanilla()
|
|
||||||
scriptDir = path.Join("services", "registration")
|
|
||||||
menuSeparator = ": "
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
initializers.LoadEnvVariables()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: external script automatically generate language handler list from select language vise code OR consider dynamic menu generation script possibility
|
|
||||||
func main() {
|
|
||||||
config.LoadConfig()
|
|
||||||
|
|
||||||
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(&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()
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
|
||||||
ctx = context.WithValue(ctx, "Database", database)
|
|
||||||
|
|
||||||
ln, err := lang.LanguageFromCode(config.DefaultLanguage)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "default language set error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
ctx = context.WithValue(ctx, "Language", ln)
|
|
||||||
|
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
|
||||||
|
|
||||||
cfg := engine.Config{
|
|
||||||
Root: "root",
|
|
||||||
SessionId: sessionId,
|
|
||||||
OutputSize: uint32(size),
|
|
||||||
FlagCount: uint32(128),
|
|
||||||
MenuSeparator: menuSeparator,
|
|
||||||
}
|
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
|
||||||
|
|
||||||
if gettextDir != "" {
|
|
||||||
menuStorageService = menuStorageService.WithGettext(gettextDir, langs.Langs())
|
|
||||||
}
|
|
||||||
|
|
||||||
rs, err := menuStorageService.GetResource(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pe, err := menuStorageService.GetPersister(ctx)
|
|
||||||
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())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
dbResource, ok := rs.(*resource.DbResource)
|
|
||||||
if !ok {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
|
|
||||||
lhs.SetDataStore(&userdatastore)
|
|
||||||
lhs.SetPersister(pe)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
accountService := remote.AccountService{}
|
|
||||||
hl, err := lhs.GetHandler(&accountService)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
en := lhs.GetEngine()
|
|
||||||
en = en.WithFirst(hl.Init)
|
|
||||||
if engineDebug {
|
|
||||||
en = en.WithDebug(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = engine.Loop(ctx, en, os.Stdin, os.Stdout, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# URDT-USSD SSH server
|
|
||||||
|
|
||||||
An SSH server entry point for the vise engine.
|
|
||||||
|
|
||||||
|
|
||||||
## Adding public keys for access
|
|
||||||
|
|
||||||
Map your (client) public key to a session identifier (e.g. phone number)
|
|
||||||
|
|
||||||
```
|
|
||||||
go run -v -tags logtrace ./cmd/ssh/sshkey/main.go -i <session_id> [--dbdir <dbpath>] <client_publickey_filepath>
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Create a private key for the server
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh-keygen -N "" -f <server_privatekey_filepath>
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Run the server
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
go run -v -tags logtrace ./cmd/ssh/main.go -h <host> -p <port> [--dbdir <dbpath>] <server_privatekey_filepath>
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Connect to the server
|
|
||||||
|
|
||||||
```
|
|
||||||
ssh [-v] -T -p <port> -i <client_publickey_filepath> <host>
|
|
||||||
```
|
|
||||||
144
cmd/ssh/main.go
144
cmd/ssh/main.go
@ -1,144 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"path"
|
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
|
||||||
"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 (
|
|
||||||
wg sync.WaitGroup
|
|
||||||
keyStore db.Db
|
|
||||||
logg = logging.NewVanilla()
|
|
||||||
scriptDir = path.Join("services", "registration")
|
|
||||||
|
|
||||||
build = "dev"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
initializers.LoadEnvVariables()
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
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(&connStr, "c", "", "connection string")
|
|
||||||
flag.StringVar(&authConnStr, "authdb", "", "auth connection string")
|
|
||||||
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
|
|
||||||
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", "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)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "cannot open ssh server private key file: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
logg.WarnCtxf(ctx, "!!!!! WARNING WARNING WARNING")
|
|
||||||
logg.WarnCtxf(ctx, "!!!!! =======================")
|
|
||||||
logg.WarnCtxf(ctx, "!!!!! This is not a production ready server!")
|
|
||||||
logg.WarnCtxf(ctx, "!!!!! Do not expose to internet and only use with tunnel!")
|
|
||||||
logg.WarnCtxf(ctx, "!!!!! (See ssh -L <...>)")
|
|
||||||
|
|
||||||
logg.Infof("start command", "conn", connData, "authconn", authConnData, "resourcedir", resourceDir, "outputsize", size, "keyfile", sshKeyFile, "host", host, "port", port)
|
|
||||||
|
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
|
||||||
|
|
||||||
cfg := engine.Config{
|
|
||||||
Root: "root",
|
|
||||||
OutputSize: uint32(size),
|
|
||||||
FlagCount: uint32(16),
|
|
||||||
}
|
|
||||||
if stateDebug {
|
|
||||||
cfg.StateDebug = true
|
|
||||||
}
|
|
||||||
if engineDebug {
|
|
||||||
cfg.EngineDebug = true
|
|
||||||
}
|
|
||||||
|
|
||||||
authKeyStore, err := ssh.NewSshKeyStore(ctx, authConnData.String())
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "keystore file open error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
logg.TraceCtxf(ctx, "shutdown auth key store reached")
|
|
||||||
err = authKeyStore.Close()
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "keystore close error", "err", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
cint := make(chan os.Signal)
|
|
||||||
cterm := make(chan os.Signal)
|
|
||||||
signal.Notify(cint, os.Interrupt, syscall.SIGINT)
|
|
||||||
signal.Notify(cterm, os.Interrupt, syscall.SIGTERM)
|
|
||||||
|
|
||||||
runner := &ssh.SshRunner{
|
|
||||||
Cfg: cfg,
|
|
||||||
Debug: engineDebug,
|
|
||||||
FlagFile: pfp,
|
|
||||||
Conn: connData,
|
|
||||||
ResourceDir: resourceDir,
|
|
||||||
SrvKeyFile: sshKeyFile,
|
|
||||||
Host: host,
|
|
||||||
Port: port,
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case _ = <-cint:
|
|
||||||
case _ = <-cterm:
|
|
||||||
}
|
|
||||||
logg.TraceCtxf(ctx, "shutdown runner reached")
|
|
||||||
err := runner.Stop()
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "runner stop error", "err", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}()
|
|
||||||
runner.Run(ctx, authKeyStore)
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/ssh"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var dbDir string
|
|
||||||
var sessionId string
|
|
||||||
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
|
|
||||||
flag.StringVar(&sessionId, "i", "", "session id")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
if sessionId == "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "empty session id\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
sshKeyFile := flag.Arg(0)
|
|
||||||
if sshKeyFile == "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "missing key file argument\n")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
store, err := ssh.NewSshKeyStore(ctx, dbDir)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
defer store.Close()
|
|
||||||
|
|
||||||
err = store.AddFromFile(ctx, sshKeyFile, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,10 +7,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/config"
|
"git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
"git.grassecon.net/urdt/ussd/initializers"
|
"git.grassecon.net/grassrootseconomics/visedriver/initializers"
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
"git.grassecon.net/urdt/ussd/debug"
|
"git.grassecon.net/grassrootseconomics/visedriver/debug"
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
)
|
)
|
||||||
@ -9,14 +9,15 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/urdt/ussd/config"
|
"git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
"git.grassecon.net/urdt/ussd/initializers"
|
"git.grassecon.net/grassrootseconomics/visedriver/initializers"
|
||||||
"git.grassecon.net/urdt/ussd/common"
|
"git.grassecon.net/grassrootseconomics/visedriver/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logg = logging.NewVanilla()
|
logg = logging.NewVanilla()
|
||||||
|
baseDir = testdataloader.GetBasePath()
|
||||||
scriptDir = path.Join("services", "registration")
|
scriptDir = path.Join("services", "registration")
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,7 +25,6 @@ func init() {
|
|||||||
initializers.LoadEnvVariables()
|
initializers.LoadEnvVariables()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
@ -86,5 +86,4 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -7,8 +7,8 @@ import (
|
|||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.defalsify.org/vise.git/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
dbstorage "git.grassecon.net/urdt/ussd/internal/storage/db"
|
dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
dbstorage "git.grassecon.net/urdt/ussd/internal/storage/db"
|
dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db"
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
dbstorage "git.grassecon.net/urdt/ussd/internal/storage/db"
|
dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db"
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
visedb "git.defalsify.org/vise.git/db"
|
visedb "git.defalsify.org/vise.git/db"
|
||||||
memdb "git.defalsify.org/vise.git/db/mem"
|
memdb "git.defalsify.org/vise.git/db/mem"
|
||||||
dbstorage "git.grassecon.net/urdt/ussd/internal/storage/db"
|
dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db"
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/initializers"
|
"git.grassecon.net/grassrootseconomics/visedriver/initializers"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/common"
|
"git.grassecon.net/grassrootseconomics/visedriver/common"
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ package debug
|
|||||||
import (
|
import (
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/common"
|
"git.grassecon.net/grassrootseconomics/visedriver/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package debug
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/common"
|
"git.grassecon.net/grassrootseconomics/visedriver/common"
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package errors
|
package errors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.grassecon.net/urdt/ussd/internal/handlers"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -1,4 +1,4 @@
|
|||||||
module git.grassecon.net/urdt/ussd
|
module git.grassecon.net/grassrootseconomics/visedriver
|
||||||
|
|
||||||
go 1.23.0
|
go 1.23.0
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,10 @@ import (
|
|||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
"git.grassecon.net/urdt/ussd/errors"
|
"git.grassecon.net/grassrootseconomics/visedriver/errors"
|
||||||
"git.grassecon.net/urdt/ussd/internal/handlers/application"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers/application"
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -1,141 +0,0 @@
|
|||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/asm"
|
|
||||||
"git.defalsify.org/vise.git/db"
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
|
||||||
"git.defalsify.org/vise.git/persist"
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
|
||||||
|
|
||||||
"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() (*application.Handlers, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getParser(fp string, debug bool) (*asm.FlagParser, error) {
|
|
||||||
flagParser := asm.NewFlagParser().WithDebug()
|
|
||||||
_, err := flagParser.Load(fp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return flagParser, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type LocalHandlerService struct {
|
|
||||||
Parser *asm.FlagParser
|
|
||||||
DbRs *resource.DbResource
|
|
||||||
Pe *persist.Persister
|
|
||||||
UserdataStore *db.Db
|
|
||||||
AdminStore *utils.AdminStore
|
|
||||||
Cfg engine.Config
|
|
||||||
Rs resource.Resource
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLocalHandlerService(ctx context.Context, fp string, debug bool, dbResource *resource.DbResource, cfg engine.Config, rs resource.Resource) (*LocalHandlerService, error) {
|
|
||||||
parser, err := getParser(fp, debug)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
adminstore, err := utils.NewAdminStore(ctx, "admin_numbers")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &LocalHandlerService{
|
|
||||||
Parser: parser,
|
|
||||||
DbRs: dbResource,
|
|
||||||
AdminStore: adminstore,
|
|
||||||
Cfg: cfg,
|
|
||||||
Rs: rs,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LocalHandlerService) SetPersister(Pe *persist.Persister) {
|
|
||||||
ls.Pe = Pe
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LocalHandlerService) SetDataStore(db *db.Db) {
|
|
||||||
ls.UserdataStore = db
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LocalHandlerService) GetHandler(accountService remote.AccountServiceInterface) (*application.Handlers, error) {
|
|
||||||
replaceSeparatorFunc := func(input string) string {
|
|
||||||
return strings.ReplaceAll(input, ":", ls.Cfg.MenuSeparator)
|
|
||||||
}
|
|
||||||
|
|
||||||
appHandlers, err := application.NewHandlers(ls.Parser, *ls.UserdataStore, ls.AdminStore, accountService, replaceSeparatorFunc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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 appHandlers, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: enable setting of sessionId on engine init time
|
|
||||||
func (ls *LocalHandlerService) GetEngine() *engine.DefaultEngine {
|
|
||||||
en := engine.NewEngine(ls.Cfg, ls.Rs)
|
|
||||||
en = en.WithPersister(ls.Pe)
|
|
||||||
return en
|
|
||||||
}
|
|
||||||
@ -3,24 +3,30 @@ package initializers
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadEnvVariables() {
|
func LoadEnvVariables() {
|
||||||
err := godotenv.Load()
|
LoadEnvVariablesPath(".")
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadEnvVariablesPath(dir string) {
|
||||||
|
fp := path.Join(dir, ".env")
|
||||||
|
err := godotenv.Load(fp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error loading .env file")
|
log.Fatal("Error loading .env file", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to get environment variables with a default fallback
|
// Helper to get environment variables with a default fallback
|
||||||
func GetEnv(key, defaultVal string) string {
|
func GetEnv(key, defaultVal string) string {
|
||||||
if value, exists := os.LookupEnv(key); exists {
|
if value, exists := os.LookupEnv(key); exists {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
return defaultVal
|
return defaultVal
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to safely convert environment variables to uint
|
// Helper to safely convert environment variables to uint
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
package args
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/lang"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LangVar struct {
|
|
||||||
v []lang.Language
|
|
||||||
}
|
|
||||||
|
|
||||||
func(lv *LangVar) Set(s string) error {
|
|
||||||
v, err := lang.LanguageFromCode(s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
lv.v = append(lv.v, v)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func(lv *LangVar) String() string {
|
|
||||||
var s []string
|
|
||||||
for _, v := range(lv.v) {
|
|
||||||
s = append(s, v.Code)
|
|
||||||
}
|
|
||||||
return strings.Join(s, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
func(lv *LangVar) Langs() []lang.Language {
|
|
||||||
return lv.v
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@ import (
|
|||||||
"git.defalsify.org/vise.git/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/handlers"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DefaultRequestParser struct {
|
type DefaultRequestParser struct {
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/handlers"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers"
|
||||||
"git.grassecon.net/urdt/ussd/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -9,9 +9,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
"git.grassecon.net/urdt/ussd/internal/handlers"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/handlers"
|
||||||
"git.grassecon.net/urdt/ussd/testutil/mocks/httpmocks"
|
"git.grassecon.net/grassrootseconomics/visedriver/testutil/mocks/httpmocks"
|
||||||
"git.grassecon.net/urdt/ussd/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
// invalidRequestType is a custom type to test invalid request scenarios
|
// invalidRequestType is a custom type to test invalid request scenarios
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import (
|
|||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
dbstorage "git.grassecon.net/urdt/ussd/internal/storage/db/gdbm"
|
dbstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db/gdbm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SshKeyStore struct {
|
type SshKeyStore struct {
|
||||||
|
|||||||
@ -17,9 +17,9 @@ import (
|
|||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.defalsify.org/vise.git/state"
|
"git.defalsify.org/vise.git/state"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/handlers"
|
"git.grassecon.net/grassrootseconomics/visedriver/handlers"
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
"git.grassecon.net/urdt/ussd/remote"
|
"git.grassecon.net/grassrootseconomics/visedriver/remote"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -1,127 +0,0 @@
|
|||||||
package testutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
|
||||||
"git.grassecon.net/urdt/ussd/handlers"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/testutil/testservice"
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/testutil/testtag"
|
|
||||||
testdataloader "github.com/peteole/testdata-loader"
|
|
||||||
"git.grassecon.net/urdt/ussd/remote"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
baseDir = testdataloader.GetBasePath()
|
|
||||||
logg = logging.NewVanilla()
|
|
||||||
scriptDir = path.Join(baseDir, "services", "registration")
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
|
|
||||||
ctx := context.Background()
|
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
|
||||||
|
|
||||||
var eventChannel = make(chan bool)
|
|
||||||
|
|
||||||
cfg := engine.Config{
|
|
||||||
Root: "root",
|
|
||||||
SessionId: sessionId,
|
|
||||||
OutputSize: uint32(160),
|
|
||||||
FlagCount: uint32(128),
|
|
||||||
}
|
|
||||||
|
|
||||||
connStr, err := filepath.Abs(".test_state/state.gdbm")
|
|
||||||
if err != nil {
|
|
||||||
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, "resource error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pe, err := menuStorageService.GetPersister(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "persister error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
userDataStore, err := menuStorageService.GetUserdataDb(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "userdb error: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
dbResource, ok := rs.(*resource.DbResource)
|
|
||||||
if !ok {
|
|
||||||
fmt.Fprintf(os.Stderr, "dbresource cast error")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
|
|
||||||
lhs.SetDataStore(&userDataStore)
|
|
||||||
lhs.SetPersister(pe)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if testtag.AccountService == nil {
|
|
||||||
testtag.AccountService = &remote.AccountService{}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch testtag.AccountService.(type) {
|
|
||||||
case *testservice.TestAccountService:
|
|
||||||
go func() {
|
|
||||||
eventChannel <- false
|
|
||||||
}()
|
|
||||||
case *remote.AccountService:
|
|
||||||
go func() {
|
|
||||||
time.Sleep(5 * time.Second) // Wait for 5 seconds
|
|
||||||
eventChannel <- true
|
|
||||||
}()
|
|
||||||
default:
|
|
||||||
panic("Unknown account service type")
|
|
||||||
}
|
|
||||||
|
|
||||||
hl, err := lhs.GetHandler(testtag.AccountService)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
en := lhs.GetEngine()
|
|
||||||
en = en.WithFirst(hl.Init)
|
|
||||||
cleanFn := func() {
|
|
||||||
err := en.Finish()
|
|
||||||
if err != nil {
|
|
||||||
logg.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = menuStorageService.Close()
|
|
||||||
if err != nil {
|
|
||||||
logg.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
logg.Infof("testengine storage closed")
|
|
||||||
}
|
|
||||||
return en, cleanFn, eventChannel
|
|
||||||
}
|
|
||||||
@ -3,7 +3,7 @@ package mocks
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/models"
|
"git.grassecon.net/grassrootseconomics/visedriver/models"
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
// +build !online
|
|
||||||
|
|
||||||
package testtag
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.grassecon.net/urdt/ussd/remote"
|
|
||||||
accountservice "git.grassecon.net/urdt/ussd/internal/testutil/testservice"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
AccountService remote.AccountServiceInterface = &accountservice.TestAccountService{}
|
|
||||||
)
|
|
||||||
@ -6,13 +6,11 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/internal/testutil"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/testutil"
|
||||||
"git.grassecon.net/urdt/ussd/internal/testutil/driver"
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/testutil/driver"
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,11 +22,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var groupTestFile = flag.String("test-file", "group_test.json", "The test file to use for running the group tests")
|
var groupTestFile = flag.String("test-file", "group_test.json", "The test file to use for running the group tests")
|
||||||
|
var database = flag.String("db", "gdbm", "Specify the database (gdbm or postgres)")
|
||||||
func testStore() string {
|
var connStr = flag.String("conn", ".test_state", "connection string")
|
||||||
v, _ := filepath.Abs(".test_state/state.gdbm")
|
var dbSchema = flag.String("schema", "test", "Specify the database schema (default test)")
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateSessionId() string {
|
func GenerateSessionId() string {
|
||||||
uu := uuid.NewGenWithOptions(uuid.WithRandomReader(g))
|
uu := uuid.NewGenWithOptions(uuid.WithRandomReader(g))
|
||||||
@ -84,12 +80,15 @@ func extractSendAmount(response []byte) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
|
// Parse the flags
|
||||||
|
flag.Parse()
|
||||||
sessionID = GenerateSessionId()
|
sessionID = GenerateSessionId()
|
||||||
defer func() {
|
// set the db
|
||||||
if err := os.RemoveAll(testStore()); err != nil {
|
testutil.SetDatabase(*database, *connStr, *dbSchema)
|
||||||
log.Fatalf("Failed to delete state store %s: %v", testStore(), err)
|
|
||||||
}
|
// Cleanup the db after tests
|
||||||
}()
|
defer testutil.CleanDatabase()
|
||||||
|
|
||||||
m.Run()
|
m.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +125,6 @@ func TestAccountCreationSuccessful(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
<-eventChannel
|
<-eventChannel
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccountRegistrationRejectTerms(t *testing.T) {
|
func TestAccountRegistrationRejectTerms(t *testing.T) {
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/config"
|
"git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
"git.grassecon.net/urdt/ussd/models"
|
"git.grassecon.net/grassrootseconomics/visedriver/models"
|
||||||
"github.com/grassrootseconomics/eth-custodial/pkg/api"
|
"github.com/grassrootseconomics/eth-custodial/pkg/api"
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"git.defalsify.org/vise.git/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/urdt/ussd/internal/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -15,6 +15,7 @@ const (
|
|||||||
type ConnData struct {
|
type ConnData struct {
|
||||||
typ int
|
typ int
|
||||||
str string
|
str string
|
||||||
|
domain string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cd *ConnData) DbType() int {
|
func (cd *ConnData) DbType() int {
|
||||||
@ -25,23 +26,38 @@ func (cd *ConnData) String() string {
|
|||||||
return cd.str
|
return cd.str
|
||||||
}
|
}
|
||||||
|
|
||||||
func probePostgres(s string) (string, bool) {
|
func (cd *ConnData) Domain() string {
|
||||||
v, err := url.Parse(s)
|
return cd.domain
|
||||||
if err != nil {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
if v.Scheme != "postgres" {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
return s, true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func probeGdbm(s string) (string, bool) {
|
func (cd *ConnData) Path() string {
|
||||||
|
v, _ := url.Parse(cd.str)
|
||||||
|
v.RawQuery = ""
|
||||||
|
return v.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func probePostgres(s string) (string, string, bool) {
|
||||||
|
domain := "public"
|
||||||
|
v, err := url.Parse(s)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
if v.Scheme != "postgres" {
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
vv := v.Query()
|
||||||
|
if vv.Has("search_path") {
|
||||||
|
domain = vv.Get("search_path")
|
||||||
|
}
|
||||||
|
return s, domain, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func probeGdbm(s string) (string, string, bool) {
|
||||||
if !path.IsAbs(s) {
|
if !path.IsAbs(s) {
|
||||||
return "", false
|
return "", "", false
|
||||||
}
|
}
|
||||||
s = path.Clean(s)
|
s = path.Clean(s)
|
||||||
return s, true
|
return s, "", true
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToConnData(connStr string) (ConnData, error) {
|
func ToConnData(connStr string) (ConnData, error) {
|
||||||
@ -51,14 +67,15 @@ func ToConnData(connStr string) (ConnData, error) {
|
|||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
v, ok := probePostgres(connStr)
|
v, domain, ok := probePostgres(connStr)
|
||||||
if ok {
|
if ok {
|
||||||
o.typ = DBTYPE_POSTGRES
|
o.typ = DBTYPE_POSTGRES
|
||||||
o.str = v
|
o.str = v
|
||||||
|
o.domain = domain
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
v, ok = probeGdbm(connStr)
|
v, _, ok = probeGdbm(connStr)
|
||||||
if ok {
|
if ok {
|
||||||
o.typ = DBTYPE_GDBM
|
o.typ = DBTYPE_GDBM
|
||||||
o.str = v
|
o.str = v
|
||||||
@ -13,7 +13,7 @@ import (
|
|||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.defalsify.org/vise.git/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
gdbmstorage "git.grassecon.net/urdt/ussd/internal/storage/db/gdbm"
|
gdbmstorage "git.grassecon.net/grassrootseconomics/visedriver/storage/db/gdbm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -59,7 +59,12 @@ func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.D
|
|||||||
connStr := ms.conn.String()
|
connStr := ms.conn.String()
|
||||||
dbTyp := ms.conn.DbType()
|
dbTyp := ms.conn.DbType()
|
||||||
if dbTyp == DBTYPE_POSTGRES {
|
if dbTyp == DBTYPE_POSTGRES {
|
||||||
newDb = postgres.NewPgDb()
|
// TODO: move to vise
|
||||||
|
err = ensureSchemaExists(ctx, ms.conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
newDb = postgres.NewPgDb().WithSchema(ms.conn.Domain())
|
||||||
} else if dbTyp == DBTYPE_GDBM {
|
} else if dbTyp == DBTYPE_GDBM {
|
||||||
err = ms.ensureDbDir()
|
err = ms.ensureDbDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -70,7 +75,7 @@ func (ms *MenuStorageService) getOrCreateDb(ctx context.Context, existingDb db.D
|
|||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("unsupported connection string: '%s'\n", ms.conn.String())
|
return nil, fmt.Errorf("unsupported connection string: '%s'\n", ms.conn.String())
|
||||||
}
|
}
|
||||||
logg.DebugCtxf(ctx, "connecting to db", "conn", connStr)
|
logg.DebugCtxf(ctx, "connecting to db", "conn", connStr, "conndata", ms.conn)
|
||||||
err = newDb.Connect(ctx, connStr)
|
err = newDb.Connect(ctx, connStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -101,6 +106,23 @@ func (ms *MenuStorageService) WithGettext(path string, lns []lang.Language) *Men
|
|||||||
return ms
|
return ms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensureSchemaExists creates a new schema if it does not exist
|
||||||
|
func ensureSchemaExists(ctx context.Context, conn ConnData) error {
|
||||||
|
h, err := pgxpool.New(ctx, conn.Path())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to connect to the database: %w", err)
|
||||||
|
}
|
||||||
|
defer h.Close()
|
||||||
|
|
||||||
|
query := fmt.Sprintf("CREATE SCHEMA IF NOT EXISTS %s", conn.Domain())
|
||||||
|
_, err = h.Exec(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create schema: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ms *MenuStorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
|
func (ms *MenuStorageService) GetPersister(ctx context.Context) (*persist.Persister, error) {
|
||||||
stateStore, err := ms.GetStateStore(ctx)
|
stateStore, err := ms.GetStateStore(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
209
testutil/engine.go
Normal file
209
testutil/engine.go
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
package testutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
"git.defalsify.org/vise.git/engine"
|
||||||
|
"git.defalsify.org/vise.git/logging"
|
||||||
|
"git.defalsify.org/vise.git/resource"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/initializers"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/handlers"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/testutil/testservice"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/internal/testutil/testtag"
|
||||||
|
testdataloader "github.com/peteole/testdata-loader"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/remote"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
logg = logging.NewVanilla()
|
||||||
|
baseDir = testdataloader.GetBasePath()
|
||||||
|
scriptDir = path.Join(baseDir, "services", "registration")
|
||||||
|
setDbType string
|
||||||
|
setConnStr string
|
||||||
|
setDbSchema string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
initializers.LoadEnvVariablesPath(baseDir)
|
||||||
|
config.LoadConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDatabase updates the database used by TestEngine
|
||||||
|
func SetDatabase(database, connStr, dbSchema string) {
|
||||||
|
setDbType = database
|
||||||
|
setConnStr = connStr
|
||||||
|
setDbSchema = dbSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanDatabase removes all test data from the database
|
||||||
|
func CleanDatabase() {
|
||||||
|
if setDbType == "postgres" {
|
||||||
|
ctx := context.Background()
|
||||||
|
// Update the connection string with the new search path
|
||||||
|
updatedConnStr, err := updateSearchPath(setConnStr, setDbSchema)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to update search path: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbConn, err := pgxpool.New(ctx, updatedConnStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to connect to database for cleanup: %v", err)
|
||||||
|
}
|
||||||
|
defer dbConn.Close()
|
||||||
|
|
||||||
|
query := fmt.Sprintf("DELETE FROM %s.kv_vise;", setDbSchema)
|
||||||
|
_, execErr := dbConn.Exec(ctx, query)
|
||||||
|
if execErr != nil {
|
||||||
|
log.Printf("Failed to cleanup table %s.kv_vise: %v", setDbSchema, execErr)
|
||||||
|
} else {
|
||||||
|
log.Printf("Successfully cleaned up table %s.kv_vise", setDbSchema)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setConnStr, _ := filepath.Abs(setConnStr)
|
||||||
|
if err := os.RemoveAll(setConnStr); err != nil {
|
||||||
|
log.Fatalf("Failed to delete state store %s: %v", setConnStr, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateSearchPath updates the search_path (schema) to be used in the connection
|
||||||
|
func updateSearchPath(connStr string, newSearchPath string) (string, error) {
|
||||||
|
u, err := url.Parse(connStr)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("invalid connection string: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the query parameters
|
||||||
|
q := u.Query()
|
||||||
|
|
||||||
|
// Update or add the search_path parameter
|
||||||
|
q.Set("search_path", newSearchPath)
|
||||||
|
|
||||||
|
// Rebuild the connection string with updated parameters
|
||||||
|
u.RawQuery = q.Encode()
|
||||||
|
|
||||||
|
return u.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
|
||||||
|
var err error
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
||||||
|
pfp := path.Join(scriptDir, "pp.csv")
|
||||||
|
|
||||||
|
var eventChannel = make(chan bool)
|
||||||
|
|
||||||
|
cfg := engine.Config{
|
||||||
|
Root: "root",
|
||||||
|
SessionId: sessionId,
|
||||||
|
OutputSize: uint32(160),
|
||||||
|
FlagCount: uint32(128),
|
||||||
|
}
|
||||||
|
|
||||||
|
if setDbType == "postgres" {
|
||||||
|
setConnStr = config.DbConn
|
||||||
|
setConnStr, err = updateSearchPath(setConnStr, setDbSchema)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setConnStr, err = filepath.Abs(setConnStr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := storage.ToConnData(setConnStr)
|
||||||
|
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, "resource error: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pe, err := menuStorageService.GetPersister(ctx)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "persister error: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
userDataStore, err := menuStorageService.GetUserdataDb(ctx)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "userdb error: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbResource, ok := rs.(*resource.DbResource)
|
||||||
|
if !ok {
|
||||||
|
fmt.Fprintf(os.Stderr, "dbresource cast error")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
|
||||||
|
lhs.SetDataStore(&userDataStore)
|
||||||
|
lhs.SetPersister(pe)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if testtag.AccountService == nil {
|
||||||
|
testtag.AccountService = &remote.AccountService{}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch testtag.AccountService.(type) {
|
||||||
|
case *testservice.TestAccountService:
|
||||||
|
go func() {
|
||||||
|
eventChannel <- false
|
||||||
|
}()
|
||||||
|
case *remote.AccountService:
|
||||||
|
go func() {
|
||||||
|
time.Sleep(5 * time.Second) // Wait for 5 seconds
|
||||||
|
eventChannel <- true
|
||||||
|
}()
|
||||||
|
default:
|
||||||
|
panic("Unknown account service type")
|
||||||
|
}
|
||||||
|
|
||||||
|
hl, err := lhs.GetHandler(testtag.AccountService)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
en := lhs.GetEngine()
|
||||||
|
en = en.WithFirst(hl.Init)
|
||||||
|
cleanFn := func() {
|
||||||
|
err := en.Finish()
|
||||||
|
if err != nil {
|
||||||
|
logg.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = menuStorageService.Close()
|
||||||
|
if err != nil {
|
||||||
|
logg.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
logg.Infof("testengine storage closed")
|
||||||
|
}
|
||||||
|
return en, cleanFn, eventChannel
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
"git.defalsify.org/vise.git/persist"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.grassecon.net/urdt/ussd/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockRequestHandler implements request.RequestHandler interface for testing
|
// MockRequestHandler implements request.RequestHandler interface for testing
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"git.grassecon.net/urdt/ussd/models"
|
"git.grassecon.net/grassrootseconomics/visedriver/models"
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
12
testutil/testtag/offlinetest.go
Normal file
12
testutil/testtag/offlinetest.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// +build !online
|
||||||
|
|
||||||
|
package testtag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/remote"
|
||||||
|
accountservice "git.grassecon.net/grassrootseconomics/visedriver/internal/testutil/testservice"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
AccountService remote.AccountServiceInterface = &accountservice.TestAccountService{}
|
||||||
|
)
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
package testtag
|
package testtag
|
||||||
|
|
||||||
import "git.grassecon.net/urdt/ussd/remote"
|
import "git.grassecon.net/grassrootseconomics/visedriver/remote"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
AccountService remote.AccountServiceInterface
|
AccountService remote.AccountServiceInterface
|
||||||
Loading…
Reference in New Issue
Block a user