packages feed

aws-sns-verify-0.0.0.2: tests/Amazon/SNS/Verify/ValidateSpec.hs

module Amazon.SNS.Verify.ValidateSpec
  ( spec
  ) where

import Amazon.SNS.Verify.TestPrelude

import Amazon.SNS.Verify.Payload
import Amazon.SNS.Verify.Validate
import Data.X509.Validation (SignatureFailure(..))

spec :: Spec
spec = around_ useCertServer $ do
  describe "validateSnsMessage" $ do
    it "successfully validates an SNS notification" $ do
      let message = "Some message"
      x <- validateSnsMessage $ SNSPayload
        { snsMessage = message
        , snsMessageId = "78d4d7a0-a3eb-5c4d-834f-8d5fa9813ab6"
        , snsTimestamp = "2022-05-18T14:52:26.952Z"
        , snsTopicArn = "arn:aws:sns:us-west-2:123456789012:MyTopic"
        , snsType = "Notification"
        , snsSignatureVersion = "1"
        , snsSignature =
          "Dg24trcOUiLjclt5JwyJS0JEOnEEbi6P30XS6KBxMCwzZ08a04UwjaFTW9Ae8xurhBS5YESz1fY28vTwvEmxh/20WmB3bWIDOMp9v5RI8XSZOvpMm+hdQJ43VqGhEDyAvRU6iCDLihDlZNc/sBCwl9X0H4kh/8vIElRif9gFBbYI94ZHGgqEV+Zc3gVKo9Udrl/MxNvMVadsO/+/oPVUeWibQr3xfGK95oc/ocuNAgi0MOxZmLVnibHu36KOTSvy2qSLonnRRFcbaauYZJ4js7oTq+1ujXNO72oPLaeG3pVJ2grqMc5z8tKQxFnSTE3es7wQarU/CLrbO8j0isbnWw=="
        , snsSigningCertURL = cert
        , snsTypePayload = Notification $ SNSNotification
          { snsSubject =
            Just
              "SynthesisTaskNotification { TaskId: 680a1f1b-f3ae-4474-aa8f-3b6dfe52e656, Status: COMPLETED }"
          }
        }
      x `shouldBe` Right (SNSMessage message)

    it "fails to validate a currupt SNS notification" $ do
      let
        go = validateSnsMessage $ SNSPayload
          { snsMessage = "Some message"
          , snsMessageId = "corrupt"
          , snsTimestamp = "2022-05-18T14:52:26.952Z"
          , snsTopicArn = "arn:aws:sns:us-west-2:123456789012:MyTopic"
          , snsType = "Notification"
          , snsSignatureVersion = "1"
          , snsSignature =
            "Dg24trcOUiLjclt5JwyJS0JEOnEEbi6P30XS6KBxMCwzZ08a04UwjaFTW9Ae8xurhBS5YESz1fY28vTwvEmxh/20WmB3bWIDOMp9v5RI8XSZOvpMm+hdQJ43VqGhEDyAvRU6iCDLihDlZNc/sBCwl9X0H4kh/8vIElRif9gFBbYI94ZHGgqEV+Zc3gVKo9Udrl/MxNvMVadsO/+/oPVUeWibQr3xfGK95oc/ocuNAgi0MOxZmLVnibHu36KOTSvy2qSLonnRRFcbaauYZJ4js7oTq+1ujXNO72oPLaeG3pVJ2grqMc5z8tKQxFnSTE3es7wQarU/CLrbO8j0isbnWw=="
          , snsSigningCertURL = cert
          , snsTypePayload = Notification $ SNSNotification
            { snsSubject =
              Just
                "SynthesisTaskNotification { TaskId: 680a1f1b-f3ae-4474-aa8f-3b6dfe52e656, Status: COMPLETED }"
            }
          }
      go `shouldReturn` Left (InvalidPayload SignatureInvalid)

    it "fails to validate a bad PEM" $ do
      let
        go = validateSnsMessage $ SNSPayload
          { snsMessage = "Some message"
          , snsMessageId = "corrupt"
          , snsTimestamp = "2022-05-18T14:52:26.952Z"
          , snsTopicArn = "arn:aws:sns:us-west-2:123456789012:MyTopic"
          , snsType = "Notification"
          , snsSignatureVersion = "1"
          , snsSignature =
            "Dg24trcOUiLjclt5JwyJS0JEOnEEbi6P30XS6KBxMCwzZ08a04UwjaFTW9Ae8xurhBS5YESz1fY28vTwvEmxh/20WmB3bWIDOMp9v5RI8XSZOvpMm+hdQJ43VqGhEDyAvRU6iCDLihDlZNc/sBCwl9X0H4kh/8vIElRif9gFBbYI94ZHGgqEV+Zc3gVKo9Udrl/MxNvMVadsO/+/oPVUeWibQr3xfGK95oc/ocuNAgi0MOxZmLVnibHu36KOTSvy2qSLonnRRFcbaauYZJ4js7oTq+1ujXNO72oPLaeG3pVJ2grqMc5z8tKQxFnSTE3es7wQarU/CLrbO8j0isbnWw=="
          , snsSigningCertURL = "http://localhost:3000/404"
          , snsTypePayload = Notification $ SNSNotification
            { snsSubject =
              Just
                "SynthesisTaskNotification { TaskId: 680a1f1b-f3ae-4474-aa8f-3b6dfe52e656, Status: COMPLETED }"
            }
          }
      go `shouldReturn` Left (BadPem "Empty List")

    it "fails to validate an unexpected url" $ do
      let
        go = validateSnsMessage $ SNSPayload
          { snsMessage = "Some message"
          , snsMessageId = "corrupt"
          , snsTimestamp = "2022-05-18T14:52:26.952Z"
          , snsTopicArn = "arn:aws:sns:us-west-2:123456789012:MyTopic"
          , snsType = "Notification"
          , snsSignatureVersion = "1"
          , snsSignature =
            "Dg24trcOUiLjclt5JwyJS0JEOnEEbi6P30XS6KBxMCwzZ08a04UwjaFTW9Ae8xurhBS5YESz1fY28vTwvEmxh/20WmB3bWIDOMp9v5RI8XSZOvpMm+hdQJ43VqGhEDyAvRU6iCDLihDlZNc/sBCwl9X0H4kh/8vIElRif9gFBbYI94ZHGgqEV+Zc3gVKo9Udrl/MxNvMVadsO/+/oPVUeWibQr3xfGK95oc/ocuNAgi0MOxZmLVnibHu36KOTSvy2qSLonnRRFcbaauYZJ4js7oTq+1ujXNO72oPLaeG3pVJ2grqMc5z8tKQxFnSTE3es7wQarU/CLrbO8j0isbnWw=="
          , snsSigningCertURL = "http://attacker.com/evil.pem"
          , snsTypePayload = Notification $ SNSNotification
            { snsSubject =
              Just
                "SynthesisTaskNotification { TaskId: 680a1f1b-f3ae-4474-aa8f-3b6dfe52e656, Status: COMPLETED }"
            }
          }
      go `shouldReturn` Left (BadUri "http://attacker.com/evil.pem")

    it "successfully validates an SNS subscription" $ do
      -- pendingWith "need valid subscription payload"
      let
        message
          = "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message."
        subscription = SNSSubscription
          { snsToken = "2336412f37..."
          , snsSubscribeURL =
            "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37..."
          }
      x <- validateSnsMessage $ SNSPayload
        { snsMessage = message
        , snsMessageId = "165545c9-2a5c-472c-8df2-7ff2be2b3b1b"
        , snsTimestamp = "2012-04-26T20:45:04.751Z"
        , snsTopicArn = "arn:aws:sns:us-west-2:123456789012:MyTopic"
        , snsType = "SubscriptionConfirmation"
        , snsSignatureVersion = "1"
        , snsSignature =
          "Jec/VlsopbiA2fCckj/IwTPjDbSuFkl2hNKL898sQuZcMeKeOLthYs7YlF+xLi+Ip6rG/X08GZKtCqpoiSgKW8D9PI6eHVM2JQa76sFJO5ZdPylrDH+URwBf28gT+1l/VYk4p3VK8RZo+3Wkn87HXwxTq1YoN390o5ncT34zaBDtLx2cUA8+JOnYjItmYjVXDhrEBF6xad/vIY8V2o5xyQOfEWLm71/Tcs3radzNoSj2xlLQyJKPOzV661fG6Xz1vVKfDVC03+Q4Pn67SmU1wWRRT1nDwPPzQlcDAiAGRjB1U/C5iHfLQFF3dKo4azylkrM2ReTCMm9KMyIWqjq5eg=="
        , snsSigningCertURL = cert
        , snsTypePayload = SubscriptionConfirmation subscription
        }
      x `shouldBe` Right (SNSSubscribe subscription)

    it "successfully validates an SNS unsubscribe" $ do
      -- pendingWith "need valid subscription payload"
      let
        message
          = "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message."
        subscription = SNSSubscription
          { snsToken = "2336412f37..."
          , snsSubscribeURL =
            "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37..."
          }
      x <- validateSnsMessage $ SNSPayload
        { snsMessage = message
        , snsMessageId = "165545c9-2a5c-472c-8df2-7ff2be2b3b1b"
        , snsTimestamp = "2012-04-26T20:45:04.751Z"
        , snsTopicArn = "arn:aws:sns:us-west-2:123456789012:MyTopic"
        , snsType = "UnsubscribeConfirmation"
        , snsSignatureVersion = "1"
        , snsSignature =
          "fKtmZTE6xvGhbcCTchFPLmuhdoXI7hxWrE9qe1RjeLDecMaZGmqsn4rOrFDsteqot4ItLuJqvV7RtImGXrMa/JNnZdP71lG6FdrKTiGqZNrnxZZYbIuZMAsSQM4E8VaRwbxLXuPQY9IYFP4y9GfsdpDYx0tpbXOxGz/JFVQjTFpHY55BmV6Ec73g0X/eLSEdKfHtWg/gVf6W27ewa40jXvaa78VmcVXbPXIKwzGgSSSe9t6xxVe0kLjKXaDyJTl3rbZJZJgBLInbychWNq1vGHGZQhtCyxjKRfKIWNWDbHdM/fUBGUhuv089CblWpq8g/21HiJ9n+S3VSn0hCXB5hg=="
        , snsSigningCertURL = cert
        , snsTypePayload = UnsubscribeConfirmation subscription
        }
      x `shouldBe` Right (SNSUnsubscribe subscription)

cert :: Text
cert = "http://localhost:3000"