From b71ca59576b41b76e5be3e910581cadb89e7c581 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 14 May 2019 09:02:54 +0200 Subject: [PATCH 1/3] Fix update pass response code (204) --- lib/core/src/Cardano/Wallet/Api.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/core/src/Cardano/Wallet/Api.hs b/lib/core/src/Cardano/Wallet/Api.hs index c14f9fc6fd2..40ea73c9e28 100644 --- a/lib/core/src/Cardano/Wallet/Api.hs +++ b/lib/core/src/Cardano/Wallet/Api.hs @@ -30,6 +30,7 @@ import Servant.API , NoContent , PostAccepted , Put + , PutNoContent , QueryParam , ReqBody ) @@ -96,7 +97,7 @@ type PutWalletPassphrase = "wallets" :> Capture "walletId" (ApiT WalletId) :> "passphrase" :> ReqBody '[JSON] WalletPutPassphraseData - :> Put '[Any] NoContent + :> PutNoContent '[Any] NoContent {------------------------------------------------------------------------------- Transactions From 313ae755219046bea9a967e7926ea7708057770c Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 14 May 2019 13:38:44 +0200 Subject: [PATCH 2/3] WALLETS_UPDATE_PASS integration tests --- .../Test/Integration/Scenario/Wallets.hs | 254 +++++++++++++++++- 1 file changed, 253 insertions(+), 1 deletion(-) diff --git a/lib/http-bridge/test/integration/Test/Integration/Scenario/Wallets.hs b/lib/http-bridge/test/integration/Test/Integration/Scenario/Wallets.hs index 1549deed2de..86717dd82b6 100644 --- a/lib/http-bridge/test/integration/Test/Integration/Scenario/Wallets.hs +++ b/lib/http-bridge/test/integration/Test/Integration/Scenario/Wallets.hs @@ -687,7 +687,7 @@ spec = do expectResponseCode @IO HTTP.status400 r describe "WALLETS_CREATE_09, WALLETS_LIST_03 - v2/wallets - Methods Not Allowed" $ do - let matrix = ["PUT", "DELETE"] + let matrix = ["PUT", "DELETE", "CONNECT", "TRACE", "OPTIONS"] forM_ matrix $ \method -> it (show method) $ \ctx -> do r <- request @ApiWallet ctx (method, "v2/wallets") Default Empty expectResponseCode @IO HTTP.status405 r @@ -1020,6 +1020,252 @@ spec = do ru <- request @ApiWallet ctx ("PUT", endpoint) headers newName verify ru expectations + it "WALLETS_UPDATE_PASS_01 - passphaseLastUpdate gets updated" $ \ctx -> do + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default simplePayload + let payload = updatePassPayload "Secure passphrase" "New passphrase" + let endpoint = "v2/wallets" (getFromResponse walletId r) + ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) Default payload + expectResponseCode @IO HTTP.status204 rup + + let getEndpoint = "v2/wallets" (getFromResponse walletId r) + let originalPassUpdateDateTime = getFromResponse passphraseLastUpdate r + rg <- request @ApiWallet ctx ("GET", getEndpoint) Default Empty + expectFieldNotEqual passphraseLastUpdate originalPassUpdateDateTime rg + + describe "WALLETS_UPDATE_PASS_02 - New passphrase values" $ do + let passphraseMax = T.pack (replicate passphraseMaxLength 'ą') + let matrix = + [ ( show passphraseMinLength ++ " char long" + , T.pack (replicate passphraseMinLength 'ź') + , [ expectResponseCode @IO HTTP.status204 + ] + ) + , ( show (passphraseMinLength - 1) ++ " char long" + , T.pack (replicate (passphraseMinLength - 1) 'ż') + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "passphrase is too short: expected at\ + \ least 10 characters" + ] + ) + , ( show passphraseMaxLength ++ " char long", passphraseMax + , [ expectResponseCode @IO HTTP.status204 ] + ) + , ( show (passphraseMaxLength + 1) ++ " char long" + , T.pack (replicate (passphraseMaxLength + 1) 'ę') + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "passphrase is too long: expected at\ + \ most 255 characters" + ] + ) + , ( "Empty passphrase", "" + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "passphrase is too short: expected at\ + \ least 10 characters" + ] + ) + , ( "Russian passphrase", russianWalletName + , [ expectResponseCode @IO HTTP.status204 ] + ) + , ( "Polish passphrase", polishWalletName + , [ expectResponseCode @IO HTTP.status204 ] + ) + , ( "Kanji passphrase", kanjiWalletName + , [ expectResponseCode @IO HTTP.status204 ] + ) + , ( "Arabic passphrase", arabicWalletName + , [ expectResponseCode @IO HTTP.status204 ] + ) + , ( "Wildcards passphrase", wildcardsWalletName + , [ expectResponseCode @IO HTTP.status204 ] + ) + ] + forM_ matrix $ \(title, passphrase, expectations) -> it title $ \ctx -> do + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default simplePayload + let payload = updatePassPayload "Secure passphrase" passphrase + let endpoint = "v2/wallets" (getFromResponse walletId r) + ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) Default payload + verify rup expectations + + describe "WALLETS_UPDATE_PASS_03 - Old passphrase invalid values" $ do + let matrix = + [ ( show (passphraseMinLength - 1) ++ " char long" + , T.pack (replicate (passphraseMinLength - 1) 'ż') + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "passphrase is too short: expected at\ + \ least 10 characters" ] + ) + , ( show (passphraseMaxLength + 1) ++ " char long" + , T.pack (replicate (passphraseMaxLength + 1) 'ę') + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "passphrase is too long: expected at\ + \ most 255 characters" ] + ) + , ( "Empty passphrase", "" + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "passphrase is too short: expected at\ + \ least 10 characters" ] + ) + , ( "Incorrect old pass", "Incorrect passphrase" + , [ expectResponseCode @IO HTTP.status403 ] + ) + ] + forM_ matrix $ \(title, passphrase, expectations) -> it title $ \ctx -> do + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default simplePayload + let payload = updatePassPayload passphrase "Secure passphrase 2" + let endpoint = "v2/wallets" (getFromResponse walletId r) + ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) Default payload + verify rup expectations + + describe "WALLETS_UPDATE_PASS_03 - Can update pass from pass that's boundary\ + \ value" $ do + let matrix = + [ ( show passphraseMinLength ++ " char long" + , T.pack (replicate passphraseMinLength 'ź') ) + , ( show passphraseMaxLength ++ " char long" + , T.pack (replicate passphraseMaxLength 'ą') ) + , ( "Russian passphrase", russianWalletName ) + , ( "Polish passphrase", polishWalletName ) + , ( "Kanji passphrase", kanjiWalletName ) + , ( "Arabic passphrase", arabicWalletName ) + , ( "Wildcards passphrase", wildcardsWalletName ) + ] + forM_ matrix $ \(title, oldPass) -> it title $ \ctx -> do + let createPayload = Json [json| { + "name": "Name of the wallet", + "mnemonic_sentence": #{mnemonics24}, + "passphrase": #{oldPass} + } |] + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default createPayload + let payload = updatePassPayload oldPass + (T.pack (replicate passphraseMaxLength '💘')) + let endpoint = "v2/wallets" (getFromResponse walletId r) + ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) Default payload + expectResponseCode @IO HTTP.status204 rup + + describe "WALLETS_UPDATE_PASS_02,03 - invalid payloads" $ do + let matrix = + [ ( "[] as new passphrase" + , Json [json| { + "old_passphrase": "Secure passphrase", + "new_passphrase": [] + } |] + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "expected Text, encountered Array" ] + ) + , ( "[] as old passphrase" + , Json [json| { + "old_passphrase": [], + "new_passphrase": "Secure passphrase" + } |] + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "expected Text, encountered Array" ] + ) + , ( "Num as old passphrase" + , Json [json| { + "old_passphrase": 12345678910, + "new_passphrase": "Secure passphrase" + } |] + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "expected Text, encountered Number" ] + ) + , ( "Num as new passphrase" + , Json [json| { + "old_passphrase": "Secure passphrase", + "new_passphrase": 12345678910 + } |] + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "expected Text, encountered Number" ] + ) + , ( "Missing old passphrase" + , Json [json| { + "new_passphrase": "Secure passphrase" + } |] + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "key \"old_passphrase\" not present" ] + ) + , ( "Missing new passphrase" + , Json [json| { + "old_passphrase": "Secure passphrase" + } |] + , [ expectResponseCode @IO HTTP.status400 + , expectErrorMessage "key \"new_passphrase\" not present" ] + ) + ] + forM_ matrix $ \(title, payload, expectations) -> it title $ \ctx -> do + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default simplePayload + let endpoint = "v2/wallets" (getFromResponse walletId r) + ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) Default payload + verify rup expectations + + it "WALLETS_UPDATE_PASS_04 - Deleted wallet is not available" $ \ctx -> do + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default simplePayload + let payload = updatePassPayload "Secure passphrase" "Secure passphrase2" + let delEndp = "v2/wallets" (getFromResponse walletId r) + _ <- request @ApiWallet ctx ("DELETE", delEndp) Default Empty + + let updEndp = delEndp ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", updEndp) Default payload + expectResponseCode @IO HTTP.status403 rup + + describe "WALLETS_UPDATE_PASS_04 - non-existing wallets" $ do + forM_ falseWalletIds $ \(title, walId) -> it title $ \ctx -> do + let payload = updatePassPayload "Secure passphrase" "Secure passphrase2" + let endpoint = "v2/wallets" T.pack walId ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) Default payload + if (title == "40 chars hex") then + expectResponseCode @IO HTTP.status403 rup + else + expectResponseCode @IO HTTP.status404 rup + + it "WALLETS_UPDATE_PASS_04 - 'almost' valid walletId" $ \ctx -> do + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default simplePayload + let payload = updatePassPayload "Secure passphrase" "Secure passphrase2" + let endpoint = + "v2/wallets" + (T.append (getFromResponse walletId r) "0") + ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) Default payload + expectResponseCode @IO HTTP.status404 rup + + describe "WALLETS_UPDATE_PASS_07 - HTTP headers" $ do + let matrix = + [ ( "No HTTP headers -> 415", None + , [expectResponseCode @IO HTTP.status415] ) + , ( "Accept: text/plain -> 406" + , Headers + [ ("Content-Type", "application/json") + , ("Accept", "text/plain") ] + , [expectResponseCode @IO HTTP.status406] + ) + , ( "No Accept -> 204" + , Headers [ ("Content-Type", "application/json") ] + , [expectResponseCode @IO HTTP.status204] + ) + , ( "No Content-Type -> 415" + , Headers [ ("Accept", "application/json") ] + , [expectResponseCode @IO HTTP.status415] + ) + , ( "Content-Type: text/plain -> 415" + , Headers [ ("Content-Type", "text/plain") ] + , [expectResponseCode @IO HTTP.status415] + ) + ] + forM_ matrix $ \(title, headers, expectations) -> it title $ \ctx -> do + r <- request @ApiWallet ctx ("POST", "v2/wallets") Default simplePayload + let payload = + updatePassPayload "Secure passphrase" "Secure passphrase2" + let endpoint = + "v2/wallets" + (getFromResponse walletId r) + ("passphrase" :: Text) + rup <- request @ApiWallet ctx ("PUT", endpoint) headers payload + verify rup expectations + where falseWalletIds = [ ("40 chars hex", replicate 40 '1') @@ -1070,6 +1316,12 @@ spec = do "name": #{name} } |] + updatePassPayload :: Text -> Text -> Payload + updatePassPayload oldPass newPass = Json [json| { + "old_passphrase": #{oldPass}, + "new_passphrase": #{newPass} + } |] + mnemonics3 :: [Text] mnemonics3 = ["diamond", "flee", "window"] From 8ad499b602ad79a70f2b8f442516bdafa4c530e8 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Tue, 14 May 2019 13:45:03 +0200 Subject: [PATCH 3/3] Update API spec (remove 410 from endpoints: `PUT v2/wallets/{wallet-id}` and `PUT v2/wallets/{wallet-id}/passphrase`) --- specifications/api/swagger.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/specifications/api/swagger.yaml b/specifications/api/swagger.yaml index 2085e734646..7cd80ba4276 100644 --- a/specifications/api/swagger.yaml +++ b/specifications/api/swagger.yaml @@ -697,7 +697,6 @@ responsesPutWallet: &responsesPutWallet <<: *responsesErr400 <<: *responsesErr404 <<: *responsesErr406 - <<: *responsesErr410 <<: *responsesErr415 200: description: Ok @@ -708,7 +707,6 @@ responsesPutWalletPassphrase: &responsesPutWalletPassphrase <<: *responsesErr403 <<: *responsesErr404 <<: *responsesErr406 - <<: *responsesErr410 <<: *responsesErr415 204: description: No Content