Compare commits
158 Commits
reset-acco
...
master
Author | SHA1 | Date | |
---|---|---|---|
e2d5546de1 | |||
95089875bf | |||
4db25055ad | |||
e8e6f0e371 | |||
91c4967efa | |||
7b1824f18c | |||
04c3f5ce65 | |||
e646658f40 | |||
c4cab444ad | |||
b5ade9112e | |||
3b9184e852 | |||
07b85768d1 | |||
c9678df152 | |||
c37fee5e54 | |||
98b2a31655 | |||
d4fcf40b8d | |||
83a10efcd9 | |||
0089d6f125 | |||
a7d13dc7c4 | |||
bed7f58e81 | |||
07fd1110ed | |||
2f1dbb9147 | |||
93f1897321 | |||
c324e29aea | |||
f91056cca2 | |||
7d11377ffd | |||
9a63234470 | |||
fe74dbb848 | |||
278edc7049 | |||
3b03d40279 | |||
4d46133194 | |||
fd84f6ae98 | |||
1e8d5b1b83 | |||
628a57ea10 | |||
a37908323f | |||
|
9c27be3a9d | ||
1190c5b6f2 | |||
b95452ae5f | |||
14df16098c | |||
1cdd5a37ae | |||
6b3b8ffabe | |||
6647416115 | |||
4155b267ee | |||
0f2d6def23 | |||
|
c13768d782 | ||
|
af4b075df3 | ||
|
1d7027905d | ||
|
6c77d04284 | ||
|
12acd508b1 | ||
f88e253486 | |||
68597ea7cc | |||
3d9eeddab8 | |||
df58f69032 | |||
8b999a09a2 | |||
|
fdde1bb979 | ||
|
23cadc6178 | ||
0821241427 | |||
ca71062528 | |||
1918ea37d5 | |||
|
422b651097 | ||
|
861d04dbfd | ||
c78081fb84 | |||
ff3c597158 | |||
09c5f3a14c | |||
f7873bfef7 | |||
815e3b2a25 | |||
f9a9a9b4a6 | |||
04429ab74c | |||
d3f1a14e71 | |||
5722d4f8dd | |||
cad18c9e64 | |||
fbff584bb4 | |||
4169419442 | |||
bef62b97e7 | |||
56d0baad6e | |||
5a586eb67a | |||
6a945f8f20 | |||
39f8c86e8b | |||
73b501c8aa | |||
a6cd4b5fca | |||
d47bc6c241 | |||
dd55906e70 | |||
6fdf3735d0 | |||
b492421851 | |||
128c0162d2 | |||
ebe94c705f | |||
df0c1b3429 | |||
d66fd894bc | |||
28185fc2c5 | |||
d2f75c693a | |||
363c35efed | |||
64a87231ca | |||
0f361a065b | |||
|
4d1045a9f9 | ||
|
f3a6485bb3 | ||
cd37adc288 | |||
6f0994d692 | |||
|
fbaba15776 | ||
|
9a094f440f | ||
6c77ff58ab | |||
c8ddafcf66 | |||
5f1a659789 | |||
0d4be0f7fc | |||
b6161da749 | |||
f1c4d5f1f9 | |||
73b876dbdd | |||
18e865ba26 | |||
d7c909f028 | |||
908a52cda6 | |||
0e480e3d55 | |||
ffea1a0b96 | |||
be5bd16616 | |||
93723616f6 | |||
c9257ba0d6 | |||
caabf4f8af | |||
f884b19012 | |||
526dc822fb | |||
1249e45d54 | |||
|
99d03e3bc9 | ||
|
1e495763f5 | ||
|
5e83c89e03 | ||
|
1909b60bf4 | ||
|
49335a290f | ||
|
2c8e60e1bb | ||
|
4baacb325d | ||
|
c243edd4c4 | ||
44846c5950 | |||
|
592c57b72d | ||
|
341f0b9cc8 | ||
|
1c911ee73f | ||
|
00b9079a55 | ||
ec6b078de3 | |||
0b4fde9d1e | |||
66be350ad1 | |||
|
156511e499 | ||
|
8b68130ed4 | ||
|
7ab8eef623 | ||
7d513ac2a7 | |||
|
b31011b390 | ||
|
358567e52e | ||
|
933943636e | ||
1e69f2167a | |||
|
20feef4103 | ||
|
8d5d3f1dc8 | ||
|
0f54ab4b4a | ||
|
be47c999ca | ||
|
c719db8b92 | ||
|
16cb2846b7 | ||
|
bc2abc2464 | ||
f435046385 | |||
efaf0ab22e | |||
e29bcb5b27 | |||
cdb22f8cbb | |||
|
9cb9e02442 | ||
6aa4bd8906 | |||
|
ab03e6d529 | ||
|
9b66146ef1 | ||
|
825c06c3bb |
16
.dockerignore
Normal file
16
.dockerignore
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
!/args
|
||||||
|
!/cmd/africastalking
|
||||||
|
!/cmd/ssh
|
||||||
|
!/config
|
||||||
|
!/debug
|
||||||
|
!/handlers
|
||||||
|
!/internal
|
||||||
|
!/profile
|
||||||
|
!/services
|
||||||
|
!/ssh
|
||||||
|
!/store
|
||||||
|
!/LICENSE
|
||||||
|
!/README.md
|
||||||
|
!/go.*
|
||||||
|
!/.env.example
|
@ -18,3 +18,6 @@ DATA_URL_BASE=http://localhost:5006
|
|||||||
#Language
|
#Language
|
||||||
DEFAULT_LANGUAGE=eng
|
DEFAULT_LANGUAGE=eng
|
||||||
LANGUAGES=eng, swa
|
LANGUAGES=eng, swa
|
||||||
|
|
||||||
|
#Alias search domains
|
||||||
|
ALIAS_SEARCH_DOMAINS=sarafu.local, sarafu.eth
|
||||||
|
56
.github/workflows/docker.yaml
vendored
Normal file
56
.github/workflows/docker.yaml
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
name: release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Check out repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Cache Docker layers
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-
|
||||||
|
|
||||||
|
- name: Login to GHCR Docker registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set outputs
|
||||||
|
run: |
|
||||||
|
echo "RELEASE_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV \
|
||||||
|
&& echo "RELEASE_SHORT_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: ./
|
||||||
|
file: ./Dockerfile
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
||||||
|
build-args: |
|
||||||
|
BUILD=${{ env.RELEASE_SHORT_COMMIT }}
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||||
|
tags: |
|
||||||
|
ghcr.io/grassrootseconomics/sarafu-vise:latest
|
||||||
|
ghcr.io/grassrootseconomics/sarafu-vise:${{ env.RELEASE_TAG }}
|
50
Dockerfile
Normal file
50
Dockerfile
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
FROM golang:1.23.4-bookworm AS build
|
||||||
|
|
||||||
|
ENV CGO_ENABLED=1
|
||||||
|
|
||||||
|
ARG BUILDPLATFORM
|
||||||
|
ARG TARGETPLATFORM
|
||||||
|
ARG BUILD=dev
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
libgdbm-dev \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN git clone https://git.defalsify.org/vise.git go-vise
|
||||||
|
COPY . ./sarafu-vise
|
||||||
|
|
||||||
|
WORKDIR /build/sarafu-vise/services/registration
|
||||||
|
RUN echo "Compiling go-vise files"
|
||||||
|
RUN make VISE_PATH=/build/go-vise -B
|
||||||
|
|
||||||
|
WORKDIR /build/sarafu-vise
|
||||||
|
RUN echo "Building on $BUILDPLATFORM, building for $TARGETPLATFORM"
|
||||||
|
RUN go mod download
|
||||||
|
RUN go build -tags logtrace,online -o sarafu-at -ldflags="-X main.build=${BUILD} -s -w" cmd/africastalking/main.go
|
||||||
|
RUN go build -tags logtrace,online -o sarafu-ssh -ldflags="-X main.build=${BUILD} -s -w" cmd/ssh/main.go
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
libgdbm-dev \
|
||||||
|
ca-certificates \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /service
|
||||||
|
|
||||||
|
COPY --from=build /build/sarafu-vise/sarafu-at .
|
||||||
|
COPY --from=build /build/sarafu-vise/sarafu-ssh .
|
||||||
|
COPY --from=build /build/sarafu-vise/LICENSE .
|
||||||
|
COPY --from=build /build/sarafu-vise/README.md .
|
||||||
|
COPY --from=build /build/sarafu-vise/services ./services
|
||||||
|
COPY --from=build /build/sarafu-vise/.env.example .
|
||||||
|
RUN mv .env.example .env
|
||||||
|
|
||||||
|
EXPOSE 7123
|
||||||
|
EXPOSE 7122
|
||||||
|
|
||||||
|
CMD ["./sarafu-at"]
|
10
args/lang.go
10
args/lang.go
@ -10,7 +10,7 @@ type LangVar struct {
|
|||||||
v []lang.Language
|
v []lang.Language
|
||||||
}
|
}
|
||||||
|
|
||||||
func(lv *LangVar) Set(s string) error {
|
func (lv *LangVar) Set(s string) error {
|
||||||
v, err := lang.LanguageFromCode(s)
|
v, err := lang.LanguageFromCode(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -19,16 +19,14 @@ func(lv *LangVar) Set(s string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func(lv *LangVar) String() string {
|
func (lv *LangVar) String() string {
|
||||||
var s []string
|
var s []string
|
||||||
for _, v := range(lv.v) {
|
for _, v := range lv.v {
|
||||||
s = append(s, v.Code)
|
s = append(s, v.Code)
|
||||||
}
|
}
|
||||||
return strings.Join(s, ",")
|
return strings.Join(s, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
func(lv *LangVar) Langs() []lang.Language {
|
func (lv *LangVar) Langs() []lang.Language {
|
||||||
return lv.v
|
return lv.v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,18 +12,18 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
"git.defalsify.org/vise.git/logging"
|
|
||||||
"git.defalsify.org/vise.git/lang"
|
"git.defalsify.org/vise.git/lang"
|
||||||
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
at "git.grassecon.net/grassrootseconomics/visedriver-africastalking/africastalking"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
||||||
|
at "git.grassecon.net/grassrootseconomics/visedriver-africastalking/africastalking"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -36,8 +36,7 @@ var (
|
|||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
var connStr string
|
override := config.NewOverride()
|
||||||
var resourceDir string
|
|
||||||
var size uint
|
var size uint
|
||||||
var engineDebug bool
|
var engineDebug bool
|
||||||
var host string
|
var host string
|
||||||
@ -46,10 +45,11 @@ func main() {
|
|||||||
var gettextDir string
|
var gettextDir string
|
||||||
var langs args.LangVar
|
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.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
||||||
|
flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)")
|
||||||
|
flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string")
|
||||||
|
flag.StringVar(&override.ResourceConn, "resource", "?", "resource data directory")
|
||||||
|
flag.StringVar(&override.StateConn, "state", "?", "state store connection string")
|
||||||
flag.UintVar(&size, "s", 160, "max size of output")
|
flag.UintVar(&size, "s", 160, "max size of output")
|
||||||
flag.StringVar(&host, "h", config.Host(), "http host")
|
flag.StringVar(&host, "h", config.Host(), "http host")
|
||||||
flag.UintVar(&port, "p", config.Port(), "http port")
|
flag.UintVar(&port, "p", config.Port(), "http port")
|
||||||
@ -57,16 +57,14 @@ func main() {
|
|||||||
flag.Var(&langs, "language", "add symbol resolution for language")
|
flag.Var(&langs, "language", "add symbol resolution for language")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if connStr == "" {
|
config.Apply(override)
|
||||||
connStr = config.DbConn()
|
conns, err := config.GetConns()
|
||||||
}
|
|
||||||
connData, err := storage.ToConnData(connStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
|
fmt.Fprintf(os.Stderr, "conn specification error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
logg.Infof("start command", "build", build, "conn", connData, "resourcedir", resourceDir, "outputsize", size)
|
logg.Infof("start command", "build", build, "conn", conns, "outputsize", size)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ln, err := lang.LanguageFromCode(config.Language())
|
ln, err := lang.LanguageFromCode(config.Language())
|
||||||
@ -83,13 +81,14 @@ func main() {
|
|||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
FlagCount: uint32(128),
|
FlagCount: uint32(128),
|
||||||
MenuSeparator: menuSeparator,
|
MenuSeparator: menuSeparator,
|
||||||
|
ResetOnEmptyInput: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if engineDebug {
|
if engineDebug {
|
||||||
cfg.EngineDebug = true
|
cfg.EngineDebug = true
|
||||||
}
|
}
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
menuStorageService := storage.NewMenuStorageService(conns)
|
||||||
rs, err := menuStorageService.GetResource(ctx)
|
rs, err := menuStorageService.GetResource(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "menustorageservice: %v\n", err)
|
fmt.Fprintf(os.Stderr, "menustorageservice: %v\n", err)
|
||||||
@ -101,7 +100,6 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, "userdatadb: %v\n", err)
|
fmt.Fprintf(os.Stderr, "userdatadb: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer userdataStore.Close()
|
|
||||||
|
|
||||||
dbResource, ok := rs.(*resource.DbResource)
|
dbResource, ok := rs.(*resource.DbResource)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -120,8 +118,8 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
accountService := services.New(ctx, menuStorageService, connData)
|
accountService := services.New(ctx, menuStorageService)
|
||||||
|
|
||||||
hl, err := lhs.GetHandler(accountService)
|
hl, err := lhs.GetHandler(accountService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "httpaccountservice: %v\n", err)
|
fmt.Fprintf(os.Stderr, "httpaccountservice: %v\n", err)
|
||||||
@ -133,10 +131,10 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, "getstatestore: %v\n", err)
|
fmt.Fprintf(os.Stderr, "getstatestore: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer stateStore.Close()
|
|
||||||
|
|
||||||
rp := &at.ATRequestParser{}
|
rp := &at.ATRequestParser{}
|
||||||
bsh := request.NewBaseRequestHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
bsh := request.NewBaseRequestHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
||||||
|
bsh = bsh.WithEngineFunc(lhs.GetEngine)
|
||||||
sh := at.NewATRequestHandler(bsh)
|
sh := at.NewATRequestHandler(bsh)
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
@ -146,7 +144,10 @@ func main() {
|
|||||||
Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))),
|
Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))),
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
}
|
}
|
||||||
s.RegisterOnShutdown(sh.Shutdown)
|
shutdownFunc := func() {
|
||||||
|
sh.Shutdown(ctx)
|
||||||
|
}
|
||||||
|
s.RegisterOnShutdown(shutdownFunc)
|
||||||
|
|
||||||
cint := make(chan os.Signal)
|
cint := make(chan os.Signal)
|
||||||
cterm := make(chan os.Signal)
|
cterm := make(chan os.Signal)
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
@ -14,12 +17,12 @@ import (
|
|||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -44,9 +47,8 @@ func (p *asyncRequestParser) GetInput(r any) ([]byte, error) {
|
|||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
var connStr string
|
override := config.NewOverride()
|
||||||
var sessionId string
|
var sessionId string
|
||||||
var resourceDir string
|
|
||||||
var size uint
|
var size uint
|
||||||
var engineDebug bool
|
var engineDebug bool
|
||||||
var host string
|
var host string
|
||||||
@ -56,8 +58,11 @@ func main() {
|
|||||||
var langs args.LangVar
|
var langs args.LangVar
|
||||||
|
|
||||||
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
||||||
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
|
flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)")
|
||||||
flag.StringVar(&connStr, "c", "", "connection string")
|
flag.StringVar(&override.ResourceConn, "resource", "?", "resource data directory")
|
||||||
|
flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string")
|
||||||
|
flag.StringVar(&override.StateConn, "state", "?", "state store connection string")
|
||||||
|
|
||||||
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
||||||
flag.UintVar(&size, "s", 160, "max size of output")
|
flag.UintVar(&size, "s", 160, "max size of output")
|
||||||
flag.StringVar(&host, "h", config.Host(), "http host")
|
flag.StringVar(&host, "h", config.Host(), "http host")
|
||||||
@ -66,16 +71,14 @@ func main() {
|
|||||||
flag.Var(&langs, "language", "add symbol resolution for language")
|
flag.Var(&langs, "language", "add symbol resolution for language")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if connStr == "" {
|
config.Apply(override)
|
||||||
connStr = config.DbConn()
|
conns, err := config.GetConns()
|
||||||
}
|
|
||||||
connData, err := storage.ToConnData(connStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
|
fmt.Fprintf(os.Stderr, "conn specification error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
logg.Infof("start command", "conn", connData, "resourcedir", resourceDir, "outputsize", size, "sessionId", sessionId)
|
logg.Infof("start command", "conn", conns, "outputsize", size, "sessionId", sessionId)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
@ -93,13 +96,14 @@ func main() {
|
|||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
FlagCount: uint32(128),
|
FlagCount: uint32(128),
|
||||||
MenuSeparator: menuSeparator,
|
MenuSeparator: menuSeparator,
|
||||||
|
ResetOnEmptyInput: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if engineDebug {
|
if engineDebug {
|
||||||
cfg.EngineDebug = true
|
cfg.EngineDebug = true
|
||||||
}
|
}
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
menuStorageService := storage.NewMenuStorageService(conns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -116,7 +120,7 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer userdataStore.Close()
|
//defer userdataStore.Close(ctx)
|
||||||
|
|
||||||
dbResource, ok := rs.(*resource.DbResource)
|
dbResource, ok := rs.(*resource.DbResource)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -126,8 +130,7 @@ func main() {
|
|||||||
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
|
lhs, err := handlers.NewLocalHandlerService(ctx, pfp, true, dbResource, cfg, rs)
|
||||||
lhs.SetDataStore(&userdataStore)
|
lhs.SetDataStore(&userdataStore)
|
||||||
|
|
||||||
accountService := services.New(ctx, menuStorageService, connData)
|
accountService := services.New(ctx, menuStorageService)
|
||||||
|
|
||||||
hl, err := lhs.GetHandler(accountService)
|
hl, err := lhs.GetHandler(accountService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
@ -139,12 +142,14 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer stateStore.Close()
|
//defer stateStore.Close(ctx)
|
||||||
|
|
||||||
rp := &asyncRequestParser{
|
rp := &asyncRequestParser{
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
}
|
}
|
||||||
sh := request.NewBaseRequestHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
sh := request.NewBaseRequestHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
||||||
|
sh = sh.WithEngineFunc(lhs.GetEngine)
|
||||||
|
|
||||||
cfg.SessionId = sessionId
|
cfg.SessionId = sessionId
|
||||||
rqs := request.RequestSession{
|
rqs := request.RequestSession{
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
@ -161,7 +166,7 @@ func main() {
|
|||||||
case _ = <-cint:
|
case _ = <-cint:
|
||||||
case _ = <-cterm:
|
case _ = <-cterm:
|
||||||
}
|
}
|
||||||
sh.Shutdown()
|
sh.Shutdown(ctx)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for true {
|
for true {
|
||||||
@ -177,18 +182,26 @@ func main() {
|
|||||||
fmt.Errorf("error in output: %v", err)
|
fmt.Errorf("error in output: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
rqs, err = sh.Reset(rqs)
|
rqs, err = sh.Reset(ctx, rqs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "error in reset: %v", "err", err)
|
logg.ErrorCtxf(ctx, "error in reset: %v", "err", err)
|
||||||
fmt.Errorf("error in reset: %v", err)
|
fmt.Errorf("error in reset: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
_, err = fmt.Scanln(&rqs.Input)
|
in := bufio.NewReader(os.Stdin)
|
||||||
|
s, err := in.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
logg.DebugCtxf(ctx, "have EOF, bailing")
|
||||||
|
break
|
||||||
|
}
|
||||||
logg.ErrorCtxf(ctx, "error in input", "err", err)
|
logg.ErrorCtxf(ctx, "error in input", "err", err)
|
||||||
fmt.Errorf("error in input: %v", err)
|
fmt.Errorf("error in input: %v", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
rqs.Input = []byte{}
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
rqs.Input = []byte(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,13 @@ import (
|
|||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||||
httprequest "git.grassecon.net/grassrootseconomics/visedriver/request/http"
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
"git.grassecon.net/grassrootseconomics/visedriver/request"
|
||||||
|
httprequest "git.grassecon.net/grassrootseconomics/visedriver/request/http"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -35,8 +35,7 @@ var (
|
|||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
var connStr string
|
override := config.NewOverride()
|
||||||
var resourceDir string
|
|
||||||
var size uint
|
var size uint
|
||||||
var engineDebug bool
|
var engineDebug bool
|
||||||
var host string
|
var host string
|
||||||
@ -45,8 +44,11 @@ func main() {
|
|||||||
var gettextDir string
|
var gettextDir string
|
||||||
var langs args.LangVar
|
var langs args.LangVar
|
||||||
|
|
||||||
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
|
flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)")
|
||||||
flag.StringVar(&connStr, "c", "", "connection string")
|
flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string")
|
||||||
|
flag.StringVar(&override.ResourceConn, "resource", "?", "resource data directory")
|
||||||
|
flag.StringVar(&override.StateConn, "state", "?", "state store connection string")
|
||||||
|
|
||||||
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
||||||
flag.UintVar(&size, "s", 160, "max size of output")
|
flag.UintVar(&size, "s", 160, "max size of output")
|
||||||
flag.StringVar(&host, "h", config.Host(), "http host")
|
flag.StringVar(&host, "h", config.Host(), "http host")
|
||||||
@ -55,16 +57,14 @@ func main() {
|
|||||||
flag.Var(&langs, "language", "add symbol resolution for language")
|
flag.Var(&langs, "language", "add symbol resolution for language")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if connStr == "" {
|
config.Apply(override)
|
||||||
connStr = config.DbConn()
|
conns, err := config.GetConns()
|
||||||
}
|
|
||||||
connData, err := storage.ToConnData(connStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
|
fmt.Fprintf(os.Stderr, "conn specification error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
logg.Infof("start command", "conn", connData, "resourcedir", resourceDir, "outputsize", size)
|
logg.Infof("start command", "conn", conns, "outputsize", size)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
@ -82,13 +82,14 @@ func main() {
|
|||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
FlagCount: uint32(128),
|
FlagCount: uint32(128),
|
||||||
MenuSeparator: menuSeparator,
|
MenuSeparator: menuSeparator,
|
||||||
|
ResetOnEmptyInput: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if engineDebug {
|
if engineDebug {
|
||||||
cfg.EngineDebug = true
|
cfg.EngineDebug = true
|
||||||
}
|
}
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
menuStorageService := storage.NewMenuStorageService(conns)
|
||||||
|
|
||||||
rs, err := menuStorageService.GetResource(ctx)
|
rs, err := menuStorageService.GetResource(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -101,7 +102,6 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer userdataStore.Close()
|
|
||||||
|
|
||||||
dbResource, ok := rs.(*resource.DbResource)
|
dbResource, ok := rs.(*resource.DbResource)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -116,8 +116,8 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
accountService := services.New(ctx, menuStorageService, connData)
|
accountService := services.New(ctx, menuStorageService)
|
||||||
|
|
||||||
hl, err := lhs.GetHandler(accountService)
|
hl, err := lhs.GetHandler(accountService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
@ -129,18 +129,21 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer stateStore.Close()
|
|
||||||
|
|
||||||
//accountService := services.New(ctx, menuStorageService, connData)
|
//accountService := services.New(ctx, menuStorageService, connData)
|
||||||
|
|
||||||
rp := &httprequest.DefaultRequestParser{}
|
rp := &httprequest.DefaultRequestParser{}
|
||||||
bsh := request.NewBaseRequestHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
bsh := request.NewBaseRequestHandler(cfg, rs, stateStore, userdataStore, rp, hl)
|
||||||
|
bsh = bsh.WithEngineFunc(lhs.GetEngine)
|
||||||
sh := httprequest.NewHTTPRequestHandler(bsh)
|
sh := httprequest.NewHTTPRequestHandler(bsh)
|
||||||
s := &http.Server{
|
s := &http.Server{
|
||||||
Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))),
|
Addr: fmt.Sprintf("%s:%s", host, strconv.Itoa(int(port))),
|
||||||
Handler: sh,
|
Handler: sh,
|
||||||
}
|
}
|
||||||
s.RegisterOnShutdown(sh.Shutdown)
|
shutdownFunc := func() {
|
||||||
|
sh.Shutdown(ctx)
|
||||||
|
}
|
||||||
|
s.RegisterOnShutdown(shutdownFunc)
|
||||||
|
|
||||||
cint := make(chan os.Signal)
|
cint := make(chan os.Signal)
|
||||||
cterm := make(chan os.Signal)
|
cterm := make(chan os.Signal)
|
||||||
|
70
cmd/main.go
70
cmd/main.go
@ -5,17 +5,19 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/signal"
|
||||||
"path"
|
"path"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
|
"git.defalsify.org/vise.git/lang"
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.defalsify.org/vise.git/lang"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/args"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/services"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -27,41 +29,39 @@ var (
|
|||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
var connStr string
|
override := config.NewOverride()
|
||||||
var size uint
|
var size uint
|
||||||
var sessionId string
|
var sessionId string
|
||||||
var engineDebug bool
|
var engineDebug bool
|
||||||
var resourceDir string
|
|
||||||
var err error
|
var err error
|
||||||
var gettextDir string
|
var gettextDir string
|
||||||
var langs args.LangVar
|
var langs args.LangVar
|
||||||
|
|
||||||
flag.StringVar(&resourceDir, "resourcedir", scriptDir, "resource dir")
|
|
||||||
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
||||||
flag.StringVar(&connStr, "c", "", "connection string")
|
flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)")
|
||||||
|
flag.StringVar(&override.ResourceConn, "resource", "?", "resource data directory")
|
||||||
|
flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string")
|
||||||
|
flag.StringVar(&override.StateConn, "state", "?", "state store connection string")
|
||||||
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
||||||
flag.UintVar(&size, "s", 160, "max size of output")
|
flag.UintVar(&size, "s", 160, "max size of output")
|
||||||
flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory")
|
flag.StringVar(&gettextDir, "gettext", "", "use gettext translations from given directory")
|
||||||
flag.Var(&langs, "language", "add symbol resolution for language")
|
flag.Var(&langs, "language", "add symbol resolution for language")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if connStr == "" {
|
config.Apply(override)
|
||||||
connStr = config.DbConn()
|
conns, err := config.GetConns()
|
||||||
}
|
|
||||||
connData, err := storage.ToConnData(connStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "connstr err: %v\n", err)
|
fmt.Fprintf(os.Stderr, "conn specification error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
logg.Infof("start command", "conn", connData, "outputsize", size)
|
logg.Infof("start command", "conn", conns, "outputsize", size)
|
||||||
|
|
||||||
if len(langs.Langs()) == 0 {
|
if len(langs.Langs()) == 0 {
|
||||||
langs.Set(config.Language())
|
langs.Set(config.Language())
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
|
||||||
|
|
||||||
ln, err := lang.LanguageFromCode(config.Language())
|
ln, err := lang.LanguageFromCode(config.Language())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -73,19 +73,21 @@ func main() {
|
|||||||
pfp := path.Join(scriptDir, "pp.csv")
|
pfp := path.Join(scriptDir, "pp.csv")
|
||||||
|
|
||||||
cfg := engine.Config{
|
cfg := engine.Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
SessionId: sessionId,
|
SessionId: sessionId,
|
||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
FlagCount: uint32(128),
|
FlagCount: uint32(128),
|
||||||
MenuSeparator: menuSeparator,
|
MenuSeparator: menuSeparator,
|
||||||
|
EngineDebug: engineDebug,
|
||||||
|
ResetOnEmptyInput: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
menuStorageService := storage.NewMenuStorageService(conns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "menu storage service error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "menu storage service error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if gettextDir != "" {
|
if gettextDir != "" {
|
||||||
menuStorageService = menuStorageService.WithGettext(gettextDir, langs.Langs())
|
menuStorageService = menuStorageService.WithGettext(gettextDir, langs.Langs())
|
||||||
}
|
}
|
||||||
@ -122,18 +124,28 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
accountService := services.New(ctx, menuStorageService, connData)
|
accountService := services.New(ctx, menuStorageService)
|
||||||
hl, err := lhs.GetHandler(accountService)
|
_, err = lhs.GetHandler(accountService)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "get accounts service handler: %v\n", err)
|
fmt.Fprintf(os.Stderr, "get accounts service handler: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
en := lhs.GetEngine(cfg, rs, pe)
|
||||||
|
|
||||||
en := lhs.GetEngine()
|
cint := make(chan os.Signal)
|
||||||
en = en.WithFirst(hl.Init)
|
cterm := make(chan os.Signal)
|
||||||
if engineDebug {
|
signal.Notify(cint, os.Interrupt, syscall.SIGINT)
|
||||||
en = en.WithDebug(nil)
|
signal.Notify(cterm, os.Interrupt, syscall.SIGTERM)
|
||||||
}
|
go func() {
|
||||||
|
var s os.Signal
|
||||||
|
select {
|
||||||
|
case s = <-cterm:
|
||||||
|
case s = <-cint:
|
||||||
|
}
|
||||||
|
logg.InfoCtxf(ctx, "stopping on signal", "sig", s)
|
||||||
|
en.Finish(ctx)
|
||||||
|
os.Exit(0)
|
||||||
|
}()
|
||||||
|
|
||||||
err = engine.Loop(ctx, en, os.Stdin, os.Stdout, nil)
|
err = engine.Loop(ctx, en, os.Stdin, os.Stdout, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -31,34 +31,31 @@ var (
|
|||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
var connStr string
|
override := config.NewOverride()
|
||||||
var authConnStr string
|
var authConnStr string
|
||||||
var resourceDir string
|
|
||||||
var size uint
|
var size uint
|
||||||
var engineDebug bool
|
var engineDebug bool
|
||||||
var stateDebug bool
|
var stateDebug bool
|
||||||
var host string
|
var host string
|
||||||
var port uint
|
var port uint
|
||||||
flag.StringVar(&connStr, "c", "", "connection string")
|
|
||||||
flag.StringVar(&authConnStr, "authdb", "", "auth connection string")
|
flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)")
|
||||||
flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
|
flag.StringVar(&override.ResourceConn, "resource", "?", "resource connection string")
|
||||||
|
flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string")
|
||||||
|
flag.StringVar(&override.StateConn, "state", "?", "state store connection string")
|
||||||
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
||||||
flag.UintVar(&size, "s", 160, "max size of output")
|
flag.UintVar(&size, "s", 160, "max size of output")
|
||||||
flag.StringVar(&host, "h", config.HostSSH(), "socket host")
|
flag.StringVar(&host, "h", config.HostSSH(), "socket host")
|
||||||
flag.UintVar(&port, "p", config.PortSSH(), "socket port")
|
flag.UintVar(&port, "p", config.PortSSH(), "socket port")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if connStr == "" {
|
config.Apply(override)
|
||||||
connStr = config.DbConn()
|
conns, err := config.GetConns()
|
||||||
}
|
|
||||||
if authConnStr == "" {
|
|
||||||
authConnStr = connStr
|
|
||||||
}
|
|
||||||
connData, err := storage.ToConnData(connStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
|
fmt.Fprintf(os.Stderr, "conn specification error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
authConnData, err := storage.ToConnData(authConnStr)
|
authConnData, err := storage.ToConnData(authConnStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "auth connstr err: %v", err)
|
fmt.Fprintf(os.Stderr, "auth connstr err: %v", err)
|
||||||
@ -79,7 +76,7 @@ func main() {
|
|||||||
logg.WarnCtxf(ctx, "!!!!! Do not expose to internet and only use with tunnel!")
|
logg.WarnCtxf(ctx, "!!!!! Do not expose to internet and only use with tunnel!")
|
||||||
logg.WarnCtxf(ctx, "!!!!! (See ssh -L <...>)")
|
logg.WarnCtxf(ctx, "!!!!! (See ssh -L <...>)")
|
||||||
|
|
||||||
logg.Infof("start command", "conn", connData, "authconn", authConnData, "resourcedir", resourceDir, "outputsize", size, "keyfile", sshKeyFile, "host", host, "port", port)
|
logg.Infof("start command", "conn", conns, "authconn", authConnData, "outputsize", size, "keyfile", sshKeyFile, "host", host, "port", port)
|
||||||
|
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
pfp := path.Join(scriptDir, "pp.csv")
|
||||||
|
|
||||||
@ -87,6 +84,7 @@ func main() {
|
|||||||
Root: "root",
|
Root: "root",
|
||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
FlagCount: uint32(128),
|
FlagCount: uint32(128),
|
||||||
|
ResetOnEmptyInput: true,
|
||||||
}
|
}
|
||||||
if stateDebug {
|
if stateDebug {
|
||||||
cfg.StateDebug = true
|
cfg.StateDebug = true
|
||||||
@ -102,7 +100,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
logg.TraceCtxf(ctx, "shutdown auth key store reached")
|
logg.TraceCtxf(ctx, "shutdown auth key store reached")
|
||||||
err = authKeyStore.Close()
|
err = authKeyStore.Close(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "keystore close error", "err", err)
|
logg.ErrorCtxf(ctx, "keystore close error", "err", err)
|
||||||
}
|
}
|
||||||
@ -114,14 +112,13 @@ func main() {
|
|||||||
signal.Notify(cterm, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(cterm, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
runner := &ssh.SshRunner{
|
runner := &ssh.SshRunner{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Debug: engineDebug,
|
Debug: engineDebug,
|
||||||
FlagFile: pfp,
|
FlagFile: pfp,
|
||||||
Conn: connData,
|
Conn: conns,
|
||||||
ResourceDir: resourceDir,
|
SrvKeyFile: sshKeyFile,
|
||||||
SrvKeyFile: sshKeyFile,
|
Host: host,
|
||||||
Host: host,
|
Port: port,
|
||||||
Port: port,
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
|
@ -34,7 +34,7 @@ func main() {
|
|||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer store.Close()
|
defer store.Close(ctx)
|
||||||
|
|
||||||
err = store.AddFromFile(ctx, sshKeyFile, sessionId)
|
err = store.AddFromFile(ctx, sshKeyFile, sessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
20
config/args.go
Normal file
20
config/args.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
viseconfig "git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewOverride() *viseconfig.Override {
|
||||||
|
o := &viseconfig.Override{
|
||||||
|
StateConnMode: storage.DBMODE_TEXT,
|
||||||
|
ResourceConnMode: storage.DBMODE_TEXT,
|
||||||
|
UserConnMode: storage.DBMODE_BINARY,
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
func Apply(o *viseconfig.Override) error {
|
||||||
|
viseconfig.ApplyConn(o)
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,24 +1,36 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/env"
|
"strings"
|
||||||
viseconfig "git.grassecon.net/grassrootseconomics/visedriver/config"
|
|
||||||
apiconfig "git.grassecon.net/grassrootseconomics/sarafu-api/config"
|
apiconfig "git.grassecon.net/grassrootseconomics/sarafu-api/config"
|
||||||
|
viseconfig "git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/env"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
var (
|
||||||
env.LoadEnvVariables()
|
GetConns = viseconfig.GetConns
|
||||||
|
EnvPath string
|
||||||
|
)
|
||||||
|
|
||||||
|
func loadEnv() {
|
||||||
|
if EnvPath == "" {
|
||||||
|
env.LoadEnvVariables()
|
||||||
|
} else {
|
||||||
|
env.LoadEnvVariablesPath(EnvPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultSSHHost string = "127.0.0.1"
|
defaultSSHHost string = "127.0.0.1"
|
||||||
defaultSSHPort uint = 7122
|
defaultSSHPort uint = 7122
|
||||||
defaultHTTPHost string = "127.0.0.1"
|
defaultHTTPHost string = "127.0.0.1"
|
||||||
defaultHTTPPort uint = 7123
|
defaultHTTPPort uint = 7123
|
||||||
|
defaultDomain = "sarafu.local"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func LoadConfig() error {
|
func LoadConfig() error {
|
||||||
|
loadEnv()
|
||||||
err := viseconfig.LoadConfig()
|
err := viseconfig.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -30,10 +42,17 @@ func LoadConfig() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DbConn() string {
|
func SearchDomains() []string {
|
||||||
return viseconfig.DbConn
|
var ParsedDomains []string
|
||||||
|
SearchDomains := env.GetEnv("ALIAS_SEARCH_DOMAINS", defaultDomain)
|
||||||
|
SearchDomainList := strings.Split(env.GetEnv("ALIAS_SEARCH_DOMAINS", SearchDomains), ",")
|
||||||
|
for _, domain := range SearchDomainList {
|
||||||
|
ParsedDomains = append(ParsedDomains, strings.ReplaceAll(domain, " ", ""))
|
||||||
|
}
|
||||||
|
return ParsedDomains
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Language() string {
|
func Language() string {
|
||||||
return viseconfig.DefaultLanguage
|
return viseconfig.DefaultLanguage
|
||||||
}
|
}
|
||||||
|
41
debug/db.go
41
debug/db.go
@ -1,11 +1,11 @@
|
|||||||
package debug
|
package debug
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
|
||||||
visedb "git.defalsify.org/vise.git/db"
|
visedb "git.defalsify.org/vise.git/db"
|
||||||
|
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -13,10 +13,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type KeyInfo struct {
|
type KeyInfo struct {
|
||||||
SessionId string
|
SessionId string
|
||||||
Typ uint8
|
Typ uint8
|
||||||
SubTyp storedb.DataTyp
|
SubTyp storedb.DataTyp
|
||||||
Label string
|
Label string
|
||||||
Description string
|
Description string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,18 +32,10 @@ func (k KeyInfo) String() string {
|
|||||||
|
|
||||||
func ToKeyInfo(k []byte, sessionId string) (KeyInfo, error) {
|
func ToKeyInfo(k []byte, sessionId string) (KeyInfo, error) {
|
||||||
o := KeyInfo{}
|
o := KeyInfo{}
|
||||||
b := []byte(sessionId)
|
|
||||||
|
|
||||||
if len(k) <= len(b) {
|
|
||||||
return o, fmt.Errorf("storage key missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
o.SessionId = sessionId
|
o.SessionId = sessionId
|
||||||
|
|
||||||
o.Typ = uint8(k[0])
|
o.Typ = uint8(k[0])
|
||||||
k = k[1:]
|
k = k[1:]
|
||||||
o.SessionId = string(k[:len(b)])
|
|
||||||
k = k[len(b):]
|
|
||||||
|
|
||||||
if o.Typ == visedb.DATATYPE_USERDATA {
|
if o.Typ == visedb.DATATYPE_USERDATA {
|
||||||
if len(k) == 0 {
|
if len(k) == 0 {
|
||||||
@ -53,30 +45,19 @@ func ToKeyInfo(k []byte, sessionId string) (KeyInfo, error) {
|
|||||||
o.SubTyp = storedb.DataTyp(v)
|
o.SubTyp = storedb.DataTyp(v)
|
||||||
o.Label = subTypToString(o.SubTyp)
|
o.Label = subTypToString(o.SubTyp)
|
||||||
k = k[2:]
|
k = k[2:]
|
||||||
|
if len(k) != 0 {
|
||||||
|
return o, fmt.Errorf("excess key information: %x", k)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
o.Label = typToString(o.Typ)
|
o.Label = typToString(o.Typ)
|
||||||
}
|
k = k[2:]
|
||||||
|
|
||||||
if len(k) != 0 {
|
|
||||||
return o, fmt.Errorf("excess key information")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromKey(k []byte) (KeyInfo, error) {
|
|
||||||
o := KeyInfo{}
|
|
||||||
|
|
||||||
if len(k) < 4 {
|
|
||||||
return o, fmt.Errorf("insufficient key length")
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionIdBytes := k[1:len(k)-2]
|
|
||||||
return ToKeyInfo(k, string(sessionIdBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func subTypToString(v storedb.DataTyp) string {
|
func subTypToString(v storedb.DataTyp) string {
|
||||||
return dbTypStr[v + visedb.DATATYPE_USERDATA + 1]
|
return dbTypStr[v+visedb.DATATYPE_USERDATA+1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func typToString(v uint8) string {
|
func typToString(v uint8) string {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//go:build debugdb
|
||||||
// +build debugdb
|
// +build debugdb
|
||||||
|
|
||||||
package debug
|
package debug
|
||||||
@ -11,34 +12,37 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
DebugCap |= 1
|
DebugCap |= 1
|
||||||
dbTypStr[db.DATATYPE_STATE] = "internal state"
|
dbTypStr[db.DATATYPE_STATE] = "internal state"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TRACKING_ID] = "tracking id"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TRACKING_ID] = "tracking id"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_PUBLIC_KEY] = "public key"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_PUBLIC_KEY] = "public key"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_ACCOUNT_PIN] = "account pin"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_ACCOUNT_PIN] = "account pin"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_FIRST_NAME] = "first name"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_FIRST_NAME] = "first name"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_FAMILY_NAME] = "family name"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_FAMILY_NAME] = "family name"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_YOB] = "year of birth"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_YOB] = "year of birth"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_LOCATION] = "location"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_LOCATION] = "location"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_GENDER] = "gender"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_GENDER] = "gender"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_OFFERINGS] = "offerings"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_OFFERINGS] = "offerings"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_RECIPIENT] = "recipient"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_RECIPIENT] = "recipient"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_AMOUNT] = "amount"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_AMOUNT] = "amount"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TEMPORARY_VALUE] = "temporary value"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TEMPORARY_VALUE] = "temporary value"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_ACTIVE_SYM] = "active sym"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_ACTIVE_SYM] = "active sym"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_ACTIVE_BAL] = "active bal"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_ACTIVE_BAL] = "active bal"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_BLOCKED_NUMBER] = "blocked number"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_BLOCKED_NUMBER] = "blocked number"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_PUBLIC_KEY_REVERSE] = "public_key_reverse"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_PUBLIC_KEY_REVERSE] = "public_key_reverse"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_ACTIVE_DECIMAL] = "active decimal"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_ACTIVE_DECIMAL] = "active decimal"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_ACTIVE_ADDRESS] = "active address"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_ACTIVE_ADDRESS] = "active address"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_VOUCHER_SYMBOLS] = "voucher symbols"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_INCORRECT_PIN_ATTEMPTS] = "incorrect pin attempts"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_VOUCHER_BALANCES] = "voucher balances"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_SELECTED_LANGUAGE_CODE] = "selected language"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_VOUCHER_DECIMALS] = "voucher decimals"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_INITIAL_LANGUAGE_CODE] = "initial language"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_VOUCHER_ADDRESSES] = "voucher addresses"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_VOUCHER_SYMBOLS] = "voucher symbols"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_SENDERS] = "tx senders"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_VOUCHER_BALANCES] = "voucher balances"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_RECIPIENTS] = "tx recipients"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_VOUCHER_DECIMALS] = "voucher decimals"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_VALUES] = "tx values"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_VOUCHER_ADDRESSES] = "voucher addresses"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_ADDRESSES] = "tx addresses"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_SENDERS] = "tx senders"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_HASHES] = "tx hashes"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_RECIPIENTS] = "tx recipients"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_DATES] = "tx dates"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_VALUES] = "tx values"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_SYMBOLS] = "tx symbols"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_ADDRESSES] = "tx addresses"
|
||||||
dbTypStr[db.DATATYPE_USERDATA + 1 + storedb.DATA_TX_DECIMALS] = "tx decimals"
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_HASHES] = "tx hashes"
|
||||||
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_DATES] = "tx dates"
|
||||||
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_SYMBOLS] = "tx symbols"
|
||||||
|
dbTypStr[db.DATATYPE_USERDATA+1+storedb.DATA_TX_DECIMALS] = "tx decimals"
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,13 @@ package debug
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
|
||||||
visedb "git.defalsify.org/vise.git/db"
|
visedb "git.defalsify.org/vise.git/db"
|
||||||
|
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDebugDbSubKeyInfo(t *testing.T) {
|
func TestDebugDbSubKeyInfo(t *testing.T) {
|
||||||
s := "foo"
|
s := "foo"
|
||||||
b := []byte{0x20}
|
b := []byte{0x20}
|
||||||
b = append(b, []byte(s)...)
|
|
||||||
b = append(b, []byte{0x00, 0x02}...)
|
b = append(b, []byte{0x00, 0x02}...)
|
||||||
r, err := ToKeyInfo(b, s)
|
r, err := ToKeyInfo(b, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -25,7 +24,7 @@ func TestDebugDbSubKeyInfo(t *testing.T) {
|
|||||||
if r.SubTyp != 2 {
|
if r.SubTyp != 2 {
|
||||||
t.Fatalf("expected 2, got %d", r.SubTyp)
|
t.Fatalf("expected 2, got %d", r.SubTyp)
|
||||||
}
|
}
|
||||||
if DebugCap & 1 > 0 {
|
if DebugCap&1 > 0 {
|
||||||
if r.Label != "tracking id" {
|
if r.Label != "tracking id" {
|
||||||
t.Fatalf("expected 'tracking id', got '%s'", r.Label)
|
t.Fatalf("expected 'tracking id', got '%s'", r.Label)
|
||||||
}
|
}
|
||||||
@ -46,7 +45,7 @@ func TestDebugDbKeyInfo(t *testing.T) {
|
|||||||
if r.Typ != 16 {
|
if r.Typ != 16 {
|
||||||
t.Fatalf("expected 16, got %d", r.Typ)
|
t.Fatalf("expected 16, got %d", r.Typ)
|
||||||
}
|
}
|
||||||
if DebugCap & 1 > 0 {
|
if DebugCap&1 > 0 {
|
||||||
if r.Label != "internal state" {
|
if r.Label != "internal state" {
|
||||||
t.Fatalf("expected 'internal_state', got '%s'", r.Label)
|
t.Fatalf("expected 'internal_state', got '%s'", r.Label)
|
||||||
}
|
}
|
||||||
@ -56,7 +55,6 @@ func TestDebugDbKeyInfo(t *testing.T) {
|
|||||||
func TestDebugDbKeyInfoRestore(t *testing.T) {
|
func TestDebugDbKeyInfoRestore(t *testing.T) {
|
||||||
s := "bar"
|
s := "bar"
|
||||||
b := []byte{visedb.DATATYPE_USERDATA}
|
b := []byte{visedb.DATATYPE_USERDATA}
|
||||||
b = append(b, []byte(s)...)
|
|
||||||
k := storedb.ToBytes(storedb.DATA_ACTIVE_SYM)
|
k := storedb.ToBytes(storedb.DATA_ACTIVE_SYM)
|
||||||
b = append(b, k...)
|
b = append(b, k...)
|
||||||
|
|
||||||
@ -70,7 +68,7 @@ func TestDebugDbKeyInfoRestore(t *testing.T) {
|
|||||||
if r.Typ != 32 {
|
if r.Typ != 32 {
|
||||||
t.Fatalf("expected 32, got %d", r.Typ)
|
t.Fatalf("expected 32, got %d", r.Typ)
|
||||||
}
|
}
|
||||||
if DebugCap & 1 > 0 {
|
if DebugCap&1 > 0 {
|
||||||
if r.Label != "active sym" {
|
if r.Label != "active sym" {
|
||||||
t.Fatalf("expected 'active sym', got '%s'", r.Label)
|
t.Fatalf("expected 'active sym', got '%s'", r.Label)
|
||||||
}
|
}
|
||||||
|
@ -10,37 +10,38 @@ import (
|
|||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/internal/cmd"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/application"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/application"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/internal/cmd"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logg = logging.NewVanilla().WithContextKey("SessionId")
|
logg = logging.NewVanilla().WithContextKey("SessionId")
|
||||||
scriptDir = path.Join("services", "registration")
|
scriptDir = path.Join("services", "registration")
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
|
override := config.NewOverride()
|
||||||
var sessionId string
|
var sessionId string
|
||||||
var connStr string
|
|
||||||
|
|
||||||
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
||||||
flag.StringVar(&connStr, "c", "", "connection string")
|
flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)")
|
||||||
|
flag.StringVar(&override.ResourceConn, "resource", "?", "resource data directory")
|
||||||
|
|
||||||
|
flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string")
|
||||||
|
flag.StringVar(&override.StateConn, "state", "?", "state store connection string")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
config.Apply(override)
|
||||||
if connStr == "" {
|
conns, err := config.GetConns()
|
||||||
connStr = config.DbConn()
|
|
||||||
}
|
|
||||||
connData, err := storage.ToConnData(connStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "connstr err: %v\n", err)
|
fmt.Fprintf(os.Stderr, "conn specification error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
|
||||||
|
|
||||||
pfp := path.Join(scriptDir, "pp.csv")
|
pfp := path.Join(scriptDir, "pp.csv")
|
||||||
flagParser, err := application.NewFlagManager(pfp)
|
flagParser, err := application.NewFlagManager(pfp)
|
||||||
@ -49,16 +50,16 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
x := cmd.NewCmd(connData, sessionId, flagParser)
|
x := cmd.NewCmd(sessionId, flagParser)
|
||||||
err = x.Parse(flag.Args())
|
err = x.Parse(flag.Args())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "cmd parse fail: %v\n", err)
|
fmt.Fprintf(os.Stderr, "cmd parse fail: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
logg.Infof("start command", "conn", connData, "subcmd", x)
|
logg.Infof("start command", "conn", conns, "subcmd", x)
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, "")
|
menuStorageService := storage.NewMenuStorageService(conns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "menu storage service error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "menu storage service error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -8,18 +8,17 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
|
||||||
"git.defalsify.org/vise.git/lang"
|
"git.defalsify.org/vise.git/lang"
|
||||||
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/config"
|
"git.grassecon.net/grassrootseconomics/visedriver/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
||||||
changeHeadSrc = `LOAD reset_account_authorized 0
|
changeHeadSrc = `LOAD reset_account_authorized 0
|
||||||
LOAD reset_incorrect 0
|
LOAD reset_incorrect 0
|
||||||
CATCH incorrect_pin flag_incorrect_pin 1
|
CATCH incorrect_pin flag_incorrect_pin 1
|
||||||
CATCH pin_entry flag_account_authorized 0
|
CATCH pin_entry flag_account_authorized 0
|
||||||
`
|
`
|
||||||
|
|
||||||
selectSrc = `LOAD set_language 6
|
selectSrc = `LOAD set_language 6
|
||||||
RELOAD set_language
|
RELOAD set_language
|
||||||
@ -29,8 +28,8 @@ MOVE language_changed
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logg = logging.NewVanilla()
|
logg = logging.NewVanilla()
|
||||||
mouts string
|
mouts string
|
||||||
incmps string
|
incmps string
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -63,7 +62,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
logg.Tracef("using languages", "lang", config.Languages)
|
logg.Tracef("using languages", "lang", config.Languages)
|
||||||
|
|
||||||
for i, v := range(config.Languages) {
|
for i, v := range config.Languages {
|
||||||
ln, err := lang.LanguageFromCode(v)
|
ln, err := lang.LanguageFromCode(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error parsing language: %s\n", v)
|
fmt.Fprintf(os.Stderr, "error parsing language: %s\n", v)
|
||||||
@ -76,7 +75,7 @@ func main() {
|
|||||||
incmps += fmt.Sprintf("INCMP %s %v\n", v, n)
|
incmps += fmt.Sprintf("INCMP %s %v\n", v, n)
|
||||||
|
|
||||||
p := path.Join(srcDir, v)
|
p := path.Join(srcDir, v)
|
||||||
w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_EXCL, 0600)
|
w, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed open language set template output: %v\n", err)
|
fmt.Fprintf(os.Stderr, "failed open language set template output: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -93,7 +92,7 @@ func main() {
|
|||||||
src += "INCMP . *\n"
|
src += "INCMP . *\n"
|
||||||
|
|
||||||
p := path.Join(srcDir, "select_language.vis")
|
p := path.Join(srcDir, "select_language.vis")
|
||||||
w, err := os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_EXCL, 0600)
|
w, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed open select language vis output: %v\n", err)
|
fmt.Fprintf(os.Stderr, "failed open select language vis output: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -107,7 +106,7 @@ func main() {
|
|||||||
|
|
||||||
src = changeHeadSrc + src
|
src = changeHeadSrc + src
|
||||||
p = path.Join(srcDir, "change_language.vis")
|
p = path.Join(srcDir, "change_language.vis")
|
||||||
w, err = os.OpenFile(p, os.O_WRONLY | os.O_CREATE | os.O_EXCL, 0600)
|
w, err = os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "failed open select language vis output: %v\n", err)
|
fmt.Fprintf(os.Stderr, "failed open select language vis output: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -7,11 +7,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/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"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/debug"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -19,55 +19,58 @@ var (
|
|||||||
scriptDir = path.Join("services", "registration")
|
scriptDir = path.Join("services", "registration")
|
||||||
)
|
)
|
||||||
|
|
||||||
func formatItem(k []byte, v []byte) (string, error) {
|
func formatItem(k []byte, v []byte, sessionId string) (string, error) {
|
||||||
o, err := debug.FromKey(k)
|
o, err := debug.ToKeyInfo(k, sessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
s := fmt.Sprintf("%vValue: %v\n\n", o, string(v))
|
s := fmt.Sprintf("%v\t%v\n", o.Label, string(v))
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
var connStr string
|
override := config.NewOverride()
|
||||||
var sessionId string
|
var sessionId string
|
||||||
var database string
|
var database string
|
||||||
var engineDebug bool
|
var engineDebug bool
|
||||||
var err error
|
var err error
|
||||||
|
var first bool
|
||||||
|
|
||||||
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
||||||
flag.StringVar(&connStr, "c", ".state", "connection string")
|
flag.StringVar(&override.DbConn, "c", "?", "default connection string (replaces all unspecified strings)")
|
||||||
|
flag.StringVar(&override.ResourceConn, "resource", "?", "resource data directory")
|
||||||
|
flag.StringVar(&override.UserConn, "userdata", "?", "userdata store connection string")
|
||||||
|
flag.StringVar(&override.StateConn, "state", "?", "state store connection string")
|
||||||
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if connStr != "" {
|
config.Apply(override)
|
||||||
connStr = config.DbConn()
|
conns, err := config.GetConns()
|
||||||
}
|
|
||||||
connData, err := storage.ToConnData(connStr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "connstr err: %v", err)
|
fmt.Fprintf(os.Stderr, "conn specification error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
logg.Infof("start command", "conn", connData)
|
logg.Infof("start command", "conn", conns)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
||||||
ctx = context.WithValue(ctx, "Database", database)
|
ctx = context.WithValue(ctx, "Database", database)
|
||||||
|
|
||||||
resourceDir := scriptDir
|
menuStorageService := storage.NewMenuStorageService(conns)
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
|
||||||
|
|
||||||
store, err := menuStorageService.GetUserdataDb(ctx)
|
store, err := menuStorageService.GetUserdataDb(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "get userdata db: %v\n", err.Error())
|
fmt.Fprintf(os.Stderr, "get userdata db: %v\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
store.SetSession(sessionId)
|
||||||
store.SetPrefix(db.DATATYPE_USERDATA)
|
store.SetPrefix(db.DATATYPE_USERDATA)
|
||||||
|
|
||||||
d, err := store.Dump(ctx, []byte(sessionId))
|
d, err := store.Dump(ctx, []byte(""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "store dump fail: %v\n", err.Error())
|
fmt.Fprintf(os.Stderr, "store dump fail: %v\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -78,15 +81,19 @@ func main() {
|
|||||||
if k == nil {
|
if k == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
r, err := formatItem(k, v)
|
if !first {
|
||||||
|
fmt.Printf("Session ID: %s\n---\n", sessionId)
|
||||||
|
first = true
|
||||||
|
}
|
||||||
|
r, err := formatItem(append([]byte{db.DATATYPE_USERDATA}, k...), v, sessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "format db item error: %v", err)
|
fmt.Fprintf(os.Stderr, "format db item error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
fmt.Printf(r)
|
fmt.Printf(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = store.Close()
|
err = store.Close(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/sha1"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
testdataloader "github.com/peteole/testdata-loader"
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
logg = logging.NewVanilla()
|
|
||||||
baseDir = testdataloader.GetBasePath()
|
|
||||||
scriptDir = path.Join("services", "registration")
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
config.LoadConfig()
|
|
||||||
|
|
||||||
var connStr string
|
|
||||||
var sessionId string
|
|
||||||
var database string
|
|
||||||
var engineDebug bool
|
|
||||||
var err error
|
|
||||||
|
|
||||||
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
|
|
||||||
flag.StringVar(&connStr, "c", "", "connection string")
|
|
||||||
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
|
|
||||||
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)
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
|
||||||
ctx = context.WithValue(ctx, "Database", database)
|
|
||||||
|
|
||||||
resourceDir := scriptDir
|
|
||||||
menuStorageService := storage.NewMenuStorageService(connData, resourceDir)
|
|
||||||
|
|
||||||
userDb, err := menuStorageService.GetUserdataDb(ctx)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
userStore := store.UserDataStore{userDb}
|
|
||||||
|
|
||||||
h := sha1.New()
|
|
||||||
h.Write([]byte(sessionId))
|
|
||||||
address := h.Sum(nil)
|
|
||||||
addressString := fmt.Sprintf("%x", address)
|
|
||||||
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY, []byte(addressString))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = userStore.WriteEntry(ctx, addressString, storedb.DATA_PUBLIC_KEY_REVERSE, []byte(sessionId))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = userDb.Close()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
10
go.mod
10
go.mod
@ -3,11 +3,11 @@ module git.grassecon.net/grassrootseconomics/sarafu-vise
|
|||||||
go 1.23.4
|
go 1.23.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.defalsify.org/vise.git v0.2.3-0.20250115000535-e2d329b3f739
|
git.defalsify.org/vise.git v0.2.3-0.20250205173834-d1f6647211ac
|
||||||
git.grassecon.net/grassrootseconomics/common v0.0.0-20250113174703-6afccefd1f05
|
git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.0.0-20250115072214-bca7c5de969f
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250206112944-31eb30de0f69
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250115003256-c0534ede1b63
|
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.1.0.20250204132347-1eb0b1555244
|
||||||
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250113103030-f0b2056fd87d
|
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694
|
||||||
github.com/alecthomas/assert/v2 v2.2.2
|
github.com/alecthomas/assert/v2 v2.2.2
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible
|
github.com/gofrs/uuid v4.4.0+incompatible
|
||||||
github.com/grassrootseconomics/ussd-data-service v1.2.0-beta
|
github.com/grassrootseconomics/ussd-data-service v1.2.0-beta
|
||||||
|
20
go.sum
20
go.sum
@ -1,13 +1,13 @@
|
|||||||
git.defalsify.org/vise.git v0.2.3-0.20250115000535-e2d329b3f739 h1:w7pj1oh7jXrfajahVYU7m7AfHst4C6jNVzDVoaqJ7e8=
|
git.defalsify.org/vise.git v0.2.3-0.20250205173834-d1f6647211ac h1:f/E0ZTclVfMEnD/3Alrzzbg+dOm138zGydV42jT0JPw=
|
||||||
git.defalsify.org/vise.git v0.2.3-0.20250115000535-e2d329b3f739/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
|
git.defalsify.org/vise.git v0.2.3-0.20250205173834-d1f6647211ac/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
|
||||||
git.grassecon.net/grassrootseconomics/common v0.0.0-20250113174703-6afccefd1f05 h1:BenzGx6aDHKDwE23/mWIFD2InYIXyzHroZWV3MF5WUk=
|
git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d h1:5mzLas+jxTUtusOKx4XvU+n2QvrV/mH17MnJRy46siQ=
|
||||||
git.grassecon.net/grassrootseconomics/common v0.0.0-20250113174703-6afccefd1f05/go.mod h1:wgQJZGIS6QuNLHqDhcsvehsbn5PvgV7aziRebMnJi60=
|
git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d/go.mod h1:wgQJZGIS6QuNLHqDhcsvehsbn5PvgV7aziRebMnJi60=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.0.0-20250115072214-bca7c5de969f h1:FgccQi8vipX6dUt+GRiRDYHMR3UqC+plz73vw7y3fyU=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250206112944-31eb30de0f69 h1:cbBpm9uNJak58MpFpNXJuvgCmz+A8kquXr9har4expg=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.0.0-20250115072214-bca7c5de969f/go.mod h1:tbA4whUGMUIDgQVdIW0sxWPuuXOvZRSny5zeku5hX4k=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250206112944-31eb30de0f69/go.mod h1:gOn89ipaDcDvmQXRMQYKUqcw/sJcwVOPVt2eC6Geip8=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250115003256-c0534ede1b63 h1:bX7klKZpX+ZZu1LKbtOXDAhV/KK0YwExehiIi0jusAM=
|
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.1.0.20250204132347-1eb0b1555244 h1:BXotWSKg04U97sf/xeWJuUTSVgKk2aEK+5BtBrnafXQ=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250115003256-c0534ede1b63/go.mod h1:Syw9TZyigPAM7t9FvicOm36iUnidt45f0SxzT2JniQ8=
|
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.1.0.20250204132347-1eb0b1555244/go.mod h1:6B6ByxXOiRY0NR7K02Bf3fEu7z+2c/6q8PFVNjC5G8w=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250113103030-f0b2056fd87d h1:q/NO1rEgK3pia32D/tCq5hXfEuJp84COZRwceFvy/MM=
|
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694 h1:DjJlBSz0S13acft5XZDWk7ZYnzElym0xLMYEVgyNJ+E=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250113103030-f0b2056fd87d/go.mod h1:AH15xABcvaJr1TCGlih3oGSuwWC0E5IdbHQwuu+E1KI=
|
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694/go.mod h1:DpibtYpnT3nG4Kn556hRAkdu4+CtiI/6MbnQHal51mQ=
|
||||||
github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=
|
github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=
|
||||||
github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
|
github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
|
||||||
github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
|
github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
|
||||||
|
@ -23,7 +23,9 @@ import (
|
|||||||
"git.grassecon.net/grassrootseconomics/common/person"
|
"git.grassecon.net/grassrootseconomics/common/person"
|
||||||
"git.grassecon.net/grassrootseconomics/common/phone"
|
"git.grassecon.net/grassrootseconomics/common/phone"
|
||||||
"git.grassecon.net/grassrootseconomics/common/pin"
|
"git.grassecon.net/grassrootseconomics/common/pin"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-api/models"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-api/remote"
|
"git.grassecon.net/grassrootseconomics/sarafu-api/remote"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/profile"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/profile"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
||||||
@ -100,14 +102,12 @@ func NewMenuHandlers(appFlags *FlagManager, userdataStore db.Db, accountService
|
|||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithPersister sets persister instance to the handlers.
|
// SetPersister sets persister instance to the handlers.
|
||||||
// func (h *MenuHandlers) WithPersister(pe *persist.Persister) *MenuHandlers {
|
|
||||||
func (h *MenuHandlers) SetPersister(pe *persist.Persister) {
|
func (h *MenuHandlers) SetPersister(pe *persist.Persister) {
|
||||||
if h.pe != nil {
|
if h.pe != nil {
|
||||||
panic("persister already set")
|
panic("persister already set")
|
||||||
}
|
}
|
||||||
h.pe = pe
|
h.pe = pe
|
||||||
//return h
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes the handler for a new session.
|
// Init initializes the handler for a new session.
|
||||||
@ -123,12 +123,6 @@ func (h *MenuHandlers) Init(ctx context.Context, sym string, input []byte) (reso
|
|||||||
|
|
||||||
h.st = h.pe.GetState()
|
h.st = h.pe.GetState()
|
||||||
h.ca = h.pe.GetMemory()
|
h.ca = h.pe.GetMemory()
|
||||||
|
|
||||||
if len(input) == 0 {
|
|
||||||
// move to the top node
|
|
||||||
h.st.Code = []byte{}
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
sessionId, ok := ctx.Value("SessionId").(string)
|
||||||
if ok {
|
if ok {
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
||||||
@ -273,7 +267,7 @@ func (h *MenuHandlers) CheckBlockedStatus(ctx context.Context, sym string, input
|
|||||||
}
|
}
|
||||||
|
|
||||||
pinAttemptsValue, _ := strconv.ParseUint(string(currentWrongPinAttempts), 0, 64)
|
pinAttemptsValue, _ := strconv.ParseUint(string(currentWrongPinAttempts), 0, 64)
|
||||||
|
|
||||||
if pinAttemptsValue == 0 {
|
if pinAttemptsValue == 0 {
|
||||||
res.FlagReset = append(res.FlagReset, flag_account_blocked)
|
res.FlagReset = append(res.FlagReset, flag_account_blocked)
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -324,12 +318,16 @@ func (h *MenuHandlers) VerifyNewPin(ctx context.Context, sym string, input []byt
|
|||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
flag_valid_pin, _ := h.flagManager.GetFlag("flag_valid_pin")
|
flag_valid_pin, _ := h.flagManager.GetFlag("flag_valid_pin")
|
||||||
pinInput := string(input)
|
if string(input) != "0" {
|
||||||
// Validate that the PIN is a 4-digit number.
|
pinInput := string(input)
|
||||||
if pin.IsValidPIN(pinInput) {
|
// Validate that the PIN is a 4-digit number.
|
||||||
res.FlagSet = append(res.FlagSet, flag_valid_pin)
|
if pin.IsValidPIN(pinInput) {
|
||||||
|
res.FlagSet = append(res.FlagSet, flag_valid_pin)
|
||||||
|
} else {
|
||||||
|
res.FlagReset = append(res.FlagReset, flag_valid_pin)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
res.FlagReset = append(res.FlagReset, flag_valid_pin)
|
res.FlagSet = append(res.FlagSet, flag_valid_pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -386,6 +384,12 @@ func (h *MenuHandlers) SaveOthersTemporaryPin(ctx context.Context, sym string, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
temporaryPin := string(input)
|
temporaryPin := string(input)
|
||||||
|
|
||||||
|
// Validate that the input is a 4-digit number.
|
||||||
|
if !pin.IsValidPIN(temporaryPin) {
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve the blocked number associated with this session
|
// Retrieve the blocked number associated with this session
|
||||||
blockedNumber, err := store.ReadEntry(ctx, sessionId, storedb.DATA_BLOCKED_NUMBER)
|
blockedNumber, err := store.ReadEntry(ctx, sessionId, storedb.DATA_BLOCKED_NUMBER)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -418,6 +422,11 @@ func (h *MenuHandlers) CheckBlockedNumPinMisMatch(ctx context.Context, sym strin
|
|||||||
if !ok {
|
if !ok {
|
||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
|
if string(input) == "0" {
|
||||||
|
res.FlagReset = append(res.FlagReset, flag_pin_mismatch)
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Get blocked number from storage.
|
// Get blocked number from storage.
|
||||||
store := h.userdataStore
|
store := h.userdataStore
|
||||||
blockedNumber, err := store.ReadEntry(ctx, sessionId, storedb.DATA_BLOCKED_NUMBER)
|
blockedNumber, err := store.ReadEntry(ctx, sessionId, storedb.DATA_BLOCKED_NUMBER)
|
||||||
@ -431,6 +440,11 @@ func (h *MenuHandlers) CheckBlockedNumPinMisMatch(ctx context.Context, sym strin
|
|||||||
logg.ErrorCtxf(ctx, "failed to read hashedTemporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
logg.ErrorCtxf(ctx, "failed to read hashedTemporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
if len(hashedTemporaryPin) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "hashedTemporaryPin is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
|
|
||||||
if pin.VerifyPIN(string(hashedTemporaryPin), string(input)) {
|
if pin.VerifyPIN(string(hashedTemporaryPin), string(input)) {
|
||||||
res.FlagReset = append(res.FlagReset, flag_pin_mismatch)
|
res.FlagReset = append(res.FlagReset, flag_pin_mismatch)
|
||||||
} else {
|
} else {
|
||||||
@ -448,12 +462,21 @@ func (h *MenuHandlers) ConfirmPinChange(ctx context.Context, sym string, input [
|
|||||||
}
|
}
|
||||||
flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch")
|
flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch")
|
||||||
|
|
||||||
|
if string(input) == "0" {
|
||||||
|
res.FlagReset = append(res.FlagReset, flag_pin_mismatch)
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
store := h.userdataStore
|
store := h.userdataStore
|
||||||
hashedTemporaryPin, err := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
hashedTemporaryPin, err := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to read hashedTemporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
logg.ErrorCtxf(ctx, "failed to read hashedTemporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
if len(hashedTemporaryPin) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "hashedTemporaryPin is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
|
|
||||||
if pin.VerifyPIN(string(hashedTemporaryPin), string(input)) {
|
if pin.VerifyPIN(string(hashedTemporaryPin), string(input)) {
|
||||||
res.FlagReset = append(res.FlagReset, flag_pin_mismatch)
|
res.FlagReset = append(res.FlagReset, flag_pin_mismatch)
|
||||||
@ -488,13 +511,17 @@ func (h *MenuHandlers) ResetOthersPin(ctx context.Context, sym string, input []b
|
|||||||
logg.ErrorCtxf(ctx, "failed to read blockedPhonenumber entry with", "key", storedb.DATA_BLOCKED_NUMBER, "error", err)
|
logg.ErrorCtxf(ctx, "failed to read blockedPhonenumber entry with", "key", storedb.DATA_BLOCKED_NUMBER, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
hashedTmporaryPin, err := store.ReadEntry(ctx, string(blockedPhonenumber), storedb.DATA_TEMPORARY_VALUE)
|
hashedTemporaryPin, err := store.ReadEntry(ctx, string(blockedPhonenumber), storedb.DATA_TEMPORARY_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to read hashedTmporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
logg.ErrorCtxf(ctx, "failed to read hashedTmporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
if len(hashedTemporaryPin) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "hashedTemporaryPin is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
|
|
||||||
err = store.WriteEntry(ctx, string(blockedPhonenumber), storedb.DATA_ACCOUNT_PIN, []byte(hashedTmporaryPin))
|
err = store.WriteEntry(ctx, string(blockedPhonenumber), storedb.DATA_ACCOUNT_PIN, []byte(hashedTemporaryPin))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -579,12 +606,21 @@ func (h *MenuHandlers) ValidateBlockedNumber(ctx context.Context, sym string, in
|
|||||||
if !ok {
|
if !ok {
|
||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
blockedNumber := string(input)
|
|
||||||
_, err = store.ReadEntry(ctx, blockedNumber, storedb.DATA_PUBLIC_KEY)
|
if string(input) == "0" {
|
||||||
if !phone.IsValidPhoneNumber(blockedNumber) {
|
res.FlagReset = append(res.FlagReset, flag_unregistered_number)
|
||||||
res.FlagSet = append(res.FlagSet, flag_unregistered_number)
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockedNumber := string(input)
|
||||||
|
formattedNumber, err := phone.FormatPhoneNumber(blockedNumber)
|
||||||
|
if err != nil {
|
||||||
|
res.FlagSet = append(res.FlagSet, flag_unregistered_number)
|
||||||
|
logg.ErrorCtxf(ctx, "Failed to format the phone number: %s", blockedNumber, "error", err)
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = store.ReadEntry(ctx, formattedNumber, storedb.DATA_PUBLIC_KEY)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if db.IsNotFound(err) {
|
if db.IsNotFound(err) {
|
||||||
logg.InfoCtxf(ctx, "Invalid or unregistered number")
|
logg.InfoCtxf(ctx, "Invalid or unregistered number")
|
||||||
@ -595,7 +631,7 @@ func (h *MenuHandlers) ValidateBlockedNumber(ctx context.Context, sym string, in
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_BLOCKED_NUMBER, []byte(blockedNumber))
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_BLOCKED_NUMBER, []byte(formattedNumber))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@ -622,6 +658,11 @@ func (h *MenuHandlers) VerifyCreatePin(ctx context.Context, sym string, input []
|
|||||||
logg.ErrorCtxf(ctx, "failed to read hashedTemporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
logg.ErrorCtxf(ctx, "failed to read hashedTemporaryPin entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
if len(hashedTemporaryPin) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "hashedTemporaryPin is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
|
|
||||||
if pin.VerifyPIN(string(hashedTemporaryPin), string(input)) {
|
if pin.VerifyPIN(string(hashedTemporaryPin), string(input)) {
|
||||||
res.FlagSet = []uint32{flag_valid_pin}
|
res.FlagSet = []uint32{flag_valid_pin}
|
||||||
res.FlagReset = []uint32{flag_pin_mismatch}
|
res.FlagReset = []uint32{flag_pin_mismatch}
|
||||||
@ -657,11 +698,19 @@ func (h *MenuHandlers) SaveFirstname(ctx context.Context, sym string, input []by
|
|||||||
firstNameSet := h.st.MatchFlag(flag_firstname_set, true)
|
firstNameSet := h.st.MatchFlag(flag_firstname_set, true)
|
||||||
if allowUpdate {
|
if allowUpdate {
|
||||||
temporaryFirstName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
temporaryFirstName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(temporaryFirstName) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "temporaryFirstName is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryFirstName))
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_FIRST_NAME, []byte(temporaryFirstName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write firstName entry with", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write firstName entry with", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
err := h.constructAccountAlias(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
res.FlagSet = append(res.FlagSet, flag_firstname_set)
|
res.FlagSet = append(res.FlagSet, flag_firstname_set)
|
||||||
} else {
|
} else {
|
||||||
if firstNameSet {
|
if firstNameSet {
|
||||||
@ -697,6 +746,10 @@ func (h *MenuHandlers) SaveFamilyname(ctx context.Context, sym string, input []b
|
|||||||
|
|
||||||
if allowUpdate {
|
if allowUpdate {
|
||||||
temporaryFamilyName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
temporaryFamilyName, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(temporaryFamilyName) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "temporaryFamilyName is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME, []byte(temporaryFamilyName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write familyName entry with", "key", storedb.DATA_FAMILY_NAME, "value", temporaryFamilyName, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write familyName entry with", "key", storedb.DATA_FAMILY_NAME, "value", temporaryFamilyName, "error", err)
|
||||||
@ -767,6 +820,10 @@ func (h *MenuHandlers) SaveYob(ctx context.Context, sym string, input []byte) (r
|
|||||||
|
|
||||||
if allowUpdate {
|
if allowUpdate {
|
||||||
temporaryYob, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
temporaryYob, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(temporaryYob) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "temporaryYob is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_YOB, []byte(temporaryYob))
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_YOB, []byte(temporaryYob))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write yob entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", temporaryYob, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write yob entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", temporaryYob, "error", err)
|
||||||
@ -806,6 +863,10 @@ func (h *MenuHandlers) SaveLocation(ctx context.Context, sym string, input []byt
|
|||||||
|
|
||||||
if allowUpdate {
|
if allowUpdate {
|
||||||
temporaryLocation, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
temporaryLocation, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(temporaryLocation) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "temporaryLocation is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_LOCATION, []byte(temporaryLocation))
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_LOCATION, []byte(temporaryLocation))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write location entry with", "key", storedb.DATA_LOCATION, "value", temporaryLocation, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write location entry with", "key", storedb.DATA_LOCATION, "value", temporaryLocation, "error", err)
|
||||||
@ -847,6 +908,10 @@ func (h *MenuHandlers) SaveGender(ctx context.Context, sym string, input []byte)
|
|||||||
|
|
||||||
if allowUpdate {
|
if allowUpdate {
|
||||||
temporaryGender, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
temporaryGender, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(temporaryGender) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "temporaryGender is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_GENDER, []byte(temporaryGender))
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_GENDER, []byte(temporaryGender))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write gender entry with", "key", storedb.DATA_GENDER, "value", gender, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write gender entry with", "key", storedb.DATA_GENDER, "value", gender, "error", err)
|
||||||
@ -888,6 +953,10 @@ func (h *MenuHandlers) SaveOfferings(ctx context.Context, sym string, input []by
|
|||||||
|
|
||||||
if allowUpdate {
|
if allowUpdate {
|
||||||
temporaryOfferings, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
temporaryOfferings, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(temporaryOfferings) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "temporaryOfferings is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_OFFERINGS, []byte(temporaryOfferings))
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_OFFERINGS, []byte(temporaryOfferings))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write offerings entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", offerings, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write offerings entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", offerings, "error", err)
|
||||||
@ -1076,6 +1145,11 @@ func (h *MenuHandlers) GetProfileInfo(ctx context.Context, sym string, input []b
|
|||||||
gender := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_GENDER))
|
gender := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_GENDER))
|
||||||
location := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_LOCATION))
|
location := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_LOCATION))
|
||||||
offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS))
|
offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS))
|
||||||
|
alias := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS))
|
||||||
|
|
||||||
|
if alias != defaultValue {
|
||||||
|
alias = strings.Split(alias, ".")[0]
|
||||||
|
}
|
||||||
|
|
||||||
// Construct the full name
|
// Construct the full name
|
||||||
name := person.ConstructName(firstName, familyName, defaultValue)
|
name := person.ConstructName(firstName, familyName, defaultValue)
|
||||||
@ -1092,18 +1166,18 @@ func (h *MenuHandlers) GetProfileInfo(ctx context.Context, sym string, input []b
|
|||||||
switch language.Code {
|
switch language.Code {
|
||||||
case "eng":
|
case "eng":
|
||||||
res.Content = fmt.Sprintf(
|
res.Content = fmt.Sprintf(
|
||||||
"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n",
|
"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\nYour alias: %s\n",
|
||||||
name, gender, age, location, offerings,
|
name, gender, age, location, offerings, alias,
|
||||||
)
|
)
|
||||||
case "swa":
|
case "swa":
|
||||||
res.Content = fmt.Sprintf(
|
res.Content = fmt.Sprintf(
|
||||||
"Jina: %s\nJinsia: %s\nUmri: %s\nEneo: %s\nUnauza: %s\n",
|
"Jina: %s\nJinsia: %s\nUmri: %s\nEneo: %s\nUnauza: %s\nLakabu yako: %s\n",
|
||||||
name, gender, age, location, offerings,
|
name, gender, age, location, offerings, alias,
|
||||||
)
|
)
|
||||||
default:
|
default:
|
||||||
res.Content = fmt.Sprintf(
|
res.Content = fmt.Sprintf(
|
||||||
"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n",
|
"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\nYour alias: %s\n",
|
||||||
name, gender, age, location, offerings,
|
name, gender, age, location, offerings, alias,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1159,6 +1233,10 @@ func (h *MenuHandlers) UpdateAllProfileItems(ctx context.Context, sym string, in
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
err = h.constructAccountAlias(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1204,7 +1282,9 @@ func (h *MenuHandlers) Authorize(ctx context.Context, sym string, input []byte)
|
|||||||
logg.ErrorCtxf(ctx, "failed to read AccountPin entry with", "key", storedb.DATA_ACCOUNT_PIN, "error", err)
|
logg.ErrorCtxf(ctx, "failed to read AccountPin entry with", "key", storedb.DATA_ACCOUNT_PIN, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
if len(input) == 4 {
|
str := string(input)
|
||||||
|
_, err = strconv.Atoi(str)
|
||||||
|
if len(input) == 4 && err == nil {
|
||||||
if pin.VerifyPIN(string(AccountPin), string(input)) {
|
if pin.VerifyPIN(string(AccountPin), string(input)) {
|
||||||
if h.st.MatchFlag(flag_account_authorized, false) {
|
if h.st.MatchFlag(flag_account_authorized, false) {
|
||||||
res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
|
res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
|
||||||
@ -1222,7 +1302,7 @@ func (h *MenuHandlers) Authorize(ctx context.Context, sym string, input []byte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := h.incrementIncorrectPINAttempts(ctx, sessionId)
|
err = h.incrementIncorrectPINAttempts(ctx, sessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -1239,11 +1319,13 @@ func (h *MenuHandlers) Authorize(ctx context.Context, sym string, input []byte)
|
|||||||
// Setback sets the flag_back_set flag when the navigation is back.
|
// Setback sets the flag_back_set flag when the navigation is back.
|
||||||
func (h *MenuHandlers) SetBack(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *MenuHandlers) SetBack(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
var res resource.Result
|
var res resource.Result
|
||||||
|
flag_back_set, _ := h.flagManager.GetFlag("flag_back_set")
|
||||||
//TODO:
|
//TODO:
|
||||||
//Add check if the navigation is lateral nav instead of checking the input.
|
//Add check if the navigation is lateral nav instead of checking the input.
|
||||||
if string(input) == "0" {
|
if string(input) == "0" {
|
||||||
flag_back_set, _ := h.flagManager.GetFlag("flag_back_set")
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_back_set)
|
res.FlagSet = append(res.FlagSet, flag_back_set)
|
||||||
|
} else {
|
||||||
|
res.FlagReset = append(res.FlagReset, flag_back_set)
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@ -1399,16 +1481,16 @@ func (h *MenuHandlers) FetchCommunityBalance(ctx context.Context, sym string, in
|
|||||||
// TODO: split up functino
|
// TODO: split up functino
|
||||||
func (h *MenuHandlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *MenuHandlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
var res resource.Result
|
var res resource.Result
|
||||||
|
var AliasAddressResult string
|
||||||
|
var AliasAddress *models.AliasAddress
|
||||||
store := h.userdataStore
|
store := h.userdataStore
|
||||||
|
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
sessionId, ok := ctx.Value("SessionId").(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
|
|
||||||
flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
|
flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
|
||||||
flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
|
flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
|
||||||
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
|
|
||||||
recipient := string(input)
|
recipient := string(input)
|
||||||
|
|
||||||
@ -1468,21 +1550,36 @@ func (h *MenuHandlers) ValidateRecipient(ctx context.Context, sym string, input
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "alias":
|
case "alias":
|
||||||
// Call the API to validate and retrieve the address for the alias
|
if strings.Contains(recipient, ".") {
|
||||||
r, aliasErr := h.accountService.CheckAliasAddress(ctx, recipient)
|
AliasAddress, err = h.accountService.CheckAliasAddress(ctx, recipient)
|
||||||
if aliasErr != nil {
|
if err == nil {
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_error)
|
AliasAddressResult = AliasAddress.Address
|
||||||
res.Content = recipient
|
} else {
|
||||||
|
logg.ErrorCtxf(ctx, "failed to resolve alias", "alias", recipient, "error_alias_check", err)
|
||||||
logg.ErrorCtxf(ctx, "failed on CheckAliasAddress", "error", aliasErr)
|
}
|
||||||
return res, err
|
} else {
|
||||||
|
//Perform a search for each search domain,break on first match
|
||||||
|
for _, domain := range config.SearchDomains() {
|
||||||
|
fqdn := fmt.Sprintf("%s.%s", recipient, domain)
|
||||||
|
AliasAddress, err = h.accountService.CheckAliasAddress(ctx, fqdn)
|
||||||
|
if err == nil {
|
||||||
|
AliasAddressResult = AliasAddress.Address
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
logg.ErrorCtxf(ctx, "failed to resolve alias", "alias", recipient, "error_alias_check", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if AliasAddressResult == "" {
|
||||||
// Alias validation succeeded, save the Ethereum address
|
res.Content = recipient
|
||||||
err = store.WriteEntry(ctx, sessionId, storedb.DATA_RECIPIENT, []byte(r.Address))
|
res.FlagSet = append(res.FlagSet, flag_invalid_recipient)
|
||||||
if err != nil {
|
return res, nil
|
||||||
logg.ErrorCtxf(ctx, "failed to write recipient entry with", "key", storedb.DATA_RECIPIENT, "value", r.Address, "error", err)
|
} else {
|
||||||
return res, err
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_RECIPIENT, []byte(AliasAddressResult))
|
||||||
|
if err != nil {
|
||||||
|
logg.ErrorCtxf(ctx, "failed to write recipient entry with", "key", storedb.DATA_RECIPIENT, "value", AliasAddressResult, "error", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1534,6 +1631,10 @@ func (h *MenuHandlers) InviteValidRecipient(ctx context.Context, sym string, inp
|
|||||||
l.AddDomain("default")
|
l.AddDomain("default")
|
||||||
|
|
||||||
recipient, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
recipient, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(recipient) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "recipient is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// send an invitation SMS
|
// send an invitation SMS
|
||||||
@ -1652,6 +1753,10 @@ func (h *MenuHandlers) GetRecipient(ctx context.Context, sym string, input []byt
|
|||||||
}
|
}
|
||||||
store := h.userdataStore
|
store := h.userdataStore
|
||||||
recipient, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
recipient, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
if len(recipient) == 0 {
|
||||||
|
logg.ErrorCtxf(ctx, "recipient is empty", "key", storedb.DATA_TEMPORARY_VALUE)
|
||||||
|
return res, fmt.Errorf("Data error encountered")
|
||||||
|
}
|
||||||
|
|
||||||
res.Content = string(recipient)
|
res.Content = string(recipient)
|
||||||
|
|
||||||
@ -2015,7 +2120,6 @@ func (h *MenuHandlers) GetVoucherDetails(ctx context.Context, sym string, input
|
|||||||
if !ok {
|
if !ok {
|
||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
|
|
||||||
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
||||||
|
|
||||||
// get the active address
|
// get the active address
|
||||||
@ -2211,6 +2315,7 @@ func (h *MenuHandlers) ViewTransactionStatement(ctx context.Context, sym string,
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// persistInitialLanguageCode receives an initial language code and persists it to the store
|
||||||
func (h *MenuHandlers) persistInitialLanguageCode(ctx context.Context, sessionId string, code string) error {
|
func (h *MenuHandlers) persistInitialLanguageCode(ctx context.Context, sessionId string, code string) error {
|
||||||
store := h.userdataStore
|
store := h.userdataStore
|
||||||
_, err := store.ReadEntry(ctx, sessionId, storedb.DATA_INITIAL_LANGUAGE_CODE)
|
_, err := store.ReadEntry(ctx, sessionId, storedb.DATA_INITIAL_LANGUAGE_CODE)
|
||||||
@ -2242,3 +2347,68 @@ func (h *MenuHandlers) persistLanguageCode(ctx context.Context, code string) err
|
|||||||
}
|
}
|
||||||
return h.persistInitialLanguageCode(ctx, sessionId, code)
|
return h.persistInitialLanguageCode(ctx, sessionId, code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constructAccountAlias retrieves and alias based on the first and family name
|
||||||
|
// and writes the result in DATA_ACCOUNT_ALIAS
|
||||||
|
func (h *MenuHandlers) constructAccountAlias(ctx context.Context) error {
|
||||||
|
var alias string
|
||||||
|
store := h.userdataStore
|
||||||
|
sessionId, ok := ctx.Value("SessionId").(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("missing session")
|
||||||
|
}
|
||||||
|
firstName, err := store.ReadEntry(ctx, sessionId, storedb.DATA_FIRST_NAME)
|
||||||
|
if err != nil {
|
||||||
|
if db.IsNotFound(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
familyName, err := store.ReadEntry(ctx, sessionId, storedb.DATA_FAMILY_NAME)
|
||||||
|
if err != nil {
|
||||||
|
if db.IsNotFound(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pubKey, err := store.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
|
||||||
|
if err != nil {
|
||||||
|
if db.IsNotFound(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
aliasInput := fmt.Sprintf("%s%s", firstName, familyName)
|
||||||
|
aliasResult, err := h.accountService.RequestAlias(ctx, string(pubKey), aliasInput)
|
||||||
|
if err != nil {
|
||||||
|
logg.ErrorCtxf(ctx, "failed to retrieve alias", "alias", aliasInput, "error_alias_request", err)
|
||||||
|
return fmt.Errorf("Failed to retrieve alias: %s", err.Error())
|
||||||
|
}
|
||||||
|
alias = aliasResult.Alias
|
||||||
|
//Store the alias
|
||||||
|
err = store.WriteEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS, []byte(alias))
|
||||||
|
if err != nil {
|
||||||
|
logg.ErrorCtxf(ctx, "failed to write account alias", "key", storedb.DATA_ACCOUNT_ALIAS, "value", alias, "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearTemporaryValue empties the DATA_TEMPORARY_VALUE at the main menu to prevent
|
||||||
|
// previously stored data from being accessed
|
||||||
|
func (h *MenuHandlers) ClearTemporaryValue(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
|
var res resource.Result
|
||||||
|
sessionId, ok := ctx.Value("SessionId").(string)
|
||||||
|
if !ok {
|
||||||
|
return res, fmt.Errorf("missing session")
|
||||||
|
}
|
||||||
|
userStore := h.userdataStore
|
||||||
|
|
||||||
|
// clear the temporary value at the start
|
||||||
|
err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(""))
|
||||||
|
if err != nil {
|
||||||
|
logg.ErrorCtxf(ctx, "failed to clear DATA_TEMPORARY_VALUE entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", "empty", "error", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -35,13 +35,6 @@ func (eu *EventsUpdater) HandleCustodialRegistration(ctx context.Context, ev *ap
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// err = pe.Load(identity.SessionId)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// st := pe.GetState()
|
|
||||||
// st.SetFlag(accountCreatedFlag)
|
|
||||||
// return pe.Save(identity.SessionId)
|
|
||||||
logg.DebugCtxf(ctx, "received custodial registration event", "identity", identity)
|
logg.DebugCtxf(ctx, "received custodial registration event", "identity", identity)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/persist"
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
"git.defalsify.org/vise.git/persist"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-api/remote"
|
|
||||||
apievent "git.grassecon.net/grassrootseconomics/sarafu-api/event"
|
apievent "git.grassecon.net/grassrootseconomics/sarafu-api/event"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-api/remote"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -17,9 +17,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type EventsUpdater struct {
|
type EventsUpdater struct {
|
||||||
api remote.AccountService
|
api remote.AccountService
|
||||||
formatFunc func(string, int, any) string
|
formatFunc func(string, int, any) string
|
||||||
store storage.StorageService
|
store storage.StorageService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEventsUpdater(api remote.AccountService, store storage.StorageService) *EventsUpdater {
|
func NewEventsUpdater(api remote.AccountService, store storage.StorageService) *EventsUpdater {
|
||||||
|
@ -6,13 +6,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
|
||||||
"git.grassecon.net/grassrootseconomics/common/identity"
|
"git.grassecon.net/grassrootseconomics/common/identity"
|
||||||
apievent "git.grassecon.net/grassrootseconomics/sarafu-api/event"
|
apievent "git.grassecon.net/grassrootseconomics/sarafu-api/event"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
||||||
|
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
// execute all
|
// execute all
|
||||||
func (eu *EventsUpdater) updateToken(ctx context.Context, identity identity.Identity, userStore *store.UserDataStore, tokenAddress string) error {
|
func (eu *EventsUpdater) updateToken(ctx context.Context, identity identity.Identity, userStore *store.UserDataStore, tokenAddress string) error {
|
||||||
err := eu.updateTokenList(ctx, identity, userStore)
|
err := eu.updateTokenList(ctx, identity, userStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -47,7 +47,6 @@ func (eu *EventsUpdater) updateToken(ctx context.Context, identity identity.Iden
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// set default token to given symbol.
|
// set default token to given symbol.
|
||||||
func (eu *EventsUpdater) updateDefaultToken(ctx context.Context, identity identity.Identity, userStore *store.UserDataStore, activeSym string) error {
|
func (eu *EventsUpdater) updateDefaultToken(ctx context.Context, identity identity.Identity, userStore *store.UserDataStore, activeSym string) error {
|
||||||
pfxDb := toPrefixDb(userStore, identity.SessionId)
|
pfxDb := toPrefixDb(userStore, identity.SessionId)
|
||||||
@ -59,7 +58,6 @@ func (eu *EventsUpdater) updateDefaultToken(ctx context.Context, identity identi
|
|||||||
return store.UpdateVoucherData(ctx, userStore, identity.SessionId, tokenData)
|
return store.UpdateVoucherData(ctx, userStore, identity.SessionId, tokenData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// handle token transfer.
|
// handle token transfer.
|
||||||
//
|
//
|
||||||
// if from and to are NOT the same, handle code will be executed once for each side of the transfer.
|
// if from and to are NOT the same, handle code will be executed once for each side of the transfer.
|
||||||
@ -189,7 +187,7 @@ func (eu *EventsUpdater) updateTokenTransferList(ctx context.Context, identity i
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tx := range(txs) {
|
for i, tx := range txs {
|
||||||
r = append(r, eu.formatFunc(apievent.EventTokenTransferTag, i, tx))
|
r = append(r, eu.formatFunc(apievent.EventTokenTransferTag, i, tx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.defalsify.org/vise.git/engine"
|
"git.defalsify.org/vise.git/engine"
|
||||||
|
"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"
|
||||||
|
|
||||||
@ -13,6 +14,10 @@ import (
|
|||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/application"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/application"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
logg = logging.NewVanilla().WithDomain("sarafu-vise.engine")
|
||||||
|
)
|
||||||
|
|
||||||
type HandlerService interface {
|
type HandlerService interface {
|
||||||
GetHandler() (*application.MenuHandlers, error)
|
GetHandler() (*application.MenuHandlers, error)
|
||||||
}
|
}
|
||||||
@ -24,6 +29,7 @@ type LocalHandlerService struct {
|
|||||||
UserdataStore *db.Db
|
UserdataStore *db.Db
|
||||||
Cfg engine.Config
|
Cfg engine.Config
|
||||||
Rs resource.Resource
|
Rs resource.Resource
|
||||||
|
first resource.EntryFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLocalHandlerService(ctx context.Context, fp string, debug bool, dbResource *resource.DbResource, cfg engine.Config, rs resource.Resource) (*LocalHandlerService, error) {
|
func NewLocalHandlerService(ctx context.Context, fp string, debug bool, dbResource *resource.DbResource, cfg engine.Config, rs resource.Resource) (*LocalHandlerService, error) {
|
||||||
@ -60,7 +66,6 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//appHandlers = appHandlers.WithPersister(ls.Pe)
|
|
||||||
appHandlers.SetPersister(ls.Pe)
|
appHandlers.SetPersister(ls.Pe)
|
||||||
ls.DbRs.AddLocalFunc("check_blocked_status", appHandlers.CheckBlockedStatus)
|
ls.DbRs.AddLocalFunc("check_blocked_status", appHandlers.CheckBlockedStatus)
|
||||||
ls.DbRs.AddLocalFunc("set_language", appHandlers.SetLanguage)
|
ls.DbRs.AddLocalFunc("set_language", appHandlers.SetLanguage)
|
||||||
@ -118,13 +123,20 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
|
|||||||
ls.DbRs.AddLocalFunc("update_all_profile_items", appHandlers.UpdateAllProfileItems)
|
ls.DbRs.AddLocalFunc("update_all_profile_items", appHandlers.UpdateAllProfileItems)
|
||||||
ls.DbRs.AddLocalFunc("set_back", appHandlers.SetBack)
|
ls.DbRs.AddLocalFunc("set_back", appHandlers.SetBack)
|
||||||
ls.DbRs.AddLocalFunc("show_blocked_account", appHandlers.ShowBlockedAccount)
|
ls.DbRs.AddLocalFunc("show_blocked_account", appHandlers.ShowBlockedAccount)
|
||||||
|
ls.DbRs.AddLocalFunc("clear_temporary_value", appHandlers.ClearTemporaryValue)
|
||||||
|
ls.first = appHandlers.Init
|
||||||
|
|
||||||
return appHandlers, nil
|
return appHandlers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: enable setting of sessionId on engine init time
|
func (ls *LocalHandlerService) GetEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) engine.Engine {
|
||||||
func (ls *LocalHandlerService) GetEngine() *engine.DefaultEngine {
|
en := engine.NewEngine(cfg, rs)
|
||||||
en := engine.NewEngine(ls.Cfg, ls.Rs)
|
if ls.first != nil {
|
||||||
en = en.WithPersister(ls.Pe)
|
en = en.WithFirst(ls.first)
|
||||||
|
}
|
||||||
|
en = en.WithPersister(pr)
|
||||||
|
if cfg.EngineDebug {
|
||||||
|
en = en.WithDebug(nil)
|
||||||
|
}
|
||||||
return en
|
return en
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/application"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/application"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -14,18 +14,17 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Cmd struct {
|
type Cmd struct {
|
||||||
sessionId string
|
sessionId string
|
||||||
conn storage.ConnData
|
conn storage.ConnData
|
||||||
flagParser *application.FlagManager
|
flagParser *application.FlagManager
|
||||||
cmd int
|
cmd int
|
||||||
enable bool
|
enable bool
|
||||||
exec func(ctx context.Context, ss storage.StorageService) error
|
exec func(ctx context.Context, ss storage.StorageService) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmd(conn storage.ConnData, sessionId string, flagParser *application.FlagManager) *Cmd {
|
func NewCmd(sessionId string, flagParser *application.FlagManager) *Cmd {
|
||||||
return &Cmd{
|
return &Cmd{
|
||||||
conn: conn,
|
sessionId: sessionId,
|
||||||
sessionId: sessionId,
|
|
||||||
flagParser: flagParser,
|
flagParser: flagParser,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,5 +94,3 @@ func (c *Cmd) Parse(args []string) error {
|
|||||||
|
|
||||||
return fmt.Errorf("unknown subcommand: %s", cmd)
|
return fmt.Errorf("unknown subcommand: %s", cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,67 @@
|
|||||||
{
|
{
|
||||||
"groups": [
|
"groups": [
|
||||||
|
{
|
||||||
|
"name": "main_my_vouchers_select_voucher_using_index",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "2",
|
||||||
|
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "Enter PIN to confirm selection:\nSymbol: SRF\nBalance: 2.745987\n0:Back\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1234",
|
||||||
|
"expectedContent": "Success! SRF is now your active voucher.\n0:Back\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "main_my_vouchers_select_voucher_using_symbol",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "2",
|
||||||
|
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "SRF",
|
||||||
|
"expectedContent": "Enter PIN to confirm selection:\nSymbol: SRF\nBalance: 2.745987\n0:Back\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1234",
|
||||||
|
"expectedContent": "Success! SRF is now your active voucher.\n0:Back\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "my_account_change_pin",
|
"name": "my_account_change_pin",
|
||||||
"steps": [
|
"steps": [
|
||||||
@ -48,13 +110,17 @@
|
|||||||
"input": "3",
|
"input": "3",
|
||||||
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"input": "2",
|
"input": "2",
|
||||||
"expectedContent": "Please enter your PIN:"
|
"expectedContent": "Please enter your PIN:"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1235",
|
"input": "1235",
|
||||||
"expectedContent": "Incorrect PIN. You have: 2 remaining attempt(s).\n1:Retry\n9:Quit"
|
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
@ -74,6 +140,121 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "menu_my_account_reset_others_pin_with_unregistered_number",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "3",
|
||||||
|
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "5",
|
||||||
|
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "2",
|
||||||
|
"expectedContent": "Enter other's phone number:\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0700000001",
|
||||||
|
"expectedContent": "The number you have entered is either not registered with Sarafu or is invalid.\n1:Retry\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "Enter other's phone number:\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "menu_my_account_reset_others_pin_with_registered_number",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "3",
|
||||||
|
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "5",
|
||||||
|
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "2",
|
||||||
|
"expectedContent": "Enter other's phone number:\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0700000000",
|
||||||
|
"expectedContent": "Please enter new PIN for: {secondary_session_id}\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "11111",
|
||||||
|
"expectedContent": "The PIN you have entered is invalid.Please try a 4 digit number instead.\n1:Retry\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "Please enter new PIN for: {secondary_session_id}\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1111",
|
||||||
|
"expectedContent": "Please confirm new PIN for: {secondary_session_id}\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1111",
|
||||||
|
"expectedContent": "Please enter your PIN:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1234",
|
||||||
|
"expectedContent": "PIN reset request for {secondary_session_id} was successful\n0:Back\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "menu_my_account_reset_others_pin_with_no_privileges",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "3",
|
||||||
|
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "5",
|
||||||
|
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "2",
|
||||||
|
"expectedContent": "You do not have privileges to perform this action\n\n9:Quit\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "0",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "menu_my_account_check_my_balance",
|
"name": "menu_my_account_check_my_balance",
|
||||||
"steps": [
|
"steps": [
|
||||||
@ -95,7 +276,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1235",
|
"input": "1235",
|
||||||
"expectedContent": "Incorrect PIN. You have: 2 remaining attempt(s).\n1:Retry\n9:Quit"
|
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
@ -140,7 +321,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1235",
|
"input": "1235",
|
||||||
"expectedContent": "Incorrect PIN. You have: 2 remaining attempt(s).\n1:Retry\n9:Quit"
|
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
@ -277,6 +458,10 @@
|
|||||||
"input": "3",
|
"input": "3",
|
||||||
"expectedContent": "Select gender: \n1:Male\n2:Female\n3:Unspecified\n0:Back"
|
"expectedContent": "Select gender: \n1:Male\n2:Female\n3:Unspecified\n0:Back"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "Select gender: \n1:Male\n2:Female\n3:Unspecified\n0:Back"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
"expectedContent": "Please enter your PIN:"
|
"expectedContent": "Please enter your PIN:"
|
||||||
@ -427,7 +612,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1234",
|
"input": "1234",
|
||||||
"expectedContent": "My profile:\nName: foo bar\nGender: male\nAge: 80\nLocation: Kilifi\nYou provide: Bananas\n\n0:Back\n9:Quit"
|
"expectedContent": "My profile:\nName: foo bar\nGender: male\nAge: 80\nLocation: Kilifi\nYou provide: Bananas\nYour alias: \n\n0:Back\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
@ -438,6 +623,47 @@
|
|||||||
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "menu_block_account_via_view_profile",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"input": "",
|
||||||
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "3",
|
||||||
|
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "My profile\n1:Edit name\n2:Edit family name\n3:Edit gender\n4:Edit year of birth\n5:Edit location\n6:Edit offerings\n7:View profile\n0:Back"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "7",
|
||||||
|
"expectedContent": "Please enter your PIN:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1254",
|
||||||
|
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "Please enter your PIN:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1254",
|
||||||
|
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1",
|
||||||
|
"expectedContent": "Please enter your PIN:"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": "1254",
|
||||||
|
"expectedContent": "Your account has been locked. For help on how to unblock your account, contact support at: 0757628885"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -9,22 +9,22 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"git.defalsify.org/vise.git/logging"
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/testutil/driver"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/testutil"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/testutil"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/testutil/driver"
|
||||||
|
"github.com/gofrs/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testData = driver.ReadData()
|
logg = logging.NewVanilla().WithDomain("menutraversaltest")
|
||||||
sessionID string
|
testData = driver.ReadData()
|
||||||
src = rand.NewSource(42)
|
sessionID string
|
||||||
g = rand.New(src)
|
src = rand.NewSource(42)
|
||||||
|
g = rand.New(src)
|
||||||
|
secondarySessionId = "+254700000000"
|
||||||
)
|
)
|
||||||
|
|
||||||
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)")
|
|
||||||
var connStr = flag.String("conn", ".test_state", "connection string")
|
|
||||||
var dbSchema = flag.String("schema", "test", "Specify the database schema (default test)")
|
|
||||||
|
|
||||||
func GenerateSessionId() string {
|
func GenerateSessionId() string {
|
||||||
uu := uuid.NewGenWithOptions(uuid.WithRandomReader(g))
|
uu := uuid.NewGenWithOptions(uuid.WithRandomReader(g))
|
||||||
@ -68,6 +68,16 @@ func extractMaxAmount(response []byte) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractRemainingAttempts(response []byte) string {
|
||||||
|
// Regex to match "You have: <number> remaining attempt(s)"
|
||||||
|
re := regexp.MustCompile(`(?m)You have:\s+(\d+)\s+remaining attempt\(s\)`)
|
||||||
|
match := re.FindSubmatch(response)
|
||||||
|
if match != nil {
|
||||||
|
return string(match[1]) // "<number>" of remaining attempts
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// Extracts the send amount value from the engine response.
|
// Extracts the send amount value from the engine response.
|
||||||
func extractSendAmount(response []byte) string {
|
func extractSendAmount(response []byte) string {
|
||||||
// Regex to match the pattern "will receive X.XX SYM from"
|
// Regex to match the pattern "will receive X.XX SYM from"
|
||||||
@ -80,12 +90,7 @@ func extractSendAmount(response []byte) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
// Parse the flags
|
|
||||||
flag.Parse()
|
|
||||||
sessionID = GenerateSessionId()
|
sessionID = GenerateSessionId()
|
||||||
// set the db
|
|
||||||
testutil.SetDatabase(*database, *connStr, *dbSchema)
|
|
||||||
|
|
||||||
// Cleanup the db after tests
|
// Cleanup the db after tests
|
||||||
defer testutil.CleanDatabase()
|
defer testutil.CleanDatabase()
|
||||||
|
|
||||||
@ -93,14 +98,51 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAccountCreationSuccessful(t *testing.T) {
|
func TestAccountCreationSuccessful(t *testing.T) {
|
||||||
en, fn, eventChannel := testutil.TestEngine(sessionID)
|
en, fn, eventChannel, _, _ := testutil.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
for _, session := range sessions {
|
for _, session := range sessions {
|
||||||
groups := driver.FilterGroupsByName(session.Groups, "account_creation_successful")
|
groups := driver.FilterGroupsByName(session.Groups, "account_creation_successful")
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
for _, step := range group.Steps {
|
for i, step := range group.Steps {
|
||||||
|
logg.TraceCtxf(ctx, "executing step", "i", i, "step", step)
|
||||||
|
cont, err := en.Exec(ctx, []byte(step.Input))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
||||||
|
}
|
||||||
|
if !cont {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
w := bytes.NewBuffer(nil)
|
||||||
|
_, err = en.Flush(ctx, w)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Test case '%s' failed during Flush: %v", group.Name, err)
|
||||||
|
}
|
||||||
|
b := w.Bytes()
|
||||||
|
match, err := step.MatchesExpectedContent(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error compiling regex for step '%s': %v", step.Input, err)
|
||||||
|
}
|
||||||
|
if !match {
|
||||||
|
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", step.ExpectedContent, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<-eventChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSecondaryAccount(t *testing.T) {
|
||||||
|
en, fn, eventChannel, _, _ := testutil.TestEngine(secondarySessionId)
|
||||||
|
defer fn()
|
||||||
|
ctx := context.Background()
|
||||||
|
sessions := testData
|
||||||
|
for _, session := range sessions {
|
||||||
|
groups := driver.FilterGroupsByName(session.Groups, "account_creation_successful")
|
||||||
|
for _, group := range groups {
|
||||||
|
for i, step := range group.Steps {
|
||||||
|
logg.TraceCtxf(ctx, "executing step", "i", i, "step", step)
|
||||||
cont, err := en.Exec(ctx, []byte(step.Input))
|
cont, err := en.Exec(ctx, []byte(step.Input))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
||||||
@ -135,14 +177,15 @@ func TestAccountRegistrationRejectTerms(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
edgeCaseSessionID := v.String()
|
edgeCaseSessionID := v.String()
|
||||||
en, fn, _ := testutil.TestEngine(edgeCaseSessionID)
|
en, fn, _, _, _ := testutil.TestEngine(edgeCaseSessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
for _, session := range sessions {
|
for _, session := range sessions {
|
||||||
groups := driver.FilterGroupsByName(session.Groups, "account_creation_reject_terms")
|
groups := driver.FilterGroupsByName(session.Groups, "account_creation_reject_terms")
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
for _, step := range group.Steps {
|
for i, step := range group.Steps {
|
||||||
|
logg.TraceCtxf(ctx, "executing step", "i", i, "step", step)
|
||||||
cont, err := en.Exec(ctx, []byte(step.Input))
|
cont, err := en.Exec(ctx, []byte(step.Input))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
||||||
@ -170,14 +213,15 @@ func TestAccountRegistrationRejectTerms(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMainMenuHelp(t *testing.T) {
|
func TestMainMenuHelp(t *testing.T) {
|
||||||
en, fn, _ := testutil.TestEngine(sessionID)
|
en, fn, _, _, _ := testutil.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
for _, session := range sessions {
|
for _, session := range sessions {
|
||||||
groups := driver.FilterGroupsByName(session.Groups, "main_menu_help")
|
groups := driver.FilterGroupsByName(session.Groups, "main_menu_help")
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
for _, step := range group.Steps {
|
for i, step := range group.Steps {
|
||||||
|
logg.TraceCtxf(ctx, "executing step", "i", i, "step", step)
|
||||||
cont, err := en.Exec(ctx, []byte(step.Input))
|
cont, err := en.Exec(ctx, []byte(step.Input))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
|
||||||
@ -211,7 +255,7 @@ func TestMainMenuHelp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMainMenuQuit(t *testing.T) {
|
func TestMainMenuQuit(t *testing.T) {
|
||||||
en, fn, _ := testutil.TestEngine(sessionID)
|
en, fn, _, _, _ := testutil.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -252,7 +296,7 @@ func TestMainMenuQuit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMyAccount_MyAddress(t *testing.T) {
|
func TestMyAccount_MyAddress(t *testing.T) {
|
||||||
en, fn, _ := testutil.TestEngine(sessionID)
|
en, fn, _, _, _ := testutil.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -296,7 +340,7 @@ func TestMyAccount_MyAddress(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMainMenuSend(t *testing.T) {
|
func TestMainMenuSend(t *testing.T) {
|
||||||
en, fn, _ := testutil.TestEngine(sessionID)
|
en, fn, _, _, _ := testutil.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sessions := testData
|
sessions := testData
|
||||||
@ -347,9 +391,12 @@ func TestGroups(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to load test groups: %v", err)
|
log.Fatalf("Failed to load test groups: %v", err)
|
||||||
}
|
}
|
||||||
en, fn, _ := testutil.TestEngine(sessionID)
|
en, fn, _, pe, flagParser := testutil.TestEngine(sessionID)
|
||||||
defer fn()
|
defer fn()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
flag_admin_privilege, _ := flagParser.GetFlag("flag_admin_privilege")
|
||||||
|
|
||||||
// Create test cases from loaded groups
|
// Create test cases from loaded groups
|
||||||
tests := driver.CreateTestCases(groups)
|
tests := driver.CreateTestCases(groups)
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -368,9 +415,21 @@ func TestGroups(t *testing.T) {
|
|||||||
}
|
}
|
||||||
b := w.Bytes()
|
b := w.Bytes()
|
||||||
balance := extractBalance(b)
|
balance := extractBalance(b)
|
||||||
|
attempts := extractRemainingAttempts(b)
|
||||||
|
|
||||||
|
st := pe.GetState()
|
||||||
|
|
||||||
|
if st != nil {
|
||||||
|
st.SetFlag(flag_admin_privilege)
|
||||||
|
if tt.Name == "menu_my_account_reset_others_pin_with_no_privileges" {
|
||||||
|
st.ResetFlag(flag_admin_privilege)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expectedContent := []byte(tt.ExpectedContent)
|
expectedContent := []byte(tt.ExpectedContent)
|
||||||
expectedContent = bytes.Replace(expectedContent, []byte("{balance}"), []byte(balance), -1)
|
expectedContent = bytes.Replace(expectedContent, []byte("{balance}"), []byte(balance), -1)
|
||||||
|
expectedContent = bytes.Replace(expectedContent, []byte("{attempts}"), []byte(attempts), -1)
|
||||||
|
expectedContent = bytes.Replace(expectedContent, []byte("{secondary_session_id}"), []byte(secondarySessionId), -1)
|
||||||
|
|
||||||
tt.ExpectedContent = string(expectedContent)
|
tt.ExpectedContent = string(expectedContent)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ func (p *Profile) InsertOrShift(index int, value string) {
|
|||||||
for len(p.ProfileItems) < index {
|
for len(p.ProfileItems) < index {
|
||||||
p.ProfileItems = append(p.ProfileItems, "0")
|
p.ProfileItems = append(p.ProfileItems, "0")
|
||||||
}
|
}
|
||||||
p.ProfileItems = append(p.ProfileItems, "0")
|
p.ProfileItems = append(p.ProfileItems, "0")
|
||||||
p.ProfileItems[index] = value
|
p.ProfileItems[index] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
profile/profile_test.go
Normal file
42
profile/profile_test.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package profile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alecthomas/assert/v2"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInsertOrShift(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
profile Profile
|
||||||
|
index int
|
||||||
|
value string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Insert within range",
|
||||||
|
profile: Profile{ProfileItems: []string{"A", "B", "C"}, Max: 5},
|
||||||
|
index: 1,
|
||||||
|
value: "X",
|
||||||
|
expected: []string{"A", "X"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Insert beyond range",
|
||||||
|
profile: Profile{ProfileItems: []string{"A"}, Max: 5},
|
||||||
|
index: 3,
|
||||||
|
value: "Y",
|
||||||
|
expected: []string{"A", "0", "0", "Y"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
p := tt.profile
|
||||||
|
p.InsertOrShift(tt.index, tt.value)
|
||||||
|
require.NotNil(t, p.ProfileItems)
|
||||||
|
assert.Equal(t, tt.expected, p.ProfileItems)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,17 @@
|
|||||||
|
//go:build !online
|
||||||
// +build !online
|
// +build !online
|
||||||
|
|
||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
|
||||||
devremote "git.grassecon.net/grassrootseconomics/sarafu-api/dev"
|
devremote "git.grassecon.net/grassrootseconomics/sarafu-api/dev"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-api/remote"
|
|
||||||
apievent "git.grassecon.net/grassrootseconomics/sarafu-api/event"
|
apievent "git.grassecon.net/grassrootseconomics/sarafu-api/event"
|
||||||
|
"git.grassecon.net/grassrootseconomics/sarafu-api/remote"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/event"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/handlers/event"
|
||||||
|
"git.grassecon.net/grassrootseconomics/visedriver/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
type localEmitter struct {
|
type localEmitter struct {
|
||||||
@ -37,7 +38,7 @@ func (d *localEmitter) emit(ctx context.Context, msg apievent.Msg) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx context.Context, storageService storage.StorageService, conn storage.ConnData) remote.AccountService {
|
func New(ctx context.Context, storageService storage.StorageService) remote.AccountService {
|
||||||
svc := devremote.NewDevAccountService(ctx, storageService)
|
svc := devremote.NewDevAccountService(ctx, storageService)
|
||||||
svc = svc.WithAutoVoucher(ctx, "FOO", 42)
|
svc = svc.WithAutoVoucher(ctx, "FOO", 42)
|
||||||
eu := event.NewEventsUpdater(svc, storageService)
|
eu := event.NewEventsUpdater(svc, storageService)
|
||||||
|
@ -4,8 +4,8 @@ TXTS = $(wildcard ./*.txt.orig)
|
|||||||
VISE_PATH := ../../go-vise
|
VISE_PATH := ../../go-vise
|
||||||
|
|
||||||
# Rule to build .bin files from .vis files
|
# Rule to build .bin files from .vis files
|
||||||
%.vis:
|
%.vis: buildasm
|
||||||
go run $(VISE_PATH)/dev/asm/main.go -f pp.csv $(basename $@).vis > $(basename $@).bin
|
./vise-asm -f pp.csv $(basename $@).vis > $(basename $@).bin
|
||||||
@echo "Built $(basename $@).bin from $(basename $@).vis"
|
@echo "Built $(basename $@).bin from $(basename $@).vis"
|
||||||
|
|
||||||
# Rule to copy .orig files to .txt
|
# Rule to copy .orig files to .txt
|
||||||
@ -19,5 +19,10 @@ all: $(INPUTS) $(TXTS)
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -vf *.bin
|
rm -vf *.bin
|
||||||
|
rm -vf ./vise-asm
|
||||||
|
|
||||||
|
buildasm:
|
||||||
|
go build -v -o ./vise-asm $(VISE_PATH)/dev/asm/main.go
|
||||||
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
|||||||
Please confirm new PIN for:{{.retrieve_blocked_number}}
|
Please confirm new PIN for: {{.retrieve_blocked_number}}
|
Binary file not shown.
@ -1,4 +1,4 @@
|
|||||||
CATCH pin_entry flag_incorrect_pin 1
|
CATCH incorrect_pin flag_incorrect_pin 1
|
||||||
RELOAD retrieve_blocked_number
|
RELOAD retrieve_blocked_number
|
||||||
MAP retrieve_blocked_number
|
MAP retrieve_blocked_number
|
||||||
CATCH invalid_others_pin flag_valid_pin 0
|
CATCH invalid_others_pin flag_valid_pin 0
|
||||||
@ -8,7 +8,7 @@ RELOAD save_others_temporary_pin
|
|||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
INCMP _ 0
|
INCMP _ 0
|
||||||
LOAD check_pin_mismatch 0
|
LOAD check_pin_mismatch 6
|
||||||
RELOAD check_pin_mismatch
|
RELOAD check_pin_mismatch
|
||||||
CATCH others_pin_mismatch flag_pin_mismatch 1
|
CATCH others_pin_mismatch flag_pin_mismatch 1
|
||||||
INCMP pin_entry *
|
INCMP pin_entry *
|
||||||
|
Binary file not shown.
@ -1,5 +1,7 @@
|
|||||||
CATCH invalid_pin flag_valid_pin 0
|
LOAD confirm_pin_change 0
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
INCMP _ 0
|
INCMP _ 0
|
||||||
|
RELOAD confirm_pin_change
|
||||||
|
CATCH pin_reset_mismatch flag_pin_mismatch 1
|
||||||
INCMP * pin_reset_success
|
INCMP * pin_reset_success
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,7 +1,10 @@
|
|||||||
CATCH no_admin_privilege flag_admin_privilege 0
|
CATCH no_admin_privilege flag_admin_privilege 0
|
||||||
LOAD reset_account_authorized 0
|
LOAD reset_account_authorized 0
|
||||||
RELOAD reset_account_authorized
|
RELOAD reset_account_authorized
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
INCMP _ 0
|
INCMP _ 0
|
||||||
|
LOAD validate_blocked_number 6
|
||||||
|
RELOAD validate_blocked_number
|
||||||
|
CATCH unregistered_number flag_unregistered_number 1
|
||||||
INCMP enter_others_new_pin *
|
INCMP enter_others_new_pin *
|
||||||
|
Binary file not shown.
@ -1,6 +1,3 @@
|
|||||||
LOAD validate_blocked_number 6
|
|
||||||
RELOAD validate_blocked_number
|
|
||||||
CATCH unregistered_number flag_unregistered_number 1
|
|
||||||
LOAD retrieve_blocked_number 0
|
LOAD retrieve_blocked_number 0
|
||||||
RELOAD retrieve_blocked_number
|
RELOAD retrieve_blocked_number
|
||||||
MAP retrieve_blocked_number
|
MAP retrieve_blocked_number
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -7,3 +7,4 @@ MOUT quit 9
|
|||||||
HALT
|
HALT
|
||||||
INCMP _ 1
|
INCMP _ 1
|
||||||
INCMP quit 9
|
INCMP quit 9
|
||||||
|
INCMP . *
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,5 @@
|
|||||||
|
LOAD clear_temporary_value 2
|
||||||
|
RELOAD clear_temporary_value
|
||||||
LOAD set_default_voucher 8
|
LOAD set_default_voucher 8
|
||||||
RELOAD set_default_voucher
|
RELOAD set_default_voucher
|
||||||
LOAD check_vouchers 10
|
LOAD check_vouchers 10
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,13 +1,7 @@
|
|||||||
LOAD authorize_account 12
|
|
||||||
RELOAD authorize_account
|
|
||||||
CATCH incorrect_pin flag_incorrect_pin 1
|
|
||||||
CATCH old_pin flag_allow_update 0
|
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
INCMP _ 0
|
INCMP _ 0
|
||||||
LOAD save_temporary_pin 6
|
|
||||||
LOAD verify_new_pin 0
|
|
||||||
RELOAD save_temporary_pin
|
RELOAD save_temporary_pin
|
||||||
RELOAD verify_new_pin
|
RELOAD verify_new_pin
|
||||||
|
CATCH invalid_pin flag_valid_pin 0
|
||||||
INCMP * confirm_pin_change
|
INCMP * confirm_pin_change
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
MOUT quit 9
|
MOUT quit 9
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
INCMP pin_management 0
|
INCMP ^ 0
|
||||||
INCMP quit 9
|
INCMP quit 9
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,7 +1,8 @@
|
|||||||
LOAD reset_allow_update 0
|
RELOAD reset_allow_update
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
RELOAD reset_allow_update
|
|
||||||
INCMP _ 0
|
INCMP _ 0
|
||||||
|
RELOAD authorize_account
|
||||||
|
CATCH incorrect_pin flag_incorrect_pin 1
|
||||||
|
CATCH _ flag_allow_update 0
|
||||||
INCMP new_pin *
|
INCMP new_pin *
|
||||||
|
|
||||||
|
Binary file not shown.
@ -3,3 +3,4 @@ MOUT quit 9
|
|||||||
HALT
|
HALT
|
||||||
INCMP _ 1
|
INCMP _ 1
|
||||||
INCMP quit 9
|
INCMP quit 9
|
||||||
|
INCMP . *
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -1,8 +1,14 @@
|
|||||||
|
LOAD set_back 6
|
||||||
|
LOAD authorize_account 5
|
||||||
|
LOAD reset_allow_update 4
|
||||||
|
LOAD verify_new_pin 2
|
||||||
|
LOAD save_temporary_pin 1
|
||||||
|
LOAD reset_incorrect 0
|
||||||
MOUT change_pin 1
|
MOUT change_pin 1
|
||||||
MOUT reset_pin 2
|
MOUT reset_pin 2
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
INCMP my_account 0
|
INCMP _ 0
|
||||||
INCMP old_pin 1
|
INCMP old_pin 1
|
||||||
INCMP enter_other_number 2
|
INCMP enter_other_number 2
|
||||||
INCMP . *
|
INCMP . *
|
||||||
|
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
MOUT retry 1
|
MOUT retry 1
|
||||||
MOUT quit 9
|
MOUT quit 9
|
||||||
HALT
|
HALT
|
||||||
INCMP confirm_pin_change 1
|
INCMP _ 1
|
||||||
INCMP quit 9
|
INCMP quit 9
|
||||||
|
INCMP . *
|
||||||
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user