From da849cc9be68974f49621b0f188e336d1b6afc0e Mon Sep 17 00:00:00 2001 From: Daniel Krol Date: Fri, 17 Jun 2022 16:12:20 -0400 Subject: [PATCH] Test (and fix) validation for register --- server/auth.go | 17 +---------------- server/register.go | 2 +- server/register_test.go | 23 ++++++++++++++++++++++- server/server.go | 15 +++++++++++++++ 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/server/auth.go b/server/auth.go index bbd4614..ac03854 100644 --- a/server/auth.go +++ b/server/auth.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "net/http" - "net/mail" "orblivion/lbry-id/auth" "orblivion/lbry-id/store" ) @@ -20,21 +19,7 @@ type AuthRequest struct { // TODO - validate funcs probably should return error rather than bool for // idiomatic golang func (r *AuthRequest) validate() bool { - e, err := mail.ParseAddress(string(r.Email)) - if err != nil { - return false - } - // "Joe " is valid according to ParseAddress. Likewise - // " joe@example.com". Etc. We only want the exact address, "joe@example.com" - // to be valid. ParseAddress will extract the exact address as e.Address. So - // we'll take the input email, put it through ParseAddress, see if it parses - // successfully, and then compare the input email to e.Address to make sure - // that it was an exact address to begin with. - if string(r.Email) != e.Address { - return false - } - - return (r.DeviceId != "" && r.Password != auth.Password("")) + return r.DeviceId != "" && r.Password != auth.Password("") && validateEmail(r.Email) } func (s *Server) getAuthToken(w http.ResponseWriter, req *http.Request) { diff --git a/server/register.go b/server/register.go index b67f60c..e196efa 100644 --- a/server/register.go +++ b/server/register.go @@ -17,7 +17,7 @@ type RegisterRequest struct { } func (r *RegisterRequest) validate() bool { - return r.Email != "" && r.Password != "" + return validateEmail(r.Email) && r.Password != "" } func (s *Server) register(w http.ResponseWriter, req *http.Request) { diff --git a/server/register_test.go b/server/register_test.go index fbdda7b..c5aac5e 100644 --- a/server/register_test.go +++ b/server/register_test.go @@ -41,5 +41,26 @@ func TestServerRegisterErrors(t *testing.T) { } func TestServerValidateRegisterRequest(t *testing.T) { - t.Fatalf("Test me: Implement and test RegisterRequest.validate()") + registerRequest := RegisterRequest{Email: "joe@example.com", Password: "aoeu"} + if !registerRequest.validate() { + t.Fatalf("Expected valid RegisterRequest to successfully validate") + } + + registerRequest = RegisterRequest{Email: "joe-example.com", Password: "aoeu"} + if registerRequest.validate() { + t.Fatalf("Expected RegisterRequest with invalid email to not successfully validate") + } + + // Note that Golang's email address parser, which I use, will accept + // "Joe " so we need to make sure to avoid accepting it. See + // the implementation. + registerRequest = RegisterRequest{Email: "Joe ", Password: "aoeu"} + if registerRequest.validate() { + t.Fatalf("Expected RegisterRequest with email with unexpected formatting to not successfully validate") + } + + registerRequest = RegisterRequest{Email: "joe@example.com"} + if registerRequest.validate() { + t.Fatalf("Expected RegisterRequest with missing password to not successfully validate") + } } diff --git a/server/server.go b/server/server.go index 765e94f..4413ff5 100644 --- a/server/server.go +++ b/server/server.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "net/mail" "orblivion/lbry-id/auth" "orblivion/lbry-id/store" ) @@ -149,6 +150,20 @@ func (s *Server) checkAuth( return authToken } +func validateEmail(email auth.Email) bool { + e, err := mail.ParseAddress(string(email)) + if err != nil { + return false + } + // "Joe " is valid according to ParseAddress. Likewise + // " joe@example.com". Etc. We only want the exact address, "joe@example.com" + // to be valid. ParseAddress will extract the exact address as e.Address. So + // we'll take the input email, put it through ParseAddress, see if it parses + // successfully, and then compare the input email to e.Address to make sure + // that it was an exact address to begin with. + return string(email) == e.Address +} + // TODO - both wallet and token requests should be PUT, not POST. // PUT = "...creates a new resource or replaces a representation of the target resource with the request payload."