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