Compare commits
2 Commits
582c90c32a
...
2fefbe5e6c
| Author | SHA1 | Date | |
|---|---|---|---|
| 2fefbe5e6c | |||
| fcdad8c2a3 |
@@ -1,296 +1,395 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
"os/signal"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
||||||
"github.com/libp2p/go-libp2p/core/peer"
|
|
||||||
ipfslite "github.com/hsanjuan/ipfs-lite"
|
|
||||||
badger "github.com/ipfs/go-ds-badger2"
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/k4lipso/pentapass/storage"
|
"github.com/k4lipso/pentapass/rpc"
|
||||||
"github.com/k4lipso/pentapass/crypto/age"
|
|
||||||
"github.com/k4lipso/pentapass/crypto"
|
"github.com/k4lipso/pentapass/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
topicNameFlag = flag.String("topicName", "akdjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd2", "name of topic to join")
|
|
||||||
dbPath = flag.String("db", "./db", "db file path")
|
dbPath = flag.String("db", "./db", "db file path")
|
||||||
nameSpace = flag.String("namespace", "crdt", "namespace")
|
|
||||||
logger = logging.Logger("globaldb")
|
logger = logging.Logger("globaldb")
|
||||||
// topicName = "globaldb-example"
|
// topicName = "globaldb-example"
|
||||||
// netTopic = "globaldb-example-net"
|
// netTopic = "globaldb-example-net"
|
||||||
// config = "globaldb-example"
|
// config = "globaldb-example"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Create the root command
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "ppass",
|
||||||
|
Short: "Interact with the Password Store",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the 'list' subcommand
|
||||||
|
var listCmd = &cobra.Command{
|
||||||
|
Use: "list",
|
||||||
|
Short: "List all passwords",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
//all, _ := cmd.Flags().GetBool("all")
|
||||||
|
dbPath, _ := cmd.Flags().GetString("db")
|
||||||
|
|
||||||
|
client, err := rpc.Receive(dbPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("dialing: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var names []string
|
||||||
|
namespace := "root"
|
||||||
|
err = client.Call("Query.GetAllNames", &namespace, &names)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range names {
|
||||||
|
fmt.Println(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var generateCmd = &cobra.Command{
|
||||||
|
Use: "generate",
|
||||||
|
Short: "Generate a Password",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
dbPath, _ := cmd.Flags().GetString("db")
|
||||||
|
client, err := rpc.Receive(dbPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("dialing: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceName := args[0]
|
||||||
|
|
||||||
|
var password *crypto.Password
|
||||||
|
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName }
|
||||||
|
err = client.Call("Query.Generate", &np, &password)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(*password)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var showCmd = &cobra.Command{
|
||||||
|
Use: "show",
|
||||||
|
Short: "show a Password",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
dbPath, _ := cmd.Flags().GetString("db")
|
||||||
|
client, err := rpc.Receive(dbPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("dialing: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceName := args[0]
|
||||||
|
|
||||||
|
var password *crypto.Password
|
||||||
|
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName }
|
||||||
|
err = client.Call("Query.Get", &np, &password)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(password.Password)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteCmd = &cobra.Command{
|
||||||
|
Use: "delete",
|
||||||
|
Short: "delete a Password",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
dbPath, _ := cmd.Flags().GetString("db")
|
||||||
|
client, err := rpc.Receive(dbPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("dialing: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceName := args[0]
|
||||||
|
|
||||||
|
var success *bool
|
||||||
|
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName }
|
||||||
|
err = client.Call("Query.Delete", &np, &success)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(*success)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Add flags to the 'list' command
|
||||||
|
//listCmd.Flags().BoolP("all", "a", false, "List all items")
|
||||||
|
rootCmd.PersistentFlags().String("db", "", "db path")
|
||||||
|
rootCmd.MarkPersistentFlagRequired("db")
|
||||||
|
|
||||||
|
// Add subcommands to the root command
|
||||||
|
rootCmd.AddCommand(listCmd)
|
||||||
|
rootCmd.AddCommand(generateCmd)
|
||||||
|
rootCmd.AddCommand(showCmd)
|
||||||
|
rootCmd.AddCommand(deleteCmd)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
if err := rootCmd.Execute(); err != nil {
|
||||||
ctx := context.Background()
|
fmt.Println(err)
|
||||||
data := *dbPath
|
os.Exit(1)
|
||||||
|
|
||||||
key, err := age.LoadOrGenerateKeys(*dbPath + "/age.key")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("AgeKey: %s\n", key.String())
|
//flag.Parse()
|
||||||
fmt.Printf("AgePublicKey: %s\n", key.Recipient().String())
|
|
||||||
|
|
||||||
//cipher, err := age.Encrypt([]byte("Test Message"), []string{key.Recipient().String()})
|
//client, err := rpc.Receive(*dbPath)
|
||||||
//fmt.Printf("Encrypted: %s\n", cipher)
|
|
||||||
//decrypted, err := age.Decrypt(cipher, key)
|
|
||||||
//fmt.Printf("Decrypted: %s\n", decrypted)
|
|
||||||
|
|
||||||
h, dht, err := storage.SetupLibp2pHost(ctx, *dbPath)
|
|
||||||
|
|
||||||
pid := h.ID().String()
|
|
||||||
fmt.Println(h.ID().String())
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ps, err := pubsub.NewGossipSub(ctx, h)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
//topic, err := ps.Join(*topicNameFlag)
|
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
// panic(err)
|
// fmt.Printf("dialing: %s\n", err)
|
||||||
|
// return
|
||||||
//}
|
//}
|
||||||
|
|
||||||
go storage.DiscoverPeers(ctx, h, dht)
|
//var names []string
|
||||||
|
//namespace := "root"
|
||||||
|
//err = client.Call("Query.GetAllNames", &namespace, &names)
|
||||||
|
|
||||||
store, err := badger.NewDatastore(data, &badger.DefaultOptions)
|
//if err != nil {
|
||||||
if err != nil {
|
// fmt.Println(err)
|
||||||
logger.Fatal(err)
|
//}
|
||||||
}
|
|
||||||
defer store.Close()
|
|
||||||
|
|
||||||
ipfs, err := ipfslite.New(ctx, store, nil, h, dht, nil)
|
//fmt.Println(names)
|
||||||
if err != nil {
|
|
||||||
logger.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
Cfg, err := storage.NewConfig(*dbPath + "/config.json")
|
//var password *crypto.Password
|
||||||
|
//np := rpc.NamespaceService{ Namespace: "root", Service: "Test" }
|
||||||
|
//err = client.Call("Query.Generate", &np, &password)
|
||||||
|
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
logger.Fatal(err)
|
// fmt.Println(err)
|
||||||
}
|
//}
|
||||||
|
|
||||||
storageHandler := storage.StorageHandler{
|
//fmt.Println(*password)
|
||||||
Ctx: ctx ,
|
|
||||||
Store: store,
|
|
||||||
Host: h,
|
|
||||||
Ipfs: ipfs,
|
|
||||||
PubSub: ps,
|
|
||||||
Key: key,
|
|
||||||
Config: Cfg,
|
|
||||||
}
|
|
||||||
|
|
||||||
storageHandler.InitNamespaces()
|
//var success bool
|
||||||
|
//err = client.Call("Query.Delete", &np, &success)
|
||||||
|
|
||||||
for _, val := range storageHandler.Namespaces {
|
//if success == true {
|
||||||
defer val.Close()
|
// fmt.Println("Deleted Test")
|
||||||
}
|
//}
|
||||||
|
|
||||||
fmt.Printf(`
|
//var password2 *crypto.Password
|
||||||
Peer ID: %s
|
//err = client.Call("Query.Get", &np, &password2)
|
||||||
Listen address: %s
|
|
||||||
Topic: %s
|
|
||||||
Data Folder: %s
|
|
||||||
|
|
||||||
Ready!
|
//if err != nil {
|
||||||
|
// fmt.Println(err)
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
Commands:
|
//fmt.Println(*password2)
|
||||||
|
|
||||||
> list -> list items in the store
|
// fmt.Printf(`
|
||||||
> get <key> -> get value for a key
|
//Peer ID: %s
|
||||||
> put <key> <value> -> store value on a key
|
//Listen address: %s
|
||||||
> exit -> quit
|
//Topic: %s
|
||||||
|
//Data Folder: %s
|
||||||
|
//
|
||||||
`,
|
//Ready!
|
||||||
pid, storage.Listen, *topicNameFlag, data,
|
//
|
||||||
)
|
//Commands:
|
||||||
|
//
|
||||||
if len(os.Args) > 1 && os.Args[1] == "daemon" {
|
//> list -> list items in the store
|
||||||
fmt.Println("Running in daemon mode")
|
//> get <key> -> get value for a key
|
||||||
go func() {
|
//> put <key> <value> -> store value on a key
|
||||||
for {
|
//> exit -> quit
|
||||||
fmt.Printf("%s - %d connected peers\n", time.Now().Format(time.Stamp), len(storage.ConnectedPeers(h)))
|
//
|
||||||
time.Sleep(10 * time.Second)
|
//
|
||||||
}
|
//`,
|
||||||
}()
|
// pid, storage.Listen, *topicNameFlag, data,
|
||||||
signalChan := make(chan os.Signal, 20)
|
// )
|
||||||
signal.Notify(
|
//
|
||||||
signalChan,
|
// if len(os.Args) > 1 && os.Args[1] == "daemon" {
|
||||||
syscall.SIGINT,
|
// fmt.Println("Running in daemon mode")
|
||||||
syscall.SIGTERM,
|
// go func() {
|
||||||
syscall.SIGHUP,
|
// for {
|
||||||
)
|
// fmt.Printf("%s - %d connected peers\n", time.Now().Format(time.Stamp), len(storage.ConnectedPeers(h)))
|
||||||
<-signalChan
|
// time.Sleep(10 * time.Second)
|
||||||
return
|
// }
|
||||||
}
|
// }()
|
||||||
|
// signalChan := make(chan os.Signal, 20)
|
||||||
fmt.Printf("> ")
|
// signal.Notify(
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
// signalChan,
|
||||||
for scanner.Scan() {
|
// syscall.SIGINT,
|
||||||
text := scanner.Text()
|
// syscall.SIGTERM,
|
||||||
fields := strings.Fields(text)
|
// syscall.SIGHUP,
|
||||||
if len(fields) == 0 {
|
// )
|
||||||
fmt.Printf("> ")
|
// <-signalChan
|
||||||
continue
|
// return
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
cmd := fields[0]
|
// fmt.Printf("> ")
|
||||||
|
// scanner := bufio.NewScanner(os.Stdin)
|
||||||
switch cmd {
|
// for scanner.Scan() {
|
||||||
case "exit", "quit":
|
// text := scanner.Text()
|
||||||
return
|
// fields := strings.Fields(text)
|
||||||
case "debug":
|
// if len(fields) == 0 {
|
||||||
if len(fields) < 2 {
|
// fmt.Printf("> ")
|
||||||
fmt.Println("debug <on/off/peers>")
|
// continue
|
||||||
}
|
// }
|
||||||
st := fields[1]
|
//
|
||||||
switch st {
|
// cmd := fields[0]
|
||||||
case "on":
|
//
|
||||||
logging.SetLogLevel("globaldb", "debug")
|
// switch cmd {
|
||||||
case "off":
|
// case "exit", "quit":
|
||||||
logging.SetLogLevel("globaldb", "error")
|
// return
|
||||||
case "peers":
|
// case "debug":
|
||||||
for _, p := range storage.ConnectedPeers(h) {
|
// if len(fields) < 2 {
|
||||||
addrs, err := peer.AddrInfoToP2pAddrs(p)
|
// fmt.Println("debug <on/off/peers>")
|
||||||
if err != nil {
|
// }
|
||||||
logger.Warn(err)
|
// st := fields[1]
|
||||||
continue
|
// switch st {
|
||||||
}
|
// case "on":
|
||||||
for _, a := range addrs {
|
// logging.SetLogLevel("globaldb", "debug")
|
||||||
fmt.Println(a)
|
// case "off":
|
||||||
}
|
// logging.SetLogLevel("globaldb", "error")
|
||||||
}
|
// case "peers":
|
||||||
}
|
// for _, p := range storage.ConnectedPeers(h) {
|
||||||
case "list":
|
// addrs, err := peer.AddrInfoToP2pAddrs(p)
|
||||||
if len(fields) < 2 {
|
// if err != nil {
|
||||||
fmt.Printf("Available Namespaces:\n")
|
// logger.Warn(err)
|
||||||
for k := range storageHandler.Namespaces {
|
// continue
|
||||||
fmt.Printf("%s\n", k)
|
// }
|
||||||
}
|
// for _, a := range addrs {
|
||||||
continue
|
// fmt.Println(a)
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
namespace := fields[1]
|
// }
|
||||||
|
// case "list":
|
||||||
fmt.Printf("Listing content of %s", namespace)
|
// if len(fields) < 2 {
|
||||||
|
// fmt.Printf("Available Namespaces:\n")
|
||||||
val, ok := storageHandler.Namespaces[namespace]
|
// for k := range storageHandler.Namespaces {
|
||||||
|
// fmt.Printf("%s\n", k)
|
||||||
if !ok {
|
// }
|
||||||
fmt.Println("Namespace does not exist")
|
// continue
|
||||||
continue
|
// }
|
||||||
}
|
//
|
||||||
|
// namespace := fields[1]
|
||||||
val.List()
|
//
|
||||||
case "get":
|
// fmt.Printf("Listing content of %s", namespace)
|
||||||
if len(fields) < 3 {
|
//
|
||||||
fmt.Println("get <namespace> <key>")
|
// val, ok := storageHandler.Namespaces[namespace]
|
||||||
fmt.Println("> ")
|
//
|
||||||
continue
|
// if !ok {
|
||||||
}
|
// fmt.Println("Namespace does not exist")
|
||||||
|
// continue
|
||||||
namespace := fields[1]
|
// }
|
||||||
|
//
|
||||||
val, ok := storageHandler.Namespaces[namespace]
|
// val.List()
|
||||||
|
// case "get":
|
||||||
if !ok {
|
// if len(fields) < 3 {
|
||||||
fmt.Println("Namespace does not exist")
|
// fmt.Println("get <namespace> <key>")
|
||||||
continue
|
// fmt.Println("> ")
|
||||||
}
|
// continue
|
||||||
|
// }
|
||||||
k := fields[2]
|
//
|
||||||
v, err := val.Get(k)
|
// namespace := fields[1]
|
||||||
if err != nil {
|
//
|
||||||
printErr(err)
|
// val, ok := storageHandler.Namespaces[namespace]
|
||||||
continue
|
//
|
||||||
}
|
// if !ok {
|
||||||
|
// fmt.Println("Namespace does not exist")
|
||||||
fmt.Printf("[%s] -> %s\n", k, string(v))
|
// continue
|
||||||
case "generate":
|
// }
|
||||||
if len(fields) < 3 {
|
//
|
||||||
fmt.Println("generate <namespace> <Service>")
|
// k := fields[2]
|
||||||
fmt.Println("> ")
|
// v, err := val.Get(k)
|
||||||
continue
|
// if err != nil {
|
||||||
}
|
// printErr(err)
|
||||||
|
// continue
|
||||||
namespace := fields[1]
|
// }
|
||||||
|
//
|
||||||
val, ok := storageHandler.Namespaces[namespace]
|
// fmt.Printf("[%s] -> %s\n", k, string(v))
|
||||||
|
// case "generate":
|
||||||
if !ok {
|
// if len(fields) < 3 {
|
||||||
fmt.Println("Namespace does not exist")
|
// fmt.Println("generate <namespace> <Service>")
|
||||||
continue
|
// fmt.Println("> ")
|
||||||
}
|
// continue
|
||||||
|
// }
|
||||||
service := fields[2]
|
//
|
||||||
password := crypto.NewPassword()
|
// namespace := fields[1]
|
||||||
password.Service = service
|
//
|
||||||
|
// val, ok := storageHandler.Namespaces[namespace]
|
||||||
data, err := password.ToJson()
|
//
|
||||||
if err != nil {
|
// if !ok {
|
||||||
printErr(err)
|
// fmt.Println("Namespace does not exist")
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
encryptedPassword, err := age.Encrypt(data, val.GetRecipients())
|
// service := fields[2]
|
||||||
if err != nil {
|
// password := crypto.NewPassword()
|
||||||
printErr(err)
|
// password.Service = service
|
||||||
continue
|
//
|
||||||
}
|
// data, err := password.ToJson()
|
||||||
|
// if err != nil {
|
||||||
err = val.Put(password.Id.String(), string(encryptedPassword))
|
// printErr(err)
|
||||||
if err != nil {
|
// continue
|
||||||
printErr(err)
|
// }
|
||||||
continue
|
//
|
||||||
}
|
// encryptedPassword, err := age.Encrypt(data, val.GetRecipients())
|
||||||
case "put":
|
// if err != nil {
|
||||||
if len(fields) < 4 {
|
// printErr(err)
|
||||||
fmt.Println("put <namespace> <key> <value>")
|
// continue
|
||||||
fmt.Println("> ")
|
// }
|
||||||
continue
|
//
|
||||||
}
|
// //err = val.Put(password.Id.String(), string(encryptedPassword))
|
||||||
|
// err = val.Put(password.Service, string(encryptedPassword))
|
||||||
namespace := fields[1]
|
// if err != nil {
|
||||||
|
// printErr(err)
|
||||||
val, ok := storageHandler.Namespaces[namespace]
|
// continue
|
||||||
|
// }
|
||||||
if !ok {
|
// case "put":
|
||||||
fmt.Println("Namespace does not exist")
|
// if len(fields) < 4 {
|
||||||
continue
|
// fmt.Println("put <namespace> <key> <value>")
|
||||||
}
|
// fmt.Println("> ")
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
k := fields[2]
|
//
|
||||||
v := strings.Join(fields[3:], " ")
|
// namespace := fields[1]
|
||||||
err := val.Put(k, v)
|
//
|
||||||
if err != nil {
|
// val, ok := storageHandler.Namespaces[namespace]
|
||||||
printErr(err)
|
//
|
||||||
continue
|
// if !ok {
|
||||||
}
|
// fmt.Println("Namespace does not exist")
|
||||||
}
|
// continue
|
||||||
fmt.Printf("> ")
|
// }
|
||||||
}
|
//
|
||||||
|
//
|
||||||
|
// k := fields[2]
|
||||||
|
// v := strings.Join(fields[3:], " ")
|
||||||
|
// err := val.Put(k, v)
|
||||||
|
// if err != nil {
|
||||||
|
// printErr(err)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// fmt.Printf("> ")
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func printErr(err error) {
|
func printErr(err error) {
|
||||||
|
|||||||
103
cmd/ppassd/ppassd.go
Normal file
103
cmd/ppassd/ppassd.go
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||||
|
ipfslite "github.com/hsanjuan/ipfs-lite"
|
||||||
|
badger "github.com/ipfs/go-ds-badger2"
|
||||||
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
|
||||||
|
"github.com/k4lipso/pentapass/storage"
|
||||||
|
"github.com/k4lipso/pentapass/rpc"
|
||||||
|
"github.com/k4lipso/pentapass/crypto/age"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
topicNameFlag = flag.String("topicName", "akdjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd2", "name of topic to join")
|
||||||
|
dbPath = flag.String("db", "./db", "db file path")
|
||||||
|
nameSpace = flag.String("namespace", "crdt", "namespace")
|
||||||
|
logger = logging.Logger("globaldb")
|
||||||
|
// topicName = "globaldb-example"
|
||||||
|
// netTopic = "globaldb-example-net"
|
||||||
|
// config = "globaldb-example"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
ctx := context.Background()
|
||||||
|
data := *dbPath
|
||||||
|
|
||||||
|
key, err := age.LoadOrGenerateKeys(*dbPath + "/age.key")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("AgeKey: %s\n", key.String())
|
||||||
|
fmt.Printf("AgePublicKey: %s\n", key.Recipient().String())
|
||||||
|
|
||||||
|
//cipher, err := age.Encrypt([]byte("Test Message"), []string{key.Recipient().String()})
|
||||||
|
//fmt.Printf("Encrypted: %s\n", cipher)
|
||||||
|
//decrypted, err := age.Decrypt(cipher, key)
|
||||||
|
//fmt.Printf("Decrypted: %s\n", decrypted)
|
||||||
|
|
||||||
|
h, dht, err := storage.SetupLibp2pHost(ctx, *dbPath)
|
||||||
|
|
||||||
|
fmt.Println(h.ID().String())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ps, err := pubsub.NewGossipSub(ctx, h)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//topic, err := ps.Join(*topicNameFlag)
|
||||||
|
//if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
//}
|
||||||
|
|
||||||
|
go storage.DiscoverPeers(ctx, h, dht)
|
||||||
|
|
||||||
|
store, err := badger.NewDatastore(data, &badger.DefaultOptions)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal(err)
|
||||||
|
}
|
||||||
|
defer store.Close()
|
||||||
|
|
||||||
|
ipfs, err := ipfslite.New(ctx, store, nil, h, dht, nil)
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
Cfg, err := storage.NewConfig(*dbPath + "/config.json")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
storageHandler := storage.StorageHandler{
|
||||||
|
Ctx: ctx ,
|
||||||
|
Store: store,
|
||||||
|
Host: h,
|
||||||
|
Ipfs: ipfs,
|
||||||
|
PubSub: ps,
|
||||||
|
Key: key,
|
||||||
|
Config: Cfg,
|
||||||
|
}
|
||||||
|
|
||||||
|
storageHandler.InitNamespaces()
|
||||||
|
|
||||||
|
for _, val := range storageHandler.Namespaces {
|
||||||
|
defer val.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc.StorageHandler = &storageHandler
|
||||||
|
rpc.Serve(*dbPath)
|
||||||
|
}
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/rand"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DEFAULT_LENGTH int = 25
|
||||||
|
|
||||||
type Password struct {
|
type Password struct {
|
||||||
Service string `json:"Service"`
|
Service string `json:"Service"`
|
||||||
Url string `json:"Url"`
|
Url string `json:"Url"`
|
||||||
@@ -21,7 +24,7 @@ func (p *Password) ToJson() ([]byte, error) {
|
|||||||
|
|
||||||
func GetPasswordFromJson(b []byte) (Password, error) {
|
func GetPasswordFromJson(b []byte) (Password, error) {
|
||||||
var result Password
|
var result Password
|
||||||
err := json.Unmarshal(b, result)
|
err := json.Unmarshal(b, &result)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Password{}, err
|
return Password{}, err
|
||||||
@@ -30,9 +33,20 @@ func GetPasswordFromJson(b []byte) (Password, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPassword() *Password {
|
func NewPassword(length int) *Password {
|
||||||
return &Password{
|
return &Password{
|
||||||
Id: uuid.New(),
|
Id: uuid.New(),
|
||||||
|
Password: GenerateRandomString(length),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateRandomString(length int) string {
|
||||||
|
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
b := make([]byte, length)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = charset[rand.Intn(len(charset))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
5
go.mod
5
go.mod
@@ -4,6 +4,7 @@ go 1.22.5
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/age v1.2.0
|
filippo.io/age v1.2.0
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
github.com/hsanjuan/ipfs-lite v1.8.2
|
github.com/hsanjuan/ipfs-lite v1.8.2
|
||||||
github.com/ipfs/go-datastore v0.6.0
|
github.com/ipfs/go-datastore v0.6.0
|
||||||
github.com/ipfs/go-ds-badger2 v0.1.3
|
github.com/ipfs/go-ds-badger2 v0.1.3
|
||||||
@@ -13,6 +14,7 @@ require (
|
|||||||
github.com/libp2p/go-libp2p-kad-dht v0.25.2
|
github.com/libp2p/go-libp2p-kad-dht v0.25.2
|
||||||
github.com/libp2p/go-libp2p-pubsub v0.11.0
|
github.com/libp2p/go-libp2p-pubsub v0.11.0
|
||||||
github.com/multiformats/go-multiaddr v0.13.0
|
github.com/multiformats/go-multiaddr v0.13.0
|
||||||
|
github.com/spf13/cobra v0.0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -48,13 +50,13 @@ require (
|
|||||||
github.com/golang/snappy v0.0.1 // indirect
|
github.com/golang/snappy v0.0.1 // indirect
|
||||||
github.com/google/gopacket v1.1.19 // indirect
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
|
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||||
github.com/huin/goupnp v1.3.0 // indirect
|
github.com/huin/goupnp v1.3.0 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
github.com/ipfs/bbloom v0.0.4 // indirect
|
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||||
github.com/ipfs/boxo v0.21.0 // indirect
|
github.com/ipfs/boxo v0.21.0 // indirect
|
||||||
github.com/ipfs/go-bitfield v1.1.0 // indirect
|
github.com/ipfs/go-bitfield v1.1.0 // indirect
|
||||||
@@ -138,6 +140,7 @@ require (
|
|||||||
github.com/quic-go/webtransport-go v0.8.0 // indirect
|
github.com/quic-go/webtransport-go v0.8.0 // indirect
|
||||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.3 // indirect
|
||||||
github.com/stretchr/testify v1.9.0 // indirect
|
github.com/stretchr/testify v1.9.0 // indirect
|
||||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
|
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
|
||||||
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
|
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
|
||||||
|
|||||||
3
go.sum
3
go.sum
@@ -188,6 +188,7 @@ github.com/hsanjuan/ipfs-lite v1.8.2 h1:PwYpfvh4HpActJyP03O4k6QznBR3xd6NmRWeOSJu
|
|||||||
github.com/hsanjuan/ipfs-lite v1.8.2/go.mod h1:PfY4I2whwnZBHviwoajNzwjSyR9IQIJHxkpPAc5SLxw=
|
github.com/hsanjuan/ipfs-lite v1.8.2/go.mod h1:PfY4I2whwnZBHviwoajNzwjSyR9IQIJHxkpPAc5SLxw=
|
||||||
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
|
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
|
||||||
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||||
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
|
||||||
@@ -487,8 +488,10 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
|
|||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|||||||
139
rpc/rpc.go
Normal file
139
rpc/rpc.go
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/rpc"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/k4lipso/pentapass/storage"
|
||||||
|
"github.com/k4lipso/pentapass/crypto"
|
||||||
|
"github.com/k4lipso/pentapass/crypto/age"
|
||||||
|
)
|
||||||
|
|
||||||
|
var StorageHandler *storage.StorageHandler
|
||||||
|
|
||||||
|
type Query int
|
||||||
|
|
||||||
|
type NamespaceService struct {
|
||||||
|
Namespace string
|
||||||
|
Service string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Query) Generate(np *NamespaceService, reply *crypto.Password) error {
|
||||||
|
val, ok := StorageHandler.Namespaces[np.Namespace]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Namespace does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
password := crypto.NewPassword(crypto.DEFAULT_LENGTH)
|
||||||
|
password.Service = np.Service
|
||||||
|
|
||||||
|
data, err := password.ToJson()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedPassword, err := age.Encrypt(data, val.GetRecipients())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = val.Put(password.Service, string(encryptedPassword))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*reply = *password
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Query) Get(np *NamespaceService, reply *crypto.Password) error {
|
||||||
|
namespace := np.Namespace
|
||||||
|
val, ok := StorageHandler.Namespaces[namespace]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Namespace does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := val.GetPassword(np.Service)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*reply = v
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (t *Query) Add(password *crypto.Password, reply *[]string) error {
|
||||||
|
// return nil
|
||||||
|
//}
|
||||||
|
|
||||||
|
func (t *Query) Delete(np *NamespaceService, success *bool) error {
|
||||||
|
namespace := np.Namespace
|
||||||
|
val, ok := StorageHandler.Namespaces[namespace]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Namespace does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := val.Delete(np.Service)
|
||||||
|
if err != nil {
|
||||||
|
*success = false
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*success = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Query) GetAllNames(namespace *string, reply *[]string) error {
|
||||||
|
fmt.Println("RPC Request: Query::LoadedTriggers")
|
||||||
|
fmt.Printf("Listing content of %s", *namespace)
|
||||||
|
|
||||||
|
val, ok := StorageHandler.Namespaces[*namespace]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Namesapce does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
*reply = val.GetAllNames()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Serve(path string) {
|
||||||
|
query := new(Query)
|
||||||
|
rpc.Register(query)
|
||||||
|
rpc.HandleHTTP()
|
||||||
|
l, err := net.Listen("unix", path + "/rpc_test.socket")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error while listening on unix socket: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
go http.Serve(l, nil)
|
||||||
|
|
||||||
|
sigc := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigc, os.Interrupt, syscall.SIGTERM)
|
||||||
|
func(ln net.Listener, c chan os.Signal) {
|
||||||
|
sig := <-c
|
||||||
|
fmt.Printf("Caught signal %s: shutting down.\n", sig)
|
||||||
|
ln.Close()
|
||||||
|
os.Exit(0)
|
||||||
|
}(l, sigc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Receive(path string) (*rpc.Client, error) {
|
||||||
|
client, err := rpc.DialHTTP("unix", path + "/rpc_test.socket")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Cant connect to RPC server: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, err
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
topicNameFlag = "afbjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd2"
|
topicNameFlag = "afbjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd4"
|
||||||
logger = logging.Logger("globaldb")
|
logger = logging.Logger("globaldb")
|
||||||
Listen = libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0")
|
Listen = libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0")
|
||||||
)
|
)
|
||||||
@@ -216,6 +216,42 @@ func (n *Namespace) Put(k string, v string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Namespace) Delete(k string) error {
|
||||||
|
key := ds.NewKey(k)
|
||||||
|
err := n.Datastore.Delete(n.ctx, key)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
printErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Namespace) GetPassword(k string) (password.Password, error) {
|
||||||
|
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
|
||||||
|
if err != nil {
|
||||||
|
printErr(err)
|
||||||
|
return password.Password{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
val, err := age.Decrypt(v, n.Key)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
printErr(err)
|
||||||
|
return password.Password{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pw, err := password.GetPasswordFromJson(val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
printErr(err)
|
||||||
|
return password.Password{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pw, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func (n *Namespace) Get(k string) (string, error) {
|
func (n *Namespace) Get(k string) (string, error) {
|
||||||
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
|
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -226,6 +262,27 @@ func (n *Namespace) Get(k string) (string, error) {
|
|||||||
return string(v), nil
|
return string(v), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Namespace) GetAllNames() []string {
|
||||||
|
q := query.Query{}
|
||||||
|
results, err := n.Datastore.Query(n.ctx, q)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
printErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []string
|
||||||
|
for r := range results.Next() {
|
||||||
|
if r.Error != nil {
|
||||||
|
printErr(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, r.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Namespace) List() {
|
func (n *Namespace) List() {
|
||||||
q := query.Query{}
|
q := query.Query{}
|
||||||
results, err := n.Datastore.Query(n.ctx, q)
|
results, err := n.Datastore.Query(n.ctx, q)
|
||||||
@@ -375,8 +432,7 @@ func CreateNamespace(ID string, storageHandler StorageHandler) (*Namespace, erro
|
|||||||
opts.Logger = logger
|
opts.Logger = logger
|
||||||
opts.RebroadcastInterval = 5 * time.Second
|
opts.RebroadcastInterval = 5 * time.Second
|
||||||
opts.PutHook = func(k ds.Key, v []byte) {
|
opts.PutHook = func(k ds.Key, v []byte) {
|
||||||
fmt.Printf("Added: [%s] -> %s\n", k, string(v))
|
fmt.Printf("Added: [%s]\n", k)
|
||||||
|
|
||||||
}
|
}
|
||||||
opts.DeleteHook = func(k ds.Key) {
|
opts.DeleteHook = func(k ds.Key) {
|
||||||
fmt.Printf("Removed: [%s]\n", k)
|
fmt.Printf("Removed: [%s]\n", k)
|
||||||
|
|||||||
Reference in New Issue
Block a user