Add keyinfo restore

This commit is contained in:
lash 2024-12-07 23:06:03 +00:00
parent ff943a125c
commit 3416fdf50c
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
5 changed files with 151 additions and 40 deletions

View File

@ -20,7 +20,7 @@ type UserDataStore struct {
func (store *UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error) { func (store *UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error) {
store.SetPrefix(db.DATATYPE_USERDATA) store.SetPrefix(db.DATATYPE_USERDATA)
store.SetSession(sessionId) store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId)) k := ToBytes(typ)
return store.Get(ctx, k) return store.Get(ctx, k)
} }
@ -29,6 +29,6 @@ func (store *UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ
func (store *UserDataStore) WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error { func (store *UserDataStore) WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error {
store.SetPrefix(db.DATATYPE_USERDATA) store.SetPrefix(db.DATATYPE_USERDATA)
store.SetSession(sessionId) store.SetSession(sessionId)
k := PackKey(typ, []byte(sessionId)) k := ToBytes(typ)
return store.Put(ctx, k, value) return store.Put(ctx, k, value)
} }

View File

@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"encoding/binary" "encoding/binary"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/common" "git.grassecon.net/urdt/ussd/common"
"git.defalsify.org/vise.git/db"
) )
var ( var (
@ -30,11 +30,12 @@ func ToKeyInfo(k []byte, sessionId string) (KeyInfo, error) {
o.SessionId = sessionId o.SessionId = sessionId
k = k[len(b):] o.Typ = uint8(k[0])
o.Typ = k[0]
k = k[1:] k = k[1:]
o.SessionId = string(k[:len(b)])
k = k[len(b):]
if o.Typ == storage.DATATYPE_USERSUB { if o.Typ == db.DATATYPE_USERDATA {
if len(k) == 0 { if len(k) == 0 {
return o, fmt.Errorf("missing subtype key") return o, fmt.Errorf("missing subtype key")
} }
@ -53,8 +54,19 @@ func ToKeyInfo(k []byte, sessionId string) (KeyInfo, error) {
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 common.DataTyp) string { func subTypToString(v common.DataTyp) string {
return dbTypStr[v + storage.DATATYPE_USERSUB + 1] return dbTypStr[v + db.DATATYPE_USERDATA + 1]
} }
func typToString(v uint8) string { func typToString(v uint8) string {

View File

@ -6,33 +6,43 @@ import (
"git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/db"
"git.grassecon.net/urdt/ussd/common" "git.grassecon.net/urdt/ussd/common"
"git.grassecon.net/urdt/ussd/internal/storage"
) )
func init() { func init() {
DebugCap |= 1 DebugCap |= 1
dbTypStr[db.DATATYPE_STATE] = "internal_state" dbTypStr[db.DATATYPE_STATE] = "internal state"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT] = "account" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT] = "account"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT_CREATED] = "account_created" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT_CREATED] = "account created"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_TRACKING_ID] = "tracking id" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TRACKING_ID] = "tracking id"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_PUBLIC_KEY] = "public key" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_PUBLIC_KEY] = "public key"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_CUSTODIAL_ID] = "custodial id" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_CUSTODIAL_ID] = "custodial id"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT_PIN] = "account pin" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT_PIN] = "account pin"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT_STATUS] = "account status" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACCOUNT_STATUS] = "account status"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_FIRST_NAME] = "first name" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_FIRST_NAME] = "first name"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_FAMILY_NAME] = "family name" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_FAMILY_NAME] = "family name"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_YOB] = "year of birth" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_YOB] = "year of birth"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_LOCATION] = "location" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_LOCATION] = "location"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_GENDER] = "gender" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_GENDER] = "gender"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_OFFERINGS] = "offerings" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_OFFERINGS] = "offerings"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_RECIPIENT] = "recipient" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_RECIPIENT] = "recipient"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_AMOUNT] = "amount" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_AMOUNT] = "amount"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_TEMPORARY_VALUE] = "temporary value" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TEMPORARY_VALUE] = "temporary value"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_SYM] = "active sym" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_SYM] = "active sym"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_BAL] = "active bal" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_BAL] = "active bal"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_BLOCKED_NUMBER] = "blocked number" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_BLOCKED_NUMBER] = "blocked number"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_PUBLIC_KEY_REVERSE] = "public_key_reverse" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_PUBLIC_KEY_REVERSE] = "public_key_reverse"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_DECIMAL] = "active decimal" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_DECIMAL] = "active decimal"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_ADDRESS] = "active address" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_ACTIVE_ADDRESS] = "active address"
dbTypStr[storage.DATATYPE_USERDATA + 1 + common.DATA_TRANSACTIONS] = "transactions" dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_VOUCHER_SYMBOLS] = "voucher symbols"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_VOUCHER_BALANCES] = "voucher balances"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_VOUCHER_DECIMALS] = "voucher decimals"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_VOUCHER_ADDRESSES] = "voucher addresses"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_SENDERS] = "tx senders"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_RECIPIENTS] = "tx recipients"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_VALUES] = "tx values"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_ADDRESSES] = "tx addresses"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_HASHES] = "tx hashes"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_DATES] = "tx dates"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_SYMBOLS] = "tx symbols"
dbTypStr[db.DATATYPE_USERDATA + 1 + common.DATA_TX_DECIMALS] = "tx decimals"
} }

View File

@ -2,12 +2,16 @@ package debug
import ( import (
"testing" "testing"
"git.grassecon.net/urdt/ussd/common"
"git.defalsify.org/vise.git/db"
) )
func TestDebugDbSubKeyInfo(t *testing.T) { func TestDebugDbSubKeyInfo(t *testing.T) {
s := "foo" s := "foo"
b := []byte(s) b := []byte{0x20}
b = append(b, []byte{0x40, 0x00, 0x02}...) b = append(b, []byte(s)...)
b = append(b, []byte{0x00, 0x02}...)
r, err := ToKeyInfo(b, s) r, err := ToKeyInfo(b, s)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -15,7 +19,7 @@ func TestDebugDbSubKeyInfo(t *testing.T) {
if r.SessionId != s { if r.SessionId != s {
t.Fatalf("expected %s, got %s", s, r.SessionId) t.Fatalf("expected %s, got %s", s, r.SessionId)
} }
if r.Typ != 64 { if r.Typ != 32 {
t.Fatalf("expected 64, got %d", r.Typ) t.Fatalf("expected 64, got %d", r.Typ)
} }
if r.SubTyp != 2 { if r.SubTyp != 2 {
@ -30,8 +34,32 @@ func TestDebugDbSubKeyInfo(t *testing.T) {
func TestDebugDbKeyInfo(t *testing.T) { func TestDebugDbKeyInfo(t *testing.T) {
s := "bar" s := "bar"
b := []byte(s) b := []byte{0x10}
b = append(b, []byte{0x20}...) b = append(b, []byte(s)...)
r, err := ToKeyInfo(b, s)
if err != nil {
t.Fatal(err)
}
if r.SessionId != s {
t.Fatalf("expected %s, got %s", s, r.SessionId)
}
if r.Typ != 16 {
t.Fatalf("expected 16, got %d", r.Typ)
}
if DebugCap & 1 > 0 {
if r.Label != "internal state" {
t.Fatalf("expected 'internal_state', got '%s'", r.Label)
}
}
}
func TestDebugDbKeyInfoRestore(t *testing.T) {
s := "bar"
b := []byte{db.DATATYPE_USERDATA}
b = append(b, []byte(s)...)
k := common.ToBytes(common.DATA_ACTIVE_SYM)
b = append(b, k...)
r, err := ToKeyInfo(b, s) r, err := ToKeyInfo(b, s)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -40,11 +68,11 @@ func TestDebugDbKeyInfo(t *testing.T) {
t.Fatalf("expected %s, got %s", s, r.SessionId) t.Fatalf("expected %s, got %s", s, r.SessionId)
} }
if r.Typ != 32 { if r.Typ != 32 {
t.Fatalf("expected 64, got %d", r.Typ) t.Fatalf("expected 32, got %d", r.Typ)
} }
if DebugCap & 1 > 0 { if DebugCap & 1 > 0 {
if r.Label != "userdata" { if r.Label != "active sym" {
t.Fatalf("expected 'userdata', got '%s'", r.Label) t.Fatalf("expected 'active sym', got '%s'", r.Label)
} }
} }
} }

61
devtools/gen/main.go Normal file
View File

@ -0,0 +1,61 @@
package main
import (
"context"
"flag"
"fmt"
"os"
"path"
"git.defalsify.org/vise.git/logging"
"git.grassecon.net/urdt/ussd/config"
"git.grassecon.net/urdt/ussd/internal/storage"
"git.grassecon.net/urdt/ussd/common"
)
var (
logg = logging.NewVanilla()
scriptDir = path.Join("services", "registration")
)
func main() {
config.LoadConfig()
var dbDir string
var sessionId string
var database string
var engineDebug bool
flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
flag.StringVar(&database, "db", "gdbm", "database to be used")
flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
flag.BoolVar(&engineDebug, "d", false, "use engine debug output")
flag.Parse()
ctx := context.Background()
ctx = context.WithValue(ctx, "SessionId", sessionId)
ctx = context.WithValue(ctx, "Database", database)
resourceDir := scriptDir
menuStorageService := storage.NewMenuStorageService(dbDir, resourceDir)
store, err := menuStorageService.GetUserdataDb(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
userStore := common.UserDataStore{store}
err = userStore.WriteEntry(ctx, sessionId, common.DATA_AMOUNT, []byte("1.0"))
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
err = store.Close()
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
}