mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
passing test
This commit is contained in:
parent
5c54198a68
commit
35e187b8f7
4 changed files with 75 additions and 23 deletions
|
|
@ -256,3 +256,23 @@ func PeerInfoFromContext(ctx context.Context) PeerInfo {
|
|||
info, _ := ctx.Value(peerInfoContextKey{}).(PeerInfo)
|
||||
return info
|
||||
}
|
||||
|
||||
// ContextWithMockPeerInfo is a helper function to create a context with a mock peer info.
|
||||
// It is used in tests to simulate a peer info.
|
||||
func ContextWithMockPeerInfo(ctx context.Context, transport, source, account string) context.Context {
|
||||
peerInfo := PeerInfo{
|
||||
Transport: transport,
|
||||
HTTP: struct {
|
||||
Version string
|
||||
UserAgent string
|
||||
Origin string
|
||||
Host string
|
||||
}{
|
||||
Version: "1.1",
|
||||
UserAgent: "test",
|
||||
Origin: source,
|
||||
Host: "test",
|
||||
},
|
||||
}
|
||||
return context.WithValue(ctx, peerInfoContextKey{}, peerInfo)
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package core_test
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
|
@ -32,6 +33,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/ethereum/go-ethereum/signer/core"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -1068,14 +1070,23 @@ func TestSignInWithEtheriumValid(t *testing.T) {
|
|||
testFiles, err := os.ReadDir(filepath.Join("testdata", "siwe"))
|
||||
require.NoError(t, err)
|
||||
|
||||
var messages map[string]string
|
||||
type TestData struct {
|
||||
Msg string `json:"msg"`
|
||||
Account string `json:"account"`
|
||||
RequestContext struct {
|
||||
Transport string `json:"transport"`
|
||||
Source string `json:"source"`
|
||||
Account string `json:"account"`
|
||||
} `json:"request_context"`
|
||||
}
|
||||
var messages map[string]TestData
|
||||
var expectingWarning bool
|
||||
|
||||
for _, fInfo := range testFiles {
|
||||
if !strings.HasSuffix(fInfo.Name(), "json") {
|
||||
continue
|
||||
}
|
||||
if fInfo.Name() != "warning_uris.json" {
|
||||
if fInfo.Name() != "valid_eip1271.json" {
|
||||
continue
|
||||
}
|
||||
expectingWarning = strings.HasPrefix(fInfo.Name(), "warning")
|
||||
|
|
@ -1086,7 +1097,7 @@ func TestSignInWithEtheriumValid(t *testing.T) {
|
|||
err = json.Unmarshal(jsonFile, &messages)
|
||||
require.NoError(t, err)
|
||||
|
||||
for testName, message := range messages {
|
||||
for testName, testData := range messages {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
@ -1098,9 +1109,13 @@ func TestSignInWithEtheriumValid(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
a := common.NewMixedcaseAddress(list[0])
|
||||
|
||||
ctx := rpc.ContextWithMockPeerInfo(context.Background(), testData.RequestContext.Transport, testData.RequestContext.Source, testData.Account)
|
||||
account := cmp.Or(testData.Account, a.Address().Hex())
|
||||
message := strings.ReplaceAll(testData.Msg, "{{Account}}", account)
|
||||
|
||||
control.approveCh <- "Y"
|
||||
control.inputCh <- "a_long_password"
|
||||
signature, err := api.SignData(context.Background(), apitypes.TextPlain.Mime, a, hexutil.Encode([]byte(message)))
|
||||
signature, err := api.SignData(ctx, apitypes.TextPlain.Mime, a, hexutil.Encode([]byte(message)))
|
||||
|
||||
if expectingWarning {
|
||||
// todo: check UI for warning message
|
||||
|
|
|
|||
|
|
@ -25,24 +25,27 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
// Message size
|
||||
var messageSize = `(?:\d+)`
|
||||
|
||||
// Regular expression to match SIWE messages
|
||||
// Scheme (optional)
|
||||
var scheme = `(?:[a-zA-Z][a-zA-Z0-9+\-.]*://)?`
|
||||
var scheme = `([a-zA-Z][a-zA-Z0-9+\-.]*://)?`
|
||||
|
||||
// Domain
|
||||
var domain = `(?:[^ ]+)`
|
||||
var domain = `([^ ]+)`
|
||||
|
||||
// Static message
|
||||
var wantsMsg = ` wants you to sign in with your Ethereum account:\n`
|
||||
|
||||
// Ethereum address (with basic 0x prefix + 40 hex digits)
|
||||
var address = `(?:0x[a-fA-F0-9]{40})\n`
|
||||
var address = `(0x[a-fA-F0-9]{40})\n`
|
||||
|
||||
// Optional statement (any line not containing "\n\n")
|
||||
var statement = `(?:[^\n]+\n)?`
|
||||
|
||||
// URI
|
||||
var uri = `URI: (.+)\n`
|
||||
var uri = `URI: (?:.+)\n`
|
||||
|
||||
// Version
|
||||
var version = `Version: 1\n`
|
||||
|
|
@ -51,25 +54,25 @@ var version = `Version: 1\n`
|
|||
var chainID = `Chain ID: (\d+)\n`
|
||||
|
||||
// Nonce (min 8 alphanumeric characters)
|
||||
var nonce = `Nonce: [a-zA-Z0-9]{8,}\n`
|
||||
var nonce = `Nonce: (?:[a-zA-Z0-9]{8,})\n`
|
||||
|
||||
// Issued At (RFC 3339 date-time)
|
||||
var issuedAt = `Issued At: ([0-9T:\-+.Z]+)`
|
||||
var issuedAt = `Issued At: (?:[0-9T:\-+.Z]+)`
|
||||
|
||||
// Optional Expiration Time
|
||||
var expiration = `(?:\nExpiration Time: ([0-9T:\-+.Z]+))?`
|
||||
var expiration = `(?:\nExpiration Time: (?:[0-9T:\-+.Z]+))?`
|
||||
|
||||
// Optional Not Before
|
||||
var notBefore = `(?:\nNot Before: ([0-9T:\-+.Z]+))?`
|
||||
var notBefore = `(?:\nNot Before: (?:[0-9T:\-+.Z]+))?`
|
||||
|
||||
// Optional Request ID
|
||||
var requestID = `(?:\nRequest ID: ([^\n]+))?`
|
||||
var requestID = `(?:\nRequest ID: (?:[^\n]+))?`
|
||||
|
||||
// Optional Resources
|
||||
var resources = `(?:\nResources:(?:\n- .+)+)?`
|
||||
|
||||
// SIWE Message Regex
|
||||
var siweMessageRegex = regexp.MustCompile(`(?m)^` + scheme + domain + wantsMsg +
|
||||
var siweMessageRegex = regexp.MustCompile(`(?m)^` + messageSize + scheme + domain + wantsMsg +
|
||||
address + `\n` + statement + `\n` +
|
||||
uri + version + chainID + nonce + issuedAt +
|
||||
expiration + notBefore + requestID + resources + `$`)
|
||||
|
|
@ -85,18 +88,19 @@ func validateSIWE(req *SignDataRequest) error {
|
|||
if !strings.Contains(s, "wants you to sign in with your Ethereum account") {
|
||||
continue
|
||||
}
|
||||
|
||||
patterns := siweMessageRegex.FindStringSubmatch(s)
|
||||
if len(patterns) != 15 {
|
||||
if patterns == nil {
|
||||
return ErrMalformedSIWEMEssage
|
||||
}
|
||||
scheme := "https"
|
||||
if patterns[0] != "" {
|
||||
scheme = patterns[0]
|
||||
if patterns[1] != "" {
|
||||
scheme = patterns[1]
|
||||
}
|
||||
if err := validateDomain(req, scheme, patterns[1]); err != nil {
|
||||
if err := validateDomain(req, scheme, patterns[2]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateAddress(req, patterns[2]); err != nil {
|
||||
if err := validateAddress(req, patterns[3]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -105,8 +109,9 @@ func validateSIWE(req *SignDataRequest) error {
|
|||
|
||||
func validateDomain(request *SignDataRequest, scheme, domain string) error {
|
||||
siweOrigin := fmt.Sprintf("%s://%s", scheme, domain)
|
||||
if siweOrigin != request.Meta.Origin {
|
||||
return fmt.Errorf("sign in request domain (%s) does not match source: %s", siweOrigin, request.Meta.Origin)
|
||||
requestOrigin := fmt.Sprintf("%s://%s", request.Meta.Scheme, request.Meta.Origin)
|
||||
if siweOrigin != requestOrigin {
|
||||
return fmt.Errorf("sign in request domain (%s) does not match source: %s", siweOrigin, requestOrigin)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
16
signer/core/testdata/siwe/valid_eip1271.json
vendored
16
signer/core/testdata/siwe/valid_eip1271.json
vendored
|
|
@ -1,4 +1,16 @@
|
|||
{
|
||||
"argent": "localhost:4361 wants you to sign in with your Ethereum account:\n0xa5b3A53800cD49669F34DE80f2C569c6D4Ca3009\n\nSIWE Notepad Example\n\nURI: http://localhost:4361\nVersion: 1\nChain ID: 1\nNonce: FbYd6TNB4m0IUHDG7\nIssued At: 2022-04-19T18:55:04.444Z",
|
||||
"loopring": "localhost:4361 wants you to sign in with your Ethereum account:\n0x0e565A6dFc43DE21455a67bbF196f7F7b15447A7\n\nSIWE Notepad Example\n\nURI: http://localhost:4361\nVersion: 1\nChain ID: 1\nNonce: b19JyMHnM0Jdm20as\nIssued At: 2022-04-19T18:57:09.490Z"
|
||||
"argent": {
|
||||
"msg": "localhost:4361 wants you to sign in with your Ethereum account:\n{{Account}}\n\nSIWE Notepad Example\n\nURI: http://localhost:4361\nVersion: 1\nChain ID: 1\nNonce: FbYd6TNB4m0IUHDG7\nIssued At: 2022-04-19T18:55:04.444Z",
|
||||
"request_context": {
|
||||
"transport": "https",
|
||||
"source": "localhost:4361"
|
||||
}
|
||||
},
|
||||
"loopring": {
|
||||
"msg": "localhost:4361 wants you to sign in with your Ethereum account:\n{{Account}}\n\nSIWE Notepad Example\n\nURI: http://localhost:4361\nVersion: 1\nChain ID: 1\nNonce: b19JyMHnM0Jdm20as\nIssued At: 2022-04-19T18:57:09.490Z",
|
||||
"request_context": {
|
||||
"transport": "https",
|
||||
"source": "localhost:4361"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue