diff --git a/auth_requestor_plymouth.go b/auth_requestor_plymouth.go index ac86bbb1..8a4af157 100644 --- a/auth_requestor_plymouth.go +++ b/auth_requestor_plymouth.go @@ -32,13 +32,10 @@ import ( // PlymouthAuthRequestorStringer is used by the Plymouth implementation // of [AuthRequestor] to obtain translated strings. type PlymouthAuthRequestorStringer interface { - // RequestUserCredentialFormatString returns a format string used by - // RequestUserCredential to construct a message that is used to request - // credentials with the supplied auth types. The returned format string - // is interpreted with the following parameters: - // - %[1]s: A human readable name for the storage container. - // - %[2]s: The path of the encrypted storage container. - RequestUserCredentialFormatString(authTypes UserAuthType) (string, error) + // RequestUserCredentialString returns messages used by RequestUserCredential. The + // name is a string supplied via the WithAuthRequestorUserVisibleName option, and the + // path is the storage container path. + RequestUserCredentialString(name, path string, authTypes UserAuthType) (string, error) } type plymouthAuthRequestor struct { @@ -46,11 +43,10 @@ type plymouthAuthRequestor struct { } func (r *plymouthAuthRequestor) RequestUserCredential(ctx context.Context, name, path string, authTypes UserAuthType) (string, UserAuthType, error) { - fmtString, err := r.stringer.RequestUserCredentialFormatString(authTypes) + msg, err := r.stringer.RequestUserCredentialString(name, path, authTypes) if err != nil { - return "", 0, fmt.Errorf("cannot request format string for requested auth types: %w", err) + return "", 0, fmt.Errorf("cannot request message string: %w", err) } - msg := fmt.Sprintf(fmtString, name, path) cmd := exec.CommandContext( ctx, "plymouth", "ask-for-password", diff --git a/auth_requestor_plymouth_test.go b/auth_requestor_plymouth_test.go index 21b3a138..e1308a5e 100644 --- a/auth_requestor_plymouth_test.go +++ b/auth_requestor_plymouth_test.go @@ -60,29 +60,31 @@ type mockPlymouthAuthRequestorStringer struct { rucErr error } -func (s *mockPlymouthAuthRequestorStringer) RequestUserCredentialFormatString(authType UserAuthType) (string, error) { +func (s *mockPlymouthAuthRequestorStringer) RequestUserCredentialString(name, path string, authType UserAuthType) (string, error) { if s.rucErr != nil { return "", s.rucErr } + var fmtString string switch authType { case UserAuthTypePassphrase: - return "Enter passphrase for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase for %s (%s):" case UserAuthTypePIN: - return "Enter PIN for %[1]s (%[2]s):", nil + fmtString = "Enter PIN for %s (%s):" case UserAuthTypeRecoveryKey: - return "Enter recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter recovery key for %s (%s):" case UserAuthTypePassphrase | UserAuthTypePIN: - return "Enter passphrase or PIN for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase or PIN for %s (%s):" case UserAuthTypePassphrase | UserAuthTypeRecoveryKey: - return "Enter passphrase or recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase or recovery key for %s (%s):" case UserAuthTypePIN | UserAuthTypeRecoveryKey: - return "Enter PIN or recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter PIN or recovery key for %s (%s):" case UserAuthTypePassphrase | UserAuthTypePIN | UserAuthTypeRecoveryKey: - return "Enter passphrase, PIN or recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase, PIN or recovery key for %s (%s):" default: return "", errors.New("unexpected UserAuthType") } + return fmt.Sprintf(fmtString, name, path), nil } type testPlymouthRequestUserCredentialsParams struct { @@ -226,14 +228,14 @@ func (s *authRequestorPlymouthSuite) TestNewRequestorNoStringer(c *C) { c.Check(err, ErrorMatches, `must supply an implementation of PlymouthAuthRequestorStringer`) } -func (s *authRequestorPlymouthSuite) TestRequestUserCredentialObtainFormatStringError(c *C) { +func (s *authRequestorPlymouthSuite) TestRequestUserCredentialObtainMessageError(c *C) { requestor, err := NewPlymouthAuthRequestor(&mockPlymouthAuthRequestorStringer{ rucErr: errors.New("some error"), }) c.Assert(err, IsNil) _, _, err = requestor.RequestUserCredential(context.Background(), "data", "/dev/sda1", UserAuthTypePassphrase) - c.Check(err, ErrorMatches, `cannot request format string for requested auth types: some error`) + c.Check(err, ErrorMatches, `cannot request message string: some error`) } func (s *authRequestorPlymouthSuite) TestRequestUserCredentialFailure(c *C) { diff --git a/auth_requestor_systemd.go b/auth_requestor_systemd.go index a58c7d33..dfc48672 100644 --- a/auth_requestor_systemd.go +++ b/auth_requestor_systemd.go @@ -30,16 +30,21 @@ import ( "strings" ) +// SystemdAuthRequestorStringFn is a callback used to supply translated messages +// to the systemd implementation of AuthRequestor.RequestUserCredential. The name +// is a string supplied via the [WithAuthRequestorUserVisibleName] option, and the +// path is the storage container path. +type SystemdAuthRequestorStringFn func(name, path string, authTypes UserAuthType) (string, error) + type systemdAuthRequestor struct { - formatStringFn func(UserAuthType) (string, error) + stringFn SystemdAuthRequestorStringFn } func (r *systemdAuthRequestor) RequestUserCredential(ctx context.Context, name, path string, authTypes UserAuthType) (string, UserAuthType, error) { - fmtString, err := r.formatStringFn(authTypes) + msg, err := r.stringFn(name, path, authTypes) if err != nil { - return "", 0, fmt.Errorf("cannot request format string for requested auth types: %w", err) + return "", 0, fmt.Errorf("cannot request message string: %w", err) } - msg := fmt.Sprintf(fmtString, name, path) cmd := exec.CommandContext( ctx, "systemd-ask-password", @@ -62,15 +67,12 @@ func (r *systemdAuthRequestor) RequestUserCredential(ctx context.Context, name, // NewSystemdAuthRequestor creates an implementation of AuthRequestor that // delegates to the systemd-ask-password binary. The caller supplies a callback -// to map user auth type combinations to format strings that are used to -// messages.The format strings are interpreted with the following parameters: -// - %[1]s: A human readable name for the storage container. -// - %[2]s: The path of the encrypted storage container. -func NewSystemdAuthRequestor(formatStringFn func(UserAuthType) (string, error)) (AuthRequestor, error) { - if formatStringFn == nil { - return nil, errors.New("must supply a callback to obtain format strings for requesting user credentials") +// to supply messages for user auth requests. +func NewSystemdAuthRequestor(stringFn SystemdAuthRequestorStringFn) (AuthRequestor, error) { + if stringFn == nil { + return nil, errors.New("must supply a SystemdAuthRequestorStringFn") } return &systemdAuthRequestor{ - formatStringFn: formatStringFn, + stringFn: stringFn, }, nil } diff --git a/auth_requestor_systemd_test.go b/auth_requestor_systemd_test.go index 4ecea549..6504a3c2 100644 --- a/auth_requestor_systemd_test.go +++ b/auth_requestor_systemd_test.go @@ -71,25 +71,27 @@ type testSystemdRequestUserCredentialsParams struct { func (s *authRequestorSystemdSuite) testRequestUserCredential(c *C, params *testSystemdRequestUserCredentialsParams) { s.setPassphrase(c, params.passphrase) - requestor, err := NewSystemdAuthRequestor(func(authType UserAuthType) (string, error) { + requestor, err := NewSystemdAuthRequestor(func(name, path string, authType UserAuthType) (string, error) { + var fmtString string switch authType { case UserAuthTypePassphrase: - return "Enter passphrase for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase for %s (%s):" case UserAuthTypePIN: - return "Enter PIN for %[1]s (%[2]s):", nil + fmtString = "Enter PIN for %s (%s):" case UserAuthTypeRecoveryKey: - return "Enter recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter recovery key for %s (%s):" case UserAuthTypePassphrase | UserAuthTypePIN: - return "Enter passphrase or PIN for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase or PIN for %s (%s):" case UserAuthTypePassphrase | UserAuthTypeRecoveryKey: - return "Enter passphrase or recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase or recovery key for %s (%s):" case UserAuthTypePIN | UserAuthTypeRecoveryKey: - return "Enter PIN or recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter PIN or recovery key for %s (%s):" case UserAuthTypePassphrase | UserAuthTypePIN | UserAuthTypeRecoveryKey: - return "Enter passphrase, PIN or recovery key for %[1]s (%[2]s):", nil + fmtString = "Enter passphrase, PIN or recovery key for %s (%s):" default: return "", errors.New("unexpected UserAuthType") } + return fmt.Sprintf(fmtString, name, path), nil }) c.Assert(err, IsNil) @@ -215,23 +217,23 @@ func (s *authRequestorSystemdSuite) TestRequestUserCredentialPassphraseOrPINOrRe func (s *authRequestorSystemdSuite) TestNewRequestorNoFormatStringCallback(c *C) { _, err := NewSystemdAuthRequestor(nil) - c.Check(err, ErrorMatches, `must supply a callback to obtain format strings for requesting user credentials`) + c.Check(err, ErrorMatches, `must supply a SystemdAuthRequestorStringFn`) } -func (s *authRequestorSystemdSuite) TestRequestUserCredentialObtainFormatStringError(c *C) { - requestor, err := NewSystemdAuthRequestor(func(UserAuthType) (string, error) { +func (s *authRequestorSystemdSuite) TestRequestUserCredentialObtainMessageError(c *C) { + requestor, err := NewSystemdAuthRequestor(func(string, string, UserAuthType) (string, error) { return "", errors.New("some error") }) c.Assert(err, IsNil) _, _, err = requestor.RequestUserCredential(context.Background(), "data", "/dev/sda1", UserAuthTypePassphrase) - c.Check(err, ErrorMatches, `cannot request format string for requested auth types: some error`) + c.Check(err, ErrorMatches, `cannot request message string: some error`) } func (s *authRequestorSystemdSuite) TestRequestUserCredentialInvalidResponse(c *C) { c.Assert(ioutil.WriteFile(s.passwordFile, []byte("foo"), 0600), IsNil) - requestor, err := NewSystemdAuthRequestor(func(UserAuthType) (string, error) { + requestor, err := NewSystemdAuthRequestor(func(string, string, UserAuthType) (string, error) { return "", nil }) c.Assert(err, IsNil) @@ -241,7 +243,7 @@ func (s *authRequestorSystemdSuite) TestRequestUserCredentialInvalidResponse(c * } func (s *authRequestorSystemdSuite) TestRequestUserCredentialFailure(c *C) { - requestor, err := NewSystemdAuthRequestor(func(UserAuthType) (string, error) { + requestor, err := NewSystemdAuthRequestor(func(string, string, UserAuthType) (string, error) { return "", nil }) c.Assert(err, IsNil) @@ -253,7 +255,7 @@ func (s *authRequestorSystemdSuite) TestRequestUserCredentialFailure(c *C) { func (s *authRequestorSystemdSuite) TestRequestUserCredentialCanceledContext(c *C) { c.Assert(ioutil.WriteFile(s.passwordFile, []byte("foo"), 0600), IsNil) - requestor, err := NewSystemdAuthRequestor(func(UserAuthType) (string, error) { + requestor, err := NewSystemdAuthRequestor(func(string, string, UserAuthType) (string, error) { return "", nil }) c.Assert(err, IsNil)