Files
gopass-mirror/internal/backend/crypto/plain/backend.go
Dominik Schulz f84e676ec1 Improve logging and pretty printing (#3286)
* [chore] Add PID to the debug logs

This helps differentiate between gopass foreground and background (e.g.
agent) processes.

Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>

* [chore] Adjust logging severities and improve pretty printing

Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>

---------

Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
2025-11-12 20:37:52 +01:00

179 lines
4.3 KiB
Go

// Package plain implements a plaintext backend
package plain
import (
"context"
"fmt"
"runtime"
"strings"
"time"
"github.com/blang/semver/v4"
"github.com/gopasspw/gopass/internal/backend/crypto/gpg"
"github.com/gopasspw/gopass/pkg/debug"
)
var staticPrivateKeyList = gpg.KeyList{
gpg.Key{
KeyType: "rsa",
KeyLength: 2048,
Validity: "u",
CreationDate: time.Now(),
Fingerprint: "000000000000000000000000DEADBEEF",
Identities: map[string]gpg.Identity{
"Dead Beef <dead.beef@example.com>": {
Name: "Dead Beef",
Email: "dead.beef@example.com",
CreationDate: time.Now(),
},
},
},
gpg.Key{
KeyType: "rsa",
KeyLength: 2048,
Validity: "u",
CreationDate: time.Now(),
Fingerprint: "000000000000000000000000FEEDBEEF",
Identities: map[string]gpg.Identity{
"Feed Beef <feed.beef@example.com>": {
Name: "Feed Beef",
Email: "feed.beef@example.com",
CreationDate: time.Now(),
},
},
},
}
// Mocker is a no-op GPG mock.
type Mocker struct{}
// New creates a new GPG mock.
func New() *Mocker {
return &Mocker{}
}
// ListRecipients does nothing.
func (m *Mocker) ListRecipients(context.Context) ([]string, error) {
return staticPrivateKeyList.Recipients(), nil
}
// FindRecipients does nothing.
func (m *Mocker) FindRecipients(ctx context.Context, keys ...string) ([]string, error) {
rs := staticPrivateKeyList.Recipients()
res := make([]string, 0, len(rs))
for _, r := range rs {
for _, needle := range keys {
debug.V(1).Log("checking recipient %q = %q", r, needle)
if strings.HasSuffix(r, needle) {
res = append(res, r)
}
}
}
return res, nil
}
// ListIdentities does nothing.
func (m *Mocker) ListIdentities(context.Context) ([]string, error) {
return staticPrivateKeyList.Recipients(), nil
}
// FindIdentities does nothing.
func (m *Mocker) FindIdentities(ctx context.Context, keys ...string) ([]string, error) {
return m.FindRecipients(ctx, keys...)
}
// RecipientIDs does nothing.
func (m *Mocker) RecipientIDs(context.Context, []byte) ([]string, error) {
return staticPrivateKeyList.Recipients(), nil
}
// Encrypt writes the input to disk unaltered.
func (m *Mocker) Encrypt(ctx context.Context, content []byte, recipients []string) ([]byte, error) {
return content, nil
}
// Decrypt read the file from disk unaltered.
func (m *Mocker) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) {
return ciphertext, nil
}
// ImportPublicKey does nothing.
func (m *Mocker) ImportPublicKey(context.Context, []byte) error {
return nil
}
// Version returns dummy version info.
func (m *Mocker) Version(context.Context) semver.Version {
return debug.ModuleVersion("github.com/gopasspw/gopass/internal/backend/crypto/plain")
}
// Binary always returns 'gpg'.
func (m *Mocker) Binary() string {
return "gpg"
}
// GenerateIdentity is not implemented.
func (m *Mocker) GenerateIdentity(ctx context.Context, name, email, pw string) (string, error) {
return "", fmt.Errorf("not yet implemented")
}
// Fingerprint returns thd id.
func (m *Mocker) Fingerprint(ctx context.Context, id string) string {
return id
}
// FormatKey returns the id.
func (m *Mocker) FormatKey(ctx context.Context, id, tpl string) string {
return id
}
// Initialized returns nil.
func (m *Mocker) Initialized(context.Context) error {
return nil
}
// Name returns plain, the name of the backend.
func (m *Mocker) Name() string {
return Name
}
// Ext returns gpg.
func (m *Mocker) Ext() string {
return Ext
}
const (
// Name is the name of this backend.
Name = "plain"
// Ext is the file extension used by this backend.
Ext = "txt"
// IDFile is the name of the recipients file used by this backend.
IDFile = ".plain-id"
)
// IDFile returns the name of the recipients file.
func (m *Mocker) IDFile() string {
return IDFile
}
// ReadNamesFromKey does nothing.
func (m *Mocker) ReadNamesFromKey(ctx context.Context, buf []byte) ([]string, error) {
return []string{"unsupported"}, nil
}
// GetFingerprint returns an empty fingerprint.
func (m *Mocker) GetFingerprint(ctx context.Context, key []byte) (string, error) {
return "", nil
}
// Concurrency returns the number of CPUs.
func (m *Mocker) Concurrency() int {
return runtime.NumCPU()
}
// String implements fmt.Stringer.
func (m *Mocker) String() string {
return "Plaintext(Encrypt/Decrypt no-op)"
}