-
Notifications
You must be signed in to change notification settings - Fork 334
Federation error wrapping #3742
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 16 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
c4d7e62
Remove redundant copy of error body from Wai.Error
pcapriotti fbcdbc4
Prevent unnecessary federator error wrapping
pcapriotti fd5a076
Remove dead code
pcapriotti 540d75c
Remove more dead code.
pcapriotti c8fe6ee
Add inner error to Wai.Error
pcapriotti e1e1338
Add nested error to federation remote error value
pcapriotti 1d4f9ff
Add CHANGELOG entry
pcapriotti 853473e
Test error wrapping
pcapriotti 39f2aca
Lint
pcapriotti 96ed095
Fix federation denied check in startBackend
pcapriotti 44fe497
Make sure mock server is killed in the finaliser
pcapriotti 0be8b9f
Fix root path in integration Mock
pcapriotti c5d402a
Lint
pcapriotti 469bf90
Use correct certificate paths in CI
pcapriotti 1ae48f2
Set fallback inner error
pcapriotti ab982e8
Spawn federator instead of ingress on error test
pcapriotti 2929ecb
Minor refactoring
pcapriotti 6136cf0
Restore explicit pattern matching
pcapriotti 493eb16
Avoid boolean argument in mock server
pcapriotti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Improved formatting of federation errors. No extra copy of the response body, and nested errors are now part of the JSON structure, not quoted inside the message. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| {-# OPTIONS -Wno-ambiguous-fields #-} | ||
| module Test.Errors where | ||
|
|
||
| import API.Brig | ||
| import Control.Monad.Codensity | ||
| import Control.Monad.Reader | ||
| import Data.Aeson qualified as Aeson | ||
| import Network.HTTP.Types qualified as HTTP | ||
| import Network.Wai qualified as Wai | ||
| import SetupHelpers | ||
| import Testlib.Mock | ||
| import Testlib.Prelude | ||
| import Testlib.ResourcePool | ||
|
|
||
| testNestedError :: HasCallStack => App () | ||
| testNestedError = do | ||
| let innerError = | ||
| object | ||
| [ "code" .= (400 :: Int), | ||
| "label" .= "example", | ||
| "message" .= "Example remote federator failure" | ||
| ] | ||
|
|
||
| resourcePool <- asks resourcePool | ||
| lowerCodensity $ do | ||
| [res] <- acquireResources 1 resourcePool | ||
pcapriotti marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| mockConfig <- do | ||
| mBase <- asks (.servicesCwdBase) | ||
| pure $ case mBase of | ||
| Just _ -> | ||
| -- when running locally, spawn a fake ingress returning an error | ||
| def | ||
| { port = Just (fromIntegral res.berNginzSslPort), | ||
| tls = True | ||
| } | ||
| Nothing -> do | ||
| -- on CI, the real federation ingress is available, so we spawn its federator upstream instead | ||
| def | ||
| { port = Just (fromIntegral res.berFederatorExternal), | ||
| tls = False | ||
| } | ||
| void $ | ||
| startMockServer mockConfig $ | ||
| codensityApp $ | ||
| \_req -> pure $ Wai.responseLBS HTTP.status400 mempty $ Aeson.encode innerError | ||
|
|
||
| -- get remote user | ||
| lift $ do | ||
| user <- randomUser OwnDomain def | ||
| targetId <- randomId | ||
| let target = object ["id" .= targetId, "domain" .= res.berDomain] | ||
| bindResponse (getUser user target) $ \resp -> do | ||
| resp.status `shouldMatchInt` 533 | ||
| resp.json %. "inner" `shouldMatch` innerError | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| module Testlib.Mock (startMockServer, MockServerConfig (..), codensityApp) where | ||
|
|
||
| import Control.Concurrent.Async | ||
| import Control.Concurrent.MVar | ||
| import Control.Exception | ||
| import Control.Monad.Codensity | ||
| import Control.Monad.Reader | ||
| import Data.Streaming.Network | ||
| import Network.Socket qualified as Socket | ||
| import Network.Wai qualified as Wai | ||
| import Network.Wai.Handler.Warp qualified as Warp | ||
| import Network.Wai.Handler.WarpTLS qualified as Warp | ||
| import Testlib.Prelude | ||
|
|
||
| codensityApp :: (Wai.Request -> Codensity IO Wai.Response) -> Wai.Application | ||
| codensityApp f req = runCodensity (f req) | ||
fisx marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| data MockServerConfig = MockServerConfig | ||
| { port :: Maybe Warp.Port, | ||
| tls :: Bool | ||
| } | ||
|
|
||
| instance Default MockServerConfig where | ||
| def = MockServerConfig {port = Nothing, tls = False} | ||
|
|
||
| spawnServer :: Bool -> Warp.Settings -> Socket.Socket -> Wai.Application -> App () | ||
| spawnServer False wsettings sock app = liftIO $ Warp.runSettingsSocket wsettings sock app | ||
pcapriotti marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| spawnServer True wsettings sock app = do | ||
| (cert, key) <- | ||
| asks (.servicesCwdBase) >>= \case | ||
| Nothing -> | ||
| pure | ||
| ( "/etc/wire/federator/secrets/tls.crt", | ||
| "/etc/wire/federator/secrets/tls.key" | ||
| ) | ||
| Just base -> | ||
| pure | ||
| ( base <> "/federator/test/resources/integration-leaf.pem", | ||
| base <> "/federator/test/resources/integration-leaf-key.pem" | ||
| ) | ||
pcapriotti marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| liftIO $ Warp.runTLSSocket (Warp.tlsSettings cert key) wsettings sock app | ||
|
|
||
| startMockServer :: MockServerConfig -> Wai.Application -> Codensity App Warp.Port | ||
| startMockServer config app = do | ||
| let closeSocket sock = catch (Socket.close sock) (\(_ :: SomeException) -> pure ()) | ||
| (port, sock) <- Codensity $ \k -> do | ||
| action <- appToIOKleisli k | ||
| liftIO $ | ||
| bracket | ||
| ( case config.port of | ||
| Nothing -> bindRandomPortTCP (fromString "*6") | ||
| Just n -> (n,) <$> bindPortTCP n (fromString "*6") | ||
| ) | ||
| (\(_, sock) -> closeSocket sock) | ||
| action | ||
| serverStarted <- liftIO newEmptyMVar | ||
| let wsettings = | ||
| Warp.defaultSettings | ||
| & Warp.setPort port | ||
| & Warp.setGracefulCloseTimeout2 0 | ||
| & Warp.setBeforeMainLoop (putMVar serverStarted Nothing) | ||
|
|
||
| -- Action to start server in a separate thread. | ||
| startServer <- lift . appToIO $ spawnServer config.tls wsettings sock app | ||
| let startServerAsync = do | ||
| a <- async $ do | ||
| catch startServer $ \(e :: SomeException) -> | ||
| void $ tryPutMVar serverStarted (Just e) | ||
| mException <- readMVar serverStarted | ||
| traverse_ throw mException | ||
| pure a | ||
|
|
||
| Codensity $ \k -> do | ||
| action <- appToIO (k ()) | ||
| liftIO | ||
| $ bracket | ||
| startServerAsync | ||
| ( \serverAsync -> do | ||
| closeSocket sock | ||
| -- kill the thread running the server | ||
| cancel serverAsync | ||
| ) | ||
| $ const action | ||
|
|
||
| pure port | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.