Skip to content

Commit

Permalink
fix gundeck aws endpoint parsing (#2921)
Browse files Browse the repository at this point in the history
Fix broken parser for "endpoint already exists" error message. 
It tried to consume the end twice. This could not work.
  • Loading branch information
supersven authored Dec 12, 2022
1 parent fbfa1a0 commit 1c85346
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 9 deletions.
1 change: 1 addition & 0 deletions changelog.d/3-bug-fixes/aws-error-message-parser-bug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The parser for the AWS/SNS error message to explain that an endpoint is already in use was incorrect. This lead to an "invalid token" error when registering push tokens for multiple user accounts (user ids) instead of updating the SNS endpoint with an additional user id.
1 change: 1 addition & 0 deletions services/gundeck/gundeck.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ test-suite gundeck-tests
Json
MockGundeck
Native
ParseExistsError
Paths_gundeck
Push
ThreadBudget
Expand Down
19 changes: 11 additions & 8 deletions services/gundeck/src/Gundeck/Aws.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ module Gundeck.Aws

-- * Feedback
listen,

-- * Exported for testing purposes
parseExistsError,
)
where

Expand Down Expand Up @@ -323,14 +326,6 @@ createEndpoint u tr arnEnv app token = do
where
readArn r = either (throwM . InvalidArn r) pure (fromText r)
tokenLength = toInteger . Text.length . Push.tokenText
-- Thank you Amazon for not having granular error codes!
parseExistsError Nothing = Nothing
parseExistsError (Just s) = hush . flip parseOnly (toText s) $ do
_ <- string "Invalid parameter: Token Reason: Endpoint "
let endParser = string " already exists with the same Token, but different attributes."
a <- manyTill anyChar endParser >>= either fail pure . AWS.fromText . Text.pack
_ <- endParser
pure a
isTokenError Nothing = False
isTokenError (Just s) = isRight . flip parseOnly (toText s) $ do
_ <- string "Invalid parameter: Token"
Expand All @@ -344,6 +339,14 @@ createEndpoint u tr arnEnv app token = do
<|> string "iOS device tokens must be no more than 400 hexadecimal characters"
pure ()

-- Thank you Amazon for not having granular error codes!
parseExistsError :: Maybe AWS.ErrorMessage -> Maybe EndpointArn
parseExistsError Nothing = Nothing
parseExistsError (Just s) = hush . flip parseOnly (toText s) $ do
_ <- string "Invalid parameter: Token Reason: Endpoint "
let endParser = string " already exists with the same Token, but different attributes."
manyTill anyChar endParser >>= either fail pure . AWS.fromText . Text.pack

--------------------------------------------------------------------------------
-- Publish

Expand Down
4 changes: 3 additions & 1 deletion services/gundeck/test/unit/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import qualified Json
import qualified Native
import Network.Wai.Utilities.Server (compile)
import OpenSSL (withOpenSSL)
import qualified ParseExistsError
import qualified Push
import Test.Tasty
import Test.Tasty.HUnit
Expand All @@ -48,5 +49,6 @@ main =
Json.tests,
Native.tests,
Push.tests,
ThreadBudget.tests
ThreadBudget.tests,
ParseExistsError.tests
]
39 changes: 39 additions & 0 deletions services/gundeck/test/unit/ParseExistsError.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module ParseExistsError where

import Amazonka.Types
import Gundeck.Aws
import Gundeck.Aws.Arn
import Gundeck.Types.Push.V2 (Transport (APNS))
import Imports
import Test.Tasty
import Test.Tasty.HUnit

tests :: TestTree
tests =
testGroup
"parseExistsError"
[ testCase "parse error string from real world example" parseErrorTest,
testCase "parse errors" parseErrors
]

parseErrorTest :: Assertion
parseErrorTest =
let e = Just $ ErrorMessage "Invalid parameter: Token Reason: Endpoint arn:aws:sns:eu-west-1:093205192929:endpoint/APNS/staging-com.wire.dev.ent/f90c8f08-a0a1-33bc-aa43-23c94770d936 already exists with the same Token, but different attributes."
expectedTopic = mkEndpointTopic (ArnEnv "staging") APNS "com.wire.dev.ent" (EndpointId "f90c8f08-a0a1-33bc-aa43-23c94770d936")
expected = mkSnsArn Ireland (Account "093205192929") expectedTopic
in parseExistsError e @?= Just expected

parseErrors :: Assertion
parseErrors = do
parseExistsError Nothing @?= Nothing
parseExistsError ((Just . ErrorMessage) "Invalid parameter: Token Reason: Endpoint") @?= Nothing
parseExistsError
( (Just . ErrorMessage)
"Invalid parameter: Token Reason: Endpoint NO_ARN already exists with the same Token, but different attributes."
)
@?= Nothing
parseExistsError
( (Just . ErrorMessage)
"Invalid parameter: Token Reason: Endpoint arn:aws:sns:eu-west-1:093205192929:endpoint/APNS/staging-com.wire.dev.ent/f90c8f08-a0a1-33bc-aa43-23c94770d936"
)
@?= Nothing

0 comments on commit 1c85346

Please sign in to comment.