diff --git a/auth/auth.go b/auth/auth.go index 7fe2853..6dc82a3 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -152,6 +152,10 @@ func (c ClientSaltSeed) Validate() bool { return len(c) == seedHexLength && err == nil } +func (p Password) Validate() bool { + return len(p) >= 8 // Should be much longer but it's a sanity check. +} + // TODO consider unicode. Also some providers might be case sensitive, and/or // may have other ways of having email addresses be equivalent (which we may // not care about though) diff --git a/server/account.go b/server/account.go index 64ae56f..01f97d6 100644 --- a/server/account.go +++ b/server/account.go @@ -25,8 +25,8 @@ func (r *RegisterRequest) validate() error { if !r.Email.Validate() { return fmt.Errorf("Invalid or missing 'email'") } - if r.Password == "" { - return fmt.Errorf("Missing 'password'") + if !r.Password.Validate() { + return fmt.Errorf("Invalid or missing 'password'") } if !r.ClientSaltSeed.Validate() { diff --git a/server/account_test.go b/server/account_test.go index 8b84ebf..e6e1470 100644 --- a/server/account_test.go +++ b/server/account_test.go @@ -24,7 +24,7 @@ func TestServerRegisterSuccess(t *testing.T) { testAuth := TestAuth{TestNewVerifyTokenString: "abcd1234abcd1234abcd1234abcd1234"} s := Server{&testAuth, testStore, &TestEnv{env}, &testMail, TestPort} - requestBody := []byte(`{"email": "abc@example.com", "password": "123", "clientSaltSeed": "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234" }`) + requestBody := []byte(`{"email": "abc@example.com", "password": "12345678", "clientSaltSeed": "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234" }`) req := httptest.NewRequest(http.MethodPost, paths.PathRegister, bytes.NewBuffer(requestBody)) w := httptest.NewRecorder() @@ -132,7 +132,7 @@ func TestServerRegisterErrors(t *testing.T) { s := Server{&testAuth, &testStore, &TestEnv{env}, &testMail, TestPort} // Make request - requestBody := fmt.Sprintf(`{"email": "%s", "password": "123", "clientSaltSeed": "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"}`, tc.email) + requestBody := fmt.Sprintf(`{"email": "%s", "password": "12345678", "clientSaltSeed": "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"}`, tc.email) req := httptest.NewRequest(http.MethodPost, paths.PathAuthToken, bytes.NewBuffer([]byte(requestBody))) w := httptest.NewRecorder() @@ -229,7 +229,7 @@ func TestServerRegisterAccountVerification(t *testing.T) { testMail := TestMail{} s := Server{&testAuth, testStore, &TestEnv{tc.env}, &testMail, TestPort} - requestBody := []byte(`{"email": "abc@example.com", "password": "123", "clientSaltSeed": "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234" }`) + requestBody := []byte(`{"email": "abc@example.com", "password": "12345678", "clientSaltSeed": "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234" }`) req := httptest.NewRequest(http.MethodPost, paths.PathRegister, bytes.NewBuffer(requestBody)) w := httptest.NewRecorder() @@ -274,12 +274,12 @@ func TestServerRegisterAccountVerification(t *testing.T) { } func TestServerValidateRegisterRequest(t *testing.T) { - registerRequest := RegisterRequest{Email: "joe@example.com", Password: "aoeu", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} + registerRequest := RegisterRequest{Email: "joe@example.com", Password: "12345678", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} if registerRequest.validate() != nil { t.Errorf("Expected valid RegisterRequest to successfully validate") } - registerRequest = RegisterRequest{Email: "joe-example.com", Password: "aoeu", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} + registerRequest = RegisterRequest{Email: "joe-example.com", Password: "12345678", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} err := registerRequest.validate() if !strings.Contains(err.Error(), "email") { t.Errorf("Expected RegisterRequest with invalid email to return an appropriate error") @@ -288,13 +288,13 @@ func TestServerValidateRegisterRequest(t *testing.T) { // 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", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} + registerRequest = RegisterRequest{Email: "Joe ", Password: "12345678", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} err = registerRequest.validate() if !strings.Contains(err.Error(), "email") { t.Errorf("Expected RegisterRequest with email with unexpected formatting to return an appropriate error") } - registerRequest = RegisterRequest{Password: "aoeu", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} + registerRequest = RegisterRequest{Password: "12345678", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"} err = registerRequest.validate() if !strings.Contains(err.Error(), "email") { t.Errorf("Expected RegisterRequest with missing email to return an appropriate error") @@ -306,19 +306,19 @@ func TestServerValidateRegisterRequest(t *testing.T) { t.Errorf("Expected RegisterRequest with missing password to return an appropriate error") } - registerRequest = RegisterRequest{Email: "joe@example.com", Password: "aoeu"} + registerRequest = RegisterRequest{Email: "joe@example.com", Password: "12345678"} err = registerRequest.validate() if !strings.Contains(err.Error(), "clientSaltSeed") { t.Errorf("Expected RegisterRequest with missing clientSaltSeed to return an appropriate error") } - registerRequest = RegisterRequest{Email: "joe@example.com", Password: "aoeu", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234"} + registerRequest = RegisterRequest{Email: "joe@example.com", Password: "12345678", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234"} err = registerRequest.validate() if !strings.Contains(err.Error(), "clientSaltSeed") { t.Errorf("Expected RegisterRequest with clientSaltSeed of wrong length to return an appropriate error") } - registerRequest = RegisterRequest{Email: "joe@example.com", Password: "aoeu", ClientSaltSeed: "xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234"} + registerRequest = RegisterRequest{Email: "joe@example.com", Password: "12345678", ClientSaltSeed: "xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234"} err = registerRequest.validate() if !strings.Contains(err.Error(), "clientSaltSeed") { t.Errorf("Expected RegisterRequest with clientSaltSeed with a non-hex string to return an appropriate error") diff --git a/server/auth.go b/server/auth.go index ed1356b..85ea9ba 100644 --- a/server/auth.go +++ b/server/auth.go @@ -21,8 +21,8 @@ func (r *AuthRequest) validate() error { if !r.Email.Validate() { return fmt.Errorf("Invalid 'email'") } - if r.Password == "" { - return fmt.Errorf("Missing 'password'") + if !r.Password.Validate() { + return fmt.Errorf("Invalid or missing 'password'") } if r.DeviceId == "" { return fmt.Errorf("Missing 'deviceId'") diff --git a/server/auth_test.go b/server/auth_test.go index 66fc059..36dd8f9 100644 --- a/server/auth_test.go +++ b/server/auth_test.go @@ -20,7 +20,7 @@ func TestServerAuthHandlerSuccess(t *testing.T) { testStore := TestStore{} s := Server{&testAuth, &testStore, &TestEnv{}, &TestMail{}, TestPort} - requestBody := []byte(`{"deviceId": "dev-1", "email": "abc@example.com", "password": "123"}`) + requestBody := []byte(`{"deviceId": "dev-1", "email": "abc@example.com", "password": "12345678"}`) req := httptest.NewRequest(http.MethodPost, paths.PathAuthToken, bytes.NewBuffer(requestBody)) w := httptest.NewRecorder() @@ -108,7 +108,7 @@ func TestServerAuthHandlerErrors(t *testing.T) { // Make request // So long as the JSON is well-formed, the content doesn't matter here since the password check will be stubbed out - requestBody := fmt.Sprintf(`{"deviceId": "dev-1", "email": "%s", "password": "123"}`, tc.email) + requestBody := fmt.Sprintf(`{"deviceId": "dev-1", "email": "%s", "password": "12345678"}`, tc.email) req := httptest.NewRequest(http.MethodPost, paths.PathAuthToken, bytes.NewBuffer([]byte(requestBody))) w := httptest.NewRecorder() @@ -123,7 +123,7 @@ func TestServerAuthHandlerErrors(t *testing.T) { } func TestServerValidateAuthRequest(t *testing.T) { - authRequest := AuthRequest{DeviceId: "dId", Email: "joe@example.com", Password: "aoeu"} + authRequest := AuthRequest{DeviceId: "dId", Email: "joe@example.com", Password: "12345678"} if authRequest.validate() != nil { t.Errorf("Expected valid AuthRequest to successfully validate") } @@ -134,22 +134,22 @@ func TestServerValidateAuthRequest(t *testing.T) { failureDescription string }{ { - AuthRequest{Email: "joe@example.com", Password: "aoeu"}, + AuthRequest{Email: "joe@example.com", Password: "12345678"}, "deviceId", "Expected AuthRequest with missing device to not successfully validate", }, { - AuthRequest{DeviceId: "dId", Email: "joe-example.com", Password: "aoeu"}, + AuthRequest{DeviceId: "dId", Email: "joe-example.com", Password: "12345678"}, "email", "Expected AuthRequest 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. - AuthRequest{DeviceId: "dId", Email: "Joe ", Password: "aoeu"}, + AuthRequest{DeviceId: "dId", Email: "Joe ", Password: "12345678"}, "email", "Expected AuthRequest with email with unexpected formatting to not successfully validate", }, { - AuthRequest{DeviceId: "dId", Password: "aoeu"}, + AuthRequest{DeviceId: "dId", Password: "12345678"}, "email", "Expected AuthRequest with missing email to not successfully validate", }, { diff --git a/server/integration_test.go b/server/integration_test.go index af8c067..3c58bb1 100644 --- a/server/integration_test.go +++ b/server/integration_test.go @@ -114,7 +114,7 @@ func TestIntegrationWalletUpdates(t *testing.T) { s.register, paths.PathRegister, ®isterResponse, - `{"email": "abc@example.com", "password": "123", "clientSaltSeed": "1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd"}`, + `{"email": "abc@example.com", "password": "12345678", "clientSaltSeed": "1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd"}`, ) checkStatusCode(t, statusCode, responseBody, http.StatusCreated) @@ -130,7 +130,7 @@ func TestIntegrationWalletUpdates(t *testing.T) { s.getAuthToken, paths.PathAuthToken, &authToken1, - `{"deviceId": "dev-1", "email": "abc@example.com", "password": "123"}`, + `{"deviceId": "dev-1", "email": "abc@example.com", "password": "12345678"}`, ) checkStatusCode(t, statusCode, responseBody) @@ -158,7 +158,7 @@ func TestIntegrationWalletUpdates(t *testing.T) { s.getAuthToken, paths.PathAuthToken, &authToken2, - `{"deviceId": "dev-2", "email": "abc@example.com", "password": "123"}`, + `{"deviceId": "dev-2", "email": "abc@example.com", "password": "12345678"}`, ) checkStatusCode(t, statusCode, responseBody) @@ -284,7 +284,7 @@ func TestIntegrationChangePassword(t *testing.T) { s.register, paths.PathRegister, ®isterResponse, - `{"email": "abc@example.com", "password": "123", "clientSaltSeed": "1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd"}`, + `{"email": "abc@example.com", "password": "12345678", "clientSaltSeed": "1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd"}`, ) checkStatusCode(t, statusCode, responseBody, http.StatusCreated) @@ -322,7 +322,7 @@ func TestIntegrationChangePassword(t *testing.T) { s.getAuthToken, paths.PathAuthToken, &authToken, - `{"deviceId": "dev-1", "email": "abc@example.com", "password": "123"}`, + `{"deviceId": "dev-1", "email": "abc@example.com", "password": "12345678"}`, ) checkStatusCode(t, statusCode, responseBody) @@ -350,7 +350,7 @@ func TestIntegrationChangePassword(t *testing.T) { s.changePassword, paths.PathPassword, &changePasswordResponse, - `{"email": "abc@example.com", "oldPassword": "123", "newPassword": "456", "clientSaltSeed": "8678def95678def98678def95678def98678def95678def98678def95678def9"}`, + `{"email": "abc@example.com", "oldPassword": "12345678", "newPassword": "45678901", "clientSaltSeed": "8678def95678def98678def95678def98678def95678def98678def95678def9"}`, ) checkStatusCode(t, statusCode, responseBody) @@ -405,7 +405,7 @@ func TestIntegrationChangePassword(t *testing.T) { s.getAuthToken, paths.PathAuthToken, &authToken, - `{"deviceId": "dev-1", "email": "abc@example.com", "password": "456"}`, + `{"deviceId": "dev-1", "email": "abc@example.com", "password": "45678901"}`, ) checkStatusCode(t, statusCode, responseBody) @@ -457,8 +457,8 @@ func TestIntegrationChangePassword(t *testing.T) { "sequence": 2, "hmac": "my-hmac-2", "email": "abc@example.com", - "oldPassword": "456", - "newPassword": "789", + "oldPassword": "45678901", + "newPassword": "78901234", "clientSaltSeed": "0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff" }`), ) @@ -510,7 +510,7 @@ func TestIntegrationChangePassword(t *testing.T) { s.getAuthToken, paths.PathAuthToken, &authToken, - `{"deviceId": "dev-1", "email": "abc@example.com", "password": "789"}`, + `{"deviceId": "dev-1", "email": "abc@example.com", "password": "78901234"}`, ) checkStatusCode(t, statusCode, responseBody) @@ -575,7 +575,7 @@ func TestIntegrationVerifyAccount(t *testing.T) { s.register, paths.PathRegister, ®isterResponse, - `{"email": "abc@example.com", "password": "123", "clientSaltSeed": "1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd"}`, + `{"email": "abc@example.com", "password": "12345678", "clientSaltSeed": "1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd"}`, ) checkStatusCode(t, statusCode, responseBody, http.StatusCreated) @@ -619,7 +619,7 @@ func TestIntegrationVerifyAccount(t *testing.T) { s.getAuthToken, paths.PathAuthToken, &authToken, - `{"deviceId": "dev-1", "email": "abc@example.com", "password": "123"}`, + `{"deviceId": "dev-1", "email": "abc@example.com", "password": "12345678"}`, ) checkStatusCode(t, statusCode, responseBody, http.StatusUnauthorized) @@ -652,7 +652,7 @@ func TestIntegrationVerifyAccount(t *testing.T) { s.getAuthToken, paths.PathAuthToken, &authToken, - `{"deviceId": "dev-1", "email": "abc@example.com", "password": "123"}`, + `{"deviceId": "dev-1", "email": "abc@example.com", "password": "12345678"}`, ) checkStatusCode(t, statusCode, responseBody) diff --git a/server/password.go b/server/password.go index ed45e72..ba745fe 100644 --- a/server/password.go +++ b/server/password.go @@ -28,11 +28,11 @@ func (r *ChangePasswordRequest) validate() error { if !r.Email.Validate() { return fmt.Errorf("Invalid or missing 'email'") } - if r.OldPassword == "" { - return fmt.Errorf("Missing 'oldPassword'") + if !r.OldPassword.Validate() { + return fmt.Errorf("Invalid or missing 'oldPassword'") } - if r.NewPassword == "" { - return fmt.Errorf("Missing 'newPassword'") + if !r.NewPassword.Validate() { + return fmt.Errorf("Invalid or missing 'newPassword'") } // Too bad we can't do this so easily with clientSaltSeed if r.OldPassword == r.NewPassword { diff --git a/server/password_test.go b/server/password_test.go index 7dabd68..f2e88fc 100644 --- a/server/password_test.go +++ b/server/password_test.go @@ -260,8 +260,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", } if changePasswordRequest.validate() != nil { @@ -270,8 +270,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { changePasswordRequest = ChangePasswordRequest{ Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", } if changePasswordRequest.validate() != nil { @@ -289,8 +289,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc-example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "email", @@ -304,8 +304,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "Abc ", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "email", @@ -315,8 +315,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { EncryptedWallet: "my-encrypted-wallet", Hmac: "my-hmac", Sequence: 2, - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "email", @@ -327,7 +327,7 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - NewPassword: "456", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "oldPassword", @@ -338,7 +338,7 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", + OldPassword: "12345678", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "newPassword", @@ -349,8 +349,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", }, "clientSaltSeed", "Expected ChangePasswordRequest with missing clientSaltSeed to return an appropriate error", @@ -360,8 +360,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234", }, "clientSaltSeed", @@ -372,8 +372,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234xxxx1234", }, "clientSaltSeed", @@ -383,8 +383,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "'encryptedWallet', 'sequence', and 'hmac'", // More likely to fail when we change the error message but whatever @@ -394,8 +394,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { EncryptedWallet: "my-encrypted-wallet", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "'encryptedWallet', 'sequence', and 'hmac'", // More likely to fail when we change the error message but whatever @@ -406,8 +406,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 0, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "456", + OldPassword: "12345678", + NewPassword: "45678901", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "'encryptedWallet', 'sequence', and 'hmac'", // More likely to fail when we change the error message but whatever @@ -418,8 +418,8 @@ func TestServerValidateChangePasswordRequest(t *testing.T) { Hmac: "my-hmac", Sequence: 2, Email: "abc@example.com", - OldPassword: "123", - NewPassword: "123", + OldPassword: "12345678", + NewPassword: "12345678", ClientSaltSeed: "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234", }, "should not be the same",