diff --git a/cmd/serve.go b/cmd/serve.go index d3e0a20..4e2c524 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -42,7 +42,7 @@ func (c *serveCmd) Command() *cobra.Command { OptType: types.String, ConfigKey: &cfg.ServerBaseURL, FlagDefault: "http://localhost:8000", - Required: false, + Required: true, }, { Name: "wallet-signing-key", diff --git a/cmd/utils/custom_set_value.go b/cmd/utils/custom_set_value.go index e19b54c..f075a40 100644 --- a/cmd/utils/custom_set_value.go +++ b/cmd/utils/custom_set_value.go @@ -13,7 +13,7 @@ func SetConfigOptionStellarPublicKey(co *config.ConfigOption) error { kp, err := keypair.ParseAddress(publicKey) if err != nil { - return fmt.Errorf("error validating public key in %s: %w", co.Name, err) + return fmt.Errorf("validating public key in %s: %w", co.Name, err) } key, ok := co.ConfigKey.(*string) diff --git a/cmd/utils/custom_set_value_test.go b/cmd/utils/custom_set_value_test.go index 49c5cf9..d390d5c 100644 --- a/cmd/utils/custom_set_value_test.go +++ b/cmd/utils/custom_set_value_test.go @@ -93,17 +93,17 @@ func TestSetConfigOptionStellarPublicKey(t *testing.T) { testCases := []customSetterTestCase[string]{ { name: "returns an error if the public key is empty", - wantErrContains: "error validating public key in wallet-signing-key: strkey is 0 bytes long; minimum valid length is 5", + wantErrContains: "validating public key in wallet-signing-key: strkey is 0 bytes long; minimum valid length is 5", }, { name: "returns an error if the public key is invalid", args: []string{"--wallet-signing-key", "invalid_public_key"}, - wantErrContains: "error validating public key in wallet-signing-key: base32 decode failed: illegal base32 data at input byte 18", + wantErrContains: "validating public key in wallet-signing-key: base32 decode failed: illegal base32 data at input byte 18", }, { name: "returns an error if the public key is invalid (private key instead)", args: []string{"--wallet-signing-key", "SDISQRUPIHAO5WIIGY4QRDCINZSA44TX3OIIUK3C63NUKN5DABKEQ276"}, - wantErrContains: "error validating public key in wallet-signing-key: invalid version byte", + wantErrContains: "validating public key in wallet-signing-key: invalid version byte", }, { name: "handles Stellar public key through the CLI flag", diff --git a/internal/serve/auth/signature_verifier.go b/internal/serve/auth/signature_verifier.go index 37400d1..2dbb502 100644 --- a/internal/serve/auth/signature_verifier.go +++ b/internal/serve/auth/signature_verifier.go @@ -25,11 +25,15 @@ var ( ) type ErrInvalidTimestampFormat struct { - TimestampString string + TimestampString string + timestampValueError bool } func (e ErrInvalidTimestampFormat) Error() string { - return fmt.Sprintf("signature format different than expected. expected unix seconds, got: %s", e.TimestampString) + if e.timestampValueError { + return fmt.Sprintf("signature format different than expected. expected unix seconds, got: %s", e.TimestampString) + } + return fmt.Sprintf("malformed timestamp: %s", e.TimestampString) } type ErrExpiredSignatureTimestamp struct { @@ -53,21 +57,13 @@ func (sv *StellarSignatureVerifier) VerifySignature(ctx context.Context, signatu t, s, err := ExtractTimestampedSignature(signatureHeaderContent) if err != nil { log.Ctx(ctx).Error(err) - var errTimestampFormat *ErrInvalidTimestampFormat - if errors.As(err, &errTimestampFormat) { - return err - } return ErrStellarSignatureNotVerified } - // 2 minutes in seconds + // 2 seconds err = VerifyGracePeriodSeconds(t, 2*time.Second) if err != nil { log.Ctx(ctx).Error(err) - var errExpiredSignatureTimestamp *ErrExpiredSignatureTimestamp - if errors.As(err, &errExpiredSignatureTimestamp) { - return err - } return ErrStellarSignatureNotVerified } @@ -97,20 +93,20 @@ func (sv *StellarSignatureVerifier) VerifySignature(ctx context.Context, signatu func ExtractTimestampedSignature(signatureHeaderContent string) (t string, s string, err error) { parts := strings.SplitN(signatureHeaderContent, ",", 2) if len(parts) != 2 { - return "", "", fmt.Errorf("malformed header format: %s", signatureHeaderContent) + return "", "", fmt.Errorf("malformed header: %s", signatureHeaderContent) } tHeaderContent := parts[0] timestampParts := strings.SplitN(tHeaderContent, "=", 2) if len(timestampParts) != 2 || strings.TrimSpace(timestampParts[0]) != "t" { - return "", "", fmt.Errorf("malformed timestamp format: %s", timestampParts) + return "", "", &ErrInvalidTimestampFormat{TimestampString: tHeaderContent} } t = strings.TrimSpace(timestampParts[1]) sHeaderContent := parts[1] signatureParts := strings.SplitN(sHeaderContent, "=", 2) if len(signatureParts) != 2 || strings.TrimSpace(signatureParts[0]) != "s" { - return "", "", fmt.Errorf("malformed signature format: %s", signatureParts) + return "", "", fmt.Errorf("malformed signature: %s", signatureParts) } s = strings.TrimSpace(signatureParts[1]) @@ -120,7 +116,7 @@ func ExtractTimestampedSignature(signatureHeaderContent string) (t string, s str func VerifyGracePeriodSeconds(timestampString string, gracePeriod time.Duration) error { // Note: from Nov 20th, 2286 this RegEx will fail because of an extra digit if ok, _ := regexp.MatchString(`^\d{10}$`, timestampString); !ok { - return &ErrInvalidTimestampFormat{TimestampString: timestampString} + return &ErrInvalidTimestampFormat{TimestampString: timestampString, timestampValueError: true} } timestampUnix, err := strconv.ParseInt(timestampString, 10, 64) diff --git a/internal/serve/auth/signature_verifier_test.go b/internal/serve/auth/signature_verifier_test.go index 91be3bc..aae45f6 100644 --- a/internal/serve/auth/signature_verifier_test.go +++ b/internal/serve/auth/signature_verifier_test.go @@ -61,17 +61,19 @@ func TestSignatureVerifierVerifySignature(t *testing.T) { func TestExtractTimestampedSignature(t *testing.T) { t.Run("invalid_header_content", func(t *testing.T) { ts, s, err := ExtractTimestampedSignature("") - assert.EqualError(t, err, "malformed header format: ") + assert.EqualError(t, err, "malformed header: ") assert.Empty(t, ts) assert.Empty(t, s) ts, s, err = ExtractTimestampedSignature("a,b") - assert.EqualError(t, err, "malformed timestamp format: [a]") + var errTimestampFormat *ErrInvalidTimestampFormat + assert.ErrorAs(t, err, &errTimestampFormat) + assert.EqualError(t, err, "malformed timestamp: a") assert.Empty(t, ts) assert.Empty(t, s) ts, s, err = ExtractTimestampedSignature("t=abc,b") - assert.EqualError(t, err, "malformed signature format: [b]") + assert.EqualError(t, err, "malformed signature: [b]") assert.Empty(t, ts) assert.Empty(t, s) })