mirror of
https://github.com/gopasspw/gopass.git
synced 2025-12-08 19:24:54 +00:00
* feat(age): Add unlock command to age agent This change introduces a proper lock/unlock mechanism for the age agent. The issue was that after locking the agent with `gopass age lock`, there was no way to unlock it without restarting the agent. This made the lock command mostly useless. This change introduces a new `unlock` command for the agent and a `locked` state. - The `lock` command now sets a `locked` flag to `true` in addition to clearing identities. - The `decrypt` function in the agent now checks this `locked` flag and returns an error if the agent is locked. - When the gopass client receives the "agent is locked" error, it will ask the user for their passphrase, reload the identities, and send them to the agent. - A new `gopass age agent unlock` CLI command is added to trigger this new functionality. - The `gopass age agent status` command is enhanced to report whether the agent is locked. - The old top-level `gopass age lock` command is hidden, and a new `gopass age agent lock` command is introduced for consistency. Fixes #3242 * feat(age): Add unlock command to age agent This change introduces a proper lock/unlock mechanism for the age agent. The issue was that after locking the agent with `gopass age lock`, there was no way to unlock it without restarting the agent. This made the lock command mostly useless. This change introduces a new `unlock` command for the agent and a `locked` state. - The `lock` command now sets a `locked` flag to `true` in addition to clearing identities. - The `decrypt` function in the agent now checks this `locked` flag and returns an error if the agent is locked. - When the gopass client receives the "agent is locked" error, it will ask the user for their passphrase, reload the identities, and send them to the agent. - A new `gopass age agent unlock` CLI command is added to trigger this new functionality. - The `gopass age agent status` command is enhanced to report whether the agent is locked. - The old top-level `gopass age lock` command is hidden, and a new `gopass age agent lock` command is introduced for consistency. I have also addressed the PR comment about the import alias. I have removed the alias and used a dot import instead to avoid the name collision. Fixes #3242 * feat(age): Add unlock command to age agent This change introduces a proper lock/unlock mechanism for the age agent. The issue was that after locking the agent with `gopass age lock`, there was no way to unlock it without restarting the agent. This made the lock command mostly useless. This change introduces a new `unlock` command for the agent and a `locked` state. - The `lock` command now sets a `locked` flag to `true` in addition to clearing identities. - The `decrypt` function in the agent now checks this `locked` flag and returns an error if the agent is locked. - When the gopass client receives the "agent is locked" error, it will ask the user for their passphrase, reload the identities, and send them to the agent. - A new `gopass age agent unlock` CLI command is added to trigger this new functionality. - The `gopass age agent status` command is enhanced to report whether the agent is locked. - The old top-level `gopass age lock` command is hidden, and a new `gopass age agent lock` command is introduced for consistency. To avoid name collisions with the imported `filippo.io/age` package, the local `age` package has been renamed to `agecrypto`. Fixes #3242 * feat(age): Add auto-lock feature to age agent This change introduces an auto-lock feature for the age agent. The agent will now automatically lock itself after a configurable period of inactivity. This change also includes the initial fix for issue #3242, which introduced a proper lock/unlock mechanism for the age agent. - A new config option `age.agent-timeout` is added to specify the inactivity timeout in seconds. - The agent now has a timer that is reset on every successful decryption operation. - If the timer expires, the agent locks itself. - A new `set-timeout` command is added to the agent protocol to configure the timeout. - The gopass client sends the timeout to the agent when it starts or when it unlocks the agent. - A new test `TestAgentAutoLock` is added to verify the new functionality. To avoid name collisions with the imported `filippo.io/age` package, the local `age` package has been renamed to `agecrypto`. Fixes #3242 * [fix] Fix lint issues Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org> --------- Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Dominik Schulz <dominik.schulz@gauner.org>
147 lines
3.4 KiB
Go
147 lines
3.4 KiB
Go
package action
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gopasspw/gopass/internal/config"
|
|
"github.com/gopasspw/gopass/internal/out"
|
|
"github.com/gopasspw/gopass/pkg/ctxutil"
|
|
"github.com/gopasspw/gopass/tests/gptest"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestConfig(t *testing.T) {
|
|
u := gptest.NewUnitTester(t)
|
|
|
|
ctx := config.NewContextInMemory()
|
|
ctx = ctxutil.WithInteractive(ctx, false)
|
|
act, err := newMock(ctx, u.StoreDir(""))
|
|
require.NoError(t, err)
|
|
require.NotNil(t, act)
|
|
ctx = act.cfg.WithConfig(ctx)
|
|
|
|
buf := &bytes.Buffer{}
|
|
out.Stdout = buf
|
|
stdout = buf
|
|
defer func() {
|
|
out.Stdout = os.Stdout
|
|
stdout = os.Stdout
|
|
}()
|
|
|
|
t.Run("display config", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
c := gptest.CliCtx(ctx, t)
|
|
require.NoError(t, act.Config(c))
|
|
want := `age.agent-enabled = false
|
|
age.agent-timeout = 0
|
|
core.autoimport = true
|
|
core.autopush = true
|
|
core.autosync = true
|
|
core.cliptimeout = 45
|
|
core.exportkeys = true
|
|
core.follow-references = false
|
|
core.nopager = true
|
|
core.notifications = true
|
|
generate.autoclip = true
|
|
`
|
|
want += "mounts.path = " + u.StoreDir("") + "\n" +
|
|
"pwgen.xkcd-lang = en\n"
|
|
assert.Equal(t, want, buf.String())
|
|
})
|
|
|
|
t.Run("set valid config value", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
require.NoError(t, act.setConfigValue(ctx, "", "core.nopager", "true"))
|
|
|
|
// should print accepted config value
|
|
assert.Equal(t, "true", strings.TrimSpace(buf.String()), "action.setConfigValue")
|
|
})
|
|
|
|
t.Run("set invalid config value", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
require.Error(t, act.setConfigValue(ctx, "", "foobar", "true"))
|
|
})
|
|
|
|
t.Run("print single config value", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
act.printConfigValues(ctx, "", "core.nopager")
|
|
|
|
want := "true"
|
|
assert.Equal(t, want, strings.TrimSpace(buf.String()), "action.printConfigValues")
|
|
})
|
|
|
|
t.Run("print all config values", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
act.printConfigValues(ctx, "")
|
|
want := `age.agent-enabled = false
|
|
age.agent-timeout = 0
|
|
core.autoimport = true
|
|
core.autopush = true
|
|
core.autosync = true
|
|
core.cliptimeout = 45
|
|
core.exportkeys = true
|
|
core.follow-references = false
|
|
core.nopager = true
|
|
core.notifications = true
|
|
generate.autoclip = true
|
|
`
|
|
want += "mounts.path = " + u.StoreDir("") + "\n" +
|
|
"pwgen.xkcd-lang = en\n"
|
|
|
|
assert.Equal(t, want, buf.String(), "action.printConfigValues")
|
|
})
|
|
|
|
t.Run("show autoimport value", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
c := gptest.CliCtx(ctx, t, "core.autoimport")
|
|
require.NoError(t, act.Config(c))
|
|
assert.Equal(t, "true", strings.TrimSpace(buf.String()))
|
|
})
|
|
|
|
t.Run("disable autoimport", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
c := gptest.CliCtx(ctx, t, "core.autoimport", "false")
|
|
require.NoError(t, act.Config(c))
|
|
assert.Equal(t, "false", strings.TrimSpace(buf.String()))
|
|
})
|
|
|
|
t.Run("complete config items", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
act.ConfigComplete(gptest.CliCtx(ctx, t))
|
|
want := `age.agent-enabled
|
|
age.agent-timeout
|
|
core.autoimport
|
|
core.autopush
|
|
core.autosync
|
|
core.cliptimeout
|
|
core.exportkeys
|
|
core.follow-references
|
|
core.nopager
|
|
core.notifications
|
|
generate.autoclip
|
|
mounts.path
|
|
pwgen.xkcd-lang
|
|
`
|
|
assert.Equal(t, want, buf.String())
|
|
})
|
|
|
|
t.Run("set autoimport to invalid value", func(t *testing.T) {
|
|
defer buf.Reset()
|
|
|
|
c := gptest.CliCtx(ctx, t, "autoimport", "false", "42")
|
|
require.Error(t, act.Config(c))
|
|
})
|
|
}
|