Skip to content

Commit

Permalink
Add keepass (#3)
Browse files Browse the repository at this point in the history
* add keepass store
* refactoring
  • Loading branch information
revengel authored Nov 24, 2024
1 parent ce74dde commit 744c33e
Show file tree
Hide file tree
Showing 26 changed files with 1,178 additions and 773 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: Go

on:
push:
branches: [ "master", "main" ]
branches: [ "*" ]
tags: [ 'v*.*.*', 'v*.*.*-*' ]
pull_request:
branches: [ "master", "main" ]
Expand All @@ -25,7 +25,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
go-version: 1.22

- name: Run GoReleaser
uses: goreleaser/[email protected]
Expand Down
132 changes: 132 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package main

import (
"context"
"errors"
"fmt"

"github.com/revengel/enpass2gopass/store"
"github.com/revengel/enpass2gopass/store/enpass"
"github.com/revengel/enpass2gopass/store/gopass"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

const (
EnpassJsonSourceType = "enpassJsonSource"
GopassDestinationType = "gopassDestination"
KeepassDestinationType = "keepassDestination"
)

type app struct {
ctx context.Context
logger *logrus.Logger
source store.StoreSource
destination store.StoreDestination
}

func (a *app) Close() error {
var err error
if a.destination != nil {
err = a.destination.Close()
if err != nil {
return err
}
}
return nil
}

func (a *app) SetLogLevel(cmd *cobra.Command, args []string) error {
debug, _ := cmd.Flags().GetBool("debug")
if debug {
a.logger.SetLevel(logrus.DebugLevel)
return nil
}

logLevelStr, _ := cmd.Flags().GetString("log-level")
if logLevelStr == "" {
return nil
}

lvl, err := logrus.ParseLevel(logLevelStr)
if err != nil {
a.logger.Warnf("cannot parse log level '%s': %s", logLevelStr, err.Error())
return nil
}

a.logger.SetLevel(lvl)
return nil
}

func (a *app) Before(cmd *cobra.Command, args []string) error {
var err error
err = a.SetLogLevel(cmd, args)
if err != nil {
return err
}

prefix, _ := cmd.Flags().GetString("prefix")
dryRun, _ := cmd.Flags().GetBool("dry-run")

sourceProvider, _ := cmd.Flags().GetString("source-provider")
destProvider, _ := cmd.Flags().GetString("destination-provider")

switch sourceProvider {
case EnpassJsonSourceType:
enpassJsonPath, _ := cmd.Flags().GetString("source-enpass-json-path")
if enpassJsonPath == "" {
return errors.New("source enpass json file is not set")
}
a.source, err = enpass.NewEnpassJsonSource(enpassJsonPath)
default:
return fmt.Errorf("invalid source provider: %s", sourceProvider)
}

if err != nil {
return fmt.Errorf("failed to connect source: %s", err)
}

switch destProvider {
case GopassDestinationType:
a.destination, err = gopass.NewStore(a.ctx, prefix, dryRun, a.logger)
default:
return fmt.Errorf("invalid destination provider: %s", destProvider)
}

if err != nil {
return fmt.Errorf("failed to connect destination: %s", err)
}

return nil
}

func (a *app) Import(cmd *cobra.Command, args []string) error {
items, err := a.source.LoadData()
if err != nil {
return fmt.Errorf("Cannot load data from source: %s", err.Error())
}

for _, item := range items {
secretPath, err := item.GetSecretPath()
if err != nil {
return fmt.Errorf("cannot get seceret path: %s", err.Error())
}

fields, err := item.GetFields()
if err != nil {
return fmt.Errorf("cannot get item fields; secret key - '%s': %s", secretPath, err.Error())
}

_, err = a.destination.Save(fields, secretPath)
if err != nil {
return fmt.Errorf("cannot save secret; secret key - '%s': %s", secretPath, err.Error())
}
}

_, err = a.destination.Cleanup()
if err != nil {
return fmt.Errorf("cannot cleanup passwords storage: %s", err.Error())
}

return nil
}
88 changes: 0 additions & 88 deletions enpass/item.go

This file was deleted.

104 changes: 104 additions & 0 deletions field/field.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package field

const (
// SecretTitleField - secret field password type
SecretTitleField = "title"
// SecretUsernameField -
SecretUsernameField = "username"
// SecretPasswordField - secret field password type
SecretPasswordField = "password"
// SecretURLField -
SecretURLField = "url"
// SecretTagsField -
SecretTagsField = "tags"
// SecretSimpleField - secret field simple text type
SecretSimpleField = "simple"
// SecretAttachmentField - secret field multiline type
SecretAttachmentField = "attachment"
)

type FieldType string

type Field struct {
Key string
Value []byte
Type FieldType
Multiline bool
Sensitive bool
}

func (self Field) GetKey() string {
return self.Key
}

func (self Field) GetValue() []byte {
return self.Value
}

func (self Field) GetValueString() string {
return string(self.Value)
}

func (self Field) GetType() FieldType {
if self.Type == "" {
return SecretSimpleField
}
return self.Type
}

func (self Field) IsType(t FieldType) bool {
return self.GetType() == t
}

func (self Field) IsMultiline() bool {
return self.Multiline
}

func (self Field) IsSensitive() bool {
return self.Sensitive
}

func NewField(k string, v []byte, t FieldType, multi, sens bool) FieldInterface {
return &Field{
Key: k,
Value: v,
Type: t,
Multiline: multi,
Sensitive: sens,
}
}

func vOrDef(in, def string) string {
if in != "" {
return in
}
return def
}

func NewTitleField(k, v string) FieldInterface {
return NewField(vOrDef(k, "title"), []byte(v), SecretTitleField, false, false)
}

func NewSimpleField(k string, v []byte, multi, sens bool) FieldInterface {
return NewField(k, v, SecretSimpleField, multi, sens)
}

func NewUsernameField(k, v string) FieldInterface {
return NewField(vOrDef(k, "username"), []byte(v), SecretUsernameField, false, false)
}

func NewUrlField(k, v string) FieldInterface {
return NewField(vOrDef(k, "url"), []byte(v), SecretUsernameField, false, false)
}

func NewTagsField(k, v string) FieldInterface {
return NewField(vOrDef(k, "tags"), []byte(v), SecretTagsField, false, false)
}

func NewAttachmentField(k string, v []byte) FieldInterface {
return NewField(k, v, SecretAttachmentField, false, false)
}

func NewPasswordField(k, v string) FieldInterface {
return NewField(vOrDef(k, "password"), []byte(v), SecretPasswordField, false, true)
}
11 changes: 11 additions & 0 deletions field/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package field

type FieldInterface interface {
GetKey() string
GetValue() []byte
GetValueString() string
GetType() FieldType
IsType(t FieldType) bool
IsMultiline() bool
IsSensitive() bool
}
Loading

0 comments on commit 744c33e

Please sign in to comment.