From f9ed8fba7aa982b44aa71713126d3ca50a2d9096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Kokelj?= Date: Wed, 20 Sep 2023 12:08:24 +0200 Subject: [PATCH 1/4] try to get userID from URL if not present in query params --- tools/walletextension/api/routes.go | 14 ++++++--- tools/walletextension/api/utils.go | 33 ++++++++++++++++++++- tools/walletextension/common/constants.go | 1 + tools/walletextension/userconn/user_conn.go | 9 ++++++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/tools/walletextension/api/routes.go b/tools/walletextension/api/routes.go index 197ae64850..393df5f940 100644 --- a/tools/walletextension/api/routes.go +++ b/tools/walletextension/api/routes.go @@ -157,7 +157,7 @@ func ethRequestHandler(walletExt *walletextension.WalletExtension, conn userconn } // Get userID - hexUserID, err := getQueryParameter(conn.ReadRequestParams(), common.UserQueryParameter) + hexUserID, err := getUserID(conn, 1) if err != nil { walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w. Using the default user", err).Error()) hexUserID = hex.EncodeToString([]byte(common.DefaultUser)) // todo (@ziga) - this can be removed once old WE endpoints are removed @@ -317,7 +317,7 @@ func authenticateRequestHandler(walletExt *walletextension.WalletExtension, user } // read userID from query params - hexUserID, err := getQueryParameter(userConn.ReadRequestParams(), common.UserQueryParameter) + hexUserID, err := getUserID(userConn, 2) if err != nil { userConn.HandleError("Malformed query: 'u' required - representing userID") walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w", err).Error()) @@ -350,7 +350,7 @@ func queryRequestHandler(walletExt *walletextension.WalletExtension, userConn us return } - hexUserID, err := getQueryParameter(userConn.ReadRequestParams(), common.UserQueryParameter) + hexUserID, err := getUserID(userConn, 2) if err != nil { userConn.HandleError("user ('u') not found in query parameters") walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w", err).Error()) @@ -362,6 +362,12 @@ func queryRequestHandler(walletExt *walletextension.WalletExtension, userConn us walletExt.Logger().Error(fmt.Errorf("address not found in the query params: %w", err).Error()) return } + // check if address length is correct + if len(address) != common.EthereumAddressLen { + userConn.HandleError(fmt.Sprintf("provided address length is %d, expected: %d", len(address), common.EthereumAddressLen)) + walletExt.Logger().Error(fmt.Errorf(fmt.Sprintf("provided address length is %d, expected: %d", len(address), common.EthereumAddressLen)).Error()) + return + } // check if this account is registered with given user found, err := walletExt.UserHasAccount(hexUserID, address) @@ -399,7 +405,7 @@ func revokeRequestHandler(walletExt *walletextension.WalletExtension, userConn u return } - hexUserID, err := getQueryParameter(userConn.ReadRequestParams(), common.UserQueryParameter) + hexUserID, err := getUserID(userConn, 2) if err != nil { userConn.HandleError("user ('u') not found in query parameters") walletExt.Logger().Error(fmt.Errorf("user not found in the query params: %w", err).Error()) diff --git a/tools/walletextension/api/utils.go b/tools/walletextension/api/utils.go index 8a8ef189bb..ed5eab4c17 100644 --- a/tools/walletextension/api/utils.go +++ b/tools/walletextension/api/utils.go @@ -3,9 +3,10 @@ package api import ( "encoding/json" "fmt" - "github.com/obscuronet/go-obscuro/tools/walletextension/accountmanager" "github.com/obscuronet/go-obscuro/tools/walletextension/common" + "github.com/obscuronet/go-obscuro/tools/walletextension/userconn" + "strings" ) func parseRequest(body []byte) (*accountmanager.RPCRequest, error) { @@ -46,3 +47,33 @@ func getQueryParameter(params map[string]string, selectedParameter string) (stri return value, nil } + +func getUserID(conn userconn.UserConn, userIDPosition int) (string, error) { + // try getting userID from query parameters and return it if successful + userID, err := getQueryParameter(conn.ReadRequestParams(), common.UserQueryParameter) + if err == nil { + if len(userID) != common.MessageUserIDLen { + return "", fmt.Errorf(fmt.Sprintf("wrong length of userID from URL. Got: %d, Expected: %d", len(userID), common.MessageUserIDLen)) + } + return userID, err + } + + // Alternatively, try to get it from URL path + path := conn.GetHttpRequest().URL.Path + path = strings.Trim(path, "/") + parts := strings.Split(path, "/") + + // our URLs, which require userID, have following pattern: // + // userID can be only on second or third position + if len(parts) != userIDPosition+1 { + return "", fmt.Errorf("URL structure of the request looks wrong") + } + userID = parts[userIDPosition] + + // Check if userID has the correct length + if len(userID) != common.MessageUserIDLen { + return "", fmt.Errorf(fmt.Sprintf("wrong length of userID from URL. Got: %d, Expected: %d", len(userID), common.MessageUserIDLen)) + } + + return userID, nil +} diff --git a/tools/walletextension/common/constants.go b/tools/walletextension/common/constants.go index 0d57916901..4243aea462 100644 --- a/tools/walletextension/common/constants.go +++ b/tools/walletextension/common/constants.go @@ -45,6 +45,7 @@ const ( MessageFormatRegex = `^Register\s(\w+)\sfor\s(\w+)$` MessageUserIDLen = 64 SignatureLen = 65 + EthereumAddressLen = 42 PersonalSignMessagePrefix = "\x19Ethereum Signed Message:\n%d%s" GetStorageAtUserIDRequestMethodName = "getUserID" SuccessMsg = "success" diff --git a/tools/walletextension/userconn/user_conn.go b/tools/walletextension/userconn/user_conn.go index 017f85c775..4633309dad 100644 --- a/tools/walletextension/userconn/user_conn.go +++ b/tools/walletextension/userconn/user_conn.go @@ -31,6 +31,7 @@ type UserConn interface { HandleError(msg string) SupportsSubscriptions() bool IsClosed() bool + GetHttpRequest() *http.Request } // Represents a user's connection over HTTP. @@ -106,6 +107,10 @@ func (h *userConnHTTP) ReadRequestParams() map[string]string { return getQueryParams(h.req.URL.Query()) } +func (h *userConnHTTP) GetHttpRequest() *http.Request { + return h.req +} + func (w *userConnWS) ReadRequest() ([]byte, error) { _, msg, err := w.conn.ReadMessage() if err != nil { @@ -166,6 +171,10 @@ func (w *userConnWS) ReadRequestParams() map[string]string { return getQueryParams(w.req.URL.Query()) } +func (w *userConnWS) GetHttpRequest() *http.Request { + return w.req +} + // Logs the error, prints it to the console, and returns the error over HTTP. func httpLogAndSendErr(resp http.ResponseWriter, msg string) { http.Error(resp, msg, httpCodeErr) From fd278a81b1117d4af38ceb5c5ebf3c9cd5af02c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Kokelj?= Date: Thu, 21 Sep 2023 10:35:14 +0200 Subject: [PATCH 2/4] always sign address in lowercase --- tools/walletextension/api/staticOG/javascript.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/walletextension/api/staticOG/javascript.js b/tools/walletextension/api/staticOG/javascript.js index f416ee5017..d48cf4fbd5 100644 --- a/tools/walletextension/api/staticOG/javascript.js +++ b/tools/walletextension/api/staticOG/javascript.js @@ -64,7 +64,7 @@ async function authenticateAccountWithObscuroGateway(ethereum, account, userID) return "Account is already authenticated" } - const textToSign = "Register " + userID + " for " + account; + const textToSign = "Register " + userID + " for " + account.toLowerCase(); const signature = await ethereum.request({ method: metamaskPersonalSign, params: [textToSign, account] From 5a501c1e14520333371023186bc40fd2b224555f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Kokelj?= Date: Thu, 21 Sep 2023 10:37:54 +0200 Subject: [PATCH 3/4] lint fixes --- tools/walletextension/api/utils.go | 5 +++-- tools/walletextension/userconn/user_conn.go | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/walletextension/api/utils.go b/tools/walletextension/api/utils.go index ed5eab4c17..736b0bd928 100644 --- a/tools/walletextension/api/utils.go +++ b/tools/walletextension/api/utils.go @@ -3,10 +3,11 @@ package api import ( "encoding/json" "fmt" + "strings" + "github.com/obscuronet/go-obscuro/tools/walletextension/accountmanager" "github.com/obscuronet/go-obscuro/tools/walletextension/common" "github.com/obscuronet/go-obscuro/tools/walletextension/userconn" - "strings" ) func parseRequest(body []byte) (*accountmanager.RPCRequest, error) { @@ -59,7 +60,7 @@ func getUserID(conn userconn.UserConn, userIDPosition int) (string, error) { } // Alternatively, try to get it from URL path - path := conn.GetHttpRequest().URL.Path + path := conn.GetHTTPRequest().URL.Path path = strings.Trim(path, "/") parts := strings.Split(path, "/") diff --git a/tools/walletextension/userconn/user_conn.go b/tools/walletextension/userconn/user_conn.go index 4633309dad..b40e0ed28e 100644 --- a/tools/walletextension/userconn/user_conn.go +++ b/tools/walletextension/userconn/user_conn.go @@ -31,7 +31,7 @@ type UserConn interface { HandleError(msg string) SupportsSubscriptions() bool IsClosed() bool - GetHttpRequest() *http.Request + GetHTTPRequest() *http.Request } // Represents a user's connection over HTTP. @@ -107,7 +107,7 @@ func (h *userConnHTTP) ReadRequestParams() map[string]string { return getQueryParams(h.req.URL.Query()) } -func (h *userConnHTTP) GetHttpRequest() *http.Request { +func (h *userConnHTTP) GetHTTPRequest() *http.Request { return h.req } @@ -171,7 +171,7 @@ func (w *userConnWS) ReadRequestParams() map[string]string { return getQueryParams(w.req.URL.Query()) } -func (w *userConnWS) GetHttpRequest() *http.Request { +func (w *userConnWS) GetHTTPRequest() *http.Request { return w.req } From 85a67183265b5f3fb51c593d19740f507dbf688f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDiga=20Kokelj?= Date: Thu, 21 Sep 2023 12:11:59 +0200 Subject: [PATCH 4/4] comment updated --- tools/walletextension/api/utils.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/walletextension/api/utils.go b/tools/walletextension/api/utils.go index 736b0bd928..3bca5e921a 100644 --- a/tools/walletextension/api/utils.go +++ b/tools/walletextension/api/utils.go @@ -60,6 +60,9 @@ func getUserID(conn userconn.UserConn, userIDPosition int) (string, error) { } // Alternatively, try to get it from URL path + // This is a temporary hack to work around hardhat bug which causes hardhat to ignore query parameters. + // It is unsafe because https encrypts query parameters, + // but not URL itself and will be removed once hardhat bug is resolved. path := conn.GetHTTPRequest().URL.Path path = strings.Trim(path, "/") parts := strings.Split(path, "/")