Refactor
This commit is contained in:
parent
c5f978d32b
commit
02ff452c09
10 changed files with 89 additions and 77 deletions
|
@ -1,4 +1,4 @@
|
|||
package pkg
|
||||
package internal
|
||||
|
||||
import (
|
||||
"cli-go/internal/api"
|
5
main.go
5
main.go
|
@ -4,6 +4,7 @@ import (
|
|||
"cli-go/cmd"
|
||||
"cli-go/internal/api"
|
||||
"cli-go/pkg"
|
||||
"cli-go/pkg/secrets"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -17,8 +18,8 @@ func main() {
|
|||
Host: "http://localhost:8080",
|
||||
}),
|
||||
DB: db,
|
||||
CliKey: pkg.GetOrCreateClISecret(),
|
||||
KeyHolder: pkg.NewKeyHolder(),
|
||||
CliKey: secrets.GetOrCreateClISecret(),
|
||||
KeyHolder: secrets.NewKeyHolder(),
|
||||
}
|
||||
err = ctrl.Init()
|
||||
if err != nil {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"cli-go/internal"
|
||||
"cli-go/internal/api"
|
||||
"cli-go/pkg/model"
|
||||
"cli-go/utils/encoding"
|
||||
|
@ -21,9 +22,9 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
|
|||
log.Fatal(flowErr)
|
||||
}
|
||||
}()
|
||||
app := GetAppType()
|
||||
app := internal.GetAppType()
|
||||
cxt = context.WithValue(cxt, "app", string(app))
|
||||
email, flowErr := GetUserInput("Enter email address")
|
||||
email, flowErr := internal.GetUserInput("Enter email address")
|
||||
if flowErr != nil {
|
||||
return
|
||||
}
|
||||
|
@ -69,7 +70,7 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, secretInfo *accSecretInfo) error {
|
||||
func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, secretInfo *model.AccSecretInfo) error {
|
||||
// get password
|
||||
secret := c.CliKey
|
||||
err := c.DB.Update(func(tx *bolt.Tx) error {
|
||||
|
|
57
pkg/collections.go
Normal file
57
pkg/collections.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"cli-go/internal/api"
|
||||
enteCrypto "cli-go/internal/crypto"
|
||||
"cli-go/pkg/model"
|
||||
"cli-go/utils/encoding"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
func (c *ClICtrl) syncRemoteCollections(ctx context.Context, info model.Account) error {
|
||||
collections, err := c.Client.GetCollections(ctx, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get collections: %s", err)
|
||||
}
|
||||
for _, collection := range collections {
|
||||
collectionKey, err := c.getCollectionKey(ctx, collection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name, nameErr := enteCrypto.SecretBoxOpenBase64(collection.EncryptedName, collection.NameDecryptionNonce, collectionKey)
|
||||
if nameErr != nil {
|
||||
log.Fatalf("failed to decrypt collection name: %v", nameErr)
|
||||
}
|
||||
if collection.Owner.ID != info.UserID {
|
||||
fmt.Printf("Shared Album %s\n", string(name))
|
||||
continue
|
||||
} else {
|
||||
fmt.Printf("Owned Name %s\n", string(name))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClICtrl) getCollectionKey(ctx context.Context, collection api.Collection) ([]byte, error) {
|
||||
accSecretInfo := c.KeyHolder.GetAccountSecretInfo(ctx)
|
||||
userID := ctx.Value("user_id").(int64)
|
||||
if collection.Owner.ID == userID {
|
||||
collKey, err := enteCrypto.SecretBoxOpen(
|
||||
encoding.DecodeBase64(collection.EncryptedKey),
|
||||
encoding.DecodeBase64(collection.KeyDecryptionNonce),
|
||||
accSecretInfo.MasterKey)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to decrypt collection key %s", err)
|
||||
}
|
||||
return collKey, nil
|
||||
} else {
|
||||
collKey, err := enteCrypto.SealedBoxOpen(encoding.DecodeBase64(collection.EncryptedKey),
|
||||
accSecretInfo.PublicKey, accSecretInfo.SecretKey)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to decrypt collection key %s", err)
|
||||
}
|
||||
return collKey, nil
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package pkg
|
|||
|
||||
import (
|
||||
"cli-go/internal/api"
|
||||
"cli-go/pkg/secrets"
|
||||
"fmt"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
@ -11,7 +12,7 @@ type ClICtrl struct {
|
|||
DB *bolt.DB
|
||||
// CliKey is the key used to encrypt/decrypt sensitive data stored in the database
|
||||
CliKey []byte
|
||||
KeyHolder *KeyHolder
|
||||
KeyHolder *secrets.KeyHolder
|
||||
}
|
||||
|
||||
func (c *ClICtrl) Init() error {
|
||||
|
|
|
@ -23,3 +23,10 @@ func (a *Account) AccountKey() string {
|
|||
func (a *Account) DataBucket() string {
|
||||
return fmt.Sprintf("%s-%d-data", a.App, a.UserID)
|
||||
}
|
||||
|
||||
type AccSecretInfo struct {
|
||||
MasterKey []byte
|
||||
SecretKey []byte
|
||||
Token []byte
|
||||
PublicKey []byte
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"cli-go/internal/api"
|
||||
enteCrypto "cli-go/internal/crypto"
|
||||
"cli-go/pkg/model"
|
||||
"cli-go/utils/encoding"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
@ -51,50 +48,3 @@ func createDataBuckets(db *bolt.DB, account model.Account) error {
|
|||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ClICtrl) syncRemoteCollections(ctx context.Context, info model.Account) error {
|
||||
collections, err := c.Client.GetCollections(ctx, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get collections: %s", err)
|
||||
}
|
||||
for _, collection := range collections {
|
||||
|
||||
collectionKey, err := c.getCollectionKey(ctx, collection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name, nameErr := enteCrypto.SecretBoxOpenBase64(collection.EncryptedName, collection.NameDecryptionNonce, collectionKey)
|
||||
if nameErr != nil {
|
||||
log.Fatalf("failed to decrypt collection name: %v", nameErr)
|
||||
}
|
||||
if collection.Owner.ID != info.UserID {
|
||||
fmt.Printf("Shared Album %s\n", string(name))
|
||||
continue
|
||||
} else {
|
||||
fmt.Printf("Owned Name %s\n", string(name))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClICtrl) getCollectionKey(ctx context.Context, collection api.Collection) ([]byte, error) {
|
||||
accSecretInfo := c.KeyHolder.GetAccountSecretInfo(ctx)
|
||||
userID := ctx.Value("user_id").(int64)
|
||||
if collection.Owner.ID == userID {
|
||||
collKey, err := enteCrypto.SecretBoxOpen(
|
||||
encoding.DecodeBase64(collection.EncryptedKey),
|
||||
encoding.DecodeBase64(collection.KeyDecryptionNonce),
|
||||
accSecretInfo.MasterKey)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to decrypt collection key %s", err)
|
||||
}
|
||||
return collKey, nil
|
||||
} else {
|
||||
collKey, err := enteCrypto.SealedBoxOpen(encoding.DecodeBase64(collection.EncryptedKey),
|
||||
accSecretInfo.PublicKey, accSecretInfo.SecretKey)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to decrypt collection key %s", err)
|
||||
}
|
||||
return collKey, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package pkg
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"cli-go/pkg/model"
|
||||
|
@ -7,22 +7,22 @@ import (
|
|||
)
|
||||
|
||||
type KeyHolder struct {
|
||||
AccountSecrets map[string]*accSecretInfo
|
||||
AccountSecrets map[string]*model.AccSecretInfo
|
||||
CollectionKeys map[string][]byte
|
||||
}
|
||||
|
||||
func NewKeyHolder() *KeyHolder {
|
||||
return &KeyHolder{
|
||||
AccountSecrets: make(map[string]*accSecretInfo),
|
||||
AccountSecrets: make(map[string]*model.AccSecretInfo),
|
||||
CollectionKeys: make(map[string][]byte),
|
||||
}
|
||||
}
|
||||
|
||||
func (k *KeyHolder) LoadSecrets(account model.Account, cliKey []byte) (*accSecretInfo, error) {
|
||||
func (k *KeyHolder) LoadSecrets(account model.Account, cliKey []byte) (*model.AccSecretInfo, error) {
|
||||
tokenKey := account.Token.MustDecrypt(cliKey)
|
||||
masterKey := account.MasterKey.MustDecrypt(cliKey)
|
||||
secretKey := account.SecretKey.MustDecrypt(cliKey)
|
||||
k.AccountSecrets[account.AccountKey()] = &accSecretInfo{
|
||||
k.AccountSecrets[account.AccountKey()] = &model.AccSecretInfo{
|
||||
Token: tokenKey,
|
||||
MasterKey: masterKey,
|
||||
SecretKey: secretKey,
|
||||
|
@ -31,7 +31,7 @@ func (k *KeyHolder) LoadSecrets(account model.Account, cliKey []byte) (*accSecre
|
|||
return k.AccountSecrets[account.AccountKey()], nil
|
||||
}
|
||||
|
||||
func (k *KeyHolder) GetAccountSecretInfo(ctx context.Context) *accSecretInfo {
|
||||
func (k *KeyHolder) GetAccountSecretInfo(ctx context.Context) *model.AccSecretInfo {
|
||||
accountKey := ctx.Value("account_id").(string)
|
||||
return k.AccountSecrets[accountKey]
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package pkg
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
|
@ -1,8 +1,10 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"cli-go/internal"
|
||||
"cli-go/internal/api"
|
||||
enteCrypto "cli-go/internal/crypto"
|
||||
"cli-go/pkg/model"
|
||||
"cli-go/utils/encoding"
|
||||
"context"
|
||||
"fmt"
|
||||
|
@ -11,17 +13,10 @@ import (
|
|||
"github.com/kong/go-srp"
|
||||
)
|
||||
|
||||
type accSecretInfo struct {
|
||||
MasterKey []byte
|
||||
SecretKey []byte
|
||||
Token []byte
|
||||
PublicKey []byte
|
||||
}
|
||||
|
||||
func (c *ClICtrl) signInViaPassword(ctx context.Context, email string, srpAttr *api.SRPAttributes) (*api.AuthorizationResponse, []byte, error) {
|
||||
for {
|
||||
// CLI prompt for password
|
||||
password, flowErr := GetSensitiveField("Enter password")
|
||||
password, flowErr := internal.GetSensitiveField("Enter password")
|
||||
if flowErr != nil {
|
||||
return nil, nil, flowErr
|
||||
}
|
||||
|
@ -62,7 +57,7 @@ func (c *ClICtrl) decryptAccSecretInfo(
|
|||
_ context.Context,
|
||||
authResp *api.AuthorizationResponse,
|
||||
keyEncKey []byte,
|
||||
) (*accSecretInfo, error) {
|
||||
) (*model.AccSecretInfo, error) {
|
||||
var currentKeyEncKey []byte
|
||||
var err error
|
||||
var masterKey, secretKey, tokenKey []byte
|
||||
|
@ -70,7 +65,7 @@ func (c *ClICtrl) decryptAccSecretInfo(
|
|||
for {
|
||||
if keyEncKey == nil {
|
||||
// CLI prompt for password
|
||||
password, flowErr := GetSensitiveField("Enter password")
|
||||
password, flowErr := internal.GetSensitiveField("Enter password")
|
||||
if flowErr != nil {
|
||||
return nil, flowErr
|
||||
}
|
||||
|
@ -117,7 +112,7 @@ func (c *ClICtrl) decryptAccSecretInfo(
|
|||
}
|
||||
break
|
||||
}
|
||||
return &accSecretInfo{
|
||||
return &model.AccSecretInfo{
|
||||
MasterKey: masterKey,
|
||||
SecretKey: secretKey,
|
||||
Token: tokenKey,
|
||||
|
@ -131,7 +126,7 @@ func (c *ClICtrl) validateTOTP(ctx context.Context, authResp *api.AuthorizationR
|
|||
}
|
||||
for {
|
||||
// CLI prompt for TOTP
|
||||
totp, flowErr := GetCode("Enter TOTP", 6)
|
||||
totp, flowErr := internal.GetCode("Enter TOTP", 6)
|
||||
if flowErr != nil {
|
||||
return nil, flowErr
|
||||
}
|
||||
|
@ -151,7 +146,7 @@ func (c *ClICtrl) validateEmail(ctx context.Context, email string) (*api.Authori
|
|||
}
|
||||
for {
|
||||
// CLI prompt for OTP
|
||||
ott, flowErr := GetCode("Enter OTP", 6)
|
||||
ott, flowErr := internal.GetCode("Enter OTP", 6)
|
||||
if flowErr != nil {
|
||||
return nil, flowErr
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue