Add more logging
This commit is contained in:
parent
82d576d546
commit
3a1e47ff67
@ -15,28 +15,33 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func handleGetBiometricsKey(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) {
|
func handleGetBiometricsKey(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, ctx *sockets.CallingContext) (response messages.IPCMessage, err error) {
|
||||||
|
actionsLog.Info("Browser Biometrics: Key requested, verifying biometrics...")
|
||||||
if !(systemauth.VerifyPinSession(*ctx) || biometrics.CheckBiometrics(biometrics.BrowserBiometrics)) {
|
if !(systemauth.VerifyPinSession(*ctx) || biometrics.CheckBiometrics(biometrics.BrowserBiometrics)) {
|
||||||
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
|
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
Message: "not approved",
|
Message: "not approved",
|
||||||
})
|
})
|
||||||
|
actionsLog.Info("Browser Biometrics: Biometrics not approved %v", err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return messages.IPCMessage{}, err
|
return messages.IPCMessage{}, err
|
||||||
}
|
}
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionsLog.Info("Browser Biometrics: Biometrics verified, asking for approval...")
|
||||||
if approved, err := pinentry.GetApproval("Approve Credential Access", fmt.Sprintf("%s on %s>%s>%s is trying to access your vault encryption key for browser biometric unlock.", ctx.UserName, ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName)); err != nil || !approved {
|
if approved, err := pinentry.GetApproval("Approve Credential Access", fmt.Sprintf("%s on %s>%s>%s is trying to access your vault encryption key for browser biometric unlock.", ctx.UserName, ctx.GrandParentProcessName, ctx.ParentProcessName, ctx.ProcessName)); err != nil || !approved {
|
||||||
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
|
response, err = messages.IPCMessageFromPayload(messages.ActionResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
Message: "not approved",
|
Message: "not approved",
|
||||||
})
|
})
|
||||||
|
actionsLog.Info("Browser Biometrics: Biometrics not approved %v", err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return messages.IPCMessage{}, err
|
return messages.IPCMessage{}, err
|
||||||
}
|
}
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionsLog.Info("Browser Biometrics: Approved, getting key...")
|
||||||
masterKey, err := cfg.GetMasterKey()
|
masterKey, err := cfg.GetMasterKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return messages.IPCMessage{}, err
|
return messages.IPCMessage{}, err
|
||||||
@ -45,6 +50,7 @@ func handleGetBiometricsKey(request messages.IPCMessage, cfg *config.Config, vau
|
|||||||
response, err = messages.IPCMessageFromPayload(messages.GetBiometricsKeyResponse{
|
response, err = messages.IPCMessageFromPayload(messages.GetBiometricsKeyResponse{
|
||||||
Key: masterKeyB64,
|
Key: masterKeyB64,
|
||||||
})
|
})
|
||||||
|
actionsLog.Info("Browser Biometrics: Sending key...")
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,10 +185,20 @@ func handlePinStatus(request messages.IPCMessage, cfg *config.Config, vault *vau
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleVaultStatus(request messages.IPCMessage, cfg *config.Config, vault *vault.Vault, callingContext *sockets.CallingContext) (response messages.IPCMessage, err error) {
|
||||||
|
var vaultStatus messages.VaultStatusResponse = messages.VaultStatusResponse{}
|
||||||
|
vaultStatus.Locked = cfg.IsLocked()
|
||||||
|
vaultStatus.NumberOfLogins = len(vault.GetLogins())
|
||||||
|
vaultStatus.NumberOfNotes = len(vault.GetNotes())
|
||||||
|
response, err = messages.IPCMessageFromPayload(vaultStatus)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.UnlockVaultRequest{}), handleUnlockVault)
|
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.UnlockVaultRequest{}), handleUnlockVault)
|
||||||
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.LockVaultRequest{}), handleLockVault)
|
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.LockVaultRequest{}), handleLockVault)
|
||||||
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.WipeVaultRequest{}), handleWipeVault)
|
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.WipeVaultRequest{}), handleWipeVault)
|
||||||
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.UpdateVaultPINRequest{}), ensureBiometricsAuthorized(systemauth.AccessVault, handleUpdateVaultPin))
|
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.UpdateVaultPINRequest{}), ensureBiometricsAuthorized(systemauth.AccessVault, handleUpdateVaultPin))
|
||||||
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.GetVaultPINRequest{}), handlePinStatus)
|
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.GetVaultPINRequest{}), handlePinStatus)
|
||||||
|
AgentActionsRegistry.Register(messages.MessageTypeForEmptyPayload(messages.VaultStatusRequest{}), handleVaultStatus)
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,12 @@ package crypto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/quexten/goldwarden/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var keyringLog = logging.GetLogger("Goldwarden", "Keyring")
|
||||||
|
|
||||||
type Keyring struct {
|
type Keyring struct {
|
||||||
AccountKey SymmetricEncryptionKey
|
AccountKey SymmetricEncryptionKey
|
||||||
AsymmetricEncyryptionKey AsymmetricEncryptionKey
|
AsymmetricEncyryptionKey AsymmetricEncryptionKey
|
||||||
@ -12,12 +16,14 @@ type Keyring struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryKeyring(accountKey *MemorySymmetricEncryptionKey) Keyring {
|
func NewMemoryKeyring(accountKey *MemorySymmetricEncryptionKey) Keyring {
|
||||||
|
keyringLog.Info("Creating new memory keyring")
|
||||||
return Keyring{
|
return Keyring{
|
||||||
AccountKey: accountKey,
|
AccountKey: accountKey,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemguardKeyring(accountKey *MemguardSymmetricEncryptionKey) Keyring {
|
func NewMemguardKeyring(accountKey *MemguardSymmetricEncryptionKey) Keyring {
|
||||||
|
keyringLog.Info("Creating new memguard keyring")
|
||||||
return Keyring{
|
return Keyring{
|
||||||
AccountKey: accountKey,
|
AccountKey: accountKey,
|
||||||
}
|
}
|
||||||
@ -28,6 +34,7 @@ func (keyring Keyring) IsLocked() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (keyring *Keyring) Lock() {
|
func (keyring *Keyring) Lock() {
|
||||||
|
keyringLog.Info("Locking keyring")
|
||||||
keyring.AccountKey = nil
|
keyring.AccountKey = nil
|
||||||
keyring.AsymmetricEncyryptionKey = MemoryAsymmetricEncryptionKey{}
|
keyring.AsymmetricEncyryptionKey = MemoryAsymmetricEncryptionKey{}
|
||||||
keyring.OrganizationKeys = nil
|
keyring.OrganizationKeys = nil
|
||||||
|
@ -30,35 +30,39 @@ func Sync(ctx context.Context, config *config.Config) (models.SyncData, error) {
|
|||||||
|
|
||||||
func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config, userSymmetricKey *crypto.SymmetricEncryptionKey, allowCache bool) error {
|
func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config, userSymmetricKey *crypto.SymmetricEncryptionKey, allowCache bool) error {
|
||||||
log.Info("Performing full sync...")
|
log.Info("Performing full sync...")
|
||||||
|
|
||||||
sync, err := Sync(ctx, config)
|
sync, err := Sync(ctx, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error("Could not sync: %v", err)
|
||||||
if allowCache {
|
if allowCache {
|
||||||
home, _ := os.UserHomeDir()
|
home, _ := os.UserHomeDir()
|
||||||
sync, err = ReadVault(home + path)
|
sync, err = ReadVault(home + path)
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Info("Sync successful, initializing keyring and vault...")
|
||||||
}
|
}
|
||||||
|
|
||||||
var orgKeys map[string]string = make(map[string]string)
|
var orgKeys map[string]string = make(map[string]string)
|
||||||
|
log.Info("Initializing %d org keys...", len(sync.Profile.Organizations))
|
||||||
for _, org := range sync.Profile.Organizations {
|
for _, org := range sync.Profile.Organizations {
|
||||||
orgId := org.Id.String()
|
orgId := org.Id.String()
|
||||||
orgKeys[orgId] = org.Key
|
orgKeys[orgId] = org.Key
|
||||||
}
|
}
|
||||||
if userSymmetricKey != nil {
|
if userSymmetricKey != nil {
|
||||||
|
log.Info("Initializing keyring from user symmetric key...")
|
||||||
crypto.InitKeyringFromUserSymmetricKey(vault.Keyring, *userSymmetricKey, sync.Profile.PrivateKey, orgKeys)
|
crypto.InitKeyringFromUserSymmetricKey(vault.Keyring, *userSymmetricKey, sync.Profile.PrivateKey, orgKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Info("Clearing vault...")
|
||||||
vault.Clear()
|
vault.Clear()
|
||||||
|
log.Info("Adding %d ciphers to vault...", len(sync.Ciphers))
|
||||||
for _, cipher := range sync.Ciphers {
|
for _, cipher := range sync.Ciphers {
|
||||||
switch cipher.Type {
|
switch cipher.Type {
|
||||||
case models.CipherLogin:
|
case models.CipherLogin:
|
||||||
vault.AddOrUpdateLogin(cipher)
|
vault.AddOrUpdateLogin(cipher)
|
||||||
break
|
|
||||||
case models.CipherNote:
|
case models.CipherNote:
|
||||||
vault.AddOrUpdateSecureNote(cipher)
|
vault.AddOrUpdateSecureNote(cipher)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package bitwarden
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@ -49,7 +48,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
WEBSOCKET_SLEEP_DURATION_SECONDS = 5
|
WEBSOCKET_SLEEP_DURATION_SECONDS = 60
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunWebsocketDaemon(ctx context.Context, vault *vault.Vault, cfg *config.Config) {
|
func RunWebsocketDaemon(ctx context.Context, vault *vault.Vault, cfg *config.Config) {
|
||||||
@ -95,12 +94,15 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con
|
|||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
for {
|
for {
|
||||||
mt, message, err := c.ReadMessage()
|
_, message, err := c.ReadMessage()
|
||||||
fmt.Println(mt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
websocketLog.Error("Error reading websocket message %s", err)
|
websocketLog.Error("Error reading websocket message %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(message) < 3 {
|
||||||
|
//ignore empty messages
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if messageType, cipherid, success := websocketMessageType(message); success {
|
if messageType, cipherid, success := websocketMessageType(message); success {
|
||||||
var mt1 = NotificationMessageType(messageType)
|
var mt1 = NotificationMessageType(messageType)
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
package processsecurity
|
package processsecurity
|
||||||
|
|
||||||
import "golang.org/x/sys/unix"
|
|
||||||
|
|
||||||
func DisableDumpable() error {
|
func DisableDumpable() error {
|
||||||
return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0)
|
// return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,12 @@ import (
|
|||||||
|
|
||||||
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
"github.com/quexten/goldwarden/agent/bitwarden/crypto"
|
||||||
"github.com/quexten/goldwarden/agent/bitwarden/models"
|
"github.com/quexten/goldwarden/agent/bitwarden/models"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/quexten/goldwarden/logging"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var vaultLog = logging.GetLogger("Goldwarden", "Vault")
|
||||||
|
|
||||||
type Vault struct {
|
type Vault struct {
|
||||||
Keyring *crypto.Keyring
|
Keyring *crypto.Keyring
|
||||||
logins map[string]models.Cipher
|
logins map[string]models.Cipher
|
||||||
@ -94,7 +96,7 @@ func (vault *Vault) isEnv(cipher models.Cipher) (string, bool) {
|
|||||||
|
|
||||||
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
|
vaultLog.Error("Failed to get key for cipher "+cipher.ID.String(), err.Error())
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +134,7 @@ func (vault *Vault) isSSHKey(cipher models.Cipher) bool {
|
|||||||
|
|
||||||
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
|
vaultLog.Error("Failed to get key for cipher "+cipher.ID.String(), err.Error())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,8 +142,12 @@ func (vault *Vault) isSSHKey(cipher models.Cipher) bool {
|
|||||||
fieldName, err := crypto.DecryptWith(field.Name, key)
|
fieldName, err := crypto.DecryptWith(field.Name, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cipherID := cipher.ID.String()
|
cipherID := cipher.ID.String()
|
||||||
|
if cipher.OrganizationID != nil {
|
||||||
orgID := cipher.OrganizationID.String()
|
orgID := cipher.OrganizationID.String()
|
||||||
log.Warn().Err(err).Msg("Failed to decrypt field name with on cipher " + cipherID + " in organization " + orgID)
|
vaultLog.Error("Failed to decrypt field name with on cipher "+cipherID+" in organization "+orgID, err.Error())
|
||||||
|
} else {
|
||||||
|
vaultLog.Error("Failed to decrypt field name with on cipher "+cipherID, err.Error())
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fieldValue, err := crypto.DecryptWith(field.Value, key)
|
fieldValue, err := crypto.DecryptWith(field.Value, key)
|
||||||
@ -229,7 +235,7 @@ func (vault *Vault) GetEnvCredentialForExecutable(executableName string) (map[st
|
|||||||
if id, ok := vault.envCredentials[executableName]; ok {
|
if id, ok := vault.envCredentials[executableName]; ok {
|
||||||
key, err := vault.secureNotes[id].GetKeyForCipher(*vault.Keyring)
|
key, err := vault.secureNotes[id].GetKeyForCipher(*vault.Keyring)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to get key for cipher " + id)
|
vaultLog.Error("Failed to get key for cipher " + id)
|
||||||
return make(map[string]string), false
|
return make(map[string]string), false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +308,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
|
|||||||
|
|
||||||
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
|
vaultLog.Error("Failed to get key for cipher " + cipher.ID.String())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if name != "" {
|
if name != "" {
|
||||||
@ -312,7 +318,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
|
|||||||
|
|
||||||
decryptedName, err := crypto.DecryptWith(cipher.Name, key)
|
decryptedName, err := crypto.DecryptWith(cipher.Name, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to decrypt name for cipher " + cipher.ID.String())
|
vaultLog.Error("Failed to decrypt name for cipher " + cipher.ID.String())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if name != "" && string(decryptedName) != name {
|
if name != "" && string(decryptedName) != name {
|
||||||
@ -327,7 +333,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
|
|||||||
|
|
||||||
decryptedUsername, err := crypto.DecryptWith(cipher.Login.Username, key)
|
decryptedUsername, err := crypto.DecryptWith(cipher.Login.Username, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to decrypt username for cipher " + cipher.ID.String())
|
vaultLog.Error("Failed to decrypt username for cipher " + cipher.ID.String())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if username != "" && string(decryptedUsername) != username {
|
if username != "" && string(decryptedUsername) != username {
|
||||||
@ -338,7 +344,7 @@ func (vault *Vault) GetLoginByFilter(uuid string, orgId string, name string, use
|
|||||||
return cipher, nil
|
return cipher, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return models.Cipher{}, errors.New("Cipher not found")
|
return models.Cipher{}, errors.New("cipher not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vault *Vault) GetNoteByFilter(uuid string, orgId string, name string) (models.Cipher, error) {
|
func (vault *Vault) GetNoteByFilter(uuid string, orgId string, name string) (models.Cipher, error) {
|
||||||
@ -355,12 +361,12 @@ func (vault *Vault) GetNoteByFilter(uuid string, orgId string, name string) (mod
|
|||||||
|
|
||||||
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
key, err := cipher.GetKeyForCipher(*vault.Keyring)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to get key for cipher " + cipher.ID.String())
|
vaultLog.Error("Failed to get key for cipher "+cipher.ID.String(), err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
decryptedName, err := crypto.DecryptWith(cipher.Name, key)
|
decryptedName, err := crypto.DecryptWith(cipher.Name, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Failed to decrypt name for cipher " + cipher.ID.String())
|
vaultLog.Error("Failed to decrypt name for cipher "+cipher.ID.String(), err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if name != "" && string(decryptedName) != name {
|
if name != "" && string(decryptedName) != name {
|
||||||
|
28
cmd/vault.go
28
cmd/vault.go
@ -1,6 +1,8 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/quexten/goldwarden/ipc/messages"
|
"github.com/quexten/goldwarden/ipc/messages"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -89,9 +91,35 @@ var purgeCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var statusCmd = &cobra.Command{
|
||||||
|
Use: "status",
|
||||||
|
Short: "Shows the vault status",
|
||||||
|
Long: `Shows the vault status.`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
request := messages.VaultStatusRequest{}
|
||||||
|
|
||||||
|
result, err := commandClient.SendToAgent(request)
|
||||||
|
if err != nil {
|
||||||
|
handleSendToAgentError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result.(type) {
|
||||||
|
case messages.VaultStatusResponse:
|
||||||
|
status := result.(messages.VaultStatusResponse)
|
||||||
|
fmt.Println("Locked: ", status.Locked)
|
||||||
|
fmt.Println("Number of logins: ", status.NumberOfLogins)
|
||||||
|
fmt.Println("Number of notes: ", status.NumberOfNotes)
|
||||||
|
default:
|
||||||
|
println("Wrong response type")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(vaultCmd)
|
rootCmd.AddCommand(vaultCmd)
|
||||||
vaultCmd.AddCommand(unlockCmd)
|
vaultCmd.AddCommand(unlockCmd)
|
||||||
vaultCmd.AddCommand(lockCmd)
|
vaultCmd.AddCommand(lockCmd)
|
||||||
vaultCmd.AddCommand(purgeCmd)
|
vaultCmd.AddCommand(purgeCmd)
|
||||||
|
vaultCmd.AddCommand(statusCmd)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,17 @@ type WipeVaultRequest struct {
|
|||||||
type GetVaultPINRequest struct {
|
type GetVaultPINRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VaultStatusRequest struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type VaultStatusResponse struct {
|
||||||
|
Locked bool
|
||||||
|
NumberOfLogins int
|
||||||
|
NumberOfNotes int
|
||||||
|
// todo websocket status
|
||||||
|
// todo last synced
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerPayloadParser(func(payload []byte) (interface{}, error) {
|
registerPayloadParser(func(payload []byte) (interface{}, error) {
|
||||||
var req LockVaultRequest
|
var req LockVaultRequest
|
||||||
@ -62,4 +73,22 @@ func init() {
|
|||||||
}
|
}
|
||||||
return req, nil
|
return req, nil
|
||||||
}, GetVaultPINRequest{})
|
}, GetVaultPINRequest{})
|
||||||
|
|
||||||
|
registerPayloadParser(func(payload []byte) (interface{}, error) {
|
||||||
|
var req VaultStatusRequest
|
||||||
|
err := json.Unmarshal(payload, &req)
|
||||||
|
if err != nil {
|
||||||
|
panic("Unmarshal: " + err.Error())
|
||||||
|
}
|
||||||
|
return req, nil
|
||||||
|
}, VaultStatusRequest{})
|
||||||
|
|
||||||
|
registerPayloadParser(func(payload []byte) (interface{}, error) {
|
||||||
|
var req VaultStatusResponse
|
||||||
|
err := json.Unmarshal(payload, &req)
|
||||||
|
if err != nil {
|
||||||
|
panic("Unmarshal: " + err.Error())
|
||||||
|
}
|
||||||
|
return req, nil
|
||||||
|
}, VaultStatusResponse{})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user