diff --git a/cmd/africastalking/main.go b/cmd/africastalking/main.go index c0db723..3e17d81 100644 --- a/cmd/africastalking/main.go +++ b/cmd/africastalking/main.go @@ -98,21 +98,22 @@ func main() { cfg.EngineDebug = true } - menuStorageService := storage.MenuStorageService{} + resourceDir := scriptDir + menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir) - rs, err := menuStorageService.GetResource(scriptDir, ctx) + rs, err := menuStorageService.GetResource(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - err = menuStorageService.EnsureDbDir(dbDir) + err = menuStorageService.EnsureDbDir() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdataStore := menuStorageService.GetUserdataDb(dbDir, ctx) + userdataStore := menuStorageService.GetUserdataDb(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -138,7 +139,7 @@ func main() { os.Exit(1) } - stateStore, err := menuStorageService.GetStateStore(dbDir, ctx) + stateStore, err := menuStorageService.GetStateStore(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) diff --git a/cmd/async/main.go b/cmd/async/main.go index 2ff0d1e..8d50e4a 100644 --- a/cmd/async/main.go +++ b/cmd/async/main.go @@ -71,20 +71,21 @@ func main() { cfg.EngineDebug = true } - menuStorageService := storage.MenuStorageService{} - rs, err := menuStorageService.GetResource(scriptDir, ctx) + resourceDir := scriptDir + menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir) + rs, err := menuStorageService.GetResource(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - err = menuStorageService.EnsureDbDir(dbDir) + err = menuStorageService.EnsureDbDir() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdataStore := menuStorageService.GetUserdataDb(dbDir, ctx) + userdataStore := menuStorageService.GetUserdataDb(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -105,7 +106,7 @@ func main() { os.Exit(1) } - stateStore, err := menuStorageService.GetStateStore(dbDir, ctx) + stateStore, err := menuStorageService.GetStateStore(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) diff --git a/cmd/http/main.go b/cmd/http/main.go index 7b74e19..a9e7d00 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -59,20 +59,21 @@ func main() { cfg.EngineDebug = true } - menuStorageService := storage.MenuStorageService{} - rs, err := menuStorageService.GetResource(scriptDir, ctx) + resourceDir := scriptDir + menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir) + rs, err := menuStorageService.GetResource(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - err = menuStorageService.EnsureDbDir(dbDir) + err = menuStorageService.EnsureDbDir() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdataStore := menuStorageService.GetUserdataDb(dbDir, ctx) + userdataStore := menuStorageService.GetUserdataDb(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) diff --git a/cmd/main.go b/cmd/main.go index 26ffe3a..2a2f896 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -43,27 +43,28 @@ func main() { FlagCount: uint32(16), } - menuStorageService := storage.MenuStorageService{} + resourceDir := scriptDir + menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir) - err := menuStorageService.EnsureDbDir(dbDir) + err := menuStorageService.EnsureDbDir() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - rs, err := menuStorageService.GetResource(scriptDir, ctx) + rs, err := menuStorageService.GetResource(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - pe, err := menuStorageService.GetPersister(dbDir, ctx) + pe, err := menuStorageService.GetPersister(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdatastore := menuStorageService.GetUserdataDb(dbDir, ctx) + userdatastore := menuStorageService.GetUserdataDb(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -76,8 +77,8 @@ func main() { } lhs, err := handlers.NewLocalHandlerService(pfp, true, dbResource, cfg, rs) - lhs.WithDataStore(&userdatastore) - lhs.WithPersister(pe) + lhs.SetDataStore(&userdatastore) + lhs.SetPersister(pe) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) diff --git a/cmd/ssh/main.go b/cmd/ssh/main.go index f973dff..5728aa6 100644 --- a/cmd/ssh/main.go +++ b/cmd/ssh/main.go @@ -2,6 +2,8 @@ package main import ( "context" + "encoding/hex" + "errors" "flag" "fmt" "log" @@ -16,55 +18,75 @@ import ( "git.defalsify.org/vise.git/engine" "git.defalsify.org/vise.git/logging" "git.defalsify.org/vise.git/resource" + "git.defalsify.org/vise.git/state" gdbmdb "git.defalsify.org/vise.git/db/gdbm" "git.grassecon.net/urdt/ussd/internal/handlers" "git.grassecon.net/urdt/ussd/internal/storage" - "git.grassecon.net/urdt/ussd/internal/handlers/ussd" ) var ( wg sync.WaitGroup - auth map[string]string keyStore db.Db logg = logging.NewVanilla() scriptDir = path.Join("services", "registration") ) type auther struct { - SessionId string Ctx context.Context + auth map[string]string +} + +func NewAuther(ctx context.Context) *auther { + return &auther{ + Ctx: ctx, + auth: make(map[string]string), + } } func(a *auther) Check(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) { + keyStore.SetLanguage(nil) keyStore.SetPrefix(storage.DATATYPE_CUSTOM) k := append([]byte{0x01}, pubKey.Marshal()...) v, err := keyStore.Get(a.Ctx, k) if err != nil { return nil, err } - a.SessionId = string(v) - fmt.Fprintf(os.Stderr, "connect: %s\n", a.SessionId) + ka := hex.EncodeToString(conn.SessionID()) + va := string(v) + a.auth[ka] = va + fmt.Fprintf(os.Stderr, "connect: %s -> %s\n", ka, v) return nil, nil } -func populateAuth() { - auth = make(map[string]string) - pubKey, _, _, rest, err := ssh.ParseAuthorizedKey([]byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCu5rYCxMBsVAL1TEkMQgmElAYEZj5zYDdyHjUxZ6qzHBOZD9GAzdxx9GyQDx2vdYm3329tLH/69ky1YA3nUz8SnJGBD6hC5XrqwN6zo9R9oOHAKTwiPGhey2NTVmheP+9XNHukBnOlkkWOQlpDDvMbWOztaZOWDaA8OIeP0t6qzFqLyelyg65lxzM3BKd7bCmmfzl/64BcP1MotAmB9DUxmY0Wb4Q2hYZfNYBx50Z4xthTgKV+Xoo8CbTduKotIz6hluQGvWdtxlCJQEiZ2f4RYY87JSA6/BAH2fhxuLHMXRpzocJNqARqCWpdcTGSg7bzxbKvTFH9OU4wZtr9ie40OR4zsc1lOBZL0rnp8GLkG8ZmeBQrgEDlmR9TTlz4okgtL+c5TCS37rjZYVjmtGwihws0EL9+wyv2dSQibirklC4wK5eWHKXl5vab19qzw/qRLdoRBK40DxbRKggxA7gqSsKrmrf+z7CuLIz/kxF+169FBLbh1MfBOGdx1awm6aU= lash@furioso")) - if err != nil { - panic(err) +func(a *auther) FromConn(c *ssh.ServerConn) (string, error) { + if c == nil { + return "", errors.New("nil server conn") } - auth[string(pubKey.Marshal())] = "+25113243546" - _ = rest + if c.Conn == nil { + return "", errors.New("nil underlying conn") + } + return a.Get(c.Conn.SessionID()) } -func serve(ch ssh.NewChannel) { + +func(a *auther) Get(k []byte) (string, error) { + ka := hex.EncodeToString(k) + v, ok := a.auth[ka] + if !ok { + return "", errors.New("not found") + } + return v, nil +} + +// TODO: where should the session id be uniquely embedded +func serve(ctx context.Context, sessionId string, ch ssh.NewChannel, mss *storage.MenuStorageService, lhs *handlers.LocalHandlerService) error { if ch == nil { - return + return errors.New("nil channel") } if ch.ChannelType() != "session" { ch.Reject(ssh.UnknownChannelType, "that is not the channel you are looking for") - return + return errors.New("not a session") } channel, requests, err := ch.Accept() if err != nil { @@ -80,19 +102,65 @@ func serve(ch ssh.NewChannel) { _ = requests }(requests) - n, err := channel.Write([]byte("foobarbaz\n")) + pe, err := mss.GetPersister(ctx) if err != nil { - panic(err) + return fmt.Errorf("cannot get persister: %v", err) } - log.Printf("wrote %d", n) + lhs.SetPersister(pe) + lhs.Cfg.SessionId = sessionId + + hl, err := lhs.GetHandler() + if err != nil { + return fmt.Errorf("cannot get handler: %v", err) + } + + en := lhs.GetEngine() + en = en.WithFirst(hl.Init) + en = en.WithDebug(nil) + defer en.Finish() + + cont, err := en.Exec(ctx, []byte{}) + if err != nil { + return fmt.Errorf("initial engine exec err: %v", err) + } + + var input [state.INPUT_LIMIT]byte + for cont { + c, err := en.Flush(ctx, channel) + if err != nil { + return fmt.Errorf("flush err: %v", err) + } + _, err = channel.Write([]byte{0x0a}) + if err != nil { + return fmt.Errorf("newline err: %v", err) + } + c, err = channel.Read(input[:]) + if err != nil { + return fmt.Errorf("read input fail: %v", err) + } + logg.TraceCtxf(ctx, "input read", "c", c, "input", input[:c-1]) + cont, err = en.Exec(ctx, input[:c-1]) + if err != nil { + return fmt.Errorf("engine exec err: %v", err) + } + logg.TraceCtxf(ctx, "exec cont", "cont", cont, "en", en) + _ = c + } + c, err := en.Flush(ctx, channel) + if err != nil { + return fmt.Errorf("last flush err: %v", err) + } + _ = c + return nil } -func sshRun(ctx context.Context, hl *ussd.Handlers) { +func sshRun(ctx context.Context, mss *storage.MenuStorageService, lhs *handlers.LocalHandlerService) { running := true defer wg.Wait() - auth := auther{Ctx: ctx} + // TODO: must set ServerConn.Conn.SessionId to phone sessionid + auth := NewAuther(ctx) cfg := ssh.ServerConfig{ PublicKeyCallback: auth.Check, } @@ -118,23 +186,31 @@ func sshRun(ctx context.Context, hl *ussd.Handlers) { panic(err) } + go func(conn net.Conn) { defer conn.Close() for true { srvConn, nC, rC, err := ssh.NewServerConn(conn, &cfg) if err != nil { - log.Printf("rejected client: %v", err) + logg.InfoCtxf(ctx, "rejected client", "err", err) + return } - log.Printf("haveconn %v", srvConn) + logg.DebugCtxf(ctx, "ssh client connected", "conn", srvConn) wg.Add(1) go func() { ssh.DiscardRequests(rC) wg.Done() }() - + + sessionId, err := auth.FromConn(srvConn) + if err != nil { + logg.ErrorCtxf(ctx, "Cannot find authentication") + return + } for ch := range nC { - serve(ch) + err = serve(ctx, sessionId, ch, mss, lhs) + logg.ErrorCtxf(ctx, "ssh server finish", "err", err) } } }(conn) @@ -149,7 +225,6 @@ func sshLoadKeys(ctx context.Context, dbDir string) error { if err != nil { return err } - //auth[string(pubKey.Marshal())] = "+25113243546" k := append([]byte{0x01}, pubKey.Marshal()...) keyStore.SetPrefix(storage.DATATYPE_CUSTOM) return keyStore.Put(ctx, k, []byte("+25113243546")) @@ -189,52 +264,37 @@ func main() { cfg.EngineDebug = true } - menuStorageService := storage.MenuStorageService{} - rs, err := menuStorageService.GetResource(scriptDir, ctx) + mss := storage.NewMenuStorageService(dbDir, resourceDir) + rs, err := mss.GetResource(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - err = menuStorageService.EnsureDbDir(dbDir) + err = mss.EnsureDbDir() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - userdataStore := menuStorageService.GetUserdataDb(dbDir, 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(pfp, true, dbResource, cfg, rs) - lhs.WithDataStore(&userdataStore) - + userdataStore := mss.GetUserdataDb(ctx) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - hl, err := lhs.GetHandler() + lhs, err := handlers.NewLocalHandlerService(pfp, engineDebug, dbResource, cfg, rs) + lhs.SetDataStore(&userdataStore) + + err = sshLoadKeys(ctx, dbDir) if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - stateStore, err := menuStorageService.GetStateStore(dbDir, ctx) - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - defer stateStore.Close() - - sshLoadKeys(ctx, dbDir) - sshRun(ctx, hl) + sshRun(ctx, mss, lhs) } diff --git a/internal/handlers/handlerservice.go b/internal/handlers/handlerservice.go index 93c5a10..1d6f5fd 100644 --- a/internal/handlers/handlerservice.go +++ b/internal/handlers/handlerservice.go @@ -44,62 +44,63 @@ func NewLocalHandlerService(fp string, debug bool, dbResource *resource.DbResour }, nil } -func (localHandlerService *LocalHandlerService) WithPersister(Pe *persist.Persister) { - localHandlerService.Pe = Pe +func (ls *LocalHandlerService) SetPersister(Pe *persist.Persister) { + ls.Pe = Pe } -func (localHandlerService *LocalHandlerService) WithDataStore(db *db.Db) { - localHandlerService.UserdataStore = db +func (ls *LocalHandlerService) SetDataStore(db *db.Db) { + ls.UserdataStore = db } -func (localHandlerService *LocalHandlerService) GetHandler() (*ussd.Handlers, error) { - ussdHandlers, err := ussd.NewHandlers(localHandlerService.Parser, *localHandlerService.UserdataStore) +func (ls *LocalHandlerService) GetHandler() (*ussd.Handlers, error) { + ussdHandlers, err := ussd.NewHandlers(ls.Parser, *ls.UserdataStore) if err != nil { return nil, err } - ussdHandlers = ussdHandlers.WithPersister(localHandlerService.Pe) - localHandlerService.DbRs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) - localHandlerService.DbRs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) - localHandlerService.DbRs.AddLocalFunc("save_pin", ussdHandlers.SavePin) - localHandlerService.DbRs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) - localHandlerService.DbRs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) - localHandlerService.DbRs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) - localHandlerService.DbRs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) - localHandlerService.DbRs.AddLocalFunc("quit", ussdHandlers.Quit) - localHandlerService.DbRs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) - localHandlerService.DbRs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) - localHandlerService.DbRs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) - localHandlerService.DbRs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) - localHandlerService.DbRs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) - localHandlerService.DbRs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) - localHandlerService.DbRs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) - localHandlerService.DbRs.AddLocalFunc("get_sender", ussdHandlers.GetSender) - localHandlerService.DbRs.AddLocalFunc("get_amount", ussdHandlers.GetAmount) - localHandlerService.DbRs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) - localHandlerService.DbRs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) - localHandlerService.DbRs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) - localHandlerService.DbRs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) - localHandlerService.DbRs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) - localHandlerService.DbRs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) - localHandlerService.DbRs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) - localHandlerService.DbRs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) - localHandlerService.DbRs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized) - localHandlerService.DbRs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate) - localHandlerService.DbRs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) - localHandlerService.DbRs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) - localHandlerService.DbRs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) - localHandlerService.DbRs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) - localHandlerService.DbRs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) - localHandlerService.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) - localHandlerService.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) - localHandlerService.DbRs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) - localHandlerService.DbRs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp) + ussdHandlers = ussdHandlers.WithPersister(ls.Pe) + ls.DbRs.AddLocalFunc("set_language", ussdHandlers.SetLanguage) + ls.DbRs.AddLocalFunc("create_account", ussdHandlers.CreateAccount) + ls.DbRs.AddLocalFunc("save_pin", ussdHandlers.SavePin) + ls.DbRs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin) + ls.DbRs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier) + ls.DbRs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus) + ls.DbRs.AddLocalFunc("authorize_account", ussdHandlers.Authorize) + ls.DbRs.AddLocalFunc("quit", ussdHandlers.Quit) + ls.DbRs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance) + ls.DbRs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient) + ls.DbRs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset) + ls.DbRs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount) + ls.DbRs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount) + ls.DbRs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount) + ls.DbRs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient) + ls.DbRs.AddLocalFunc("get_sender", ussdHandlers.GetSender) + ls.DbRs.AddLocalFunc("get_amount", ussdHandlers.GetAmount) + ls.DbRs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin) + ls.DbRs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname) + ls.DbRs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname) + ls.DbRs.AddLocalFunc("save_gender", ussdHandlers.SaveGender) + ls.DbRs.AddLocalFunc("save_location", ussdHandlers.SaveLocation) + ls.DbRs.AddLocalFunc("save_yob", ussdHandlers.SaveYob) + ls.DbRs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings) + ls.DbRs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance) + ls.DbRs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized) + ls.DbRs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate) + ls.DbRs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo) + ls.DbRs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob) + ls.DbRs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob) + ls.DbRs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit) + ls.DbRs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction) + ls.DbRs.AddLocalFunc("save_temporary_pin", ussdHandlers.SaveTemporaryPin) + ls.DbRs.AddLocalFunc("verify_new_pin", ussdHandlers.VerifyNewPin) + ls.DbRs.AddLocalFunc("confirm_pin_change", ussdHandlers.ConfirmPinChange) + ls.DbRs.AddLocalFunc("quit_with_help", ussdHandlers.QuitWithHelp) return ussdHandlers, nil } -func (localHandlerService *LocalHandlerService) GetEngine() *engine.DefaultEngine { - en := engine.NewEngine(localHandlerService.Cfg, localHandlerService.Rs) - en = en.WithPersister(localHandlerService.Pe) +// 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 } diff --git a/internal/storage/storageservice.go b/internal/storage/storageservice.go index a3f50d6..3b622a1 100644 --- a/internal/storage/storageservice.go +++ b/internal/storage/storageservice.go @@ -14,33 +14,42 @@ import ( ) type StorageService interface { - GetPersister(dbDir string, ctx context.Context) (*persist.Persister, error) - GetUserdataDb(dbDir string, ctx context.Context) db.Db - GetResource(resourceDir string, ctx context.Context) (resource.Resource, error) - EnsureDbDir(dbDir string) error + GetPersister(ctx context.Context) (*persist.Persister, error) + GetUserdataDb(ctx context.Context) db.Db + GetResource(ctx context.Context) (resource.Resource, error) + EnsureDbDir() error } -type MenuStorageService struct{} +type MenuStorageService struct{ + dbDir string + resourceDir string +} -func (menuStorageService *MenuStorageService) GetPersister(dbDir string, ctx context.Context) (*persist.Persister, error) { +func NewMenuStorageService(dbDir string, resourceDir string) *MenuStorageService { + return &MenuStorageService{ + dbDir: dbDir, + resourceDir: resourceDir, + } +} + +func (ms *MenuStorageService) GetPersister(ctx context.Context) (*persist.Persister, error) { store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "state.gdbm") + storeFile := path.Join(ms.dbDir, "state.gdbm") store.Connect(ctx, storeFile) pr := persist.NewPersister(store) return pr, nil } -func (menuStorageService *MenuStorageService) GetUserdataDb(dbDir string, ctx context.Context) db.Db { +func (ms *MenuStorageService) GetUserdataDb(ctx context.Context) db.Db { store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "userdata.gdbm") + storeFile := path.Join(ms.dbDir, "userdata.gdbm") store.Connect(ctx, storeFile) - return store } -func (menuStorageService *MenuStorageService) GetResource(resourceDir string, ctx context.Context) (resource.Resource, error) { +func (ms *MenuStorageService) GetResource(ctx context.Context) (resource.Resource, error) { store := fsdb.NewFsDb() - err := store.Connect(ctx, resourceDir) + err := store.Connect(ctx, ms.resourceDir) if err != nil { return nil, err } @@ -48,15 +57,15 @@ func (menuStorageService *MenuStorageService) GetResource(resourceDir string, ct return rfs, nil } -func (menuStorageService *MenuStorageService) GetStateStore(dbDir string, ctx context.Context) (db.Db, error) { +func (ms *MenuStorageService) GetStateStore(ctx context.Context) (db.Db, error) { store := gdbmdb.NewGdbmDb() - storeFile := path.Join(dbDir, "state.gdbm") + storeFile := path.Join(ms.dbDir, "state.gdbm") store.Connect(ctx, storeFile) return store, nil } -func (menuStorageService *MenuStorageService) EnsureDbDir(dbDir string) error { - err := os.MkdirAll(dbDir, 0700) +func (ms *MenuStorageService) EnsureDbDir() error { + err := os.MkdirAll(ms.dbDir, 0700) if err != nil { return fmt.Errorf("state dir create exited with error: %v\n", err) }