Change password endpoint implemented and tested
This commit is contained in:
parent
bce47979f6
commit
125e461d95
5 changed files with 502 additions and 13 deletions
84
server/password.go
Normal file
84
server/password.go
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"orblivion/lbry-id/auth"
|
||||||
|
"orblivion/lbry-id/store"
|
||||||
|
"orblivion/lbry-id/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ChangePasswordRequest struct {
|
||||||
|
EncryptedWallet wallet.EncryptedWallet `json:"encryptedWallet"`
|
||||||
|
Sequence wallet.Sequence `json:"sequence"`
|
||||||
|
Hmac wallet.WalletHmac `json:"hmac"`
|
||||||
|
Email auth.Email `json:"email"`
|
||||||
|
OldPassword auth.Password `json:"oldPassword"`
|
||||||
|
NewPassword auth.Password `json:"newPassword"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ChangePasswordRequest) validate() bool {
|
||||||
|
// The wallet should be here or not. Not partially here.
|
||||||
|
walletPresent := (r.EncryptedWallet != "" && r.Hmac != "" && r.Sequence > 0)
|
||||||
|
walletAbsent := (r.EncryptedWallet == "" && r.Hmac == "" && r.Sequence == 0)
|
||||||
|
|
||||||
|
return (validateEmail(r.Email) &&
|
||||||
|
r.OldPassword != "" &&
|
||||||
|
r.NewPassword != "" &&
|
||||||
|
r.OldPassword != r.NewPassword &&
|
||||||
|
(walletPresent || walletAbsent))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) changePassword(w http.ResponseWriter, req *http.Request) {
|
||||||
|
var changePasswordRequest ChangePasswordRequest
|
||||||
|
if !getPostData(w, req, &changePasswordRequest) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if changePasswordRequest.EncryptedWallet != "" {
|
||||||
|
err = s.store.ChangePasswordWithWallet(
|
||||||
|
changePasswordRequest.Email,
|
||||||
|
changePasswordRequest.OldPassword,
|
||||||
|
changePasswordRequest.NewPassword,
|
||||||
|
changePasswordRequest.EncryptedWallet,
|
||||||
|
changePasswordRequest.Sequence,
|
||||||
|
changePasswordRequest.Hmac)
|
||||||
|
if err == store.ErrWrongSequence {
|
||||||
|
errorJson(w, http.StatusConflict, "Bad sequence number or wallet does not exist")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = s.store.ChangePasswordNoWallet(
|
||||||
|
changePasswordRequest.Email,
|
||||||
|
changePasswordRequest.OldPassword,
|
||||||
|
changePasswordRequest.NewPassword,
|
||||||
|
)
|
||||||
|
if err == store.ErrUnexpectedWallet {
|
||||||
|
errorJson(w, http.StatusConflict, "Wallet exists; need an updated wallet when changing password")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == store.ErrWrongCredentials {
|
||||||
|
errorJson(w, http.StatusUnauthorized, "No match for email and password")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
internalServiceErrorJson(w, err, "Error changing password")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var changePasswordResponse struct{} // no data to respond with, but keep it JSON
|
||||||
|
var response []byte
|
||||||
|
response, err = json.Marshal(changePasswordResponse)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
internalServiceErrorJson(w, err, "Error generating change password response")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintf(w, string(response))
|
||||||
|
}
|
350
server/password_test.go
Normal file
350
server/password_test.go
Normal file
|
@ -0,0 +1,350 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"orblivion/lbry-id/auth"
|
||||||
|
"orblivion/lbry-id/store"
|
||||||
|
"orblivion/lbry-id/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestServerChangePassword(t *testing.T) {
|
||||||
|
tt := []struct {
|
||||||
|
name string
|
||||||
|
|
||||||
|
expectedStatusCode int
|
||||||
|
expectedErrorString string
|
||||||
|
|
||||||
|
// Whether we expect the call to ChangePassword*Wallet to happen
|
||||||
|
expectChangePasswordCall bool
|
||||||
|
|
||||||
|
// `new...` refers to what is being passed into the via POST request (and
|
||||||
|
// what we expect to get passed into SetWallet for the *non-error* cases
|
||||||
|
// below)
|
||||||
|
newEncryptedWallet wallet.EncryptedWallet
|
||||||
|
newSequence wallet.Sequence
|
||||||
|
newHmac wallet.WalletHmac
|
||||||
|
|
||||||
|
email auth.Email
|
||||||
|
|
||||||
|
storeErrors TestStoreFunctionsErrors
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "success with wallet",
|
||||||
|
|
||||||
|
expectedStatusCode: http.StatusOK,
|
||||||
|
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
newEncryptedWallet: "my-enc-wallet",
|
||||||
|
newSequence: 2,
|
||||||
|
newHmac: "my-hmac",
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
}, {
|
||||||
|
name: "success no wallet",
|
||||||
|
|
||||||
|
expectedStatusCode: http.StatusOK,
|
||||||
|
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
}, {
|
||||||
|
name: "conflict with wallet",
|
||||||
|
expectedStatusCode: http.StatusConflict,
|
||||||
|
expectedErrorString: http.StatusText(http.StatusConflict) + ": Bad sequence number or wallet does not exist",
|
||||||
|
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
newEncryptedWallet: "my-enc-wallet",
|
||||||
|
newSequence: 2,
|
||||||
|
newHmac: "my-hmac",
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
|
||||||
|
storeErrors: TestStoreFunctionsErrors{ChangePasswordWithWallet: store.ErrWrongSequence},
|
||||||
|
}, {
|
||||||
|
name: "conflict no wallet",
|
||||||
|
expectedStatusCode: http.StatusConflict,
|
||||||
|
expectedErrorString: http.StatusText(http.StatusConflict) + ": Wallet exists; need an updated wallet when changing password",
|
||||||
|
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
|
||||||
|
storeErrors: TestStoreFunctionsErrors{ChangePasswordNoWallet: store.ErrUnexpectedWallet},
|
||||||
|
}, {
|
||||||
|
name: "incorrect email with wallet",
|
||||||
|
expectedStatusCode: http.StatusUnauthorized,
|
||||||
|
expectedErrorString: http.StatusText(http.StatusUnauthorized) + ": No match for email and password",
|
||||||
|
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
newEncryptedWallet: "my-enc-wallet",
|
||||||
|
newSequence: 2,
|
||||||
|
newHmac: "my-hmac",
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
|
||||||
|
storeErrors: TestStoreFunctionsErrors{ChangePasswordWithWallet: store.ErrWrongCredentials},
|
||||||
|
}, {
|
||||||
|
name: "incorrect email no wallet",
|
||||||
|
expectedStatusCode: http.StatusUnauthorized,
|
||||||
|
expectedErrorString: http.StatusText(http.StatusUnauthorized) + ": No match for email and password",
|
||||||
|
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
|
||||||
|
storeErrors: TestStoreFunctionsErrors{ChangePasswordNoWallet: store.ErrWrongCredentials},
|
||||||
|
}, {
|
||||||
|
name: "validation error",
|
||||||
|
expectedStatusCode: http.StatusBadRequest,
|
||||||
|
expectedErrorString: http.StatusText(http.StatusBadRequest) + ": Request failed validation",
|
||||||
|
|
||||||
|
// Just check one validation error (missing email address) to make sure
|
||||||
|
// the validate function is called. We'll check the rest of the
|
||||||
|
// validation errors in the other test below.
|
||||||
|
|
||||||
|
expectChangePasswordCall: false,
|
||||||
|
}, {
|
||||||
|
name: "db error changing password with wallet",
|
||||||
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
|
expectedErrorString: http.StatusText(http.StatusInternalServerError),
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
// Putting in valid data here so it's clear that this isn't what causes
|
||||||
|
// the error
|
||||||
|
newEncryptedWallet: "my-encrypted-wallet",
|
||||||
|
newSequence: 2,
|
||||||
|
newHmac: "my-hmac",
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
|
||||||
|
// What causes the error
|
||||||
|
storeErrors: TestStoreFunctionsErrors{ChangePasswordWithWallet: fmt.Errorf("Some random db problem")},
|
||||||
|
}, {
|
||||||
|
name: "db error changing password no wallet",
|
||||||
|
expectedStatusCode: http.StatusInternalServerError,
|
||||||
|
expectedErrorString: http.StatusText(http.StatusInternalServerError),
|
||||||
|
expectChangePasswordCall: true,
|
||||||
|
|
||||||
|
email: "abc@example.com",
|
||||||
|
|
||||||
|
// What causes the error
|
||||||
|
storeErrors: TestStoreFunctionsErrors{ChangePasswordNoWallet: fmt.Errorf("Some random db problem")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
testAuth := TestAuth{}
|
||||||
|
testStore := TestStore{Errors: tc.storeErrors}
|
||||||
|
s := Server{&testAuth, &testStore}
|
||||||
|
|
||||||
|
// Whether we passed in wallet fields (these test cases should be passing
|
||||||
|
// in all of them or none of them, so we only test EncryptedWallet). This
|
||||||
|
// determines whether we expect a call to ChangePasswordWithWallet (as
|
||||||
|
// opposed to ChangePasswordNoWallet).
|
||||||
|
withWallet := (tc.newEncryptedWallet != "")
|
||||||
|
|
||||||
|
const oldPassword = "old password"
|
||||||
|
const newPassword = "new password"
|
||||||
|
|
||||||
|
requestBody := []byte(
|
||||||
|
fmt.Sprintf(`{
|
||||||
|
"encryptedWallet": "%s",
|
||||||
|
"sequence": %d,
|
||||||
|
"hmac": "%s",
|
||||||
|
"email": "%s",
|
||||||
|
"oldPassword": "%s",
|
||||||
|
"newPassword": "%s"
|
||||||
|
}`, tc.newEncryptedWallet, tc.newSequence, tc.newHmac, tc.email, oldPassword, newPassword),
|
||||||
|
)
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodPost, PathPassword, bytes.NewBuffer(requestBody))
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
s.changePassword(w, req)
|
||||||
|
|
||||||
|
body, _ := ioutil.ReadAll(w.Body)
|
||||||
|
|
||||||
|
expectStatusCode(t, w, tc.expectedStatusCode)
|
||||||
|
expectErrorString(t, body, tc.expectedErrorString)
|
||||||
|
|
||||||
|
if tc.expectedErrorString == "" && string(body) != "{}" {
|
||||||
|
t.Errorf("Expected change password response to be \"{}\": result: %+v", string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
if tc.expectChangePasswordCall {
|
||||||
|
if withWallet {
|
||||||
|
// Called ChangePasswordWithWallet with the expected parameters
|
||||||
|
if want, got := (ChangePasswordWithWalletCall{
|
||||||
|
EncryptedWallet: tc.newEncryptedWallet,
|
||||||
|
Sequence: tc.newSequence,
|
||||||
|
Hmac: tc.newHmac,
|
||||||
|
Email: tc.email,
|
||||||
|
OldPassword: oldPassword,
|
||||||
|
NewPassword: newPassword,
|
||||||
|
}), testStore.Called.ChangePasswordWithWallet; want != got {
|
||||||
|
t.Errorf("Store.ChangePasswordWithWallet called with: expected %+v, got %+v", want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did *not* call ChangePasswordNoWallet
|
||||||
|
if want, got := (ChangePasswordNoWalletCall{}), testStore.Called.ChangePasswordNoWallet; want != got {
|
||||||
|
t.Errorf("Store.ChangePasswordNoWallet unexpectly called with: %+v", got)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Called ChangePasswordNoWallet with the expected parameters
|
||||||
|
if want, got := (ChangePasswordNoWalletCall{
|
||||||
|
Email: tc.email,
|
||||||
|
OldPassword: oldPassword,
|
||||||
|
NewPassword: newPassword,
|
||||||
|
}), testStore.Called.ChangePasswordNoWallet; want != got {
|
||||||
|
t.Errorf("Store.ChangePasswordNoWallet called with: expected %+v, got %+v", want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did *not* call ChangePasswordWithWallet
|
||||||
|
if want, got := (ChangePasswordWithWalletCall{}), testStore.Called.ChangePasswordWithWallet; want != got {
|
||||||
|
t.Errorf("Store.ChangePasswordWithWallet unexpectly called with: %+v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if want, got := (ChangePasswordWithWalletCall{}), testStore.Called.ChangePasswordWithWallet; want != got {
|
||||||
|
t.Errorf("Store.ChangePasswordWithWallet unexpectly called with: %+v", got)
|
||||||
|
}
|
||||||
|
if want, got := (ChangePasswordNoWalletCall{}), testStore.Called.ChangePasswordNoWallet; want != got {
|
||||||
|
t.Errorf("Store.ChangePasswordNoWallet unexpectly called with: %+v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerValidateChangePasswordRequest(t *testing.T) {
|
||||||
|
changePasswordRequest := ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "abc@example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
}
|
||||||
|
if !changePasswordRequest.validate() {
|
||||||
|
t.Errorf("Expected valid ChangePasswordRequest with wallet fields to successfully validate")
|
||||||
|
}
|
||||||
|
|
||||||
|
changePasswordRequest = ChangePasswordRequest{
|
||||||
|
Email: "abc@example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
}
|
||||||
|
if !changePasswordRequest.validate() {
|
||||||
|
t.Errorf("Expected valid ChangePasswordRequest without wallet fields to successfully validate")
|
||||||
|
}
|
||||||
|
|
||||||
|
tt := []struct {
|
||||||
|
changePasswordRequest ChangePasswordRequest
|
||||||
|
failureDescription string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "abc-example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with invalid email to not successfully validate",
|
||||||
|
}, {
|
||||||
|
// Note that Golang's email address parser, which I use, will accept
|
||||||
|
// "Abc <abc@example.com>" so we need to make sure to avoid accepting it. See
|
||||||
|
// the implementation.
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "Abc <abc@example.com>",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with email with unexpected formatting to not successfully validate",
|
||||||
|
}, {
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with missing email to not successfully validate",
|
||||||
|
}, {
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "abc@example.com",
|
||||||
|
NewPassword: "456",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with missing old password to not successfully validate",
|
||||||
|
}, {
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "abc@example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with missing new password to not successfully validate",
|
||||||
|
}, {
|
||||||
|
ChangePasswordRequest{
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "abc@example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with missing encrypted wallet (but with other wallet fields present) to not successfully validate",
|
||||||
|
}, {
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "abc@example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with missing hmac (but with other wallet fields present) to not successfully validate",
|
||||||
|
}, {
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 0,
|
||||||
|
Email: "abc@example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "456",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with sequence < 1 (but with other wallet fields present) to not successfully validate",
|
||||||
|
}, {
|
||||||
|
ChangePasswordRequest{
|
||||||
|
EncryptedWallet: "my-encrypted-wallet",
|
||||||
|
Hmac: "my-hmac",
|
||||||
|
Sequence: 2,
|
||||||
|
Email: "abc@example.com",
|
||||||
|
OldPassword: "123",
|
||||||
|
NewPassword: "123",
|
||||||
|
},
|
||||||
|
"Expected WalletRequest with password that does not change to not successfully validate",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tt {
|
||||||
|
if tc.changePasswordRequest.validate() {
|
||||||
|
t.Errorf(tc.failureDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ const PathPrefix = "/api/" + ApiVersion
|
||||||
|
|
||||||
const PathAuthToken = PathPrefix + "/auth/full"
|
const PathAuthToken = PathPrefix + "/auth/full"
|
||||||
const PathRegister = PathPrefix + "/signup"
|
const PathRegister = PathPrefix + "/signup"
|
||||||
|
const PathPassword = PathPrefix + "/password"
|
||||||
const PathWallet = PathPrefix + "/wallet"
|
const PathWallet = PathPrefix + "/wallet"
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
|
@ -178,6 +179,7 @@ func (s *Server) Serve() {
|
||||||
http.HandleFunc(PathAuthToken, s.getAuthToken)
|
http.HandleFunc(PathAuthToken, s.getAuthToken)
|
||||||
http.HandleFunc(PathWallet, s.handleWallet)
|
http.HandleFunc(PathWallet, s.handleWallet)
|
||||||
http.HandleFunc(PathRegister, s.register)
|
http.HandleFunc(PathRegister, s.register)
|
||||||
|
http.HandleFunc(PathPassword, s.changePassword)
|
||||||
|
|
||||||
fmt.Println("Serving at localhost:8090")
|
fmt.Println("Serving at localhost:8090")
|
||||||
http.ListenAndServe("localhost:8090", nil)
|
http.ListenAndServe("localhost:8090", nil)
|
||||||
|
|
|
@ -35,23 +35,42 @@ type SetWalletCall struct {
|
||||||
Hmac wallet.WalletHmac
|
Hmac wallet.WalletHmac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ChangePasswordNoWalletCall struct {
|
||||||
|
Email auth.Email
|
||||||
|
OldPassword auth.Password
|
||||||
|
NewPassword auth.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChangePasswordWithWalletCall struct {
|
||||||
|
EncryptedWallet wallet.EncryptedWallet
|
||||||
|
Sequence wallet.Sequence
|
||||||
|
Hmac wallet.WalletHmac
|
||||||
|
Email auth.Email
|
||||||
|
OldPassword auth.Password
|
||||||
|
NewPassword auth.Password
|
||||||
|
}
|
||||||
|
|
||||||
// Whether functions are called, and sometimes what they're called with
|
// Whether functions are called, and sometimes what they're called with
|
||||||
type TestStoreFunctionsCalled struct {
|
type TestStoreFunctionsCalled struct {
|
||||||
SaveToken auth.TokenString
|
SaveToken auth.TokenString
|
||||||
GetToken auth.TokenString
|
GetToken auth.TokenString
|
||||||
GetUserId bool
|
GetUserId bool
|
||||||
CreateAccount bool
|
CreateAccount bool
|
||||||
SetWallet SetWalletCall
|
SetWallet SetWalletCall
|
||||||
GetWallet bool
|
GetWallet bool
|
||||||
|
ChangePasswordWithWallet ChangePasswordWithWalletCall
|
||||||
|
ChangePasswordNoWallet ChangePasswordNoWalletCall
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestStoreFunctionsErrors struct {
|
type TestStoreFunctionsErrors struct {
|
||||||
SaveToken error
|
SaveToken error
|
||||||
GetToken error
|
GetToken error
|
||||||
GetUserId error
|
GetUserId error
|
||||||
CreateAccount error
|
CreateAccount error
|
||||||
SetWallet error
|
SetWallet error
|
||||||
GetWallet error
|
GetWallet error
|
||||||
|
ChangePasswordWithWallet error
|
||||||
|
ChangePasswordNoWallet error
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestStore struct {
|
type TestStore struct {
|
||||||
|
@ -110,6 +129,38 @@ func (s *TestStore) GetWallet(userId auth.UserId) (encryptedWallet wallet.Encryp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *TestStore) ChangePasswordWithWallet(
|
||||||
|
email auth.Email,
|
||||||
|
oldPassword auth.Password,
|
||||||
|
newPassword auth.Password,
|
||||||
|
encryptedWallet wallet.EncryptedWallet,
|
||||||
|
sequence wallet.Sequence,
|
||||||
|
hmac wallet.WalletHmac,
|
||||||
|
) (err error) {
|
||||||
|
s.Called.ChangePasswordWithWallet = ChangePasswordWithWalletCall{
|
||||||
|
EncryptedWallet: encryptedWallet,
|
||||||
|
Sequence: sequence,
|
||||||
|
Hmac: hmac,
|
||||||
|
Email: email,
|
||||||
|
OldPassword: oldPassword,
|
||||||
|
NewPassword: newPassword,
|
||||||
|
}
|
||||||
|
return s.Errors.ChangePasswordWithWallet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *TestStore) ChangePasswordNoWallet(
|
||||||
|
email auth.Email,
|
||||||
|
oldPassword auth.Password,
|
||||||
|
newPassword auth.Password,
|
||||||
|
) (err error) {
|
||||||
|
s.Called.ChangePasswordNoWallet = ChangePasswordNoWalletCall{
|
||||||
|
Email: email,
|
||||||
|
OldPassword: oldPassword,
|
||||||
|
NewPassword: newPassword,
|
||||||
|
}
|
||||||
|
return s.Errors.ChangePasswordNoWallet
|
||||||
|
}
|
||||||
|
|
||||||
// expectStatusCode: A helper to call in functions that test that request
|
// expectStatusCode: A helper to call in functions that test that request
|
||||||
// handlers responded with a certain status code. Cuts down on noise.
|
// handlers responded with a certain status code. Cuts down on noise.
|
||||||
func expectStatusCode(t *testing.T, w *httptest.ResponseRecorder, expectedStatusCode int) {
|
func expectStatusCode(t *testing.T, w *httptest.ResponseRecorder, expectedStatusCode int) {
|
||||||
|
|
|
@ -42,7 +42,9 @@ type StoreInterface interface {
|
||||||
SetWallet(auth.UserId, wallet.EncryptedWallet, wallet.Sequence, wallet.WalletHmac) error
|
SetWallet(auth.UserId, wallet.EncryptedWallet, wallet.Sequence, wallet.WalletHmac) error
|
||||||
GetWallet(auth.UserId) (wallet.EncryptedWallet, wallet.Sequence, wallet.WalletHmac, error)
|
GetWallet(auth.UserId) (wallet.EncryptedWallet, wallet.Sequence, wallet.WalletHmac, error)
|
||||||
GetUserId(auth.Email, auth.Password) (auth.UserId, error)
|
GetUserId(auth.Email, auth.Password) (auth.UserId, error)
|
||||||
CreateAccount(auth.Email, auth.Password) (err error)
|
CreateAccount(auth.Email, auth.Password) error
|
||||||
|
ChangePasswordWithWallet(auth.Email, auth.Password, auth.Password, wallet.EncryptedWallet, wallet.Sequence, wallet.WalletHmac) error
|
||||||
|
ChangePasswordNoWallet(auth.Email, auth.Password, auth.Password) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Store struct {
|
type Store struct {
|
||||||
|
|
Loading…
Reference in a new issue