diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c8be9f65d0f..dc7bf5c98df 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,8 +4,8 @@ - [ ] The **PR description** provides context as to why the change should occur and what the code contributes to that effect. This could also be a link to a JIRA ticket or a Github issue, if there is one. - [ ] If end-points have been added or changed: the **endpoint / config-flag checklist** (see Wire-employee only backend [wiki page](https://github.com/zinfra/backend-wiki/wiki/Checklists)) has been followed. - [ ] If a schema migration has been added, I ran **`make git-add-cassandra-schema`** to update the cassandra schema documentation. - - [ ] Section *Unreleased* of **CHANGELOG-draft.md** contains the following bits of information: - - [ ] A line with the title and number of the PR in one or more suitable sub-sections. + - [ ] **changelog.d** contains the following bits of information: + - [ ] A file with the changelog entry in one or more suitable sub-sections. The sub-sections are marked by directories inside `changelog.d`. - [ ] If /a: measures to be taken by instance operators. - [ ] If /a: list of cassandra migrations. - [ ] If public end-points have been changed or added: does nginz need upgrade? diff --git a/CHANGELOG-draft.md b/CHANGELOG-draft.md deleted file mode 100644 index 6d46698b169..00000000000 --- a/CHANGELOG-draft.md +++ /dev/null @@ -1,17 +0,0 @@ -THIS FILE ACCUMULATES THE RELEASE NOTES FOR THE UPCOMING RELEASE. - -# [2021-xx-xx] - -## Release Notes - -## API Changes - -## Features - -## Bug fixes and other updates - -## Documentation - -## Internal changes - -## Federation changes diff --git a/CHANGELOG.md b/CHANGELOG.md index 49a26da34a1..15e4cfa1fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ + + +# [2021-09-14] + +## API changes + +* Remove the long-deprecated `message` field in `POST /connections` (#1726) +* Add `PUT /conversations/:domain/:cnv/name` (#1737) +* Deprecate `PUT /conversations/:cnv/name` (#1737) +* Add `GET & PUT /conversations/:domain/:cnv/self` (#1740) +* Deprecate `GET & PUT /conversations/:cnv/self` (#1740) +* Remove endpoint `GET /conversations/:domain/:cnv/self` (#1752) +* The `otr_muted` field in `Member` and `MemberUpdate` has been removed. (#1751) +* Removed the ability to update one's own role (#1752) + +## Features + +* Disallow changing phone number to a black listed phone number (#1758) +* Support using a single IDP with a single EntityID (aka issuer ID) to set up two teams. Required to support multiple teams in environments where the IDP software cannot present anything but one EntityID (E.G.: DualShield). (#1755) + +## Documentation + +* Added documentation of federation errors (#1674) +* Better swagger schema for the Range type (#1748) +* Add better example for Domain in swagger (#1748) + +## Internal changes + +* Introduce new process for writing changelogs (#1749) +* Clean up JSON golden tests (Part 4, Part 5) (#1756, #1762) +* Increased timeout on certificate update tests to 10s (#1750) +* Fix for flaky test in spar (#1760) +* Rewrite the `POST /connections` endpoint to Servant (#1726) +* Various improvements and fixes around SAML/SCIM (#1735) + +## Federation changes + +* Avoid remote calls to get conversation when it is not found locally (#1749) +* Federator CA store and client credentials are now automatically reloaded (#1730) +* Ensure clients only receive messages meant for them in remote convs (#1739) - # [2021-09-08] diff --git a/changelog.d/0-release-notes/.title b/changelog.d/0-release-notes/.title new file mode 100644 index 00000000000..d754b17caa9 --- /dev/null +++ b/changelog.d/0-release-notes/.title @@ -0,0 +1 @@ +Release notes \ No newline at end of file diff --git a/changelog.d/1-api-changes/.title b/changelog.d/1-api-changes/.title new file mode 100644 index 00000000000..9a9b53cb77b --- /dev/null +++ b/changelog.d/1-api-changes/.title @@ -0,0 +1 @@ +API changes \ No newline at end of file diff --git a/changelog.d/2-features/.title b/changelog.d/2-features/.title new file mode 100644 index 00000000000..9c364a39bbe --- /dev/null +++ b/changelog.d/2-features/.title @@ -0,0 +1 @@ +Features \ No newline at end of file diff --git a/changelog.d/2-features/pr-1755 b/changelog.d/2-features/pr-1755 new file mode 100644 index 00000000000..81624c4022e --- /dev/null +++ b/changelog.d/2-features/pr-1755 @@ -0,0 +1,3 @@ +Support using a single IDP with a single EntityID (aka issuer ID) to set up two teams. +Sets up a migration, and makes teamID + EntityID unique, rather than relying on EntityID to be unique. +Required to support multiple teams in environments where the IDP software cannot present anything but one EntityID (E.G.: DualShield). \ No newline at end of file diff --git a/changelog.d/3-bug-fixes/.title b/changelog.d/3-bug-fixes/.title new file mode 100644 index 00000000000..23bcb1b648b --- /dev/null +++ b/changelog.d/3-bug-fixes/.title @@ -0,0 +1 @@ +Bug fixes and other updates \ No newline at end of file diff --git a/changelog.d/4-docs/.title b/changelog.d/4-docs/.title new file mode 100644 index 00000000000..8db05209440 --- /dev/null +++ b/changelog.d/4-docs/.title @@ -0,0 +1 @@ +Documentation \ No newline at end of file diff --git a/changelog.d/5-internal/.title b/changelog.d/5-internal/.title new file mode 100644 index 00000000000..0377a227864 --- /dev/null +++ b/changelog.d/5-internal/.title @@ -0,0 +1 @@ +Internal changes \ No newline at end of file diff --git a/changelog.d/6-federation/.title b/changelog.d/6-federation/.title new file mode 100644 index 00000000000..efcb0217131 --- /dev/null +++ b/changelog.d/6-federation/.title @@ -0,0 +1 @@ +Federation changes \ No newline at end of file diff --git a/changelog.d/mk-changelog.sh b/changelog.d/mk-changelog.sh new file mode 100755 index 00000000000..3d0391dd951 --- /dev/null +++ b/changelog.d/mk-changelog.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +set -euo pipefail +shopt -s nullglob + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +getPRNumber() { + git log --reverse --format=%s -- $1 | sed -rn '1 { /\((#.*)\)$/ s|^.*\((#.*)\)$|\1|p; }' | grep "" || + echo "#PR_NOT_FOUND" +} + +for d in "$DIR"/*; do + if [[ ! -d "$d" ]]; then continue; fi + + echo -n "## " + sed '$ a\' "$d/.title" + echo "" + for f in "$d"/*; do + pr=$(getPRNumber $f) + sed -r ' + # create a bullet point on the first line + 1 { s/^/\* /; } + + # indent subsequent lines + 1 !{ s/^/ /; } + + # replace ## with PR number throughout + s/##/'"$pr"'/g + + # add PR number at the end (unless already present) + $ { /^.*\((#.*)\)$/ ! { s/$/ ('"$pr"')/; } } + + # remove trailing whitespace + s/\s+$// + + # make sure there is a trailing newline + $ a\' "$f" + done + echo "" +done diff --git a/changelog.d/mk-cleanup.sh b/changelog.d/mk-cleanup.sh new file mode 100755 index 00000000000..b483a6e6041 --- /dev/null +++ b/changelog.d/mk-cleanup.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -euo pipefail +shopt -s nullglob + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +rm -f "$DIR"/*/* +git add "$DIR" diff --git a/docs/developer/cassandra-interaction.md b/docs/developer/cassandra-interaction.md index 029830f7823..da62ea90291 100644 --- a/docs/developer/cassandra-interaction.md +++ b/docs/developer/cassandra-interaction.md @@ -1,5 +1,21 @@ # Writing code interacting with cassandra + + +* [Anti-patterns](#anti-patterns) + * [Anti-pattern: Using full table scans in production code](#anti-pattern-using-full-table-scans-in-production-code) + * [Anti-pattern: Using IN queries on a field in the partition key](#anti-pattern-using-in-queries-on-a-field-in-the-partition-key) + * [Anti-pattern: Designing for a lot of deletes or updates](#anti-pattern-designing-for-a-lot-of-deletes-or-updates) +* [Understanding more about cassandra](#understanding-more-about-cassandra) + * [primary partition clustering keys](#primary-partition-clustering-keys) + * [optimizing parallel request performance](#optimizing-parallel-request-performance) +* [Cassandra schema migrations](#cassandra-schema-migrations) + * [Backwards compatible schema changes](#backwards-compatible-schema-changes) + * [Backwards incompatible schema changes](#backwards-incompatible-schema-changes) + * [What to do about backwards incompatible schema changes](#what-to-do-about-backwards-incompatible-schema-changes) + + + ## Anti-patterns ### Anti-pattern: Using full table scans in production code @@ -36,3 +52,47 @@ Confused about primary key, partition key, and clustering key? See e.g. [this po ### optimizing parallel request performance See the thoughts in https://github.com/wireapp/wire-server/pull/1345#discussion_r567829234 - measuring overall and per-request performance and trying out different settings here might be worthwhile if increasing read or write performance is critical. + +## Cassandra schema migrations + +### Backwards compatible schema changes + +Most cassandra schema changes are backwards compatible, or *should* be designed to be so. Looking at the changes under `services/{brig,spar,galley,gundeck}/schema` you'll find this to be mostly the case. + +The general deployment setup for services interacting with cassandra have the following assumption: + +* cassandra schema updates happen *before* new code is deployed. + * This is safeguarded by the concourse deployment pipelines + * This is also safeguarded by the `wire-server` helm chart, which deploys the `cassandra-migrations` job as part of a helm [pre-install/pre-upgrade hook](https://github.com/wireapp/wire-server/blob/b3b1af6757194aa1dc86a8f387887936f2afd2fb/charts/cassandra-migrations/templates/migrate-schema.yaml#L10-L13): that means the schema changes are applied, and helm waits before launching the new code in the brig/galley/spar/gundeck pods until the changes have completed applying. + * This is further safeguarded by the code e.g. in brig refusing to even start the service up if the applied schema migration is not at least at a version the code expects it to. See [versionCheck](https://github.com/wireapp/wire-server/blob/b3b1af6757194aa1dc86a8f387887936f2afd2fb/services/brig/src/Brig/App.hs#L411) and [schemaVersion](https://github.com/wireapp/wire-server/blob/b3b1af6757194aa1dc86a8f387887936f2afd2fb/services/brig/src/Brig/App.hs#L136-L137) + +So usually with these safeguards in place, and backwards-compatible changes, we have the following: + +* At time t=0, old schema, old code serves traffic; all good. +* At time t=1, new schema, old code serves traffic: all good since backwards compatible. +* At time t=2, new schema, old code AND new code serve traffic: all good since backwards compatible. +* At time t=3, new schema, new code serves traffic: all good since backwards compatible. + +If this order (apply schema first; then deploy code) is not safeguarded, then there will be code running in e.g. production which `SELECT my_new_field FROM my_new_table` even though this doesn't yet exist, leading to 500 server errors for as long as the mismatch between applied schema and code version persists. + +### Backwards incompatible schema changes + +In the case where a schema migration is **not backwards compatible**, such as in the form of `ALTER TABLE my_table DROP my_column`, the reverse problem exists: + +During a deployment: + +* At time t=0, old schema, old code serves traffic; all good. +* At time t=1, new schema, old code serves traffic: 500 server errors as the old code is still active, bit columns or tables have been deleted, so old queries of `SELECT x from my_table` cause exceptions / HTTP 5xx results. + * In the worst deployment scenario, this could raise an alarm and lead operators or automation to stop the deployment or roll back; but that doesn't solve the issue, 500s will continue being thrown until the new code is deployed. +* At time t=2, new schema, old code AND new code serve traffic: partial 500s (all traffic still serves by old code) +* At time t=3, new schema, new code serves traffic: all good again. + +#### What to do about backwards incompatible schema changes + +Options from most to least desirable: + +* Never make backwards-incompatbile changes to the database schema :) +* Do changes in a two-step process: + * First make a change that stops the code from using queries involving `my_column` or `my_table` (assuming you wish to remove those), and deploy this all the way across all of your environments (staging, prod, customers, ...). + * After all deployments have gone through (this can take weeks or months), do the schema change removing that column or table from the database. Often there is no urgency with removal of data, so it's fine to do this e.g. 6 months later. +* Do changes in a one-step process, but accept partial service interruption for several minutes up to a few hours, accept communication overhead across teams to warn them about upcoming interruption or explain previous interruption; accept communication and documentation to warn all operators deploying that or a future version of the code, and accept some amount of frustration that may arise from a lack of said communication and understanding of what is happening. diff --git a/docs/reference/cassandra-schema.cql b/docs/reference/cassandra-schema.cql index cd0b9d85d5c..e9383b36184 100644 --- a/docs/reference/cassandra-schema.cql +++ b/docs/reference/cassandra-schema.cql @@ -1513,6 +1513,7 @@ CREATE TABLE spar_test.issuer_idp ( CREATE TABLE spar_test.idp ( idp uuid PRIMARY KEY, + api_version int, extra_public_keys list, issuer text, old_issuers list, @@ -1681,6 +1682,27 @@ CREATE TABLE spar_test.team_idp ( AND read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE'; +CREATE TABLE spar_test.issuer_idp_v2 ( + issuer text, + team uuid, + idp uuid, + PRIMARY KEY (issuer, team) +) WITH CLUSTERING ORDER BY (team ASC) + AND bloom_filter_fp_chance = 0.1 + AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'} + AND comment = '' + AND compaction = {'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'} + AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} + AND crc_check_chance = 1.0 + AND dclocal_read_repair_chance = 0.1 + AND default_time_to_live = 0 + AND gc_grace_seconds = 864000 + AND max_index_interval = 2048 + AND memtable_flush_period_in_ms = 0 + AND min_index_interval = 128 + AND read_repair_chance = 0.0 + AND speculative_retry = '99PERCENTILE'; + CREATE TABLE spar_test.scim_user_times ( uid uuid PRIMARY KEY, created_at timestamp, diff --git a/libs/brig-types/src/Brig/Types/Connection.hs b/libs/brig-types/src/Brig/Types/Connection.hs index 3d6b37ff99a..a606894f767 100644 --- a/libs/brig-types/src/Brig/Types/Connection.hs +++ b/libs/brig-types/src/Brig/Types/Connection.hs @@ -29,7 +29,6 @@ module Brig.Types.Connection UpdateConnectionsInternal (..), -- * re-exports - Message (..), Relation (..), UserConnection (..), ConnectionRequest (..), diff --git a/libs/galley-types/src/Galley/Types/Conversations/Members.hs b/libs/galley-types/src/Galley/Types/Conversations/Members.hs index b54ac8e3f14..c88e46c76e5 100644 --- a/libs/galley-types/src/Galley/Types/Conversations/Members.hs +++ b/libs/galley-types/src/Galley/Types/Conversations/Members.hs @@ -43,8 +43,6 @@ data RemoteMember = RemoteMember data InternalMember id = InternalMember { memId :: id, memService :: Maybe ServiceRef, - -- | DEPRECATED, remove it once enough clients use `memOtrMutedStatus` - memOtrMuted :: Bool, memOtrMutedStatus :: Maybe MutedStatus, memOtrMutedRef :: Maybe Text, memOtrArchived :: Bool, diff --git a/libs/hscim/.gitignore b/libs/hscim/.gitignore index 691684e8295..bda3c806788 100644 --- a/libs/hscim/.gitignore +++ b/libs/hscim/.gitignore @@ -25,3 +25,4 @@ cabal.project.local~ *~ *.el \#* +.ghci diff --git a/libs/hscim/src/Web/Scim/Test/Util.hs b/libs/hscim/src/Web/Scim/Test/Util.hs index ee77c1f6029..9234eee6953 100644 --- a/libs/hscim/src/Web/Scim/Test/Util.hs +++ b/libs/hscim/src/Web/Scim/Test/Util.hs @@ -101,6 +101,7 @@ shouldEventuallyRespondWith action matcher = data AcceptanceConfig tag = AcceptanceConfig { scimAppAndConfig :: IO (Application, AcceptanceQueryConfig tag), + -- TODO: add a destructor, something like: @destroy :: CustomEnv tag -> IO ()@, genUserName :: IO Text, -- | some acceptance tests match against a fully rendered -- response body, which will not work when running the test diff --git a/libs/tasty-cannon/package.yaml b/libs/tasty-cannon/package.yaml index b325f84156f..972dafbd113 100644 --- a/libs/tasty-cannon/package.yaml +++ b/libs/tasty-cannon/package.yaml @@ -12,6 +12,7 @@ dependencies: - aeson - async - base >=4.6 && <5 +- bilge - bytestring - bytestring-conversion - data-timeout diff --git a/libs/tasty-cannon/src/Test/Tasty/Cannon.hs b/libs/tasty-cannon/src/Test/Tasty/Cannon.hs index 66be04fbf21..94c1f68da03 100644 --- a/libs/tasty-cannon/src/Test/Tasty/Cannon.hs +++ b/libs/tasty-cannon/src/Test/Tasty/Cannon.hs @@ -26,16 +26,22 @@ module Test.Tasty.Cannon -- * WebSockets WebSocket, connect, + connectAsClient, close, bracket, + bracketAsClient, bracketN, + bracketAsClientN, -- ** Random Connection IDs connectR, + connectAsClientR, bracketR, + bracketAsClientR, bracketR2, bracketR3, bracketRN, + bracketAsClientRN, -- * Awaiting & Asserting on Notifications MatchTimeout (..), @@ -63,6 +69,7 @@ module Test.Tasty.Cannon ) where +import Bilge.Request (queryItem) import Control.Concurrent.Async import Control.Concurrent.Timeout hiding (threadDelay) import Control.Exception (asyncExceptionFromException, throwIO) @@ -96,10 +103,16 @@ data WebSocket = WebSocket } connect :: MonadIO m => Cannon -> UserId -> ConnId -> m WebSocket -connect can uid cid = liftIO $ do +connect can uid = connectAsMaybeClient can uid Nothing + +connectAsClient :: MonadIO m => Cannon -> UserId -> ClientId -> ConnId -> m WebSocket +connectAsClient can uid client = connectAsMaybeClient can uid (Just client) + +connectAsMaybeClient :: MonadIO m => Cannon -> UserId -> Maybe ClientId -> ConnId -> m WebSocket +connectAsMaybeClient can uid client conn = liftIO $ do nchan <- newTChanIO latch <- newEmptyMVar - wsapp <- run can uid cid (clientApp nchan latch) + wsapp <- run can uid client conn (clientApp nchan latch) return $ WebSocket nchan latch wsapp close :: MonadIO m => WebSocket -> m () @@ -114,7 +127,19 @@ bracket :: ConnId -> (WebSocket -> m a) -> m a -bracket can uid cid = Catch.bracket (connect can uid cid) close +bracket can uid conn = + Catch.bracket (connect can uid conn) close + +bracketAsClient :: + (MonadMask m, MonadIO m) => + Cannon -> + UserId -> + ClientId -> + ConnId -> + (WebSocket -> m a) -> + m a +bracketAsClient can uid client conn = + Catch.bracket (connectAsClient can uid client conn) close bracketN :: (MonadIO m, MonadMask m) => @@ -127,16 +152,35 @@ bracketN c us f = go [] us go wss [] = f (reverse wss) go wss ((x, y) : xs) = bracket c x y (\ws -> go (ws : wss) xs) +bracketAsClientN :: + (MonadMask m, MonadIO m) => + Cannon -> + [(UserId, ClientId, ConnId)] -> + ([WebSocket] -> m a) -> + m a +bracketAsClientN c us f = go [] us + where + go wss [] = f (reverse wss) + go wss ((x, y, z) : xs) = bracketAsClient c x y z (\ws -> go (ws : wss) xs) + -- Random Connection IDs connectR :: MonadIO m => Cannon -> UserId -> m WebSocket connectR can uid = randomConnId >>= connect can uid +connectAsClientR :: MonadIO m => Cannon -> UserId -> ClientId -> m WebSocket +connectAsClientR can uid clientId = randomConnId >>= connectAsClient can uid clientId + bracketR :: (MonadIO m, MonadMask m) => Cannon -> UserId -> (WebSocket -> m a) -> m a bracketR can usr f = do cid <- randomConnId bracket can usr cid f +bracketAsClientR :: (MonadIO m, MonadMask m) => Cannon -> UserId -> ClientId -> (WebSocket -> m a) -> m a +bracketAsClientR can usr clientId f = do + connId <- randomConnId + bracketAsClient can usr clientId connId f + bracketR2 :: (MonadIO m, MonadMask m) => Cannon -> @@ -174,6 +218,17 @@ bracketRN c us f = go [] us go wss [] = f (reverse wss) go wss (x : xs) = bracketR c x (\ws -> go (ws : wss) xs) +bracketAsClientRN :: + (MonadIO m, MonadMask m) => + Cannon -> + [(UserId, ClientId)] -> + ([WebSocket] -> m a) -> + m a +bracketAsClientRN can us f = go [] us + where + go wss [] = f (reverse wss) + go wss ((u, c) : xs) = bracketAsClientR can u c (\ws -> go (ws : wss) xs) + ----------------------------------------------------------------------------- -- Awaiting & Asserting on Notifications @@ -336,8 +391,8 @@ randomConnId = liftIO $ do -- | Start a client thread in 'Async' that opens a web socket to a Cannon, wait -- for the connection to register with Gundeck, and return the 'Async' thread. -run :: MonadIO m => Cannon -> UserId -> ConnId -> WS.ClientApp () -> m (Async ()) -run (($ Http.defaultRequest) -> ca) uid cid app = liftIO $ do +run :: MonadIO m => Cannon -> UserId -> Maybe ClientId -> ConnId -> WS.ClientApp () -> m (Async ()) +run cannon@(($ Http.defaultRequest) -> ca) uid client connId app = liftIO $ do latch <- newEmptyMVar wsapp <- async $ @@ -359,9 +414,10 @@ run (($ Http.defaultRequest) -> ca) uid cid app = liftIO $ do where caHost = C.unpack (Http.host ca) caPort = Http.port ca - caPath = "/await" ++ C.unpack (Http.queryString ca) + caPath = "/await" ++ C.unpack caQuery + caQuery = Http.queryString . cannon . maybe id (queryItem "client" . toByteString') client $ Http.defaultRequest caOpts = WS.defaultConnectionOptions - caHdrs = [("Z-User", toByteString' uid), ("Z-Connection", toByteString' cid)] + caHdrs = [("Z-User", toByteString' uid), ("Z-Connection", toByteString' connId)] numRetries = 30 waitForRegistry 0 = throwIO $ RegistrationTimeout numRetries waitForRegistry (n :: Int) = do @@ -369,7 +425,7 @@ run (($ Http.defaultRequest) -> ca) uid cid app = liftIO $ do let ca' = ca { method = "HEAD", - path = "/i/presences/" <> toByteString' uid <> "/" <> toByteString' cid + path = "/i/presences/" <> toByteString' uid <> "/" <> toByteString' connId } res <- httpLbs ca' man unless (responseStatus res == status200) $ do diff --git a/libs/tasty-cannon/tasty-cannon.cabal b/libs/tasty-cannon/tasty-cannon.cabal index 2e8fd861df1..11de15b68e6 100644 --- a/libs/tasty-cannon/tasty-cannon.cabal +++ b/libs/tasty-cannon/tasty-cannon.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: b7fca22ffa51fd956424d50af91793bd16e3d1b5170e6ccc48b26bf821793358 +-- hash: 3e4d6b79f93c721b5df897b6653023feaa197910713bf3a2a759ea37ca05427f name: tasty-cannon version: 0.4.0 @@ -30,6 +30,7 @@ library aeson , async , base >=4.6 && <5 + , bilge , bytestring , bytestring-conversion , data-timeout diff --git a/libs/types-common/src/Data/CommaSeparatedList.hs b/libs/types-common/src/Data/CommaSeparatedList.hs index 8f944bde33e..4346769a131 100644 --- a/libs/types-common/src/Data/CommaSeparatedList.hs +++ b/libs/types-common/src/Data/CommaSeparatedList.hs @@ -41,6 +41,7 @@ instance FromByteString (List a) => FromHttpApiData (CommaSeparatedList a) where instance ToParamSchema (CommaSeparatedList a) where toParamSchema _ = mempty & type_ ?~ SwaggerString +-- | TODO: is this obsoleted by the instances in "Data.Range"? instance (ToParamSchema a, ToParamSchema (Range n m [a])) => ToParamSchema (Range n m (CommaSeparatedList a)) where toParamSchema _ = toParamSchema (Proxy @(Range n m [a])) diff --git a/libs/types-common/src/Data/Domain.hs b/libs/types-common/src/Data/Domain.hs index 82ab246614f..7656834b433 100644 --- a/libs/types-common/src/Data/Domain.hs +++ b/libs/types-common/src/Data/Domain.hs @@ -19,6 +19,7 @@ module Data.Domain where +import Control.Lens ((?~)) import Data.Aeson (FromJSON, FromJSONKey, FromJSONKeyFunction (FromJSONKeyTextParser), ToJSON, ToJSONKey (toJSONKey)) import qualified Data.Aeson as Aeson import Data.Aeson.Types (toJSONKeyText) @@ -66,7 +67,9 @@ newtype Domain = Domain {_domainText :: Text} deriving (FromJSON, ToJSON, S.ToSchema) via Schema Domain instance ToSchema Domain where - schema = domainText .= parsedText "Domain" mkDomain + schema = + domainText .= parsedText "Domain" mkDomain + & doc . S.schema . S.example ?~ "example.com" domainText :: Domain -> Text domainText = _domainText diff --git a/libs/types-common/src/Data/Range.hs b/libs/types-common/src/Data/Range.hs index 9ed5be7950f..832746ccc13 100644 --- a/libs/types-common/src/Data/Range.hs +++ b/libs/types-common/src/Data/Range.hs @@ -55,7 +55,7 @@ module Data.Range where import Cassandra (ColumnType, Cql (..), Tagged, retag) -import Control.Lens ((?~)) +import Control.Lens ((%~), (?~)) import Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON)) import Data.Aeson.Types as Aeson (Parser) import qualified Data.Attoparsec.ByteString as Atto @@ -121,7 +121,7 @@ instance (Within a n m, FromJSON a) => FromJSON (Range n m a) where msg sn sm = fail (errorMsg (fromSing sn) (fromSing sm) "") rangedSchema :: - (Within a n m, Bounds b) => + (Within a n m, HasRangedSchemaDocModifier d b) => SNat n -> SNat m -> SchemaP d v w a b -> @@ -131,18 +131,55 @@ rangedSchema sn sm sch = Range <$> untypedRangedSchema (get sn) (get sm) sch get = toInteger . fromSing untypedRangedSchema :: - Bounds b => + forall d v w a b. + (HasRangedSchemaDocModifier d b) => Integer -> Integer -> SchemaP d v w a b -> SchemaP d v w a b -untypedRangedSchema n m sch = sch `withParser` check +untypedRangedSchema n m sch = (sch `withParser` check) & doc %~ rangedSchemaDocModifier (Proxy @b) n m where check x = x <$ guard (within x n m) <|> fail (errorMsg n m "") -instance (Within a n m, ToSchema a) => ToSchema (Range n m a) where +class Bounds a => HasRangedSchemaDocModifier d a where + rangedSchemaDocModifier :: Proxy a -> Integer -> Integer -> d -> d + +listRangedSchemaDocModifier :: S.HasSchema d S.Schema => Integer -> Integer -> d -> d +listRangedSchemaDocModifier n m = S.schema %~ ((S.minItems ?~ n) . (S.maxItems ?~ m)) + +stringRangedSchemaDocModifier :: S.HasSchema d S.Schema => Integer -> Integer -> d -> d +stringRangedSchemaDocModifier n m = S.schema %~ ((S.minLength ?~ n) . (S.maxLength ?~ m)) + +numRangedSchemaDocModifier :: S.HasSchema d S.Schema => Integer -> Integer -> d -> d +numRangedSchemaDocModifier n m = S.schema %~ ((S.minimum_ ?~ fromIntegral n) . (S.maximum_ ?~ fromIntegral m)) + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d [a] where rangedSchemaDocModifier _ = listRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Text where rangedSchemaDocModifier _ = stringRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d String where rangedSchemaDocModifier _ = stringRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d (AsciiText c) where rangedSchemaDocModifier _ = stringRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Int where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Int32 where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Integer where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Word where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Word8 where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Word16 where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Word32 where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance S.HasSchema d S.Schema => HasRangedSchemaDocModifier d Word64 where rangedSchemaDocModifier _ = numRangedSchemaDocModifier + +instance (Within a n m, ToSchema a, HasRangedSchemaDocModifier NamedSwaggerDoc a) => ToSchema (Range n m a) where schema = fromRange .= rangedSchema sing sing schema instance (Within a n m, Cql a) => Cql (Range n m a) where diff --git a/libs/wire-api-federation/proto/router.proto b/libs/wire-api-federation/proto/router.proto index c6511364cfd..e3c253dd4bf 100644 --- a/libs/wire-api-federation/proto/router.proto +++ b/libs/wire-api-federation/proto/router.proto @@ -37,16 +37,16 @@ message OutwardError { DiscoveryFailed = 1; ConnectionRefused = 2; TLSFailure = 3; - InvalidCertificate = 4; - VersionMismatch = 5; - FederationDeniedByRemote = 6; - FederationDeniedLocally = 7; - RemoteFederatorError = 8; + VersionMismatch = 4; + FederationDeniedByRemote = 5; + FederationDeniedLocally = 6; + TooMuchConcurrency = 7; + GrpcError = 8; InvalidRequest = 9; } ErrorType type = 1; - ErrorPayload payload = 2; + string msg = 2; } message InwardError { @@ -63,11 +63,6 @@ message InwardError { string msg = 2; } -message ErrorPayload { - string label = 1; - string msg = 2; -} - // The envelope message which is sent from brig to the Outward service of a local federator message FederatedRequest { string domain = 1; diff --git a/libs/wire-api-federation/src/Wire/API/Federation/Error.hs b/libs/wire-api-federation/src/Wire/API/Federation/Error.hs index bc0ed03bed1..6aa875b608a 100644 --- a/libs/wire-api-federation/src/Wire/API/Federation/Error.hs +++ b/libs/wire-api-federation/src/Wire/API/Federation/Error.hs @@ -38,7 +38,11 @@ federationErrorToWai FederationNotImplemented = federationNotImplemented federationErrorToWai FederationNotConfigured = federationNotConfigured federationErrorToWai (FederationCallFailure failure) = addErrorData $ case fedFailError failure of - FederationClientRPCError msg -> federationRpcError msg + FederationClientRPCError msg -> + Wai.mkError + HTTP.status500 + "client-rpc-error" + (LT.fromStrict msg) FederationClientInvalidMethod mth -> federationInvalidCall ("Unexpected method: " <> LT.fromStrict (T.decodeUtf8 mth)) @@ -117,13 +121,6 @@ federationNotConfigured = "federation-not-enabled" "no federator configured" -federationRpcError :: Text -> Wai.Error -federationRpcError msg = - Wai.mkError - HTTP.status500 - "federation-rpc-error" - (LT.fromStrict msg) - federationUnavailable :: Text -> Wai.Error federationUnavailable err = Wai.mkError @@ -144,25 +141,25 @@ federationRemoteInwardError err = Wai.mkError status (LT.fromStrict label) (LT.f Proto.IOther -> (unexpectedFederationResponseStatus, "inward-other") federationRemoteError :: Proto.OutwardError -> Wai.Error -federationRemoteError err = Wai.mkError status (LT.fromStrict label) (LT.fromStrict msg) +federationRemoteError err = case Proto.outwardErrorType err of + Proto.RemoteNotFound -> mkErr HTTP.status422 "srv-record-not-found" + Proto.DiscoveryFailed -> mkErr HTTP.status500 "srv-lookup-dns-error" + Proto.ConnectionRefused -> + mkErr + (HTTP.Status 521 "Web Server Is Down") + "cannot-connect-to-remote-federator" + Proto.TLSFailure -> mkErr (HTTP.Status 525 "SSL Handshake Failure") "tls-failure" + Proto.VersionMismatch -> mkErr (HTTP.Status 531 "Version Mismatch") "version-mismatch" + Proto.FederationDeniedByRemote -> + mkErr + (HTTP.Status 532 "Federation Denied") + "federation-denied-remotely" + Proto.FederationDeniedLocally -> mkErr HTTP.status400 "federation-not-allowed" + Proto.TooMuchConcurrency -> mkErr unexpectedFederationResponseStatus "too-much-concurrency" + Proto.GrpcError -> mkErr unexpectedFederationResponseStatus "grpc-error" + Proto.InvalidRequest -> mkErr HTTP.status500 "invalid-request-to-federator" where - decodeError :: Maybe Proto.ErrorPayload -> (Text, Text) - decodeError Nothing = ("unknown-federation-error", "Unknown federation error") - decodeError (Just (Proto.ErrorPayload label' msg')) = (label', msg') - - (label, msg) = decodeError (Proto.outwardErrorPayload err) - - status = case Proto.outwardErrorType err of - Proto.RemoteNotFound -> HTTP.status422 - Proto.DiscoveryFailed -> HTTP.status500 - Proto.ConnectionRefused -> HTTP.Status 521 "Web Server Is Down" - Proto.TLSFailure -> HTTP.Status 525 "SSL Handshake Failure" - Proto.InvalidCertificate -> HTTP.Status 526 "Invalid SSL Certificate" - Proto.VersionMismatch -> HTTP.Status 531 "Version Mismatch" - Proto.FederationDeniedByRemote -> HTTP.Status 532 "Federation Denied" - Proto.FederationDeniedLocally -> HTTP.status400 - Proto.RemoteFederatorError -> unexpectedFederationResponseStatus - Proto.InvalidRequest -> HTTP.status500 + mkErr status label = Wai.mkError status label (LT.fromStrict (Proto.outwardErrorMessage err)) federationInvalidCall :: LText -> Wai.Error federationInvalidCall = Wai.mkError HTTP.status500 "federation-invalid-call" diff --git a/libs/wire-api-federation/src/Wire/API/Federation/GRPC/Types.hs b/libs/wire-api-federation/src/Wire/API/Federation/GRPC/Types.hs index 8beff443acc..cd59dd25d4f 100644 --- a/libs/wire-api-federation/src/Wire/API/Federation/GRPC/Types.hs +++ b/libs/wire-api-federation/src/Wire/API/Federation/GRPC/Types.hs @@ -26,6 +26,7 @@ module Wire.API.Federation.GRPC.Types where import Data.Domain (Domain (..), domainText, mkDomain) import Data.Either.Validation import Data.List.NonEmpty (NonEmpty ((:|))) +import qualified Data.Text as Text import Imports import Mu.Quasi.GRpc (grpc) import Mu.Schema @@ -101,12 +102,12 @@ instance FromSchema Router "OutwardResponse" OutwardResponse where -- https://higherkindness.io/mu-haskell/schema/#mapping-haskell-types type OutwardErrorFieldMapping = '[ "outwardErrorType" ':-> "type", - "outwardErrorPayload" ':-> "payload" + "outwardErrorMessage" ':-> "msg" ] data OutwardError = OutwardError { outwardErrorType :: OutwardErrorType, - outwardErrorPayload :: Maybe ErrorPayload + outwardErrorMessage :: Text } deriving (Typeable, Show, Eq, Generic) deriving (Arbitrary) via (GenericUniform OutwardError) @@ -119,22 +120,15 @@ data OutwardErrorType | DiscoveryFailed | ConnectionRefused | TLSFailure - | InvalidCertificate | VersionMismatch | FederationDeniedByRemote | FederationDeniedLocally - | RemoteFederatorError + | TooMuchConcurrency + | GrpcError | InvalidRequest deriving (Typeable, Show, Eq, Generic, ToSchema Router "OutwardError.ErrorType", FromSchema Router "OutwardError.ErrorType") deriving (Arbitrary) via (GenericUniform OutwardErrorType) -data ErrorPayload = ErrorPayload - { label :: Text, - msg :: Text - } - deriving (Typeable, Show, Eq, Generic, ToSchema Router "ErrorPayload", FromSchema Router "ErrorPayload") - deriving (Arbitrary) via (GenericUniform ErrorPayload) - -- See mu-haskell Custom Mapping documentation here: -- https://higherkindness.io/mu-haskell/schema/#mapping-haskell-types type InwardErrorFieldMapping = @@ -190,6 +184,16 @@ data ValidatedFederatedRequest = ValidatedFederatedRequest } deriving (Typeable, Eq, Show) +showFederatedRequestValidationError :: FederatedRequestValidationError -> Text +showFederatedRequestValidationError (InvalidDomain msg) = "invalid domain: " <> Text.pack msg +showFederatedRequestValidationError RequestMissing = "federation request is missing" + +showFederatedRequestValidationErrors :: NonEmpty FederatedRequestValidationError -> Text +showFederatedRequestValidationErrors = + Text.intercalate "; " + . map showFederatedRequestValidationError + . toList + validateFederatedRequest :: FederatedRequest -> Validation (NonEmpty FederatedRequestValidationError) ValidatedFederatedRequest validateFederatedRequest FederatedRequest {..} = do vDomain <- validateDomain diff --git a/libs/wire-api/src/Wire/API/Connection.hs b/libs/wire-api/src/Wire/API/Connection.hs index 46e51e67d05..7b217f31e85 100644 --- a/libs/wire-api/src/Wire/API/Connection.hs +++ b/libs/wire-api/src/Wire/API/Connection.hs @@ -1,5 +1,4 @@ -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE StrictData #-} -- This file is part of the Wire Server implementation. @@ -26,7 +25,6 @@ module Wire.API.Connection ( -- * UserConnection UserConnection (..), UserConnectionList (..), - Message (..), Relation (..), RelationWithHistory (..), relationDropHistory, @@ -38,24 +36,23 @@ module Wire.API.Connection -- * Swagger modelConnectionList, modelConnection, - modelConnectionRequest, modelConnectionUpdate, ) where -import Data.Aeson -import Data.Aeson.Types (Parser) +import Control.Lens ((?~)) +import Data.Aeson as Aeson import Data.Attoparsec.ByteString (takeByteString) import Data.ByteString.Conversion import Data.Id import Data.Json.Util (UTCTimeMillis) import Data.Range +import qualified Data.Schema as P import qualified Data.Swagger.Build.Api as Doc -import Data.Swagger.Schema +import Data.Swagger.Schema as S import Data.Text as Text -import Deriving.Swagger (CamelToKebab, ConstructorTagModifier, CustomSwagger) import Imports -import Wire.API.Arbitrary (Arbitrary (arbitrary), GenericUniform (..)) +import Wire.API.Arbitrary (Arbitrary (..), GenericUniform (..)) -------------------------------------------------------------------------------- -- UserConnectionList @@ -68,6 +65,14 @@ data UserConnectionList = UserConnectionList } deriving stock (Eq, Show, Generic) deriving (Arbitrary) via (GenericUniform UserConnectionList) + deriving (FromJSON, ToJSON, S.ToSchema) via (P.Schema UserConnectionList) + +instance P.ToSchema UserConnectionList where + schema = + P.object "UserConnectionList" $ + UserConnectionList + <$> clConnections P..= P.field "connections" (P.array P.schema) + <*> clHasMore P..= P.fieldWithDocModifier "has_more" (P.description ?~ "Indicator that the server has more connections than returned.") P.schema modelConnectionList :: Doc.Model modelConnectionList = Doc.defineModel "UserConnectionList" $ do @@ -76,19 +81,6 @@ modelConnectionList = Doc.defineModel "UserConnectionList" $ do Doc.property "has_more" Doc.bool' $ Doc.description "Indicator that the server has more connections than returned." -instance ToJSON UserConnectionList where - toJSON (UserConnectionList l m) = - object - [ "connections" .= l, - "has_more" .= m - ] - -instance FromJSON UserConnectionList where - parseJSON = withObject "UserConnectionList" $ \o -> - UserConnectionList - <$> o .: "connections" - <*> o .: "has_more" - -------------------------------------------------------------------------------- -- UserConnection @@ -103,11 +95,21 @@ data UserConnection = UserConnection ucStatus :: Relation, -- | When 'ucStatus' was last changed ucLastUpdate :: UTCTimeMillis, - ucMessage :: Maybe Message, ucConvId :: Maybe ConvId } deriving stock (Eq, Show, Generic) deriving (Arbitrary) via (GenericUniform UserConnection) + deriving (FromJSON, ToJSON, S.ToSchema) via (P.Schema UserConnection) + +instance P.ToSchema UserConnection where + schema = + P.object "UserConnection" $ + UserConnection + <$> ucFrom P..= P.field "from" P.schema + <*> ucTo P..= P.field "to" P.schema + <*> ucStatus P..= P.field "status" P.schema + <*> ucLastUpdate P..= P.field "last_update" P.schema + <*> ucConvId P..= P.optField "conversation" Nothing P.schema modelConnection :: Doc.Model modelConnection = Doc.defineModel "Connection" $ do @@ -127,27 +129,6 @@ modelConnection = Doc.defineModel "Connection" $ do Doc.description "Conversation ID" Doc.optional -instance ToJSON UserConnection where - toJSON uc = - object - [ "from" .= ucFrom uc, - "to" .= ucTo uc, - "status" .= ucStatus uc, - "last_update" .= ucLastUpdate uc, - "message" .= ucMessage uc, - "conversation" .= ucConvId uc - ] - -instance FromJSON UserConnection where - parseJSON = withObject "user-connection" $ \o -> - UserConnection - <$> o .: "from" - <*> o .: "to" - <*> o .: "status" - <*> o .: "last_update" - <*> o .:? "message" - <*> o .:? "conversation" - -------------------------------------------------------------------------------- -- Relation @@ -165,7 +146,7 @@ data Relation MissingLegalholdConsent deriving stock (Eq, Ord, Show, Generic) deriving (Arbitrary) via (GenericUniform Relation) - deriving (ToSchema) via (CustomSwagger '[ConstructorTagModifier CamelToKebab] Relation) + deriving (FromJSON, ToJSON, S.ToSchema) via (P.Schema Relation) -- | 'updateConnectionInternal', requires knowledge of the previous state (before -- 'MissingLegalholdConsent'), but the clients don't need that information. To avoid having @@ -215,29 +196,22 @@ typeRelation = "missing-legalhold-consent" ] -instance ToJSON Relation where - toJSON = \case - Accepted -> "accepted" - Blocked -> "blocked" - Pending -> "pending" - Ignored -> "ignored" - Sent -> "sent" - Cancelled -> "cancelled" - MissingLegalholdConsent -> "missing-legalhold-consent" - -instance FromJSON Relation where - parseJSON (String "accepted") = return Accepted - parseJSON (String "blocked") = return Blocked - parseJSON (String "pending") = return Pending - parseJSON (String "ignored") = return Ignored - parseJSON (String "sent") = return Sent - parseJSON (String "cancelled") = return Cancelled - parseJSON (String "missing-legalhold-consent") = return MissingLegalholdConsent - parseJSON _ = mzero +instance P.ToSchema Relation where + schema = + P.enum @Text "Relation" $ + mconcat + [ P.element "accepted" Accepted, + P.element "blocked" Blocked, + P.element "pending" Pending, + P.element "ignored" Ignored, + P.element "sent" Sent, + P.element "cancelled" Cancelled, + P.element "missing-legalhold-consent" MissingLegalholdConsent + ] instance FromByteString Relation where parser = - takeByteString >>= \b -> case b of + takeByteString >>= \case "accepted" -> return Accepted "blocked" -> return Blocked "pending" -> return Pending @@ -257,21 +231,6 @@ instance ToByteString Relation where Cancelled -> "cancelled" MissingLegalholdConsent -> "missing-legalhold-consent" --------------------------------------------------------------------------------- --- Message - --- | Initial message sent along with a connection request. 1-256 characters. --- --- /Note 2019-03-28:/ some clients send it, but we have hidden it anyway in the UI since it --- works as a nice source of spam. TODO deprecate and remove. -newtype Message = Message {messageText :: Text} - deriving stock (Eq, Ord, Show, Generic) - deriving newtype (ToJSON) - deriving (Arbitrary) via (Ranged 1 256 Text) - -instance FromJSON Message where - parseJSON x = Message . fromRange <$> (parseJSON x :: Parser (Range 1 256 Text)) - -------------------------------------------------------------------------------- -- Requests @@ -280,61 +239,36 @@ data ConnectionRequest = ConnectionRequest { -- | Connection recipient crUser :: UserId, -- | Name of the conversation to be created - crName :: Text, - -- | Initial message - crMessage :: Message + -- FUTUREWORK investigate: shouldn't this name be optional? Do we use this name actually anywhere? + crName :: Range 1 256 Text } deriving stock (Eq, Show, Generic) + deriving (Arbitrary) via (GenericUniform ConnectionRequest) + deriving (FromJSON, ToJSON, S.ToSchema) via (P.Schema ConnectionRequest) -modelConnectionRequest :: Doc.Model -modelConnectionRequest = Doc.defineModel "ConnectionRequest" $ do - Doc.description "Connection request from one user to another" - Doc.property "user" Doc.bytes' $ - Doc.description "User ID of the user to request a connection with" - Doc.property "name" Doc.string' $ - Doc.description "Name of the (pending) conversation being initiated (1 - 256 characters)." - Doc.property "message" Doc.string' $ - Doc.description "The initial message in the request (1 - 256 characters)." - -instance ToJSON ConnectionRequest where - toJSON c = - object - [ "user" .= crUser c, - "name" .= crName c, - "message" .= crMessage c - ] - -instance FromJSON ConnectionRequest where - parseJSON = withObject "connection-request" $ \o -> - ConnectionRequest - <$> o .: "user" - <*> (fromRange <$> ((o .: "name") :: Parser (Range 1 256 Text))) - <*> o .: "message" - --- | TODO: make 'crName :: Range 1 256 Text' and derive this instance. -instance Arbitrary ConnectionRequest where - arbitrary = - ConnectionRequest - <$> arbitrary - <*> (fromRange <$> arbitrary @(Range 1 256 Text)) - <*> arbitrary +instance P.ToSchema ConnectionRequest where + schema = + P.object "ConnectionRequest" $ + ConnectionRequest + <$> crUser P..= P.fieldWithDocModifier "user" (P.description ?~ "user ID of the user to request a connection with") P.schema + <*> crName P..= P.fieldWithDocModifier "name" (P.description ?~ "Name of the (pending) conversation being initiated (1 - 256) characters)") P.schema -- | Payload type for "please change the status of this connection". -data ConnectionUpdate = ConnectionUpdate +newtype ConnectionUpdate = ConnectionUpdate { cuStatus :: Relation } deriving stock (Eq, Show, Generic) deriving (Arbitrary) via (GenericUniform ConnectionUpdate) + deriving (FromJSON, ToJSON, S.ToSchema) via (P.Schema ConnectionUpdate) + +instance P.ToSchema ConnectionUpdate where + schema = + P.object "ConnectionUpdate" $ + ConnectionUpdate + <$> cuStatus P..= P.fieldWithDocModifier "status" (P.description ?~ "New relation status") P.schema modelConnectionUpdate :: Doc.Model modelConnectionUpdate = Doc.defineModel "ConnectionUpdate" $ do Doc.description "Connection update" Doc.property "status" typeRelation $ Doc.description "New relation status" - -instance ToJSON ConnectionUpdate where - toJSON c = object ["status" .= cuStatus c] - -instance FromJSON ConnectionUpdate where - parseJSON = withObject "connection-update" $ \o -> - ConnectionUpdate <$> o .: "status" diff --git a/libs/wire-api/src/Wire/API/Conversation.hs b/libs/wire-api/src/Wire/API/Conversation.hs index 9cc597a4794..36a397eb65f 100644 --- a/libs/wire-api/src/Wire/API/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Conversation.hs @@ -757,7 +757,7 @@ newtype ConversationRename = ConversationRename } deriving stock (Eq, Show) deriving newtype (Arbitrary) - deriving (ToJSON, FromJSON) via Schema ConversationRename + deriving (S.ToSchema, ToJSON, FromJSON) via Schema ConversationRename instance ToSchema ConversationRename where schema = diff --git a/libs/wire-api/src/Wire/API/Conversation/Member.hs b/libs/wire-api/src/Wire/API/Conversation/Member.hs index 246b5bb5e0f..d2bcc02db7e 100644 --- a/libs/wire-api/src/Wire/API/Conversation/Member.hs +++ b/libs/wire-api/src/Wire/API/Conversation/Member.hs @@ -94,8 +94,6 @@ modelConversationMembers = Doc.defineModel "ConversationMembers" $ do data Member = Member { memId :: UserId, memService :: Maybe ServiceRef, - -- | DEPRECATED, remove it once enough clients use `memOtrMutedStatus` - memOtrMuted :: Bool, memOtrMutedStatus :: Maybe MutedStatus, memOtrMutedRef :: Maybe Text, memOtrArchived :: Bool, @@ -124,7 +122,6 @@ instance ToSchema Member where (c ("1970-01-01T00:00:00.000Z" :: Text)) ) -- ... until here - <*> memOtrMuted .= (field "otr_muted" schema <|> pure False) <*> memOtrMutedStatus .= lax (field "otr_muted_status" (optWithDefault A.Null schema)) <*> memOtrMutedRef .= lax (field "otr_muted_ref" (optWithDefault A.Null schema)) <*> memOtrArchived .= (field "otr_archived" schema <|> pure False) @@ -140,9 +137,6 @@ modelMember :: Doc.Model modelMember = Doc.defineModel "Member" $ do Doc.property "id" Doc.bytes' $ Doc.description "User ID" - Doc.property "otr_muted" Doc.bool' $ do - Doc.description "Whether the conversation is muted" - Doc.optional Doc.property "otr_muted_ref" Doc.bytes' $ do Doc.description "A reference point for (un)muting" Doc.optional @@ -207,27 +201,22 @@ modelOtherMember = Doc.defineModel "OtherMember" $ do -- | Inbound self member updates. This is what galley expects on its endpoint. See also -- 'MemberUpdateData' - that event is meant to be sent only to the _self_ user. data MemberUpdate = MemberUpdate - { mupOtrMute :: Maybe Bool, - mupOtrMuteStatus :: Maybe MutedStatus, + { mupOtrMuteStatus :: Maybe MutedStatus, mupOtrMuteRef :: Maybe Text, mupOtrArchive :: Maybe Bool, mupOtrArchiveRef :: Maybe Text, mupHidden :: Maybe Bool, - mupHiddenRef :: Maybe Text, - mupConvRoleName :: Maybe RoleName + mupHiddenRef :: Maybe Text } deriving stock (Eq, Show, Generic) deriving (FromJSON, ToJSON, S.ToSchema) via Schema MemberUpdate memberUpdate :: MemberUpdate -memberUpdate = MemberUpdate Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing +memberUpdate = MemberUpdate Nothing Nothing Nothing Nothing Nothing Nothing modelMemberUpdate :: Doc.Model modelMemberUpdate = Doc.defineModel "MemberUpdate" $ do Doc.description "Update user properties relative to a conversation" - Doc.property "otr_muted" Doc.bool' $ do - Doc.description "Whether to notify on conversation updates" - Doc.optional Doc.property "otr_muted_ref" Doc.bytes' $ do Doc.description "A reference point for (un)muting" Doc.optional @@ -243,23 +232,18 @@ modelMemberUpdate = Doc.defineModel "MemberUpdate" $ do Doc.property "hidden_ref" Doc.bytes' $ do Doc.description "A reference point for (un)hiding" Doc.optional - Doc.property "conversation_role" Doc.string' $ do - Doc.description "Name of the conversation role to update to" - Doc.optional instance ToSchema MemberUpdate where schema = (`withParser` (either fail pure . validateMemberUpdate)) . object "MemberUpdate" $ MemberUpdate - <$> mupOtrMute .= opt (field "otr_muted" schema) - <*> mupOtrMuteStatus .= opt (field "otr_muted_status" schema) + <$> mupOtrMuteStatus .= opt (field "otr_muted_status" schema) <*> mupOtrMuteRef .= opt (field "otr_muted_ref" schema) <*> mupOtrArchive .= opt (field "otr_archived" schema) <*> mupOtrArchiveRef .= opt (field "otr_archived_ref" schema) <*> mupHidden .= opt (field "hidden" schema) <*> mupHiddenRef .= opt (field "hidden_ref" schema) - <*> mupConvRoleName .= opt (field "conversation_role" schema) instance Arbitrary MemberUpdate where arbitrary = @@ -268,23 +252,21 @@ instance Arbitrary MemberUpdate where validateMemberUpdate :: MemberUpdate -> Either String MemberUpdate validateMemberUpdate u = - if ( isJust (mupOtrMute u) - || isJust (mupOtrMuteStatus u) + if ( isJust (mupOtrMuteStatus u) || isJust (mupOtrMuteRef u) || isJust (mupOtrArchive u) || isJust (mupOtrArchiveRef u) || isJust (mupHidden u) || isJust (mupHiddenRef u) - || isJust (mupConvRoleName u) ) then Right u else Left - "One of { \'otr_muted', 'otr_muted_ref', 'otr_archived', \ - \'otr_archived_ref', 'hidden', 'hidden_ref', 'conversation_role'} required." + "One of { 'otr_muted_ref', 'otr_archived', 'otr_archived_ref', \ + \'hidden', 'hidden_ref', 'conversation_role'} required." -- | Inbound other member updates. This is what galley expects on its endpoint. See also --- 'OtherMemberUpdateData' - that event is meant to be sent to all users in a conversation. +-- 'MemberUpdateData' - that event is meant to be sent to all users in a conversation. data OtherMemberUpdate = OtherMemberUpdate { omuConvRoleName :: Maybe RoleName } diff --git a/libs/wire-api/src/Wire/API/ErrorDescription.hs b/libs/wire-api/src/Wire/API/ErrorDescription.hs index f484f73a59c..d9c0def1b3a 100644 --- a/libs/wire-api/src/Wire/API/ErrorDescription.hs +++ b/libs/wire-api/src/Wire/API/ErrorDescription.hs @@ -221,6 +221,21 @@ type NotConnected = ErrorDescription 403 "not-connected" "Users are not connecte notConnected :: NotConnected notConnected = mkErrorDescription +type ConnectionLimitReached = ErrorDescription 403 "connection-limit" "Too many sent/accepted connections." + +connectionLimitReached :: ConnectionLimitReached +connectionLimitReached = mkErrorDescription + +type InvalidUser = ErrorDescription 400 "invalid-user" "Invalid user." + +invalidUser :: InvalidUser +invalidUser = mkErrorDescription + +type NoIdentity = ErrorDescription 403 "no-identity" "The user has no verified identity (email or phone number)." + +noIdentity :: forall code lbl desc. (NoIdentity ~ ErrorDescription code lbl desc) => Int -> NoIdentity +noIdentity n = ErrorDescription (Text.pack (symbolVal (Proxy @desc)) <> " (code " <> Text.pack (show n) <> ")") + type OperationDenied = ErrorDescription 403 "operation-denied" "Insufficient permissions" operationDenied :: Show perm => perm -> OperationDenied diff --git a/libs/wire-api/src/Wire/API/Event/Conversation.hs b/libs/wire-api/src/Wire/API/Event/Conversation.hs index d9438e4051e..b83bf2d955d 100644 --- a/libs/wire-api/src/Wire/API/Event/Conversation.hs +++ b/libs/wire-api/src/Wire/API/Event/Conversation.hs @@ -337,6 +337,9 @@ instance ToSchema SimpleMember where data Connect = Connect { cRecipient :: UserId, + -- FUTUREWORK: As a follow-up from + -- https://github.com/wireapp/wire-server/pull/1726, the message field can + -- be removed from this event. cMessage :: Maybe Text, cName :: Maybe Text, cEmail :: Maybe Text @@ -381,7 +384,6 @@ data MemberUpdateData = MemberUpdateData -- out there do not contain an ID. -- misTarget :: Maybe UserId, - misOtrMuted :: Maybe Bool, misOtrMutedStatus :: Maybe MutedStatus, misOtrMutedRef :: Maybe Text, misOtrArchived :: Maybe Bool, @@ -401,7 +403,6 @@ memberUpdateDataObjectSchema :: ObjectSchema SwaggerDoc MemberUpdateData memberUpdateDataObjectSchema = MemberUpdateData <$> misTarget .= opt (field "target" schema) - <*> misOtrMuted .= opt (field "otr_muted" schema) <*> misOtrMutedStatus .= opt (field "otr_muted_status" schema) <*> misOtrMutedRef .= opt (field "otr_muted_ref" schema) <*> misOtrArchived .= opt (field "otr_archived" schema) @@ -416,9 +417,6 @@ modelMemberUpdateData = Doc.defineModel "MemberUpdateData" $ do Doc.property "target" Doc.bytes' $ do Doc.description "Target ID of the user that the action was performed on" Doc.optional - Doc.property "otr_muted" Doc.bool' $ do - Doc.description "Whether to notify on conversation updates" - Doc.optional Doc.property "otr_muted_ref" Doc.bytes' $ do Doc.description "A reference point for (un)muting" Doc.optional diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs index 933362d46e7..b31097c67a3 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Brig.hs @@ -33,17 +33,11 @@ import Servant hiding (Handler, JSON, addHeader, respond) import Servant.API.Generic import Servant.Swagger (HasSwagger (toSwagger)) import Servant.Swagger.Internal.Orphans () +import Wire.API.Connection import Wire.API.ErrorDescription - ( CanThrow, - EmptyErrorForLegacyReasons, - HandleNotFound, - MalformedPrekeys, - MissingAuth, - TooManyClients, - UserNotFound, - ) import Wire.API.Routes.MultiVerb import Wire.API.Routes.Public (ZConn, ZUser) +import Wire.API.Routes.Public.Util import Wire.API.Routes.QualifiedCapture import Wire.API.User import Wire.API.User.Client @@ -309,6 +303,34 @@ data Api routes = Api :> CaptureClientId "client" :> "prekeys" :> Get '[JSON] [PrekeyId], + -- + -- This endpoint can lead to the following events being sent: + -- - ConnectionUpdated event to self and other, if any side's connection state changes + -- - MemberJoin event to self and other, if joining an existing connect conversation (via galley) + -- - ConvCreate event to self, if creating a connect conversation (via galley) + -- - ConvConnect event to self, in some cases (via galley), + -- for details see 'Galley.API.Create.createConnectConversation' + -- + createConnection :: + routes :- Summary "Create a connection to another user." + :> CanThrow MissingLegalholdConsent + :> CanThrow InvalidUser + :> CanThrow ConnectionLimitReached + :> CanThrow NoIdentity + -- Config value 'setUserMaxConnections' value in production/by default + -- is currently 1000 and has not changed in the last few years. + -- While it would be more correct to use the config value here, that + -- might not be time well spent. + :> Description "You can have no more than 1000 connections in accepted or sent state" + :> ZUser + :> ZConn + :> "connections" + :> ReqBody '[JSON] ConnectionRequest + :> MultiVerb + 'POST + '[JSON] + (ResponsesForExistedCreated "Connection existed" "Connection was created" UserConnection) + (ResponseForExistedCreated UserConnection), searchContacts :: routes :- Summary "Search for users" :> ZUser diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs b/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs index 3e8fa9921b1..3ded88e7732 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Galley.hs @@ -33,40 +33,26 @@ import Servant import Servant.API.Generic (ToServantApi, (:-)) import Servant.Swagger.Internal import Servant.Swagger.Internal.Orphans () -import Wire.API.Conversation as Public -import qualified Wire.API.Conversation.Role as Public +import Wire.API.Conversation +import Wire.API.Conversation.Role import Wire.API.ErrorDescription -import qualified Wire.API.Event.Conversation as Public +import Wire.API.Event.Conversation import Wire.API.Message import Wire.API.Routes.MultiVerb import Wire.API.Routes.Public (ZConn, ZUser) import Wire.API.Routes.Public.Galley.Responses +import Wire.API.Routes.Public.Util import Wire.API.Routes.QualifiedCapture import Wire.API.ServantProto (Proto, RawProto) -import qualified Wire.API.Team.Conversation as Public +import Wire.API.Team.Conversation import Wire.API.Team.Feature instance AsHeaders '[Header "Location" ConvId] Conversation Conversation where -- FUTUREWORK: use addHeader - toHeaders c = Headers c (HCons (Header (qUnqualified (Public.cnvQualifiedId c))) HNil) + toHeaders c = Headers c (HCons (Header (qUnqualified (cnvQualifiedId c))) HNil) fromHeaders = getResponse -instance - (ResponseType r1 ~ a, ResponseType r2 ~ a) => - AsUnion '[r1, r2] (ConversationResponseFor a) - where - toUnion (ConversationExisted x) = Z (I x) - toUnion (ConversationCreated x) = S (Z (I x)) - - fromUnion (Z (I x)) = ConversationExisted x - fromUnion (S (Z (I x))) = ConversationCreated x - fromUnion (S (S x)) = case x of - -data ConversationResponseFor a - = ConversationExisted !a - | ConversationCreated !a - -type ConversationResponse = ConversationResponseFor Conversation +type ConversationResponse = ResponseForExistedCreated Conversation type ConversationHeaders = '[DescHeader "Location" "Conversation ID" ConvId] @@ -87,12 +73,12 @@ type ConversationVerb = type UpdateResponses = '[ RespondEmpty 204 "Conversation unchanged", - Respond 200 "Conversation updated" Public.Event + Respond 200 "Conversation updated" Event ] data UpdateResult = Unchanged - | Updated Public.Event + | Updated Event instance AsUnion UpdateResponses UpdateResult where toUnion Unchanged = inject (I ()) @@ -111,14 +97,14 @@ data Api routes = Api :> ZUser :> "conversations" :> Capture "cnv" ConvId - :> Get '[Servant.JSON] Public.Conversation, + :> Get '[Servant.JSON] Conversation, getConversation :: routes :- Summary "Get a conversation by ID" :> ZUser :> "conversations" :> QualifiedCapture "cnv" ConvId - :> Get '[Servant.JSON] Public.Conversation, + :> Get '[Servant.JSON] Conversation, getConversationRoles :: routes :- Summary "Get existing roles available for the given conversation" @@ -126,7 +112,7 @@ data Api routes = Api :> "conversations" :> Capture "cnv" ConvId :> "roles" - :> Get '[Servant.JSON] Public.ConversationRolesList, + :> Get '[Servant.JSON] ConversationRolesList, listConversationIdsUnqualified :: routes :- Summary "[deprecated] Get all local conversation IDs." @@ -148,7 +134,7 @@ data Api routes = Api ] "size" (Range 1 1000 Int32) - :> Get '[Servant.JSON] (Public.ConversationList ConvId), + :> Get '[Servant.JSON] (ConversationList ConvId), listConversationIds :: routes :- Summary "Get all conversation IDs." @@ -156,8 +142,8 @@ data Api routes = Api :> ZUser :> "conversations" :> "list-ids" - :> ReqBody '[Servant.JSON] Public.GetPaginatedConversationIds - :> Post '[Servant.JSON] Public.ConvIdsPage, + :> ReqBody '[Servant.JSON] GetPaginatedConversationIds + :> Post '[Servant.JSON] ConvIdsPage, getConversations :: routes :- Summary "Get all *local* conversations." @@ -185,7 +171,7 @@ data Api routes = Api ] "size" (Range 1 500 Int32) - :> Get '[Servant.JSON] (Public.ConversationList Public.Conversation), + :> Get '[Servant.JSON] (ConversationList Conversation), listConversations :: routes :- Summary "[deprecated] Get all conversations (also returns remote conversations)" @@ -196,8 +182,8 @@ data Api routes = Api \**NOTE** This endpoint will soon be removed." :> ZUser :> "list-conversations" - :> ReqBody '[Servant.JSON] Public.ListConversations - :> Post '[Servant.JSON] (Public.ConversationList Public.Conversation), + :> ReqBody '[Servant.JSON] ListConversations + :> Post '[Servant.JSON] (ConversationList Conversation), listConversationsV2 :: routes :- Summary "Get conversation metadata for a list of conversation ids" @@ -205,8 +191,8 @@ data Api routes = Api :> "conversations" :> "list" :> "v2" - :> ReqBody '[Servant.JSON] Public.ListConversationsV2 - :> Post '[Servant.JSON] Public.ConversationsResponse, + :> ReqBody '[Servant.JSON] ListConversationsV2 + :> Post '[Servant.JSON] ConversationsResponse, -- This endpoint can lead to the following events being sent: -- - ConvCreate event to members getConversationByReusableCode :: @@ -221,7 +207,7 @@ data Api routes = Api :> "join" :> QueryParam' [Required, Strict] "key" Code.Key :> QueryParam' [Required, Strict] "code" Code.Value - :> Get '[Servant.JSON] Public.ConversationCoverView, + :> Get '[Servant.JSON] ConversationCoverView, createGroupConversation :: routes :- Summary "Create a new conversation" @@ -232,7 +218,7 @@ data Api routes = Api :> ZUser :> ZConn :> "conversations" - :> ReqBody '[Servant.JSON] Public.NewConvUnmanaged + :> ReqBody '[Servant.JSON] NewConvUnmanaged :> ConversationVerb, createSelfConversation :: routes @@ -251,7 +237,7 @@ data Api routes = Api :> ZConn :> "conversations" :> "one2one" - :> ReqBody '[Servant.JSON] Public.NewConvUnmanaged + :> ReqBody '[Servant.JSON] NewConvUnmanaged :> ConversationVerb, addMembersToConversationV2 :: routes @@ -262,7 +248,7 @@ data Api routes = Api :> Capture "cnv" ConvId :> "members" :> "v2" - :> ReqBody '[Servant.JSON] Public.InviteQualified + :> ReqBody '[Servant.JSON] InviteQualified :> MultiVerb 'POST '[Servant.JSON] UpdateResponses UpdateResult, -- This endpoint can lead to the following events being sent: -- - MemberLeave event to members @@ -296,6 +282,99 @@ data Api routes = Api '[JSON] RemoveFromConversationHTTPResponse RemoveFromConversationResponse, + -- This endpoint can lead to the following events being sent: + -- - ConvRename event to members + updateConversationNameDeprecated :: + routes + :- Summary "Update conversation name (deprecated)" + :> Description "Use `/conversations/:domain/:conv/name` instead." + :> ZUser + :> ZConn + :> "conversations" + :> Capture' '[Description "Conversation ID"] "cnv" ConvId + :> ReqBody '[JSON] ConversationRename + :> MultiVerb + 'PUT + '[JSON] + [ ConvNotFound, + Respond 200 "Conversation updated" Event + ] + (Maybe Event), + updateConversationNameUnqualified :: + routes + :- Summary "Update conversation name (deprecated)" + :> Description "Use `/conversations/:domain/:conv/name` instead." + :> ZUser + :> ZConn + :> "conversations" + :> Capture' '[Description "Conversation ID"] "cnv" ConvId + :> "name" + :> ReqBody '[JSON] ConversationRename + :> MultiVerb + 'PUT + '[JSON] + [ ConvNotFound, + Respond 200 "Conversation updated" Event + ] + (Maybe Event), + updateConversationName :: + routes + :- Summary "Update conversation name" + :> ZUser + :> ZConn + :> "conversations" + :> QualifiedCapture' '[Description "Conversation ID"] "cnv" ConvId + :> "name" + :> ReqBody '[JSON] ConversationRename + :> MultiVerb + 'PUT + '[JSON] + [ ConvNotFound, + Respond 200 "Conversation updated" Event + ] + (Maybe Event), + getConversationSelfUnqualified :: + routes + :- Summary "Get self membership properties (deprecated)" + :> ZUser + :> "conversations" + :> Capture' '[Description "Conversation ID"] "cnv" ConvId + :> "self" + :> Get '[JSON] (Maybe Member), + updateConversationSelfUnqualified :: + routes + :- Summary "Update self membership properties (deprecated)" + :> Description "Use `/conversations/:domain/:conv/self` instead." + :> CanThrow ConvNotFound + :> CanThrow ConvAccessDenied + :> ZUser + :> ZConn + :> "conversations" + :> Capture' '[Description "Conversation ID"] "cnv" ConvId + :> "self" + :> ReqBody '[JSON] MemberUpdate + :> MultiVerb + 'PUT + '[JSON] + '[RespondEmpty 200 "Update successful"] + (), + updateConversationSelf :: + routes + :- Summary "Update self membership properties" + :> Description "**Note**: at least one field has to be provided." + :> CanThrow ConvNotFound + :> CanThrow ConvAccessDenied + :> ZUser + :> ZConn + :> "conversations" + :> QualifiedCapture' '[Description "Conversation ID"] "cnv" ConvId + :> "self" + :> ReqBody '[JSON] MemberUpdate + :> MultiVerb + 'PUT + '[JSON] + '[RespondEmpty 200 "Update successful"] + (), -- Team Conversations getTeamConversationRoles :: @@ -307,7 +386,7 @@ data Api routes = Api :> Capture "tid" TeamId :> "conversations" :> "roles" - :> Get '[Servant.JSON] Public.ConversationRolesList, + :> Get '[Servant.JSON] ConversationRolesList, getTeamConversations :: routes :- Summary "Get team conversations" @@ -316,7 +395,7 @@ data Api routes = Api :> "teams" :> Capture "tid" TeamId :> "conversations" - :> Get '[Servant.JSON] Public.TeamConversationList, + :> Get '[Servant.JSON] TeamConversationList, getTeamConversation :: routes :- Summary "Get one team conversation" @@ -326,7 +405,7 @@ data Api routes = Api :> Capture "tid" TeamId :> "conversations" :> Capture "cid" ConvId - :> Get '[Servant.JSON] Public.TeamConversation, + :> Get '[Servant.JSON] TeamConversation, deleteTeamConversation :: routes :- Summary "Remove a team conversation" diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs index ad54f2aa87b..5492a0be769 100644 --- a/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs +++ b/libs/wire-api/src/Wire/API/Routes/Public/Spar.hs @@ -53,8 +53,10 @@ type API = type APISSO = "metadata" :> SAML.APIMeta + :<|> "metadata" :> Capture "team" TeamId :> SAML.APIMeta :<|> "initiate-login" :> APIAuthReqPrecheck :<|> "initiate-login" :> APIAuthReq + :<|> APIAuthRespLegacy :<|> APIAuthResp :<|> "settings" :> SsoSettingsGet @@ -131,8 +133,16 @@ data DoInitiate = DoInitiateLogin | DoInitiateBind type WithSetBindCookie = Headers '[Servant.Header "Set-Cookie" SetBindCookie] +type APIAuthRespLegacy = + "finalize-login" + :> Header "Cookie" ST + -- (SAML.APIAuthResp from here on, except for response) + :> MultipartForm Mem SAML.AuthnResponseBody + :> Post '[PlainText] Void + type APIAuthResp = "finalize-login" + :> Capture "team" TeamId :> Header "Cookie" ST -- (SAML.APIAuthResp from here on, except for response) :> MultipartForm Mem SAML.AuthnResponseBody @@ -156,6 +166,7 @@ type IdpGetAll = Get '[JSON] IdPList type IdpCreate = ReqBodyCustomError '[RawXML, JSON] "wai-error" IdPMetadataInfo :> QueryParam' '[Optional, Strict] "replaces" SAML.IdPId + :> QueryParam' '[Optional, Strict] "api-version" WireIdPAPIVersion :> PostCreated '[JSON] IdP type IdpUpdate = @@ -176,11 +187,17 @@ type APIINTERNAL = :<|> "teams" :> Capture "team" TeamId :> DeleteNoContent :<|> "sso" :> "settings" :> ReqBody '[JSON] SsoSettings :> Put '[JSON] NoContent -sparSPIssuer :: SAML.HasConfig m => m SAML.Issuer -sparSPIssuer = SAML.Issuer <$> SAML.getSsoURI (Proxy @APISSO) (Proxy @APIAuthResp) - -sparResponseURI :: SAML.HasConfig m => m URI.URI -sparResponseURI = SAML.getSsoURI (Proxy @APISSO) (Proxy @APIAuthResp) +sparSPIssuer :: SAML.HasConfig m => Maybe TeamId -> m SAML.Issuer +sparSPIssuer Nothing = + SAML.Issuer <$> SAML.getSsoURI (Proxy @APISSO) (Proxy @APIAuthRespLegacy) +sparSPIssuer (Just tid) = + SAML.Issuer <$> SAML.getSsoURI' (Proxy @APISSO) (Proxy @APIAuthResp) tid + +sparResponseURI :: SAML.HasConfig m => Maybe TeamId -> m URI.URI +sparResponseURI Nothing = + SAML.getSsoURI (Proxy @APISSO) (Proxy @APIAuthRespLegacy) +sparResponseURI (Just tid) = + SAML.getSsoURI' (Proxy @APISSO) (Proxy @APIAuthResp) tid -- SCIM diff --git a/libs/wire-api/src/Wire/API/Routes/Public/Util.hs b/libs/wire-api/src/Wire/API/Routes/Public/Util.hs new file mode 100644 index 00000000000..e3efc84ba12 --- /dev/null +++ b/libs/wire-api/src/Wire/API/Routes/Public/Util.hs @@ -0,0 +1,48 @@ +{-# LANGUAGE DerivingVia #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2021 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + +module Wire.API.Routes.Public.Util where + +import Data.SOP (I (..), NS (..)) +import Servant.Swagger.Internal.Orphans () +import Wire.API.Routes.MultiVerb + +instance + (ResponseType r1 ~ a, ResponseType r2 ~ a) => + AsUnion '[r1, r2] (ResponseForExistedCreated a) + where + toUnion (Existed x) = Z (I x) + toUnion (Created x) = S (Z (I x)) + + fromUnion (Z (I x)) = Existed x + fromUnion (S (Z (I x))) = Created x + fromUnion (S (S x)) = case x of + +-- Note: order is important here; if you swap Existed with Created, the wrong +-- status codes will be returned. Keep the Order in ResponseForExistedCreated +-- and the corresponding type the same. +data ResponseForExistedCreated a + = Existed !a + | Created !a + +type ResponsesForExistedCreated eDesc cDesc a = + '[ Respond 200 eDesc a, + Respond 201 cDesc a + ] diff --git a/libs/wire-api/src/Wire/API/Swagger.hs b/libs/wire-api/src/Wire/API/Swagger.hs index 2d3989b03a3..3777e1d3544 100644 --- a/libs/wire-api/src/Wire/API/Swagger.hs +++ b/libs/wire-api/src/Wire/API/Swagger.hs @@ -57,7 +57,6 @@ models = Call.Config.modelRtcIceServer, Connection.modelConnectionList, Connection.modelConnection, - Connection.modelConnectionRequest, Connection.modelConnectionUpdate, Conversation.modelConversation, Conversation.modelConversations, diff --git a/libs/wire-api/src/Wire/API/User.hs b/libs/wire-api/src/Wire/API/User.hs index 24758723fe0..ffef5aa6762 100644 --- a/libs/wire-api/src/Wire/API/User.hs +++ b/libs/wire-api/src/Wire/API/User.hs @@ -101,6 +101,7 @@ import Control.Lens (over, view, (.~), (?~)) import Data.Aeson (FromJSON (..), ToJSON (..)) import qualified Data.Aeson.Types as A import Data.ByteString.Conversion +import qualified Data.CaseInsensitive as CI import qualified Data.Code as Code import qualified Data.Currency as Currency import Data.Domain (Domain (Domain)) @@ -413,7 +414,10 @@ userSCIMExternalId usr = userSSOId >=> ssoIdExtId $ usr ssoIdExtId :: UserSSOId -> Maybe Text ssoIdExtId (UserSSOId _ nameIdXML) = case userManagedBy usr of ManagedByWire -> Nothing - ManagedByScim -> SAML.unsafeShowNameID <$> either (const Nothing) pure (SAML.decodeElem (TL.fromStrict nameIdXML)) + ManagedByScim -> + -- FUTUREWORK: keep the CI value, store the original in the database, but always use + -- the CI value for processing. + CI.original . SAML.unsafeShowNameID <$> either (const Nothing) pure (SAML.decodeElem (TL.fromStrict nameIdXML)) ssoIdExtId (UserScimExternalId extId) = pure extId connectedProfile :: User -> UserLegalHoldStatus -> UserProfile diff --git a/libs/wire-api/src/Wire/API/User/IdentityProvider.hs b/libs/wire-api/src/Wire/API/User/IdentityProvider.hs index 868c59ab6fd..f3d88cfd958 100644 --- a/libs/wire-api/src/Wire/API/User/IdentityProvider.hs +++ b/libs/wire-api/src/Wire/API/User/IdentityProvider.hs @@ -17,10 +17,14 @@ module Wire.API.User.IdentityProvider where +import qualified Cassandra as Cql import Control.Lens (makeLenses, (.~), (?~)) import Control.Monad.Except import Data.Aeson import Data.Aeson.TH +import qualified Data.Attoparsec.ByteString as AP +import qualified Data.Binary.Builder as BSB +import qualified Data.ByteString.Conversion as BSC import Data.HashMap.Strict.InsOrd (InsOrdHashMap) import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap import Data.Id (TeamId) @@ -33,6 +37,7 @@ import SAML2.WebSSO (IdPConfig) import qualified SAML2.WebSSO as SAML import SAML2.WebSSO.Types.TH (deriveJSONOptions) import Servant.API as Servant hiding (MkLink, URI (..)) +import Wire.API.Arbitrary (Arbitrary, GenericUniform (GenericUniform)) import Wire.API.User.Orphans (samlSchemaOptions) -- | The identity provider type used in Spar. @@ -43,6 +48,7 @@ data WireIdP = WireIdP -- | list of issuer names that this idp has replaced, most recent first. this is used -- for finding users that are still stored under the old issuer, see -- 'findUserWithOldIssuer', 'moveUserToNewIssuer'. + _wiApiVersion :: Maybe WireIdPAPIVersion, _wiOldIssuers :: [SAML.Issuer], -- | the issuer that has replaced this one. this is set iff a new issuer is created -- with the @"replaces"@ query parameter, and it is used to decide whether users not @@ -51,10 +57,61 @@ data WireIdP = WireIdP } deriving (Eq, Show, Generic) +data WireIdPAPIVersion + = -- | initial API + WireIdPAPIV1 + | -- | support for different SP entityIDs per team + WireIdPAPIV2 + deriving stock (Eq, Show, Enum, Bounded, Generic) + deriving (Arbitrary) via (GenericUniform WireIdPAPIVersion) + +defWireIdPAPIVersion :: WireIdPAPIVersion +defWireIdPAPIVersion = WireIdPAPIV1 + makeLenses ''WireIdP +deriveJSON deriveJSONOptions ''WireIdPAPIVersion deriveJSON deriveJSONOptions ''WireIdP +instance BSC.ToByteString WireIdPAPIVersion where + builder = + BSB.fromByteString . \case + WireIdPAPIV1 -> "v1" + WireIdPAPIV2 -> "v2" + +instance BSC.FromByteString WireIdPAPIVersion where + parser = + (AP.string "v1" >> pure WireIdPAPIV1) + <|> (AP.string "v2" >> pure WireIdPAPIV2) + +instance FromHttpApiData WireIdPAPIVersion where + parseQueryParam txt = maybe err Right $ BSC.fromByteString' (cs txt) + where + err = Left $ "FromHttpApiData WireIdPAPIVersion: " <> txt + +instance ToHttpApiData WireIdPAPIVersion where + toQueryParam = cs . BSC.toByteString' + +instance ToParamSchema WireIdPAPIVersion where + toParamSchema Proxy = + mempty + { _paramSchemaDefault = Just "v2", + _paramSchemaType = Just SwaggerString, + _paramSchemaEnum = Just (String . toQueryParam <$> [(minBound :: WireIdPAPIVersion) ..]) + } + +instance Cql.Cql WireIdPAPIVersion where + ctype = Cql.Tagged Cql.IntColumn + + toCql WireIdPAPIV1 = Cql.CqlInt 1 + toCql WireIdPAPIV2 = Cql.CqlInt 2 + + fromCql (Cql.CqlInt i) = case i of + 1 -> return WireIdPAPIV1 + 2 -> return WireIdPAPIV2 + n -> Left $ "Unexpected ClientCapability value: " ++ show n + fromCql _ = Left "ClientCapability value: int expected" + -- | A list of 'IdP's, returned by some endpoints. Wrapped into an object to -- allow extensibility later on. data IdPList = IdPList @@ -104,6 +161,9 @@ instance ToJSON IdPMetadataInfo where instance ToSchema IdPList where declareNamedSchema = genericDeclareNamedSchema samlSchemaOptions +instance ToSchema WireIdPAPIVersion where + declareNamedSchema = genericDeclareNamedSchema samlSchemaOptions + instance ToSchema WireIdP where declareNamedSchema = genericDeclareNamedSchema samlSchemaOptions diff --git a/libs/wire-api/src/Wire/API/User/RichInfo.hs b/libs/wire-api/src/Wire/API/User/RichInfo.hs index dfa65cce8e7..a3c176771b9 100644 --- a/libs/wire-api/src/Wire/API/User/RichInfo.hs +++ b/libs/wire-api/src/Wire/API/User/RichInfo.hs @@ -54,6 +54,7 @@ import qualified Data.HashMap.Strict as HashMap import Data.Hashable (Hashable) import Data.List.Extra (nubOrdOn) import qualified Data.Map as Map +import Data.String.Conversions (cs) import qualified Data.Swagger.Build.Api as Doc import qualified Data.Text as Text import Imports @@ -278,8 +279,8 @@ instance FromJSON RichField where instance Arbitrary RichField where arbitrary = RichField - <$> arbitrary - <*> (arbitrary `QC.suchThat` (/= "")) -- This is required because FromJSON calls @normalizeRichInfo@ and roundtrip tests fail + <$> (CI.mk . cs . QC.getPrintableString <$> arbitrary) + <*> (cs . QC.getPrintableString <$> arbitrary `QC.suchThat` (/= QC.PrintableString "")) -- This is required because FromJSON calls @normalizeRichInfo*@ and roundtrip tests fail -------------------------------------------------------------------------------- -- convenience functions diff --git a/libs/wire-api/test/golden/fromJSON/testObject_Conversation_qualifiedId.json b/libs/wire-api/test/golden/fromJSON/testObject_Conversation_qualifiedId.json index 5d4879210c0..b1713e08da4 100644 --- a/libs/wire-api/test/golden/fromJSON/testObject_Conversation_qualifiedId.json +++ b/libs/wire-api/test/golden/fromJSON/testObject_Conversation_qualifiedId.json @@ -26,7 +26,6 @@ "id": "00000000-0000-0000-0000-000100000000", "otr_archived": true, "otr_muted_status": 1, - "otr_muted": true, "otr_archived_ref": "" }, "others": [] diff --git a/libs/wire-api/test/golden/fromJSON/testObject_NewUserPublic_user_1-1.json b/libs/wire-api/test/golden/fromJSON/testObject_NewUserPublic_user_1-1.json new file mode 100644 index 00000000000..1f1c81c450e --- /dev/null +++ b/libs/wire-api/test/golden/fromJSON/testObject_NewUserPublic_user_1-1.json @@ -0,0 +1,32 @@ +{ + "accent_id": 39125, + "assets": [ + { + "key": "", + "size": "complete", + "type": "image" + }, + { + "key": "(󼊊\u001bp󳢼u]'􅄻", + "type": "image" + }, + { + "key": "􁿐f", + "size": "preview", + "type": "image" + } + ], + "email_code": "cfTQLlhl6H6sYloQXsghILggxWoGhM2WGbxjzm0=", + "label": ">>Mp१𤘇9:󺰽􋼒\u0010D1j󾮢􂊠;􄆇󳸪f#]", + "locale": "so", + "managed_by": "wire", + "name": "\\sY4]u󼛸\u0010󺲻\u001c\u0003 \u001f\u0017􄚐dw;}􆃪@𭂿\r8", + "password": "dX󹊒赲󶻎ht𘙏󴰏\u0007>\u0018\u000bO95\u0015\n(𩝙󻞌嶝f]_𪀮\u00002FQbNS=6g󿷼P𢲾􃨫󰧽􅤹M\u001e7\u0016~\u0017m󽎭\u0006\u0001\u000bkgmBp\u0017w悬𩓯f󹼮%Q\u0004𢔶kP|G𥬅\u0017B-\nJWH(8)4$󱠶<7𭨖\u001cI\u0008A\u0010\r?󹀊\u0008\u00085\u0006󶟨d \u00166􍉶G\u0018\u0008\t=qG􃁰 D\u0002vV\tYpg󸋮吝q\n \u0017L􁼛-􏕋\u0013󺃝F7Q􊔜]揃i?\r\u0010\u001b{=􎕻_?e􇢹%\u000eR󱆼\u001b+\u000ef\u0017q:g\\Rk馍𪝞[l\u0015􉜀VK\njwp\u00043TJྏEj\u0002R7d83ON\u0017q獿\u0019𮣜N8\n\u000f󻦼u:GꓻFZ\u001c<\u0015揤7􉖬tH󿳸;hbS{ꮯ\u001csMs󲷒9B4􀷾35c(~CUc󸇪\\V_XD3>Mp१𤘇9:󺰽􋼒\u0010D1j󾮢􂊠;􄆇󳸪f#]", + "locale": "so", + "managed_by": "wire", + "name": "\\sY4]u󼛸\u0010󺲻\u001c\u0003 \u001f\u0017􄚐dw;}􆃪@𭂿\r8", + "password": "dX󹊒赲󶻎ht𘙏󴰏\u0007>\u0018\u000bO95\u0015\n(𩝙󻞌嶝f]_𪀮\u00002FQbNS=6g󿷼P𢲾􃨫󰧽􅤹M\u001e7\u0016~\u0017m󽎭\u0006\u0001\u000bkgmBp\u0017w悬𩓯f󹼮%Q\u0004𢔶kP|G𥬅\u0017B-\nJWH(8)4$󱠶<7𭨖\u001cI\u0008A\u0010\r?󹀊\u0008\u00085\u0006󶟨d \u00166􍉶G\u0018\u0008\t=qG􃁰 D\u0002vV\tYpg󸋮吝q\n \u0017L􁼛-􏕋\u0013󺃝F7Q􊔜]揃i?\r\u0010\u001b{=􎕻_?e􇢹%\u000eR󱆼\u001b+\u000ef\u0017q:g\\Rk馍𪝞[l\u0015􉜀VK\njwp\u00043TJྏEj\u0002R7d83ON\u0017q獿\u0019𮣜N8\n\u000f󻦼u:GꓻFZ\u001c<\u0015揤7􉖬tH󿳸;hbS{ꮯ\u001csMs󲷒9B4􀷾35c(~CUc󸇪\\V_XD3>Mp१𤘇9:󺰽􋼒\u0010D1j󾮢􂊠;􄆇󳸪f#]", + "locale": "so", + "managed_by": "scim", + "name": "\\sY4]u󼛸\u0010󺲻\u001c\u0003 \u001f\u0017􄚐dw;}􆃪@𭂿\r8", + "password": "dX󹊒赲󶻎ht𘙏󴰏\u0007>\u0018\u000bO95\u0015\n(𩝙󻞌嶝f]_𪀮\u00002FQbNS=6g󿷼P𢲾􃨫󰧽􅤹M\u001e7\u0016~\u0017m󽎭\u0006\u0001\u000bkgmBp\u0017w悬𩓯f󹼮%Q\u0004𢔶kP|G𥬅\u0017B-\nJWH(8)4$󱠶<7𭨖\u001cI\u0008A\u0010\r?󹀊\u0008\u00085\u0006󶟨d \u00166􍉶G\u0018\u0008\t=qG􃁰 D\u0002vV\tYpg󸋮吝q\n \u0017L􁼛-􏕋\u0013󺃝F7Q􊔜]揃i?\r\u0010\u001b{=􎕻_?e􇢹%\u000eR󱆼\u001b+\u000ef\u0017q:g\\Rk馍𪝞[l\u0015􉜀VK\njwp\u00043TJྏEj\u0002R7d83ON\u0017q獿\u0019𮣜N8\n\u000f󻦼u:GꓻFZ\u001c<\u0015揤7􉖬tH󿳸;hbS{ꮯ\u001csMs󲷒9B4􀷾35c(~CUc󸇪\\V_XD3}\u00195z𑈣\t>w\u000e󵾱" +} diff --git a/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_5-2.json b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_5-2.json new file mode 100644 index 00000000000..ac23c7729e3 --- /dev/null +++ b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_5-2.json @@ -0,0 +1,5 @@ +{ + "assets": [], + "name": "test name", + "team_code": "RUne0vse27qsm5jxGmL0xQaeuEOqcqr65rU=" +} diff --git a/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-2.json b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-2.json new file mode 100644 index 00000000000..659d11f9261 --- /dev/null +++ b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-2.json @@ -0,0 +1,9 @@ +{ + "assets": [], + "name": "test name", + "sso_id": { + "subject": "thing", + "tenant": "some" + }, + "team_code": "RUne0vse27qsm5jxGmL0xQaeuEOqcqr65rU=" +} diff --git a/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-3.json b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-3.json new file mode 100644 index 00000000000..e122c01ab80 --- /dev/null +++ b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-3.json @@ -0,0 +1,5 @@ +{ + "assets": [], + "name": "test name", + "team_id": "00007b0e-0000-3489-0000-075c00005be7" +} diff --git a/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-4.json b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-4.json new file mode 100644 index 00000000000..c349db320dc --- /dev/null +++ b/libs/wire-api/test/golden/fromJSON/testObject_NewUser_user_6-4.json @@ -0,0 +1,10 @@ +{ + "assets": [], + "invitation_code": "RUne0vse27qsm5jxGmL0xQaeuEOqcqr65rU=", + "name": "test name", + "sso_id": { + "subject": "thing", + "tenant": "some" + }, + "team_id": "00007b0e-0000-3489-0000-075c00005be7" +} diff --git a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_1.json b/libs/wire-api/test/golden/testObject_ConnectionRequest_user_1.json index 548331fcd67..33ce331c173 100644 --- a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_1.json +++ b/libs/wire-api/test/golden/testObject_ConnectionRequest_user_1.json @@ -1,5 +1,4 @@ { - "message": "X[l\u001d}\u0000c𣈚@\u0004b,{\u0002DSZ7\n\u0013\"V󳇉Wox𝌥*᷈q4IO\u001f\u000b]YJ\u0004!􍳘􃛁瑹\u001a:󿄟*b\u001a+4nByz7uF\u0003셇􀨚$𨴺􊰀<;9\u0015*\u0012&\r'*(^>C􄴦LxZ륬\u001b󲇯𨩹zM\u0016𣟧s􄸩i⌧\u000b𨟑􈄬\u0007dO\u000c\u0015l", "name": "$Sz%e泐9湬NfG a\u001a􍥰士\u0000kF\u000eq𘎖W\u0014K\u0010\u0004F1e\u000b\u0004Q1D󶸏𩞈R󰊠\u0008\u0010QNvP!i󿊤A雷\u0011fE􁱥𗜗􉟫+g~r%'J󱵟s\u00139/'󼆮󲫈𓅢w\u001d\u0006ㅘ􇝅<(o􀦬", "user": "00005686-0000-796a-0000-712b00006414" } diff --git a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_2.json b/libs/wire-api/test/golden/testObject_ConnectionRequest_user_2.json index 20cd8230bc9..f65dde6bd72 100644 --- a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_2.json +++ b/libs/wire-api/test/golden/testObject_ConnectionRequest_user_2.json @@ -1,5 +1,4 @@ { - "message": "}k󲊔\u0000𐚺\u0013𣑛T.kjW@󲚕cㅏ􏂲n𝜰0\u0001pH,?^+󷉴8\u0002𤶞b\tF𐊎n\u0003!![\u000b󺐯3󳱌\u0002𝀵\u0015󵸲􅇫I􀻀La𨲸.碅󵰮33a\u0011H󺓶X𡰧𣷖pSyL2\"y\\8ꎴ󿄈@!F\u001cQ\u000c􃜻𦼗\u000e󱘯[!\u000e麪\u0006=uH󴼌㺨\u0003󻋣󰩞B2􃿍𑱃\u0000yy𢝴\u000c\"􌩢鑋!𢓿\u0017󻋟K 舧Z􃄌5.m󰁱n\u001c\u001ds頒JXo[8󸧹􃄙%\u0001}I|>\u00084aG4􍝌􎨳(U􇐍􉿗e4q\u0004\u0006\u0010\"𬺖Q*u|􉸾T}bT\u000ct\u0012UꜮ_Y\u0003􀼶v𗧅􇏆'󲙄.%󿠇v8\u001b;\u000bl>🖋s􂡋􄠈f\"\u0002\u0003𤘍", "name": "垏󿄣a𨪺\u000f$\u001b2&\u0012S<\u0011􊐙o󳜛𑐤U", "user": "00003697-0000-346d-0000-6baf00003034" } diff --git a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_3.json b/libs/wire-api/test/golden/testObject_ConnectionRequest_user_3.json deleted file mode 100644 index 57fafed82e6..00000000000 --- a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_3.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "message": "􉈤󲚥\u0002\u0012\u001aj𩰙X\u001ez[r\u0010꼃L]zl𣦂\u0015", - "name": "e\u001cx膂IBV 5􎑇hWeYpU􃣠(\n딾\tn𨐺󲵽𤜅󴈔\u0007MNk 3V\u000c~𭮩XltD'\u0018𤡶􈖘g\u0015L3S\u0018𣂲􈲎煪莧Y\u0005󼲖T󱖃I𪴏E [\t􌝤!􈟌\u0014\u0011􇕊⃪jn'(cw\u0002\u0013󾔴\n\u0010T%\u0018𩓔`󾘜㸈|iGOZ\u0001R8FC\u00087黼\u001dN*dT#𭕙\\<\u0010?𣓃%\tZC+Ht௸;\u000f􃶕(𤀀H𦬊=P\u000e𧉽\u001buO*\\QM\u000c{r)~E\u000b!k􍴫W}1\u0017[𦿡a󿠏7/LM9𪭩隝pk\u0001>m􂳡1z􉝪\\𐇜𤙷\u001c5􈐣𗲿0\u0007\t󲵭a\u001a󴣽`XY\u001d^𐒩!ၘ\u001b냨Z뼽\u001f\u001a[R>\u001a*\u0012=X󴐝/UE\u0016􅙗𨙾>􊆍>\u0015\",\u0014", - "user": "0000302a-0000-1612-0000-459400001b2a" -} diff --git a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_4.json b/libs/wire-api/test/golden/testObject_ConnectionRequest_user_4.json deleted file mode 100644 index e48c0c38ae6..00000000000 --- a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_4.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "message": "bJiQ􍌐m_\u0013!\u000bD㩄>京'eᘬ]1i㎛\u000fiy𣘃\t🖼)􎣗\u001aD|_慃\nDP\u0011>𨡰<󵛖\u0013\u0011\u001a0:Z1V\u0015\u0010j󴢀r🜼𪌺𠽊DgC&3┩0~󹄛S\u0018z:L\u001b]󽎺%xM󴇏ᙰ\u0019!64%v\u001bsj\u0014Io3$逖SH:N4𭠈Do䋞;|u跢u{&􃣒󰐲\u0014vX󳿒g\"O􋘆%􁷫ᔣ盍􊙯(\u000e\u0017\u0014-^F\u0010\u0013n𪽯𝘴\u0001whiU󵥙l\n􂾆s󽁛\u0010 􄁌􂲛\nu$*P􀲊R5w`𫁰U𣊻_5𥫎G\u0017\u000c~d\u00104", - "name": ".#Y󻇶\u0004D|<.╭\u0007@v󹬯Nn􂗨k󻺱f=M\u0000쀿彸Pd\u0018&s󿙰􆘎b\u001b󳖤G}󿞇\u0015iE\u000c\n|\u0013\t􆃾\u001d騃\u0002R&>∞\n\u0005􋨧8$󲤺G\u0008\u001eYA8.}!k*􌍀𬭮X󲲔^𘓥𫒞󳏋Z􍭬7X\u0002󵺣\"=&Sr^o􇓉`鼬/\n'𓍿8f\n𡅲{", - "user": "00005bd6-0000-77a4-0000-2a3600001251" -} diff --git a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_8.json b/libs/wire-api/test/golden/testObject_ConnectionRequest_user_8.json deleted file mode 100644 index bd1d8f16df0..00000000000 --- a/libs/wire-api/test/golden/testObject_ConnectionRequest_user_8.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "message": "u𗠶:@o\u0005W&\u0004_\u001f{𗗩L󾍽E\u0002䩩&\u0010\u0004󸤴\u0011[\u0007KU_\tC왛G8$doଉ󵹁ZU6\u0000\u001eT{4;mq󰃌󺿘\u001a𒉉\u0012\u0008􀵜|fs7􊢗\u0014\u0018⇊>^,K1l\u0004{t󾟀𩪋W\u00025𞠰rS\u0011i\u001d\u0007\u0004K6𦕔f69lZdw\u000c\n\u0013T𝡭#j\u001ey𥹦7󲱨un𭑯􈚱xa#5D\\\u00114\u0011𮡟􀮵?\u00070>Z𧹓v\u000b", - "name": "󺽑;𣶡W莡%vJ\u0011馶/#\r󵯝mUO𠉙5\u0001È⭝𢐨u\u0008\u0006K4\u0011\u0004`%)3\u0019\u0016\u0010uUqQP-\u0008\u0015╓\u0017\u001d*,1\u0003j󴂰h𩽬:ㇿ𦡀t\u0007\u000cH􋁺\u000b䶌TDxd\u0013\u0000<📅𧬨M7\u0011|C\ttLD􊑌􉐑[\u0007z􃛪y𥄖캹V8󽳄󰟚rRD \u0002𨚚􏙞F\u0010G\u001f{%;\u000buaJ\"\u0010!=D묡\u001b;~w>\u001a_\u0018'𝥶]~􂩛0\u000f󾎥\"\u0016'>\u000f4\u0015㭼\u0017[eFL\u000e%W$𨪓_􃨞]\u00135*>$u𣆅\u0001󶛍\u001d󹂓\u00134\u0008\u000b", - "user": "00001ab1-0000-6eb7-0000-71e900007867" -} diff --git a/libs/wire-api/test/golden/testObject_ConvMembers_user_1.json b/libs/wire-api/test/golden/testObject_ConvMembers_user_1.json index 6670b96e5d8..67711be729a 100644 --- a/libs/wire-api/test/golden/testObject_ConvMembers_user_1.json +++ b/libs/wire-api/test/golden/testObject_ConvMembers_user_1.json @@ -21,7 +21,6 @@ "id": "00000000-0000-0001-0000-000100000001", "otr_archived": true, "otr_archived_ref": "", - "otr_muted": true, "otr_muted_ref": "", "otr_muted_status": null, "service": { diff --git a/libs/wire-api/test/golden/testObject_ConvMembers_user_2.json b/libs/wire-api/test/golden/testObject_ConvMembers_user_2.json index 80eb4d1c716..97ecd589b74 100644 --- a/libs/wire-api/test/golden/testObject_ConvMembers_user_2.json +++ b/libs/wire-api/test/golden/testObject_ConvMembers_user_2.json @@ -7,7 +7,6 @@ "id": "00000000-0000-0000-0000-000000000000", "otr_archived": false, "otr_archived_ref": null, - "otr_muted": false, "otr_muted_ref": "", "otr_muted_status": null, "service": { diff --git a/libs/wire-api/test/golden/testObject_ConversationList_20Conversation_user_1.json b/libs/wire-api/test/golden/testObject_ConversationList_20Conversation_user_1.json index a13add1af1c..326adbbcda0 100644 --- a/libs/wire-api/test/golden/testObject_ConversationList_20Conversation_user_1.json +++ b/libs/wire-api/test/golden/testObject_ConversationList_20Conversation_user_1.json @@ -16,7 +16,6 @@ "id": "00000000-0000-0000-0000-000100000000", "otr_archived": true, "otr_archived_ref": null, - "otr_muted": true, "otr_muted_ref": "", "otr_muted_status": 0, "service": null, diff --git a/libs/wire-api/test/golden/testObject_Conversation_user_1.json b/libs/wire-api/test/golden/testObject_Conversation_user_1.json index 67d5c3ed06d..5ac0de117e1 100644 --- a/libs/wire-api/test/golden/testObject_Conversation_user_1.json +++ b/libs/wire-api/test/golden/testObject_Conversation_user_1.json @@ -14,7 +14,6 @@ "id": "00000001-0000-0001-0000-000100000000", "otr_archived": false, "otr_archived_ref": "", - "otr_muted": true, "otr_muted_ref": null, "otr_muted_status": null, "service": null, diff --git a/libs/wire-api/test/golden/testObject_Conversation_user_2.json b/libs/wire-api/test/golden/testObject_Conversation_user_2.json index 3d7c556f9b6..6b605941104 100644 --- a/libs/wire-api/test/golden/testObject_Conversation_user_2.json +++ b/libs/wire-api/test/golden/testObject_Conversation_user_2.json @@ -41,7 +41,6 @@ "id": "00000000-0000-0001-0000-000100000001", "otr_archived": false, "otr_archived_ref": null, - "otr_muted": true, "otr_muted_ref": null, "otr_muted_status": -1, "service": null, diff --git a/libs/wire-api/test/golden/testObject_ConversationsResponse_1.json b/libs/wire-api/test/golden/testObject_ConversationsResponse_1.json index 205d0782828..f33bf1205ea 100644 --- a/libs/wire-api/test/golden/testObject_ConversationsResponse_1.json +++ b/libs/wire-api/test/golden/testObject_ConversationsResponse_1.json @@ -26,7 +26,6 @@ "id": "00000001-0000-0001-0000-000100000000", "otr_archived": false, "otr_archived_ref": "", - "otr_muted": true, "otr_muted_ref": null, "otr_muted_status": null, "service": null, @@ -74,7 +73,6 @@ "id": "00000000-0000-0001-0000-000100000001", "otr_archived": false, "otr_archived_ref": null, - "otr_muted": true, "otr_muted_ref": null, "otr_muted_status": -1, "service": null, diff --git a/libs/wire-api/test/golden/testObject_Event_user_5.json b/libs/wire-api/test/golden/testObject_Event_user_5.json index 75ee1c2d97d..87eb24b6b8b 100644 --- a/libs/wire-api/test/golden/testObject_Event_user_5.json +++ b/libs/wire-api/test/golden/testObject_Event_user_5.json @@ -5,7 +5,6 @@ "hidden_ref": "\u0008\t\u0018", "otr_archived": false, "otr_archived_ref": "\u0001J", - "otr_muted": false, "otr_muted_ref": "𗋭" }, "from": "00002a12-0000-73e1-0000-71f700002ec9", diff --git a/libs/wire-api/test/golden/testObject_Event_user_8.json b/libs/wire-api/test/golden/testObject_Event_user_8.json index ea54d696e4a..bf7fab73317 100644 --- a/libs/wire-api/test/golden/testObject_Event_user_8.json +++ b/libs/wire-api/test/golden/testObject_Event_user_8.json @@ -34,7 +34,6 @@ "id": "00000001-0000-0000-0000-000000000001", "otr_archived": true, "otr_archived_ref": "", - "otr_muted": false, "otr_muted_ref": "", "otr_muted_status": 0, "service": { diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_1.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_1.json deleted file mode 100644 index 63f3733f538..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_1.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "sh7636.gcg-c", - "id": "00005bed-0000-0771-0000-447a00005b32" - }, - { - "domain": "dw14y-97764r.26en.wa9", - "id": "00005953-0000-2b40-0000-567100002d0c" - }, - { - "domain": "6e-4.ic.paf", - "id": "000012f7-0000-581b-0000-377600006eb9" - }, - { - "domain": "wsy0vskgzy.7zb.u-g-p-58", - "id": "00000c1b-0000-59c0-0000-3ff000001533" - }, - { - "domain": "ug.mph1359u6sttb3w28v-968", - "id": "00002419-0000-37e8-0000-329900001118" - }, - { - "domain": "hgrc.1y.kyvg3", - "id": "00006112-0000-1fd0-0000-5ca500001e6f" - }, - { - "domain": "p.q0h.b", - "id": "00005052-0000-09ec-0000-74d50000574e" - }, - { - "domain": "r376-462.74o6.0zo-z.9w50a2f9jn9.7rto1q7r.t-99", - "id": "00003e30-0000-3f72-0000-23ec000019a0" - }, - { - "domain": "dt-1.76n6.5-1.n.6-ax81lr5.k13tld-9.k.a0-bd-c.s-jt", - "id": "00003ae9-0000-4d95-0000-08f30000606b" - }, - { - "domain": "njz-3741-78-2--36.e0", - "id": "00005051-0000-6a16-0000-6a3c00007a41" - }, - { - "domain": "t335k19.mpv.i31k9.pnks6s", - "id": "000068c0-0000-2fb4-0000-2891000020d3" - }, - { - "domain": "8-9.z3--ga", - "id": "000055b6-0000-236b-0000-52cb00002561" - }, - { - "domain": "ey4.09g.0wqpp01091.i-y.6pufi5-8vp2g8.lg.ad9p2", - "id": "00007189-0000-04f6-0000-318500001872" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_10.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_10.json deleted file mode 100644 index 38c727a0480..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_10.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "k30p.u-q5.z8--9", - "id": "00007b0e-0000-3489-0000-075c00005be7" - }, - { - "domain": "54e.75-24.ycx80-0j9hl", - "id": "00007dd8-0000-45af-0000-23c400001cc9" - }, - { - "domain": "1.b8u6", - "id": "000020c6-0000-0c74-0000-6c0200007917" - }, - { - "domain": "09js-x.q3dh0.400.c", - "id": "00006465-0000-4dfb-0000-011100004ced" - }, - { - "domain": "17845k.kj9juu63k.79j6x3b.x5rzt", - "id": "000069ce-0000-77fd-0000-063b0000215a" - }, - { - "domain": "9h.0.0.fbi7.l32er.b-0", - "id": "0000768e-0000-027e-0000-2630000069c7" - }, - { - "domain": "1.s.z9ykaf5", - "id": "00004eea-0000-4b92-0000-64840000084e" - }, - { - "domain": "37h.w84715.m4", - "id": "0000078f-0000-4f8e-0000-07a20000002b" - }, - { - "domain": "b6.k5g3.3ozcd.2.0.z2-1hj", - "id": "00000757-0000-203e-0000-74ce0000158b" - }, - { - "domain": "b47-0o2.b335", - "id": "00000dbb-0000-7821-0000-7c8500003661" - }, - { - "domain": "87.lo-nc", - "id": "00005695-0000-4799-0000-461d00004c32" - }, - { - "domain": "a5d.z40n", - "id": "00000b19-0000-7cf6-0000-4c1f000040ca" - }, - { - "domain": "ez9.lc-3h8", - "id": "0000302e-0000-6a65-0000-21d90000268a" - }, - { - "domain": "2g-c.h6569.602.j5", - "id": "000032ae-0000-2713-0000-2286000031b4" - }, - { - "domain": "125-x.g6l8", - "id": "00003993-0000-0d94-0000-167f00006327" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_11.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_11.json deleted file mode 100644 index 27e572e47b4..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_11.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "8---v6s64rx1.t.y3d", - "id": "00005ac5-0000-11dd-0000-578100007f21" - }, - { - "domain": "s3j86.r00", - "id": "000056cc-0000-6489-0000-6fbd00001428" - }, - { - "domain": "2q.t", - "id": "00000d55-0000-2626-0000-1be500002927" - }, - { - "domain": "k8.7bk---2es.mbq", - "id": "00001088-0000-489f-0000-73f2000068b8" - }, - { - "domain": "5s9s--1.d8", - "id": "00006310-0000-7d5d-0000-65d20000555c" - }, - { - "domain": "qo.q443.2c-l61-73.8sy269.k30", - "id": "00001592-0000-1b6b-0000-011d00005365" - }, - { - "domain": "n.h6p", - "id": "00005b03-0000-76b4-0000-5311000050f9" - }, - { - "domain": "th-28m.y00", - "id": "00001e66-0000-6c43-0000-3a3d00002e55" - }, - { - "domain": "77uc.v4-ob.ty", - "id": "000062a9-0000-147b-0000-0aa6000034ce" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_12.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_12.json deleted file mode 100644 index 038ac7ee718..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_12.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "5.g", - "id": "00005baf-0000-0b85-0000-5fe6000002bc" - }, - { - "domain": "yw3y.h8.9u1p.n70-8", - "id": "0000215e-0000-0070-0000-1b2e00007d34" - }, - { - "domain": "i1.f7i", - "id": "00002b43-0000-548f-0000-30b800007417" - }, - { - "domain": "231wo62.u296", - "id": "00007bf1-0000-3b3c-0000-23f600006104" - }, - { - "domain": "y6.c7b9pn.dyj.wbj7-jf0-mjw6", - "id": "000074e8-0000-60de-0000-502000007602" - }, - { - "domain": "54.rft", - "id": "00001650-0000-2acc-0000-48cf0000105f" - }, - { - "domain": "1tb4.67sg7.m60x804lm", - "id": "0000144f-0000-2acd-0000-637000002760" - }, - { - "domain": "d-5-5.k", - "id": "00006bc4-0000-5e39-0000-43120000670f" - }, - { - "domain": "9024-r.35.s6.w5", - "id": "000013a1-0000-4d65-0000-1f400000055c" - }, - { - "domain": "2fgsir.iwu", - "id": "00004445-0000-21ae-0000-5bc500003975" - }, - { - "domain": "8ed.ty0tno", - "id": "000063b4-0000-2dbb-0000-60e8000012f1" - }, - { - "domain": "u-6.f8", - "id": "0000469c-0000-4553-0000-625e00002207" - }, - { - "domain": "9x.0.0-8--v.d-93u-7-k.l3104", - "id": "00004ec6-0000-429d-0000-5d5000005a14" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_13.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_13.json deleted file mode 100644 index 7bc72e714ba..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_13.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "ze-e.j2r", - "id": "0000475e-0000-38ec-0000-391400001acc" - }, - { - "domain": "23.jpt063n", - "id": "000043ba-0000-7985-0000-182a0000506e" - }, - { - "domain": "9ha.p80.o1u-1", - "id": "00007e10-0000-7798-0000-624100004f2d" - }, - { - "domain": "tj46.v8.qaqm", - "id": "00006c62-0000-1c79-0000-2b9800006efd" - }, - { - "domain": "n64o9z-br.j15-q.g915i51c.e8194", - "id": "00001698-0000-27fd-0000-7db100003861" - }, - { - "domain": "915-1w.85782-0.a", - "id": "00006cd3-0000-24fd-0000-09f400005ba9" - }, - { - "domain": "487q7.y164on2", - "id": "0000300a-0000-162c-0000-3ee700005878" - }, - { - "domain": "880eu0.y9", - "id": "0000686a-0000-4dc3-0000-5ad200001895" - }, - { - "domain": "3qvah.sx1-2", - "id": "000035d9-0000-1499-0000-7ef40000702d" - }, - { - "domain": "g0-c.t78ob0f", - "id": "00007097-0000-0f45-0000-43ca0000574a" - }, - { - "domain": "d0-j75303.k-e4-946q0.8h5nb-t--w-of.gm7", - "id": "00004643-0000-0913-0000-263d00002ec2" - }, - { - "domain": "d6-fo.y028", - "id": "00002d65-0000-31b9-0000-20df00007924" - }, - { - "domain": "n2q0ano4z3.o111-3v-5", - "id": "000053a0-0000-053e-0000-47c100006543" - }, - { - "domain": "to.7z.39.lb.noxz", - "id": "00004080-0000-0c3e-0000-65b900000a32" - }, - { - "domain": "9-1u.5--2zb.dh-485un.a.b455b", - "id": "00006e11-0000-3fd3-0000-7d660000121a" - }, - { - "domain": "3281.wk55l", - "id": "00000430-0000-2075-0000-4cd500004b77" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_14.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_14.json deleted file mode 100644 index f5bc7f05b95..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_14.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "j-ip-l.7-1v.k95u43z3", - "id": "000042a7-0000-32cb-0000-1b6100007e97" - }, - { - "domain": "1fuok9.6-l.b-t926.171.l-8pfu", - "id": "00004a01-0000-719f-0000-687e000065e8" - }, - { - "domain": "227ot.61z.tr", - "id": "00005d4f-0000-38a9-0000-1d6b00007d93" - }, - { - "domain": "s-0.x1lw1.l940-5-1ip", - "id": "0000173c-0000-1a35-0000-48120000671e" - }, - { - "domain": "48lg-78-mp.j.2g.v6", - "id": "00007329-0000-386b-0000-08c300001a02" - }, - { - "domain": "5.mc.642.z6ezu0n24.5dmb9.p32940g", - "id": "00002714-0000-6ff3-0000-661200005afc" - }, - { - "domain": "y---wl.01w5.j5j72.z--d0", - "id": "00005d7b-0000-42c8-0000-4c2100007901" - }, - { - "domain": "zf-njrau.hnzq", - "id": "000072c5-0000-5e32-0000-24810000445d" - }, - { - "domain": "z0-atdfh7.j", - "id": "00004b43-0000-5516-0000-557400000a48" - }, - { - "domain": "z.i89r", - "id": "000002a1-0000-6666-0000-598f00005906" - }, - { - "domain": "54l.v", - "id": "000063f8-0000-4d4f-0000-18e400005d2e" - }, - { - "domain": "5mway6.a5", - "id": "000005d7-0000-446c-0000-412000003819" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_15.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_15.json deleted file mode 100644 index 7adad4f4c85..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_15.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "f01r.m", - "id": "00000c25-0000-79e0-0000-541600004086" - }, - { - "domain": "58amj.if8", - "id": "000050bc-0000-4f16-0000-21d400005201" - }, - { - "domain": "6.u5vi2.ue.4-2-e.43.nw", - "id": "00002856-0000-4dc3-0000-767200003807" - }, - { - "domain": "k.ii", - "id": "000014a4-0000-3d56-0000-03e3000054d8" - }, - { - "domain": "7688.e9h.95-r--2dbdvt6.j.x9ol.dp6e", - "id": "0000206e-0000-5537-0000-2e0800006b16" - }, - { - "domain": "2ru96lpzoyh7t5u.t9.d-t.re", - "id": "000007a0-0000-18b0-0000-5d9200006699" - }, - { - "domain": "08y.42w-9v-10.ak5---5w", - "id": "00006edc-0000-5d78-0000-652400003edc" - }, - { - "domain": "3.b7po", - "id": "00007e47-0000-6da7-0000-26fd00003b7b" - }, - { - "domain": "6w-5.1xe26.80lg.jw9.mex.oegh0706n", - "id": "00000cee-0000-6ee0-0000-106700007a67" - }, - { - "domain": "j0de1800---s0.9.psqs", - "id": "000021b1-0000-245c-0000-7a9100007085" - }, - { - "domain": "p8coz0-tebsr85f.f.zxk.l-yq-y--y79222", - "id": "00006a1a-0000-6b70-0000-1994000077fa" - }, - { - "domain": "s2.e-dkwb.o.465903al--y.q5gn", - "id": "000018b3-0000-2d82-0000-2bc1000074ae" - }, - { - "domain": "v.62-5.gnk6.i7b", - "id": "00003080-0000-1228-0000-50f500006f76" - }, - { - "domain": "8wd7.n990", - "id": "00000b92-0000-0818-0000-4392000026f4" - }, - { - "domain": "qh-m.1.xgihs80", - "id": "00005589-0000-19ca-0000-24da00003073" - }, - { - "domain": "7q-wi6d-42a-t-j.egp2.9z1h-2-n-0--y.r2fej7.7.v-6.80g0.d4", - "id": "00005238-0000-7ca4-0000-4139000066a8" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_16.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_16.json deleted file mode 100644 index 0b7acce67a2..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_16.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "72086-5g6.n4d6.r", - "id": "00002d40-0000-6639-0000-3e6300005645" - }, - { - "domain": "26mg.x.rw9h.44o22.k54", - "id": "00004351-0000-78e5-0000-22ec0000582e" - }, - { - "domain": "c02dw6e-17.7---ps8.q7-3", - "id": "00000cce-0000-565a-0000-640400007618" - }, - { - "domain": "96i8.z7", - "id": "000003cb-0000-2902-0000-3225000013e2" - }, - { - "domain": "4c86.fto6un", - "id": "00001ecc-0000-0ca4-0000-5be000003aa3" - }, - { - "domain": "38gp7.i73", - "id": "00003ce3-0000-25bb-0000-5dff00007832" - }, - { - "domain": "s7h6-8.ut2", - "id": "00000453-0000-2978-0000-2cbd00001358" - }, - { - "domain": "2kb.9--kl.hyj", - "id": "00000c0a-0000-7937-0000-271000007ae6" - }, - { - "domain": "k3v.q21.8dlz.y4", - "id": "00006d99-0000-163f-0000-179c000076de" - }, - { - "domain": "y-f78.72.aqk6a", - "id": "0000413e-0000-2f3d-0000-5e2f000006cb" - }, - { - "domain": "85-n-v.a-5j", - "id": "00002eb2-0000-74bc-0000-028000006a15" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_17.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_17.json deleted file mode 100644 index e4e6bb5fa1f..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_17.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "m-26n-8248.w-y.q3-p", - "id": "0000307a-0000-5e89-0000-1ac9000011e7" - }, - { - "domain": "h-5-20.g-yd", - "id": "00001b46-0000-45d9-0000-6c53000054b2" - }, - { - "domain": "p9tn1y-0e.f7.k-7-7tp", - "id": "00004013-0000-5a56-0000-27b20000118a" - }, - { - "domain": "u1wvly.x348y848-3f917ae", - "id": "00003bf9-0000-28d3-0000-6f300000431d" - }, - { - "domain": "unw5.u07", - "id": "000017c9-0000-5c6d-0000-30f8000063f5" - }, - { - "domain": "2-r.x", - "id": "0000613c-0000-29c0-0000-49ac00003fea" - }, - { - "domain": "s0--aw-4-e0-3.dm.r0", - "id": "000064f6-0000-74b2-0000-791700002965" - }, - { - "domain": "x5.bm.6-36.o9-v2-4", - "id": "00000d5f-0000-4e9a-0000-400400003da9" - }, - { - "domain": "m-200.hz8-790bfb974", - "id": "000022b3-0000-12ad-0000-3f170000060e" - }, - { - "domain": "3s250z0.2-dd8a0f2.dp89d", - "id": "00000894-0000-41f7-0000-6e0d00002aaf" - }, - { - "domain": "ih.0n0--9--qlk.736.16v.5.8l.9.e", - "id": "00002c22-0000-01fb-0000-02f600005b08" - }, - { - "domain": "9jp0.r.b1.1kex3k7o8-7s.e.4vx.7yhx-y.82pwmd.u5zv5cfv-a435.3.1.i52", - "id": "0000026c-0000-4409-0000-2bc200003589" - }, - { - "domain": "3.n3", - "id": "000041b8-0000-4a59-0000-390b00004250" - }, - { - "domain": "1d4i9.e-8.nc3698q-tp7bu", - "id": "00003caa-0000-4dac-0000-747d0000204a" - }, - { - "domain": "3--7.w", - "id": "00005d7c-0000-1dfa-0000-323f00000e43" - }, - { - "domain": "17.c9", - "id": "00006665-0000-0b5b-0000-31e300000435" - }, - { - "domain": "y4-le9r6.295j-v-3oad.lx64.j6", - "id": "00006671-0000-3602-0000-5064000037f6" - }, - { - "domain": "3---e59---u.1-7b.hl-o.mg.qnm292", - "id": "00000561-0000-7d9b-0000-513a00007677" - }, - { - "domain": "c.dya-8w625yg9", - "id": "00000bdf-0000-6e75-0000-44dd00001d49" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_18.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_18.json deleted file mode 100644 index 991ca118ded..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_18.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "g.n596a.ab.q09g-7--a11", - "id": "00001804-0000-6e5a-0000-4eab000018cc" - }, - { - "domain": "2rt.l5", - "id": "000052b4-0000-3543-0000-486300007862" - }, - { - "domain": "253.n8l-g85", - "id": "000033cf-0000-515d-0000-636300006773" - }, - { - "domain": "h1-r.5l13.6-4.t4z3.so", - "id": "0000649a-0000-6461-0000-639e000000e2" - }, - { - "domain": "5i57.v1-y", - "id": "0000338d-0000-4926-0000-17ad00001921" - }, - { - "domain": "0n-c.e72-yd", - "id": "00003e1a-0000-56ab-0000-597a0000325a" - }, - { - "domain": "xb2717.7pjc.e1", - "id": "00000cb1-0000-12d5-0000-52d700007bd4" - }, - { - "domain": "u6-p.ap", - "id": "00003395-0000-5ba0-0000-057d00004458" - }, - { - "domain": "x13.u2mw.o5i.w--l172t", - "id": "00002ab6-0000-48a8-0000-00b60000292a" - }, - { - "domain": "rf.qw4", - "id": "000025b9-0000-0bb8-0000-7ac5000016a7" - }, - { - "domain": "f49c7ot.61.e8xkl5a-k90-x59.8087d-o.p7m-bg", - "id": "000045d5-0000-4768-0000-1ef5000078c4" - }, - { - "domain": "joua87.elmdl5i", - "id": "00001884-0000-0afc-0000-340b00005592" - }, - { - "domain": "ck.n8-8gv27-b-h", - "id": "00005ae5-0000-6d3c-0000-73ae00004c05" - }, - { - "domain": "yx3.z0ok.f-3", - "id": "00005726-0000-14ea-0000-17480000204e" - }, - { - "domain": "i60k7.e-9", - "id": "00006f73-0000-7cac-0000-247f00001533" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_19.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_19.json deleted file mode 100644 index 0f4b0c4a1e3..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_19.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "2r.vxj87-e--91-50.5.n-s.0r09o-n4w0ax.6n-1b.m--j", - "id": "00005908-0000-331e-0000-50e90000660e" - }, - { - "domain": "13rrbh.8-0.5.c4.3n.q", - "id": "00003595-0000-586f-0000-74f70000747f" - }, - { - "domain": "7t7s.nd1", - "id": "00000697-0000-7891-0000-37bc0000652d" - }, - { - "domain": "154ailfu.4i3p-in9.a53w", - "id": "000013c3-0000-2387-0000-5bd200005a7c" - }, - { - "domain": "56.2.fu.22q.8--14-3u.9v11v.ll-d", - "id": "0000576e-0000-3c78-0000-486a00000ebb" - }, - { - "domain": "9of.j.2.l.1-xy3o2-6jm5-3b.a5qk91.9ie1oc.cl--ia955", - "id": "00007550-0000-1992-0000-535d00007f78" - }, - { - "domain": "w.s", - "id": "00006ac3-0000-50c7-0000-71d100003262" - }, - { - "domain": "8a30.4.pqffe", - "id": "00000d04-0000-686a-0000-1efe00002502" - }, - { - "domain": "3y9.51h6a3.w2z8", - "id": "00004183-0000-1706-0000-1cc100004a6b" - }, - { - "domain": "b00qi1d.2-b.ux0", - "id": "0000199c-0000-0c7a-0000-361c00004756" - }, - { - "domain": "6rdda39---p.0-707gp6cf.vwt.n", - "id": "00007e44-0000-521f-0000-610800003437" - }, - { - "domain": "x6u-q-t.u0", - "id": "00005f32-0000-173a-0000-467200002d38" - }, - { - "domain": "3e.l1.pd.m-ph2t", - "id": "00003b2f-0000-3345-0000-611900001081" - }, - { - "domain": "5--k.qd-3.i-01-k", - "id": "00000ad1-0000-64e7-0000-6f78000079cf" - }, - { - "domain": "211.li37", - "id": "00005ebe-0000-2820-0000-09880000152e" - }, - { - "domain": "8-vi.v.z", - "id": "00004438-0000-3d15-0000-454100003176" - }, - { - "domain": "5.h5", - "id": "00007f68-0000-1cc6-0000-4d41000000d5" - }, - { - "domain": "0aj.wgm.i3ql.w-m8-0fkh.a9gr", - "id": "000035b4-0000-56e0-0000-4bde00004ace" - }, - { - "domain": "mk.a3ylw", - "id": "00006a6f-0000-5b10-0000-65fe000011f1" - }, - { - "domain": "n238.a.3.zt-x", - "id": "000024b2-0000-05a6-0000-0ed200007cdc" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_2.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_2.json deleted file mode 100644 index 61718b92d90..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_2.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "t02vm1.gm810xwh1l4rb", - "id": "000016a5-0000-000e-0000-2ad50000589c" - }, - { - "domain": "620au-6.2j.x23-5w", - "id": "00004bd5-0000-363b-0000-1af6000051cf" - }, - { - "domain": "809.b9m0", - "id": "00006375-0000-417b-0000-3da900004015" - }, - { - "domain": "4bc1.k7-z", - "id": "000075be-0000-770a-0000-471d00005410" - }, - { - "domain": "010.2bu3-2hu.s164s1-2f", - "id": "00002999-0000-35d4-0000-413300001831" - }, - { - "domain": "z8.q.l", - "id": "000016d9-0000-5086-0000-65cb00000e53" - }, - { - "domain": "g-40a.pa2-4", - "id": "00006c57-0000-16c2-0000-5eb200001985" - }, - { - "domain": "0e-1-5-9.h085rwr815", - "id": "00005572-0000-1ad1-0000-75d700000dc8" - }, - { - "domain": "8cp.0.b5", - "id": "00007231-0000-30dc-0000-692e00006a70" - }, - { - "domain": "0.s-16", - "id": "0000458d-0000-373c-0000-2799000037cd" - }, - { - "domain": "9mk.mbz.75307.e9vg.n1.m7kv", - "id": "00004a0c-0000-185d-0000-472d00002ef4" - }, - { - "domain": "u86.7z-v0.q8-78", - "id": "000069d1-0000-3674-0000-31db0000330b" - }, - { - "domain": "22.r-r8k86", - "id": "00007645-0000-015b-0000-41470000445d" - }, - { - "domain": "1-fx97tg2.j7", - "id": "00000c73-0000-44b8-0000-5712000045fc" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_20.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_20.json deleted file mode 100644 index c33bb858048..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_20.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "3fb5t7-7x.d6893-5-g-23-37", - "id": "00001eb7-0000-5c21-0000-1418000038be" - }, - { - "domain": "r9ig5y.mkg-16", - "id": "000025cc-0000-362c-0000-098e00004748" - }, - { - "domain": "v.p491.e", - "id": "0000656b-0000-3adb-0000-365e000020e6" - }, - { - "domain": "4.f", - "id": "00004338-0000-1fd8-0000-0dd90000728e" - }, - { - "domain": "10xem.0w5b77n.of1", - "id": "000001b8-0000-6314-0000-1dd600005284" - }, - { - "domain": "3u2.39.y1", - "id": "00007b75-0000-30e5-0000-6f9f000027fc" - }, - { - "domain": "3--4-ojhd.l-4t0.czw", - "id": "00006fae-0000-0e42-0000-132f00000f89" - }, - { - "domain": "yj.gkm", - "id": "000011ad-0000-6124-0000-261900003e84" - }, - { - "domain": "6613.r462559qf", - "id": "0000058d-0000-1b5b-0000-6b6400004f75" - }, - { - "domain": "27zw.tu1w3w8.u9di6.d", - "id": "00005147-0000-0e15-0000-75e0000012b0" - }, - { - "domain": "v38n.753.j-0-1o", - "id": "00000886-0000-4a6c-0000-1f6400001429" - }, - { - "domain": "c7os-n.yjp", - "id": "00000a49-0000-6a09-0000-3f3200004517" - }, - { - "domain": "17.2p6-6.y626-m0.8e.m4f.g", - "id": "00006213-0000-211e-0000-6e3500001d96" - }, - { - "domain": "0n-0h.cx", - "id": "00002dfc-0000-6836-0000-4fc00000572b" - }, - { - "domain": "k2-6.gqub.t1", - "id": "00001097-0000-2761-0000-74b100004a0b" - }, - { - "domain": "15abt9-hk.qr", - "id": "0000384b-0000-3c2a-0000-181d000011e6" - }, - { - "domain": "g9-2.1cc.tv.b7", - "id": "00001826-0000-3e92-0000-11b800000c4d" - }, - { - "domain": "6.m.g56-y", - "id": "000000c4-0000-33ac-0000-796a00003581" - }, - { - "domain": "cs.q56t-s", - "id": "00006c54-0000-12e3-0000-521c000040fe" - }, - { - "domain": "l59n63b-r4.jq-1", - "id": "00002e84-0000-3519-0000-3b410000306f" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_3.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_3.json deleted file mode 100644 index e8fbf6e6bd8..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_3.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "06s.eaq.xbih-26z--5.jqaqc", - "id": "0000027a-0000-42bd-0000-2fdb00000811" - }, - { - "domain": "v8nj2.c11974lq.go", - "id": "00007fce-0000-1b96-0000-2d96000022bc" - }, - { - "domain": "d3.q6h2k", - "id": "00002688-0000-4fed-0000-15550000504b" - }, - { - "domain": "1s4hu-4-j.63ja.o", - "id": "00007f08-0000-3f81-0000-183d00000a31" - }, - { - "domain": "33.uz", - "id": "00003717-0000-6494-0000-38f100001684" - }, - { - "domain": "s.49-412g.tq38odf83m", - "id": "00003f18-0000-4543-0000-04b800007af9" - }, - { - "domain": "8q7i3.d.4.z1es5.t53.jj540u82s13u.5-2-0y.yf41vaq.ii8-9", - "id": "000043e7-0000-0e87-0000-42c000003d59" - }, - { - "domain": "1qses.gw.7j6e-97-n5c--41aep6-ka.p5-i4ju1k-f-qgj.5bf.u83-88", - "id": "00002858-0000-2ed0-0000-75b800000f63" - }, - { - "domain": "1.d--h6n7-7", - "id": "00000df6-0000-1c5c-0000-524e0000722d" - }, - { - "domain": "f.pe25", - "id": "00006298-0000-4211-0000-46e600007d43" - }, - { - "domain": "660v.w.x-3m", - "id": "00003de8-0000-3ec3-0000-471900001e22" - }, - { - "domain": "e05.tk", - "id": "00002770-0000-067d-0000-6c2700004c25" - }, - { - "domain": "6628-mnod16vk-q.s087", - "id": "000025ff-0000-320c-0000-1f3000005a89" - }, - { - "domain": "y15-4i.1.v-v--3x.za2o.j-jcxy13m3", - "id": "00005748-0000-16a9-0000-6ea200001808" - }, - { - "domain": "4-0jag.z5", - "id": "000031a0-0000-026f-0000-4b1100002e59" - }, - { - "domain": "k89l3.s84u.j", - "id": "00000a8f-0000-31bb-0000-758d00001228" - }, - { - "domain": "6lht3--5028.n901-d.e8v.l6k-5", - "id": "00003989-0000-7b83-0000-658b00003037" - }, - { - "domain": "8-4p5.j7a.jw", - "id": "000033c5-0000-1bcd-0000-52770000345c" - }, - { - "domain": "1i0.w0u02oh-664c1", - "id": "000078f9-0000-5175-0000-281f00007560" - }, - { - "domain": "7--04wq.q-r", - "id": "00005639-0000-6968-0000-5e500000794f" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_4.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_4.json deleted file mode 100644 index a6c32dea3a4..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_4.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "c.8-023o-842jfqd-n11womr81-2.q3", - "id": "000070a1-0000-7aa2-0000-09d80000161f" - }, - { - "domain": "z.tjab089t", - "id": "00002210-0000-7baf-0000-444a00001684" - }, - { - "domain": "rzsu.5rxxw.a2-q505c58i", - "id": "00003ce0-0000-6f08-0000-184100000079" - }, - { - "domain": "7nr.b09-0zj5r-x.gqeb9d.f9", - "id": "00006f6f-0000-5ae7-0000-59f600001ce9" - }, - { - "domain": "7c1irw39.wkc.u.0--h05.37wo.yx0mj.d1sdwqmgy0t7", - "id": "0000659b-0000-07b5-0000-4db800002c52" - }, - { - "domain": "8x3-0t.o3.n99", - "id": "0000228e-0000-2891-0000-439000006693" - }, - { - "domain": "79.j03xh73n66-pc-6", - "id": "0000446f-0000-043f-0000-284e00006e73" - }, - { - "domain": "66v.y-3", - "id": "00003fcd-0000-4f99-0000-2ae600002d4b" - }, - { - "domain": "8.e5.e76.wws05el.z", - "id": "000053a3-0000-3ddd-0000-19820000294d" - }, - { - "domain": "0drfgvr38.5-t-4.z87.8v.o-2j9", - "id": "00001b98-0000-3008-0000-544c0000707d" - }, - { - "domain": "b5.4-2-y1.p7h.3urzu-pc5j.krq36.s498a", - "id": "000060bf-0000-6cc0-0000-4c6800003505" - }, - { - "domain": "68.1.9dyn.135h-e4i5.s83", - "id": "00006510-0000-44c8-0000-4840000034db" - }, - { - "domain": "v--50gum0.05u.u", - "id": "00001467-0000-7458-0000-25930000232e" - }, - { - "domain": "77ek.f", - "id": "00000c43-0000-62c2-0000-59ce00000650" - }, - { - "domain": "0-3s94.44h47uy.fdzis4xj-yywzd", - "id": "0000461f-0000-64cd-0000-0d8400007072" - }, - { - "domain": "8l9t4.qy8", - "id": "000037c4-0000-1e74-0000-531800003136" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_5.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_5.json deleted file mode 100644 index a7d81c37056..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_5.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "o-5--9-gk4.8q626hgb.1147.m.oj-8.f", - "id": "00007de3-0000-1c8f-0000-1f92000009f5" - }, - { - "domain": "w.x.m", - "id": "00003c26-0000-2af0-0000-517700000473" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_6.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_6.json deleted file mode 100644 index 58ad0617332..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_6.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "07313.51n.r-3545op", - "id": "000064b7-0000-4eda-0000-493c00004a3c" - }, - { - "domain": "t7452-c5c.b67", - "id": "00005ab2-0000-0fae-0000-7dc20000611f" - }, - { - "domain": "6ru2-i.fm.537f.kx-j-c45", - "id": "00004bf5-0000-065d-0000-6d9900002a46" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_7.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_7.json deleted file mode 100644 index 9a8ee8a1d04..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_7.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "yz.s69", - "id": "000036da-0000-4904-0000-3000000033bf" - }, - { - "domain": "up-a0.f-d5s2", - "id": "00007eef-0000-3fc4-0000-707d00004ca9" - }, - { - "domain": "4-0.l4383.sv7ris", - "id": "0000181f-0000-4315-0000-5c8500002fca" - }, - { - "domain": "87k-1.1rq1.q", - "id": "0000330d-0000-6a09-0000-09c600001846" - }, - { - "domain": "56.3an.g810-5", - "id": "0000277c-0000-6769-0000-6a4500007223" - }, - { - "domain": "u42h.m450s29", - "id": "00004876-0000-3492-0000-496a00004ece" - }, - { - "domain": "q.vv", - "id": "00002f16-0000-4420-0000-6dbc00002c63" - }, - { - "domain": "0.is898n-43", - "id": "00006b8f-0000-40ac-0000-419c00000293" - }, - { - "domain": "r0pbc6.r-d", - "id": "00004e89-0000-2935-0000-5377000011b0" - }, - { - "domain": "53jmrm174-h3e-6dc-8.w", - "id": "00002002-0000-0eca-0000-2e87000057c6" - }, - { - "domain": "5.m-5a121y7626qx.u--ow93937", - "id": "00003722-0000-4db5-0000-3ccd00000a87" - }, - { - "domain": "66f-9s.vd-08g", - "id": "00006aae-0000-751f-0000-33010000320f" - }, - { - "domain": "1fu.p-77zp", - "id": "00004861-0000-2d48-0000-515100003b38" - }, - { - "domain": "p7-n.f1028", - "id": "000070d4-0000-0839-0000-172400003284" - }, - { - "domain": "2pj.f14.f", - "id": "000044c8-0000-436d-0000-61d800005c3a" - }, - { - "domain": "t.m.xq-e17-o.jz432", - "id": "00007e01-0000-208b-0000-5bde00007e98" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_8.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_8.json deleted file mode 100644 index d66c321119e..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_8.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "jq2.h", - "id": "00001533-0000-0cd6-0000-488c00000223" - }, - { - "domain": "98n0.ktvkb0qlx.5.i", - "id": "00001ca9-0000-3d4c-0000-5b7600000a4f" - }, - { - "domain": "si320k62.5wh.rwnj", - "id": "0000757d-0000-13f8-0000-53fb000059d8" - }, - { - "domain": "t255.nd8", - "id": "00007dc1-0000-0874-0000-499200005920" - }, - { - "domain": "0u.q5z1sy", - "id": "000079b5-0000-3602-0000-5fb500006d48" - }, - { - "domain": "a4a.z3b.nao2---0uv-il", - "id": "0000169c-0000-0d25-0000-3fbf00007bb7" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_9.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_9.json deleted file mode 100644 index 1c7bb5e9c74..00000000000 --- a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_2020_user_9.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "qualified_users": [ - { - "domain": "2.07io.g464-sf8", - "id": "0000406b-0000-0c05-0000-7a7f00006547" - }, - { - "domain": "wrbsoq.0s-2.u6.xnd5.k9r-8", - "id": "00006cc0-0000-3409-0000-094700002637" - }, - { - "domain": "u21.v6n", - "id": "000017d9-0000-4cc8-0000-5dc8000009e0" - }, - { - "domain": "e8kr600xi.pb81-7", - "id": "00002139-0000-07f7-0000-20210000535c" - }, - { - "domain": "38y2.2iip7.e-i.0893.f7", - "id": "00001ae2-0000-056b-0000-2bdc000030a9" - }, - { - "domain": "2x2.53.4a-5x7ad.cay2zjw--z9-1.avpv9-1x1", - "id": "00001568-0000-3c21-0000-73eb00001a78" - }, - { - "domain": "2im.g", - "id": "0000453b-0000-26c2-0000-622d00007b3b" - }, - { - "domain": "4.31evw16.kgcf.u6m.0-s3j745.0h2.aavp99h", - "id": "00000abe-0000-5b93-0000-1130000033d9" - }, - { - "domain": "c9.k0s.02----2-8nk2q50.cr5-ns.g5-n", - "id": "000044d4-0000-56d6-0000-41a8000040e0" - }, - { - "domain": "i9.c12", - "id": "000015d6-0000-4f61-0000-72e500004d5f" - }, - { - "domain": "s8y-j-cw3.u8e.6.o5xje.ms9gq-290.3.m2n756j101q.t690", - "id": "00007b49-0000-758d-0000-73d9000074c9" - }, - { - "domain": "q9--p3c0hw.1.dkd", - "id": "00002562-0000-5a59-0000-05a100000c18" - }, - { - "domain": "4u9.a-1j3p", - "id": "0000427f-0000-3c33-0000-4629000077b8" - }, - { - "domain": "f33.s1", - "id": "00002f4c-0000-17f0-0000-51ba00001b95" - }, - { - "domain": "126.o7-2", - "id": "00000458-0000-1a4f-0000-6b3400000c30" - }, - { - "domain": "0v.4qytdlh7t066p59m-km-40.k", - "id": "00000634-0000-2ff7-0000-62600000322b" - }, - { - "domain": "wp.o.3-s.h4-t6", - "id": "000021ea-0000-5833-0000-707b00005042" - }, - { - "domain": "377.h9m", - "id": "00000e79-0000-4ab3-0000-57bb00007ca8" - } - ] -} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_1.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_1.json new file mode 100644 index 00000000000..c2d1a64feb3 --- /dev/null +++ b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_1.json @@ -0,0 +1,8 @@ +{ + "qualified_users": [ + { + "domain": "sh7636.gcg-c", + "id": "00005bed-0000-0771-0000-447a00005b32" + } + ] +} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_2.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_2.json new file mode 100644 index 00000000000..ce814528a86 --- /dev/null +++ b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_2.json @@ -0,0 +1,12 @@ +{ + "qualified_users": [ + { + "domain": "t02vm1.gm810xwh1l4rb", + "id": "000016a5-0000-000e-0000-2ad50000589c" + }, + { + "domain": "620au-6.2j.x23-5w", + "id": "00004bd5-0000-363b-0000-1af6000051cf" + } + ] +} diff --git a/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_3.json b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_3.json new file mode 100644 index 00000000000..6cd2f940734 --- /dev/null +++ b/libs/wire-api/test/golden/testObject_LimitedQualifiedUserIdList_user_3.json @@ -0,0 +1,8 @@ +{ + "qualified_users": [ + { + "domain": "06s.eaq.xbih-26z--5.jqaqc", + "id": "0000027a-0000-42bd-0000-2fdb00000811" + } + ] +} diff --git a/libs/wire-api/test/golden/testObject_MemberUpdateData_user_1.json b/libs/wire-api/test/golden/testObject_MemberUpdateData_user_1.json index 9c844111a28..6b538b2fc02 100644 --- a/libs/wire-api/test/golden/testObject_MemberUpdateData_user_1.json +++ b/libs/wire-api/test/golden/testObject_MemberUpdateData_user_1.json @@ -4,7 +4,6 @@ "hidden_ref": "1", "otr_archived": false, "otr_archived_ref": "a", - "otr_muted": false, "otr_muted_ref": "#M𗗐", "otr_muted_status": -1, "target": "00000000-0000-0002-0000-000100000001" diff --git a/libs/wire-api/test/golden/testObject_MemberUpdate_user_1.json b/libs/wire-api/test/golden/testObject_MemberUpdate_user_1.json index 68c0e105c0d..1bdf47e1ffd 100644 --- a/libs/wire-api/test/golden/testObject_MemberUpdate_user_1.json +++ b/libs/wire-api/test/golden/testObject_MemberUpdate_user_1.json @@ -1,10 +1,8 @@ { - "conversation_role": "nn8oubrrivojp29q65krhyfzzgvzt3yb18z_39zct19xff_7_wm4xk0ixmzaep5oj3cdajj36vwbc89pgajtmzo1rbwc40ulc837b1aknib6cj03k64ovt4p0h", "hidden": false, "hidden_ref": "", "otr_archived": true, "otr_archived_ref": "ref", - "otr_muted": false, "otr_muted_ref": "h컮N", "otr_muted_status": 0 } diff --git a/libs/wire-api/test/golden/testObject_Member_user_1.json b/libs/wire-api/test/golden/testObject_Member_user_1.json index 9e99cb4bf0a..76d176b1bef 100644 --- a/libs/wire-api/test/golden/testObject_Member_user_1.json +++ b/libs/wire-api/test/golden/testObject_Member_user_1.json @@ -5,7 +5,6 @@ "id": "00000002-0000-0001-0000-000100000000", "otr_archived": false, "otr_archived_ref": "𢖖", - "otr_muted": false, "otr_muted_ref": "ref", "otr_muted_status": -2, "service": { diff --git a/libs/wire-api/test/golden/testObject_Member_user_2.json b/libs/wire-api/test/golden/testObject_Member_user_2.json index c0c85f3ba00..e6f6fd61ce9 100644 --- a/libs/wire-api/test/golden/testObject_Member_user_2.json +++ b/libs/wire-api/test/golden/testObject_Member_user_2.json @@ -5,7 +5,6 @@ "id": "00000000-0000-0001-0000-000100000002", "otr_archived": true, "otr_archived_ref": null, - "otr_muted": false, "otr_muted_ref": null, "otr_muted_status": null, "service": null, diff --git a/libs/wire-api/test/golden/testObject_Message_user_1.json b/libs/wire-api/test/golden/testObject_Message_user_1.json deleted file mode 100644 index 2a7eade9b65..00000000000 --- a/libs/wire-api/test/golden/testObject_Message_user_1.json +++ /dev/null @@ -1 +0,0 @@ -"@󽰧n󰟨𫴗l`d\u00087󲯙ﻘ럢,8\u0004~\u001eA𧎨󸹼𣝦\u0008]\u0003f𡡛3n\u0014펹.99􋢷5\n9OqXR[`𐨯𦂙󲹹舽k\u0018􂐣1PK" diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_10.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_10.json deleted file mode 100644 index 0ca20c62469..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_10.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "}󱑶􅬖6G" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_11.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_11.json deleted file mode 100644 index e0adc7e150a..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_11.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "󰅊CVbPfdR󼃁r*'󴦛31m9狚eB" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_12.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_12.json deleted file mode 100644 index 2879764312f..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_12.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "2矛\u001dJw96\ti𩉸汓3K\u0011s^" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_13.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_13.json deleted file mode 100644 index 7a2c49414e8..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_13.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "N􌞲𭔙\u001e2󴝗𤊕E􁍧\u0008$T`5*@􈹸𨐜UK" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_14.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_14.json deleted file mode 100644 index f8b9c5e0311..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_14.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "𫈰\u0003u\u0007Qtw􆛒.\u0005We" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_15.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_15.json deleted file mode 100644 index 71be7bbe7b6..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_15.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "\u0003" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_16.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_16.json deleted file mode 100644 index 061e0101820..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_16.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "􃽃y􃉍C󷣏󹸐􆱵ࢻ>|􈾯?" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_17.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_17.json deleted file mode 100644 index 343b7c83828..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_17.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "ࠚ6\u0012\u0001\u001b􇞪󵳐$ .FCG󿱠𓏹巤<8W" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_18.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_18.json deleted file mode 100644 index 998897f1633..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_18.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "뉦\u0001[.𬢁D􆚱f𧰥.錋a􈊦𢱡ⱃB𠒜RK\t]􆬛m𩡲" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_19.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_19.json deleted file mode 100644 index 9258c14e3c2..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_19.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "𡀞CO7`O⧯[p" -} diff --git a/libs/wire-api/test/golden/testObject_NameUpdate_user_2.json b/libs/wire-api/test/golden/testObject_NameUpdate_user_2.json deleted file mode 100644 index 89d9964a8a0..00000000000 --- a/libs/wire-api/test/golden/testObject_NameUpdate_user_2.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "", - "type": "image" - }, - { - "key": "ጅ󽆑+ᬝFMEp􀔌H\t\u0005", - "size": "preview", - "type": "image" - }, - { - "key": "\u0001;\u0013\u0013\u0006\u0004b5^s:\u001c\u0005󰩐y\u0011\u0017", - "size": "complete", - "type": "image" - }, - { - "key": "v􃮞", - "size": "preview", - "type": "image" - }, - { - "key": "􅐺", - "type": "image" - }, - { - "key": "^ 𘡣藝\u001e@", - "size": "preview", - "type": "image" - }, - { - "key": "8ﶱ𩳢\u0010E𒌍󻀏\\Z\u001b5<c𧅒2", - "size": "preview", - "type": "image" - }, - { - "key": "\u0010󽨻𦤩Gc", - "size": "complete", - "type": "image" - }, - { - "key": "𥃱0@\\r|J􂲢\u0013\u0003\u0017d*\u0003󽠒]", - "type": "image" - }, - { - "key": "􏹌Q\u001fh%1\u000c𝨝溬:`", - "size": "preview", - "type": "image" - }, - { - "key": "6z5󹠣\u001de:}𘕏", - "type": "image" - }, - { - "key": "瀷\\Q<\u0001X44鮚d􁎺", - "size": "complete", - "type": "image" - } - ], - "email_code": "Z-Zl_Qv7tQ2uarU-IzTDMXzogSXj", - "invitation_code": "w1bhwQG7MiCYb7O4aguK7iSgND5JBw==", - "locale": "tg-BD", - "name": "hG\u0013碡e-󿲗f5\u000c󶭗\u0018d󺚌𫌻bR\u000c󳟢􊍽􎧏pJ", - "phone": "+43575413322561", - "phone_code": "XnBOrq6YI4Q_OfxeADfxgHnlqFMQaauOlT003dC1JCCI", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_12.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_12.json deleted file mode 100644 index b5de0b71dc9..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_12.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "accent_id": -48922, - "assets": [ - { - "key": "󽅗\n􏀬N", - "size": "preview", - "type": "image" - }, - { - "key": "ENiRZ L􆢱. 𨤁\u0000S\u001a =", - "size": "preview", - "type": "image" - }, - { - "key": "h𝑆\u0013", - "size": "preview", - "type": "image" - }, - { - "key": "𢥃x󾗒p\u000e찴,\u0015](\u000f", - "size": "preview", - "type": "image" - }, - { - "key": "\u0005.P贈_쨔􆋐D", - "size": "preview", - "type": "image" - }, - { - "key": "𩏸􃫬b", - "size": "preview", - "type": "image" - }, - { - "key": "\u001bo\u00146", - "size": "complete", - "type": "image" - }, - { - "key": "t,𫊆\u0002\"\u0008\u0002mE\u000e", - "size": "complete", - "type": "image" - }, - { - "key": "t𔔓\\\u0014\u0018;", - "size": "complete", - "type": "image" - }, - { - "key": "p)LK", - "size": "preview", - "type": "image" - }, - { - "key": "􈓁˟qx\u000f8mQ\u0002\u0014\u001c𮝡Ŧ", - "size": "preview", - "type": "image" - }, - { - "key": "e", - "size": "preview", - "type": "image" - }, - { - "key": "󳩫zY|", - "type": "image" - }, - { - "key": "Y\u0006", - "size": "preview", - "type": "image" - }, - { - "key": "󴭛\u000f\u0002\u0003Mux𧽨탸껙j\n}7\u001e\u0011", - "size": "complete", - "type": "image" - }, - { - "key": ":", - "size": "complete", - "type": "image" - }, - { - "key": "j􆛝\u0011n󳦷`\u0012n\u0007𑱷𮞖\u0004􍎭\u0008𬢟", - "size": "complete", - "type": "image" - }, - { - "key": "Mx\u0018/\u001b\"G_\u0015\u001b", - "size": "complete", - "type": "image" - }, - { - "key": "[[􁓾<󼣄+I", - "type": "image" - }, - { - "key": ",󲗦F@󷸒", - "type": "image" - }, - { - "key": "]󹼲X(q\u0017O𦳹", - "size": "preview", - "type": "image" - } - ], - "email": "g\u001cn))s/𧙊?\u001dQXb2 @U𨱐=B3Cod*󵓄ᯡ㏔", - "email_code": "UVZ6MaxnslUCv-4=", - "label": "\u0011\u0008g󷤜-\u0008\u0018댂LP|l⅂􂫅/㩗\u001b\u0005", - "locale": "et-TG", - "managed_by": "wire", - "name": "S𠴷[\u001eVD, \u0010BH\n,\u001a\t􄊇M棿1\u0001\u001e[􎤟,𥠈\"v󾶮MP\u000cObI\u001e\u0014씞󽻧\u001c\t7i𠧭\u0008\u0002T#뾱O󷙫\u000e\u001d!C\u001a\u0004{1\u0016 +\u0013\u0004􌲇𣝨(𤶐󷇀\u0014𬽑lh\u000f𡱹", - "password": "c𣪫~b@qM􅢳󿲯􇨘BL$b\n.^{p\nq\r\u001a,šP~󳂙`\u0016?\u0018􉦊7I놘\u0012􁧞\u0003f\u001a𣝼\u000ck%\u001f􅓹𡅗;0&k\u000f\u0015HY5_u𡜷", - "phone": "+195504776", - "phone_code": "fsYfmzlCyBE3ZK8opHg=" -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_13.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_13.json deleted file mode 100644 index 3bc1910f48e..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_13.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "accent_id": -18284, - "assets": [ - { - "key": "6􌮆|󵌫\u00045z􇹊󻬤", - "type": "image" - }, - { - "key": "\u0015􋴶􋖝y\u0002󽒯c\u0008-", - "size": "complete", - "type": "image" - }, - { - "key": "􂱞T", - "type": "image" - }, - { - "key": "[󻶝\u0019WU3d0/K", - "size": "preview", - "type": "image" - }, - { - "key": "A𭄍v\u001f2R􂜖Ff𫩢&􎑃&", - "type": "image" - }, - { - "key": "􊷫􎄍#\u0006", - "size": "complete", - "type": "image" - }, - { - "key": "K", - "type": "image" - }, - { - "key": "6$(TkM", - "size": "complete", - "type": "image" - }, - { - "key": "+㌇𤨰\u0012𣲔", - "type": "image" - }, - { - "key": "\u0008\u0005􈵞La65=󳁈𫌵R8", - "size": "preview", - "type": "image" - }, - { - "key": "󷨘\u000bj𪉡k", - "size": "preview", - "type": "image" - }, - { - "key": "\u0014\u001b|􀉎", - "size": "complete", - "type": "image" - }, - { - "key": "D\u0001\u0018ṉl:", - "size": "preview", - "type": "image" - } - ], - "email_code": "jtAT26_-fRZ3qS2Gx5Cfvrk0mgi5gnPx", - "invitation_code": "oYu2EkO4OdjPAeBx-tOeGAHapJ62b5ZcuA==", - "label": "d􄠧𩢬\u000f󹳁𪀘IZ蓀sS\"wjcI􄙨𤁗𢛸`X", - "locale": "bg-UZ", - "managed_by": "wire", - "name": "\u0004ui", - "password": "󰲋2\u000e檑vXm1𨜰>\u001dY𠌓g󸫡pjer􉶴𮨁?원'JKn,Jat\u001c\u0007q󾂺𝖑\u0011傄󽄛e#󵊉{.󽶯d􏀧\u001e􋾒􅫑!󴞔󶪰\u0007娦\u0007~Nv!\u0007l󷃦z{\u000eeF\t*\u0006\ryt􉜑i𗵲\u0010%`tZ\u0017 HC'бJ\u0002\u001e/𑖛e\u0008󱲘󰁥 C(Ef\u0006􆌃`{/%\u0018ox3𠛩󽹚􊱃𦥈㒸\u0016?\u0002=􌾱J𦑮o>\u0011:𠔿\u0015󵻽!F{\n\u0003Q\u0013᎒\u0002YzrH\nG9ZS𬧥\u001f\u000b\u0018O􁄚󸓚< Mu􉯵𣸉yi3\u001a3\u0012#M𐴊\u000e\u0008,.E瓤􇜗@2󹪬\"Kd\u0001t󶣰m\u0010\u000f\u001a0\u0008s]C\r\u0016\u001foXD:\u0011%\u000b[􊠺=U]󼬒8\u0002x7𤵍\u001fJ􊠕n?틾𢘘K 𐠙]􀩑@啫`H\rL%𥆇Z\r\u0016􉘗oqtFEB𪋜[\u0015\u0007\u000bv$H&J\u0003😟􂰀󹸛8D頥X􆀉\u001a􌦓􌾆𖼷)uV❋䪢\u0000\u00119o\u0012(䕝\u001b\u001b\u0001*YO>fWl\u000etේ룙s*\"\u0010󺐈󻄤\u0001vgKYmv,𩬽v𧜆\n\u001dO􃎬}􄲓Dfj\u0017\u0016\u0014󠆔\u001e~𪉪[𩎫􅦠錀s𑄉󷂏@W如𧹼w.\u00155<𣷪n󺗺E4is𢥶o𡱊V'೦\u000cy\u0016a\u0002\u0005\u0001\u000f@\u0016鬙萞AO>S\u000b󽼺#`𞤊.\u0006𝡕F􌧓󹗬#󸊨R\n𤄳\u0010xL𦦓\\􄢨(􆑉G2𧮂 $􊐱􈉃𦋟g\r'#;m\t\u0016􁕱􉣐𬄏\u0004U(\u000b\u0004", - "type": "image" - }, - { - "key": "4Hi𫵸b7", - "size": "complete", - "type": "image" - }, - { - "key": "\u0017􋭱@搈9\u001e%Ⅺ*\u0019𬱪]􆗋\u0014{", - "size": "preview", - "type": "image" - }, - { - "key": "f=X\u001fF|xOI\u0010𧕃𘩑U%a", - "size": "complete", - "type": "image" - }, - { - "key": "\u001c\u0018𘧷", - "type": "image" - }, - { - "key": "摧4I\u001b\u0016.", - "size": "complete", - "type": "image" - }, - { - "key": "\u0004𮌭M𠗬", - "size": "preview", - "type": "image" - }, - { - "key": "K`jC4x]", - "type": "image" - } - ], - "email": "_𡶱0yK~}|8웾5\r􍙱A\u000b>􄮐?f*n𗳉'F쒔kg @\u0012Zi᥊𤁏V宎\u000f\u0007\u0018􏕢6E\u000f\u000b7,󼵋f2N", - "email_code": "879HiMc=", - "label": "󲛴N", - "name": "H'[\u0010Ep+G\u000e𮫞M\"󴒒", - "phone_code": "2IG53xZ-sTN_Om5U9MMGmxMXgD4I8m0OOhHe2VI=", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_15.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_15.json deleted file mode 100644 index fbf3b1274b5..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_15.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "accent_id": 55236, - "assets": [ - { - "key": "|/𣉘咪", - "size": "complete", - "type": "image" - }, - { - "key": "\u0004", - "size": "complete", - "type": "image" - }, - { - "key": "\nwa^|?𥴺\u0013v", - "size": "complete", - "type": "image" - }, - { - "key": "}Wh", - "size": "preview", - "type": "image" - }, - { - "key": "^e]􍉟", - "type": "image" - }, - { - "key": "g", - "size": "preview", - "type": "image" - }, - { - "key": "q", - "type": "image" - }, - { - "key": "9b\u0016? /\u0016\u0010", - "size": "preview", - "type": "image" - }, - { - "key": "􎃫.𪇈r", - "size": "preview", - "type": "image" - }, - { - "key": "9L䠟Azm𩸈;㿬", - "size": "preview", - "type": "image" - }, - { - "key": "􌃈!􂑢sQnJ罝h08𮑹-􊷫Sf𐓸o\u0002𑿀3*󻄠e\u001f\u0005\u001b[|`𪹾\u001e􆠽P􆃹_$𥢀9RY\u0016􄏶3#\u0016f\u001ahN_!𤦽\u000e(@|>C\u001c㌦_U\\-𖹆.\u000b𡏰|􃞆=&󱀏\ny\u0012󳋖\u0005M!𣚄\u0014@qj󵜬x𭹋ꖎ\u0013V祙\u000b=󳋀\u0004Afq􌿁\u00050k\u000e玲\u000eN\u000e~*\u0007庰\u0007\u0014\u0003蒗U#\u0000{kb`\u000eu\u001f\u0003/󺃏6j􀧐j\u0019󿐕|`󿆟\u000e5>𤜥\u001f⒁f>}b󴾛CV\u0008qx\u001fC󿁛\u0011\u0004k3;qC󾚝􆀩`𪂈󽉲Z_:􋷓􁎈\u0011v𥣬􃴶t\u0013櫹w \u0010󳬜am0𢼋󼒝\\\u0000]\u0008NwqW\u0011.A􊹩rn\u0015L2\\@v󼗧􎆫\u0005𢂄JsifO`􉘅ZDD|Il􊽳Nd󼴬\r􂆏\u0000\u000b􅿱󺁼v􄨋MPW>&D\u0001􈫤힅h\u0015􏀵\u0008m\u000f^)J>@I7\u0000󰬵\u0015\u0012]Jr󺦢Qi\u0008󱛂\u0014-󳅨\u001b􌛽Yb%vY\u0014 KP󹁷\u001d󶰽􀠐d\u0019(0􊺡nz]*$󴻕󽍜^D\u00179􆪮X􄞻𣋋\"]󲏡#ꯪw𧽵Y\u0019𡠰{0\u001f䲯𭫜QqW壎裄󲲴𠤏O<`jAams7xC𭙖p\u0000􌵸\u0013􁜬fd\"\u0004q2?忲𥆙7DxTn\u0010!V\\僼A\u0005;\u0000?\u001b𩋧\u0004)A\u001a\u0003󼒂A\u0010O\u001dw螪~r惐*󹊼3Y\u001e\u000c\u000fl]p󷜼Nb󱈆a:cm\u0002Y\\`쵯XV;WWFG\u0014𢐚i7\u001f4(𐬓\u0019Z]A\u0019p􉘾o-e\u0015Sn⍪𮒓\u0002󻕍󶹂p𣈻\u0008\u000eT􆆎Hi󰹠𪄈𪠝􇞶e␙{⌼G*c􍩼'𢳏\u001c*9TgW\r뛌,vV=+{𨸷󾆨|􍤅E(\u001f=U~\u000fd#9lkWi*x\u0015}E?晻q㳴𗅻4em𝜺\u0002J\u000c\u0006\u0008\u000bByD\u0001𮙗\u000c\u001b餕\t*󱂕\"\u001d\u001cA{XvC)𑧢A蛋\"󴔖\n󱀗j󲸡𡝊\u0018\u001c􉵙𩗒\u0006_󵄡c뫖􆬵tccC㮷􂚍`\u000c9P陼亞􏭤i􂍡>󹏑\u0019G\u001fa\u0014J􉂵G|\u0002\u00033\u000eEZ.\u0018\u000cy_A\u0013F+sX{-\ndy􈈴􊥁!8a1a􁽋Rv󴖁\u0007e𘣾􅂧=󲾗\u0002\t0V\u000c𫃖8I􃔜_\u0018l6Ra+sX\n4󼭓R􍙊𖧼]%\"r㣵s<󽀹𩄍󽏤0󰇆=K넜ZQ󱀾󺩟lx`\u0006|7\u000c\t𒂰\u0011풞\n\u000fO󶶭 \u001a?<󷓚鈭Di􆸘.U~\u000c𮁛,>w.鸊𪂲!3􏴂\u0019[l-tI\"y壸󲇨bS><󺊯𤹅n𝡍&􌞧X+\nvhY^\ny\u000e0𤃉\u0002\u0005V\u0011~%\u0001K>𪈰(;G/;汦M􈝪\u0018$t􁺼~􄟧𘔼JZ󰫞e𘞭\u0015􀏓-{}s󱩕v@\u0019Tf\u0004+뎰\u0007󺂱pS\u0012\u001cJ?𠸱┲y씿~\u0001\u0017𖨗(,󲹸=W𦹪J\u0006%*9;q󺅞𩥷\u001fp\u00079@; \u0001N\u000b!䚋(on\\!0P<&X󸻝QmuA􎹟\u001bC%\u0005𥨽\u0013\u0014vRnch􉾤'󹽼ᆚ\u000f\u000e󳁢wB󰊿h?qt+\u0005\\7餶󾏋\u0003\\;􆪏", - "phone_code": "lrdPhnTqFFN2mVM=", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_16.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_16.json deleted file mode 100644 index 4877eeea425..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_16.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "accent_id": -26284, - "assets": [], - "email": "x\u0007𝑫𡕞􎅘@C􁇸\u001c;􏾁\t?􃳼;\u001d`\u0000𗐠\u0007", - "email_code": "XYsxg7ZJ_P0cEi1JGv7oJTI=", - "label": "9", - "locale": "yi-CK", - "managed_by": "wire", - "name": "36僥\u0019𡇩󶖖\u0012􎴠L\\𧪈籣\\:c𣨥󳪛𧒢-틴N㼍𣮪[oe𧚪%4\u0017]𮔎", - "password": "󱦄Bᨩx󻕙v*Sh\u0017W k\u0012D ThP6$􀴏\\gc曞𬙓LS􌥾apGZ?8+􊶂h:\u001c)􁳴W󼎍Z'C\u000bH􇸀yI!u9[ ;*_𑀱[\u0001F󼈻\u0019.,󲢱󷧾\u0010wL\u0000\u0015S󼁴潫󺧓_K\u0004󱭻\u000eB􃐭EM>;􅾓1\u0012MT\u0017󻀫\nX\u000f\u0014󿄍&s󽿅3\u001a\u0013!cz𨡳𑰩Ab􇦑𒒑\"\u00113󶁭#%`\u0000\rr􆊆[0鬩g!/𪸰\u0006\u001a𤉣X\\\u0019y􅭽Ci\u0001)8'\u000f2\u0007\u0008j4h呲􇎵!􄓋􉁋􉒽jp󼧔󾍞𨶡.𠊼[<拖\u000fve(\u0016 K􋠒\u0007E\u0019TC\u0014L󺛜j\u0015`j`􇏜g\u0002?QQKh􄢥Gdp/\u001e몠\u000bj𪤝&;,qr䖽\u0014Bz\u001eW󿟠c\u0012}\u001b󳅓LdU\\cwz󳃶\u0018|gY󻵞n􉓻lꀇoi󰝺𢽯\u001a\u000c//􍮘L=煈]󶙆⌿𤾿󶮽y(\u0000w\u001f_\u0005m􊼳K|館d\u0004R,􏫳󸁲󳝺Nx𐚀󲭮\u0007\u000ejS=27,k\u0001w\u000b\u000be 󿙙\n絠{\u000bC𪄳6K 󿘺\u0010n[zPl\u000e\t\u0017%􈷜\u000b􈉕J􌹩𘒰\u000eN!󴧷ꉱ􎳝)\u001eN;0\u0003H+𪊅?}6쎋麰󿭋廩5S\u0010\\\u000b\thJ@\u000f\u0012󸞛WD􅧎𥽌`\u0011e\u0006\u0019𠉆\u000b􎌮\u0011h\u0011'KR𘖢cB\u000f5\u0007^⡌?0{y􍤈`㾉\u001bS(\n(6:=󸽯uvwL=󱗢\u001f0t\u001e|􆪿<􄺐\u0010U#=\u0004)KR~(歃𪧥\u0001\u0017极󲣹\r\u001a-𩨑<𣵨\"iVGqt+]c샋\u000e\u001cl􃬉𬛟\u0000]m󸔰R\u001f꾥\u0011B\u001c\u0012\u0014\t\u001d霖嫌#FB/W󻡹􍘪\u0017`\u0003B󶎖h]꒖U%\u0000\n\u000eY𣮵엯;t\t-%󷥒L9𗣸Ju\u0015v\u001ccw\u001d,􋄡𠅅3 􁼵x0l+_i\u0008󶢻?\n&􊂇\")H-C-􄈋_\u0016(b|뾆\u000fo𐍂?e⎛]𥱥0E\u00001\u0011辶􉡞쌭\u001bl .P5XY\u0007􇷦󾶖&􄛇󹵅tKm𠢳🩃'\u0002J\u000e9􁢊N\"\u0008\u000fRo􇴡䌦i%󻆔􉭮󾬜1\"\u0014j􃌸𮎌槌\u0006\u0004V<5\u0001\u0000]N陴qCf𧫅;.$~a60𩱷W\"\u000ea\u0001􁸒􏳂\u001e\u0005󱪔q苯쯼\n⍄\u0004\\}𮛞w\u0012(\u001c𥐞/󷢈kv\u0006T􈜖Ze3􊺲l䞊M}e\u0000U]󾽥@DOW\tu2t|@\u0002𤝓xc?%󹩇?]\u000b!\u0005\u00158@G𛇤~l𧯉E-\u0000w\u000cFl\u001ev\u000bNb:虠e\u0012@𩔕\u0007o9G󷨶B􂙇f|􋊤\"\u0002-C*>RM&\u0012〔\u0010uPt󿲧@\u001ak󾟏?\u0007󷽐5Q~dUMlfk\u000e\u0007MC𧨋'J(\u0016\u0013⏶𩻘/𠶴<󷩍+󶉼XSzcB𨉣/$𝜂n𘋗􊟇_v\u000e􂪱8蒗\u0007CO􎦲󵇞􍴃𥓄:켐qy𥃂\u001a𢰀𧷤elk\\\u0019𢃼\n󹻟7쬲𬷭e󺾀K+e󷻀\n\u00198h\u0018\u0013eLD\u0011䈓Y\u0004$#\u0013겂ܮT𢈳=!\u0005􊎣<\u0013Fᣏ(5?\u00112𦩵\u001fr໔3%􎤁󴇓\u0006}9\u00070rF\u0018MH\u00108𫮩R󷆼𐅡􃍭Q*\u001b~%𐄁C\u0004\n\u001ar#\u0014\u0014n\u0012tx𠲤e􁇩𩟷.Z\ry8O\u0017", - "phone": "+534443880", - "phone_code": "zCo9DoCXHJwpHDl4N7m-hyRBkTE__sgzyg==", - "picture": [], - "team": { - "currency": "HRK", - "icon": "󿯬%\u001f\u0014y0隨\u001fx箌󳓐4ᴦ􎻷􉩞*=∃#V%(\t\u0006x\u0018k􃹨\u001el\nG\u0012d椿\"W􉧶)~󲡳fx\u001a\\󵮭\u000c􀛎\u0015O\u0011t&𭽮\u000f\u00199􈑶\u0013𖫰Z엦J􈏚#JjO3\u0004\u0007􏬻'\u000b><%5SFN\u0014S +7+䎝2􆺇🦑􉔌ⷐ]\t\u0015󴑂v\u001b&D(\u0016c\u0019ꖈ\u0001􃏂𥽖'\u0008󵸨\u0016cv/Z\\⨬󸽬􇐋O}\u0013\u00081X󱒵K\u0018n𠠃I!󸏤8\u0007so􀩽il󰁆󻎩󹄵\u0000󹋍𣕕'𞻰趜BJ\\.v󼆊\u000c󻘥gB󹹑󼴝y\u0002@0󹵾\u0012L)𡍹Q󸕥&m】u [󾹥'\u0013n𮔋\u001d\u0016𧎡􅍦🌂Mq4|\tz6󸧀\\hN㧧\u0007s3r", - "type": "image" - }, - { - "key": ".-Vja\u0000!\u0001\u000e9ὧ", - "size": "preview", - "type": "image" - }, - { - "key": "6𧕷Eu{s🎇a6󹁄\u0008", - "type": "image" - } - ], - "label": " T𝩰9!\u001f P>x􄊰.𩌥􀾀].􄸛-&̴󾯳x\u001b\u0015􃿍[\u001e\"𪳿\u00029", - "locale": "ga-IT", - "managed_by": "wire", - "name": "􌷒\u000f\rM𩙴≗B👹𪢘2\n\u0002\u00121n]啙", - "password": "𬓿YALj\"􇟼􋫒\u00146󼅰\u0015{\u000b2𡷗􂒕59yPA,%\r\u0000_𗤂\n􍘯nᛅpA𑢻P%>\u0008_0\u000c\u0003o\u0006>􁳇𪻔JG$7uj+𣍝\\𩜗\u001fS\u000e􌆧\u0015$Z\u0007\u001aG𡨺풲j 𞺰sE\u0016N𨣰􁰯\u0017\u000fSG8-𗍘󶖲\u000b\u0014\u0001􏬚a\u001d𖽴Y,𘧭\u001eF\u001arZ瘪\nEo\u0002\u001al\u0012􅄒}vJM󾜲65\u001cP5\u000bK󰹜=]P􎗛𑘕𮉁𫒊T𢐯𦘶𥢚\u0012Y󽒬E󽂸󳃣\u0016`􎳆\n􁨩6\u0000\u00077킮{4􀴀jx\nŦ󸜸.嬖󹩩7\u0013\u0007+f𐅴N󽰠\u0016?G󻚮𤂹M\r\u0016𮢩_􏕛歈C󿎉G\u0010󻠫󷶶T$\u0001}󲪥\u0000L􀯟ń镐Y*v㝒􄁮𦝹\\T\u0001󺼿EL pS󺞘0Ny5\u0008>뼚提4}8᪓\u0001.󠅝\u0000𩽼s\u0006j󴛚𦵀혴>􆪒x\u0017M\u0011u㕤裂I\u0008\u0007x0|U.\u001bb|'l\u001a󺹫h􄇔<攁hxJㄤo]g\u001cdUj􏺇\u001a7\u0002𭸙􍷥􆅲\u001a󱖏 ?ji@\u0001􇊵󶮰Q𔔨\u0005<>􍴕(󴛸h\u0017\u0013m*j+፞t\r􃚡󻨕sv\u0014\u0019􏿍󻁨`.a󠁓&𬿥c\u0003S\rEq\u001a=Zc𭽷ᓭ\u0003v뾿\u0003\u0017\u001e\u0004 󷹞jMt􅷙O鐖,䷔𫝅_>#BB𝣧-t󵎭𧯌\"q@󼆲􏪍ꏒ𮄿%,󲭳9z𗬪\nM𠹦󹗗p\u0001􎎕p𒎋🢠\u000c𖧔r7+󵚫\u000fX\u0012\u001aPtOj\u000fZO@'󴙎󿧺o𡇫󴖀P􆂭\u000cb(skyZ羚b;@􀬻.\n4v'gD󺌴9\u001600Ih|󼬺䡁a\u0002t\u0015\u0008󷬄XᡛQh-m冕@犽q\u001ew=:󸾽\u0016𦴍&&n\u0018\u001e\u0010\u0011\u0017樻􃫌􁟆*zQ\u0004`O󷪤|%[\u001a󵶉\u0002x\u0013ezypH4󺬣\u0016<\u001f/wb\"𬛯\u0001'􁻚𨣢|\u0017𫛍\u0005S\u0018[\u0017D􄞭🔀{蛦(\u0016g7u \u0007pvj󻲮Vr\u00168󳔴\u000f\n󶞵j𦑣,𨚀Nn\u0000d긕^]#\u0007a}k^𤐺ZPzT6|JA\n4w4󲚎𨮄R^z7㤘U\u0006􏸭䵇ᒸ噑𦓩W􁭻-\u0016𧋎L󴶖\u001d\u0001􎢪\u0007\u0011᧞5p\u001f廖V&I𪴪\\ #\u0014J\t􀕖pb.󶮫Y=\u0019B󳋣󾆆\u0017\\\u0003Fu3=fgk0tHMV󶝷L&\u001c􇥘𨹼𗢿u󰦹􉕽#$\u001aHr\u0015bC=󽌨𨔘f}@FOXE㵮b􌝩\t\u0004󲫒\u001a'0\u0001ℛ\u0004𗟤|UBm􍏼U.0󽨪௦0ᕑqC5𨭔qTEeK?Y󾲺V!Po𭝇y󵕀󵰈􇘖)>󳰣\u0001𧞞𨪂@\u001b\n>-q\n8\u0004󴸒E*/󵨱3\u0019q:JRP󰊤􍹁𮡸L떘yl󲕥!Iczg\u001b嵟Zdc󹾲󲅶IlG\u0010fwx釒b莳/{\u001a,0𑋄\u00055>䎉􊠏U7J󼸜\u0000z'🙑凇'\u0004௧_f\u0011B\"B{Q@\u0015𘀔𒀝b3y𣹧􇑝W[j𢪶j􃱋[𬉹]\u001a\u0019\u0018{\u001a폓^%󺱔T\r쥑qIfX𒓑w𘡞}\u0007F􌴂\u000fq,󰟞teNy𥏂vM", - "phone": "+251656534", - "phone_code": "KHcnKK_qpFuroGfcTO0nxQ5ntFkICAdG" -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_18.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_18.json deleted file mode 100644 index 00409dfeadc..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_18.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "accent_id": -14264, - "assets": [ - { - "key": "*e􉼖⩣", - "size": "preview", - "type": "image" - }, - { - "key": "H𥩹𫼧_^", - "size": "preview", - "type": "image" - }, - { - "key": "􌡾\u0010S\n𡣡Z􈭆\u0017z20󹉨0S䭮", - "size": "preview", - "type": "image" - }, - { - "key": "Zi\u0002\u0016𩸻#/ힷ}\"\u001b󼞞", - "size": "preview", - "type": "image" - }, - { - "key": "Z𡬙\u0017]NL1t\u0012\u0019\tE\u0004󻓭", - "size": "complete", - "type": "image" - }, - { - "key": "𤜦%9󴱼󷺥", - "size": "preview", - "type": "image" - }, - { - "key": "%y", - "size": "complete", - "type": "image" - }, - { - "key": "\\H\r8~4󳐰䒩V", - "size": "preview", - "type": "image" - }, - { - "key": "`j乄", - "size": "preview", - "type": "image" - } - ], - "email": "@𥧧󽏧🛆􆢸", - "locale": "rm", - "managed_by": "wire", - "name": "!1\u00181𣌯=o/+􉤄(\u0013\u0013f\u0010ꃕ⁛𮫊󹉥;=\u0011\u000e}\u0019􃨃Vla\u0014𩕉{xx 1rYe􀥯K/", - "password": "\u0002嶔-\u000eyRe\u0017\u001b\u0010E𤫵/-\n\u0006\u0006z\u0008\\)󽘙:z𫁙􈐣W~\u0017햳yU@\u001e9!􌝚S&\u0011U\u00023f\u0007𬃣D-:8x Z\u000b𣢘y\u0007󲷵t𘨲0󹴩\u0018LvB𢨰􀭒`dq𖬥\u0008@Dh\u001e^𬝋!Zrdy&郧njK𨊤󾾈c>k\\󹈓a'{?􇨚8勤2󷮛\u0010{0倦<𢫧𒈂Jyp󻖟C]{{쒇EJ2qᎣm󲞣8\u001cj?\u001a\u000fq𡋃%󳗉\u0015c𛰡󼠉B#D􅩺d[)H%1V\u001d󼠦Ul􃑐􄳌i\u001b綝쾞}1\u000f􆖍e_\u0016󷙥􉵒/\u0011h􏑦\u001bniQ𨹤/z\u0015BHL\u000f\u001e\u0002􌸙󱋈􆴮\u000c졳$𡧼\u001f\u0005\r\")榎􂯞\u0016𤽱󵔈ZTY^􎓡E󵌽\"ౕ\u001a.;;ꤍvw󿫥7𦝤\\\u0002]󾹘Sk\u0011)\tx'b󳄑􌙿󹑢v1L'b\u001a𬶜.t%ꇜ􀇰\u00141𥽅}\u0019{{/0\n据A3󰝺f\u0008󷣦􋚸\u0005𪖗𡅪\u001e􋯁仺bC/𗾏𐤉_~䆡>􁨨췤l\r𗡻洊6Sl\u0019\u000f𪒦𥽙 IR57\u0004\u000b=H4h>%􊯽Z𦭿\u0018_󼼍\u000f􅩈Q8e𭙏\u001dn\u000c\u0008y󳾚𤟝RWn\u0007i\u001a\u0015󰜡\u001eVG{󾘝,Sw=󳵣QB1V\u0004eb𓉷+\u0018A鄖bR\u001bᮺ󿣥\u0015\u0000&󼉰w\u001e%\t𢹽`*󻚤e:􂪞Nbk\n]tYJ\u0006(n\u0011(2%ﻲa j`)\u0010􏓓􋨼𭸺c'􁾩k\u001d\u0010wsz㊠+󻧍7𭐐𩱿\u0014R\u0017􏪧n\u0010B=\u000fj{􆐎05㿱w\u0014X󸊧\u0001\u001f𧖢\u0016{d2c\u0014cn%qT𐳀N💢빻0􂷖P9N\u0017\u0000e9!🩣㕀2\r\u0007@U\u001c\u001d𘁝Z\u000b=(w┭\u0008\u0019.)Lp􋦥RJJ\u00142􉪈\u001d𪐀A\u0010\nZ\u001bx􌢻f1b鉧cn3>9}eተ󵤾\u000b\u0011]K[\u0012h􁇞C􈬖\tQ\"@hDY􎈯\u001c\u0011\u0003sY@\u0019OAc\u0019)k\u0011\u0008r9~q\u0006R~􆛃m=󷭉$𐡵P#s\u0010lH\u0004K\u0015*\u001f}z䓠拫\u001e𭎠W`U\u0012@ワv.e7\\\u0002UQ\u0015󿣴\u000b^C%&[9p\u000c_\u001bg49)\u0003㘧r\u001b𫼋8󾦬V\u000bX\u0008qh􆀾\u0011|\u0018􀞾{0榪-\u0012y\u0010tH&P󷿰x\n\"G\u0007\u0004m𨍓鏠󿨨;#G\t^sSr𧹒c", - "phone_code": "ZdxnNFLHOnpzlZ3zpURGlFYKDDX3bA==" -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_2.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_2.json deleted file mode 100644 index dcd93abb676..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_2.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "accent_id": 83826, - "assets": [ - { - "key": "􀻍m", - "size": "preview", - "type": "image" - }, - { - "key": "9\u001bu", - "size": "preview", - "type": "image" - }, - { - "key": "B^A𑲔*", - "type": "image" - }, - { - "key": "a", - "size": "complete", - "type": "image" - }, - { - "key": ")6z􏟊", - "size": "complete", - "type": "image" - }, - { - "key": "󸣓\u0011l砎f9\u0002]a", - "size": "complete", - "type": "image" - }, - { - "key": "𪫕󳩣󽸏5n\u0017:\u0004𫐛ey`", - "type": "image" - }, - { - "key": "\u0015荤|󽬄𢍸.􉕪󹋀\u0019\u000ea", - "size": "complete", - "type": "image" - }, - { - "key": "𬢛囹𨜴+*", - "size": "preview", - "type": "image" - }, - { - "key": "\u001e\r\u0019RL?𑣪꺈𢪥\u0012\u0017", - "size": "preview", - "type": "image" - }, - { - "key": "󰫻\u0006ois\u0005.𧢦,\u0012𫅎wQ8ˣ", - "size": "preview", - "type": "image" - } - ], - "email_code": "", - "invitation_code": "diTpWbMfSg==", - "label": "\u0010w𨢍 4\nṝ6\u0014>0.\u001b\u001bR\u0015", - "locale": "pl", - "name": "ﱷ􇅥TL󱕶M9𢀝+\u000eꄄ󱁤P\u0012𮝸惡o𞄃󻉘0\u001d\u0015󸸴d\u001e𭩥'&\u000fc𝁝\u00005􄐳sRi&_lྔj#𥈌M\u0010j`󵧸Y􌼿<\u0006󱜥2/\r\u001cbE鯕|n\u0017󰌩.Q\u0016\u001e,𢷚S𨧺𣳤3𦢜󻕕츤yg-h,", - "password": "2\r+7k;B\r$=󶸡^j);._bux绨.硖ohh\\m⦗#􆙚\u001bQ\u000f\u0000(\u000b\u0004g\n=𭃾>.`\u0005u2_\u001e\t\u000c1%a\u0018\u0011𧔞(z𢋰\u0005+e!sク􆈨\u0015)\u0016?V5󶋖󲉖e\u001d\u0004aZ줦#􊃥W5ej\u0019\u0015'()‧9=%i&K=\u0016\u0004+\u0018\u0013ti\u000e\u0018(G􉀸E;𬣩\u0007􈋿fw嗘\u001c4vM`B\u0005!,吉g=s\u001e`6󼑤\u0004qJ𧲁\"^W\u0013𝆂𡨆7.\\惂y5\u00100\t㲷fXk+󾅔0JFKHU1_􌨉荍3\u0000[mjLZ󹽑wꢩ󳵴O\u0010\u0015󱤿󱯖w87\\ms\tv\u000c𬏦\u0010􇸧]\u001dY\u0014.^\u0018cXz3􉯴wFP󳆝\u0014DED󵆖~s\u0004\u001f\r\u0011T?%]f􂬗R󳕮\u0004\u0014Nt?&wk\"􆻜V􈁲R_lO󵥪\u0015|\u0015O,\u0014󲍤0󽣍{󽧗󼉗󶘖􌮣\u0018\u0008\u0018\u0001𠰭\u000eF\u001f=𩠦𢂨zWGwm\u00101𭬝z%\u0017𠐘&\u0010􁖑𣷥𑪏\u0017\u000bl\u000530L8u.6󺺃􃋚𠖣\u0014P쥸\nUr;@\u0004@􊚆󷗍q DB􎪙7􏻽󳋮)T\u0006+𘓨\u001e?守 x\u00152\u001bo}\t*0􋖱\u0017[\u0008>\u0019h\u0001!\u0018 {H'\u001a􈨓1Bj0L\u000bDf𭻡\u0016T\u001c𥵛+/B􁏎멲|vE-🟧d`JN5}*n+a@sw覩Ll𡇖*B\u0017!'􉯓R\u0002RHv=xl𪰽)▀󶘽=J\ru\u0014ej1\t&ᗃ;\u0002eFIc|:􇷚T􂛉Qr𠹤u", - "phone_code": "f8P9kJNmXRDbYKMdk-M4-uszmYmBIHZ4hLmc" -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_20.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_20.json deleted file mode 100644 index afc9fa11247..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_20.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "accent_id": -14182, - "assets": [ - { - "key": "06m\u0000𩼄", - "size": "preview", - "type": "image" - }, - { - "key": "􌯪1?9t󳴤g\u0011\t\u0007\u0001\u0015`g", - "type": "image" - }, - { - "key": "92", - "size": "preview", - "type": "image" - }, - { - "key": "9􀣢\"B\t1󴂷|", - "size": "complete", - "type": "image" - }, - { - "key": "B ", - "size": "complete", - "type": "image" - }, - { - "key": "\u001ag", - "size": "preview", - "type": "image" - }, - { - "key": "[\u001e􎯪n/", - "size": "preview", - "type": "image" - }, - { - "key": "嗿", - "size": "complete", - "type": "image" - }, - { - "key": "􄦨3", - "size": "preview", - "type": "image" - }, - { - "key": "!Ἓ|R!81", - "size": "preview", - "type": "image" - }, - { - "key": "\"U))K𡽢\u0014`P", - "size": "complete", - "type": "image" - }, - { - "key": "\u0014\u0000𭕂󷾡癎􌼏D@@", - "type": "image" - }, - { - "key": "M\u0012,\u0017\t篜", - "size": "complete", - "type": "image" - }, - { - "key": "&𘞣%e5", - "size": "preview", - "type": "image" - }, - { - "key": "Fu􋕾X\u0006󱯴8wq", - "size": "preview", - "type": "image" - }, - { - "key": "L", - "size": "preview", - "type": "image" - }, - { - "key": "FyZs9暑2\u0005", - "size": "complete", - "type": "image" - }, - { - "key": "B\u001fZ󰚌o\u000c\u001e-􋽳", - "size": "complete", - "type": "image" - } - ], - "email_code": "u7kZwe4BWVUT4ofDJg==", - "label": "\u0012눎I'\u0015\u0012,\t|", - "locale": "pl", - "managed_by": "wire", - "name": ")Q>\t\u0004􀲻O&G`)wJ􂑑󼄟󺅞𨐦~\u0002V.􎎑e+d\u001b𐃢󽁉󹫧g[~𠦱9𠗫QxR\u0017HMtNg\u0015𠨴H𮥄_x󺚍ⴔvx3\u0006}\u001bNo9Pd\u001cV>", - "password": "$LQ\u001e@󻗇Q𘪕y5𠚒T\u000b󿯉mMd􆌍6@0T뉊}S𞸲>󰣚󾱏\u0007C𠈢\u0010=m:$^g󳁻N\u0013Q\u0003\u0013>]hmg(謧Ae\u0003𘃴@-m\"@\u000b\u0002훵yY􂾺]\u000cby1괥O􉃨ZO⼄󸹨:\"&廊􄁕\u001a𡿐a󾦪qE\u0011W됽gBʰ5MTꉚI𪟗􎍬;\u0007&2𗈒`;Uy𠑯𝜁3\nࠅ󰇭\u0016\u0012Ʌ𑖞k*\u0001v󻿘\u0019\u0005\u0012􄀧\u0013]+鴰'𛉣􇳷,", - "picture": [], - "team_code": "B7ams5fFLxcw1iSuEZIpbQ==" -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_3.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_3.json deleted file mode 100644 index 404946de1d1..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_3.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "accent_id": 26132, - "assets": [ - { - "key": "\u000c\r", - "type": "image" - }, - { - "key": "Mt𨡳y𝦞4&\u001e", - "type": "image" - }, - { - "key": "󷀶󲪁-\u001c\rK59(", - "type": "image" - }, - { - "key": "j\u0019\u001a𐢝𦴬󲅬a8ࡐ\u00144V𝧨y󷰭", - "size": "complete", - "type": "image" - }, - { - "key": "6􄖫\u0008󺕠4\u0010", - "size": "preview", - "type": "image" - }, - { - "key": "`1j'C3'}\u0012", - "size": "preview", - "type": "image" - }, - { - "key": "e", - "size": "preview", - "type": "image" - }, - { - "key": "*B", - "size": "complete", - "type": "image" - }, - { - "key": "𦳢C𢭴䕜!X􌧴\u00014\u000f+󻉢", - "size": "complete", - "type": "image" - } - ], - "expires_in": 13846, - "locale": "kn", - "managed_by": "wire", - "name": "&W\u001aQ𪕧A3N\u00164Y(Z,\u000b\u0010\u000bpv􉀕h\u0016𭛂^`P:\u0015r\u000c_𡟿,􉈈&󾔪󽚸憿8\u0015ixb\u000fhE􄱫\u0004󹀄ᎌt=𤟠󲈡\\푥iX\u000b\u0017𤥓\n膀`acU'鎯\u0007\u001d􃋿\u001d󼜝4fGC-", - "password": "\u000f􂤾\u00122\u0019x𧐵[Bo_I+𭂢(\ti􂋠l\u0008𡎅𭯢𧟴y󶗓\u000e\u00162/^\nN\u0017jꓖ ᄌ+I󱎓󴾀펌E)+𤬙􋘗\u0004C衾􎩟ᦘ󿿔E%O𦂃+e\thZ􏰴\u0011􌎇\u0001p@얥𤌊\u0007[\u00028F󳧕 45𦺩\n\u001a^*1h𝢕󰵭g𗤣d\u000b=𭁗UM\u001bi𮭗\u001d\u0010󺑸\u000bb0vV\u0017󾋗7􏜜8W<𣘏瓪􊁅d\u0017󿮿󹳜\rh􇏬qr[𦝫+\\)a7L:\u0016\u0000D@@Y$\u001fn􄮛\u0005\u00015\u001b3󹼯uC-t>\u0014\u0002䜯􆾄2]\u0007󹯴専VK^Pd𨯐Vp𫨮zW􄵌(󾪴9`x𫾐󰕯\u0011󶤂<=LP\u000c󸪋e\u000cz=3<𥥯e𘔭5.A▿oL\u0012]􌹸􎝕\u0008{cDQ𐳰굏G󽰇qf𒂥_f󰳪D\"\u0012u\u001a\u0005􀅹++Es􆔀\u001e<󹨜?[j\u0017\\󷅛\u000f^}5𫤀𢊿k\u0000\\X\u0019􁛃qG\u0006+\u000e\u0003\u0012U狾!:\t._󶲩ېﲗS.!\u001al_󿢏\u001a󹥾5M𡼄𮁛v^\t\u0008`P-蕕𬜱𢠟𨥩𠄖𨗵􄂴(Zo\n󾞿𩂸b뱲\u0018\u001aS􉶒O=U􁯄Y]󴞰󹟛.N\u001fg!\u0014L$VbD􆜪\u0000p旰\re\u000c䎕Sz[㢵>\u0016\u001b\u0001g\u0012𫝝L.\u0004Uz󴔟\r\u0019\u000e🄇X􇎤8{|\u000fU\u0016$Q!9\n\u001f󹲱桗\u0006'_w]\u001bQ|:\u000b\u001a3H󼟱M:d\u0000󼲝OkD\u0014󵌄4\u001c𛋅󱡐屬p_𗄗M", - "phone_code": "6xSzqRncYoN4AWAUeSKRw5ZKPWz8PBSQkOx-", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_4.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_4.json deleted file mode 100644 index cb07c67607b..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_4.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "assets": [ - { - "key": "󻥂m􄼋𣴄I尧<\u0012Ww󳔒I\u0006U0", - "size": "complete", - "type": "image" - }, - { - "key": "\u000bMBX6[\u0005`o𫲒yW)\t\u0010\u0005", - "size": "complete", - "type": "image" - }, - { - "key": "k\u0005M.\u0001^\u0011\u0000", - "size": "complete", - "type": "image" - }, - { - "key": "z\n\u001aa얿{j\u0013", - "type": "image" - }, - { - "key": "󰮪*s)\u0016`", - "size": "preview", - "type": "image" - }, - { - "key": "󾯎󳩁󲖰3\u0005 \u001fo,󿖪;􊊱SF5𝕀", - "size": "complete", - "type": "image" - }, - { - "key": "𠤵􌢛", - "size": "preview", - "type": "image" - }, - { - "key": "/\u001e􀎥貐Q]ppr", - "size": "preview", - "type": "image" - }, - { - "key": "'u\u0013:𣊌\u001c\u0002󿆘o.椉􎵓v􍌋\u001c{\r\u0005", - "size": "preview", - "type": "image" - }, - { - "key": ".&Vc􈆱", - "type": "image" - }, - { - "key": "\u0011", - "size": "preview", - "type": "image" - }, - { - "key": "*\u00081Mӹ3\u0012󽹢[F􎑫", - "type": "image" - }, - { - "key": "鋍\u0018z󼩮M^󿜡Wdc􇊾6\u000b~𪬓c\\", - "type": "image" - }, - { - "key": "h笓&;b\u001du]\u0019t\u000c9𪼕.ⓕ n%", - "size": "complete", - "type": "image" - } - ], - "email": "󾏙橭5h4@I㎛\u001e\u0005L\u001d^i\u001c\u0013{", - "label": "\u0000􉴵vK\u0016󽵋壋", - "name": "\tP\u0002\u000fꃦ\u000b\\\u0016?`U\u0018t<7[i󻚇\u0012\"𠩲L\u001b+Z<_㈙M󴤩𤎺5Y陡󿋃`/0􇪘.\u0017],N?U_𢁛\r&􅞃j폚\u0003羜U!3vXgT𓀐𠋒\u0012@?龘󵮓麊\u0011\u0000𠽟㚢G\u0019jM~\r\u0017]S\n8\u001fkmi", - "password": "\u0004\u0014𬊽2􍚻􇟢C3\u000eB\u001am0󱟠?[9kX鯊󷑥\u0019𠳴gDmi4n􆋸VH󷝠\u0019l\u0006\u0000𪫕\u0007𮞏ट%\u0015+5A/Hꨮ!2\u001f\"V􋱮瀽󷾨𭘛Yet󹐼=Q\u0015$o=Pg𑈁􀓐𤵗𧸐#\u0000;󺨿\\󿎙R䯇󴉎-󾔐`;0󴶂驊T󿓦􌵨󺆠𥪀𡱺0\u0019EM󰾌I\u0003첐9O\u0003􇿶? s&󺸁獉#6ﮝS\u0000j)Lp𛁎􆘽Ba$\u0014H5􇲏e>[󵓡\u0002𝘾__􍜓O󷥃Mi+NQ\r\u0006o@𩱺岫pX􁿧`\u001co󹶾Wbu\u0003W61𮟦`\u000f$􉠱q𫥕9", - "phone": "+900959711", - "phone_code": "2HSeS4jKke89LUPF1_upoD2sztr2wqUm1wUagZKM", - "team": { - "currency": "PAB", - "icon": "󴍲]𢡆󽼽v7􈗵󰴳󺳟.􀂌,A\u0008\u0012C-\u000bX𭄯9\u0010\u0000?\rK􍂶\u001bg_m\u001e\u000c\u001b\u0003<>d 2𩯮h.,\\㯨b􈔌\u000f'.j&巨'`\u001b\u0004NA\u0008", - "name": "T󾨣y+f󱭄Td>#N7P\u0012\tU:T#􊡏Ib\r􏺀\u001b7e󼎌􌪵\u000bTr\n寎7>Kp𘜺H#&\u0011-A+𝋪MD𒂉gbmyh\u001bzHtUH𫋝\u000bO\u0001茶\u0013b(l\u000fA\u0005UW9s\u0003㰚𢌊𣔡󹓡1󳆂䥒􁳺\u0017\u00110ᅖ\u001f𬴓f󴡃Y𠟯\u0006𗨫z7\u0004􋪻DY􉈟􍚡PT0\u0000󼩼\u0018𨍎a􋗌\u000ec\u0006%U󾵮Q0{4󶬀!\u0003\u001ahTV󸿊\ti𪞓4NX󴉍\u0006\\3􏈕q󼨯📑􏼖22^I\u001d*𗙐WK\u00071𗸾i6\u0010!𣴪\u0015hHfⵦ\u0007󲳕G\u0016⯨󸗌􆎀bXw􍾡󴆴\u001b]r{􂠂u􈄒󸾼󹈾G^^&𫛮\u0011l󲐦󵢁D?*\nz𭞬^𤡨󿮛𘌟[S󺎭󰷡𩖰t&\u001dxd$\u0005􄊀\u00080ꖻA􉵣󶡜s\u001b󵊡\u000b$𮪳4󶀳\u00182@\u0017\u001f8|" - } -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_5.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_5.json deleted file mode 100644 index 8e82f596f7d..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_5.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "assets": [ - { - "key": "\\fDs.\u000e;]𘈖\u000c\u0010🛉嘪+𬶇", - "size": "preview", - "type": "image" - }, - { - "key": "𫪼WlMjr$~", - "size": "preview", - "type": "image" - }, - { - "key": "%􏌃H#𘁣\u0001􂂤d", - "type": "image" - }, - { - "key": "\n0\u0006", - "size": "preview", - "type": "image" - }, - { - "key": "`E_󽵷gcy`La%\t", - "size": "complete", - "type": "image" - }, - { - "key": "􊽲g􆡖\u001c)甩M󿂸C", - "size": "preview", - "type": "image" - }, - { - "key": " \u0012yXO\u0004f9\u0002𘟍\u0001D", - "size": "preview", - "type": "image" - }, - { - "key": "@OV𠴒wK%&", - "type": "image" - }, - { - "key": "㋪!󻫭􊋠^\u0008_\r=~", - "type": "image" - }, - { - "key": "\u000e*㾉\u001f\u0001G`\u0010O+R`Q_", - "size": "preview", - "type": "image" - }, - { - "key": "􈑄_O&g*}", - "size": "complete", - "type": "image" - }, - { - "key": "QLDr\u0016^gg", - "size": "complete", - "type": "image" - }, - { - "key": "􁏦條􂘋\u001dZ0RnH#e𠭈w\u000b\u0018󵒙", - "size": "complete", - "type": "image" - }, - { - "key": "|EZ:􏌢\u0016r", - "type": "image" - }, - { - "key": "/n\u001cSpZ", - "size": "complete", - "type": "image" - }, - { - "key": "o\u001a/j!󻆔싱󱾼䩶", - "size": "preview", - "type": "image" - }, - { - "key": "\u0018𤹳\u0007\u0012𩄏.󿎟󹐬𮓛\u0018􀦕J􋥇7󸓛X", - "size": "preview", - "type": "image" - }, - { - "key": "xv𪉵\u0010󸪠Wh", - "size": "complete", - "type": "image" - }, - { - "key": "g9螮", - "size": "preview", - "type": "image" - }, - { - "key": "CAi<ﰷGV󻃶}M", - "size": "preview", - "type": "image" - } - ], - "email_code": "rn0=", - "expires_in": 183097, - "invitation_code": "rSv20mRblPLCYnVt", - "label": "", - "locale": "io", - "managed_by": "wire", - "name": "󹘘󴇎サ\u0019^쀚H-9o\u0018twv󲶺\u000c@6􀄸 𤱝\u000b\u0003b\u0015󼇻A* ~D)􆖺IX,^|e󻧳\u0014\u0014\u0006#\u001c\u0016􈻴𒌓󿛲O󱎊\u001cQt%\u000b-\"\u0011🍆g9\u0011Ss6n~Y$m'\u001e\u000b󰕀Mm.`亞\u0017\tYv燦:2fg'\u0001􀁠?\u0007km\u0004\u0000\u0004𐬄𦃔\u0006ie93\u000b\u000b󴁕\\U󻢋&irA/\u0014tdP𣔪l􃘑J!𗭣󼶏\u000c𡫔D+􁅝i\u0000Q8\u0000]1{\ttD恥{\u0002\u0007\u0000\u0008\u0015Y\u0008\u0000v􏯮􋿃᠑􇱉f~\u0007Gua(Q\u001c렕H🐟ݑ斌\u0003'Q\\39W~𠎝$&􋝌Mhp<\u0005󳠒8{c+uj𓉝LJ\u001d0.\u0000\"\u001a-䄯r􏜰R\r\u001b􉈝.]Ʌ󾄈\u0006\th[\u001eO󾷫Ꞑo\u0017󳗮iT\u0012\u0002F\u0003\u0018\u000065苗\u0004Y󼨡\u00023􄎔g\u0010kn;;󰬻[rGNM1\u0017➜y'#cw𘏛\u0003w8Xp\u0015Mv\ni\u001a􁑫\u000e\u0017\u0008󼆲j8ꁞ󴂩뗨=TYHq󲊢~'\u001e􃏖\u0000I9𬉏\u0008aoZ\u0007󹥥]\u0018􋛦J,g*N\u0000|ad詅\u0015H0IfuH?Y=^h\u0014𡷕'\u0017􁢴@\u0005􌯘퍷[_?p􌎯󿳭􌧃󺀟&S\u0013􄾮)弣\u00198Xb\u000c!,DL􏱆\u001aY>󴽨\u0011mg&󲏝􈷎$\u000f\u001e;|􆨥!y|𨙭\r\u001c󻥸󼧨󱭼l𑂻f\u0003鈏#P(\\\u0007\u0014ce\u0008Ieec2\u001cc\u0003K~\u00006𫕮杂V\rqV\u001c􍲪rz}l࠘\u0011󽼑*s𢚋􀡷\u001d[󷍡\u0001f𤴛?󵽆󵩒\u0014*BK𑀬󿱊w6C\u0019=>輩", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_6.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_6.json deleted file mode 100644 index 8ff54e28046..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_6.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "accent_id": 24037, - "assets": [ - { - "key": "\n{{\u0018\u000c}-(k७H􎆵", - "size": "preview", - "type": "image" - }, - { - "key": "m", - "size": "complete", - "type": "image" - }, - { - "key": "7󸔩\u001c?R", - "size": "preview", - "type": "image" - }, - { - "key": "\u000bJ\t\u0015", - "size": "preview", - "type": "image" - }, - { - "key": "\n󼴟\u001a#7ើ\u0013\r󼐾\u0001\u0003{𩔙W", - "type": "image" - }, - { - "key": "?𝙁\u0012]SA'T&", - "type": "image" - }, - { - "key": "$P𥲲󷩴2\u0002b\n=󳿝\u001d/", - "size": "preview", - "type": "image" - }, - { - "key": "t𔖯\u0000𣒦A", - "size": "preview", - "type": "image" - }, - { - "key": "\u000e\u00154x:m-Q5󹎡Xw𭺊􏝼<", - "size": "preview", - "type": "image" - }, - { - "key": "􏶵", - "type": "image" - }, - { - "key": "%􊒠N󷧺\u0011", - "size": "complete", - "type": "image" - }, - { - "key": "\u0010hB~㸾", - "size": "preview", - "type": "image" - }, - { - "key": "4𣒣_\u0000O)oc9V\u0007", - "size": "preview", - "type": "image" - }, - { - "key": "\r8󵴱F@v󵇜r\u00138", - "size": "complete", - "type": "image" - }, - { - "key": "mp\u001a𗥚n\u0015Q􄸦7{7W걣)8", - "size": "complete", - "type": "image" - }, - { - "key": "宦z\u0008\u0012ﺊ􇹀", - "size": "complete", - "type": "image" - } - ], - "email_code": "", - "expires_in": 217311, - "invitation_code": "XYcMU-BCwqn3aNTQPp6q0KU09PhX", - "label": "#l𧔱r𢘌9\u00111󲙘𬴳\u0010y_\u000epw􈢧4PowP\u0012- ;m$\u0006\u0015", - "locale": "he", - "managed_by": "wire", - "name": "b\u001a🜤5{})\u000bqe7\n*M,!i\u0019\u001e𧛲~\u0018𘅫\u0000@󾽶t𡊅Bb|/b벂󽦳'W𤟪[]\u0006󾐶W!]>l󳙅泳,\u000e:\u001f𗚄󷡴y󹇮Q+|`Q\u00156󱀵>\u0016k󴤈a6𭛔oCQ\u0019y󾕒\u000c\u001a\u0015A\u0016Z>W󹄗9\u0012 P\u000e0\\𩇻􍇘󱆎>\u0012m\u000f\u0013SC%C󾞴", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_7.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_7.json deleted file mode 100644 index 2d34192e6a6..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_7.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "accent_id": 30744, - "assets": [ - { - "key": "[z\u00179)", - "size": "preview", - "type": "image" - }, - { - "key": "Q𘄎;'鋻N", - "type": "image" - }, - { - "key": "{", - "size": "preview", - "type": "image" - }, - { - "key": "r𒐔Y􍮅\u0014\u0006", - "size": "complete", - "type": "image" - }, - { - "key": "\u0017v8*C", - "size": "preview", - "type": "image" - }, - { - "key": "K", - "type": "image" - }, - { - "key": "\u000e􎘙P𪎆;t&g󹩽(", - "size": "preview", - "type": "image" - }, - { - "key": "0i\u000c\u0008-E\u0005R睫2j", - "size": "complete", - "type": "image" - }, - { - "key": "\u0002BK𐐶#\u000b'䗜\u0018z𨒘󾁟$jH", - "size": "complete", - "type": "image" - }, - { - "key": "@>r\u000c%", - "size": "preview", - "type": "image" - }, - { - "key": "\"9\u0015𢂿ci󼡆3\u0003ARh\u001eX", - "size": "complete", - "type": "image" - }, - { - "key": ".", - "size": "preview", - "type": "image" - }, - { - "key": "6#\u0001Ho雒𓌊", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "FO5A", - "size": "complete", - "type": "image" - }, - { - "key": "Qe\u0011DK\u0015,X\ny\u0019P􍴪", - "type": "image" - }, - { - "key": "󽽘\\1󺺢d睾q\u0014𒎇", - "size": "complete", - "type": "image" - }, - { - "key": ")RU1?󽫛r ^$Wq", - "size": "preview", - "type": "image" - }, - { - "key": "h76F\u001b", - "size": "complete", - "type": "image" - }, - { - "key": "'궦\t􍎰", - "size": "complete", - "type": "image" - }, - { - "key": "\u001cZ^+\u001f\u0002𑊑V_Z􆥀n", - "type": "image" - } - ], - "email_code": "pwYYlQn1WDrF_I02s6jDhkfLyudwpqrum063eTo=", - "expires_in": 406641, - "label": "cz\u0018*[|&󴓈\u0019E\u001dW", - "locale": "ig", - "managed_by": "wire", - "name": "IO󹧈K􏓲g􍔍J\tiZJ\u001e}0'A\u000f\u001f𓇝𠜊`𠪒zNo􈰃nb󳹝@\u0017\u00158ᇾyCz贛?!\\똼S\u000c󳛂H𡩕b\u001dv\u001d𠀛狽o扻}䡅'\u0008*M_}\u001f𝕍􌬳裕V\u000c*钬K2𝧞K_#77]-&𗋂𢏇뀱`𐭠􃯟L\u0002-󾎣>𘒲𥲴QC]+wqU", - "phone_code": "0fz6tQ==" -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_8.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_8.json deleted file mode 100644 index d24f15fb0e8..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_8.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "accent_id": 121476, - "assets": [ - { - "key": "D􅅱3q\u001d𠣞z", - "size": "preview", - "type": "image" - }, - { - "key": "W*=􍖰P͔󽉕𨨐", - "type": "image" - }, - { - "key": "斠D󷧞i\n􄞢sG\u0008", - "type": "image" - }, - { - "key": "󴌜嵅X\u001a#CcL\u0006ᣁ\u0002\u001727􂰦", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "j>!i1", - "size": "preview", - "type": "image" - }, - { - "key": "o\u0013w", - "size": "complete", - "type": "image" - } - ], - "email_code": "ynbMi06R2nC6tta6KB4=", - "expires_in": 419615, - "locale": "sm", - "name": "1Ox󼼎\u0011+z+\u001fqV\u0010", - "password": "z𠤲󴮁󲳗渿𝨗𨏟z𥬸\u0003\u0001e𬱗S𮈮ぽ\u0008\u001c𛀁𫑐\u00194(CD{𥵖𑃢8䓘/\u001a\u0003􆱰󷸓=\u001d􆕍#\u0013\u0004d0L,\u0017W.*􏭥Y(\u0014~L1J\u0003m{t=VRᏢ8yꘪ𭼟]Rv(Q\u0018􆾆\u0018\u000c5\u001e(u6OMe\u000b\u0002\u0017\u0008f)ᢃ]u􎪧⛲\u0000\u00147𨛓L𗂬%Gd󾡄h枃\t\u001d\\􇟊Y\u0004>RYX]𖭑W/[\u0010𝇕\r}\"􈽉W[$\u000f=Xr&࿗4󼠾\u0005\u0019^𤢒%4𗶈\u0016𦠡;:g\u001eo\u0006\npm\u0015Me􋘉𥁡;󸋺𧈘R~􍆃\u001eE8;%󹄕j𪳟𧢌\u0001󷃅kJ𫳀􎔢𡄇L󺦆~j\u0005\u0013g릎tP𗡦(qn4𡞏I𝕕nE\u00101g𦖱𤀦S\\\u0004搼H𠎩瞭f/_􁏴C-;r\u0019_6􌳥MQ|𡉘\\gY\u0017x𫁼TqT𠡫_b\u00165\u0004d􀰞](􌥣󿏽Ou\u0014d\tgvU𫒍\u0019k\u0016s\u000b2\u000cla􈾂\u000b\u001a{US%󻵥󸼫n\u0018燃<\")\u0001믵k\u0006H𮬩7\rl\u001a􀬙-𫩚\u001a􉮝󼾉2{T\u000cO𮒣Qd|𢂷>󰭨🕜\u0002)𡊊􆪸\u0003􀚩R\u000b\u0018𧐹𤬹u\u0007\u0007U\u001cOj` \u0008\u001c\u0001\"\u0010:Kw\u0018𣆝잊璐2F祂\u0005g𪕬􌅥u󰏮唦󵵞xk\u0006\rAE+$\u000f󲤓𘀻󹨌ja\u001chL􅶫\\T󴴺WD((bZ􎉵V}\u0004\u001d_?􊾱\"5A󹓲\u0003n􏹇hv<;rO*\u001achIS7[\u0016|\u001b)\u0006A_\\?vC!u\u0011錣\u001a\u0014컈􏕊K8\u0012\u001a<@􅕡􄙊󼊌vZ6\u0019\u0018󾑞*3\\𡈓\u0003\u000b2󼇵󸼀\u001a\u001d}\u000b𖧻\u0013P%ዢ*\u0014\u000cQ\u0004㆐􊽡\t󸨖{\u0001𫮒\u0000/{\u000eoJ3\u0001H5-}𥍙𨌜\ton\r𥦗𩣲OV\u001d)w𣐂t\u0007@d\u0016\u0007饡􄩓l嚽2`\n󴠔Q燷󰺯V\u0015\u0018𦸂󵱬XB󴠉I􋬲\u0019􉘚𫃾WwX􍍆\u000b~=m0EYY\u0001x\\'𒊼dI􄞸m=\u0011*𤆏e \u001d\u000f\u001b󱌼j\u0016\u000cAI-eDY󴃹𦱛]Y.􅛨Oﺅ\u0003;􀭮\u0004󾾬^꼽\u001b+:Z訅\u001bZp 7=L𩸹Ptx􉟖\"髎2KL\u000bM󲬣C7^Ⓜ𣍟Or*e󾥕dX,^f[\u000c\u00032X\u001f\u0007Fov`\u001a\rj8P\u0017`⪏8\u0018\u0000ྔ.\u0019􊗛𘁢+󽥷L\u0004A𦱳`t?\\j!𝝊e6\u0000f\u001b.`M\u0001퇾N\u0019\u0000\u00052󲾳䬿U氓𮤂)W􃩩􅢬2\u0010I\u0015zT􍝉@3#럎𮛱]NL?N􇚊&𘏗(?𣅻1\u001b􈗺􌚿\u0012F>Fu\u0019l¢5/\u0007𘚍\u00132Z", - "phone_code": "rQKyQz8TBUb9Klrb", - "team": { - "currency": "AOA", - "icon": "\u0018MS\u00089U{Td\u000bPgKDy\u0005#(}GퟸDd/\u0014%;", - "icon_key": "B😺𨬀\u0014\u0005O%O㿾Q𬸋{\u0003m𔖞$A\n\u0006\".n󾩉s𪷟k", - "name": "Id\n40hO󿳐_z\u001a9섥;4\u0002[\nA\u001e𦩳󿹖_.P{\u0011%𤕮􊣴Cu\u001d[<쁄\u0013s6mZ\u0006B!\u0010᧘􀍘\u001f\u001b+󸐃󽝶A𮁄𐊥T,`/\u0008坑𫺥*'\u00000w~k6`\u000b􆩍\u001e􋔾巄n?\u0005\u001a\u001b鱗p?-\u000c.Ba\u0010o\u00155.!𑄎􍀄𓏂T%󷜜\u0005\u0008C\u001fQ\u000f\u0002𗛊횎􍆷i$N􁾉\u0011\u0014\u0018𧯰􈨡鹨AX􋓜\u0006𗖫𒊞Vi4E+'t󽘜/𐎎󿀄6C`󲽦󹫕𝂪獛󳿝D3.\u000b&𪷻`𧝱*Ey$\u0013ᡪ\u0002\u001db=Uf\u0014𤁡\r㣢1p)􇮸cq9𢶟L#󲉂HF𬻊`󳆘𥝚􉹶af\ru\u0006oM*󽚱\u0003􀝊 (\u0012:ex\u0010.~9b." - } -} diff --git a/libs/wire-api/test/golden/testObject_NewUserPublic_user_9.json b/libs/wire-api/test/golden/testObject_NewUserPublic_user_9.json deleted file mode 100644 index 9dc19f0f5aa..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUserPublic_user_9.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "accent_id": 6550, - "assets": [ - { - "key": "𪌦(@Z􁲯𗨘(", - "size": "complete", - "type": "image" - }, - { - "key": "%􄰦\u0014/", - "size": "preview", - "type": "image" - }, - { - "key": "􅫈&5bo럢2$}𤻤", - "type": "image" - }, - { - "key": "\u0016vQkm|𤴖&t-W\u0015x", - "size": "complete", - "type": "image" - }, - { - "key": "|5􎦰\u0018|te[E鋔#S􃫈", - "size": "preview", - "type": "image" - }, - { - "key": "{81􊜳.\u001c\u001b", - "size": "preview", - "type": "image" - }, - { - "key": "@y\u0010k贊'jS*k!𬘤SQD", - "size": "complete", - "type": "image" - }, - { - "key": "z틇z\r&'", - "size": "preview", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "􀰼b 􎥰gGz\u0006𥦡O\\", - "size": "complete", - "type": "image" - }, - { - "key": "-9\u0003'\u0008s\u0018𣜇\u0015\u001f\u0007𤳕>;\u0002", - "size": "complete", - "type": "image" - }, - { - "key": "\u0008嗰삮ዷP\u000cX", - "size": "preview", - "type": "image" - }, - { - "key": "𘃣Lw~8", - "size": "preview", - "type": "image" - }, - { - "key": "\u0013Pd", - "size": "complete", - "type": "image" - }, - { - "key": "Q𥆭Ǖ`", - "size": "preview", - "type": "image" - }, - { - "key": "a\u000fS휡ׅo𗱲", - "size": "preview", - "type": "image" - }, - { - "key": "R𮜬𠧻\u000b𪴒𫞐m\u0005󰢣", - "size": "complete", - "type": "image" - }, - { - "key": "1󸓗", - "size": "preview", - "type": "image" - }, - { - "key": "E%\n\u0012𩙷\u000c\u0000􉞝yP", - "size": "complete", - "type": "image" - }, - { - "key": "Xz􋔩?yV\r\u0013-訥Ⳳ󰳮E𥣻", - "size": "complete", - "type": "image" - }, - { - "key": "􀜆󳈅V}o\u0010\u000bC)k􂀓%\u000b\u0005v", - "type": "image" - }, - { - "key": "5r􍟓-c􇢡b䊸v9휬󻱔z", - "size": "complete", - "type": "image" - }, - { - "key": "-󹏯E\u0012W\u0005}𗾮\u0011", - "size": "preview", - "type": "image" - }, - { - "key": "𦹍󵯈􃓾$U󳽳\u001b]􏻔𐣡𭕨$𭸎󼊖􅈜", - "size": "preview", - "type": "image" - }, - { - "key": "􉀤OMt􊰵􅜑􁼁x\u0011\u000f:i", - "size": "preview", - "type": "image" - } - ], - "email": "􆌸\u001a\u0008(纖\u000e􄱒8n󶤵F𨟣󲛉𗁱@", - "email_code": "X4k8TiOW", - "label": "J􃒡􄳸d􅠎󷐲X𤬰9C?aA:󶵶)􁔃", - "name": "\u0001𤎎~*'􊠛\u0012\u0017A\u001d#0\u0000\u000c8P@忊𘋗󷠙\u0000Ln\u0016![\u00054nU\u000c𝡵\u001c􎌰>%\u0000:𢜿\u0013a󾲛\u000f\u0018𠖹\u001bi\tI\u0003g~1", - "password": "8\u000e􂉐𪍶c􉛨\u00073_i\u0002𫐝󴡿sf\u0006*𢬦~􂠒cZ:聀\n􌊟􂶗󽄤I!Ḭ}zw%\u001e𒉯$𦮤𗀿i􈎚V𘥱'&/\u0017􎪇dU{:X韒N\u000bdaVjT󻖃M|T\u0016,𗰱I[!5%\u0019\u0004WDB=?Oe\u0005\u00110p\u0019\u00118D󰩉p6]몘-GOplF􏶾tcᐩ\u0011U󾛖\u0002=dVF\u001e\u000b\u000b𗒉\u0011A𠙐\u0012􁳦􄏬}o5􇕳j]\u001eF𦗸9\u001bl⪦2\u0007𢡗p󺲇𢂞𬵌LtJ7~])󹲡\u0015O2𠦶PJ􁘯J\u000bsb%𠀵NB1\u0006\u0014e\u0012'\u0010\u001eftG^k\u001b🧩Y\u0019r𩎸\u0015􈐵B􂔉#6\u0015\t󿏱_𠹔󸐏m8럽9HIp⍹\u0001sh􀿮X\u001f+C\"\u0012󰊩F", - "phone": "+14993214", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_1.json b/libs/wire-api/test/golden/testObject_NewUser_user_1.json index aaca16a50c9..6fb028d3955 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_1.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_1.json @@ -1,4 +1,5 @@ { + "accent_id": -7404, "assets": [ { "key": "ᏸ5\u0014󸾲𗓰`\u0007\u001aG{?", @@ -6,58 +7,21 @@ "type": "image" }, { - "key": "KE", - "type": "image" - }, - { - "key": "34A\u0003", - "type": "image" - }, - { - "key": "󸋳\u0016𗥓℆", - "size": "preview", - "type": "image" - }, - { - "key": "bN\u001dj|z*dS7􌷪\u001e\u000c`", - "size": "complete", - "type": "image" - }, - { - "key": "d\u0008,U", + "key": "something", "size": "complete", "type": "image" }, { - "key": "󾜘4𓏡\u0001Z", - "size": "preview", - "type": "image" - }, - { - "key": ",\u0010\u0017kd\n깬􉫖", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "\u001d轖󰨇2", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "preview", + "key": "KE", "type": "image" } ], + "email": "S\u0005X􆷳$\u0002\"􏇫e󷾤惿󻼜L\u0017@P.b", "email_code": "1YgaHo0=", "invitation_code": "DhBvokHtVbWSKbWi0_IATMGH3P8DLEOw5YIcYg==", "label": "𭤐15XwT󲆬: \u0011Z+\ty𗌉\u0001", "locale": "sn-LY", + "managed_by": "wire", "name": "V~㛘钟\u0000w􍻃􇅡1𑵼󹄧%㥫]y*𝧑jqM\u0016𒈔/􎨑-*\u001f \u001eA\u000e}ﭛcv [󹦺t󷇵R𬌻Y󽃈6tg\u0016󿅷+\u0010𘚈;\u0006Oj\u0013뷑&aD:\nf󴯋!*", "password": "𣉙%5T5'䎆᳦\u0005-􃭧𘨛7W@)!$%v{\u000c\n_I6􉱮츜]r􍶔\u0002Gi_L\u0005@tr<讃2Dr䂇\\\u000b8쁽\u0014􅈿e\u0008𮞲𑚜srN蜨旗Qk+赥󳼩O\\c6󼉭X󺩽􆓖VV\\󴀯^􍺔\u0014(P~y\u000f(\nrO󽖎U=$󽩻k󷀘7.\u0015[dn􃊾粷_\u0000󳞑\u000bNVd햲z󻓕pV6\u001e𨭗#/m􄊮w\u0015沐u𣎯\u000fs\u0011𡔱^A𗔌>\u001a#\u0019sC!3#`𧂅q𐅄\\VrnT\u0010\u0016􂹙\u0014\u0002𦍺󵅅\u0012d 󻆃#\u0018𫺦/k㤣X\"I\u000fO,`GU+\u0011\"\n럲n)\u001b􂰕x󸨾􋽯%\u0012\u000fVr\u000c󾾡H`🚇W\u001c\u0015􀛞vii\u001c\u0007\u0005󵙼&d\u001d𣶇󲅊.􊈄j󶈟$=a_s\u0010Q󹇪\u000e\u000c\u0003󸽌B\u0005\u0018L\u0002_ZX\u0015 h_sGj)󿬂|\u0000\u000f\rlUN)\u0006\u0011`8\u000c󸫲󳼍\u0008,A\u0011\tt/0lT􅪡\u0007}\u0016j\u000f\u0007z|\u0005𥕰J,26󹰅\u00039⮫0\u0019w'\u0000O&g\u001fF0󴞭kg\u0002\u0011|Q􀁨\u001aM𠌸󽣾vuPgVp𬆇)/󻚶𮡛ocxZ'ngJn,u𥿨󸡙.󷠥\u0013c\u0019G󽅆􀘠 󸣘t=\\|>@bc􂂥༹\\𬝑*#󵎜\u0015EuR\"𠪷\u001f~'\u0004뚻(A8m􊱙𠇓F._􉏍\u000e\u000f~3.\u001e𠚙􋊽\u0011o\u0007S@4\u0011VT_k􅫠𡥖D\u0010:ギ>UⰑ󱞔YkzU󸢔𪈯uejP􅄾᳒󰺮n\u0005\u00189~f&", - "password": "g]:󸥴𤄚\u0000􅼺\u0018L􇿷\u001d`L+i⒓,&Y\u0000*\u00173En5C\u001eI(\u0015𢽧=\u0007&B󶈓c\u000bj\u0015C5\u001c*𣀟迦h2󱍳(筃󱼑6r\u0012\u0010Q𡞷m{􌙸𫞡Y#󻎪L\u0003줲᮲􈈪署𬭍l'7/竈\u0015R\u0001T#InO:F|j\u001f+<\t}j`6𖡚wl\u0014-a]󼔍 O(\u0017X󰙌?!𫚵\u0012,Q󶛅𑂍\u001cO儶󵟿{+\u0011\u0015\u0012눡\u000clk\u001b5u󿾥{B\u000bg\u0017걸\u0015+􊣝􈒟\\*mUn$\u0012m􎄩𠄘誤03􂤥󳏃𢄇2\u0010BE\u000ek𨱐b󺏓{🔆jv󷺛_ཹ􀊊?/V!YoY󽠩\u00057P􁎼(nf􉡪+\u001c\u0002/\u0010ᯊ;􃄷\u0010f𪱗_Qsvt}DFm\u0013_􈝈\u000c\u0007_;=E,6|cAH\u0007ᤂ𐨢y&𭀶𩍛敶\u0017o\u0008\u001a8/=!\u001a廘\u0019GD9+󴃭'y㎦\u000e\u0010\u0016\u0013\u0000Z5\u0017殚\u0010\u0001sMf5KAO\u0017{J \u0007꾸𢯔]g|\u0014󸃫,4\u0012𡨞𘆎ⱽ3􌾠az㚋e}𦆥\u00191ᄍOr􍻔􊦞􄫱v\u0015", - "size": "complete", - "type": "image" - }, - { - "key": "Z\u0001𑲙/\u000e漇s\\H\u0004E{\r", - "size": "preview", - "type": "image" - }, - { - "key": "eb挀o󺔙\u0018\u0008󸪃\u000f󳂠n,", - "size": "complete", - "type": "image" - }, - { - "key": "LH􂮫\u0019\u0000", - "type": "image" - }, - { - "key": "W듨B}􂂪􈙙](𘌏I󿋇", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "\u001cHb<𧤡􄼷Z\\", - "size": "preview", - "type": "image" - }, - { - "key": "\u001d\u000c\u001f𗙘\"􄚁+", - "size": "complete", - "type": "image" - }, - { - "key": "5󽟦", - "type": "image" - }, - { - "key": "𩋭j\u001a匨󵡣󾰨󼤮\u0018\u000bN^𤁴n", - "size": "preview", - "type": "image" - }, - { - "key": "X8&r", - "size": "complete", - "type": "image" - }, - { - "key": "H𭄳awcA􅊐3/", - "size": "complete", - "type": "image" - } - ], - "email_code": "GBV8H4iTzUI=", - "expires_in": 378975, - "invitation_code": "hYCkzvFW6QzlqvDBJwPh", - "label": "󲏙󴆦􈿿\u0016u\u000e4M❲\rS􋀶o<9wHa嫡pxst", - "managed_by": "wire", - "name": "󼤘\u0008b\\󲔐𫓜C􌏎$'𩫗wG7\u0016\u001e'\u0006\u000e\"0)뛠@\u001c󾿣\nay󹝕𪚳󾍣\u0016)𬴀\u0017􇙛h𨵽􊕣🡒:\u0007󿖺\u0006u\u0000t􈮴EK鳢\\𥖵𪫉e=F-􅆬󱠍F3e𤉺\r𦹞h4\u0000%]𐒡,c2S𗍍h𢰿𪡎\u0005_􆯊_偏\nQ\u0012fHy_\u0019pB􋛊E\u0010%\u000c\"􎭧*Y-\u00121𪯕o=4A<4􎯏&t]󽈮kDM\u0012Q[󰪍\u001e -yq|𦐇zIt_\u0012mRT9󷅛$l􁸂\u000e`MQ𓁑􀪂_\u0005k~N𨲥h_\u0004o􌍊Ub\u0019\u0007_\u000f󷐲f6'XKDLq󾸑8􋟟\u0000`󲰄\u0005kQ6Gf\u001c󸉶\u0012􃺬\u0015$8r𡚔u𬴦b 2󻑧\u0016𥖹}A\u0001Y󼣟S󶁊#\u0003\u0001(u\\𧹱T\u001a!􂓱h\u00120Xx'𠔹!\u0015\u0010A9%\u0005\u0012p𤾹𬖷󶏩%S@@!d㋖=l\u0019$@% h𖡤@6;U󿢶@1b􄓬?g;s{'𩂉*v󵁋{+.┫Q𠖰u┈:Vg4]:𡳤5\u001cz4紏􏇬篇󱽈2!x3J󿷔Sd#X\u0000xJ􅓍O5\u000c𣷖f\u0019\u0008A\u000cU𧀢$\u0002C󸐗\u000eL\u001d\u001f\u0014.12𦦃\u0011𥦀豕eA\u0002\nX󾻋\u001fW?\u0018􃱲pSCi0軳峔^\u0016(\u001d뿞\u0014􉚃\u0016\u0017󺴍\u0008Z⣺13d󺑝S􇷉7𗫫󳊶*LQ𭣟nS\u001a\u0003L\u0005v\u0008(􅜽S𑑗\u001a󸄅)BT𩦹\u00129\u0017;𫩈𠴈'󿷐&刡󹩝\u0018d􈎢J􌙛ZdoMR+~<𮭧laS𑻤l󻹣\r𨭝:􍉯f>Fe􆬯i\u0016V/L@󾱙e󸞲7\u0001v\u00119󺛗!L\u0010X%\u001djx\u0018􆭺\u0016]w7W\u0001+󻛈E\u0014:渧𦕂ᔿ\u0018\r\u000f\u0005㿓\u001e\u0016Xb1\u0012Et𭹿㕿Ez􀦉\u001fo\u0010󹹊䫿𪼨e𮟩8\u0016\u0018󶓆{\u0000䢾jF\u0017,􏙾𮢥𫣆U\t􍴼Ku􍁌I?𝄽p\u001f\u0006MS*𦚬𡵼魈󰄥 􃌰ڇ󺣋𣮡\u0007U?𮙞V^\u0006/:l-.Uzz\u0016\tm#􄅻XcY*􍣜\u000c􃨛+\u001f𘩸Y󲫙7\u0010\u0001rL<+K􂖫􎗼󷵝$eᦞ(A\u001c\n", - "phone": "+504111413588", - "phone_code": "AQmcp-TSIeo05ixCVAzzxMGsAtTH7l0=", - "picture": [], - "uuid": "00000000-0000-0000-0000-000000000000" -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_13.json b/libs/wire-api/test/golden/testObject_NewUser_user_13.json deleted file mode 100644 index 47700208af5..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUser_user_13.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "accent_id": -32104, - "assets": [], - "email_code": "8XW3_eppEXD038Pz14guN-pLnL6rR1538NZxVA==", - "label": "^\u0010􊘑󸯿\t𣻨6Th𘗒􍴷I'𨛬/\u000bV<^zu\u0019\u0003\u001b>𪢗𗛇A", - "name": "[3Y\u001eF$r9,/1\u0014쨊*弉\u0011􊥝蓯I]\u000c#\u0018\u0019ITc𧍷󶱙􁡾\u001b#\t󾡄ic\u0008U􂖓\u0016'􏶱谢0xC󿔦\u001b𦐵1U뼏\u0005Rd􏗕𡜬\"$p𫡲G[\u001aW\u0008\u0014>􀳥u\u000c9\u0010U𝗔W8/;[f1\u00183.𑆮Fw1\u0008\u000e=󿷛Q\u0019lgZPCjAFm𭤍3X\u0003&󺫿\u0005u􁟎𖢠􈓅󴡩CT!+st#%󲳂'W1~\u001eD󺹸h𣱪㾧\\\u001c􍁀C𘂥R_(\u0008𠗿&>\u001e;H@v_侔󿋋Hg+m󵟺w`􎙯\"􇃈B106Q󱔯X𬊋󼡥𨘧󷏌P\u00141ꑌX􂚨󸭐?VD𧉞䛊\u0001ii􅳆\u0004nD䈖S1𐎇\u000b}􌖆훒>?𩟺T=\n\u0018BAi疉𩝡\u000c,&=󻔇g󺳎f9\"􀼬\u0015pe󰤘\u0017􏪯𦔵󸴆𬴋,\u0000j𤙜1䜩I󷊆[<*S]<7oḄ󽮧d뚗􃐗6y7릠\u000fEeE.S:_$LBG𥼟*ci5俖PFl𪣉\u0014E0b\u0002㈉/;潚p\u0011𐹺婇;m\u0008\u0012P@YBve\u0008\u0004􀷚v_6/ⅾ\\op駈H$0󻚉\u0019$Y\u0007P􊴔󻝸*\u0004fj{\u0012'3*ﷂv𣩺UW\u0001m􁡵䈅i\u0017\u0008未!S`w\u0006hJ\u0008󵚼/Deu𬑀􆦊\u0018z[", - "picture": [], - "team_code": "hhaIkzK5fTdyr4CLcPzJg9oj1G2WpaOQ5Q==" -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_15.json b/libs/wire-api/test/golden/testObject_NewUser_user_15.json deleted file mode 100644 index d15beaf4da9..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUser_user_15.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "assets": [ - { - "key": "ۣ􌎔󱽴͎F\u0019󹏿A8󵕨t~K\u0011", - "type": "image" - }, - { - "key": "}ei𧍏", - "size": "complete", - "type": "image" - }, - { - "key": "{rF_\u0006􆟏\u000eu\u0019-6", - "size": "complete", - "type": "image" - }, - { - "key": "`q", - "size": "complete", - "type": "image" - }, - { - "key": "%泃\t􊅣\u000ePb", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "􂩂\u0000\u0005𝀴cdCD'", - "size": "complete", - "type": "image" - }, - { - "key": "\u0014\u000fw", - "size": "complete", - "type": "image" - }, - { - "key": "lC\u0010\u0006🇹􎴦󳬠02􁥉T𗴎\u0000􃽜", - "size": "preview", - "type": "image" - }, - { - "key": "i\t", - "size": "preview", - "type": "image" - }, - { - "key": "𠠐FŤ􀣉4p~\r", - "size": "complete", - "type": "image" - }, - { - "key": "$\u0002;\tX", - "type": "image" - }, - { - "key": "d\u001ae\u001c\u0017󰌀4\u001f\u001e\u0005", - "size": "complete", - "type": "image" - }, - { - "key": "O謴G𘢶/~TYE\u0005󼅒K", - "size": "complete", - "type": "image" - }, - { - "key": "6K.^󰕵", - "size": "complete", - "type": "image" - }, - { - "key": "󷰇", - "type": "image" - }, - { - "key": "𑫠\\\u000b]0m𣺎bO𦿃@\u0003", - "type": "image" - }, - { - "key": "O𩝬5𪦤H󸻱\u0018𥺇", - "size": "complete", - "type": "image" - }, - { - "key": "󵇲󲎈󸸂iMl󷔲g\u000c\u0004蕌􍍨", - "size": "complete", - "type": "image" - }, - { - "key": "h~惞le󰞕╌8\u000baV~", - "size": "preview", - "type": "image" - }, - { - "key": "2!􉯭\t\u000f\u0006𪈂ᘾo", - "size": "preview", - "type": "image" - }, - { - "key": "a􋲩[mz@?P^", - "size": "complete", - "type": "image" - }, - { - "key": "Y\u0014c󺪶", - "size": "complete", - "type": "image" - }, - { - "key": "𢓢𨤨\\\r\\󰾵z\u0010v\u0005R\u0000\u0004m𐌵", - "size": "preview", - "type": "image" - }, - { - "key": "\u0007L󶁋LhVA㋀𬝿PW1Il@Koo􆍰\u0019;󰘫H7\t|],C!lf~_󴬼U!􋲙󷗚!\u001c\u0012s;\u0010 𩨷󸖊𩌇\u001f\u001e&[\u0015\u0007\u0012󲧚S'W\u0013.~\u000e􃔌󷜪Q𐭜FFxnmcy\u0004Lxrᯖ`:󷦕] x᭶\u0013赌% =\u0015\u000c6S\u001d󺳕p!\u0007𡊱(;!$\u000f]\u001f`5\u0012󹿾􊏹􆄶}9=O𡧨󵠚(I\u0018\u0019\u0018𮁀󽺟]'奚\u0012􍼆􈧪@R\u001a\u0015𘔺326\u0006􍾤sy𦛇聆Kp\u0006B~M󼹅􁘯ty0pJK\u0002zv eWY􌱬v\u001bG\u0018=󶊆\u0010[TZ􄶇𫝠󱽛`𗚻\u001b󿡐d\u0019\u0008\u001ed~\u0019󸆑𭗧爑L\t,A𠡈\u000f))Z\u0017{𡫱A?\u0015%hS+𤭌ᔌ_𤊚:dR,j𢛿(_'j{O𠡑\\X󶪩S􀊮wTD󼓣𧊞R寢\u0011\u0011􌝫:L􉇋p>\u0013岘󺿷\u0000󹃉􇒸A􉾉\"g+PD\u0001tk?N󷗹쭡𩯡_AdL2󸒤./b\u001b\t)\u001c\u001c7:\u0017󺚒P\u0007GEwk􊹟-)\u0013p0\nUG\u0005PV=齰\u0004M􄚆_js\u0003$2^YaP󽬶僯H@j䟸r𮇧Y\u0012*u𨪯󸽼-𧶔\u001cf~ZI[5\t\u0006𫪱󰻀𣘐EH𡡤J⇊Tun􉫊\u0006uO:`(0𧝅󱅉]_󳽢󵛳\t\u0002\r鲡v𩓠o􆇈󽽂h󵗽􏬾𣪹! \n\u0016'J.󻒠󳊖\u000b4\r{\u0015\u0015bPQ~􊦮3\u001f􇋻<󱘒o`q J뼲]c\"󵫅\u000b󺇾Q󿸞𤘑󱪹軈N>;}\u001d=TO\u001f 6\u001d\u001aWy8CZN둓I\u000e􎤽涚P낃I7l?\u00083\u0002v㘝㶉\u001e􋎰\u000e\\􍱑\ne뜚𧇦0mS\u0018󹈇𦗼ng􋊫xTt/옑Id}b跺𢡒v\u0005|;CसZ𐛞\u000b&C\u000eE9O5\u001b􊨾w*}\u0019Q𫥭\u0006􆰷𤟔󿕜w~𔒓7TL_\nH􂔉$𛄐􇰟\u0005UPQJ㲤\u001eS􄥙\r$\u0018U󽊭wT~:쉀/🕽`&𡞎(𫆉\u000bn\u00101𢭝\u000e􀛚)M󲡉􅫻<'=d\u0011G𨮕\u0008;\u00038g,;𮕠Z󺓅\u0011󲀢{trA𫦽5Xe.𢲶,'R\u001a聹N􀗤𤙎𡓯􃂭󴎓\u0017mW􋆙\u0003\t󶶊dQ𗮭d]#\u0019E;𠙃Y1\u0000󻝛\u001a\u001e󿻤⩼\u00073𣰏\n냡󶪟a𢜍s\u0005LZl8Dq\u00173Vp5\"\t\u0004󶹆n~󷉇􏑧HD-󽱹󰍑𬋔\u0006uQj􇌆\u001cx秨\u001b\t$O\u000b󱤓BI#4󳡎\\􆦝􀪶/D\u001b􉆙pX󴧞f]%S2𝗏z", - "phone": "+430123790", - "phone_code": "8VeH6NTGEGaO1xqt2kUhVxoO", - "picture": [], - "uuid": "00000000-0000-0000-0000-000000000000" -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_16.json b/libs/wire-api/test/golden/testObject_NewUser_user_16.json deleted file mode 100644 index a8af7c36757..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUser_user_16.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "assets": [ - { - "key": "\u0013󿴱\u0006!FC", - "size": "preview", - "type": "image" - }, - { - "key": "f{\u0005", - "size": "preview", - "type": "image" - }, - { - "key": "Hl\u000e\n8\u0005~\u0019􋨱B", - "size": "complete", - "type": "image" - }, - { - "key": "􎺞mᢎ𨓙x\u00114c⚨o%:", - "size": "complete", - "type": "image" - }, - { - "key": "\\57FFJ􄘤8F", - "size": "complete", - "type": "image" - }, - { - "key": "󰓙\u0013", - "type": "image" - }, - { - "key": "(E哈hxM\"_", - "size": "preview", - "type": "image" - }, - { - "key": "\u0016Q\u000f7z.zs𐨗Z", - "size": "preview", - "type": "image" - }, - { - "key": "~$", - "type": "image" - }, - { - "key": "h\u0005R󴽃𠤑w]sc󻙏쥒\u0011`!", - "size": "complete", - "type": "image" - }, - { - "key": "p\u000f𪖀", - "size": "complete", - "type": "image" - }, - { - "key": "s,􃎀#\u001f", - "type": "image" - }, - { - "key": "I(", - "size": "preview", - "type": "image" - }, - { - "key": "\u00027\u000c", - "type": "image" - }, - { - "key": "\u0017􉡇㇢𤀣󳃢#2{6Gwz", - "size": "preview", - "type": "image" - }, - { - "key": "\\󿱢8n[m𝆁𖢑󺰎L𩌤\u0016Yᴀ'", - "size": "complete", - "type": "image" - }, - { - "key": "\u0000/dn\u0010", - "size": "preview", - "type": "image" - }, - { - "key": "󿛏𦵱8i\u001a", - "size": "complete", - "type": "image" - }, - { - "key": "9=3i=5\u0018\u0011", - "type": "image" - }, - { - "key": "$\u0000e󳷛\u0010P\u000fnN", - "type": "image" - }, - { - "key": "#\u000f${q4]s]󻿧􉺨", - "type": "image" - }, - { - "key": "Z🦥⋩🏈\u00050F𫠜(", - "type": "image" - }, - { - "key": "󿷇v5󳞳'", - "size": "preview", - "type": "image" - }, - { - "key": "3\u0008\u001f󱗈𦏞󴷻\u0018\u0001?𪿼\u0001", - "size": "preview", - "type": "image" - }, - { - "key": "rZ𠪹l𭤫k𥥤\u000b􉰋繩Jt\u001d", - "size": "complete", - "type": "image" - }, - { - "key": "2𡨘-", - "size": "complete", - "type": "image" - } - ], - "email": "R𡭷쥢􊿊\nTAS5z|q﨟z}㊟;\u00178\u0010@𐐒𠀘ZBqrtK\u000ct􀦁h\u00088iU.&", - "email_code": "sQZw_A==", - "invitation_code": "krEHX0N2tg==", - "label": "𧳡ਉ\u001b`c&𦷐캻9b\t", - "locale": "xh-TM", - "managed_by": "scim", - "name": "\u0002nH󠀯\u0013􅊎\u0014\n𤧠󺋠𤡖\u0019`I~Q{\\:󲬆\u0013H\u001dem􂕵!󵕣\r\u000f\u0011B􊓲i\u001d\u0015\u001bY𧘒􀝡軝G𩚆UOB*Q\u001d]M\u0016", - "phone_code": "5dy6ya1yHl7TyDF03xClFXFT", - "uuid": "00000000-0000-0000-0000-000000000000" -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_17.json b/libs/wire-api/test/golden/testObject_NewUser_user_17.json deleted file mode 100644 index 8f9aba0b6a7..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUser_user_17.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "accent_id": -657, - "assets": [ - { - "key": "􁣑􍬞󺧟)D􊝪N􌞶?", - "size": "complete", - "type": "image" - }, - { - "key": "􇊋6;o\u0014\t\\\u0011\\􇔠㶊`R", - "type": "image" - }, - { - "key": "''@\u0017K\u0019i*YcomF.\u0004", - "size": "preview", - "type": "image" - }, - { - "key": "$VX\u001f\u0017M:)f/", - "size": "preview", - "type": "image" - }, - { - "key": "\u001a󳥛lkaU\u001cy󷀥s", - "size": "preview", - "type": "image" - }, - { - "key": "$}\u0014W)\u0019🍓3s", - "size": "preview", - "type": "image" - }, - { - "key": "w`틀\u000f󹨴\u0016]P>J", - "size": "preview", - "type": "image" - }, - { - "key": "\u000b=d󾅡𪄯\u001d2􃟩uw􍾬𥅳f~󽒕\u001d\u0007󳾸󵊆'1Yr󿹜7𫃙䃱魲y]𢣩~/쿘$󴫻u5JF󸂀\u0007\u000f<\u0016n\u001f/\\\t𠘨k\u00157]d>?i\u0003􇪰,=Hok$q𫴯\\=L:𒅷􅡁*𗄉*􋘴F󹙔Hk\u0001jPPsA\u0001/c󲊔]\u0000}|V7N󾐀7C_\u0013􆤯{B;E2t\u0015\u0008\u000foK󵱔􊚔\u0008ᛯ㘇HQ#𤃴􈶓$u7\u0008ꁮJMT>󶚗\u0012*R󳔒?p\u00101E𥍠󶶄k􄜱B;\u0017Sg;O:\u000eyW~\u000cb 􆭜W\u001a 𭞛%PU2o\t{Q\u001ec&r𗌗%V󲾞살󱖩d\u001fb}`M𪼕dw@󾣎꡶9eI๛󷴪|BRW\u0000􆴏ug󴮬#\u001d1󽥛O|᭷\u001e\u0019D\u0010􀧸9󵷪*𪌍O𧀼􄴗\u001aUi;\u0003心>\u000e7{C琕I𬖠vg5ﰫ_5m~\u0014e嫖\u0012󿭚𤺉0Cz5k\u0016𠷟\u0018뼲\u001d>\u001a:?#U􊜪0𒀦\u0002>=z\u001f󲢞𘓸wࢫ\u0003C􇦤\u00027\u0014𫖉\\ e멤e(oT", - "phone": "+479088519197", - "phone_code": "G1SWE8oSdxfc7Es1vzzLBkAkCFGDjxo5", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_18.json b/libs/wire-api/test/golden/testObject_NewUser_user_18.json deleted file mode 100644 index 96fd94b9342..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUser_user_18.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "assets": [ - { - "key": ",", - "size": "complete", - "type": "image" - }, - { - "key": "&vJ`!R\tVt-=i", - "size": "preview", - "type": "image" - } - ], - "email_code": "_Q==", - "expires_in": 228513, - "label": "V]#X󼋈\u0013n􃧨󴽔u&HV\u000c\u0002:Ah. 9\n\u0000", - "locale": "qu-PF", - "managed_by": "wire", - "name": "\\`O7𒒌󻣳g􂫴2*a'\u001e;x v󵙓j\u0000䴓\u001e\u0015E􂎩󹞲G!bB􇽖𢘌􏩡\"t􊧥\u000f.􈧂|\u001b𗌜]R𐜌O󰭆\u0017F𘑘泔d󷻝yLN䱟\u0010&훀I\u0004\u0000T'>>\u0007g-'|ꥇ\u0006蔦\u000b", - "password": ",S𧯃\u0004ῳ\u001c*R\u000blulO㨎󺔉󱀄]\u0005y:㠂M?󺭍X𐤐l%@\u0004\"4􃐦(\u0001\n-󿀥\u001a]𡼗\u000b\\\u0011gJ𠆜솮𞴊G(&\u0014\u00111􁓜@\u0004\u0014ze\u0017\u0017\u0015:\u0007*!x5\u0000J\u000f>F\u001cS>P]𢬂|kLmi\u0012*[⏎e\u0008\u0015󼛸n󵺫p&<2j\u000b\u0001FZQY\u0017>@uin\u0010cu3\u0019%󲙁\t-\u0008\u0019/mpW\u001f@Hb7:\u0013\u001c􎖭\u000c`4zI󵧉y|\u001f0\u00195y瓉\u0015𬆿\u001e𧈕\t5O\u000e𭩎𬰞{>􍆡ﹱ뿎~𫑂脷gt󻯻P\u001aqY\r[OO!􆨆#󵭥O􏂌_'v5O𢗦\u000b𑦴#]\"I-𠀟a𫖆:q䔟ꃂKK􃆹au/b \t.\u0007K󷒇N\u0018󿣊󶽗\u000bꟂl\u0002u\u0000PiW.u𖡸\u001d\u0011*ꂲYT𬸛𐦭+ᓱ\u0012~dZY\"p\u0019I\t閪\u001e矺{\u0006@D𠒈􂝖V\t37䓚𣦁,c􋚔ᔼ𢹏\u0008\u0016?ꀳ󽖞\u0016󴲞-􌌿󺦃?\u0006􍷩o𩴵+𣾄4US􁐇􀐪\u000c7/󻩏2𗔿\u0006|6&􆏖\u0010u󺝖0+1M", - "picture": [], - "uuid": "00000000-0000-0000-0000-000000000000" -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_19.json b/libs/wire-api/test/golden/testObject_NewUser_user_19.json deleted file mode 100644 index d1d8543fbb8..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUser_user_19.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "accent_id": 28218, - "assets": [ - { - "key": "\u000c\u001b1,", - "size": "preview", - "type": "image" - }, - { - "key": "𩸎H\u0001p\u000f>6", - "type": "image" - }, - { - "key": "W舆fj𝚵xa\u000f", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "7羇#.E\\陼i/9.", - "size": "complete", - "type": "image" - }, - { - "key": "\\!A", - "size": "complete", - "type": "image" - }, - { - "key": "󽘻+U\u001f𐤛Pp^", - "size": "preview", - "type": "image" - }, - { - "key": "\u0011􈾗\u001e󰕳Q\\2\u000f`{𦡡W􍕶", - "size": "complete", - "type": "image" - }, - { - "key": "\u0017v8\u0018𩩅X8q\u0002󠅏V", - "type": "image" - }, - { - "key": "𢀠}M𠤀\u001b􎒓l\u0002Ku,A", - "size": "complete", - "type": "image" - }, - { - "key": "1\n𣊦-J\u0017", - "size": "complete", - "type": "image" - }, - { - "key": "d1𢾪", - "type": "image" - }, - { - "key": "\u0017%1󼄴@`f\u0006 %", - "type": "image" - }, - { - "key": "\u0005l;w", - "size": "complete", - "type": "image" - }, - { - "key": "0󿡋𧲭m𞅉Z\u001fr-", - "size": "preview", - "type": "image" - }, - { - "key": ">%?]V􃽹q얅\u0002\u0013𦰎", - "size": "complete", - "type": "image" - }, - { - "key": "EE,t5璓\u000cJ-t󱧴Ft", - "type": "image" - }, - { - "key": "鷮u5孁3", - "size": "preview", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "x\u0014𘀟", - "size": "complete", - "type": "image" - }, - { - "key": "l\u001eC󿜍\u0005\u001fO\\", - "size": "preview", - "type": "image" - }, - { - "key": "\u000e朰>G\u0002𤉽\t", - "size": "preview", - "type": "image" - }, - { - "key": ">F{^s􋵙\u0017", - "size": "complete", - "type": "image" - }, - { - "key": "􆟪0ᐆV3:l'ZuA󶡑s", - "size": "complete", - "type": "image" - }, - { - "key": ";\u001f3A\u0007Z\t󴼿\u001f\u0006nv皲;4", - "type": "image" - }, - { - "key": "?b)`𐲠-c\"􈆋􊓶T", - "size": "complete", - "type": "image" - } - ], - "email": "󴲧󹼖🛒U+\u001a􇾤]x󴞦Rz\u0004p􆶟U󿎥@5𥛅\n>\u0014l\u0007ᬘ􊕕\u0015U󽖒𠥣3tj\u0001DnWz􁘬\u0015􍪳", - "email_code": "xW2K", - "label": "\u0006\u0008>􍯓󻿧73]杻7󽣍&H\\", - "locale": "pi-CC", - "name": "=5^QR$\u0012iꗭ𤴜\u0011󵑣\u001b𮠨#􅡩m\u0004󵿅𞡉+\u001ca\u0016􁘻溄T-", - "password": "\u000c󶼂\u001b\u0011U󸻂\u0007[Zn |𩅻>\u0003蟲𪥢􃒪Qq0U7\u001b*e\u0014@[)#􀳿&N-N􆂼J𫡰\u0006<\u000b5>^\u00193𥨎🐟M\"Q@_7Y𘡍oO\u0007#x\u001bsU8\u0017f􄬪𘥗{ \r&􈧦@緝'<,X𩩬<\u0001䛢>󶳷DP\u000b!놧[󾴨\u001e􄄂󴧟+&\u001f{𬛂󳗏t=Dm􍞂B󶹳t𪔊\u0010\u000cs\u0003`O\u0008\u0006⣑:󸉵\n􃆽HXJ~\u001d\u001e𬻌d𬱧󹈲󿳢F󾄘&F\u0007\u0004􋭕H]\u0000*􇷠\u0007]󿺌V!\u001c⓺EyK1𬖭\u0002v𬛋)f\u001a􍠦)#F􅣪:𤷝\u001f Nw󷩀𮎸\u0004󾖋\u0006V\u001e@k\u0017.𘂀F☶B\u0003\t𘗂 SF𬀶oy􇪩)婖\u000c\u000cM鶩퐱zw\u001f_I8j钚\"􏊮\u0004}汐m~ヮoea32?諚d$\u0004\n5\u000crGK?誮c𤹎\u0017Si弳]\t􄵊1c{:_e'S\u0014\thf\u0000Gയ!\u0008sjmf\u0004\u0013󳽗f^\u0011Z]A󺄪\"뼦􉾏p𭷌𪧍𣍉Ax􃷩O\u0014W;\u001e肻H𥾡Y\"E􋶭𤳷F/H8cV3\u000f1A\u0018\u0014\u0019i&EZ3Ka7s󿼢yB4𭴌𫬳MXSQ9𣔮𭗗q2\t􀩕H𣴍g󷑓󴑗(\u0001'\u001f𣹂𤼃\u0019eg\u0005,󰞗\u0014dF-DnZ;\u0010jz𞅀.m~o\n\u001a󽝞~y􉱞\u0005s\u001d\u000bX|}J\u0002\u0015$K\u000b[W6왊C􇇐C󸳬KA\u0010mL3*\u0005;C𮂲\u001az\u0011\u0006|⺾%e^􍻨𫝾\u000br󴹍\u0010`泱~􀤐R!*󷪆g%P2𭀤𬇃ugo햝\u001a𗧠󷛅􎀕\u001a\u0013", - "phone_code": "zRaFKSA7mqei2mjV9w9ON4OLeA==", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_2.json b/libs/wire-api/test/golden/testObject_NewUser_user_2.json index d44de129a5d..8cb4089a5aa 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_2.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_2.json @@ -1,88 +1,4 @@ { - "assets": [ - { - "key": "\u001dg", - "size": "complete", - "type": "image" - }, - { - "key": "\u0018", - "size": "preview", - "type": "image" - }, - { - "key": "7|{", - "type": "image" - }, - { - "key": "Σ[E\u0003‛\u0015\u0019R", - "size": "complete", - "type": "image" - }, - { - "key": "\u001dQ\u001e𬾠*[OCr􊫕", - "size": "complete", - "type": "image" - }, - { - "key": "_\u000e\u0000👙p󶪿7n𫋠\u0016", - "size": "preview", - "type": "image" - }, - { - "key": "𫠲􃸵ᬁkC\u0011\u0016􅺭{/󵎎󰳄\"𥈋", - "type": "image" - }, - { - "key": "*󽉠f", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "󲝗8'e4\\\u0014𩛶W\u000f&f", - "size": "preview", - "type": "image" - }, - { - "key": "x𣀨\u001d\u001cF", - "size": "preview", - "type": "image" - }, - { - "key": "U𩭴u6󳶷󺁬/℺\u0016<𥰶𭃷𗣅:\u001f", - "type": "image" - }, - { - "key": "S", - "size": "complete", - "type": "image" - }, - { - "key": "'\u0001\u000e", - "size": "complete", - "type": "image" - }, - { - "key": "\t陗8RR[#", - "type": "image" - }, - { - "key": "㘹\u0000Uᄼ1A𝗰㕃T\u0001x$P", - "size": "complete", - "type": "image" - } - ], - "email": "\u0010_\u000b*]\u0008\t󴹀 @wE즷Y$\u0017\t\u000c\u0002\u0014]u󰢽[<𓆓\rd\u0019𥗀𡩮:r􂊤\u0000\u000f", - "email_code": "XJbRdz2tmf7rgAU=", - "invitation_code": "RnoP9ThWPcujkA==", - "managed_by": "scim", - "name": "\u0000`)\u0007|>}\u00195z𑈣\t>w\u000e󵾱", - "password": "𫩏\"-ꗃ湔Og'}𦬌\u0013Sz`}^\u0019𮘆SS𭈝𨃁\u0013p\n[䷪芖.l󷤆p\r\u000e\u000e󺄚$\u001a[󶣱􎒐𥠒fV\u0013[\u0013􏾻Rc󹶹H\u001f󸸶𨎽𭩳qO󳖄\u0007𦊳\u0000<􃔁\u0019󼯰𗂟\u001f\nd莟\u000b[2󿒮s\u001eb+E𪎂W&􃬸f3\u0013[#,\u001f=f𐧉}󻭠\\@􂧄}n", - "picture": [], - "uuid": "00000000-0000-0000-0000-000000000000" + "assets": [], + "name": "\u0000`)\u0007|>}\u00195z𑈣\t>w\u000e󵾱" } diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_20.json b/libs/wire-api/test/golden/testObject_NewUser_user_20.json deleted file mode 100644 index 69a6c3b4b80..00000000000 --- a/libs/wire-api/test/golden/testObject_NewUser_user_20.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "accent_id": 13678, - "assets": [ - { - "key": " })$", - "size": "complete", - "type": "image" - }, - { - "key": "=(@S\u001af4#", - "size": "preview", - "type": "image" - }, - { - "key": "[P󹯀\u0015X󾪥墣86!Lg", - "size": "complete", - "type": "image" - }, - { - "key": "󴃩1󿡷u`𩵪\"&ea󿴙𦑨", - "type": "image" - }, - { - "key": "􊠦D<󿝾>cc\u0004'", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "r\u001e􅵉\u000eR𑅭b󰪳$#𢪬R", - "size": "preview", - "type": "image" - }, - { - "key": "=󲛕N'7I󿡪\u000f%", - "size": "complete", - "type": "image" - }, - { - "key": "X<#$\u00000𥧽􅤂*󸴻", - "size": "preview", - "type": "image" - }, - { - "key": "Dዶ\u001ci{", - "type": "image" - }, - { - "key": "5p᷋", - "size": "complete", - "type": "image" - }, - { - "key": "j\u001aG0󽄻\u000fd𮔨:Ɍ", - "size": "complete", - "type": "image" - }, - { - "key": "5H\u001e􆭸;", - "size": "complete", - "type": "image" - } - ], - "email_code": "v2-GQHZFYfDD7eV7gj3dtTZ2RDAqMLpBntdMHg==", - "invitation_code": "529Eo7BC6CKbsX0i9lKIvOFyuxhHig==", - "label": "#+EA7", - "locale": "kw-LU", - "managed_by": "scim", - "name": "\u0008󺟤z\toeq􇔙}i\u0002*RI/B(\u0016jS/L𧆹n2\u0010MAﭵ0\r𪗪jS\u0007\u001et\u0016𢾴5:*6𪕉\u001d]\u001b􀹆)][F􇛳)\u0017u{ 𫑠mC\u001dI󳜱vp\u001d*ᾱF].\u0001)\u000f𗞕p\u000e隷!B!N3'e陈󷟵2\u000b.3t*IW%\u000ec", - "password": "󵝚A酼9ﻘ \u0016󵐄]􆔛=􄀉i0󷫆.\u000b.)_$QYz󶂜s𩃅𧺮󴨹,f𗶘M7ଠ􅭩mcO\u0001\u000c\u0002󵃣DQ\u000cEq={\u0010d󲞡𠩒\u001ez\\𮤊5.F\u0019i<萯\u000fP$\u000ei|d,J.ݒ\t\u001a􉊏]UA`*\u000ch\u000b\u0002@K.z\r=𩘼\"TG\u0012=X\u0000W􋯞x\u0000V𓀺;𦔓}{hRc\u0008\u00120􉮗:𦱝\u0006$6n𓍮􄝠䄣􄪀6^z{]\t􏑬輊#W;\u001csp􃥩t􈫋󽶩\n\u000e厤󼪢𘨓󲫅𩏇TW𦽏k󳦷,J\\!􊆨󱝐bs\u001c\u0018e󱝬𭜞=\u0000\t\u0002\u0000s)A\u0006+6z𣜃=\u000f\u0007]5\u00181[O=. ,\u0013RF\u0000󻑸𞡉>\u0001kc5Tvp4'u𫜇\u000f🗁Y꣗\u0013$\u0014q亜I8阂GJ𣸁6\u001a\u0012𭎯<ᢆi𪽲􈙍XR[G\u0004:\u0011\"ꊮ󴡦\u0008$𛄘⡺󷕒\u001a􂷞Ga󰍟󲫻\u00076\u0000𨰆\"M\u0018Uz\u001c􏫋\u000e \u0011󶱃=\u0019챓\u001d X?p\u0001]3V􈼟l[ts;P뼍ye􉮵\u000f凈]􅺭\u0014|􊟚>󰾋p󱍙𨬭𡗋N<{t𭊽􋒮}源\t0&\u001cuz\u0018m葸􅃿󳖒q~S\u0003}KsYVN\t\r8pZ$.p#攚Qad5慈𫫺n<󺰖􎟛o!􅍬𩮁\u0012;?Y\u0015:\u00129{}'\u00138𔔖\u0003c𤭼\u0019\u00073aQ~\tl&\\8`\u001a\u001e,篼\u0004󼷷󴠎뒱s󼳾󴝚e􋪖󳈐J{`;]􂁘𬔐2u⿴󺟮\u001esS􊴑x鵅􌎡%z𔑛\u0010􏟮N\u0011tSL8]\u0006Yiꗈ\u001cz\n\u001f\u0018\u0017\u0017'鱣OH󲳬M}<蛩󸺛􂀋a\u000b&$k𪍌WP󿿊\u0018𘋀4oRjU\"\u0005􉥮󺔉#C𡅖'~􂲛􆜫3\u0003C􁺅(.T\u0018i\u0010wᡶ𨄾Rp", - "phone": "+60997378240829", - "picture": [] -} diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_3.json b/libs/wire-api/test/golden/testObject_NewUser_user_3.json index 356f8b32d4d..681e30b3b01 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_3.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_3.json @@ -1,61 +1,5 @@ { - "assets": [ - { - "key": "s~\u0007", - "size": "preview", - "type": "image" - }, - { - "key": "/=sG\u0008𒐬\u001dKx", - "size": "complete", - "type": "image" - }, - { - "key": "/K􊰂󸩦K\u0005𭇝(,󱱁", - "type": "image" - }, - { - "key": "𥶯SM6V4w", - "size": "preview", - "type": "image" - }, - { - "key": "e", - "size": "complete", - "type": "image" - }, - { - "key": "󹦕𦇷[0RX", - "size": "complete", - "type": "image" - }, - { - "key": "#\u0018𬘏Y𥐂𢷤.", - "type": "image" - }, - { - "key": "85C>%fMrl", - "type": "image" - }, - { - "key": "􀠶\u0015\u001b7뉂\u0018 􌊗􇇗", - "size": "preview", - "type": "image" - } - ], - "email": "𐏒𣥇iC􋲲`@*", - "email_code": "kLnw_0l8qwKitd6ZFiCd_A==", - "label": ")!􅵉!", - "locale": "sq-SI", - "managed_by": "scim", - "name": "􄵞9爈F.G\u001fn\t\u0018.K?B첵􊲢󲱫&󱊂降􎯅NijZ󴚛zr>\u0018y󺮑􀍐𗺵𪡜𢤡胔󵰚rz\u0001󹑍\u0014\r\u0014\t𭧌%\u0005jK󾳥F𐅱5[31\u0012H`𢳱l&%\u0004󴈫R*󱛓", - "password": "󵱚&1`􃀯/j𣇈\u001b@󻏨𤆵ael𢞼􅾲𭟲(ᅣ󳆔\u0016kSCY􃍻nA\u000fv3NT\u000e󺭒F\\]9\u0002\"\u0017\u001b8\u0000:\u0011󻝑s\\O#\u001as\u0003ZN\u000bN\u0019\u0014Iq󸠖w\u001f􊐾壢\u0010\u0003h0\u0001\u0014G_,8\u0001󾳈*MX󷍽(H\u000b2\t􂠈M%J(󴝴󵒧@\u0000󱰧\u000b𭯥dAm&~𤒻썜󺃧𐰢S􂫆Oo'\u0007𮌎󳿹)mGV𡄡𤀄$(+>(ok\u001e\u0010\u0014x\u00149ୋ`\u000e󹷹]\u0007\u0013[\u000c暗h􅍡Lg\u000bK?h\u0005'\u0005ER\u0018hG1q7Hw0󼍤𨣒R􆹎􎩘Xq\u0012􃍔/􂰘2􎞄𩄪𮪡$\u0018.󰮲\u0002\u0007X󳌿\u001b]󺳤r󸬳^,A豵􄉻!\u0017➮\u0013>\u0006h\r~{N\u0002𥨻p􏷍T􈥄hs\u0011=s>5\u0000^Bh𬜟􁁿~\u0003/\u001ay\tPs􊶘m7h9𠜸󱫎𠏌r󺡚4?o􂎶+󼂳󸳥󳝙\u0015\t|\u0010G𧣎𤽌褨q$󰴽𨻹頜𛇃\\\u0019\u0006rI1A󾀦YpW\u0012ef𮩖fg\"|梜󠁆\u0018􇗰)􍚑y󼈵SZ󸖥82\u0016a^#e뜼󻘗a-}uYX􊩡<纕\u0015殼I\"\u000b\u0010\u0000\u001b󱿉f𭍀\\止[􍀌=%焠Ea󰞡􋿁􁅙e􉹃𗂣I􇬙􍁖ꤤ\u001b3ၸ\u0019U|\u0016jtQ`󻰵rW\u0013\u0005Z\u0015/kHL\u0018(\t\u000f-s-􎙞'󹊚n󳪛5ހ/󵉳􌽭q􈎌􌀇p𡿾6\nZY\tq%ꬫ󶐫\u0012m\u0013𭌄䝉𨲏1\u0008:F A𐅵􈲂󷡠~vk􈌓􏀃􃗪,Z󺜚\u001ck𐊗𩹈P5_m{\\\t哷,􎗊A\u001e)L0)+\u0007\u001f'X17U\u0002#벇>\u0013|P􅎇po\u0019Rf󸶞\u0007\u0001𬸴x𣞆iL⮪h􎦘\nq𥟑\u0002@𐧃c㌇j󱇂9?R皴\u0013 NB`\u001b𨂙深\u000e\t'/k\u0013w9eFy\u0000t\u000e􌱔X/m\u001f\u0004ᗾ:&\u0018\u00184\u000b[k/f=􅾇bC\n-X㢅O6\u001e>}\u00195z𑈣\t>w\u000e󵾱" } diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_4.json b/libs/wire-api/test/golden/testObject_NewUser_user_4.json index 80b252dc16f..fb65c4a6634 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_4.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_4.json @@ -1,106 +1,5 @@ { - "assets": [ - { - "key": ">A\u0019\u001f\u0008\u0008,􍏹_m􇛺G'", - "type": "image" - }, - { - "key": "\u0004\u001e􎳱U*󻄠Ꞻ𥘟z{o\u0008", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "􂳥*\u0007E", - "type": "image" - }, - { - "key": "󹃁N\u001f7WkL􃋷G1놤𩕃􌣏", - "size": "complete", - "type": "image" - }, - { - "key": "=ntM2\n7=:\u0016 󼈂", - "size": "complete", - "type": "image" - }, - { - "key": "\u0005𪇸J􊫝\"쐈\u0004E", - "size": "complete", - "type": "image" - }, - { - "key": "B\u001d\u0003􅯒\u001a9𨍹nQ􎿞,Ps", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "\u0013rR", - "size": "complete", - "type": "image" - }, - { - "key": "K\u000b{O\n圸􍥜@G", - "size": "complete", - "type": "image" - }, - { - "key": "MT\u0019\u0008\u001bC\\i(2쮡(l", - "size": "preview", - "type": "image" - }, - { - "key": "h􉼟􇁖\\\u0016苏𒅾", - "size": "complete", - "type": "image" - }, - { - "key": "𤅢\u000b$E+Uu]", - "size": "complete", - "type": "image" - }, - { - "key": "[Y", - "size": "preview", - "type": "image" - }, - { - "key": "\\P`􈙇", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "'\u0000\u0002)G\u001d", - "size": "preview", - "type": "image" - }, - { - "key": "叝A\u001d-?\\SM󵣉_{`\u0017\u0004", - "type": "image" - } - ], - "email": "K}V􁑕t\u0011₤\u0004}nR𥅞􍮩s@\u000cI֬\u0019\u00012P\\𡏺x\u001d􌁢2!󽬌{󻒆𨊍掩􅴱4", - "email_code": "uqc=", - "label": "\u001b󹁶U<󽶈\"w\u0007<9s􌵓\u0007(?A󷤡\r\u001b󵃩y,@", - "locale": "cv-IR", - "managed_by": "wire", - "name": "藍􃯔\u001a󿓝\nN󹖰\u0017󰺲\u0005\u0014G\u000cN?󳪤p\u0008𓍀􆬽1\u0017r\u0001𘞩?\u0003|􍚢{Z\r\u0004", - "password": "\u0010\u001e圧\u0018\u0007󷉧K\u0008􀕼S/尔\u001dH󸘳D\"\u00181y:\u00191g\u000c~􌐊\\\u0005i􍵝S}앙􋯧𡃛\u000e𗆚A󲿽\u000ft\u0007N\u000fQJg6kD\u001b󹸈\u0018󾉵QU$PN%𩣧'`􍰋k\u0013Z<\n\u0019u]𘋠6􄴫🌋P𐠡(\u001a\u001a79\r𮍘\u001b\u0014􎁨􆀸=狳\u000b@晪\u0004F{𬪭<]󸵐6e8\u0006\u0004稨[\\m\u0001R>\u000b𫤅􅌋Lꂲ(,5)[s]W峝N伌浌&}\u001b@*p%'~s$o􌡿P\u001b\u0006\u0003/.&\u0016.\u001bڟ⠟𗪠\u001b.嗩t𡹬𤈛𬢆\u00197\u000czO-$K𘓈\u001b\u0010l=gcx𣅏$h\u0018B\u0011xT+ ?f+'dH􏝋󹉟2Gu𠞼𬒩4ar[+P\u0017똡vU}\u0011~\u000f\u000eWMi6\u0018_~􌪂\u0002Dಣ^\n~Zf:\"o󿎶3󽒔>|G5𔕴\u0002'=%\"\"|5\u0000y\n:5\u001bG츧}|屍C󿁸􅟮e\u000bi![?𢦜\u000cw*xIV\td F}X;􆱗𠿥\u000c=\u0018%\u001d𨑹(󰣓䆺嶚i=y6t\u0005󸳐\u0011󲄟 -5F6G\u0011󹳸NO.𠁳ly􂄭e,c\"f\u001d%\u0016\u0012󸉦71Pⶔ󷜨\u0019󸮇􀼗1\u0012|\u0006", - "phone_code": "FYKXjOe_umVeNz8oszsuHQ4S", - "picture": [], - "uuid": "00000000-0000-0000-0000-000000000000" + "assets": [], + "invitation_code": "RUne0vse27qsm5jxGmL0xQaeuEOqcqr65rU=", + "name": "test name" } diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_5.json b/libs/wire-api/test/golden/testObject_NewUser_user_5.json index 43e21ce4aad..2d0137614db 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_5.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_5.json @@ -1,148 +1,6 @@ { - "accent_id": -20961, - "assets": [ - { - "key": "\u0003󼙩8pq", - "size": "complete", - "type": "image" - }, - { - "key": "鄬c9}+}T", - "size": "preview", - "type": "image" - }, - { - "key": "7𢁻ui%4􈪳𢘅", - "size": "complete", - "type": "image" - }, - { - "key": "\u000c\u0005Vd\t#Aj7#􎝊", - "type": "image" - }, - { - "key": "nTW\u000c𡪸|𪯇\u001f󱓲0|}\r㪆", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "Q􏄏𦇯𤇧\u0004x}$", - "size": "complete", - "type": "image" - }, - { - "key": "󱍝󾈢\t\u0015\u0007~\u000e", - "type": "image" - }, - { - "key": ">\r塀)", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "?<󾒣\u0015r𩉖\u0016Qi", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": ",-&b𤰒1cw<={", - "size": "preview", - "type": "image" - }, - { - "key": "x7\u0008#", - "size": "preview", - "type": "image" - }, - { - "key": "\\\u00068p\u0006", - "size": "preview", - "type": "image" - }, - { - "key": ")\u0007黜@\u000e'z􈔄 E#􂯎󲥽", - "type": "image" - }, - { - "key": "󼗷\nlᕻ\r?", - "size": "preview", - "type": "image" - }, - { - "key": "\u0019u󹚬", - "size": "complete", - "type": "image" - }, - { - "key": "8𡷪\n8:\u0006W%M", - "size": "preview", - "type": "image" - }, - { - "key": "!\u0014\u0001\u000f𢳵\u0007𭼈\u0017|", - "size": "preview", - "type": "image" - }, - { - "key": "󲷾\u001a덣􎡋􇿬:𫖆", - "size": "complete", - "type": "image" - }, - { - "key": "𘊊饩Ub", - "size": "preview", - "type": "image" - }, - { - "key": "v}\u001a跳􁲼\n~y\u0008\u001fk", - "size": "preview", - "type": "image" - }, - { - "key": "\u000fX^􀍷f", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "󷽼𡄼󸩿f6f)S𠛾􆨺\"", - "size": "complete", - "type": "image" - }, - { - "key": "Xbj\u000c\u0010", - "size": "complete", - "type": "image" - } - ], - "email_code": "RZICMcCOzqyRTB0d17Rbsw==", - "invitation_code": "EXZtnNu96rBu0DQCJ_vGdZkjhH1SSzT2MAHgTQ==", - "label": "𭔀", - "locale": "hu-CG", - "managed_by": "scim", - "name": ";􌞇𘣣\u000f𣺗\u0001", - "phone": "+8057919910" + "assets": [], + "name": "test name", + "password": "123456", + "team_code": "RUne0vse27qsm5jxGmL0xQaeuEOqcqr65rU=" } diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_6.json b/libs/wire-api/test/golden/testObject_NewUser_user_6.json index 802b1f431fc..9302c14469c 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_6.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_6.json @@ -1,71 +1,9 @@ { - "accent_id": 30946, - "assets": [ - { - "key": "l󵵒zuLAm", - "size": "complete", - "type": "image" - }, - { - "key": "l*+}􄲦􊁁䄋%Q\u0011\u001dns𧓨\u0012", - "size": "preview", - "type": "image" - }, - { - "key": "􅶘\u001fd;\u001a󹇬􉼹s\\fo", - "size": "complete", - "type": "image" - }, - { - "key": "󻿍ty󶫾v􇧎8𮉎_Pc󽪡5", - "size": "complete", - "type": "image" - }, - { - "key": "{", - "type": "image" - }, - { - "key": "\te:q", - "size": "complete", - "type": "image" - }, - { - "key": "8]󹨴9􆲤\t𗋥\u0015{uc", - "size": "complete", - "type": "image" - }, - { - "key": "󲃵s(4J\u0006,􀅧JQ", - "type": "image" - }, - { - "key": "𬌰ﮑ\u000b", - "size": "preview", - "type": "image" - }, - { - "key": "𧚅'\u0008m􅳃腰", - "size": "complete", - "type": "image" - }, - { - "key": "\u0018s㻇\u001dX_\u0012u3YT𞤦", - "type": "image" - } - ], - "email": "@S{󹅨", - "email_code": "ZTf52SPQ5jk=", - "label": "`r}\u0014m􊐈/h𥲸EP(-u9?qU)􂜅\u00071", - "locale": "mh", - "managed_by": "wire", - "name": "T+u𣛔fe01`)S%{󿆓}u帞o8-W󲸢\n\"q]B\u0007U㑸F𡕹\u0003n\u000737\t󳕭J4*_󴊓=f\u0013獣2󹣉Go}𘑍LhA蛲\u0016PM1v􌫚\u001c\u0005󷢩,󿚤\u0019􃰞\u001c9+9,1YT\u000et𨌨𭒠\u0015\u0017\u0002󶖝\u0017%\u001d𧼪G0{􎒅🇬\u0019y󴞬.Q", - "password": "+':l➄𫢸\nk|}@Z`D.\u0000Z𨵷;\u000e\u000c\r𘁔*l{&|\u0015o8镔)+\u0002󿴢𢻧\u000fF\u0013󳞌\u0013R찙<4N󷮤􏔹z@;󵱐#􃠆$}\u0011sAXuIWoB[N󹫙X\u0008e\u001b\u0002ꕮ$4𥀽󼶠S)\u0018#w}3p\u0001\u0010\\?\u0011S7􂾾E", - "phone_code": "7dJcoVoTKFo=", - "picture": [], + "assets": [], + "name": "test name", "sso_id": { - "subject": "󿸰", - "tenant": "" + "subject": "thing", + "tenant": "some" }, - "team_id": "00000d6f-0000-2269-0000-6bf4000062f9" + "team_id": "00007b0e-0000-3489-0000-075c00005be7" } diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_7.json b/libs/wire-api/test/golden/testObject_NewUser_user_7.json index 94b564f400c..a778929fa94 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_7.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_7.json @@ -1,87 +1,12 @@ { - "accent_id": 18148, - "assets": [ - { - "key": ",m1.I7", - "type": "image" - }, - { - "key": "\u0002*RM", - "type": "image" - }, - { - "key": "sO\\\u001d㥎", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "$.A>Z", - "size": "preview", - "type": "image" - }, - { - "key": "7r􃟳󿪝", - "size": "preview", - "type": "image" - }, - { - "key": "%𮀕󿰑iW\u001ff􂜏􇊱\u000f\u0017\":𦛛󼤱", - "size": "complete", - "type": "image" - }, - { - "key": "𩓄󺎛p", - "size": "complete", - "type": "image" - }, - { - "key": "\u0017𥷭o*", - "size": "complete", - "type": "image" - }, - { - "key": "Bbt", - "size": "preview", - "type": "image" - }, - { - "key": ">^\"􀪤𝙠\u0003[􍆩𫳳", - "size": "preview", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "\u0010A숇Ue󶸳\u0019K$", - "size": "complete", - "type": "image" - }, - { - "key": "Lj\u001d?\u001at𣥪􈶿", - "size": "complete", - "type": "image" - }, - { - "key": "\u000cL𗤩?Pa\u0002󸢚R\u001e\u0006􉝳\u0007=", - "size": "complete", - "type": "image" - } - ], - "email": "%'\u0003\u001a쭩\u0007􇺛Ow󴲠耊󱾟@", - "email_code": "34dAzMrB0CunAvR9", - "label": "n󱣈2", - "locale": "gv-CH", - "managed_by": "scim", - "name": "\u000e#KrlW\u0004󴻠󴢝wzLN.*BR\u001cJ􋴵/zi[𧔬In\r.)󴍜󸄣sﴀp8\"i\u0000􎳈\u001a󳐻\u0016k弢𣨕n\u0019󼑱\u001cS󸓿L随i=\u0011\u001e$\u0005𩌕E_䣉\u000c$u𦛝`\u0001􁔖\u0011󺂖󹃟󳅩𫍡tl須P\u001dޟ&<\u001b0\u001f:\u001abm(![\u0002~l.\r􀹮𨺯)z𡃴O􄪞\u0002􋸂`􀭇|\u0004􏵅o3iy𠚑\u0019tSd󹮳", - "password": ":Y􃵘@T󳛜􈋤\u0001𩖂~󿳇\n\u000e\u0017\u000c󱉶$}􍰯\u0019􋊺𩟖𮩀𮭈Al󴦽𗦭􎖜\u0008,])^\u001esz?󼤞9S,M)\u0007s=hmpCp\u0016wS󴓲c)z\u000b=梲-dU𧈧|\u0010@\u0016\u001a\u0007\u0017,\u000c㠌𢏾(L𦧼\u0016\u001b1~B\u001a􉂈+P!{@ᆴ󻥀\u000e4:G_\nI8\u000b󸅇g|􀯙Re\u0004E\u0018󺹸Dob3\u0002\u001bA2\u000e뎤&\r?㪉0M5􍨙,&ey\u001a󺋭QB\u001e{\u0015ᓧ76󰡬D􂪹J$􇫙qZYgd0i\u001d\u000cbZ\u0004𖥧􈴮D&m\"rM⠴𗰏\nhKg=7%Il􌢢g󵽱C}뭇䩢v󺩗 7!\u001erK c\u0018 %A\u0004𣽹\u000b\tIb\u0013W8\u0001i𪧡􎧸|OfiJ@@j󻊵xO;`󼄅\u0017c#\r{𭟸󳶘󴧨𩀿n \u0003IP\u0003Y-\u001b\u0010Ev\u001f􉠣\u000b\u0015zgx\u000fE\u0002󺕹'\u001a\u001d/󰀽DCD\u001cj\u0011\\𣙐뛁􃗭{1A\"\u0014-󵕹1􀅏􆯖wT\u001dB-q1a\"$S2x;󳸭y󻸁\u0000t􂥚􁤏J䶪\u000cꜚ]0F( d􋠸~hﷰzt/Eነ3痝W\t-󿡻Lh<󳀊󵽈\u001d\u0012B\u0010𧍇𮙁􄩎a𗾈􈟏99呂\u001f\u0013f\u0002J\u001cc㽰F\u00188ਿv\u0006m􀷪k􆎞U\u0014bYm\u001fIV𨲼\u0005,n\u0008x\u000cl\\e󻀢;𤶐󳵏􉞮\u0010\u0011󲬈o󵝌KF$\u00028\r\u000cZ\u0013Z𮦛\u001c􊽯_󱵒:,\n 􇩎 AM𦽭\u0012w飌WB󷵿\u000cCS#𥛙=􎖮󱍯pC-.𨚈C~q?_O\u001b􏰙)𤝋\u0004\\\u0001\u0017-胾)\"la\u0004𤗪HAf􆼲􋄚숨l\u0002d\t)`.>󾳯u𧵮􋻎c󴂱\u0002|LiP􋐷L=󲦟ä́􄠶EE􎃀󷢻\u0003󴍥hQ\u0017W􇳛𗇣G\"ꩬD\u0014_􁺍\u0002#􉢽$𣪍\u000fL(􆼡\u0002t󸜉$IQX]p\u001b4&0􏍜\u0014􂴙m\u0016\t\\(^\u001b𝀢,D]􊆑𨆏\u0004\u0011IAd萅0N󻗾\u0008g6\u0013\u00137\u0015k\"􃿮)pI𤢭\\M𝔥\u0015砉\u001f𤺤6~T?\u0005\u0019s륀-[𡪿wጶDq𦞙\\󾕸%b\u00069󴖭2CCଥ󾡁ojGT g틓󶂞xSeL\u0018㪢\u001a󰨺'0:j4𑢹q7󴋃m\u0005s\u000e󻘭\u0005錪iG𐭇𮜌ᐓwv𮂜n\u001b\u0005\u001f\u0019􇃍󳛂\u0012Ce) U􆒑\u0006fo􀭟􎘹c􂜞L4\u0011-\u0016􂽾L󹪷𭖔\u0017|oW\u0017\u001b>bD\u0000𘉣dm𐛜vW󰹫(2\u0018z󺧐汋?n󰦚󷜅w𡀮\u0000\u0014}􌳉|H<횡U퉶\u0016󽥪𢯏\u0011W𬤏TM\u0006+LT\u0015;-!E>$\u0014j.\u0012q^\u0015ᖡIN􂮠>V\u0002𬼶󽎽OA🆪\u000bvCf𩕱n\u0000𐌋\u0005?^\u00166\u0017\t8:at\"w`􏡕rl䳹𝅆𪡨J󲣦~􋒨Q󳗴Lm?c\u0012v\u001di~i\u0014\u000cG%I\u001f>l!\u0002L\u001d\u0004UW\u0003􁏩\\Bg㋻\u001a⤢0EQM\u0015􈮕>匳\u000bY쇫𥉴𗻘L%^󴍃r𨌤%>\u000b0z󲶭m\u000bEh(𬁮u2\u0011v󽮶Q\u001eB𑰇I+\u0003kaR󴮝=)\u001a_󼂹Tv\u000e%𬭧M:𤊈&\u0014\u00070\u000c\"\u0004👫{󵄤\u0005)\u001aF\u0010N`08𭴦\u000e\u000e𤧢󽵦k􅉔𧀙Q\u001f\u00191[/󶾛𫓤Q􂡤𐲓re𠆔du*󸱠\u001c~∹a*4\u0012cr󳜕b", - "phone_code": "1Yzr8-Lo2FnYwYYaJFeGEh3yaODV8pFYx3E=", - "picture": [], - "uuid": "00000000-0000-0000-0000-000000000000" + "assets": [], + "name": "test name", + "password": "123456", + "phone": "+12345678", + "team": { + "currency": "XUA", + "icon": "Coq쳋\u000b𬟀", + "icon_key": "\u0006c𥁱L ,", + "name": "\u000ce\u0005󷀰zm" + } } diff --git a/libs/wire-api/test/golden/testObject_NewUser_user_8.json b/libs/wire-api/test/golden/testObject_NewUser_user_8.json index cda1db966b7..3331ac20e7c 100644 --- a/libs/wire-api/test/golden/testObject_NewUser_user_8.json +++ b/libs/wire-api/test/golden/testObject_NewUser_user_8.json @@ -1,31 +1,7 @@ { - "accent_id": -26710, - "assets": [ - { - "key": "\u0004󺵈􁍶/􍠥uIXl\u0005b𨍛􅻿", - "size": "complete", - "type": "image" - }, - { - "key": "\u0010&", - "size": "preview", - "type": "image" - }, - { - "key": "FP𮭗4@", - "size": "preview", - "type": "image" - }, - { - "key": "𠃌𦫚𮄠9~\"\u000f", - "size": "complete", - "type": "image" - } - ], - "email_code": "OXIgclTUyV_J5am0ZDqm7eLN-c8ecvk4", - "invitation_code": "1579", - "locale": "fo-FM", - "name": "\u0002O.岾𗳬\"\u0012k\u0004󳈓C<|𘉊𦵛蕃2\u000eu+`9\u000eb#A7n\u000edr􏋐w\u001b􍩿x8𫽾x𠆲󲞲O𣮛󲹂ฑ\u0015\u00004𗨧􁮢b\\#􂲰oC2-=+𗸢L5\u001c\\*L\u001e@F𧳸/\u00069m4)\u001d\u0007t`\u0010󷗖8)s\u0007o􆫶n", - "password": "(\u0003V󷬘󽵣\u0008𧖌􁣵$~&󽡿o󽻚MTfC.󹠠;WO􋴞6#{\n􅊷z􂀔K疶6\u0014󵡨𡙄(𦰤\r?Lc\u0018xNE\u0005h/JeS\u0006\u0018𪙊+60W3ySv\u001f@\u0013w􊔶\u0008B\u0016^%\u0019󱚗𣵠iodDm%🄸\u0011]m\u000b_啷𬏚$\u001d𮄎𡷔yt\u0004fm\u000e'@#\u0014)𬨖|\r&$*!%\n\u0017r]{v\u001c\u0018\u001c󴨉\u0008>𩆈d@X0\u001d8𦩺>\r8{𘕠\u0010􅌻󺢤C\u0000k󺦖\u001bM^:􅅴WF\u000f\t5Qi;}\n􍹜㧖󴠩\u0010\u0006*Pk\u0001𑁀*𪼤mNp徱@O\u001e&󺚥F󲼢tx𗅓?󾏘Ps􅐎r󶹴{E\u0003\u001d􍬹𮠃zcn󸗠e\u0001kr=󽀕z~e\\Dꀤc\u001c[J^\u0013𓈹\r𮈮ᯮw1􍦺󲅋\u001c𫻵\t󷛣󹅦;𪜀 \u000bM􎦱IF2\u001b𮭙cbvP\u00080脇q>󵮾#%k𘡛Zw󴠚󶫚y捡x\u0012|􀖣\u0016@\u0018>\u001dR\u0015\u001a3%\n􅺐\u0002􇲓\u0011uOs􎞂􄅝𡱪u􆃜a!\u0012𠗄fWgk5\u001d􈐿\r󸫆ꞔ𣤭\u000c\u001eydAs=󺃙z쇻\u001c\nxR\u000f Ng\u0006C:X𣲿7\u000c[󺉐k\u000b}\u00175\u0012Wm%􉡕𨠠,𤀾\u0010Gr􆜓ZvO砀B󵘩hjYZiGd\u0008P\u0001GHG-\u0014\u001fy\u0017r9$󽪣Kmh󠁦8g3ㆪt󸁮󰦠󹚓\u0008\"►\\sn\u0004>\u0011𮠫6𠱝\u000f8k󷝀6F🤲&\u00189\u000c'Bn앲\u001c땼\u00150H=\u001fe6𐨨\u001f0􃘠L\u001c𧺛o9!󿑵􋔝􈜷r\u0004:折Ǭq1\u000c􃉃Ꮧ\u001b5u5𧌡>U󰙋$蘆i\u0008P偁~𐦑\n\u001b󾹟\u00052\u0010_%𧍶󳳱\u0012b^\\_􉣖CD[Rg𡀗l🢤*󰰫🙏\u001d􏹝\u001fX\u0005`\nM\u000e􄰾0H*i\u0005󺕀\u0003#qꘒx\nOaE*U󶊍GRw󰊊]􎩐/#)E󸥝z\u0016􊒬\u0014\u0013\u001bS\u0019o𫥿U\tK􉕈𐧞`\u00016풹𩯟􍖽🃭:D䑺풓󸡝7𩼉y󿾪/S\u0015z\u0004}7HRV􎰾􉁡.FQ󵐩調􎋉𐐠a;􁤚󼚂\u0017A떆􇖋\n𑊓𣎻V𦋍󿒑S\u001e\u0008S%󽑆S^d\u0019\u0008󴤰.gd\u001d1!(\u0012(DE𭆦\u0014󳇠􎒣@󿼟m󾙏F=\u0014󰻞𔓰噀aAp𡙅\u0015f󷦓󱨕C官𠊌􆆶(@\u0018-𢚰𐰠4/]󴏣\u001d􉈝9/E𤰭<𠡽`刜#L\u0012\u00042J\t\u000fj@w\u00179OoyN\u0011\u0005棱[d􈁌􋰓\u001c󽠷F[\u0001\u0012𣵔uE󶗎H2仇H%5]\u0008𨽮\\\u000e\u00138Nr\u0019e\u0007cE􌾄S\u000f􆬆\nt\u000cI𔒡{󹏜.E*𧵚z𛅹#]zԤ6GM\u0008󽚥lb\u0008\t|RJ\u0013󼸁􃾋𩙚|^\"E\u0004mc󺷿ﱊ\u0012@􌱛\u0008󵟾􄴐󳶌\u0007x2w痳􂮊􏎉\u0006O􈑝󻝀\u0015fp\u0006S,P&\u0018Vw\u001fqI^:\u000e46m𐲙rJyiᾛ=D􍬅&\u0016Uij􂓣\u0018vi\"f\u000cX|\u0006󸰾A밌􈚎󾩻YE\u0013\u000eoh𣜼􉱔\u000c깱u&%\u0006v𘫱k#􎧺`􆴪\u000c{\u000e,\t\u0018\u0003= 􋁜 ?􄵫\u0011\u000e𨳮7U縰Y\u001c􅲄𦍴𫀃g\u0016s5B&\u0016\u000c\u0000\u0019𫐩\u0005\u001f󾀁+L\u0012iE^.􏔸|l\u0001b]i(h", - "phone": "+71827573", - "phone_code": "ohTCWvY5M-J1AbWoFfqtjg==", - "picture": [], - "sso_id": { - "subject": "󶃪", - "tenant": "L𩵖󶃲*" - }, - "team_id": "00007c3b-0000-1728-0000-6e4e00005f30", - "uuid": "00000000-0000-0000-0000-000000000000" -} diff --git a/libs/wire-api/test/golden/testObject_UserConnectionList_user_1.json b/libs/wire-api/test/golden/testObject_UserConnectionList_user_1.json index db9fd2888dd..4d3bf2d37c8 100644 --- a/libs/wire-api/test/golden/testObject_UserConnectionList_user_1.json +++ b/libs/wire-api/test/golden/testObject_UserConnectionList_user_1.json @@ -1,10 +1,8 @@ { "connections": [ { - "conversation": null, "from": "00000000-0000-0000-0000-000000000000", "last_update": "1864-05-09T06:44:37.367Z", - "message": "\u00188\u0002󼭔-󵈪z.a&Kho󴱐󺽾}9nF𪒲􁺜l\u0014q}\u001a\u0017󺋍m8#餑A􌡲􀲱}Z췅6r-/D*\u001fL󺄥􏻂D􆗉\u0019󹳬ꂛ%PZ5􅈬\\}퓞\u000fᖑ`󶡛'1xNcFhN|*󰵡\u0010\t瓏󺅎6\u0012/IK\u000e􁑑󸘟s𣽛\u0019BM*a󽈎~j\u000b#\u0011-D𭣺𘅁\u00057{𮓥N\u0017C!~😟EGS=\u0005󴋀\u000f󷙏ଡ଼b󸣚'K1\u0000E\u0002𧹴J1\u0000AI%툼QV&Z`O\u0019~Vu6t\"󸨦_I}a󻶚5󶡸Y#\u0017:U𢐵\u0007󼒭29^2t􆀜쥚dC𗏯\u0005\u0004\u001c,\"5.9;@\u0008`gl\u001dEp5\u0015\u0019.VYE_\u000c\u001a\u0004\u001c\u0005bRb;=􄷬󱰎a\u000en\u00151fF", "status": "pending", "to": "00000000-0000-0001-0000-000100000000" }, @@ -12,7 +10,6 @@ "conversation": "00000000-0000-0000-0000-000100000000", "from": "00000001-0000-0001-0000-000000000000", "last_update": "1864-05-09T00:43:52.049Z", - "message": "位\u0015O \u001ez𠥡\u001d󱼟𢎵\u00188:󺔂bQ(XKw}\u000c\t􏏙0䗼kx\u00070=󵥀;L\u000c*\u0010ko\u0019z^x2(󿛢\\ep뗂w𬸪71\n 3\u001d\u0004\u0004?z𥪟䏡->🛃a,𠟚j;-ﱻ\u0013󲨌(L\u0012󴃱\t{􋓊좙XR􃩹B\u001fW哥d\u000e-\u000e\u0007", - "picture": [], - "qualified_id": { - "domain": "7.jw8.la-0.r", - "id": "00000000-0000-0002-0000-000100000001" - }, - "service": { - "id": "00000001-0000-0000-0000-000000000000", - "provider": "00000000-0000-0000-0000-000000000001" - }, - "team": "00000002-0000-0001-0000-000200000001" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_13.json b/libs/wire-api/test/golden/testObject_UserProfile_user_13.json deleted file mode 100644 index b21ede36239..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_13.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "accent_id": 1, - "assets": [ - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - } - ], - "deleted": true, - "expires_at": "1864-05-07T18:04:28.203Z", - "id": "00000001-0000-0000-0000-000100000001", - "legalhold_status": "no_consent", - "locale": "lu-VG", - "name": "u\u0013蘇T\t\u001f;󱨲[\"n`\"\u0000D\r𧵣 Vj\u000ej>Pb􀡭]𣉾󳄵I\n\u0018􇎒6\u0001x\"p阞E\u0018@w􌹗𘢑R\u000bX𦕪𫁉􍻮@K|K󽮦4쬈𨦏\u0002o9", - "picture": [], - "qualified_id": { - "domain": "1.z6lionkv7", - "id": "00000001-0000-0000-0000-000100000001" - } -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_14.json b/libs/wire-api/test/golden/testObject_UserProfile_user_14.json deleted file mode 100644 index 160e2991a5a..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_14.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "accent_id": 2, - "assets": [ - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - } - ], - "expires_at": "1864-05-08T01:21:51.302Z", - "handle": ".0f-ea", - "id": "00000002-0000-0002-0000-000100000001", - "legalhold_status": "no_consent", - "locale": "oj", - "name": "𬜸d􃸶xuꇊ\u0019\u0002\u0007\u0017\u0013.\t.7k^!5*󴲎iT)\u0019􆹔󻰱흼\r\u001d𓏘~j\u001f\u0011X\u0001\u0010f􅔵Vo\u001c7]\u001b𩸅J𩿪􊢒,-K𫬃w`㕠憰\u0004^>A\n鄖C𝙗v􄅺R1Q󳷊\u0018U\u0005P\t\u001c8~\u0018𭏆\u0004𥔎𬪽𭓂\u0007_Kdj얒lN+L?󵡡-\u001f􁩀wGP.Zm", - "picture": [], - "qualified_id": { - "domain": "9f97og.h2af889e64zw", - "id": "00000002-0000-0002-0000-000100000001" - }, - "service": { - "id": "00000000-0000-0001-0000-000000000000", - "provider": "00000001-0000-0001-0000-000100000001" - }, - "team": "00000000-0000-0002-0000-000000000000" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_15.json b/libs/wire-api/test/golden/testObject_UserProfile_user_15.json deleted file mode 100644 index 941aed90227..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_15.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "accent_id": 1, - "assets": [ - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - } - ], - "deleted": true, - "email": "F@\u0000", - "handle": "3ti0segu2s7u294jpsv5lixp_axfvix4h.a9phbpuprb5g1.g5a-5hh7ezf2ur8z.2pms57_cv2pupxv8xdgnvbqyx_eiyk3k0bsky53x1fzivty4j.c79jfo9zr9f8pru1j-ixl67d9cz23b1e-m603_iz8_2uf8neudzfq1vi1ec", - "id": "00000002-0000-0002-0000-000000000001", - "legalhold_status": "no_consent", - "locale": "dv-MO", - "name": "󹚾-󷀧⤰\u0015S􅅐\u001aj𡄧tu\\󶜊𬁃\t\u001e𧿻𨑽󶌭\u001c\u0017\u0007d\u0017eT\u000e$􅿴YT_e𭻆!)\u000f\u0012S]􎖂SYm췈g\u0015pX,GQ\u0010F\u000fJ\u000e\u0008\u000bR\u001d\u0002挏􈍤y\u0018g轙J\u0015\"\u000cMX󲺆3g􊾈n4􁁀\u001f𝣩\u0010", - "picture": [], - "qualified_id": { - "domain": "q64o7.302d44.yvc0-7.61.v9mv", - "id": "00000002-0000-0002-0000-000000000001" - }, - "service": { - "id": "00000001-0000-0001-0000-000100000000", - "provider": "00000000-0000-0000-0000-000100000001" - }, - "team": "00000002-0000-0001-0000-000200000002" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_16.json b/libs/wire-api/test/golden/testObject_UserProfile_user_16.json deleted file mode 100644 index f6a13e110d7..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_16.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "accent_id": -1, - "assets": [ - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "type": "image" - } - ], - "email": "V@|", - "expires_at": "1864-05-07T06:39:38.220Z", - "handle": "guo2m_9jgnm.snxp7uazht2j6je41-be6p5y9g-0afnnll.k5x0al45l948yuys97uy.7azgirru0r55.h-2ylot.j.y433-1jdw_ecazkzeqpa4lr.zt9.zjjaz7bzvxo4baqtod48_388s6-vxifhn9giwz6nc290fw2589psan", - "id": "00000002-0000-0000-0000-000100000002", - "legalhold_status": "no_consent", - "locale": "ja-BB", - "name": "䰹뺎%P➪\u0007􊶙􀦨?.ő춷\u0001%ᗊ𢐑󶰧𢐰ꓸ󸪢⤻`)􊌊(&󽺅W活𨘁􉐟Sh\u0000𘦳󷜲\u0015\u0019\u0000󸈫󻚜\u0019*vUWp=/H:\u000fP𣍻K/Q}􁾋(󲮂Z𧢤)_󵕶O󼖞\u00180󿶓󳼰g>󺙵\u000e\u000fW󴰽h;𓇰\u000fyJt\u0016𑈽(q}鸶:b𠓔/\u001eGV􁇤{r㜛$oo1H󻀔n\u0008ꙛ􍧨hBiS􄈏6Az\u0010'􁆉=", - "picture": [], - "qualified_id": { - "domain": "19.i.mwv-7", - "id": "00000002-0000-0000-0000-000100000002" - }, - "service": { - "id": "00000000-0000-0001-0000-000100000000", - "provider": "00000000-0000-0000-0000-000100000001" - }, - "team": "00000002-0000-0000-0000-000100000001" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_17.json b/libs/wire-api/test/golden/testObject_UserProfile_user_17.json deleted file mode 100644 index 23791b7ef7b..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_17.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "accent_id": -2, - "assets": [ - { - "key": "N", - "size": "preview", - "type": "image" - } - ], - "deleted": true, - "email": "I\t@%", - "handle": "uva.d", - "id": "00000000-0000-0001-0000-000000000002", - "legalhold_status": "no_consent", - "locale": "gn-GA", - "name": "@@v𢇞}$2^]󰈯=\u00076𨅸\u0010*\u000c(\u0018(76kCs\u0006X[~痝\u0000\u0000􌫡􋏠o쬟a\u001f0E|\"d𥇪\u001a{!X\u0002\u0007F`\u0017\u0004*󰥚𒂇;#tOw\u0001D􉤮 􄲲E\n\u0018\u0013D`>\u0013\u0017965!CL􎖍󶿪B9\u001f\u0010[󾕮0􋃽%\u000c.y\u001e嵀\u0007\u0017莖\u001e[繜󶴎\u0006PuC", - "picture": [], - "qualified_id": { - "domain": "94nvo.97j.g83--2e.4-t1g.z", - "id": "00000000-0000-0001-0000-000000000002" - }, - "service": { - "id": "00000001-0000-0001-0000-000100000001", - "provider": "00000000-0000-0000-0000-000000000001" - } -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_18.json b/libs/wire-api/test/golden/testObject_UserProfile_user_18.json deleted file mode 100644 index dcfb8279b93..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_18.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "accent_id": 1, - "assets": [ - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - } - ], - "deleted": true, - "expires_at": "1864-05-08T13:37:48.974Z", - "handle": "50-a8ceq8yfwac.lp.", - "id": "00000001-0000-0000-0000-000000000001", - "legalhold_status": "enabled", - "locale": "kr-MN", - "name": "$󵧈\u0017q𪋑\u0015󴹰!􇑏\u0014󱯑\u0004+X𮢿󳜮n\u001c\u001ar0􉤷􃋱z5𮭮6󲎽mBxr\u0007-H𪘵≺\u0016f𧾹󶈂􄿽EMAQ𮒙hm\"t󵜏𩔄=\u0000h$:>󾤳E暦𝡗lz𭑜oY\te\u00117B􇁑Be\n\u000c􂓃/\u0017o\u001aw􉼻袼󱓬􃌍R𧜫\u0019𮐓풂\u0005饂v\u0017􊖓𫾻\u001f󲦞dj=\nZM", - "picture": [], - "qualified_id": { - "domain": "r71-2.u", - "id": "00000001-0000-0000-0000-000000000001" - }, - "service": { - "id": "00000000-0000-0001-0000-000100000000", - "provider": "00000001-0000-0000-0000-000100000001" - }, - "team": "00000000-0000-0000-0000-000200000000" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_19.json b/libs/wire-api/test/golden/testObject_UserProfile_user_19.json deleted file mode 100644 index 641efd0ca5e..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_19.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "accent_id": -2, - "assets": [ - { - "key": "", - "size": "complete", - "type": "image" - } - ], - "deleted": true, - "email": "a@\u0008", - "handle": "2g", - "id": "00000001-0000-0001-0000-000100000000", - "legalhold_status": "pending", - "locale": "to-SH", - "name": "\u000b󾑁\u0006W\u000bKmM3,j󵆅uX𭈶\u001d\u0007\u000f:󽽨𤽤m\u0017@c􁯾ePd=Bhs:\u0015\u0015a(􀲺hyWvEO󹻥Q\u001f\n𮞆􃌎y)󼓬Y􆃑ف}\\\u000f\u0010\u001e𫜃mP!z󴒽c\u0007qMFa\u001b􄸘", - "picture": [], - "qualified_id": { - "domain": "00.252-t7.7l7.r478qz0a4.b", - "id": "00000001-0000-0001-0000-000100000000" - }, - "service": { - "id": "00000001-0000-0001-0000-000100000001", - "provider": "00000000-0000-0000-0000-000000000000" - }, - "team": "00000002-0000-0001-0000-000100000001" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_2.json b/libs/wire-api/test/golden/testObject_UserProfile_user_2.json index 156136f5139..0e515e092a5 100644 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_2.json +++ b/libs/wire-api/test/golden/testObject_UserProfile_user_2.json @@ -4,6 +4,7 @@ "deleted": true, "email": "𪅁 @", "expires_at": "1864-05-09T01:42:22.437Z", + "handle": "emsonpvo3-x_4ys4qjtjtkfgx.mag6pi2ldq.77m5vnsn_tte41r-0vwgklpeejr1t4se0bknu4tsuqs-njzh34-ba_mj8lm5x6aro4o.2wsqe0ldx", "id": "00000002-0000-0002-0000-000000000001", "legalhold_status": "no_consent", "locale": "ny-MU", diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_20.json b/libs/wire-api/test/golden/testObject_UserProfile_user_20.json deleted file mode 100644 index 66cbe20b8a0..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_20.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "accent_id": -1, - "assets": [ - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "", - "type": "image" - }, - { - "key": "", - "size": "complete", - "type": "image" - } - ], - "email": "󴎚!@|D", - "expires_at": "1864-05-07T10:18:53.031Z", - "handle": "zticd1l", - "id": "00000002-0000-0000-0000-000200000001", - "legalhold_status": "disabled", - "locale": "rn-CI", - "name": "fB\u0011􎖞𐇑Wg_!\u0017\u0014oZ𬊇t<\u001c\tI􅽨શr`\u0001O𠊄+n𝥷ኒ]`dR\u001a\u0011z2􈱼-.4H~資|𘁴<𘗻󱍒^~󴿟gR,\u000c\u0000 x)`D@,\u0017v𧊘􍴘1%@#R}(C2OCy\t2ẝ\u001a\u001dgs&d󰙩𪁔\u0001󷙎^", - "picture": [], - "qualified_id": { - "domain": "2.ei5-x3", - "id": "00000002-0000-0000-0000-000200000001" - }, - "service": { - "id": "00000000-0000-0000-0000-000000000000", - "provider": "00000001-0000-0001-0000-000000000001" - } -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_3.json b/libs/wire-api/test/golden/testObject_UserProfile_user_3.json deleted file mode 100644 index a521291ff94..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_3.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "accent_id": -1, - "assets": [], - "email": "\u0019\u001b@", - "expires_at": "1864-05-08T21:15:22.178Z", - "handle": "9w41opcty3", - "id": "00000002-0000-0000-0000-000100000001", - "legalhold_status": "no_consent", - "locale": "fj-US", - "name": "𡊥-􌼇B`Fdev9lK'=/㊢J~ZI󹊕^\u0017#\u0013x𦬺Ng\u001fC4􃈌d+\u0008\u001e*\u0010Aj\u000e𬝓ᥙ6􃔫<𡞪嘈#􇍄󺊯ẚ~쾺4􃲥", - "picture": [], - "qualified_id": { - "domain": "jn0602-8rda.0s.484f421.ee7", - "id": "00000002-0000-0000-0000-000100000001" - }, - "service": { - "id": "00000001-0000-0000-0000-000000000001", - "provider": "00000000-0000-0001-0000-000100000000" - }, - "team": "00000000-0000-0002-0000-000200000000" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_4.json b/libs/wire-api/test/golden/testObject_UserProfile_user_4.json deleted file mode 100644 index 2d2d4d0351c..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_4.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "accent_id": -1, - "assets": [], - "deleted": true, - "email": "鴭@", - "expires_at": "1864-05-07T13:58:16.443Z", - "handle": "dauxfkc4f7s4ut0xhxnq9l8zzpeuze998esch51.vh.t56sr1j8bavtco.40te65.sl3b9yzgwxdpxld4_mnoou.adu0lcwxf63lmt8ev8ug7dy39ft31vweb7684k", - "id": "00000002-0000-0000-0000-000100000001", - "legalhold_status": "no_consent", - "locale": "oc-TC", - "name": "~􎚟n􊯨/Xo0/🄙Y݊!뗙|\u001dm3𬂎(󿵸g\u0007㫳f|t>3𩃒60偟􅖂𦸓-𢪀8\r𬕫<􍐆Gvz[\u0017􏪾x\u000b􎔽H6􄱞\u0001\u000c0-0dL󺫖E{5ᜡi󽶭󱔳1\\𡖨\u001a\u000e\u0007fW艵S􍣶\u0014\u0003\u0007u𭫌\u0002E\u0006𑄛𮛊죮⃓④\u001cv\u000c􃉥8E\tb5ꗣ8)\u000eS\u001fiy", - "picture": [], - "qualified_id": { - "domain": "6s4blca8bh.6u.59p4f.j18151", - "id": "00000002-0000-0000-0000-000100000001" - }, - "service": { - "id": "00000000-0000-0000-0000-000100000001", - "provider": "00000001-0000-0001-0000-000100000001" - }, - "team": "00000000-0000-0000-0000-000200000002" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_5.json b/libs/wire-api/test/golden/testObject_UserProfile_user_5.json deleted file mode 100644 index aa396ea4aef..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_5.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "accent_id": -2, - "assets": [], - "email": "/\u000b@𫊬", - "expires_at": "1864-05-07T03:37:18.107Z", - "handle": "2k1t1hdfpvdkxij-0w735w5xniggherg.c8d_be21d3mrasu9bkz38dmbwhca3neuduc0oz8v3n1-bd81z6ocf5d1i", - "id": "00000000-0000-0002-0000-000100000001", - "legalhold_status": "no_consent", - "locale": "pt-ES", - "name": "q0\u001fe𣽁\u0014e78h\u0011!E#}A\u001d𫘜b,조􆥤𫺥2\u0016P􆢑𨩢󶡠,(\u0013O0𖽊竌\nGXJ", - "picture": [], - "qualified_id": { - "domain": "awdt-0be-r.7hyxl8mkb.s.lp", - "id": "00000000-0000-0002-0000-000100000001" - }, - "team": "00000001-0000-0001-0000-000000000000" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_6.json b/libs/wire-api/test/golden/testObject_UserProfile_user_6.json deleted file mode 100644 index e6a656400b4..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_6.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "accent_id": 0, - "assets": [ - { - "key": "", - "size": "preview", - "type": "image" - }, - { - "key": "", - "size": "preview", - "type": "image" - } - ], - "email": "l@𒓧", - "expires_at": "1864-05-11T16:24:39.844Z", - "handle": "frz05jdtt5.dacr3hd-hmayzm93q91g-qbd-4rm2hs2de4jx.80xj9y6k.c70.s_s_85ymq0w.lv_", - "id": "00000000-0000-0000-0000-000000000002", - "legalhold_status": "no_consent", - "name": "L\"v\u001ck 2d$\u001fQm|𠿯r􀇄􁼚𡹲󹶢-󶆢\u0014+dC/n.\r\u001fAX\u001as$B\u0011绊G菸pTC𦽇Lgs\u0019秠,vz󹬔峄tYvC\u0013rA0{𘤳e!𮌔𠾷'r&X9k4Z𗿍\u0012YW*𫍮Wh#𪆿_􇶤􁤲r\u0015(􋏦𡱪􊉇\u001chF\u001bn^𭧷=!\u0002󵿎]`􃢒􎀣\u001c\u0017=9D.x$\u001bU/\u0002FJ", - "picture": [], - "qualified_id": { - "domain": "87k.iag53", - "id": "00000000-0000-0000-0000-000000000002" - } -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_7.json b/libs/wire-api/test/golden/testObject_UserProfile_user_7.json deleted file mode 100644 index 1ea0b1ecd20..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_7.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "accent_id": 1, - "assets": [], - "deleted": true, - "email": "@", - "expires_at": "1864-05-07T08:32:43.292Z", - "handle": "67-9yy9qo2p25zhd58xripmrgouiuww98mk.m5xfnlvqmpz8wsgjuo7eo149d_0is6w26-2zo4z1kbf6zmkth4n3j139iok0s80ccdfxcb-jy3edziep9hpb2r.glfme2q09t..ehpdjc57dv-9_8nt0f", - "id": "00000001-0000-0000-0000-000200000000", - "legalhold_status": "no_consent", - "name": "0\\xꃪ󺟎\u001e\u0010ꄬ𫒪󱘾n󺒎𝔞(w祟J𦢣\u0018~W|#!􍀃𛄐􁕠\u001d􀰿7\u001a􎇢/􌰚𣼗6󵻭𮤬]\u000e\u0005IRy𭦘/H𡶉)𨨗󸮇jEO\u0011d`]A\u001d\"\u001f𡙐􎞑Irh;M󼑖兢LzCἩN_\u0012󳶳-q1z0嫭𡡞ꛖ);𪣽z\u001a5􌝖ZN􏨆\u000e5\u0016 햭", - "picture": [], - "qualified_id": { - "domain": "uy-m.eb-p-ehu.n.t5p-i84u", - "id": "00000001-0000-0000-0000-000200000000" - }, - "service": { - "id": "00000001-0000-0000-0000-000100000000", - "provider": "00000001-0000-0001-0000-000000000001" - }, - "team": "00000001-0000-0001-0000-000100000000" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_8.json b/libs/wire-api/test/golden/testObject_UserProfile_user_8.json deleted file mode 100644 index aaf350585fb..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_8.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "accent_id": 1, - "assets": [], - "deleted": true, - "email": "󰒭@\u0013F", - "expires_at": "1864-05-10T15:50:41.047Z", - "handle": "dbiy", - "id": "00000001-0000-0001-0000-000100000002", - "legalhold_status": "no_consent", - "name": ". 䚣󻹅󲍼\\􅠋\u0002'\u000fV􈭘􊚅)󰊺\u0000􂣇[EO𬅿M\u0012A𪳧󷩱O&\r􉋱𩷚", - "picture": [], - "qualified_id": { - "domain": "755m8o7.5-6tg.x48tvxc", - "id": "00000001-0000-0001-0000-000100000002" - }, - "service": { - "id": "00000000-0000-0001-0000-000000000000", - "provider": "00000000-0000-0000-0000-000000000000" - }, - "team": "00000000-0000-0002-0000-000000000002" -} diff --git a/libs/wire-api/test/golden/testObject_UserProfile_user_9.json b/libs/wire-api/test/golden/testObject_UserProfile_user_9.json deleted file mode 100644 index c6c5d84cd15..00000000000 --- a/libs/wire-api/test/golden/testObject_UserProfile_user_9.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "accent_id": -1, - "assets": [], - "deleted": true, - "email": "_@U\u0002", - "expires_at": "1864-05-07T20:54:55.730Z", - "handle": "72nnsdja3n", - "id": "00000001-0000-0000-0000-000000000000", - "legalhold_status": "no_consent", - "locale": "sv-WF", - "name": "Xa\u0001tP\"𧚇)媥\u0012蔶y\\]E\u000b\\G", - "picture": [], - "qualified_id": { - "domain": "p.6u0.jym", - "id": "00000001-0000-0000-0000-000000000000" - }, - "service": { - "id": "00000001-0000-0000-0000-000000000001", - "provider": "00000001-0000-0001-0000-000000000001" - }, - "team": "00000000-0000-0001-0000-000200000000" -} diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/FromJSON.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/FromJSON.hs index 8f6ceae80aa..d69d1b9cddf 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/FromJSON.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/FromJSON.hs @@ -27,6 +27,7 @@ import Test.Wire.API.Golden.Generated.RmClient_user import Test.Wire.API.Golden.Generated.SimpleMember_user import Test.Wire.API.Golden.Runner import Wire.API.Conversation (Conversation, MemberUpdate, NewConvManaged, NewConvUnmanaged, OtherMemberUpdate) +import Wire.API.User (NewUser, NewUserPublic) import Wire.API.User.Client (RmClient) tests :: TestTree @@ -73,10 +74,46 @@ tests = testCase "MemberUpdate" $ testFromJSONFailureWithMsg @MemberUpdate ( Just $ - "One of { \'otr_muted', 'otr_muted_ref', 'otr_archived', " - <> "'otr_archived_ref', 'hidden', 'hidden_ref', 'conversation_role'} required." + "One of { 'otr_muted_ref', 'otr_archived', 'otr_archived_ref', \ + \'hidden', 'hidden_ref', 'conversation_role'} required." ) "testObject_MemberUpdate_user_3.json", testCase "OtherMemberUpdate" $ - testFromJSONFailure @OtherMemberUpdate "testObject_OtherMemberUpdate_user_2.json" + testFromJSONFailure @OtherMemberUpdate "testObject_OtherMemberUpdate_user_2.json", + testGroup "NewUser: failure" $ + [ testCase "testObject_NewUser_user_3-2.json" $ + testFromJSONFailureWithMsg @NewUser + (Just "Only users without an identity can expire") + "testObject_NewUser_user_3-2.json", + testCase "testObject_NewUser_user_5-2.json" $ + testFromJSONFailureWithMsg @NewUser + (Just "all team users must set a password on creation") + "testObject_NewUser_user_5-2.json", + testCase "testObject_NewUser_user_6-2.json" $ + testFromJSONFailureWithMsg @NewUser + (Just "sso_id, team_id must be either both present or both absent.") + "testObject_NewUser_user_6-2.json", + testCase "testObject_NewUser_user_6-3.json" $ + testFromJSONFailureWithMsg @NewUser + (Just "sso_id, team_id must be either both present or both absent.") + "testObject_NewUser_user_6-3.json", + testCase "testObject_NewUser_user_6-4.json" $ + testFromJSONFailureWithMsg @NewUser + (Just "team_code, team, invitation_code, sso_id, and the pair (sso_id, team_id) are mutually exclusive") + "testObject_NewUser_user_6-4.json" + ], + testGroup "NewUserPublic: failure" $ + [ testCase "testObject_NewUserPublic_user_1-1.json" $ + testFromJSONFailureWithMsg @NewUserPublic + (Just "SSO-managed users are not allowed here.") + "testObject_NewUserPublic_user_1-1.json", + testCase "testObject_NewUserPublic_user_1-2.json" $ + testFromJSONFailureWithMsg @NewUserPublic + (Just "it is not allowed to provide a UUID for the users here.") + "testObject_NewUserPublic_user_1-2.json", + testCase "testObject_NewUserPublic_user_1-3.json" $ + testFromJSONFailureWithMsg @NewUserPublic + (Just "only managed-by-Wire users can be created here.") + "testObject_NewUserPublic_user_1-3.json" + ] ] diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated.hs index b29c11dedd7..2e4a15579af 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated.hs @@ -96,7 +96,7 @@ import qualified Test.Wire.API.Golden.Generated.Invite_user import qualified Test.Wire.API.Golden.Generated.LastPrekey_user import qualified Test.Wire.API.Golden.Generated.LegalHoldServiceConfirm_team import qualified Test.Wire.API.Golden.Generated.LegalHoldServiceRemove_team -import qualified Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user +import qualified Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_user import qualified Test.Wire.API.Golden.Generated.ListType_team import qualified Test.Wire.API.Golden.Generated.LocaleUpdate_user import qualified Test.Wire.API.Golden.Generated.Locale_user @@ -108,7 +108,6 @@ import qualified Test.Wire.API.Golden.Generated.ManagedBy_user import qualified Test.Wire.API.Golden.Generated.MemberUpdateData_user import qualified Test.Wire.API.Golden.Generated.MemberUpdate_user import qualified Test.Wire.API.Golden.Generated.Member_user -import qualified Test.Wire.API.Golden.Generated.Message_user import qualified Test.Wire.API.Golden.Generated.MutedStatus_user import qualified Test.Wire.API.Golden.Generated.NameUpdate_user import qualified Test.Wire.API.Golden.Generated.Name_user @@ -388,10 +387,7 @@ tests = testCase "Golden: ConnectionRequest_user" $ testObjects [ (Test.Wire.API.Golden.Generated.ConnectionRequest_user.testObject_ConnectionRequest_user_1, "testObject_ConnectionRequest_user_1.json"), - (Test.Wire.API.Golden.Generated.ConnectionRequest_user.testObject_ConnectionRequest_user_2, "testObject_ConnectionRequest_user_2.json"), - (Test.Wire.API.Golden.Generated.ConnectionRequest_user.testObject_ConnectionRequest_user_3, "testObject_ConnectionRequest_user_3.json"), - (Test.Wire.API.Golden.Generated.ConnectionRequest_user.testObject_ConnectionRequest_user_4, "testObject_ConnectionRequest_user_4.json"), - (Test.Wire.API.Golden.Generated.ConnectionRequest_user.testObject_ConnectionRequest_user_8, "testObject_ConnectionRequest_user_8.json") + (Test.Wire.API.Golden.Generated.ConnectionRequest_user.testObject_ConnectionRequest_user_2, "testObject_ConnectionRequest_user_2.json") ], testCase "Golden: Relation_user" $ testObjects @@ -403,18 +399,10 @@ tests = (Test.Wire.API.Golden.Generated.Relation_user.testObject_Relation_user_6, "testObject_Relation_user_6.json"), (Test.Wire.API.Golden.Generated.Relation_user.testObject_Relation_user_7, "testObject_Relation_user_7.json") ], - testCase "Golden: Message_user" $ - testObjects - [ (Test.Wire.API.Golden.Generated.Message_user.testObject_Message_user_1, "testObject_Message_user_1.json"), - (Test.Wire.API.Golden.Generated.Message_user.testObject_Message_user_2, "testObject_Message_user_2.json"), - (Test.Wire.API.Golden.Generated.Message_user.testObject_Message_user_3, "testObject_Message_user_3.json") - ], testCase "Golden: UserConnection_user" $ testObjects [ (Test.Wire.API.Golden.Generated.UserConnection_user.testObject_UserConnection_user_1, "testObject_UserConnection_user_1.json"), - (Test.Wire.API.Golden.Generated.UserConnection_user.testObject_UserConnection_user_2, "testObject_UserConnection_user_2.json"), - (Test.Wire.API.Golden.Generated.UserConnection_user.testObject_UserConnection_user_3, "testObject_UserConnection_user_3.json"), - (Test.Wire.API.Golden.Generated.UserConnection_user.testObject_UserConnection_user_4, "testObject_UserConnection_user_4.json") + (Test.Wire.API.Golden.Generated.UserConnection_user.testObject_UserConnection_user_2, "testObject_UserConnection_user_2.json") ], testCase "Golden: UserConnectionList_user" $ testObjects @@ -856,15 +844,71 @@ tests = ) ], testCase "Golden: NameUpdate_user" $ - testObjects [(Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_1, "testObject_NameUpdate_user_1.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_2, "testObject_NameUpdate_user_2.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_3, "testObject_NameUpdate_user_3.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_4, "testObject_NameUpdate_user_4.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_5, "testObject_NameUpdate_user_5.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_6, "testObject_NameUpdate_user_6.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_7, "testObject_NameUpdate_user_7.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_8, "testObject_NameUpdate_user_8.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_9, "testObject_NameUpdate_user_9.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_10, "testObject_NameUpdate_user_10.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_11, "testObject_NameUpdate_user_11.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_12, "testObject_NameUpdate_user_12.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_13, "testObject_NameUpdate_user_13.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_14, "testObject_NameUpdate_user_14.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_15, "testObject_NameUpdate_user_15.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_16, "testObject_NameUpdate_user_16.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_17, "testObject_NameUpdate_user_17.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_18, "testObject_NameUpdate_user_18.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_19, "testObject_NameUpdate_user_19.json"), (Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_20, "testObject_NameUpdate_user_20.json")], + testObjects + [ ( Test.Wire.API.Golden.Generated.NameUpdate_user.testObject_NameUpdate_user_1, + "testObject_NameUpdate_user_1.json" + ) + ], testCase "Golden: NewUser_user" $ - testObjects [(Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_1, "testObject_NewUser_user_1.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_2, "testObject_NewUser_user_2.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_3, "testObject_NewUser_user_3.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_4, "testObject_NewUser_user_4.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_5, "testObject_NewUser_user_5.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_6, "testObject_NewUser_user_6.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_7, "testObject_NewUser_user_7.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_8, "testObject_NewUser_user_8.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_9, "testObject_NewUser_user_9.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_10, "testObject_NewUser_user_10.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_11, "testObject_NewUser_user_11.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_12, "testObject_NewUser_user_12.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_13, "testObject_NewUser_user_13.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_14, "testObject_NewUser_user_14.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_15, "testObject_NewUser_user_15.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_16, "testObject_NewUser_user_16.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_17, "testObject_NewUser_user_17.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_18, "testObject_NewUser_user_18.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_19, "testObject_NewUser_user_19.json"), (Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_20, "testObject_NewUser_user_20.json")], + testObjects + [ ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_1, + "testObject_NewUser_user_1.json" + ), + ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_2, + "testObject_NewUser_user_2.json" + ), + ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_3, + "testObject_NewUser_user_3.json" + ), + ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_4, + "testObject_NewUser_user_4.json" + ), + ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_5, + "testObject_NewUser_user_5.json" + ), + ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_6, + "testObject_NewUser_user_6.json" + ), + ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_7, + "testObject_NewUser_user_7.json" + ), + ( Test.Wire.API.Golden.Generated.NewUser_user.testObject_NewUser_user_8, + "testObject_NewUser_user_8.json" + ) + ], testCase "Golden: NewUserPublic_user" $ - testObjects [(Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_1, "testObject_NewUserPublic_user_1.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_2, "testObject_NewUserPublic_user_2.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_3, "testObject_NewUserPublic_user_3.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_4, "testObject_NewUserPublic_user_4.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_5, "testObject_NewUserPublic_user_5.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_6, "testObject_NewUserPublic_user_6.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_7, "testObject_NewUserPublic_user_7.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_8, "testObject_NewUserPublic_user_8.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_9, "testObject_NewUserPublic_user_9.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_10, "testObject_NewUserPublic_user_10.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_11, "testObject_NewUserPublic_user_11.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_12, "testObject_NewUserPublic_user_12.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_13, "testObject_NewUserPublic_user_13.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_14, "testObject_NewUserPublic_user_14.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_15, "testObject_NewUserPublic_user_15.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_16, "testObject_NewUserPublic_user_16.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_17, "testObject_NewUserPublic_user_17.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_18, "testObject_NewUserPublic_user_18.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_19, "testObject_NewUserPublic_user_19.json"), (Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_20, "testObject_NewUserPublic_user_20.json")], - testCase "Golden: LimitedQualifiedUserIdList_2020_user" $ - testObjects [(Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_1, "testObject_LimitedQualifiedUserIdList_2020_user_1.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_2, "testObject_LimitedQualifiedUserIdList_2020_user_2.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_3, "testObject_LimitedQualifiedUserIdList_2020_user_3.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_4, "testObject_LimitedQualifiedUserIdList_2020_user_4.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_5, "testObject_LimitedQualifiedUserIdList_2020_user_5.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_6, "testObject_LimitedQualifiedUserIdList_2020_user_6.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_7, "testObject_LimitedQualifiedUserIdList_2020_user_7.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_8, "testObject_LimitedQualifiedUserIdList_2020_user_8.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_9, "testObject_LimitedQualifiedUserIdList_2020_user_9.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_10, "testObject_LimitedQualifiedUserIdList_2020_user_10.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_11, "testObject_LimitedQualifiedUserIdList_2020_user_11.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_12, "testObject_LimitedQualifiedUserIdList_2020_user_12.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_13, "testObject_LimitedQualifiedUserIdList_2020_user_13.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_14, "testObject_LimitedQualifiedUserIdList_2020_user_14.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_15, "testObject_LimitedQualifiedUserIdList_2020_user_15.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_16, "testObject_LimitedQualifiedUserIdList_2020_user_16.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_17, "testObject_LimitedQualifiedUserIdList_2020_user_17.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_18, "testObject_LimitedQualifiedUserIdList_2020_user_18.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_19, "testObject_LimitedQualifiedUserIdList_2020_user_19.json"), (Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user.testObject_LimitedQualifiedUserIdList_2020_user_20, "testObject_LimitedQualifiedUserIdList_2020_user_20.json")], + testObjects + [ ( Test.Wire.API.Golden.Generated.NewUserPublic_user.testObject_NewUserPublic_user_1, + "testObject_NewUserPublic_user_1.json" + ) + ], + testCase "Golden: LimitedQualifiedUserIdList_user_1" $ + testObjects + [ ( Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_user.testObject_LimitedQualifiedUserIdList_user_1, + "testObject_LimitedQualifiedUserIdList_user_1.json" + ) + ], + testCase "Golden: LimitedQualifiedUserIdList_user_2" $ + testObjects + [ ( Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_user.testObject_LimitedQualifiedUserIdList_user_2, + "testObject_LimitedQualifiedUserIdList_user_2.json" + ) + ], + testCase "Golden: LimitedQualifiedUserIdList_user_3" $ + testObjects + [ ( Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_user.testObject_LimitedQualifiedUserIdList_user_3, + "testObject_LimitedQualifiedUserIdList_user_3.json" + ) + ], testCase "Golden: UserProfile_user" $ - testObjects [(Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_1, "testObject_UserProfile_user_1.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_2, "testObject_UserProfile_user_2.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_3, "testObject_UserProfile_user_3.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_4, "testObject_UserProfile_user_4.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_5, "testObject_UserProfile_user_5.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_6, "testObject_UserProfile_user_6.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_7, "testObject_UserProfile_user_7.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_8, "testObject_UserProfile_user_8.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_9, "testObject_UserProfile_user_9.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_10, "testObject_UserProfile_user_10.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_11, "testObject_UserProfile_user_11.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_12, "testObject_UserProfile_user_12.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_13, "testObject_UserProfile_user_13.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_14, "testObject_UserProfile_user_14.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_15, "testObject_UserProfile_user_15.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_16, "testObject_UserProfile_user_16.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_17, "testObject_UserProfile_user_17.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_18, "testObject_UserProfile_user_18.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_19, "testObject_UserProfile_user_19.json"), (Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_20, "testObject_UserProfile_user_20.json")], + testObjects + [ ( Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_1, + "testObject_UserProfile_user_1.json" + ), + ( Test.Wire.API.Golden.Generated.UserProfile_user.testObject_UserProfile_user_2, + "testObject_UserProfile_user_2.json" + ) + ], testCase "Golden: User_user" $ testObjects [(Test.Wire.API.Golden.Generated.User_user.testObject_User_user_1, "testObject_User_user_1.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_2, "testObject_User_user_2.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_3, "testObject_User_user_3.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_4, "testObject_User_user_4.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_5, "testObject_User_user_5.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_6, "testObject_User_user_6.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_7, "testObject_User_user_7.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_8, "testObject_User_user_8.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_9, "testObject_User_user_9.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_10, "testObject_User_user_10.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_11, "testObject_User_user_11.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_12, "testObject_User_user_12.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_13, "testObject_User_user_13.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_14, "testObject_User_user_14.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_15, "testObject_User_user_15.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_16, "testObject_User_user_16.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_17, "testObject_User_user_17.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_18, "testObject_User_user_18.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_19, "testObject_User_user_19.json"), (Test.Wire.API.Golden.Generated.User_user.testObject_User_user_20, "testObject_User_user_20.json")], testCase "Golden: SelfProfile_user" $ diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConnectionRequest_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConnectionRequest_user.hs index 5958a0f8c9b..c5545cce923 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConnectionRequest_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConnectionRequest_user.hs @@ -17,66 +17,23 @@ module Test.Wire.API.Golden.Generated.ConnectionRequest_user where import Data.Id (Id (Id)) +import Data.Range import qualified Data.UUID as UUID (fromString) import Imports (fromJust) -import Wire.API.Connection (ConnectionRequest (..), Message (Message, messageText)) +import Wire.API.Connection (ConnectionRequest (..)) testObject_ConnectionRequest_user_1 :: ConnectionRequest testObject_ConnectionRequest_user_1 = ConnectionRequest { crUser = Id (fromJust (UUID.fromString "00005686-0000-796a-0000-712b00006414")), crName = - "$Sz%e\27856\&9\28268NfG a\SUB\1104240\22763\NULkF\SOq\99222W\DC4K\DLE\EOTF1e\v\EOTQ1D\1011215\169864R\983712\b\DLEQNvP!i\1045156A\63817\DC1f\63319E\1055845\96023\1087467+g~r%'J\990559s\DC39/'\1032622\993992\78178w\GS\ACK\12632\1079109<(o\1051052", - crMessage = - Message - { messageText = - "X[l\GS}\NULc\143898@\EOTb,{\STXDSZ7\n\DC3\"V\995785Wox\57773\119589*\7624q4IO\US\v]YJ\EOT!\1105112\1062593\29817\SUB:\1044767*b\SUB+4nByz7uF\62747\ETX\49479\1051162$\167226\1092608<;9\NAK*\DC2&\r'*(^>C\1068326LxZ\47468\ESC\991727\166521zM\SYN\145383s\1068585i\8999\v\165841\1081644\adO\f\NAKl" - } + unsafeRange + "$Sz%e\27856\&9\28268NfG a\SUB\1104240\22763\NULkF\SOq\99222W\DC4K\DLE\EOTF1e\v\EOTQ1D\1011215\169864R\983712\b\DLEQNvP!i\1045156A\63817\DC1f\63319E\1055845\96023\1087467+g~r%'J\990559s\DC39/'\1032622\993992\78178w\GS\ACK\12632\1079109<(o\1051052" } testObject_ConnectionRequest_user_2 :: ConnectionRequest testObject_ConnectionRequest_user_2 = ConnectionRequest - { crUser = Id (fromJust (UUID.fromString "00003697-0000-346d-0000-6baf00003034")), - crName = "\22415\1044771a\166586\SI$\ESC2&\DC2S<\DC1\1090585o\997147\70692U", - crMessage = - Message - { messageText = - "}k\991892\NUL\67258\DC3\144475T.kjW@\992917c\12623\1110194n\120624\&0\SOHpH,?^+\1012340\&8\STX\150942b\tF\66190n\ETX!![\v\1025071\&3\998476\STX\118837\NAK\1007154\1069547I\1052352La\167096.\30853\1006638\&33a\DC1H\1025270X\138279\146902pSyL2\"y\\8\41908\1044744@!F\FSQ\f\1062715\159511\SO\988719[!\60553\SO\40618\ACK=uH\1003276\16040\ETX\1028835\985694B2\1064909\72771\NULyy\141172\f\"\1100386\37963!\140543\ETB\1028831K \33319Z\1061132\&5.m\983153n\FS\GSs\38930JXo[8\1018361\1061145%\SOH}I|>\b4aG4\1103692\1108531(U\1078285\1089495e4q\EOT\62925\ACK\DLE\"\183958Q*u|\1089086T}bT\ft\DC2U\42798_Y\ETX\1052470v\96709\1078214'\992836\61708.%\1046535v8\ESC;\vl>\128395s\1058891\1067016f\"\STX\ETX\149005" - } - } - -testObject_ConnectionRequest_user_3 :: ConnectionRequest -testObject_ConnectionRequest_user_3 = - ConnectionRequest - { crUser = Id (fromJust (UUID.fromString "0000302a-0000-1612-0000-459400001b2a")), - crName = - "e\FSx\33154IBV 5\1107015hWeYpU\1063136(\n\46398\tn\164922\994685\149253\999956\aMNk 3V\f~\187305XltD'\CAN\149622\1082776g\NAKL3S\CAN\143538\1084558\29034\33703Y\ENQ\1035414T\988547I\175375E [\t\1099620!\1083340\DC4\DC1\1078602\8426jn'(cw\STX\DC3\1041716\n\DLET%\CAN\169172`\1041948\15880\58820|iGOZ\SOHR8FC\b7\40700\GSN*dT#\185689\\<\DLE?\144579%\tZC+Ht\3064;\SI\1064341(\147456H\158474=P\SO\160381\ESCuO*\\QM\f{r)~E\v!k\1105195W}1\ETB[\159713a\1046543\&7/LM9\174953\38557pk\SOH>m\1060065\&1z\1087338\\\66012\149111\FS5\1082403\97471\&0\a\t\994669a\SUB\1001725`XY\GS^\66729!\4184\ESC\45288Z\48957\US\SUB[R>\SUB*\DC2=X\1000477/UE\SYN\1070679\165502>\1089933>\NAK\",\DC4", - crMessage = Message {messageText = "\1085988\992933\STX\DC2\SUBj\171033X\RSz[r\DLE\44803L]zl\145794\NAK"} - } - -testObject_ConnectionRequest_user_4 :: ConnectionRequest -testObject_ConnectionRequest_user_4 = - ConnectionRequest - { crUser = Id (fromJust (UUID.fromString "00005bd6-0000-77a4-0000-2a3600001251")), - crName = - ".#Y\1028598\EOTD|<.\9581\a@v\1022767Nn\1058280k\1031857f=M\NUL\49215\24440Pd\CAN&s\1046128\1074702b\ESC\996772G}\1046407\NAKiE\f\n|\DC3\t\1073406\GS\39427\STXR&>\8734\n\ENQ\1096231\&8$\993594G\b\RSYA8.\DEL}!k*\1098560\183150X\59315\994452^\99557\177310\996299Z\1104748\&7X\STX\1007267\"=&Sr^o\1078473`\40748/\n'\78719\&8f\n\135538{", - crMessage = - Message - { messageText = - "bJiQ\1102608m_\DC3!\vD\14916>\20140'e\5676]1i\13211\SIiy\144899\t\128444)\1108183\SUBD|_\24899\nDP\DC1>\166000<\1005270\DC3\DC1\SUB0:Z1V\NAK\DLEj\1001600r\128828\172858\134986DgC&3\9513\&0~\1020187S\CANz:L\ESC]\1037242%xM\999887\5744\EM!64%\65366\ESCsj\DC4Io3$\36886SH:N4\186376Do\63628\17118;|u\36322u{&\1063122\984114\DC4vX\999378g\"O\1095174%\1056235\5411\30413\1091183(\SO\ETB\DC4-^F\DLE\DC3n\175983\120372\SOHwhiU\1005913l\n\1060742s\1036379\DLE \1065036\1059995\nu$*P\1051786R5w`\176240U\144059_5\154318G\ETB\f~d\DLE4" - } - } - -testObject_ConnectionRequest_user_8 :: ConnectionRequest -testObject_ConnectionRequest_user_8 = - ConnectionRequest - { crUser = Id (fromJust (UUID.fromString "00001ab1-0000-6eb7-0000-71e900007867")), - crName = - "\1027921;\146849W\33697%vJ\DC1\39350/#\r\1006557mUO\131673\&5\SOH\200\11101\140328u\b\ACKK4\DC1\EOT`%)3\EM\SYN\DLE\DELuUqQP-\b\NAK\9555\ETB\GS*,1\ETXj\999600h\171884:\12799\157760t\a\fH\1093754\v\19852TDxd\DC3\NUL<\128197\162600M7\DC1|C\ttLD\1090636\1086481[\az\1062634y\151830\DEL\52921V8\1039556\985050rRD \STX\165530\1111646F\DLEG\US{%;\vuaJ\"\DLE!=D\47905\ESC;~w>\SUB_\CAN'\121206]~\1059419\&0\SI\1041317\"\SYN'>\SI4\NAK\15228\ETB[e\DELFL\SO%W$\166547_\1063454\59649]\DC35*>$u\143749\SOH\1009357\GS\1020051\DC34\b\v", - crMessage = - Message - { messageText = - "u\96310:@o\ENQW&\EOT_\US{\95721L\1041277E\STX\19049&\DLE\EOT\1018164\DEL\DC1[\aKU_\tC\50779G8$do\2825\1007169ZU6\NUL\RST{4;mq\983244\62749\1028056\SUB\74313\DC2\b\1051996|fs7\1091735\DC4\CAN\8650>^,K1l\EOT{t\1042368\170635W\STX5\124976r\DELS\DC1i\GS\a\EOTK6\157012f69lZdw\f\n\DC3T\120941#j\RSy\155238\&7\994408un\185455\1083057xa#5\63326D\\\DC14\DC1\190559\1051573?\a0>Z\163411v\v" - } + { crUser = (Id (fromJust (UUID.fromString "00003697-0000-346d-0000-6baf00003034"))), + crName = unsafeRange "\22415\1044771a\166586\SI$\ESC2&\DC2S<\DC1\1090585o\997147\70692U" } diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConvMembers_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConvMembers_user.hs index 80beffda1cb..c0e49460faa 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConvMembers_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConvMembers_user.hs @@ -33,7 +33,6 @@ import Wire.API.Conversation memId, memOtrArchived, memOtrArchivedRef, - memOtrMuted, memOtrMutedRef, memOtrMutedStatus, memService @@ -59,7 +58,6 @@ testObject_ConvMembers_user_1 = _serviceRefProvider = Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000")) } ), - memOtrMuted = True, memOtrMutedStatus = Nothing, memOtrMutedRef = Just "", memOtrArchived = True, @@ -102,7 +100,6 @@ testObject_ConvMembers_user_2 = _serviceRefProvider = Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000000000001")) } ), - memOtrMuted = False, memOtrMutedStatus = Nothing, memOtrMutedRef = Just "", memOtrArchived = False, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConversationList_20Conversation_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConversationList_20Conversation_user.hs index 2f96bf6ceac..02ab9eb3ba3 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConversationList_20Conversation_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/ConversationList_20Conversation_user.hs @@ -40,7 +40,6 @@ import Wire.API.Conversation memId, memOtrArchived, memOtrArchivedRef, - memOtrMuted, memOtrMutedRef, memOtrMutedStatus, memService @@ -67,7 +66,6 @@ testObject_ConversationList_20Conversation_user_1 = Member { memId = Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000000")), memService = Nothing, - memOtrMuted = True, memOtrMutedStatus = Just (MutedStatus {fromMutedStatus = 0}), memOtrMutedRef = Just "", memOtrArchived = True, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Conversation_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Conversation_user.hs index d84ec11f810..c59d97a208d 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Conversation_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Conversation_user.hs @@ -46,7 +46,6 @@ testObject_Conversation_user_1 = Member { memId = Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000000")), memService = Nothing, - memOtrMuted = True, memOtrMutedStatus = Nothing, memOtrMutedRef = Nothing, memOtrArchived = False, @@ -90,7 +89,6 @@ testObject_Conversation_user_2 = Member { memId = Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000001")), memService = Nothing, - memOtrMuted = True, memOtrMutedStatus = Just (MutedStatus {fromMutedStatus = -1}), memOtrMutedRef = Nothing, memOtrArchived = False, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Event_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Event_user.hs index 9fac68288e5..ae6cb47adb0 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Event_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Event_user.hs @@ -58,7 +58,6 @@ import Wire.API.Event.Conversation misHiddenRef, misOtrArchived, misOtrArchivedRef, - misOtrMuted, misOtrMutedRef, misOtrMutedStatus, misTarget @@ -139,7 +138,6 @@ testObject_Event_user_5 = ( EdMemberUpdate ( MemberUpdateData { misTarget = Nothing, - misOtrMuted = Just False, misOtrMutedStatus = Nothing, misOtrMutedRef = Just "\94957", misOtrArchived = Just False, @@ -203,7 +201,6 @@ testObject_Event_user_8 = Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000001")) } ), - memOtrMuted = False, memOtrMutedStatus = Just (MutedStatus {fromMutedStatus = 0}), memOtrMutedRef = Just "", memOtrArchived = True, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/LimitedQualifiedUserIdList_2020_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/LimitedQualifiedUserIdList_2020_user.hs deleted file mode 100644 index a2ff37d9c5c..00000000000 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/LimitedQualifiedUserIdList_2020_user.hs +++ /dev/null @@ -1,1323 +0,0 @@ -{-# LANGUAGE OverloadedLists #-} - --- This file is part of the Wire Server implementation. --- --- Copyright (C) 2021 Wire Swiss GmbH --- --- This program is free software: you can redistribute it and/or modify it under --- the terms of the GNU Affero General Public License as published by the Free --- Software Foundation, either version 3 of the License, or (at your option) any --- later version. --- --- This program is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS --- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more --- details. --- --- You should have received a copy of the GNU Affero General Public License along --- with this program. If not, see . -module Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user where - -import Data.Domain (Domain (Domain, _domainText)) -import Data.Id (Id (Id)) -import Data.Qualified (Qualified (Qualified, qDomain, qUnqualified)) -import Data.Range (unsafeRange) -import qualified Data.UUID as UUID (fromString) -import Imports (fromJust) -import Wire.API.User (LimitedQualifiedUserIdList (..)) - -testObject_LimitedQualifiedUserIdList_2020_user_1 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_1 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005bed-0000-0771-0000-447a00005b32"))), - qDomain = Domain {_domainText = "sh7636.gcg-c"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005953-0000-2b40-0000-567100002d0c"))), - qDomain = Domain {_domainText = "dw14y-97764r.26en.wa9"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000012f7-0000-581b-0000-377600006eb9"))), - qDomain = Domain {_domainText = "6e-4.ic.paf"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000c1b-0000-59c0-0000-3ff000001533"))), - qDomain = Domain {_domainText = "wsy0vskgzy.7zb.u-g-p-58"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002419-0000-37e8-0000-329900001118"))), - qDomain = Domain {_domainText = "ug.mph1359u6sttb3w28v-968"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006112-0000-1fd0-0000-5ca500001e6f"))), - qDomain = Domain {_domainText = "hgrc.1y.kyvg3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005052-0000-09ec-0000-74d50000574e"))), - qDomain = Domain {_domainText = "p.q0h.b"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003e30-0000-3f72-0000-23ec000019a0"))), - qDomain = Domain {_domainText = "r376-462.74o6.0zo-z.9w50a2f9jn9.7rto1q7r.t-99"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003ae9-0000-4d95-0000-08f30000606b"))), - qDomain = Domain {_domainText = "dt-1.76n6.5-1.n.6-ax81lr5.k13tld-9.k.a0-bd-c.s-jt"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005051-0000-6a16-0000-6a3c00007a41"))), - qDomain = Domain {_domainText = "njz-3741-78-2--36.e0"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000068c0-0000-2fb4-0000-2891000020d3"))), - qDomain = Domain {_domainText = "t335k19.mpv.i31k9.pnks6s"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000055b6-0000-236b-0000-52cb00002561"))), - qDomain = Domain {_domainText = "8-9.z3--ga"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007189-0000-04f6-0000-318500001872"))), - qDomain = Domain {_domainText = "ey4.09g.0wqpp01091.i-y.6pufi5-8vp2g8.lg.ad9p2"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_2 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_2 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000016a5-0000-000e-0000-2ad50000589c"))), - qDomain = Domain {_domainText = "t02vm1.gm810xwh1l4rb"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004bd5-0000-363b-0000-1af6000051cf"))), - qDomain = Domain {_domainText = "620au-6.2j.x23-5w"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006375-0000-417b-0000-3da900004015"))), - qDomain = Domain {_domainText = "809.b9m0"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000075be-0000-770a-0000-471d00005410"))), - qDomain = Domain {_domainText = "4bc1.k7-z"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002999-0000-35d4-0000-413300001831"))), - qDomain = Domain {_domainText = "010.2bu3-2hu.s164s1-2f"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000016d9-0000-5086-0000-65cb00000e53"))), - qDomain = Domain {_domainText = "z8.q.l"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006c57-0000-16c2-0000-5eb200001985"))), - qDomain = Domain {_domainText = "g-40a.pa2-4"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005572-0000-1ad1-0000-75d700000dc8"))), - qDomain = Domain {_domainText = "0e-1-5-9.h085rwr815"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007231-0000-30dc-0000-692e00006a70"))), - qDomain = Domain {_domainText = "8cp.0.b5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000458d-0000-373c-0000-2799000037cd"))), - qDomain = Domain {_domainText = "0.s-16"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004a0c-0000-185d-0000-472d00002ef4"))), - qDomain = Domain {_domainText = "9mk.mbz.75307.e9vg.n1.m7kv"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000069d1-0000-3674-0000-31db0000330b"))), - qDomain = Domain {_domainText = "u86.7z-v0.q8-78"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007645-0000-015b-0000-41470000445d"))), - qDomain = Domain {_domainText = "22.r-r8k86"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000c73-0000-44b8-0000-5712000045fc"))), - qDomain = Domain {_domainText = "1-fx97tg2.j7"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_3 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_3 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000027a-0000-42bd-0000-2fdb00000811"))), - qDomain = Domain {_domainText = "06s.eaq.xbih-26z--5.jqaqc"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007fce-0000-1b96-0000-2d96000022bc"))), - qDomain = Domain {_domainText = "v8nj2.c11974lq.go"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002688-0000-4fed-0000-15550000504b"))), - qDomain = Domain {_domainText = "d3.q6h2k"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007f08-0000-3f81-0000-183d00000a31"))), - qDomain = Domain {_domainText = "1s4hu-4-j.63ja.o"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003717-0000-6494-0000-38f100001684"))), - qDomain = Domain {_domainText = "33.uz"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003f18-0000-4543-0000-04b800007af9"))), - qDomain = Domain {_domainText = "s.49-412g.tq38odf83m"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000043e7-0000-0e87-0000-42c000003d59"))), - qDomain = Domain {_domainText = "8q7i3.d.4.z1es5.t53.jj540u82s13u.5-2-0y.yf41vaq.ii8-9"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002858-0000-2ed0-0000-75b800000f63"))), - qDomain = Domain {_domainText = "1qses.gw.7j6e-97-n5c--41aep6-ka.p5-i4ju1k-f-qgj.5bf.u83-88"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000df6-0000-1c5c-0000-524e0000722d"))), - qDomain = Domain {_domainText = "1.d--h6n7-7"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006298-0000-4211-0000-46e600007d43"))), - qDomain = Domain {_domainText = "f.pe25"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003de8-0000-3ec3-0000-471900001e22"))), - qDomain = Domain {_domainText = "660v.w.x-3m"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002770-0000-067d-0000-6c2700004c25"))), - qDomain = Domain {_domainText = "e05.tk"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000025ff-0000-320c-0000-1f3000005a89"))), - qDomain = Domain {_domainText = "6628-mnod16vk-q.s087"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005748-0000-16a9-0000-6ea200001808"))), - qDomain = Domain {_domainText = "y15-4i.1.v-v--3x.za2o.j-jcxy13m3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000031a0-0000-026f-0000-4b1100002e59"))), - qDomain = Domain {_domainText = "4-0jag.z5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000a8f-0000-31bb-0000-758d00001228"))), - qDomain = Domain {_domainText = "k89l3.s84u.j"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003989-0000-7b83-0000-658b00003037"))), - qDomain = Domain {_domainText = "6lht3--5028.n901-d.e8v.l6k-5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000033c5-0000-1bcd-0000-52770000345c"))), - qDomain = Domain {_domainText = "8-4p5.j7a.jw"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000078f9-0000-5175-0000-281f00007560"))), - qDomain = Domain {_domainText = "1i0.w0u02oh-664c1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005639-0000-6968-0000-5e500000794f"))), - qDomain = Domain {_domainText = "7--04wq.q-r"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_4 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_4 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000070a1-0000-7aa2-0000-09d80000161f"))), - qDomain = Domain {_domainText = "c.8-023o-842jfqd-n11womr81-2.q3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002210-0000-7baf-0000-444a00001684"))), - qDomain = Domain {_domainText = "z.tjab089t"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003ce0-0000-6f08-0000-184100000079"))), - qDomain = Domain {_domainText = "rzsu.5rxxw.a2-q505c58i"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006f6f-0000-5ae7-0000-59f600001ce9"))), - qDomain = Domain {_domainText = "7nr.b09-0zj5r-x.gqeb9d.f9"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000659b-0000-07b5-0000-4db800002c52"))), - qDomain = Domain {_domainText = "7c1irw39.wkc.u.0--h05.37wo.yx0mj.d1sdwqmgy0t7"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000228e-0000-2891-0000-439000006693"))), - qDomain = Domain {_domainText = "8x3-0t.o3.n99"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000446f-0000-043f-0000-284e00006e73"))), - qDomain = Domain {_domainText = "79.j03xh73n66-pc-6"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003fcd-0000-4f99-0000-2ae600002d4b"))), - qDomain = Domain {_domainText = "66v.y-3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000053a3-0000-3ddd-0000-19820000294d"))), - qDomain = Domain {_domainText = "8.e5.e76.wws05el.z"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001b98-0000-3008-0000-544c0000707d"))), - qDomain = Domain {_domainText = "0drfgvr38.5-t-4.z87.8v.o-2j9"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000060bf-0000-6cc0-0000-4c6800003505"))), - qDomain = Domain {_domainText = "b5.4-2-y1.p7h.3urzu-pc5j.krq36.s498a"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006510-0000-44c8-0000-4840000034db"))), - qDomain = Domain {_domainText = "68.1.9dyn.135h-e4i5.s83"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001467-0000-7458-0000-25930000232e"))), - qDomain = Domain {_domainText = "v--50gum0.05u.u"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000c43-0000-62c2-0000-59ce00000650"))), - qDomain = Domain {_domainText = "77ek.f"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000461f-0000-64cd-0000-0d8400007072"))), - qDomain = Domain {_domainText = "0-3s94.44h47uy.fdzis4xj-yywzd"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000037c4-0000-1e74-0000-531800003136"))), - qDomain = Domain {_domainText = "8l9t4.qy8"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_5 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_5 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007de3-0000-1c8f-0000-1f92000009f5"))), - qDomain = Domain {_domainText = "o-5--9-gk4.8q626hgb.1147.m.oj-8.f"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003c26-0000-2af0-0000-517700000473"))), - qDomain = Domain {_domainText = "w.x.m"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_6 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_6 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000064b7-0000-4eda-0000-493c00004a3c"))), - qDomain = Domain {_domainText = "07313.51n.r-3545op"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005ab2-0000-0fae-0000-7dc20000611f"))), - qDomain = Domain {_domainText = "t7452-c5c.b67"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004bf5-0000-065d-0000-6d9900002a46"))), - qDomain = Domain {_domainText = "6ru2-i.fm.537f.kx-j-c45"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_7 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_7 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000036da-0000-4904-0000-3000000033bf"))), - qDomain = Domain {_domainText = "yz.s69"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007eef-0000-3fc4-0000-707d00004ca9"))), - qDomain = Domain {_domainText = "up-a0.f-d5s2"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000181f-0000-4315-0000-5c8500002fca"))), - qDomain = Domain {_domainText = "4-0.l4383.sv7ris"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000330d-0000-6a09-0000-09c600001846"))), - qDomain = Domain {_domainText = "87k-1.1rq1.q"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000277c-0000-6769-0000-6a4500007223"))), - qDomain = Domain {_domainText = "56.3an.g810-5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004876-0000-3492-0000-496a00004ece"))), - qDomain = Domain {_domainText = "u42h.m450s29"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002f16-0000-4420-0000-6dbc00002c63"))), - qDomain = Domain {_domainText = "q.vv"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006b8f-0000-40ac-0000-419c00000293"))), - qDomain = Domain {_domainText = "0.is898n-43"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004e89-0000-2935-0000-5377000011b0"))), - qDomain = Domain {_domainText = "r0pbc6.r-d"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002002-0000-0eca-0000-2e87000057c6"))), - qDomain = Domain {_domainText = "53jmrm174-h3e-6dc-8.w"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003722-0000-4db5-0000-3ccd00000a87"))), - qDomain = Domain {_domainText = "5.m-5a121y7626qx.u--ow93937"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006aae-0000-751f-0000-33010000320f"))), - qDomain = Domain {_domainText = "66f-9s.vd-08g"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004861-0000-2d48-0000-515100003b38"))), - qDomain = Domain {_domainText = "1fu.p-77zp"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000070d4-0000-0839-0000-172400003284"))), - qDomain = Domain {_domainText = "p7-n.f1028"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000044c8-0000-436d-0000-61d800005c3a"))), - qDomain = Domain {_domainText = "2pj.f14.f"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007e01-0000-208b-0000-5bde00007e98"))), - qDomain = Domain {_domainText = "t.m.xq-e17-o.jz432"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_8 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_8 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001533-0000-0cd6-0000-488c00000223"))), - qDomain = Domain {_domainText = "jq2.h"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001ca9-0000-3d4c-0000-5b7600000a4f"))), - qDomain = Domain {_domainText = "98n0.ktvkb0qlx.5.i"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000757d-0000-13f8-0000-53fb000059d8"))), - qDomain = Domain {_domainText = "si320k62.5wh.rwnj"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007dc1-0000-0874-0000-499200005920"))), - qDomain = Domain {_domainText = "t255.nd8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000079b5-0000-3602-0000-5fb500006d48"))), - qDomain = Domain {_domainText = "0u.q5z1sy"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000169c-0000-0d25-0000-3fbf00007bb7"))), - qDomain = Domain {_domainText = "a4a.z3b.nao2---0uv-il"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_9 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_9 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000406b-0000-0c05-0000-7a7f00006547"))), - qDomain = Domain {_domainText = "2.07io.g464-sf8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006cc0-0000-3409-0000-094700002637"))), - qDomain = Domain {_domainText = "wrbsoq.0s-2.u6.xnd5.k9r-8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000017d9-0000-4cc8-0000-5dc8000009e0"))), - qDomain = Domain {_domainText = "u21.v6n"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002139-0000-07f7-0000-20210000535c"))), - qDomain = Domain {_domainText = "e8kr600xi.pb81-7"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001ae2-0000-056b-0000-2bdc000030a9"))), - qDomain = Domain {_domainText = "38y2.2iip7.e-i.0893.f7"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001568-0000-3c21-0000-73eb00001a78"))), - qDomain = Domain {_domainText = "2x2.53.4a-5x7ad.cay2zjw--z9-1.avpv9-1x1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000453b-0000-26c2-0000-622d00007b3b"))), - qDomain = Domain {_domainText = "2im.g"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000abe-0000-5b93-0000-1130000033d9"))), - qDomain = Domain {_domainText = "4.31evw16.kgcf.u6m.0-s3j745.0h2.aavp99h"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000044d4-0000-56d6-0000-41a8000040e0"))), - qDomain = Domain {_domainText = "c9.k0s.02----2-8nk2q50.cr5-ns.g5-n"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000015d6-0000-4f61-0000-72e500004d5f"))), - qDomain = Domain {_domainText = "i9.c12"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007b49-0000-758d-0000-73d9000074c9"))), - qDomain = Domain {_domainText = "s8y-j-cw3.u8e.6.o5xje.ms9gq-290.3.m2n756j101q.t690"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002562-0000-5a59-0000-05a100000c18"))), - qDomain = Domain {_domainText = "q9--p3c0hw.1.dkd"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000427f-0000-3c33-0000-4629000077b8"))), - qDomain = Domain {_domainText = "4u9.a-1j3p"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002f4c-0000-17f0-0000-51ba00001b95"))), - qDomain = Domain {_domainText = "f33.s1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000458-0000-1a4f-0000-6b3400000c30"))), - qDomain = Domain {_domainText = "126.o7-2"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000634-0000-2ff7-0000-62600000322b"))), - qDomain = Domain {_domainText = "0v.4qytdlh7t066p59m-km-40.k"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000021ea-0000-5833-0000-707b00005042"))), - qDomain = Domain {_domainText = "wp.o.3-s.h4-t6"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000e79-0000-4ab3-0000-57bb00007ca8"))), - qDomain = Domain {_domainText = "377.h9m"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_10 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_10 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007b0e-0000-3489-0000-075c00005be7"))), - qDomain = Domain {_domainText = "k30p.u-q5.z8--9"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007dd8-0000-45af-0000-23c400001cc9"))), - qDomain = Domain {_domainText = "54e.75-24.ycx80-0j9hl"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000020c6-0000-0c74-0000-6c0200007917"))), - qDomain = Domain {_domainText = "1.b8u6"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006465-0000-4dfb-0000-011100004ced"))), - qDomain = Domain {_domainText = "09js-x.q3dh0.400.c"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000069ce-0000-77fd-0000-063b0000215a"))), - qDomain = Domain {_domainText = "17845k.kj9juu63k.79j6x3b.x5rzt"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000768e-0000-027e-0000-2630000069c7"))), - qDomain = Domain {_domainText = "9h.0.0.fbi7.l32er.b-0"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004eea-0000-4b92-0000-64840000084e"))), - qDomain = Domain {_domainText = "1.s.z9ykaf5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000078f-0000-4f8e-0000-07a20000002b"))), - qDomain = Domain {_domainText = "37h.w84715.m4"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000757-0000-203e-0000-74ce0000158b"))), - qDomain = Domain {_domainText = "b6.k5g3.3ozcd.2.0.z2-1hj"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000dbb-0000-7821-0000-7c8500003661"))), - qDomain = Domain {_domainText = "b47-0o2.b335"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005695-0000-4799-0000-461d00004c32"))), - qDomain = Domain {_domainText = "87.lo-nc"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000b19-0000-7cf6-0000-4c1f000040ca"))), - qDomain = Domain {_domainText = "a5d.z40n"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000302e-0000-6a65-0000-21d90000268a"))), - qDomain = Domain {_domainText = "ez9.lc-3h8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000032ae-0000-2713-0000-2286000031b4"))), - qDomain = Domain {_domainText = "2g-c.h6569.602.j5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003993-0000-0d94-0000-167f00006327"))), - qDomain = Domain {_domainText = "125-x.g6l8"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_11 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_11 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005ac5-0000-11dd-0000-578100007f21"))), - qDomain = Domain {_domainText = "8---v6s64rx1.t.y3d"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000056cc-0000-6489-0000-6fbd00001428"))), - qDomain = Domain {_domainText = "s3j86.r00"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000d55-0000-2626-0000-1be500002927"))), - qDomain = Domain {_domainText = "2q.t"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001088-0000-489f-0000-73f2000068b8"))), - qDomain = Domain {_domainText = "k8.7bk---2es.mbq"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006310-0000-7d5d-0000-65d20000555c"))), - qDomain = Domain {_domainText = "5s9s--1.d8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001592-0000-1b6b-0000-011d00005365"))), - qDomain = Domain {_domainText = "qo.q443.2c-l61-73.8sy269.k30"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005b03-0000-76b4-0000-5311000050f9"))), - qDomain = Domain {_domainText = "n.h6p"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001e66-0000-6c43-0000-3a3d00002e55"))), - qDomain = Domain {_domainText = "th-28m.y00"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000062a9-0000-147b-0000-0aa6000034ce"))), - qDomain = Domain {_domainText = "77uc.v4-ob.ty"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_12 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_12 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005baf-0000-0b85-0000-5fe6000002bc"))), - qDomain = Domain {_domainText = "5.g"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000215e-0000-0070-0000-1b2e00007d34"))), - qDomain = Domain {_domainText = "yw3y.h8.9u1p.n70-8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002b43-0000-548f-0000-30b800007417"))), - qDomain = Domain {_domainText = "i1.f7i"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007bf1-0000-3b3c-0000-23f600006104"))), - qDomain = Domain {_domainText = "231wo62.u296"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000074e8-0000-60de-0000-502000007602"))), - qDomain = Domain {_domainText = "y6.c7b9pn.dyj.wbj7-jf0-mjw6"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001650-0000-2acc-0000-48cf0000105f"))), - qDomain = Domain {_domainText = "54.rft"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000144f-0000-2acd-0000-637000002760"))), - qDomain = Domain {_domainText = "1tb4.67sg7.m60x804lm"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006bc4-0000-5e39-0000-43120000670f"))), - qDomain = Domain {_domainText = "d-5-5.k"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000013a1-0000-4d65-0000-1f400000055c"))), - qDomain = Domain {_domainText = "9024-r.35.s6.w5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004445-0000-21ae-0000-5bc500003975"))), - qDomain = Domain {_domainText = "2fgsir.iwu"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000063b4-0000-2dbb-0000-60e8000012f1"))), - qDomain = Domain {_domainText = "8ed.ty0tno"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000469c-0000-4553-0000-625e00002207"))), - qDomain = Domain {_domainText = "u-6.f8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004ec6-0000-429d-0000-5d5000005a14"))), - qDomain = Domain {_domainText = "9x.0.0-8--v.d-93u-7-k.l3104"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_13 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_13 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000475e-0000-38ec-0000-391400001acc"))), - qDomain = Domain {_domainText = "ze-e.j2r"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000043ba-0000-7985-0000-182a0000506e"))), - qDomain = Domain {_domainText = "23.jpt063n"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007e10-0000-7798-0000-624100004f2d"))), - qDomain = Domain {_domainText = "9ha.p80.o1u-1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006c62-0000-1c79-0000-2b9800006efd"))), - qDomain = Domain {_domainText = "tj46.v8.qaqm"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001698-0000-27fd-0000-7db100003861"))), - qDomain = Domain {_domainText = "n64o9z-br.j15-q.g915i51c.e8194"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006cd3-0000-24fd-0000-09f400005ba9"))), - qDomain = Domain {_domainText = "915-1w.85782-0.a"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000300a-0000-162c-0000-3ee700005878"))), - qDomain = Domain {_domainText = "487q7.y164on2"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000686a-0000-4dc3-0000-5ad200001895"))), - qDomain = Domain {_domainText = "880eu0.y9"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000035d9-0000-1499-0000-7ef40000702d"))), - qDomain = Domain {_domainText = "3qvah.sx1-2"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007097-0000-0f45-0000-43ca0000574a"))), - qDomain = Domain {_domainText = "g0-c.t78ob0f"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004643-0000-0913-0000-263d00002ec2"))), - qDomain = Domain {_domainText = "d0-j75303.k-e4-946q0.8h5nb-t--w-of.gm7"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002d65-0000-31b9-0000-20df00007924"))), - qDomain = Domain {_domainText = "d6-fo.y028"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000053a0-0000-053e-0000-47c100006543"))), - qDomain = Domain {_domainText = "n2q0ano4z3.o111-3v-5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004080-0000-0c3e-0000-65b900000a32"))), - qDomain = Domain {_domainText = "to.7z.39.lb.noxz"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006e11-0000-3fd3-0000-7d660000121a"))), - qDomain = Domain {_domainText = "9-1u.5--2zb.dh-485un.a.b455b"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000430-0000-2075-0000-4cd500004b77"))), - qDomain = Domain {_domainText = "3281.wk55l"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_14 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_14 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000042a7-0000-32cb-0000-1b6100007e97"))), - qDomain = Domain {_domainText = "j-ip-l.7-1v.k95u43z3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004a01-0000-719f-0000-687e000065e8"))), - qDomain = Domain {_domainText = "1fuok9.6-l.b-t926.171.l-8pfu"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005d4f-0000-38a9-0000-1d6b00007d93"))), - qDomain = Domain {_domainText = "227ot.61z.tr"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000173c-0000-1a35-0000-48120000671e"))), - qDomain = Domain {_domainText = "s-0.x1lw1.l940-5-1ip"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007329-0000-386b-0000-08c300001a02"))), - qDomain = Domain {_domainText = "48lg-78-mp.j.2g.v6"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002714-0000-6ff3-0000-661200005afc"))), - qDomain = Domain {_domainText = "5.mc.642.z6ezu0n24.5dmb9.p32940g"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005d7b-0000-42c8-0000-4c2100007901"))), - qDomain = Domain {_domainText = "y---wl.01w5.j5j72.z--d0"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000072c5-0000-5e32-0000-24810000445d"))), - qDomain = Domain {_domainText = "zf-njrau.hnzq"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004b43-0000-5516-0000-557400000a48"))), - qDomain = Domain {_domainText = "z0-atdfh7.j"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000002a1-0000-6666-0000-598f00005906"))), - qDomain = Domain {_domainText = "z.i89r"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000063f8-0000-4d4f-0000-18e400005d2e"))), - qDomain = Domain {_domainText = "54l.v"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000005d7-0000-446c-0000-412000003819"))), - qDomain = Domain {_domainText = "5mway6.a5"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_15 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_15 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000c25-0000-79e0-0000-541600004086"))), - qDomain = Domain {_domainText = "f01r.m"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000050bc-0000-4f16-0000-21d400005201"))), - qDomain = Domain {_domainText = "58amj.if8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002856-0000-4dc3-0000-767200003807"))), - qDomain = Domain {_domainText = "6.u5vi2.ue.4-2-e.43.nw"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000014a4-0000-3d56-0000-03e3000054d8"))), - qDomain = Domain {_domainText = "k.ii"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000206e-0000-5537-0000-2e0800006b16"))), - qDomain = Domain {_domainText = "7688.e9h.95-r--2dbdvt6.j.x9ol.dp6e"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000007a0-0000-18b0-0000-5d9200006699"))), - qDomain = Domain {_domainText = "2ru96lpzoyh7t5u.t9.d-t.re"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006edc-0000-5d78-0000-652400003edc"))), - qDomain = Domain {_domainText = "08y.42w-9v-10.ak5---5w"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007e47-0000-6da7-0000-26fd00003b7b"))), - qDomain = Domain {_domainText = "3.b7po"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000cee-0000-6ee0-0000-106700007a67"))), - qDomain = Domain {_domainText = "6w-5.1xe26.80lg.jw9.mex.oegh0706n"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000021b1-0000-245c-0000-7a9100007085"))), - qDomain = Domain {_domainText = "j0de1800---s0.9.psqs"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006a1a-0000-6b70-0000-1994000077fa"))), - qDomain = Domain {_domainText = "p8coz0-tebsr85f.f.zxk.l-yq-y--y79222"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000018b3-0000-2d82-0000-2bc1000074ae"))), - qDomain = Domain {_domainText = "s2.e-dkwb.o.465903al--y.q5gn"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003080-0000-1228-0000-50f500006f76"))), - qDomain = Domain {_domainText = "v.62-5.gnk6.i7b"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000b92-0000-0818-0000-4392000026f4"))), - qDomain = Domain {_domainText = "8wd7.n990"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005589-0000-19ca-0000-24da00003073"))), - qDomain = Domain {_domainText = "qh-m.1.xgihs80"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005238-0000-7ca4-0000-4139000066a8"))), - qDomain = Domain {_domainText = "7q-wi6d-42a-t-j.egp2.9z1h-2-n-0--y.r2fej7.7.v-6.80g0.d4"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_16 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_16 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002d40-0000-6639-0000-3e6300005645"))), - qDomain = Domain {_domainText = "72086-5g6.n4d6.r"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004351-0000-78e5-0000-22ec0000582e"))), - qDomain = Domain {_domainText = "26mg.x.rw9h.44o22.k54"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000cce-0000-565a-0000-640400007618"))), - qDomain = Domain {_domainText = "c02dw6e-17.7---ps8.q7-3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000003cb-0000-2902-0000-3225000013e2"))), - qDomain = Domain {_domainText = "96i8.z7"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001ecc-0000-0ca4-0000-5be000003aa3"))), - qDomain = Domain {_domainText = "4c86.fto6un"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003ce3-0000-25bb-0000-5dff00007832"))), - qDomain = Domain {_domainText = "38gp7.i73"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000453-0000-2978-0000-2cbd00001358"))), - qDomain = Domain {_domainText = "s7h6-8.ut2"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000c0a-0000-7937-0000-271000007ae6"))), - qDomain = Domain {_domainText = "2kb.9--kl.hyj"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006d99-0000-163f-0000-179c000076de"))), - qDomain = Domain {_domainText = "k3v.q21.8dlz.y4"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000413e-0000-2f3d-0000-5e2f000006cb"))), - qDomain = Domain {_domainText = "y-f78.72.aqk6a"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002eb2-0000-74bc-0000-028000006a15"))), - qDomain = Domain {_domainText = "85-n-v.a-5j"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_17 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_17 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000307a-0000-5e89-0000-1ac9000011e7"))), - qDomain = Domain {_domainText = "m-26n-8248.w-y.q3-p"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001b46-0000-45d9-0000-6c53000054b2"))), - qDomain = Domain {_domainText = "h-5-20.g-yd"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004013-0000-5a56-0000-27b20000118a"))), - qDomain = Domain {_domainText = "p9tn1y-0e.f7.k-7-7tp"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003bf9-0000-28d3-0000-6f300000431d"))), - qDomain = Domain {_domainText = "u1wvly.x348y848-3f917ae"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000017c9-0000-5c6d-0000-30f8000063f5"))), - qDomain = Domain {_domainText = "unw5.u07"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000613c-0000-29c0-0000-49ac00003fea"))), - qDomain = Domain {_domainText = "2-r.x"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000064f6-0000-74b2-0000-791700002965"))), - qDomain = Domain {_domainText = "s0--aw-4-e0-3.dm.r0"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000d5f-0000-4e9a-0000-400400003da9"))), - qDomain = Domain {_domainText = "x5.bm.6-36.o9-v2-4"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000022b3-0000-12ad-0000-3f170000060e"))), - qDomain = Domain {_domainText = "m-200.hz8-790bfb974"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000894-0000-41f7-0000-6e0d00002aaf"))), - qDomain = Domain {_domainText = "3s250z0.2-dd8a0f2.dp89d"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002c22-0000-01fb-0000-02f600005b08"))), - qDomain = Domain {_domainText = "ih.0n0--9--qlk.736.16v.5.8l.9.e"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000026c-0000-4409-0000-2bc200003589"))), - qDomain = Domain {_domainText = "9jp0.r.b1.1kex3k7o8-7s.e.4vx.7yhx-y.82pwmd.u5zv5cfv-a435.3.1.i52"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000041b8-0000-4a59-0000-390b00004250"))), - qDomain = Domain {_domainText = "3.n3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003caa-0000-4dac-0000-747d0000204a"))), - qDomain = Domain {_domainText = "1d4i9.e-8.nc3698q-tp7bu"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005d7c-0000-1dfa-0000-323f00000e43"))), - qDomain = Domain {_domainText = "3--7.w"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006665-0000-0b5b-0000-31e300000435"))), - qDomain = Domain {_domainText = "17.c9"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006671-0000-3602-0000-5064000037f6"))), - qDomain = Domain {_domainText = "y4-le9r6.295j-v-3oad.lx64.j6"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000561-0000-7d9b-0000-513a00007677"))), - qDomain = Domain {_domainText = "3---e59---u.1-7b.hl-o.mg.qnm292"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000bdf-0000-6e75-0000-44dd00001d49"))), - qDomain = Domain {_domainText = "c.dya-8w625yg9"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_18 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_18 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001804-0000-6e5a-0000-4eab000018cc"))), - qDomain = Domain {_domainText = "g.n596a.ab.q09g-7--a11"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000052b4-0000-3543-0000-486300007862"))), - qDomain = Domain {_domainText = "2rt.l5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000033cf-0000-515d-0000-636300006773"))), - qDomain = Domain {_domainText = "253.n8l-g85"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000649a-0000-6461-0000-639e000000e2"))), - qDomain = Domain {_domainText = "h1-r.5l13.6-4.t4z3.so"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000338d-0000-4926-0000-17ad00001921"))), - qDomain = Domain {_domainText = "5i57.v1-y"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003e1a-0000-56ab-0000-597a0000325a"))), - qDomain = Domain {_domainText = "0n-c.e72-yd"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000cb1-0000-12d5-0000-52d700007bd4"))), - qDomain = Domain {_domainText = "xb2717.7pjc.e1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003395-0000-5ba0-0000-057d00004458"))), - qDomain = Domain {_domainText = "u6-p.ap"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002ab6-0000-48a8-0000-00b60000292a"))), - qDomain = Domain {_domainText = "x13.u2mw.o5i.w--l172t"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000025b9-0000-0bb8-0000-7ac5000016a7"))), - qDomain = Domain {_domainText = "rf.qw4"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000045d5-0000-4768-0000-1ef5000078c4"))), - qDomain = Domain {_domainText = "f49c7ot.61.e8xkl5a-k90-x59.8087d-o.p7m-bg"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001884-0000-0afc-0000-340b00005592"))), - qDomain = Domain {_domainText = "joua87.elmdl5i"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005ae5-0000-6d3c-0000-73ae00004c05"))), - qDomain = Domain {_domainText = "ck.n8-8gv27-b-h"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005726-0000-14ea-0000-17480000204e"))), - qDomain = Domain {_domainText = "yx3.z0ok.f-3"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006f73-0000-7cac-0000-247f00001533"))), - qDomain = Domain {_domainText = "i60k7.e-9"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_19 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_19 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005908-0000-331e-0000-50e90000660e"))), - qDomain = Domain {_domainText = "2r.vxj87-e--91-50.5.n-s.0r09o-n4w0ax.6n-1b.m--j"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003595-0000-586f-0000-74f70000747f"))), - qDomain = Domain {_domainText = "13rrbh.8-0.5.c4.3n.q"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000697-0000-7891-0000-37bc0000652d"))), - qDomain = Domain {_domainText = "7t7s.nd1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000013c3-0000-2387-0000-5bd200005a7c"))), - qDomain = Domain {_domainText = "154ailfu.4i3p-in9.a53w"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000576e-0000-3c78-0000-486a00000ebb"))), - qDomain = Domain {_domainText = "56.2.fu.22q.8--14-3u.9v11v.ll-d"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007550-0000-1992-0000-535d00007f78"))), - qDomain = Domain {_domainText = "9of.j.2.l.1-xy3o2-6jm5-3b.a5qk91.9ie1oc.cl--ia955"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006ac3-0000-50c7-0000-71d100003262"))), - qDomain = Domain {_domainText = "w.s"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000d04-0000-686a-0000-1efe00002502"))), - qDomain = Domain {_domainText = "8a30.4.pqffe"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004183-0000-1706-0000-1cc100004a6b"))), - qDomain = Domain {_domainText = "3y9.51h6a3.w2z8"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000199c-0000-0c7a-0000-361c00004756"))), - qDomain = Domain {_domainText = "b00qi1d.2-b.ux0"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007e44-0000-521f-0000-610800003437"))), - qDomain = Domain {_domainText = "6rdda39---p.0-707gp6cf.vwt.n"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005f32-0000-173a-0000-467200002d38"))), - qDomain = Domain {_domainText = "x6u-q-t.u0"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00003b2f-0000-3345-0000-611900001081"))), - qDomain = Domain {_domainText = "3e.l1.pd.m-ph2t"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000ad1-0000-64e7-0000-6f78000079cf"))), - qDomain = Domain {_domainText = "5--k.qd-3.i-01-k"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005ebe-0000-2820-0000-09880000152e"))), - qDomain = Domain {_domainText = "211.li37"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004438-0000-3d15-0000-454100003176"))), - qDomain = Domain {_domainText = "8-vi.v.z"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007f68-0000-1cc6-0000-4d41000000d5"))), - qDomain = Domain {_domainText = "5.h5"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000035b4-0000-56e0-0000-4bde00004ace"))), - qDomain = Domain {_domainText = "0aj.wgm.i3ql.w-m8-0fkh.a9gr"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006a6f-0000-5b10-0000-65fe000011f1"))), - qDomain = Domain {_domainText = "mk.a3ylw"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000024b2-0000-05a6-0000-0ed200007cdc"))), - qDomain = Domain {_domainText = "n238.a.3.zt-x"} - } - ] - ) - ) - } - -testObject_LimitedQualifiedUserIdList_2020_user_20 :: LimitedQualifiedUserIdList 20 -testObject_LimitedQualifiedUserIdList_2020_user_20 = - LimitedQualifiedUserIdList - { qualifiedUsers = - ( unsafeRange - ( [ Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001eb7-0000-5c21-0000-1418000038be"))), - qDomain = Domain {_domainText = "3fb5t7-7x.d6893-5-g-23-37"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000025cc-0000-362c-0000-098e00004748"))), - qDomain = Domain {_domainText = "r9ig5y.mkg-16"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000656b-0000-3adb-0000-365e000020e6"))), - qDomain = Domain {_domainText = "v.p491.e"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00004338-0000-1fd8-0000-0dd90000728e"))), - qDomain = Domain {_domainText = "4.f"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000001b8-0000-6314-0000-1dd600005284"))), - qDomain = Domain {_domainText = "10xem.0w5b77n.of1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00007b75-0000-30e5-0000-6f9f000027fc"))), - qDomain = Domain {_domainText = "3u2.39.y1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006fae-0000-0e42-0000-132f00000f89"))), - qDomain = Domain {_domainText = "3--4-ojhd.l-4t0.czw"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000011ad-0000-6124-0000-261900003e84"))), - qDomain = Domain {_domainText = "yj.gkm"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000058d-0000-1b5b-0000-6b6400004f75"))), - qDomain = Domain {_domainText = "6613.r462559qf"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00005147-0000-0e15-0000-75e0000012b0"))), - qDomain = Domain {_domainText = "27zw.tu1w3w8.u9di6.d"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000886-0000-4a6c-0000-1f6400001429"))), - qDomain = Domain {_domainText = "v38n.753.j-0-1o"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000a49-0000-6a09-0000-3f3200004517"))), - qDomain = Domain {_domainText = "c7os-n.yjp"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006213-0000-211e-0000-6e3500001d96"))), - qDomain = Domain {_domainText = "17.2p6-6.y626-m0.8e.m4f.g"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002dfc-0000-6836-0000-4fc00000572b"))), - qDomain = Domain {_domainText = "0n-0h.cx"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001097-0000-2761-0000-74b100004a0b"))), - qDomain = Domain {_domainText = "k2-6.gqub.t1"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "0000384b-0000-3c2a-0000-181d000011e6"))), - qDomain = Domain {_domainText = "15abt9-hk.qr"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00001826-0000-3e92-0000-11b800000c4d"))), - qDomain = Domain {_domainText = "g9-2.1cc.tv.b7"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "000000c4-0000-33ac-0000-796a00003581"))), - qDomain = Domain {_domainText = "6.m.g56-y"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00006c54-0000-12e3-0000-521c000040fe"))), - qDomain = Domain {_domainText = "cs.q56t-s"} - }, - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00002e84-0000-3519-0000-3b410000306f"))), - qDomain = Domain {_domainText = "l59n63b-r4.jq-1"} - } - ] - ) - ) - } diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/LimitedQualifiedUserIdList_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/LimitedQualifiedUserIdList_user.hs new file mode 100644 index 00000000000..eeec037c54a --- /dev/null +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/LimitedQualifiedUserIdList_user.hs @@ -0,0 +1,67 @@ +{-# LANGUAGE OverloadedLists #-} + +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2021 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . +module Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_user where + +import Data.Domain (Domain (Domain, _domainText)) +import Data.Id (Id (Id)) +import Data.Qualified (Qualified (Qualified, qDomain, qUnqualified)) +import Data.Range (unsafeRange) +import qualified Data.UUID as UUID (fromString) +import Imports (fromJust) +import Wire.API.User (LimitedQualifiedUserIdList (..)) + +testObject_LimitedQualifiedUserIdList_user_1 :: LimitedQualifiedUserIdList 1 +testObject_LimitedQualifiedUserIdList_user_1 = + LimitedQualifiedUserIdList + { qualifiedUsers = + unsafeRange + [ Qualified + { qUnqualified = Id (fromJust (UUID.fromString "00005bed-0000-0771-0000-447a00005b32")), + qDomain = Domain {_domainText = "sh7636.gcg-c"} + } + ] + } + +testObject_LimitedQualifiedUserIdList_user_2 :: LimitedQualifiedUserIdList 2 +testObject_LimitedQualifiedUserIdList_user_2 = + LimitedQualifiedUserIdList + { qualifiedUsers = + unsafeRange + [ Qualified + { qUnqualified = Id (fromJust (UUID.fromString "000016a5-0000-000e-0000-2ad50000589c")), + qDomain = Domain {_domainText = "t02vm1.gm810xwh1l4rb"} + }, + Qualified + { qUnqualified = Id (fromJust (UUID.fromString "00004bd5-0000-363b-0000-1af6000051cf")), + qDomain = Domain {_domainText = "620au-6.2j.x23-5w"} + } + ] + } + +testObject_LimitedQualifiedUserIdList_user_3 :: LimitedQualifiedUserIdList 3 +testObject_LimitedQualifiedUserIdList_user_3 = + LimitedQualifiedUserIdList + { qualifiedUsers = + unsafeRange + [ Qualified + { qUnqualified = Id (fromJust (UUID.fromString "0000027a-0000-42bd-0000-2fdb00000811")), + qDomain = Domain {_domainText = "06s.eaq.xbih-26z--5.jqaqc"} + } + ] + } diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdateData_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdateData_user.hs index 529d9cf3d27..22180ec29c2 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdateData_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdateData_user.hs @@ -27,7 +27,6 @@ testObject_MemberUpdateData_user_1 :: MemberUpdateData testObject_MemberUpdateData_user_1 = MemberUpdateData { misTarget = Just (Id (fromJust (UUID.fromString "00000000-0000-0002-0000-000100000001"))), - misOtrMuted = Just False, misOtrMutedStatus = Just (MutedStatus {fromMutedStatus = -1}), misOtrMutedRef = Just "#M\95696", misOtrArchived = Just False, @@ -47,7 +46,6 @@ testObject_MemberUpdateData_user_2 :: MemberUpdateData testObject_MemberUpdateData_user_2 = MemberUpdateData { misTarget = Nothing, - misOtrMuted = Nothing, misOtrMutedStatus = Nothing, misOtrMutedRef = Nothing, misOtrArchived = Nothing, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdate_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdate_user.hs index 579913bcb17..36fccb34a21 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdate_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/MemberUpdate_user.hs @@ -16,39 +16,28 @@ -- with this program. If not, see . module Test.Wire.API.Golden.Generated.MemberUpdate_user where -import Imports (Bool (False, True), Maybe (Just, Nothing), fromJust, ($), (.)) +import Imports (Bool (False, True), Maybe (Just, Nothing), ($), (.)) import Wire.API.Conversation (MemberUpdate (..)) import Wire.API.Conversation.Member (MutedStatus (MutedStatus)) -import Wire.API.Conversation.Role (parseRoleName) testObject_MemberUpdate_user_1 :: MemberUpdate testObject_MemberUpdate_user_1 = MemberUpdate - { mupOtrMute = Just False, - mupOtrMuteStatus = Just . MutedStatus $ 0, + { mupOtrMuteStatus = Just . MutedStatus $ 0, mupOtrMuteRef = Just "h\52974N", mupOtrArchive = Just True, mupOtrArchiveRef = Just "ref", mupHidden = Just False, - mupHiddenRef = Just "", - mupConvRoleName = - Just - ( fromJust - ( parseRoleName - "nn8oubrrivojp29q65krhyfzzgvzt3yb18z_39zct19xff_7_wm4xk0ixmzaep5oj3cdajj36vwbc89pgajtmzo1rbwc40ulc837b1aknib6cj03k64ovt4p0h" - ) - ) + mupHiddenRef = Just "" } testObject_MemberUpdate_user_2 :: MemberUpdate testObject_MemberUpdate_user_2 = MemberUpdate - { mupOtrMute = Nothing, - mupOtrMuteStatus = Nothing, + { mupOtrMuteStatus = Nothing, mupOtrMuteRef = Nothing, mupOtrArchive = Nothing, mupOtrArchiveRef = Nothing, mupHidden = Just False, - mupHiddenRef = Nothing, - mupConvRoleName = Nothing + mupHiddenRef = Nothing } diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Member_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Member_user.hs index d61739804df..5621b211694 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Member_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Member_user.hs @@ -34,7 +34,6 @@ testObject_Member_user_1 = _serviceRefProvider = Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000001")) } ), - memOtrMuted = False, memOtrMutedStatus = Just (MutedStatus {fromMutedStatus = -2}), memOtrMutedRef = Just "ref", memOtrArchived = False, @@ -50,7 +49,6 @@ testObject_Member_user_2 = Member { memId = Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000002")), memService = Nothing, - memOtrMuted = False, memOtrMutedStatus = Nothing, memOtrMutedRef = Nothing, memOtrArchived = True, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Message_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Message_user.hs deleted file mode 100644 index 38dc1bac6b9..00000000000 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/Message_user.hs +++ /dev/null @@ -1,42 +0,0 @@ -{-# LANGUAGE OverloadedLists #-} - --- This file is part of the Wire Server implementation. --- --- Copyright (C) 2021 Wire Swiss GmbH --- --- This program is free software: you can redistribute it and/or modify it under --- the terms of the GNU Affero General Public License as published by the Free --- Software Foundation, either version 3 of the License, or (at your option) any --- later version. --- --- This program is distributed in the hope that it will be useful, but WITHOUT --- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS --- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more --- details. --- --- You should have received a copy of the GNU Affero General Public License along --- with this program. If not, see . -module Test.Wire.API.Golden.Generated.Message_user where - -import Wire.API.Connection (Message (..)) - -testObject_Message_user_1 :: Message -testObject_Message_user_1 = - Message - { messageText = - "@\1039399n\985064\179479l`d\b7\994265\65240\47074,8\EOT~\RSA\160680\1019516\145254\b]\ETXf\137307\&3n\DC4\54201.99\1095863\&5\n9OqXR[`\68143\155801\994937\33341k\CAN\1057827\&1PK" - } diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NameUpdate_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NameUpdate_user.hs index f6b884f0383..284742e406e 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NameUpdate_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NameUpdate_user.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE OverloadedLists #-} - -- This file is part of the Wire Server implementation. -- -- Copyright (C) 2021 Wire Swiss GmbH @@ -22,69 +20,3 @@ import Wire.API.User (NameUpdate (..)) testObject_NameUpdate_user_1 :: NameUpdate testObject_NameUpdate_user_1 = NameUpdate {nuHandle = "Q\SO\DC2s\1031112S\r"} - -testObject_NameUpdate_user_2 :: NameUpdate -testObject_NameUpdate_user_2 = NameUpdate {nuHandle = ". module Test.Wire.API.Golden.Generated.NewUserPublic_user where -import Data.Currency (Alpha (AOA, HRK, PAB)) -import Data.ISO3166_CountryCodes (CountryCode (BD, CK, IT, SL, SV, TG, UZ)) -import qualified Data.LanguageCodes - ( ISO639_1 - ( BG, - EL, - ET, - GA, - HE, - IG, - IO, - KN, - NV, - PL, - PT, - RM, - SM, - SO, - TG, - YI - ), - ) +import qualified Data.LanguageCodes (ISO639_1 (SO)) import Data.Misc (PlainTextPassword (PlainTextPassword)) -import Data.Range (unsafeRange) import Data.Text.Ascii (AsciiChars (validate)) import Imports (Maybe (Just, Nothing), fromRight, undefined) -import Wire.API.Team - ( BindingNewTeam (BindingNewTeam), - NewTeam - ( NewTeam, - _newTeamIcon, - _newTeamIconKey, - _newTeamMembers, - _newTeamName - ), - ) import Wire.API.User ( Asset (ImageAsset), AssetSize (AssetComplete, AssetPreview), - BindingNewTeamUser (BindingNewTeamUser, bnuCurrency, bnuTeam), ColourId (ColourId, fromColourId), - Country (Country, fromCountry), - Email (Email, emailDomain, emailLocal), InvitationCode (InvitationCode, fromInvitationCode), Language (Language), Locale (Locale, lCountry, lLanguage), ManagedBy (ManagedByWire), Name (Name, fromName), - NewTeamUser (NewTeamCreator, NewTeamMember), + NewTeamUser (NewTeamMember), NewUser ( NewUser, newUserAccentId, @@ -84,11 +49,10 @@ import Wire.API.User newUserPict, newUserUUID ), - NewUserOrigin (NewUserOriginInvitationCode, NewUserOriginTeamUser), + NewUserOrigin (NewUserOriginTeamUser), NewUserPublic (..), Phone (Phone, fromPhone), - Pict (Pict, fromPict), - UserIdentity (EmailIdentity, FullIdentity, PhoneIdentity), + UserIdentity (PhoneIdentity), ) import Wire.API.User.Activation (ActivationCode (ActivationCode, fromActivationCode)) import Wire.API.User.Auth (CookieLabel (CookieLabel, cookieLabelText)) @@ -103,31 +67,23 @@ testObject_NewUserPublic_user_1 = newUserIdentity = Just (PhoneIdentity (Phone {fromPhone = "+35453839"})), newUserPict = Nothing, newUserAssets = - [ (ImageAsset "" (Just AssetComplete)), - (ImageAsset "(\1032842\ESCp\997564u]'\1069371" (Nothing)), - (ImageAsset "\1056720f" (Just AssetPreview)), - (ImageAsset "T" (Nothing)), - (ImageAsset "5]m\ESCnwr\SI\66869x\ETX\1002148\&2" (Just AssetComplete)), - (ImageAsset "\8334\1068187.`\ENQu2_\RS\t\f1%a\CAN\DC1\161054(z\140016\ENQ+e!s\65400\1073704\NAK)\SYN?V5\1008342\991830e\GS\EOTaZ\51494#\1089765W5ej\EM\NAK'()\8231\&9=%i&K=\SYN\EOT+\CAN\DC3ti\SO\CAN(G\1085496E;\182505\a\DEL\1082111fw\21976\FS\62115\&4vM`B\ENQ!,\21513g=s\RS`6\1033316\EOTqJ\162945\"^W\DC3\119170\137734\&7.\\\24770y5\DLE0\t\15543fXk+\1040724\&0JFKHU1_\1100297\33613\&3\NUL[mjLZ\1023825w\43177\998772O\DLE\NAK\989503\990166w87\\ms\tv\f\181222\DLE\1080871]\GSY\DC4.^\CANcXz3\1088500wFP\995741\DC4DED\1003926~s\EOT\US\r\DC1T?%]f\1059607R\996718\EOT\DC4Nt?&wk\"\1076956V\1081458R_lO\1005930\NAK|\NAKO,\DC4\992100\&0\1038541{\1038807\1032791\1009174\1100707\CAN\b\CAN\SOH\134189\SOF\US=\170022\139432zWGwm\DLE1\187165z%\ETB\132120&\DLE\1054097\146917\72335\ETB\vl\ENQ30L8u.6\1027715\1061594\132515\DC4P\51576\nUr;@\EOT@\1091206\1013197q DB\1108633\&7\1113853\996078)T\ACK+\99560\RS\60904?\23432 x\NAK2\ESCo}\t*0\1095089\ETB[\b>\EMh\SOH!\CAN {H\61631'\SUB\1083923\&1Bj0L\vDf\188129\SYNT\FS\154971+/B\1053646\47730|v\DELE-\128999d`\58542JN5}*n+a@sw\35241Ll\135638*B\ETB!'\1088467R\STXRHv\57995=xl\175165)\9600\1009213=J\ru\DC4ej1\t&\5571;\STXeFIc|:\1080794T\1058505Qr\134756u" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Nothing - } - ) - -testObject_NewUserPublic_user_3 :: NewUserPublic -testObject_NewUserPublic_user_3 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "&W\SUBQ\173415A3N\SYN4Y(Z,\v\DLE\vpv\1085461h\SYN\186050^`P:\NAKr\f_\137215,\61239\1085960&\1041706\1038008\25023\&8\NAKixb\SIhE\1068139\EOT\1019908\5004t=\149472\991777\\\54373iX\v\ETB\149843\n\33152`acU'\37807\a\GS\1061631\GS\1034013\&4fGC-" - }, - newUserUUID = Nothing, - newUserIdentity = Nothing, - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "\f\r" (Nothing)), - (ImageAsset "Mt\166003\60761y\121246\&4&\RS" (Nothing)), - (ImageAsset "\1011766\993921-\FS\rK59(" (Nothing)), - (ImageAsset "j\EM\SUB\67741\159020\991596a8\2128\DC44V\121320y\1014829" (Just AssetComplete)), - (ImageAsset "6\1066411\b\1025376\&4\DLE" (Just AssetPreview)), - (ImageAsset "`1j'C3'}\DC2" (Just AssetPreview)), - (ImageAsset "e" (Just AssetPreview)), - (ImageAsset "*B" (Just AssetComplete)), - (ImageAsset "\158946C\142196\17756!X\1100276\SOH4\SI+\1028706" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 26132}), - newUserEmailCode = Nothing, - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("6xSzqRncYoN4AWAUeSKRw5ZKPWz8PBSQkOx-"))) - } - ), - newUserOrigin = Nothing, - newUserLabel = Nothing, - newUserLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.KN, lCountry = Nothing}), - newUserPassword = - Just - ( PlainTextPassword - "\SI\1059134\DC22\EMx\160821[Bo_I+\184482(\ti\1057504l\b\136069\187362\161780y\1009107\SO\SYN2/^\nN\ETBj\42198 \65464+I\988051\1003392\54156E)+\150297\1095191\EOTC\34942\1108575\6552\1048532E%O\155779+e\thZ\1113140\DC1\1098631\SOHp@\50597\148234\a[\STX8F\997845 45\159401\n\SUB^*1h\120981\986477g\96547d\v=\184407UM\ESCi\191319\GS\DLE\1025144\vb0vV\ETB\1041111\&7\1111836\&8W<\144911\29930\1089605d\ETB\1047487\1023196\rh\1078252qr[\157547+\\)a7L:\SYN\NULD\58493@@Y$\USn\1067931\ENQ\SOH5\ESC3\DEL\1023791uC-t>\DC4\STX\18223\1077124\&2]\a\1022964\23554VK^Pd\166864Vp\178734zW\1068364(\1043124\&9`x\180112\984431\DC1\1009922<=LP\f\1018507e\fz=3<\153967e\99629\&5.\DELA\9663oL\DC2]\1101432\1107797\b{cDQ\68848\44367G\1039367qf\73893_f\986346D\"\DC2u\SUB\ENQ\1048953++Es\1074432\RS<\1022492?[j\ETB\\\1012059\61570\SI^}5\178432\139967k\NUL\\X\EM\1054403qG\ACK+\SO\ETX\DC2U\29438!:\t._\1010857\1744\64663S.!\SUBl_\1046671\SUB\1022334\&5M\139012\188507v^\t\b`P-\34133\182065\141343\166249\131350\165365\1065140(Zo\n\1042367\168120b\48242\CAN\SUBS\1088914O=U\1055684Y]\1001392\1021915.N\USg!\DC4L$VbD\1074986\NULp\26096\re\f\17301Sz[\14517>\SYN\DEL\ESC\SOHg\DC2\178013L.\EOTUz\1000735\r\EM\SO\127239X\1078180\&8{|\SIU\SYN$Q!9\n\US\1023153\26711\ACK'_w]\ESCQ|:\v\SUB3H\1034225M:d\NUL\1035421OkD\DC4\1004292\&4\FS\111301\989264\23660p_\94487M" - ), - newUserExpiresIn = Just (unsafeRange (13846)), - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_4 :: NewUserPublic -testObject_NewUserPublic_user_4 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "\tP\STX\SI\41190\v\\\SYN?`U\CANt<7[i\1029767\DC2\"\133746L\ESC+Z<_\12825M\1001769\DEL\148410\&5Y\38497\1045187`/0\1079960.\ETB]\DEL,N?U_\139355\r&\1070979j\54234\ETX\32668U!3vXgT\77840\131794\DC2@?\40856\1006483\40586\DC1\NUL\135007\13986G\EMjM~\r\ETB]S\61311\n8\USkmi" - }, - newUserUUID = Nothing, - newUserIdentity = - Just - ( FullIdentity - (Email {emailLocal = "\1041369\27245\&5h4", emailDomain = "I\13211\RS\ENQL\GS^i\FS\DC3{"}) - (Phone {fromPhone = "+900959711"}) - ), - newUserPict = Nothing, - newUserAssets = - [ (ImageAsset "\1030466m\1068811\146692I\23591<\DC2Ww\996626I\ACKU0" (Just AssetComplete)), - (ImageAsset "\vMBX6[\ENQ`o\179346yW)\t\DLE\ENQ" (Just AssetComplete)), - (ImageAsset "k\DEL\ENQM.\SOH^\DC1\NUL" (Just AssetComplete)), - (ImageAsset "z\n\SUBa\50623{j\DC3" (Nothing)), - (ImageAsset "\986026*s)\SYN`" (Just AssetPreview)), - (ImageAsset "\1043406\997953\992688\&3\ENQ \USo,\1045930;\1090225SF5\120128" (Just AssetComplete)), - (ImageAsset "\133429\1099931" (Just AssetPreview)), - (ImageAsset "/\RS\1049509\35984Q]ppr" (Just AssetPreview)), - (ImageAsset "'u\DC3:\144012\FS\STX\1044888o.\26889\1109331v\1102603\FS{\r\ENQ" (Just AssetPreview)), - (ImageAsset ".&Vc\1081777" (Nothing)), - (ImageAsset "\DC1" (Just AssetPreview)), - (ImageAsset "*\b1M\1273\&3\DC2\1039970[F\1107051" (Nothing)), - (ImageAsset "\37581\CANz\1034862M^\1046305Wdc\1077950\&6\v~\174867c\\\58849" (Nothing)), - (ImageAsset "h\31507&;b\GSu]\EMt\f9\175893.\9429 n%" (Just AssetComplete)) - ], - newUserAccentId = Nothing, - newUserEmailCode = Nothing, - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("2HSeS4jKke89LUPF1_upoD2sztr2wqUm1wUagZKM"))) - } - ), - newUserOrigin = - Just - ( NewUserOriginTeamUser - ( NewTeamCreator - ( BindingNewTeamUser - { bnuTeam = - BindingNewTeam - ( NewTeam - { _newTeamName = - ( unsafeRange - ("T\1042979y+f\990020Td>#N7P\DC2\tU:T#\1091663Ib\r\1113728\ESC7e\1033100\1100469\vTr\n\23502\&7>Kp\100154H#&\DC1-A+\119530MD\73865gbmyh\ESCzHtUH\176861\vO\SOH\63998\DC3b(l\SIA\ENQUW9s\62075\ETX\15386\140042\144673\1021153\&1\995714\18770\1055994\ETB\DC10\4438\US\183571f\1001539Y\133103\ACK\96811z7\EOT\1096379DY\1085983\1103521PT0\NUL\1034876\CAN\164686a\1095116\SOc\ACK%U\1043822Q0{4\1010432!\ETX\SUBhTV\1019850\ti\173971\&4NX\1000013\ACK\\3\1110549q\1034799\128209\1113878\&22^I\GS*\95824WK\a1\DEL\97854i6\DLE!\146730\NAKhHf\11622\a\994517G\SYN\11240\1017292\1074048bXw\1105825\999860\ESC]r{\1058818u\1081618\1019836\1020478G^^&\177902\DC1l\992294\1005697D?*\nz\186284^\149608\1047451\99103[S\1024941\986593\169392t&\GSxd$\ENQ\1065600\b0\42427A\1088867\1009756s\ESC\1004193\v$\191155\&4\1007667\CAN2@\ETB\US8|") - ), - _newTeamIcon = - ( unsafeRange - ("\1000306]\141382\1040189v7\1082869\986419\1027295.\1048716,A\b\DC2C-\vX\184623\&9\DLE\NUL?\rK\1102006\ESCg_m\RS\f\ESC\ETX<>d 2\170990h.,\\\15336b\1082636\SI'.j&\24040'`\ESC\EOT\DELNA\b") - ), - _newTeamMembers = Nothing - } - ), - bnuCurrency = Just PAB - } - ) - ) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = "\NUL\1088821vK\SYN\1039691\22731"}), - newUserLocale = Nothing, - newUserPassword = - Just - ( PlainTextPassword - "\EOT\DC4\180925\59737\&2\1103547\1079266C3\SOB\SUBm0\989152?[9kX\39882\1012837\EM\134388gDmi4n\1073912VH\1013600\EMl\ACK\NUL\174805\a\190351\2335%\NAK+5A/H\43566!2\US\"V\1096814\28733\1015720\185883Yet\1020988=Q\NAK$o=Pg\70145\1049808\150871\163344#\NUL;\1026623\\\1045401R\19399\1000014-\1041680`;0\1002882\39498T\1045734\1101160\1024416\154240\138362\&0\EMEM\987020I\ETX\52368\&9O\ETX\1081334? s&\1027585\29513#6\64413S\NULj)Lp\110670\1074749Ba$\DC4H5\1080463e>[\1004769\STX\120382__\1103635O\1014083Mi+NQ\r\ACKo@\171130\23723pX\1056743`\FSo\1023422Wbu\ETXW61\190438`\SI$\1087537q\178517\&9" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Nothing - } - ) - -testObject_NewUserPublic_user_5 :: NewUserPublic -testObject_NewUserPublic_user_5 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "\1021464\999886\65403\EM^\DEL\49178H-9o\CANtwv\994746\f@6\1048888 \150621\v\ETXb\NAK\1032699A* ~D)\1074618IX,^|e\1030643\DC4\DC4\ACK#\FS\SYN\1085172\74515\1046258O\988042\FSQt%\v-\"\DC1\127814g9\DC1Ss6n~Y$m'\RS\v\984384Mm.`\20126\ETB\tYv\29158:2fg'\SOH\1048672?\akm\EOT\NUL\EOT\68356\155860\ACKie93\v\v\999509\\U\1030283&irA/\DC4tdP\144682l\1062417J!\97123\1035663\f\137940D+\1053021i\NULQ8\NUL]1{\ttD\24677{\STX\a\NUL\b\NAKY\b\NULv\1113070\1097667\6161\1080393f~\aGua(Q\FS\47125H\128031\1873\25996\ETX'Q\\39W~\131997$&\1095500Mhp<\ENQ\997394\&8{c+uj\78429LJ\GS0.\NUL\"\SUB-\16687r\1111856R\r\ESC\1085981.]\581\1040648\ACK\th[\RSO\1043947\42896o\ETB\996846iT\DC2\STXF\ETX\CAN\NUL65\33495\EOTY\1034785\STX3\1065876g\DLEkn;;\985915[rGNM1\ETB\10140y'#cw\99291\ETXw8Xp\NAKMv\ni\SUB\1053803\SO\ETB\b\1032626j8\41054\999593\46568=TYHq\991906~'\RS\1061846\NULI9\180815\baoZ\a\1022309]\CAN\1095398J,g*N\NUL|ad\35397\NAKH0IfuH?Y=^h\DC4\138709'\ETB\1054900@\ENQ\1100760\54135[_?\60427p\1098671\1047789\1100227\1024031&S\DC3\1068974)\24355\EM8Xb\f!,DL\1113158\SUBY>\1003368\DC1mg&\992221\1084878$\SI\RS;|\1075749!y|\165485\r\FS\1030520\1034728\990076l\69819f\ETX\37391#P(\\\a\DC4ce\bIeec2\FSc\ETXK~\NUL6\177518\26434V\rqV\FS\1105066\58410rz}l\2072\DC1\1040145*s\140939\1050743\GS[\1012577\SOHf\150811?\1007430\1006162\DC4*BK\69676\1047626w6C\EM=>\36649" - ), - newUserExpiresIn = Just (unsafeRange (183097)), - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_6 :: NewUserPublic -testObject_NewUserPublic_user_6 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "b\SUB\128804\&5{})\vqe7\n*M,!i\EM\RS\161522~\CAN\98667\NUL@\1044342t\135813Bb|/b\48258\1038771'W\149482[]\ACK\1041462W!]>l\996933\27891,\SO:\US\95876\1013876y\1020398Q+|`Q\NAK6\987189>\SYNk\1001736a6\186068oCQ\EMy\1041746\f\SUB\NAKA\SYNZ>W\1020183\&9\DC2 P\SO0\\\168443\1102296\987534>\DC2m\SI\DC3SC%C\1042356" - }, - newUserUUID = Nothing, - newUserIdentity = Nothing, - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "\n{{\CAN\f}-(k\2413H\1106357" (Just AssetPreview)), - (ImageAsset "m" (Just AssetComplete)), - (ImageAsset "7\1017129\FS?R" (Just AssetPreview)), - (ImageAsset "\vJ\t\NAK" (Just AssetPreview)), - (ImageAsset "\n\1035551\SUB#7\6078\DC3\r\1033278\SOH\ETX{\169241W" (Nothing)), - (ImageAsset "?\120385\DC2]SA'T&" (Nothing)), - (ImageAsset "$P\154802\1014388\&2\STXb\n=\999389\GS/" (Just AssetPreview)), - (ImageAsset "t\83375\NUL\144550A" (Just AssetPreview)), - (ImageAsset "\SO\NAK4x:m-Q5\1020833Xw\188042\1111932<" (Just AssetPreview)), - (ImageAsset "\1113525" (Nothing)), - (ImageAsset "%\1090720N\1014266\DC1" (Just AssetComplete)), - (ImageAsset "\DLEhB~\15934" (Just AssetPreview)), - (ImageAsset "4\144547_\NULO)oc9V\a" (Just AssetPreview)), - (ImageAsset "\r8\1006897F@v\1003996r\DC38" (Just AssetComplete)), - (ImageAsset "mp\SUB\96602n\NAKQ\1068582\&7{7W\44131)8" (Just AssetComplete)), - (ImageAsset "\23462z\b\DC2\65162\1080896" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 24037}), - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("")))}), - newUserPhoneCode = Nothing, - newUserOrigin = - Just - ( NewUserOriginInvitationCode - (InvitationCode {fromInvitationCode = (fromRight undefined (validate ("XYcMU-BCwqn3aNTQPp6q0KU09PhX")))}) - ), - newUserLabel = - Just - ( CookieLabel - { cookieLabelText = "#l\161073r\140812\&9\DC11\992856\183603\DLEy_\SOpw\1083559\&4PowP\DC2- ;m$\ACK\NAK" - } - ), - newUserLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.HE, lCountry = Nothing}), - newUserPassword = Nothing, - newUserExpiresIn = Just (unsafeRange (217311)), - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_7 :: NewUserPublic -testObject_NewUserPublic_user_7 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "IO\1022408K\1111282g\1103117J\tiZJ\RS}0'A\SI\US\78301\132874`\133778zNo\1084419nb\999005@\ETB\NAK8\4606yCz\36123?!\\\46652S\f\997058H\137813b\GSv\GS\131099\29437o\25211}\18501'\b*M_}\US\120141\1100595\35029V\63276\f*\38060K2\121310K_#77]-&\94914\140231\45105`\68448\1063903L\STX-\1041315>\99506\154804QC]+wqU" - }, - newUserUUID = Nothing, - newUserIdentity = Nothing, - newUserPict = Nothing, - newUserAssets = - [ (ImageAsset "[z\ETB9)" (Just AssetPreview)), - (ImageAsset "Q\98574;'\37627N" (Nothing)), - (ImageAsset "{" (Just AssetPreview)), - (ImageAsset "r\74772Y\1104773\DC4\ACK" (Just AssetComplete)), - (ImageAsset "\ETBv8*C" (Just AssetPreview)), - (ImageAsset "K" (Nothing)), - (ImageAsset "\SO\1107481P\172934;t&g\1022589(" (Just AssetPreview)), - (ImageAsset "0i\f\b-E\ENQR\30571\&2j" (Just AssetComplete)), - (ImageAsset "\STXBK\66614#\v'\17884\CANz\165016\1040479$jH" (Just AssetComplete)), - (ImageAsset "@>r\f%" (Just AssetPreview)), - (ImageAsset "\"9\NAK\139455ci\1034310\&3\ETXARh\RSX" (Just AssetComplete)), - (ImageAsset "." (Just AssetPreview)), - (ImageAsset "6#\SOHHo\38610\78602" (Nothing)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "FO5A" (Just AssetComplete)), - (ImageAsset "Qe\DC1DK\NAK,X\ny\EMP\1105194" (Nothing)), - (ImageAsset "\1040216\\1\1027746d\30590q\DC4\74631" (Just AssetComplete)), - (ImageAsset ")RU1?\1039067r ^$Wq" (Just AssetPreview)), - (ImageAsset "h76F\ESC" (Just AssetComplete)), - (ImageAsset "'\44454\t\1102768" (Just AssetComplete)), - (ImageAsset "\FSZ^+\US\STX\70289V\DEL_Z\1075520n" (Nothing)) - ], - newUserAccentId = Just (ColourId {fromColourId = 30744}), - newUserEmailCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("pwYYlQn1WDrF_I02s6jDhkfLyudwpqrum063eTo="))) - } - ), - newUserPhoneCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("0fz6tQ==")))}), - newUserOrigin = Nothing, - newUserLabel = Just (CookieLabel {cookieLabelText = "cz\CAN*[|&\1000648\EME\GSW"}), - newUserLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.IG, lCountry = Nothing}), - newUserPassword = Nothing, - newUserExpiresIn = Just (unsafeRange (406641)), - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_8 :: NewUserPublic -testObject_NewUserPublic_user_8 = - NewUserPublic - ( NewUser - { newUserDisplayName = Name {fromName = "1Ox\1036046\DC1+z+\DEL\USqV\DLE\61685"}, - newUserUUID = Nothing, - newUserIdentity = Nothing, - newUserPict = Nothing, - newUserAssets = - [ (ImageAsset "D\1069425\&3q\GS\133342z" (Just AssetPreview)), - (ImageAsset "W*=\1103280P\852\1036885\166416" (Nothing)), - (ImageAsset "\26016D\1014238i\n\1066914sG\b" (Nothing)), - (ImageAsset "\1000220\23877X\SUB#CcL\ACK\6337\STX\ETB27\1059878" (Nothing)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "j>!\57789i1" (Just AssetPreview)), - (ImageAsset "o\DC3w" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 121476}), - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("ynbMi06R2nC6tta6KB4=")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("rQKyQz8TBUb9Klrb")))}), - newUserOrigin = - Just - ( NewUserOriginTeamUser - ( NewTeamCreator - ( BindingNewTeamUser - { bnuTeam = - BindingNewTeam - ( NewTeam - { _newTeamName = - ( unsafeRange - ("Id\n40hO\1047760\65343z\SUB9\49445;4\STX[\nA\RS\158323\1048150_.P{\DC1%\148846\1091828Cu\GS[<\49220\DC3s6mZ\ACKB\61027!\DLE\6616\1049432\US\ESC+\1016835\1038198A\188484\66213T,`/\b\22353\179877*'\NUL0w~k6`\v\1075789\RS\1094974\24004n?\ENQ\SUB\ESC\40023p?-\f.Ba\DLEo\NAK5.!\69902\1101828\78786T%\1013532\ENQ\bC\USQ\SI\STX\95946\54926\1102263i$N\1056649\DC1\DC4\CAN\162800\1083937\40552AX\1094876\ACK\95659\74398Vi4E+'t\1037852/\66446\1044484\&6C`\995174\1022677\118954\29531\999389D3.\v&\175611`\161649*Ey$\DC3\6250\STX\GSb=Uf\DC4\147553\r\14562\&1p)\1080248cq9\142751L#\991810HF\184010`\995736\153434\1089142af\ru\ACKoM*\1038001\ETX\1050442 (\DC2:e\58692x\DLE.~9b.") - ), - _newTeamIcon = (unsafeRange ("\CANMS\b9U{Td\vPgKDy\ENQ#(}G\55288Dd/\DC4%;")), - _newTeamIconKey = - Just - ( unsafeRange - ("B\128570\166656\DC4\ENQO%O\16382Q\183819{\ETXm\83358$\DELA\n\ACK\".n\1043017s\175583k") - ), - _newTeamMembers = Nothing - } - ), - bnuCurrency = Just AOA - } - ) - ) - ), - newUserLabel = Nothing, - newUserLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.SM, lCountry = Nothing}), - newUserPassword = - Just - ( PlainTextPassword - "z\133426\1002369\994519\28223\121367\164831z\154424\ETX\SOHe\183383S\188974\12413\b\FS\110593\177232\EM4(CD{\154966\69858\&8\17624/\SUB\ETX\1076336\1015315=\GS\1074509#\DC3\EOTd0L,\ETBW.*\1112933Y(\DC4~L1J\ETXm{t=VR\5090\&8y\42538\188191]Rv(Q\CAN\1077126\CAN\f5\RS(u6OMe\v\STX\ETB\bf)\6275]u\1108647\9970\NUL\DC47\DEL\165587L\94380%Gd\1042500h\26499\t\GS\\\1079242Y\DEL\EOT>RYX]\93009W/[\DLE\119253\r}\"\1085257W[$\SI=Xr&\4055\&4\1034302\ENQ\EM^\149650%4\97672\SYN\157729;:g\RSo\ACK\npm\NAKMe\1095177\151649;\1016570\160280R~\1102211\RSE\59426\&8;%\1020181j\175327\161932\SOH\1011909kJ\179392\1107234\135431L\1026438~j\ENQ\DC3g\47502tP\96358(qn4\137103I\120149nE\DLE1g\157105\147494S\\\EOT\25660H\132009\30637f/_\1053684C-;r\EM_6\1101029MQ|\135768\\gY\ETBx\176252TqT\133227_b\SYN5\EOTd\1051678](\1100131\1045501Ou\DC4d\tgvU\177293\EMk\SYNs\v2\DEL\fla\1085314\v\SUB{US%\1031525\1019691n\CAN\29123<\")\SOH\48117k\ACKH\191273\&7\rl\SUB\1051417-\178778\SUB\1088413\1036169\&2{T\fO\189603Qd|\139447>\985960\128348\STX)\135818\1075896\ETX\1050281R\v\CAN\160825\150329u\a\aU\FSOj` \b\FS\SOH\"\DLE:Kw\CAN\143773\51082\29840\&2F\31042\ENQg\173420\1098085u\984046\DEL\21798\1006942xk\ACK\rAE+$\SI\993555\98363\1022476ja\FShL\1072555\\T\1002810WD((bZ\1106549V}\EOT\GS_?\1093553\"5A\1021170\ETXn\1113671hv<;rO*\SUBchIS7[\SYN|\ESC)\ACKA_\\?vC!u\DC1\37667\SUB\DC4\52936\1111370K8\DC2\SUB<@\1070433\1066570\1032844vZ6\EM\CAN\1041502*3\\\135699\ETX\v2\1032693\1019648\SUB\GS}\v\92667\DC3P%\4834*\DC4\fQ\EOT\12688\1093473\t\1018390{\SOH\179090\NUL/{\SOoJ3\SOHH5-}\152409\164636\ton\r\154007\170226OV\GS)w\144386t\a@d\SYN\a\39265\1067603l\22205\&2`\n\1001492Q\29175\986799V\NAK\CAN\159234\1006700XB\1001481I\1096498\EM\1087002\176382WwX\1102662\v~=m\58276\&0EYY\SOHx\\'\74428dI\1066936m=\DC1*\147855e \GS\SI\ESC\987964j\SYN\fAI-eDY\999673\158811]Y.\1070824O\65157\ETX;\1051502\EOT\1044396^\44861\ESC+:Z\35333\ESCZp 7=L\171577Ptx\1087446\"\39630\&2\DELKL\vM\994083C7^\9410\194944Or*e\1042773dX,^f[\f\ETX2X\US\aFov`\SUB\rj8P\ETB`\10895\&8\CAN\NUL\3988.\EM\1091035\98402+\1038711L\EOTA\158835`t?\\j!\120650e6\NULf\ESC.`M\SOH\53758N\EM\NUL\ENQ2\995251\19263U\27667\190722)W\1063529\1071276\&2\DLEI\NAKzT\1103689@3#\47054\190193\61874]NL?N\1078922&\99287(?\143739\&1\ESC\1082874\1099455\DC2F>Fu\EMl\65504\&5/\a\99981\DC32Z" - ), - newUserExpiresIn = Just (unsafeRange (419615)), - newUserManagedBy = Nothing - } - ) - -testObject_NewUserPublic_user_9 :: NewUserPublic -testObject_NewUserPublic_user_9 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "\SOH\148366~*'\1091611\DC2\ETBA\GS#0\NUL\f8P@\24522\99031\1013785\NULLn\SYN![\ENQ4nU\f\120949\FS\DEL\1106736>%\NUL:\141119\DC3a\1043611\SI\CAN\132537\ESCi\tI\ETXg~1" - }, - newUserUUID = Nothing, - newUserIdentity = - Just - ( FullIdentity - ( Email - { emailLocal = "\1073976\SUB\b(\32406\SO\1068114\&8n\1009973F\165859\992969\94321", - emailDomain = "" - } - ) - (Phone {fromPhone = "+14993214"}) - ), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "\172838(@Z\1055919\96792(" (Just AssetComplete)), - (ImageAsset "%\1068070\DC4/" (Just AssetPreview)), - (ImageAsset "\1071816&5b\62518o\47074\&2$}\151268" (Nothing)), - (ImageAsset "\SYNvQkm|\150806&t-W\NAKx" (Just AssetComplete)), - (ImageAsset "|5\1108400\CAN|te[E\37588#S\1063624" (Just AssetPreview)), - (ImageAsset "{81\1091379.\FS\ESC" (Just AssetPreview)), - (ImageAsset "@y\DLEk\36106'jS*k!\181796SQD" (Just AssetComplete)), - (ImageAsset "z\53959z\r&'" (Just AssetPreview)), - (ImageAsset "" (Nothing)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "\1051708b \1108336gGz\ACK\154017O\\" (Just AssetComplete)), - (ImageAsset "-9\ETX'\bs\CAN\145159\NAK\US\a\150741>;\STX" (Just AssetComplete)), - (ImageAsset "\b\22000\49326\4855P\fX" (Just AssetPreview)), - (ImageAsset "\98531Lw~8" (Just AssetPreview)), - (ImageAsset "\DC3Pd" (Just AssetComplete)), - (ImageAsset "Q\151981\469`" (Just AssetPreview)), - (ImageAsset "a\SIS\55073\1477o\97394" (Just AssetPreview)), - (ImageAsset "R\190252\133627\v\175378\178064\DELm\ENQ\985251" (Just AssetComplete)), - (ImageAsset "1\1017047" (Just AssetPreview)), - (ImageAsset "E%\n\DC2\169591\f\NUL\1087389yP" (Just AssetComplete)), - (ImageAsset "Xz\1094953?yV\r\DC3-\35365\11506\986350E\153851" (Just AssetComplete)), - (ImageAsset "\1050374\995845V}o\DLE\vC)k\1056787%\v\ENQv" (Nothing)), - (ImageAsset "5r\1103827-c\1079457b\17080v9\55084\1031252z" (Just AssetComplete)), - (ImageAsset "-\1020911E\DC2W\ENQ}\98222\DC1" (Just AssetPreview)), - ( ImageAsset - "\159309\1006536\1062142$U\999283\ESC]\1113812\67809\185704$\187918\1032854\1069596" - (Just AssetPreview) - ), - (ImageAsset "\1085476OMt\1092661\1070865\1056513x\DC1\SI:i" (Just AssetPreview)) - ], - newUserAccentId = Just (ColourId {fromColourId = 6550}), - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("X4k8TiOW")))}), - newUserPhoneCode = Nothing, - newUserOrigin = Nothing, - newUserLabel = - Just (CookieLabel {cookieLabelText = "J\1062049\1068280d\1071118\1012786X\150320\&9C?aA:\1011062)\1053955"}), - newUserLocale = Nothing, - newUserPassword = - Just - ( PlainTextPassword - "8\SO\1057360\172918c\1087208\a3_i\STX\177181\1001599sf\ACK*\142118~\1058834cZ:\32832\n\1098399\1060247\1036580I!\7724}zw%\RS\74351$\158628\94271i\1082266V\100721'&/\ETB\1108615dU{:X\38866N\DEL\vdaVjT\1029507M|T\SYN,\97329I[!5%\EM\EOTWDB=?Oe\ENQ\DC10p\EM\DC18D\985673p6]\47768-GOplF\1113534tc\5161\DC1U\1042134\STX=dVF\RS\v\v\95369\DC1A\132688\DC2\1055974\1065964}o5\1078643j]\RSF\157176\&9\ESCl\10918\&2\a\141399p\1027207\139422\183628LtJ7~])\1023137\NAKO2\133558PJ\1054255J\vsb%\131125NB1\ACK\DC4e\DC2'\DLE\RS\DELftG^k\ESC\129513Y\EMr\168888\NAK\1082421B\1058057#6\NAK\t\1045489_\134740\1016847m8\47101\&9HIp\9081\SOHsh\1052654X\US+C\"\DC2\983721F" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Nothing - } - ) - -testObject_NewUserPublic_user_10 :: NewUserPublic -testObject_NewUserPublic_user_10 = - NewUserPublic - ( NewUser - { newUserDisplayName = Name {fromName = "\1086629\51209W\nX\\"}, - newUserUUID = Nothing, - newUserIdentity = - Just - ( EmailIdentity - ( Email - { emailLocal = - "zl\1112297\1100954\ACK" (Nothing)), - (ImageAsset "\4869\1036689+\6941FMEp\1049868H\t\ENQ" (Just AssetPreview)), - (ImageAsset "\SOH;\DC3\DC3\62614\ACK\EOTb5^s:\FS\ENQ\985680y\DC1\ETB" (Just AssetComplete)), - (ImageAsset "v\1063838" (Just AssetPreview)), - (ImageAsset "\1070138" (Nothing)), - (ImageAsset "^ \100451\34269\RS@" (Just AssetPreview)), - (ImageAsset "8\64945\171234\DLEE\74509\1028111\\Z\ESC5<\DELc\160082\&2" (Just AssetPreview)), - (ImageAsset "\DLE\1038907\157993Gc" (Just AssetComplete)), - (ImageAsset "\151793\&0@\\r|J\1060002\DC3\ETX\ETBd*\ETX\1038354]" (Nothing)), - (ImageAsset "\1113676Q\USh%1\f\121373\28332:`" (Just AssetPreview)), - (ImageAsset "6z5\1021987\GSe:}\99663" (Nothing)), - (ImageAsset "\28727\\Q<\SOHX44\39834d\1053626" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 174052}), - newUserEmailCode = - Just - (ActivationCode {fromActivationCode = (fromRight undefined (validate ("Z-Zl_Qv7tQ2uarU-IzTDMXzogSXj")))}), - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("XnBOrq6YI4Q_OfxeADfxgHnlqFMQaauOlT003dC1JCCI"))) - } - ), - newUserOrigin = - Just - ( NewUserOriginInvitationCode - ( InvitationCode - { fromInvitationCode = (fromRight undefined (validate ("w1bhwQG7MiCYb7O4aguK7iSgND5JBw=="))) - } - ) - ), - newUserLabel = Nothing, - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.TG, lCountry = Just (Country {fromCountry = BD})}), - newUserPassword = Nothing, - newUserExpiresIn = Nothing, - newUserManagedBy = Nothing - } - ) - -testObject_NewUserPublic_user_12 :: NewUserPublic -testObject_NewUserPublic_user_12 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "S\134455[\RSVD, \DLEBH\n,\SUB\t\1065607M\26879\&1\SOH\RS[\1108255,\153608\"v\1043886MP\fObI\RS\DC4\50462\1040103\FS\t7\57518i\133613\b\STXT#\49073O\1013355\SO\GS!C\DEL\SUB\EOT{1\SYN +\DC3\EOT\1100935\145256(\150928\1012160\DC4\184145lh\SI\138361\DEL" - }, - newUserUUID = Nothing, - newUserIdentity = - Just - ( FullIdentity - (Email {emailLocal = "g\FSn))s/\161354?\GSQXb2 ", emailDomain = "U\166992=B3Cod*\1004740\7137\13268"}) - (Phone {fromPhone = "+195504776"}) - ), - newUserPict = Nothing, - newUserAssets = - [ (ImageAsset "\1036631\n\1110060N" (Just AssetPreview)), - (ImageAsset "ENiRZ L\1075377. \166145\NULS\SUB =" (Just AssetPreview)), - (ImageAsset "h\119878\DC3" (Just AssetPreview)), - (ImageAsset "\141635x\1041874p\SO\52276,\NAK](\SI" (Just AssetPreview)), - (ImageAsset "\ENQ.P\64193_\51732\1073872D" (Just AssetPreview)), - (ImageAsset "\168952\1063660b" (Just AssetPreview)), - (ImageAsset "\ESCo\DC46" (Just AssetComplete)), - (ImageAsset "t,\176774\STX\"\b\STXmE\SO" (Just AssetComplete)), - (ImageAsset "t\83219\\\DC4\CAN;" (Just AssetComplete)), - (ImageAsset "p)LK" (Just AssetPreview)), - (ImageAsset "\1082561\735qx\SI8mQ\STX\DC4\FS\190305\358" (Just AssetPreview)), - (ImageAsset "e" (Just AssetPreview)), - (ImageAsset "\997995zY|" (Nothing)), - (ImageAsset "Y\ACK" (Just AssetPreview)), - (ImageAsset "\1002331\SI\STX\ETXMux\163688\53496\44761j\n}7\RS\DC1" (Just AssetComplete)), - (ImageAsset ":" (Just AssetComplete)), - (ImageAsset "j\1074909\DC1n\997815`\DC2n\a\72823\190358\EOT\1102765\b\182431" (Just AssetComplete)), - (ImageAsset "Mx\CAN/\ESC\"G_\NAK\ESC" (Just AssetComplete)), - (ImageAsset "[[\1053950<\1034436+I" (Nothing)), - (ImageAsset ",\992742F@\1015314" (Nothing)), - (ImageAsset "]\1023794X(q\ETBO\158969" (Just AssetPreview)) - ], - newUserAccentId = Just (ColourId {fromColourId = -48922}), - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("UVZ6MaxnslUCv-4=")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("fsYfmzlCyBE3ZK8opHg=")))}), - newUserOrigin = Nothing, - newUserLabel = - Just (CookieLabel {cookieLabelText = "\DC1\bg\1014044-\b\CAN\45826LP|l\8514\1059525/\14935\ESC\ENQ"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.ET, lCountry = Just (Country {fromCountry = TG})}), - newUserPassword = - Just - ( PlainTextPassword - "c\146091~b@qM\1071283\1047727\1079832BL$b\n.^{p\nq\r\SUB,\154P~\995481`\SYN?\CAN\1087882\&7I\45464\60369\DC2\1055198\ETXf\SUB\145276\fk%\US\1070329\135511;0&k\SI\NAKHY5_u\137015" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_13 :: NewUserPublic -testObject_NewUserPublic_user_13 = - NewUserPublic - ( NewUser - { newUserDisplayName = Name {fromName = "\EOTui"}, - newUserUUID = Nothing, - newUserIdentity = Just (PhoneIdentity (Phone {fromPhone = "+40846434926274"})), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "6\1100678|\1004331\EOT5z\1080906\1030948" (Nothing)), - (ImageAsset "\NAK\1097014\1095069y\STX\1037487c\b-" (Just AssetComplete)), - (ImageAsset "\1059934T" (Nothing)), - (ImageAsset "[\1031581\EMWU3d0/K" (Just AssetPreview)), - (ImageAsset "A\184589v\US2R\1058582Ff\178786&\1107011&" (Nothing)), - (ImageAsset "\1093099\1106189#\ACK" (Just AssetComplete)), - (ImageAsset "K" (Nothing)), - (ImageAsset "6$(TkM" (Just AssetComplete)), - (ImageAsset "+\13063\150064\DC2\146580" (Nothing)), - (ImageAsset "\b\ENQ\1084766La65=\995400\176949R8" (Just AssetPreview)), - (ImageAsset "\1014296\vj\172641k" (Just AssetPreview)), - (ImageAsset "\DC4\ESC|\1049166" (Just AssetComplete)), - (ImageAsset "D\SOH\CAN\7753l:" (Just AssetPreview)) - ], - newUserAccentId = Just (ColourId {fromColourId = -18284}), - newUserEmailCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("jtAT26_-fRZ3qS2Gx5Cfvrk0mgi5gnPx"))) - } - ), - newUserPhoneCode = Nothing, - newUserOrigin = - Just - ( NewUserOriginInvitationCode - ( InvitationCode - { fromInvitationCode = (fromRight undefined (validate ("oYu2EkO4OdjPAeBx-tOeGAHapJ62b5ZcuA=="))) - } - ) - ), - newUserLabel = - Just - ( CookieLabel - { cookieLabelText = "d\1067047\170156\SI\1023169\172056IZ\33984sS\"wjcI\1066600\147543\141048`X" - } - ), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.BG, lCountry = Just (Country {fromCountry = UZ})}), - newUserPassword = - Just - ( PlainTextPassword - "\986251\&2\SO\27281vXm1\165680>\GSY\131859g\1018593pjer\1088948\190977?\50896'JKn,Jat\FS\aq\1040570\120209\DC1\20612\1036571e#\1004169{.\1039791d\1110055\RS\1097618\1071825!\1001364\1010352\a\23078\a~Nv!\al\1011942z{\SOeF\t*\ACK\ryt\1087249i\97650\DLE%`tZ\ETB HC'\1073J\STX\RS/\71067e\b\990360\983141 C(Ef\ACK\1073923`{/%\CANox3\132841\1039962\62311\1092675\158024\13496\SYN?\STX\DEL=\1101745J\62762\156782o>\DC1:\132415\NAK\1007357!F{\n\ETXQ\DC3\5010\STXYzrH\nG9ZS\182757\US\v\CANO\1052954\1017050< Mu\1088501\146953yi3\SUB3\DC2#M\68874\SO\b,.E\29924\1079063@2\1022636\"Kd\SOHt\1009904m\DLE\SI\61926\SUB0\bs]C\r\SYN\USoXD:\DEL\DC1%\v[\1091642=U]\1035026\&8\STXx7\150861\USJ\1091605n?\54014\140824K \67609]\1051217@\21867`H\rL%\151943Z\r\SYN\1086999oqtFEB\172764[\NAK\a\62397\vv$H\62510&J\ETX\128543\1059840\1023515\&8D\38949X\1073161\SUB\1100179\1101702\94007)uV\10059\19106\NUL\DC19o\DC2(\17757\ESC\ESC\SOH*YO>fWl\SOt\3546\47321s*\"\DLE\1025032\1028388\SOHvgKYmv,\170813v\161542\n\GSO\1061804}\1068179Dfj\ETB\SYN\DC4\917908\RS~\172650[\168875\1071520\37632s\69897\1011855@W\22914\163452w.\NAK5<\146922n\1025530E4is\141686o\138314V'\3302\fy\SYNa\STX\ENQ\SOH\SI@\SYN\39705\33822AO>S\v\1040186#`\125194.\ACK\120917F\1100243\1021420#\1016488R\n\147763\DLExL\158099\\\1067176(\1074249G2\162690 $\1090609\1081923\156383g\r'#;m\t\SYN\1054065\1087696\180495\EOTU(\v\EOT" (Nothing)), - (ImageAsset "4Hi\179576b7" (Just AssetComplete)), - (ImageAsset "\ETB\1096561@\25608\&9\RS%\8554*\EM\183402]\1074635\DC4{" (Just AssetPreview)), - (ImageAsset "f=X\USF|xOI\DLE\161091\100945U%a" (Just AssetComplete)), - (ImageAsset "\FS\CAN\100855" (Nothing)), - (ImageAsset "\25703\&4I\ESC\SYN." (Just AssetComplete)), - (ImageAsset "\EOT\189229M\132588" (Just AssetPreview)), - (ImageAsset "K`jC4x]" (Nothing)) - ], - newUserAccentId = Just (ColourId {fromColourId = 18920}), - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("879HiMc=")))}), - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("2IG53xZ-sTN_Om5U9MMGmxMXgD4I8m0OOhHe2VI="))) - } - ), - newUserOrigin = Nothing, - newUserLabel = Just (CookieLabel {cookieLabelText = "\993012N"}), - newUserLocale = Nothing, - newUserPassword = Nothing, - newUserExpiresIn = Nothing, - newUserManagedBy = Nothing - } - ) - -testObject_NewUserPublic_user_15 :: NewUserPublic -testObject_NewUserPublic_user_15 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "\\x\ESC\146311/\1017598\1099133E\58537Go\23597\1109725\135889\1103281Q.@\rp-~\1051115q\DC4+\SOX\1097928!\1057890sQnJ\32605h08\189561-\1093099Sf\66808o\STX\73664\&3*\1028384e\US\ENQ\ESC[\62491|`\175742\RS\1075261P\1073401_$\153728\&9RY\SYN\1065974\&3#\SYNf\SUBhN_!\149949\SO(@|>C\FS\13094_U\DEL\\-\93766.\v\136176|\1062790=&\987151\ny\DC2\996054\ENQM!\145028\59066\DC4@qj\1005356x\187979\42382\DC3V\31065\v=\996032\EOTAfq\1101761\ENQ0k\SO\63917\SON\SO~*\a\194699\a\DC4\ETX\33943U#\NUL{kb`\SOu\US\ETX/\1024207\&6j\1051088j\EM\1045525|`\1044895\SO5>\149285\US\9345f>}b\1003419C\57559V\bqx\USC\1044571\DC1\EOTk3;qC\1042077\1073193`\172168\1036914Z_:\1097171\1053576\DC1v\153836\1064246t\DC3\27385w \DLE\998172am0\143115\1033373\\\NUL]\bNwqW\DC1.A\1093225rn\NAKL2\DEL\\@v\1033703\1106347\59010\ENQ\139396JsifO`\1086981ZDD|Il\1093491Nd\1035564\r\1057167\NUL\v\1073137\1024124v\1067531MPW>&D\SOH\1084132\55173h\NAK\1110069\bm\SI^)J>@I7\NUL\985909\NAK\DC2]Jr\1026466Qi\b\988866\DC4-\995688\ESC\1099517Yb%vY\DC4 KP\1020023\GS\1010749\1050640d\EM(0\1093281nz]*$\1003221\1037148^D\ETB9\1075886X\1066939\144075\"]\992225#\44010w\163701Y\EM\137264{0\US\19631\187100QqW\22734\35012\994484\133391\DELO\DEL<`jAam\62514s7xC\185942p\NUL\1101176\DC3\1054508fd\"\EOTq2?\24562\151961\&7DxTn\DLE!V\\\20732A\ENQ;\NUL\59451?\ESC\168679\EOT)A\SUB\ETX\1033346A\DLEO\GSw\34730~r\24784*\1020604\&3Y\RS\f\SIl]p\1013564Nb\987654a:cm\STXY\\`\52591XV;WWFG\DC4\140314i7\US4(\68371\EMZ]A\EMp\1087038o-e\NAKSn\9066\189587\STX\1029453\1011266p\143931\b\SOT\1073550Hi\986720\172296\174109\1079222e\9241{\9020G*c\1104508'\142543\FS*9TgW\r\46796,vV=+{\167479\1040808|\1104133E(\US=U~\SId#9lkWi*x\NAK}E?\26235q\15604\94587\&4em\120634\STXJ\f\ACK\b\vByD\SOH\190039\f\ESC\39189\t*\987285\"\GS\FSA{XvC\60179)\72162A\34507\"\1000726\n\987159j\994849\137034\CAN\FS\1088857\169426\ACK_\1003809c\47830\1076021tccC\15287\1058445`\f9P\64198\20126\1112932i\1057633>\1020881\EMG\USa\DC4J\1085621G|\STX\ETX3\SOEZ.\CAN\fy_A\DC3F+sX{-\ndy\1081908\1091905!8a1a\1056587Rv\1000833\ae\100606\1069223=\995223\STX\t0V\f\176342\&8I\1062172_\CANl6Ra+sX\n4\1035091R\1103434\92668]%\"r\14581s\58967<\1036345\168205\1037284\&0\983494=K\45340ZQ\987198\1026655lx`\ACK|7\f\t\73904\DC1\54430\n\SIO\1011117 \SUB?<\1012954\37421Di\1076760.U~\f\188507,>w.\40458\172210!\61330\&3\1113346\EM[l-tI\"y\22776\991720bS><\1024687\151109n\120909&\1099687X+\nvhY^\ny\SO0\147657\STX\ENQV\DC1~%\SOHK>\172592(;G/;\27750M\1083242\CAN$t\1056444~\1066983\99644JZ\985822e\100269\NAK\1049555-{}s\989781v@\EMTf\EOT+\46000\a\1024177pS\DC2\FSJ?\134705\9522y\50495~\SOH\ETB\92695(,\994936=W\159338J\ACK%*9;q\1024350\170359\USp\a9@; \SOHN\v!\18059(on\\!0P<&X\1019613QmuA\1109599\ESCC%\ENQ\154173\DC3\DC4vRnch\1089444'\1023868\4506\SI\SO\995426wB\983743h?q\DEL\DELt+\ENQ\\7\39222\1041355\ETX\\;\1075855" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_16 :: NewUserPublic -testObject_NewUserPublic_user_16 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "36\20709\EM\135657\1009046\DC2\1109280L\\\162440\31843\\:\65347\145957\998043\160930-\54004N\16141\146346[oe\161450%4\ETB]\189710" - }, - newUserUUID = Nothing, - newUserIdentity = - Just - ( FullIdentity - ( Email - { emailLocal = "x\a\119915\136542\1106264", - emailDomain = "C\1053176\FS;\1113985\t?\1064188;\GS`\NUL\95264\a" - } - ) - (Phone {fromPhone = "+534443880"}) - ), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = [], - newUserAccentId = Just (ColourId {fromColourId = -26284}), - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("XYsxg7ZJ_P0cEi1JGv7oJTI=")))}), - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("zCo9DoCXHJwpHDl4N7m-hyRBkTE__sgzyg=="))) - } - ), - newUserOrigin = - Just - ( NewUserOriginTeamUser - ( NewTeamCreator - ( BindingNewTeamUser - { bnuTeam = - BindingNewTeam - ( NewTeam - { _newTeamName = - ( unsafeRange - ("\DC3!\az\1025296\SOHN\999368^lC\n\988422\1032606_\169160\1112920U8 \n9\60210\&0i3Z\SUB\SYN\DC2\141346\&6\42693\92639\131907~~)\ESC=\1063269t\151890\RSs\v\12396\USs\b\SI\DEL\1077652b\151508\b\1024282\176197+e\1076701: \1021924rU") - ), - _newTeamIcon = - ( unsafeRange - ("\1047532%\US\DC4y0\38568\USx\31628\996560\&4\7462\1109751\1088094*=\8707#V%(\58108\t\ACKx\CAN\58120k\1064552\RSl\nG\DC2d\26943\"W\1087990)~\993395fx\SUB\\\1006509\f\1050318\NAKO\DC1t&\188270\SI\EM9\1082486\DC3\92912Z\50662J\1082330#JjO3\EOT\a\1112891'\v><%5SFN\DC4S +7+\17309\&2\1076871\129425\1086732\11728]\t\NAK\1000514v\ESC&D(\SYNc\EM\42376\SOH\1061826\155478'\b\1007144\SYNcv/Z\\\10796\1019756\1078283O}\DC3\b1X\988341K\CANn\133123I!\1016804\&8\aso\1051261il\983110\1029033\1020213\NUL\1020621\144725'\126704\36252BJ\\.v\1032586\f\1029669gB\1023569\1035549y\STX@0\1023358\DC2L)\136057Q\1017189&m\12305u [\1044069'\DC3n\189707\GS\SYN\160673\1069926\127746Mq4|\tz6\1018304\\hN\14823;\1073043\&1\DC2MT\ETB\1028139\nX\SI\DC4\1044749&s\1040325\&3\SUB\DC3!cz\166003\72745Ab\1079697\74897\"\DC13\1007725#%`\NUL\rr\1073798[0\39721g\DEL!/\175664\ACK\SUB\148067X\\\EMy\1071997Ci\SOH)8'\SI2\a\bj4h\21618\1078197!\1066187\1085515\1086653jp\1034708\1041246\167329.\131772[<\25302\SIve(\SYN K\1095698\aE\EM\58748TC\DC4L\1025756j\NAK`j`\1078236g\STX?QQKh\1067173Gdp/\RS\47776\vj\174365&;,qr\17853\DC4Bz\RSW\1046496c\DC2}\ESC\995667LdU\\cwz\995574\CAN|gY\1031518n\1086715l\40967oi\984954\143215\SUB\f//\1104792L=\29000]\1009222\9023\151487\1010621y(\NULw\US_\ENQm\1093427K|\64044d\EOTR,\1112819\1015922\997242Nx\67200\994158\a\SOjS=27,k\SOHw\v\ve \1046105\n\32096{\vC\172339\&6K \1046074\DLEn[zPl\SO\t\ETB%\1084892\v\1081941J\1101417\99504\SON!\1001975\41585\1109213)\DEL\RSN;0\ETXH+\172677?}6\50059\40624\1047371\24297\&5S\DLE\\\v\thJ@\SI\DC2\1017755WD\1071566\155468`\DC1e\ACK\EM\131654\v\1106734\DC1h\DC1'KR\99746cB\SI5\a^\10316?0{y\1104136\63491`\16265\ESCS(\n(6:=\1019759uvwL=\988642\US0t\RS|\1075903<\1068688\DLEU#=\EOT)KR~(\27459\174565\SOH\ETB\26497\993529\r\SUB-\170513<\146792\"iVGqt+]c\49355\SO\FSl\1063689\181983\NUL]m\1017136R\US\44965\DC1B\FS\DC2\DC4\t\GS\38678\23244#FB/W\1030265\1103402\ETB`\ETXB\1008534h]\42134U%\NUL\n\SOY\146357\50671;t\t-%\1014098L9\96504Ju\NAKv\FScw\GS,\1093921\131397\&3 \1056565x0l+_i\b\1009851?\n&\1089671\")H-C-\1065483_\SYN(b|\49030\SIo\66370?e\9115]\154725\&0E\NUL1\DC1\36790\1087582\49965\ESCl .P5XY\a\1080806\1043862&\1066695\1023301tKm\133299\129603'\STXJ\SO9\1054858N\"\b\SIRo\1080609\17190i%\1028500\1088366\1043228\&1\"\DC4j\1061688\189324\27084\ACK\EOTV<5\SOH\NUL]N\38516qCf\162501\60047\DEL;.$~a60\171127W\"\SOa\SOH\1056274\1113282\RS\ENQ\989844q\33519\52220\n\9028\EOT\\}\190174w\DC2(\FS\152606/\1013896kv\ACKT\1083158Ze3\1093298l\18314M}e\NULU]\1044325@DOW\tu2t|@\STX\149331xc?%\1022535?]\v!\ENQ\NAK8@G\111076~l\162761E-\NULw\fFl\RSv\vNb:\34400e\DC2@\169237\ao9G\1014326B\1058375f|\1094308\"\STX-C*>RM&\DC2\12308\DLEuPt\1047719@\SUBk\1042383?\a\1015632\&5Q~dUMlfk\SO\aMC\162315'J(\SYN\DC3\9206\171736/\134580<\1014349+\1008252XSzcB\164451/$\120578n\99031\1091527_v\SO\1059505\&8\33943\aCO\1108402\1003998\1105155\152772:\53008qy\151746\SUB\142336\163300elk\\\EM\139516\n\1023711\&7\52018\183789e\1027968K\61367+\59867e\1015488\n\EM8h\CAN\DC3eLD\DC1\16915Y\EOT$#\DC3\44162\1838T\139827=!\ENQ\1090467<\DC3F\6351(5?\DC12\158325\USr\3796\&3%\1108225\999891\ACK}9\a0rF\CANMH\DEL\DLE8\179113R\1012156\65889\61048\1061741Q*\ESC~%\65793C\EOT\n\SUBr#\DC4\DC4n\DC2tx\134308e\1053161\169975.Z\ry8O\ETB" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_17 :: NewUserPublic -testObject_NewUserPublic_user_17 = - NewUserPublic - ( NewUser - { newUserDisplayName = Name {fromName = "\1101266\SI\rM\169588\8791B\128121\174232\&2\n\STX\DC21n]\21849"}, - newUserUUID = Nothing, - newUserIdentity = Just (PhoneIdentity (Phone {fromPhone = "+251656534"})), - newUserPict = Nothing, - newUserAssets = - [ (ImageAsset "J(Yl\v\47278" (Just AssetComplete)), - (ImageAsset "\13472;s " (Just AssetComplete)), - (ImageAsset "\4504g\1079513`\12652F\1037198\26999" (Just AssetComplete)), - (ImageAsset "V\1088844\78375}\9958\1091466\SOHX%{2\32071\EOT" (Nothing)), - (ImageAsset "\EM\1021992\1066366\5326-\1089398" (Just AssetComplete)), - (ImageAsset "\DC3O[j\1071249\21369\\\1008478Pr\156442\NUL\\" (Just AssetPreview)), - (ImageAsset "\1015032d^\1088258\&1m\DC4j" (Just AssetPreview)), - (ImageAsset "\1082641*k`\96688\121417\67845U\ENQ" (Just AssetComplete)), - (ImageAsset "\1000136\&8\7054\ETXr2\aM#q2\v" (Nothing)), - (ImageAsset ".|" (Nothing)), - (ImageAsset ";\\" (Just AssetComplete)), - (ImageAsset "\1028757\SUB\1014681" (Just AssetComplete)), - (ImageAsset "\57923S\136911\RSA\1109666*>\as3r" (Nothing)), - (ImageAsset ".-Vja\NUL!\SOH\SO9\8039\59710" (Just AssetPreview)), - (ImageAsset "6\161143Eu{s\127879a6\1019972\b" (Nothing)) - ], - newUserAccentId = Just (ColourId {fromColourId = 13420}), - newUserEmailCode = Nothing, - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("KHcnKK_qpFuroGfcTO0nxQ5ntFkICAdG"))) - } - ), - newUserOrigin = Nothing, - newUserLabel = - Just - ( CookieLabel - { cookieLabelText = - " T\121456\&9!\US P>x\1065648.\168741\1052544].\1068571-&\820\1043443\DELx\ESC\NAK\1064909[\RS\"\175359\STX9" - } - ), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.GA, lCountry = Just (Country {fromCountry = IT})}), - newUserPassword = - Just - ( PlainTextPassword - "\181503YALj\"\1079292\1096402\DC46\1032560\NAK{\v2\138711\1057941\&59yPA,%\r\NUL_\96514\n\1103407n\5829pA\71867P%>\b_0\f\ETXo\ACK>\1055943\175828JG$7uj+\144221\\\169751\USS\SO\1098151\NAK$Z\a\SUBG\137786\54450j \126640sE\SYNN\166128\1055791\ETB\SISG8-\95064\1009074\v\DC4\SOH\1112858a\GS\94068Y,\100845\RSF\SUBrZ\30250\nEo\STX\SUBl\DC2\1069330}vJ\DELM\1042226\&65\FSP5\vK\986716=]P\1107419\71189\188993\63087\177290T\140335\157238\153754\DC2Y\1037484E\1036472\995555\SYN`\1109190\n\1055273\&6\NUL\a7\53422{4\1051904jx\n\358\1017656.\23318\1022569\&7\DC3\a+f\65908N\DEL\1039392\SYN?G\1029806\147641M\r\SYN\190633_\1111387\27464C\1045385G\DLE\1030187\1015222T$\SOH}\993957\NULL\1051615\324\38224Y*v\14162\1065070\157561\\T\SOH\1027903EL pS\1025944\&0Ny5\b>\48922\25552\&4}8\6803\SOH.\917853\NUL\171900s\ACKj\1001178\159040\54836>\1075858x\ETBM\DC1u\58020\13668\35010I\b\ax0|U.\ESCb|'l\SUB\1027691h\1065428<\25857hxJ\12580o]g\FSdUj\1113735\SUB7\STX\187929\1105381\1073522\SUB\988559 ?ji@\SOH\1077941\1010608Q\83240\ENQ<>\1105173(\1001208h\ETB\DC3m*j+\4958t\r\1062561\1030677sv\DC4\EM\1114061\1028200`.a\917587&\184293c\ETXS\rEq\SUB=Zc\188279\5357\ETXv\49087\ETX\ETB\RS\EOT \1015390jMt\1072601O\37910,\19924\177989_>#BB\121063-t\1004461\162764\"q@\1032626\1112717\41938\188735%,\994163\&9z\97066\nM\134758\1021399p\SOH\1106837p\74635\129184\f\92628r7+\1005227\SIX\DC2\SUBPtOj\SIZO@'\1001038\1047034o\135659\1000832P\1073325\fb(skyZ\32666b;@\1051451.\n4v'gD\1024820\&9\SYN00Ih|\1035066\18497a\STXt\NAK\b\1014532X\6235Qh-m\194771@\29373q\RSw=:\1019837\SYN\158989&&n\CAN\RS\DLE\DC1\ETB\27195\1063628\1054662*zQ\EOT`O\1014436|%[\SUB\1006985\STXx\DC3ezypH4\1026851\SYN<\US/wb\"\181999\SOH'\1056474\166114|\60420\ETB\177869\ENQS\CAN[\ETBD\1066925\128256{\34534(\SYNg7u \apvj\1031342Vr\SYN8\996660\SI\n\1009589j\156771,\165504Nn\NULd\44565^]#\aa}k^\148538ZPzT6|JA\n4w4\992910\166788R^z7\14616U\ACK\1113645\19783\5304\194638\156905W\1055611-\SYN\160462L\1002902\GS\SOH\1108138\a\DC1\6622\&5p\US\24278V&I\175402\\ #\DC4J\t\1049942pb.\1010603Y=\EMB\996067\1040774\ETB\\\ETXFu3=fgk0tHMV\1009527L&\FS\1079640\167548\96447u\985529\1086845#$\SUBHr\NAKbC=\1037096\165144f}@FOXE\15726b\1099625\t\EOT\994002\SUB'0\SOH\8475\EOT\96228|UBm\1102844U.0\1038890\3046\&0\5457qC5\166740qTEeK?Y\1043642V!Po\186183y\1004864\1006600\1078806)>\998435\SOH\161694\166530@\ESC\n>-q\n8\EOT\1003026E*/\1006129\&3\EMq:JRP\983716\1105473\190584L\46488yl\992613!Iczg\ESC\23903Zdc\1023922\991606IlG\DLEfwx\37330b\33715/{\SUB,\DEL0\70340\ENQ5>\17289\1091599U7J\1035804\NULz'\128593\20935'\EOT\3047_f\DC1B\"B{Q@\NAK\98324\73757b3y\147047\1078365W[j\62876\142006j\1064011[\180857]\SUB\EM\CAN{\SUB\54227^%\1027156T\r\51537\DELqIfX\74961w\100446}\aF\1101058\SIq,\985054teNy\152514vM" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_18 :: NewUserPublic -testObject_NewUserPublic_user_18 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - "!1\CAN1\144175=o/+\1087748(\DC3\DC3f\DLE\41173\8283\191178\1020517;=\DC1\SO}\EM\1063427Vla\DC4\169289{xx 1rYe\1050991K/" - }, - newUserUUID = Nothing, - newUserIdentity = - Just - ( FullIdentity - (Email {emailLocal = "", emailDomain = "\154087\1037287\128710\1075384"}) - (Phone {fromPhone = "+5329622943"}) - ), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "*e\1089302\10851" (Just AssetPreview)), - (ImageAsset "H\DEL\154233\180007_^" (Just AssetPreview)), - (ImageAsset "\1099902\DLES\n\137441Z\1084230\ETBz20\1020520\&0S\19310" (Just AssetPreview)), - (ImageAsset "Zi\STX\SYN\171579#/\55223}\"\ESC\1034142" (Just AssetPreview)), - (ImageAsset "Z\138009\ETB]NL1t\DC2\EM\tE\DEL\EOT\1029357" (Just AssetComplete)), - (ImageAsset "\149286%9\1002620\1015461" (Just AssetPreview)), - (ImageAsset "%y" (Just AssetComplete)), - (ImageAsset "\\H\r8~4\996400\17577V" (Just AssetPreview)), - (ImageAsset "`j\20036" (Just AssetPreview)) - ], - newUserAccentId = Just (ColourId {fromColourId = -14264}), - newUserEmailCode = Nothing, - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("lQ-HusGetqIpBMbG7sWjrEOE4v2-Ym0="))) - } - ), - newUserOrigin = - Just - ( NewUserOriginTeamUser - ( NewTeamMember - ( InvitationCode - { fromInvitationCode = (fromRight undefined (validate ("mYNFyKFVL1hf66I1Exr3P8kiIA=="))) - } - ) - ) - ), - newUserLabel = Nothing, - newUserLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.RM, lCountry = Nothing}), - newUserPassword = - Just - ( PlainTextPassword - "\STX\23956-\SOyRe\ETB\ESC\DLEE\150261/-\n\ACK\ACKz\b\\)\1037849:z\176217\1082403W~\ETB\54707yU@\RS9!\1099610S&\DC1U\STX3f\a\180451D-:8x Z\v\145560y\a\DEL\994805t\100914\&0\1023273\CANLvB\141872\1051474`dq\92965\b@Dh\RS^\DEL\182091!Z\DELrdy&\37095njK\164516\1044360\60347c>k\\\1020435a'{?\1079834\&8\64052\&2\1014683\DLE{0\20518<\142055\74242Jyp\1029535C]{{\50311EJ2q\5027m\993187\&8\FSj?\SUB\SIq\135875%\996809\NAKc\113697\1034249B#D\1071738d[)H%1V\GS\DEL\1034278Ul\1061968\1068236i\ESC\32157\53150}1\SI\1074573e_\SYN\1013349\1088850/\DC1h\1111142\ESCniQ\167524/z\NAKBHL\SI\RS\STX\1101337\987848\1076526\f\51315$\137724\US\ENQ\r\")\27022\1059806\SYN\151409\1004808ZTY^\1107169E\1004349\"\3157\SUB.;;\43277vw\1047269\&7\157540\\\STX]\1044056Sk\DC1)\tx\DEL'b\995601\1099391\1021026v1L'b\SUB\183708.t%\41436\1049072\DEL\DC41\155461}\EM{{/0\n\25454A3\984954f\b\1013990\1095352\ENQ\173463\135530\RS\1096641\20218bC/\98191\67849_~\16801>\1055272\52708l\r\96379\27914\&6Sl\EM\SI\173222\155481 IR57\EOT\v=H4h>%\1092605Z\158591\CAN_\1036045\SI\1071688Q8e\185935\GSn\f\by\999322\149469RWn\ai\SUB\NAK\984865\RSVG{\1041949,Sw=\998755QB1V\EOTeb\DEL\78455\DEL+\CANA\37142bR\ESC\7098\1046757\NAK\NUL&\1032816w\RS%\t\142973`*\1029796e:\1059486Nbk\n]tYJ\ACK(n\DC1(2%\65266a j`)\DLE\1111251\1096252\187962c'\1056681k\GS\DLEwsz\12960+\1030605\&7\185360\171135\DC4R\ETB\1112743n\DLEB=\SIj{\1074190\&05\16369w\DC4X\1016487\SOH\US\161186\SYN{d2c\DC4cn%qT\68800N\128162\48763\&0\1060310P9N\ETB\NUL\DELe9!\129635\13632\&2\r\a@U\FS\GS\98397Z\v=(w\9517\b\EM.)Lp\1096101RJJ\DC42\1088136\GS\173056A\DLE\nZ\ESCx\1099963f1b\37479cn3>9}e\4720\1005886\v\DC1]K[\DC2h\1053150C\1084182\tQ\"@hDY\1106479\FS\DC1\ETXsY@\EMOAc\EM)k\DC1\br9~q\ACKR~\1074883m=\1014601$\DEL\67701P#s\DLElH\EOTK\NAK*\US}z\17632\25323\RS\185248W`U\DC2@\12527v.e7\\\STXUQ\NAK\1046772\v^C%&[9p\f_\ESCg49)\ETX\13863r\ESC\179979\&8\1042860V\vX\bqh\1073214\DC1|\CAN\1050558{0\27050-\DC2y\DLEtH&P\1015792x\n\"G\a\EOTm\164691\37856\1047080\58628;#G\t^sSr\163410c" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire - } - ) - -testObject_NewUserPublic_user_20 :: NewUserPublic -testObject_NewUserPublic_user_20 = - NewUserPublic - ( NewUser - { newUserDisplayName = - Name - { fromName = - ")Q>\t\EOT\1051835O&G`)wJ\1057873\1032479\1024350\164902~\STXV.\1106833e+d\ESC\65762\1036361\1022695g[~\133553\&9\132587QxR\ETBHMtNg\NAK\133684H\190788_x\1025677\11540vx3\ACK}\ESCNo9Pd\FSV>" - }, - newUserUUID = Nothing, - newUserIdentity = Nothing, - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "06m\NUL\171780" (Just AssetPreview)), - (ImageAsset "\1100778\&1\DEL?9t\998692g\DC1\t\a\SOH\NAK`g" (Nothing)), - (ImageAsset "92" (Just AssetPreview)), - (ImageAsset "9\1050850\"B\t1\999607|" (Just AssetComplete)), - (ImageAsset "B " (Just AssetComplete)), - (ImageAsset "\SUBg" (Just AssetPreview)), - (ImageAsset "[\RS\1108970n/" (Just AssetPreview)), - (ImageAsset "\22015" (Just AssetComplete)), - (ImageAsset "\1067432\&3" (Just AssetPreview)), - (ImageAsset "!\7963|R!81" (Just AssetPreview)), - (ImageAsset "\"U))K\139106\DC4`P" (Just AssetComplete)), - (ImageAsset "\DC4\NUL\185666\1015713\30286\1101583D@@" (Nothing)), - (ImageAsset "M\DC2,\ETB\t\31708" (Just AssetComplete)), - (ImageAsset "&\100259%e5" (Just AssetPreview)), - (ImageAsset "Fu\1095038X\ACK\990196\&8wq\62709" (Just AssetPreview)), - (ImageAsset "L" (Just AssetPreview)), - (ImageAsset "FyZs9\64067\&2\ENQ" (Just AssetComplete)), - (ImageAsset "B\USZ\984716o\f\RS-\1097587" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = -14182}), - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("u7kZwe4BWVUT4ofDJg==")))}), - newUserPhoneCode = Nothing, - newUserOrigin = - Just - ( NewUserOriginTeamUser - ( NewTeamMember - (InvitationCode {fromInvitationCode = (fromRight undefined (validate ("B7ams5fFLxcw1iSuEZIpbQ==")))}) - ) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = "\DC2\DEL\45582I'\NAK\DC2,\t|"}), - newUserLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.PL, lCountry = Nothing}), - newUserPassword = - Just - ( PlainTextPassword - "$LQ\RS@\1029575Q\101013y5\132754T\v\1047497mMd\1073933\&6@0T\45642}S\126514>\985306\1043535\aC\131618\DLE=m:$^g\995451N\DC3Q\ETX\DC3>]hmg(\35623Ae\ETX\98548@-m\"@\v\STX\55029yY\1060794]\fby1\44325O\1085672ZO\12036\1019496:\"&\24266\1065045\SUB\139216a\1042858qE\DC1W\46141gB\688\&5MT\41562I\174039\1106796;\a&2\94738`;Uy\132207\120577\&3\n\2053\983533\SYN\DC2\581\71070k*\SOHv\1032152\EM\ENQ\DC2\1064999\DC3]+\40240'\111203\1080567," - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire - } - ) diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NewUser_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NewUser_user.hs index aa953eecf8c..d197d6bad0d 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NewUser_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/NewUser_user.hs @@ -18,47 +18,16 @@ -- with this program. If not, see . module Test.Wire.API.Golden.Generated.NewUser_user where -import Data.Currency (Alpha (VEF)) +import Data.Currency (Alpha (XUA)) import Data.ISO3166_CountryCodes ( CountryCode - ( CC, - CG, - CH, - CO, - EG, - FM, - IL, - IR, - LU, - LY, - NP, - PF, - RS, - SI, - TM, - UM + ( LY ), ) import Data.Id (Id (Id, toUUID)) import qualified Data.LanguageCodes ( ISO639_1 - ( BO, - CV, - FO, - GV, - HU, - KW, - LI, - MH, - MN, - PI, - QU, - RW, - SN, - SQ, - SR, - UZ, - XH + ( SN ), ) import Data.Misc (PlainTextPassword (PlainTextPassword)) @@ -66,43 +35,33 @@ import Data.Range (unsafeRange) import Data.Text.Ascii (AsciiChars (validate)) import qualified Data.UUID as UUID (fromString) import Imports (Maybe (Just, Nothing), fromJust, fromRight, undefined, (.)) -import Wire.API.Team - ( BindingNewTeam (BindingNewTeam), - NewTeam - ( NewTeam, - _newTeamIcon, - _newTeamIconKey, - _newTeamMembers, - _newTeamName - ), - ) +import Wire.API.Team (BindingNewTeam (..), NewTeam (..)) import Wire.API.User ( Asset (ImageAsset), - AssetSize (AssetComplete, AssetPreview), - BindingNewTeamUser (BindingNewTeamUser, bnuCurrency, bnuTeam), + AssetSize (..), + BindingNewTeamUser (..), ColourId (ColourId, fromColourId), Country (Country, fromCountry), Email (Email, emailDomain, emailLocal), InvitationCode (InvitationCode, fromInvitationCode), Language (Language), Locale (Locale, lCountry, lLanguage), - ManagedBy (ManagedByScim, ManagedByWire), + ManagedBy (ManagedByWire), Name (Name, fromName), - NewTeamUser (NewTeamCreator, NewTeamMember, NewTeamMemberSSO), + NewTeamUser (..), NewUser (..), - NewUserOrigin (NewUserOriginInvitationCode, NewUserOriginTeamUser), - Phone (Phone, fromPhone), + NewUserOrigin (..), Pict (Pict, fromPict), UserIdentity ( EmailIdentity, - FullIdentity, PhoneIdentity, SSOIdentity ), - UserSSOId (UserSSOId, UserScimExternalId), + emptyNewUser, ) import Wire.API.User.Activation (ActivationCode (ActivationCode, fromActivationCode)) import Wire.API.User.Auth (CookieLabel (CookieLabel, cookieLabelText)) +import Wire.API.User.Identity (Phone (..), UserSSOId (UserSSOId)) testObject_NewUser_user_1 :: NewUser testObject_NewUser_user_1 = @@ -113,29 +72,21 @@ testObject_NewUser_user_1 = "V~\14040\38047\NULw\1105603\1077601\&1\73084\1020199%\14699]y*\121297jqM\SYN\74260/\1108497-*\US \RSA\SO}\64347c\60361v [\1022394t\1012213R\181051Y\1036488\&6tg\SYN\1044855+\DLE\99976;\ACKOj\DC3\48593&aD:\nf\1002443!*\DEL" }, newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = Nothing, + newUserIdentity = Just (EmailIdentity (Email {emailLocal = "S\ENQX\1076723$\STX\"\1110507e\1015716\24831\1031964L\ETB", emailDomain = "P.b"})), newUserPict = Just (Pict {fromPict = []}), newUserAssets = - [ (ImageAsset "\5112\&5\DC4\1019826\95472`\a\SUBG{?" (Just AssetPreview)), - (ImageAsset "KE" (Nothing)), - (ImageAsset "34A\ETX" (Nothing)), - (ImageAsset "\1016563\SYN\96595\8454" (Just AssetPreview)), - (ImageAsset "bN\GSj|z*dS7\1101290\RS\f`" (Just AssetComplete)), - (ImageAsset "d\b,U" (Just AssetComplete)), - (ImageAsset "\1042200\&4\78817\SOHZ" (Just AssetPreview)), - (ImageAsset ",\DLE\ETBkd\n\44652\1088214" (Just AssetPreview)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "\GS\36694\985607\&2" (Just AssetComplete)), - (ImageAsset "" (Just AssetPreview)) + [ ImageAsset "\5112\&5\DC4\1019826\95472`\a\SUBG{?" (Just AssetPreview), + ImageAsset "something" (Just AssetComplete), + ImageAsset "KE" Nothing ], - newUserAccentId = Nothing, - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("1YgaHo0=")))}), - newUserPhoneCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("z1OeJQ==")))}), + newUserAccentId = Just (ColourId {fromColourId = -7404}), + newUserEmailCode = Just (ActivationCode {fromActivationCode = fromRight undefined (validate "1YgaHo0=")}), + newUserPhoneCode = Just (ActivationCode {fromActivationCode = fromRight undefined (validate "z1OeJQ==")}), newUserOrigin = Just ( NewUserOriginInvitationCode ( InvitationCode - { fromInvitationCode = (fromRight undefined (validate ("DhBvokHtVbWSKbWi0_IATMGH3P8DLEOw5YIcYg=="))) + { fromInvitationCode = fromRight undefined (validate "DhBvokHtVbWSKbWi0_IATMGH3P8DLEOw5YIcYg==") } ) ), @@ -148,1000 +99,90 @@ testObject_NewUser_user_1 = "\143961%5T5'\17286\7398\ENQ-\1063783\100891\&7W@\59062)!$%v{\f\n_I6\1088622\52764]r\1105300\61079\STXGi_L\ENQ@tr<\35715\&2Dr\16519\\\v8\49277\DC4\1069631e\b\190386\71324srN\34600\26071Qk+\36197\999209O\\c6\1032813X\1026685\1074390VV\\\999471^\1105556\DC4(P~y\SI(\nrO\1037710U=$\1038971k\1011736\&7.\NAK[dn\1061566\31927_\NUL\997265\vNVd\54706z\1029333pV6\RS\166743#/m\1065646w\NAK\27792u\144303\SIs\DC1\136497^A\95500>\SUB#\EMsC!3#\59953`\159877q\65860\\VrnT\DLE\SYN\1060441\DC4\STX\156538\1003845\DC2d \1028483#\CAN\179878/k\14627X\"I\SIO,`GU+\DC1\DEL\"\n\47090n)\ESC\1059861x\1018430\1097583%\DC2\SIVr\f\1044385H`\128647W\FS\NAK\1050334vii\FS\a\ENQ\1005180&d\GS\146823\991562.\1090052j\1008159$=a_s\DLEQ\1020394\SO\f\ETX\1019724B\ENQ\CANL\STX_ZX\NAK h_sGj)\1047298|\NUL\SI\rlUN)\ACK\DC1`8\f\1018610\999181\b,A\DC1\tt/0lT\1071777\a}\SYNj\SI\az|\ENQ\152944J,26\1022981\ETX9\11179\&0\EMw'\NULO&g\USF0\1001389kg\STX\DC1|Q\1048680\SUBM\131896\1038590vuPgVp\180615)/\CANy\1026961\1049424\97973\174172\141601\32980\1006618rz\SOH\1021005\DC4\r\DC4\t\186828%\ENQjK\1043685F\65905\&5\DEL[31\DC2H`\142577l&%\EOT\999979R*\988883" - }, - newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = - Just - ( SSOIdentity - (UserScimExternalId "_{3\159847") - (Just (Email {emailLocal = "\66514\145735iC\1096882`", emailDomain = "*"})) - (Just (Phone {fromPhone = "+08713477"})) - ), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "s~\a" (Just AssetPreview)), - (ImageAsset "/=sG\b\74796\GSKx" (Just AssetComplete)), - (ImageAsset "/K\1092610\1018470K\ENQ\184797(,\990273" (Nothing)), - (ImageAsset "\155055SM6V4w" (Just AssetPreview)), - (ImageAsset "e" (Just AssetComplete)), - (ImageAsset "\1022357\156151[0RX" (Just AssetComplete)), - (ImageAsset "#\CAN\181775Y\152578\142820." (Nothing)), - (ImageAsset "85C>%fMrl" (Nothing)), - (ImageAsset "\1050678\NAK\ESC7\45634\CAN \1098391\1077719" (Just AssetPreview)) - ], - newUserAccentId = Nothing, - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("kLnw_0l8qwKitd6ZFiCd_A==")))}), - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("SuKUHXzNTjI1FqdQiBjh5b92HrcebYYq7Vif"))) - } - ), - newUserOrigin = - Just - ( NewUserOriginTeamUser - (NewTeamMemberSSO (Id (fromJust (UUID.fromString "0000519f-0000-2c2d-0000-26150000010b")))) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = ")!\1072457!"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.SQ, lCountry = Just (Country {fromCountry = SI})}), - newUserPassword = - Just - ( PlainTextPassword - "\1006682&1`\1060911/j\143816\ESC@\1029096\147893ael\141244\1073074\186354(\4451\995732\SYNkSCY\1061755nA\SIv3NT\SO\1026898F\\]9\STX\"\ETB\ESC8\NUL:\DC1\1029969s\\O#\SUBs\ETXZN\vN\EM\DC4Iq\1017878w\US\1090622\22754\DLE\ETXh0\SOH\DC4G_,8\SOH\1043656*MX\1012605(H\v2\t\1058824M%J(\1001332\1004711@\NUL\990247\v\187365d\DELAm&~\148667\50012\1024231\68642S\1059526Oo'\a\189198\999417)mGV\135457\147460$(+>(ok\RS\DLE\DC4x\DC49\2891`\SO\1023481]\a\DC3[\f\26263h\1069921Lg\vK?h\ENQ\DEL'\ENQER\CANhG1q7Hw0\1033060\166098R\1076814\1108568Xq\DC2\1061716/\1059864\&2\1107844\168234\191137$\CAN.\986034\STX\aX\996159\ESC]\1027300r\1018675^,A\35957\1065595!\ETB\10158\DC3>\ACKh\r~{N\STX\154171p\1113549T\1083716hs\DC1=s>5\NUL^Bh\182047\1052799~\ETX/\SUBy\tPs\1093016m7h9\132920\989902\132044r\1026138\&4?o\1057718+\1032371\1019109\997209\NAK\t|\DLEG\161998\151372\35112q$\986429\167673\38940\111043\\\EM\ACKrI1A\1040422YpW\DC2ef\191062fg\"|\26780\917574\CAN\1078768)\1103505y\1032757SZ\1017253\&82\SYNa^#e\46908\1029655a-}uY\57411X\1092193<\32405\NAK\27580I\"\v\DLE\NUL\ESC\991177f\185152\\\27490[\1101836=%\28960Ea\984993\1097665\1053017e\1089091\94371I\1080089\1101910\43300\ESC3\4216\EMU|\61154\SYNjtQ`\1031221\DELrW\DC3\ENQZ\NAK/kHL\CAN(\t\SI-s-\1107550'\1020570n\998043\&5\1920/\1004147\1101677\61266q\1082252\1097735p\139262\&6\nZY\tq%\43819\1008683\DC2m\DC3\185092\18249\167055\&1\b:F A\65909\1084546\1013856~vk\1082131\1110019\1062378,Z\1025818\FSk\66199\171592P5_m{\\\t\21751,\1107402A\RS)L0)+\a\US'X17U\STX#\48263>\DC3|P\1069959po\EMRf\1019294\a\SOH\183860x\145286iL\11178h\1108376\nq\153553\STX@\68035c\13063j\987586\&9?R\30388\DC3 NB`\ESC\163993\28145\SO\t'/k\DC3w9eFy\NULt\SO\1100884X/m\US\EOT\5630:&\CAN\CAN4\v[k/f=\1073031bC\n-X\14469O6\RS>A\EM\US\b\b,\1102841_m\1079034G'" (Nothing)), - (ImageAsset "\EOT\RS\1109233U*\1028384\42938\153119z{o\b" (Just AssetPreview)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "\1060069*\aE" (Nothing)), - (ImageAsset "\1020097N\US7WkL\1061623G1\45476\169283\1099983" (Just AssetComplete)), - (ImageAsset "=ntM2\n7=:\SYN \1032706" (Just AssetComplete)), - (ImageAsset "\ENQ\172536J\1092317\"\50184\EOTE" (Just AssetComplete)), - (ImageAsset "B\GS\ETX\1072082\SUB9\164729nQ\1109982,Ps" (Just AssetPreview)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "\DC3rR" (Just AssetComplete)), - (ImageAsset "K\v{O\n\22328\1104220@G" (Just AssetComplete)), - (ImageAsset "MT\EM\b\ESCC\\i(2\52129(l" (Just AssetPreview)), - (ImageAsset "h\1089311\1077334\\\SYN\33487\74110" (Just AssetComplete)), - (ImageAsset "\147810\v$E+Uu]" (Just AssetComplete)), - (ImageAsset "[Y" (Just AssetPreview)), - (ImageAsset "\\P`\1082951" (Just AssetPreview)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "'\NUL\STX)G\GS" (Just AssetPreview)), - (ImageAsset "\21469A\GS-?\\SM\1005769_{`\ETB\EOT" (Nothing)) - ], - newUserAccentId = Nothing, - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("uqc=")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("FYKXjOe_umVeNz8oszsuHQ4S")))}), - newUserOrigin = Nothing, - newUserLabel = - Just (CookieLabel {cookieLabelText = "\ESC\1020022U<\1039752\"w\a<9s\1101139\a(?A\1014049\r\ESC\1003753y,@"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.CV, lCountry = Just (Country {fromCountry = IR})}), - newUserPassword = - Just - ( PlainTextPassword - "\DLE\RS\22311\CAN\a\1012327K\b\1049980S/\23572\GSH\1017395D\"\CAN1y:\EM1g\f~\1098762\\\ENQi\1105245S}\50521\1096679\135387\SO\94618A\995325\DEL\SIt\aN\SIQJg6kD\ESC\1023496\CAN\62375\1041013QU$PN%\170215'`\1104907k\DC3Z<\n\EMu]\99040\&6\1068331\127755P\67617(\SUB\SUB79\r\189272\ESC\DC4\1106024\1073208=\29427\v@\26218\EOTF{\182957<]\1019216\&6e8\ACK\EOT\31272[\\m\SOHR>\v\178437\1069835L\41138(,5)[s]W\23773N\20236\27980&}\ESC@*p%'~s$o\1099903P\ESC\ACK\ETX/.&\SYN.\ESC\1695\10271\96928\ESC.\21993t\138860\147995\182406\EM7\fzO-$K\99528\ESC\DLEl=gcx\143695$h\CANB\DC1xT+ ?f+'dH\1111883\1020511\&2Gu\133052\181417\&4ar[+P\ETB\46625vU}\DC1~\SI\SOWMi6\CAN_~\1100418\STXD\3235^\n~Zf:\"o\1045430\&3\1037460>\DEL|G5\DEL\83316\STX'=%\"\"|5\NULy\n:5\ESCG\52775}|\23629C\1044600\1071086e\vi![?\141724\fw*xIV\td F}X;\1076311\135141\f=\CAN%\GS\164985(\985299\16826\23962i=y6t\ENQ\1019088\DC1\991519 -5F6G\DC1\1023224NO.\131187ly\1057069e,c\"f\GS%\SYN\DC2\101642271P\11668\1013544\EM\1018759\1052439\&1\DC2|\ACK" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire + ( emptyNewUser + (Name {fromName = "test name"}) + ) + { newUserOrigin = Just (NewUserOriginInvitationCode inv_code) } testObject_NewUser_user_5 :: NewUser testObject_NewUser_user_5 = - NewUser - { newUserDisplayName = Name {fromName = ";\1099655\100579\SI\147095\SOH"}, - newUserUUID = Nothing, - newUserIdentity = Just (PhoneIdentity (Phone {fromPhone = "+8057919910"})), - newUserPict = Nothing, - newUserAssets = - [ (ImageAsset "\ETX\1033833\&8pq" (Just AssetComplete)), - (ImageAsset "\37164c9}+}T" (Just AssetPreview)), - (ImageAsset "7\139387ui%4\1084083\140805" (Just AssetComplete)), - (ImageAsset "\f\ENQVd\t#Aj7#\1107786" (Nothing)), - (ImageAsset "nTW\f\137912|\175047\US\988402\&0|}\r\14982" (Nothing)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "Q\1110287\156143\147943\EOTx}$" (Just AssetComplete)), - (ImageAsset "\987997\1040930\59400\t\NAK\a~\SO" (Nothing)), - (ImageAsset ">\r\22592)" (Just AssetComplete)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "?<\1041571\NAKr\168534\SYNQi" (Just AssetPreview)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset ",-&b\150546\&1cw<={" (Just AssetPreview)), - (ImageAsset "x7\b#" (Just AssetPreview)), - (ImageAsset "\\\ACK8p\ACK" (Just AssetPreview)), - (ImageAsset ")\a\40668@\SO'z\1082628 E#\1059790\993661" (Nothing)), - (ImageAsset "\1033719\nl\5499\r?" (Just AssetPreview)), - (ImageAsset "\EMu\DEL\1021612" (Just AssetComplete)), - (ImageAsset "8\138730\n8:\ACKW%M" (Just AssetPreview)), - (ImageAsset "!\DC4\SOH\SI\142581\a\188168\ETB|" (Just AssetPreview)), - (ImageAsset "\994814\SUB\45923\1108043\1081324:\177542" (Just AssetComplete)), - (ImageAsset "\98954\39273Ub" (Just AssetPreview)), - (ImageAsset "v}\SUB\36339\1055932\n~y\b\USk" (Just AssetPreview)), - (ImageAsset "\SIX^\1049463f" (Just AssetComplete)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "\1015676\135484\1018495f6f)S\132862\1075770\"" (Just AssetComplete)), - (ImageAsset "Xbj\f\DLE" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = -20961}), - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("RZICMcCOzqyRTB0d17Rbsw==")))}), - newUserPhoneCode = Nothing, - newUserOrigin = - Just - ( NewUserOriginInvitationCode - ( InvitationCode - { fromInvitationCode = (fromRight undefined (validate ("EXZtnNu96rBu0DQCJ_vGdZkjhH1SSzT2MAHgTQ=="))) - } - ) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = "\185600"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.HU, lCountry = Just (Country {fromCountry = CG})}), - newUserPassword = Nothing, - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByScim + ( emptyNewUser + (Name {fromName = "test name"}) + ) + { newUserOrigin = Just (NewUserOriginTeamUser (NewTeamMember inv_code)), + newUserPassword = Just (PlainTextPassword "123456") } testObject_NewUser_user_6 :: NewUser testObject_NewUser_user_6 = - NewUser - { newUserDisplayName = - Name - { fromName = - "T+u\145108fe01`)S%{\1044883}u\24094o8-W\994850\n\"q]B\aU\13432F\136569\ETXn\a37\t\996717J4*_\1000083=f\DC3\29539\&2\1022153Go}\99405Lh\62174A\34546\SYNPM1v\1100506\FS\ENQ\1013929,\1046180\EM\1063966\FS9+9,1YT\SOt\164648\185504\NAK\ETB\STX\1009053\ETB%\GS\163626G\60181\&0{\1107077\127468\EMy\1001388.Q" - }, - newUserUUID = Nothing, - newUserIdentity = - Just - (SSOIdentity (UserSSOId "" "\1048112") (Just (Email {emailLocal = "", emailDomain = "S{\1020264"})) Nothing), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "l\1006930zuLAm" (Just AssetComplete)), - (ImageAsset "l*+}\1068198\1089601\16651%Q\DC1\GSns\161000\DC2" (Just AssetPreview)), - (ImageAsset "\1072536\USd;\SUB\1020396\1089337s\\fo" (Just AssetComplete)), - (ImageAsset "\1032141ty\1010430v\1079758\&8\189006_Pc\1039009\&5" (Just AssetComplete)), - (ImageAsset "{" (Nothing)), - (ImageAsset "\te:q" (Just AssetComplete)), - (ImageAsset "8]\1022516\&9\1076388\t\94949\NAK{uc" (Just AssetComplete)), - (ImageAsset "\991477s(4J\ACK,\1048935JQ" (Nothing)), - (ImageAsset "\181040\64401\v" (Just AssetPreview)), - (ImageAsset "\161413'\bm\1072323\33136" (Just AssetComplete)), - (ImageAsset "\CANs\16071\GSX_\DC2u3\DELYT\125222" (Nothing)) - ], - newUserAccentId = Just (ColourId {fromColourId = 30946}), - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("ZTf52SPQ5jk=")))}), - newUserPhoneCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("7dJcoVoTKFo=")))}), - newUserOrigin = - Just - ( NewUserOriginTeamUser - (NewTeamMemberSSO (Id (fromJust (UUID.fromString "00000d6f-0000-2269-0000-6bf4000062f9")))) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = "`r}\DC4m\1090568/h\154808EP(-u9?qU)\1058565\a1"}), - newUserLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.MH, lCountry = Nothing}), - newUserPassword = - Just - ( PlainTextPassword - "+':l\10116\178360\nk|}@Z`D.\NULZ\167287;\SO\f\r\98388*l{&|\NAKo8\38228)+\STX\1047842\143079\SIF\DC3\997260\DC3R\52249<4N\1014692\1111353z@;\1006672#\1062918$}\DC1sAXuIWoB[N\1022681X\be\ESC\STX\42350$4\151613\1035680S)\CAN#w}3p\SOH\DLE\\?\DC1S7\1060798E" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByWire + ( emptyNewUser + (Name {fromName = "test name"}) + ) + { newUserOrigin = Just (NewUserOriginTeamUser (NewTeamMemberSSO tid)), + newUserIdentity = Just (SSOIdentity (UserSSOId "some" "thing") Nothing Nothing) } + where + tid = Id (fromJust (UUID.fromString "00007b0e-0000-3489-0000-075c00005be7")) testObject_NewUser_user_7 :: NewUser testObject_NewUser_user_7 = - NewUser - { newUserDisplayName = - Name - { fromName = - "\SO#KrlW\EOT\1003232\1001629wzLN.*BR\FSJ\1097013/zi[\161068I\59380n\r.)\1000284\1016099s\64768p8\"i\NUL\1109192\SUB\996411\SYNk\194709\145941n\EM\1033329\FSS\1017087L\38543i=\DC1\RS$\ENQ\168725E_\18633\f$u\157405`\SOH\1053974\DC1\1024150\1020127\995689\176993tl\38920P\GS\1951&<\ESC0\US:\SUBbm(![\STX~l.\r\1052270\167599)z\135412O\1067678\STX\1097218`\1051463|\EOT\1113413o3iy\132753\EMtSd\1022899" - }, - newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = - Just - (EmailIdentity (Email {emailLocal = "%'\ETX\SUB\52073\a\1080987Ow\1002656\32778\991135", emailDomain = ""})), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset ",m1.I7" (Nothing)), - (ImageAsset "\STX*RM" (Nothing)), - (ImageAsset "sO\\\GS\14670" (Just AssetComplete)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "$.A>Z" (Just AssetPreview)), - (ImageAsset "7r\1062899\1047197" (Just AssetPreview)), - (ImageAsset "%\188437\1047569iW\USf\1058575\1077937\SI\ETB\":\157403\1034545" (Just AssetComplete)), - (ImageAsset "\169156\1024923p" (Just AssetComplete)), - (ImageAsset "\ETB\155117o*" (Just AssetComplete)), - (ImageAsset "Bbt" (Just AssetPreview)), - (ImageAsset ">^\"\1051300\120416\ETX[\1102249\179443" (Just AssetPreview)), - (ImageAsset "" (Nothing)), - (ImageAsset "\DLEA\49671Ue\1011251\EMK$" (Just AssetComplete)), - (ImageAsset "Lj\GS?\SUBt\145770\1084863" (Just AssetComplete)), - (ImageAsset "\fL\96553?Pa\STX\1018010R\RS\ACK\1087347\a=" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 18148}), - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("34dAzMrB0CunAvR9")))}), - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("1Yzr8-Lo2FnYwYYaJFeGEh3yaODV8pFYx3E="))) - } - ), - newUserOrigin = Nothing, - newUserLabel = Just (CookieLabel {cookieLabelText = "n\989384\&2"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.GV, lCountry = Just (Country {fromCountry = CH})}), - newUserPassword = - Just - ( PlainTextPassword - ":Y\1064280@T\997084\1082084\SOH\169346\DEL~\1047751\n\SO\ETB\f\987766$}\1104943\EM\1094330\169942\191040\191304Al\1001917\96685\1107356\b,])^\RSsz?\1034526\&9S,M)\as=h\DELmpCp\SYNwS\1000690c)z\v=\26802-dU\160295|\DLE@\SYN\SUB\a\ETB,\f\14348\140286(L\158204\SYN\ESC1~B\SUB\1085576+P!{@\65454\1030464\SO4:G_\nI8\v\1016135g|\1051609Re\EOTE\CAN\1027704Dob3\STX\ESCA2\SO\45988&\r?\14985\&0M5\1104409,&ey\SUB\1024749QB\RS{\NAK\5351\&76\985196D\1059513J$\1080025qZYgd0i\GS\fbZ\EOT\92519\1084718D&m\"rM\10292\97295\n\DELhKg=7%Il\1099938g\1007473C}\47943\19042v\1026647 7!\RSrK c\CAN %A\EOT\147321\v\tIb\DC3W8\SOHi\174561\1108472|OfiJ@@j\1028789xO;`\1032453\ETBc#\r{\186360\998808\1001960\167999n \ETXIP\ETXY-\ESC\DLEEv\US\1087523\v\NAKzgx\SIE\STX\1025401'\SUB\GS/\983101DCD\FSj\DC1\\\144976\46785\1062381{1A\"\DC4-\1004921\&1\1048911\1076182wT\GSB-q1a\"$S2x;\998957y\1031681\NULt\1059162\1054991J\19882\f\42778]0F( d\1095736~h\65008zt/E\4752\&3\30173W\t-\1046651Lh<\995338\1007432\GS\DC2B\DLE\160583\190017\1067598a\98184\1083343\&99\21570\US\DC3f\STXJ\FSc\16240F\CAN8\2623v\ACKm\1052138k\1074078U\DC4b\57660Ym\USI\DELV\167100\ENQ,n\bx\fl\\e\1028130;\150928\DEL\998735\1087406\DLE\DC1\994056o\1005388KF$\STX8\r\fZ\DC3Z\190875\FS\1093487_\990546:,\n \1079886 AM\159597\DC2w\39116WB\1015167\fCS#\153305=\1107374\988015pC-.\165512C~q?_O\ESC\1113113)\149323\EOT\\\SOH\ETB-\33022)\"la\EOT\148970HAf\1077042\1093914\49704l\STXd\t)`.>\1043695\60257u\163182\1097422c\999601\STX|LiP\1094711L=\993695a\836\1067062EE\1106112\1013947\ETX\1000293hQ\ETBW\1080539\94691G\"\43628D\DC4_\1056397\STX#\1087677$\194807\SIL(\1077025\STXt\1017609$IQX]p\ESC4&0\1110876\DC4\1060121m\SYN\t\\(^\ESC\118818,D]\1089937\164239\EOT\DC1IAd\33797\&0N\1029630\bg6\DC3\DC37\NAKk\"\1064942)pI\149677\\M\120101\NAK\30729\US\151204\&6~T?\ENQ\EMs\47424-[\137919w\4918Dq\157593\\\1041784%b\ACK9\1000877\&2CC\2853\1042497ojG\DELT g\53971\1007774xSeL\CAN\15010\SUB\985658'0:j4\71865q7\1000131m\ENQs\SO\1029677\ENQ\37674iG\68423\190220\5139wv\188572n\ESC\ENQ\US\EM\1077453\997058\DC2Ce) U\1074321\ACKfo\1051487\1107513c\1058590L4\DC1-\SYN\1060734L\1022647\185748\ETB|oW\ETB\ESC>\DELbD\NUL\98915\59361dm\67292vW\986731(2\CANz\1026512\27723?n\985498\1013509w\135214\NUL\DC4}\1101001|H<\54945U\53878\SYN\1038698\142287\DC1W\182543TM\ACK+LT\NAK;-!E>$\DC4j.\DC2q^\NAK\5537IN\1059744>V\STX\184118\1037245OA\127402\vvCf\169329n\NUL\66315\ENQ?^\SYN6\ETB\t8:at\"w`\1112149rl\19705\119110\174184J\993510~\1094824Q\996852Lm?c\DC2v\GSi~i\DC4\fG%I\US>l!\STXL\GS\EOTUW\ETX\1053673\\Bg\58292\13051\SUB\10530\&0EQM\NAK\1084309>\21299\vY\49643\152180\98008L%^\1000259r\164644%>\v0z\994733m\vEh(\180334u2\DC1v\1039286Q\61925\RSB\72711I+\ETXkaR\1002397=)\SUB_\1032377Tv\SO\58962%\183143M:\148104&\DC4\a0\f\"\EOT\128107{\1003812\ENQ)\SUBF\DLEN`08\187686\SO\SO\149986\1039718k\1069652\159769Q\US\EM1[/\1011611\177380Q\1058916\68755re\131476du*\1018976\FS~\8761a*4\DC2cr\997141b" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByScim - } + ( emptyNewUser + (Name {fromName = "test name"}) + ) + { newUserOrigin = Just (NewUserOriginTeamUser (NewTeamCreator user)), + newUserIdentity = Just (PhoneIdentity (Phone "+12345678")), + newUserPassword = Just (PlainTextPassword "123456") + } + where + user = + BindingNewTeamUser + { bnuTeam = + BindingNewTeam + ( NewTeam + { _newTeamName = + unsafeRange + "\fe\ENQ\1011760zm", + _newTeamIcon = + unsafeRange + "Coq\52427\v\182208", + _newTeamIconKey = + Just + ( unsafeRange + "\ACKc\151665L ," + ), + _newTeamMembers = Nothing + } + ), + bnuCurrency = Just XUA + } testObject_NewUser_user_8 :: NewUser testObject_NewUser_user_8 = - NewUser - { newUserDisplayName = - Name - { fromName = - "\STXO.\23742\97516\"\DC2k\EOT\995859C<|\98890\159067\34115\&2\SOu+`9\SOb#A7n\SOdr\1110736w\ESC\DEL\1104511x8\180094x\131506\993202O\146331\994882\3601\NAK\NUL4\96807\1055650b\\#\1060016oC2-=+\97826L5\FS\\*L\RS@F\163064/\ACK9m4)\GS\at`\DLE\1013206\&8)s\ao\1075958n" - }, - newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = - Just (SSOIdentity (UserSSOId "L\171350\1007858*" "\1007850") Nothing (Just (Phone {fromPhone = "+71827573"}))), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "<%\DC2\51064" (Just AssetPreview)), - (ImageAsset "\SI" (Just AssetComplete)), - (ImageAsset "\DC2\1092208\171820K<\EOTF" (Just AssetPreview)), - (ImageAsset "P" (Nothing)), - (ImageAsset "c\EMY\v\SUB\SO{\ETX\988641\77928\135016" (Nothing)), - (ImageAsset "P$i`\DC1(w`" (Nothing)) - ], - newUserAccentId = Just (ColourId {fromColourId = 24261}), - newUserEmailCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("EGk4BobXeO_5YaLyYwCxuZv6-A==")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("ohTCWvY5M-J1AbWoFfqtjg==")))}), - newUserOrigin = - Just - ( NewUserOriginTeamUser - (NewTeamMemberSSO (Id (fromJust (UUID.fromString "00007c3b-0000-1728-0000-6e4e00005f30")))) - ), - newUserLabel = - Just - ( CookieLabel - { cookieLabelText = - "d\1025595\1092941\&0\CAN\156310\GSZu552@\161324\r4/\1057226\fo\187210N\CAN\SYN&\1021655" - } - ), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.MN, lCountry = Just (Country {fromCountry = NP})}), - newUserPassword = - Just - ( PlainTextPassword - "(\ETXV\1014552\1039715\b\161164\1054965$~&\1038463o\1040090MTfC.\1021984;W\59323O\1096990\&6#{\n\1069751z\1056788K\30134\&6\DC4\1005672\136772(\158756\r?\58421Lc\CANxNE\ENQh/JeS\ACK\CAN\173642+60W3ySv\US@\DC3w\1090870\bB\SYN^%\EM\988823\146784iodDm%\127288\DC1]m\v_\21879\181210$\GS\188686\138708yt\EOTfm\SO'@#\DC4)\182806|\r&$*!%\n\ETBr]{v\FS\CAN\FS\1001993\b>\168328d@X0\GS8\158330>\r8{\99680\DLE\1069883\1026212C\NULk\1026454\ESCM^:\1069428WF\SI\t5Qi;}\n\1105500\14806\1001513\DLE\ACK*\DELPk\SOH\69696*\175908m\59197Np\24497@O\RS&\1025701F\995106tx\94547\60298?\1041368Ps\1070094r\1011316{E\ETX\GS\1104697\190467zcn\1017312e\SOHkr=\1036309z~e\\D\40996c\FS[J^\DC3\78393\r\188974\7150w1\1104314\991563\FS\179957\t\1013475\1020262;\173824 \vM\1108401IF2\ESC\191321cbvP\b0\33031q\57419>\1006526#%k\100443Zw\1001498\1010394y\25441x\DC2|\1050019\SYN@\CAN>\GSR\NAK\SUB3%\n\1072784\STX\1080467\DC1uOs\1107842\1065309\138346u\1073372a!\DC2\132548fWgk5\GS\1082431\r\1018566\42900\145709\f\RSydA\DELs=\1024217z\49659\FS\nxR\SI Ng\ACKC:X\146623\&7\f[\1024592k\v}\ETB5\DC2Wm%\1087573\165920,\147518\DLEGr\1074963ZvO\30720B\1005097hjYZiGd\bP\SOHGHG-\DC4\USy\ETBr9$\1039011Kmh\917606\&8g3\12714t\1015918\985504\1021587\b\"\9658\\sn\EOT>\DC1\190507\&6\134237\SI8k\1013568\&6F\129330&\CAN9\f'Bn\50546\FS\46460\NAK0H=\USe6\68136\US0\1062432L\FS\163483o9!\1045621\1094941\1083191r\EOT:\25240\492q1\f\1061443\5079\ESC5u5\160545>U\984651$\63797i\bP\20545~\67985\n\ESC\1044063\ENQ2\DLE_%\160630\998641\DC2b^\\_\1087702CD[Rg\135191l\129188*\986155\128591\GS\1113693\USX\ENQ`\nM\SO\1068094\&0H*i\ENQ\1025344\ETX#q\42514x\nOaE*U\1008269GRw\983690]\1108560/#)E\1018205z\SYN\1090732\DC4\DC3\ESCS\EMo\178559U\tK\1086792\68062`\SOH6\54457\170975\1103293\127213:D\17530\54419\1017949\&7\171785y\1048490/S\NAKz\EOT}7HRV\1109054\1085537.FQ\1004585\64185\1106633\66592a;\1055002\1033858\ETBA\46470\1078667\n\70291\144315V\156365\1045649S\RS\bS%\1037382S^d\EM\b\1001776.gd\GS1!(\DC2(DE\184742\DC4\995808\1107107@\1048351m\1041999F=\DC4\986846\83184\22080aAp\136773\NAKf\1014163\989717C\23448\131724\1073590(@\CAN-\140976\68640\&4/]\1000419\GS\1085981\&9/E\150573<\133245`\21020#L\DC2\EOT2J\t\SIj@w\ETB9OoyN\DC1\ENQ\26865[d\1081420\1096723\FS\1038391F[\SOH\DC2\146772uE\1009102H2\20167H%5]\b\167790\\\SO\DC38N\62366r\EMe\acE\1101700S\SI\1075974\nt\fI\83105{\1020892.E*\163162z\110969#]z\1316\&6GM\b\1037989lb\b\t|RJ\DC3\1035777\1064843\169562|^\"E\EOTmc\1027583\64586\DC2@\1100891\b\1005566\1068304\998796\ax2w\DEL\30195\1059722\1110921\ACKO\1082461\1029952\NAKfp\ACKS,P&\CANVw\USqI^:\SO46m\68761rJyi\8091=D\1104645&\SYNUij\1058019\CANvi\"f\fX|\ACK\1018942A\48140\1083022\1043067YE\DC3\SOoh\145212\1088596\f\44657u&%\ACKv\101105k#\1108474`\1076522\f{\SO,\t\CAN\ETX= \1093724 ?\1068395\DC1\SO\167150\&7U\32304Y\FS\1072260\156532\176131g\SYNs5B&\SYN\f\NUL\EM\177193\ENQ\US\1040385+L\DC2iE^.\1111352|l\SOHb]i(h" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByScim - } - -testObject_NewUser_user_10 :: NewUser -testObject_NewUser_user_10 = - NewUser - { newUserDisplayName = - Name - { fromName = - "nz\ETXZ\CAN4>\1029814\190555ocxZ'ngJn,u\155624\1017945.\1013797\DC3c\EMG\1036614\1050144 \1018072t=\\|>@bc\1056933\3897\\\182097*#\1004444\NAKEuR\"\133815\US~'\EOT\46779(A8m\1092697\131539F._\1086413\SO\SI~3.\RS\132761\1094333\DC1o\DEL\aS@4\DC1VT_k\1071840\137558D\DLE:\12462>U\11281\989076YkzU\1018004\172591uejP\1069374\7378\986798\DELn\ENQ\CAN9~f&" - }, - newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = - Just (SSOIdentity (UserScimExternalId "\n\STX") Nothing (Just (Phone {fromPhone = "+97450398211"}))), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = [], - newUserAccentId = Just (ColourId {fromColourId = -2576}), - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("Ofo=")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("g5W5rIJFTLUrJkd9j9W3BzbyLEnW")))}), - newUserOrigin = - Just - ( NewUserOriginTeamUser - (NewTeamMemberSSO (Id (fromJust (UUID.fromString "00003fd3-0000-6075-0000-09cc00002b7a")))) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = ""}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.SR, lCountry = Just (Country {fromCountry = CO})}), - newUserPassword = - Just - ( PlainTextPassword - "g]:\1018228\147738\NUL\1072954\CANL\1081335\GS`L+i\9363,&Y\NUL*\ETB3En5C\RSI(\NAK\143207=\a&B\1008147c\vj\NAKC5\FS*\143391\36838h2\988019(\31555\990993\&6r\DC2\DLEQ\137143m{\1099384\178081Y#\1029034L\ETX\51506\7090\1081898\32626\183117l'7/\31432\NAKR\SOHT#InO:F|j\US+<\t}j`6\92250wl\DC4-a]\1033485 O(\ETBX\984652?!\177845\DC2,Q\1009349\69773\FSO\20790\1005567{+\DC1\NAK\DC2\45601\flk\ESC5u\1048485{B\vg\ETB\44152\NAK+\1091805\1082527\\*mUn$\DC2m\1106217\131352\35492\&03\1059109\996291\139527\&2\DLEBE\SOk\166992b\1024979{\128262jv\1015451_\3961\1049226\60155?/V!YoY\1038377\ENQ7P\1053628(nf\1087594+\FS\STX/\DLE\7114;\1061175\DLEf\175191_Qsvt}DFm\DC3_\1083208\f\a_;\59884=E,6|cAH\a\6402\68130y&\184374\168795\25974\ETBo\b\SUB8/=!\SUB\24280\EMGD9+\999661'y\13222\SO\DLE\SYN\DC3\NULZ5\ETB\27546\DLE\SOHsMf5KAO\ETB{J \a\44984\142292]g|\DC4\1016043,4\DC2\137758\98702\11389\&3\1101728az\13963e}\156069\EM1\65465Or\1105620\1091998\1067761v\NAK" (Just AssetComplete)), - (ImageAsset "Z\SOH\72857/\SO\28423s\\H\EOTE{\r" (Just AssetPreview)), - (ImageAsset "eb\25344o\1025305\CAN\b\1018499\SI\995488n," (Just AssetComplete)), - (ImageAsset "LH\1059755\EM\NUL" (Nothing)), - (ImageAsset "W\46312B}\1056938\1082969](\99087I\1045191" (Just AssetPreview)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "\FSHb<\162081\1068855Z\\" (Just AssetPreview)), - (ImageAsset "\GS\f\US\95832\"\1066625+" (Just AssetComplete)), - (ImageAsset "5\1038310" (Nothing)), - (ImageAsset "\168685j\SUB\21288\1005667\1043496\1034542\CAN\vN^\147572n" (Just AssetPreview)), - (ImageAsset "X8&r" (Just AssetComplete)), - (ImageAsset "H\184627awc\DELA\1069712\&3/" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 20313}), - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("GBV8H4iTzUI=")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("DjbUAo-oR5c59MDxSrR2TA==")))}), - newUserOrigin = - Just - ( NewUserOriginInvitationCode - (InvitationCode {fromInvitationCode = (fromRight undefined (validate ("hYCkzvFW6QzlqvDBJwPh")))}) - ), - newUserLabel = - Just (CookieLabel {cookieLabelText = "\992217\999846\1085439\SYNu\SO4M\10098\rS\1093686o<9wHa\23265pxst"}), - newUserLocale = Nothing, - newUserPassword = - Just - ( PlainTextPassword - "Z\62152Jg\167486\142606\158743uY\DC3~gq\1015435\EM\45450n*\DC3jE\ENQ\STXGUQ\STX\CAN\120562(/\a6%FD\1076127|]\f\FS\1000881\989197F3e\148090\r\159326h4\NUL%]\66721,c2S\95053h\142399\174158\ENQ_\1076170_\20559\nQ\DC2fHy_\EMpB\1095370E\DLE%\f\"\1108839*Y-\DC21\175061o=4A<4\1108943&t]\1036846kDM\DC2\61414Q[\985741\RS -yq|\156679zIt_\DC2mRT9\1012059$l\1056258\SO`MQ\77905\1051266_\ENQk~N\167077h_\EOTo\1098570Ub\EM\a_\SI\1012786f6'XKDLq\1043985\&8\1095647\61921\NUL`\994308\DEL\ENQkQ6Gf\FS\1016438\DC2\1064620\NAK$8r\136852u\183590b 2\1029223\SYN\153017}A\SOHY\1034463S\1007690#\ETX\SOH(u\\\163441T\SUB!\1058033h\DC20Xx'\132409!\NAK\DLEA9%\ENQ\DC2p\151481\181687\1008617%S@@\59016!d\13014=l\EM$@% h\92260@6;U\1046710@1b\1066220?g;s{'\168073*v\1003595{+.\9515Q\132528u\9480:Vg4]:\138468\&5\FSz4\32015\1110508\31687\991048\&2!x3J\1048020Sd#X\NULx\DELJ\1070285O5\f\146902f\EM\bA\fU\159778$\STXC\1016855\SOL\GS\US\DC4.12\158083\DC1\153984\195026eA\STX\nX\1044171\USW?\CAN\1064050pSCi0\36595\23764^\SYN(\GS\49118\DC4\1087107\SYN\ETB\1027341\bZ\10490\&13d\1025117S\1080777\&7\97003\996022*LQ\186591nS\SUB\ETXL\ENQv\b(\1070909S\70743\SUB\1016069)BT\170425\DC29\ETB;\178760\134408'\1048016&\21025\1022557\CANd\1082274J\1099355ZdoMR+~<\191335laS\73444l\1031779\r\166749:\1102447\60092f>Fe\1076015i\SYNV/L@\1043545e\1017778\&7\SOHv\DC19\1025751!L\DLEX%\GSjx\61605\CAN\1076090\SYN]w7W\SOH+\1029832E\DC4:\28199\156994\5439\CAN\r\SI\ENQ\16339\RS\SYNXb1\DC2Et\188031\13695Ez\1051017\USo\DLE\1023562\19199\175912e\190441\&8\SYN\CAN\1008838{\NUL\18622jF\ETB,\1111678\190629\178374U\t\1105212Ku\1101900I?\119101p\US\ACK\63584MS*\157356\138620\39752\983333 \1061680\1671\1026251\146337\aU?\190046V^\ACK/:l-.Uzz\SYN\tm#\1065339XcY*\1104092\f\1063451+\US\100984Y\994009\&7\DLE\SOHrL<+K\1058219\1107452\1015133$e\6558(A\FS\n" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Nothing - } - -testObject_NewUser_user_13 :: NewUser -testObject_NewUser_user_13 = - NewUser - { newUserDisplayName = - Name - { fromName = - "\1104031mx0D\41340\1061121\1002725\DC2\a\bW\DC1PY\n\153502A_\154481jiL\NAK\1043244;~_\DC1y|\SIp\EM=\EM\148317\164702K\EM\bVV\ETXl\SOHp\1002077V\DC1\179321\&0`xPp:d\1074886\ETX\1008945\SI\1067394Kb\992920\1029412\f\141426k\1110100\162484+\DC4\ac\188651\188058G\110929\rC0;gKQ\30166:Sl\NUL\SUB\SOH\FS\DC2T\60299Bm$\GSO\NAKBRw\21414\CAN\1019564\15840" - }, - newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = Nothing, - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = [], - newUserAccentId = Just (ColourId {fromColourId = -32104}), - newUserEmailCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("8XW3_eppEXD038Pz14guN-pLnL6rR1538NZxVA=="))) - } - ), - newUserPhoneCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("byyj1Wn5lFbsGpe3VZ7pERkfpOujdm5UzTIy2ok="))) - } - ), - newUserOrigin = - Just - ( NewUserOriginTeamUser - ( NewTeamCreator - ( BindingNewTeamUser - { bnuTeam = - BindingNewTeam - ( NewTeam - { _newTeamName = - ( unsafeRange - ("[3Y\RSF$r9,/1\DC4\51722*\24329\DC1\1091933\34031I]\f#\CAN\EMITc\160631\1010777\1054846\ESC#\t\1042500ic\bU\1058195\SYN'\1113521\35874\&0xC\1045798\ESC\156725\&1U\48911'\DEL\165612/\vV<^zu\EM\ETX\ESC>\174231\95943A") - ), - _newTeamMembers = Nothing - } - ), - bnuCurrency = Just VEF - } - ) - ) - ), - newUserLabel = - Just (CookieLabel {cookieLabelText = "^\DLE\1091089\1018879\t\147176\&6Th\99794\1105207IW\b\DC4>\1051877u\f9\DLEU\120276W8/;[f1\CAN3.\70062Fw1\b\SO=\1048027Q\EMlgZPCjAFm\186637\&3X\ETX\DEL&\1026815\ENQu\1054670\92320\1082565\1001577CT!+st#%\994498'W1~\RSD\1027704h\146538\16295\\\FS\1101888C\98469R_(\b\132607&>\RS;H@v_\20372\1045195Hg+m\1005562w`\1107567\"\1077448B106Q\988463X\180875\1034341\165415\1012684P\DC41\42060X\1058472\1018704?VD\160350\18122\SOHii\1072326\EOTnD\16918S1\66439\v}\1099142\54994>?\169978T=\n\CANBAi\30089\169825\f,&=\1029383g\1027278f9\"\1052460\NAKpe\985368\ETB\1112751\156981\1019142\183563,\NULj\149084\&1\18217I\1012358[<*S]<7o\7684\1039271d\46743\1061911\&6y7\47520\SIEeE.S:_$LBG\155423*ci5\20438PFl\174281\DC4E0b\STX\12809/;\28506p\DC1\69242\23111;m\b\DC2P@YBve\b\EOT\1052122v_6/\DEL\8574\\op\39368H$0\1029769\EM$Y\aP\1092884\1030008*\EOTfj{\DC2'3*\64962v\146042UW\SOHm\1054837\16901i\ETB\b\26410!S`w\ACKhJ\b\1005244/Deu\181312\1075594\CANz[" - ), - newUserExpiresIn = Just (unsafeRange (143078)), - newUserManagedBy = Nothing - } - -testObject_NewUser_user_15 :: NewUser -testObject_NewUser_user_15 = - NewUser - { newUserDisplayName = - Name - { fromName = - ")\SYNV%9X,%\153866\RSX:\SI\tEt\1039185C\58466{\SYN\SO\186803X)!ns\NUL8Pf>P\DELW1Il@Koo\1074032\EM;\984619H7\t|],C!lf~_\1002300U!\1096857\1013210!\FS\DC2s;\DLE \170551\1017226\168711\US\RS&[\NAK\a\DC2\993754S'W\DC3.~\SO\1062156\1013546Q\68444FFxnmcy\EOTLxr\7126`:\1014165] x\7030\DC3\36172% =\NAK\f6S\GS\1027285p!\a\135857(;!$\SI]\US`5\DC2\1023998\1090553\1073462}9=O\137704\1005594(I\CAN\EM\CAN\188480\1040031]'\22874\DC2\1105670\1083882@R\SUB\NAK\99642\&3\59901\&26\ACK\1105828sy\157383\63920Kp\ACKB~M\1035845\1054255ty0pJK\STXzv eWY\1100908v\ESCG\CAN=\1008262\DLE[TZ\1068423\178016\991067`\95931\ESC\1046608d\EM\b\RSd~\EM\1016209\185831\29201L\t,A\133192\SI))Z\ETB{\137969A?\NAK%hS+\150348\5388_\148122:dR,j\141055(_'j{O\133201\\X\1010345S\1049262wTD\1033443\160414R\23522\DC1\DC1\1099627:L\1085899p>\DC3\23704\1028087\NUL\1020105\1078456A\1089417\"g+PD\SOHtk?N\1013241\52065\170977_AdL2\1016996./b\ESC\t)\FS\FS7:\ETB\1025682P\aGEwk\1093215-)\DC3p0\nUG\ENQPV=\40816\EOTM\1066630_js\ETX$2^YaP\1039158\20719H@j\18424r\188903Y\DC2*u\166575\1019772-\163220\FSf~ZI[5\t\ACK\178865\986816\144912EH\137316J\8650Tun\1088202\ACKuO:`(0\161605\987465]_\999266\1005299\t\STX\r\40097v\169184o\1073608\1040194h\1005053\1112894\146105! \n\SYN'J.\1029280\995990\v4\r{\NAK\NAKbPQ~\1092014\&3\US\1078011<\988690o`q J\48946]c\"\1006277\v\1024510Q\1048094\149009\989881\36552N>;}\GS=TO\US 6\GS\SUBWy8CZN\46163I\SO\1108285\28058P\45187I7l?\b\DEL3\STXv\13853\15753\RS\1094576\SO\\\1104977\ne\46874\160230\&0mS\CAN\1020423\157180ng\1094315xTt/\50705Id}b\36346\141394v\ENQ|;C\2360Z\67294\v&C\SOE9O5\ESC\1092158w*}\EMQ\178541\ACK\1076279\149460\1045852w~\83091\&7TL_\nH\1058057$\110864\1080351\ENQUPQJ\15524\RSS\1067353\r$\CANU\1036973wT~:\49728/\128381`&\137102(\176521\vn\DLE1\142173\SO\1050330)M\993353\1071867<'=d\DC1G\166805\b;\ETX8g,;\189792Z\1025221\DC1\991266{trA\178621\&5Xe.\142518,'R\SUB\32889N\1050084\149070\136431\1061037\1000339\ETBmW\1094041\ETX\t\1011082dQ\97197d]#\EME;\132675Y1\NUL\1029979\SUB\RS\1048292\10876\a3\146447\n\45281\1010335a\141069s\ENQLZl8Dq\ETB3Vp5\"\t\EOT\1011270n~\1012295\1111143HD-\1039481\983889\180948\ACKuQj\1078022\FSx\31208\ESC\t$O\v\989459BI#4\997454\\\1075613\1051318/D\ESC\1085849pX\1001950f]%S2\120271z" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByScim - } - -testObject_NewUser_user_16 :: NewUser -testObject_NewUser_user_16 = - NewUser - { newUserDisplayName = - Name - { fromName = - "\STXnH\917551\DC3\1069710\DEL\DC4\n\149984\1024736\149590\EM`I~Q{\\:\994054\DC3H\GSem\1058165!\1004899\r\SI\DC1B\1090802i\GS\NAK\ESCY\161298\1050465\36573G\169606UOB*Q\GS]M\SYN" - }, - newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = - Just - ( EmailIdentity - ( Email - { emailLocal = "R\138103\51554\1093578\nTAS5z|q\64031z}\12959;\ETB8\DLE", - emailDomain = "\66578\131096ZBqrtK\ft\1051009h\b8iU.&" - } - ) - ), - newUserPict = Nothing, - newUserAssets = - [ (ImageAsset "\DC3\1047857\ACK!FC" (Just AssetPreview)), - (ImageAsset "f{\ENQ" (Just AssetPreview)), - (ImageAsset "Hl\SO\n8\ENQ~\EM\1096241B" (Just AssetComplete)), - (ImageAsset "\1109662m\6286\165081x\DC14c\9896o%:" (Just AssetComplete)), - (ImageAsset "\\57FFJ\1066532\&8F" (Just AssetComplete)), - (ImageAsset "\984281\DC3" (Nothing)), - (ImageAsset "(E\21704hxM\"_" (Just AssetPreview)), - (ImageAsset "\SYNQ\SI7z.zs\68119Z" (Just AssetPreview)), - (ImageAsset "\DEL~$" (Nothing)), - (ImageAsset "h\ENQR\1003331\133393w]sc\1029711\51538\DC1`!" (Just AssetComplete)), - (ImageAsset "p\SI\173440" (Just AssetComplete)), - (ImageAsset "s,\1061760#\US" (Nothing)), - (ImageAsset "I(" (Just AssetPreview)), - (ImageAsset "\STX7\f" (Nothing)), - (ImageAsset "\ETB\1087559\12770\147491\995554#2{6Gwz" (Just AssetPreview)), - (ImageAsset "\\\1047650\&8n[m\119169\92305\1027086L\168740\SYNY\7424'" (Just AssetComplete)), - (ImageAsset "\NUL/dn\DLE" (Just AssetPreview)), - (ImageAsset "\1046223\159089\&8i\SUB" (Just AssetComplete)), - (ImageAsset "9=3i=5\CAN\DC1" (Nothing)), - (ImageAsset "$\NULe\998875\DLEP\SInN" (Nothing)), - (ImageAsset "#\SI${q4]s]\1032167\1089192" (Nothing)), - (ImageAsset "Z\129445\62976\8937\127944\ENQ0F\178204(" (Nothing)), - (ImageAsset "\1048007v5\997299'" (Just AssetPreview)), - (ImageAsset "3\b\US\988616\156638\1003003\CAN\SOH?\176124\SOH" (Just AssetPreview)), - (ImageAsset "rZ\133817l\186667k\153956\v\1088523\32361Jt\GS" (Just AssetComplete)), - (ImageAsset "2\137752-" (Just AssetComplete)) - ], - newUserAccentId = Nothing, - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("sQZw_A==")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("5dy6ya1yHl7TyDF03xClFXFT")))}), - newUserOrigin = - Just - ( NewUserOriginInvitationCode - (InvitationCode {fromInvitationCode = (fromRight undefined (validate ("krEHX0N2tg==")))}) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = "\163041\2569\ESC`c&\159184\52923\&9b\t"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.XH, lCountry = Just (Country {fromCountry = TM})}), - newUserPassword = Nothing, - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByScim - } - -testObject_NewUser_user_17 :: NewUser -testObject_NewUser_user_17 = - NewUser - { newUserDisplayName = - Name - { fromName = - "\61160A6\DC3\169031\167858O\SODu5C\1012451\SYN\1039893K3R\92574\1014127\GSl\1033424\tl\aRm-\1011199\SOH\92715&z\23438\&8\1077050Ho\155446,3\50868s" - }, - newUserUUID = Nothing, - newUserIdentity = Just (PhoneIdentity (Phone {fromPhone = "+479088519197"})), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "\1054929\1104670\1026527)D\1091434N\1099702?" (Just AssetComplete)), - (ImageAsset "\1077899\&6;o\DC4\t\\\DC1\\\1078560\15754`R" (Nothing)), - (ImageAsset "''@\ETBK\EMi*YcomF.\EOT" (Just AssetPreview)), - (ImageAsset "$VX\US\ETBM:)f/" (Just AssetPreview)), - (ImageAsset "\SUB\997723lkaU\FSy\1011749s" (Just AssetPreview)), - (ImageAsset "$}\DC4W)\EM\127827\&3s" (Just AssetPreview)), - (ImageAsset "w`\53952\SI\1022516\SYN]P>J" (Just AssetPreview)), - (ImageAsset "\v=d\1040737\172335\GS2\1062889uw\1105836\151923f~\1037461\GS\a\999352\1004166'1\61759Yr\1048156\&7\176345\16625\39794y]\141545~/\53208$\1002235u5JF\1015936\a\SI<\SYNn\US/\\\t\132648k\NAK7]d>?i\ETX\1079984,=Hok$q\179503\\=L:\74103\1071169*\94473*\1095220F\DEL\1021524Hk\SOHjPPsA\SOH/c\991892]\NUL}|V7N\1041408\&7C_\DC3\1075503{B;E2t\NAK\b\SIoK\1006676\1091220\b\5871\13831HQ#\147700\1084819$u7\b\41070JMT>\1009303\DC2*R\996626?p\DLE1E\152416\1011076k\1066801B;\ETBSg;O:\SOyW~\fb \1076060W\SUB \186267%PU2o\t{Q\RSc&r\94999%V\995230\49332\988585d\USb}`M\175893dw@\1042638\43126\&9eI\3675\1015082|BRW\NUL\1076495ug\1002412#\GS1\1038683O|\7031\RS\EMD\DLE\1051128\&9\1007082*\172813O\159804\1068311\SUBUi;\ETX\24515>\SO7{C\29717I\181664vg5\64555_5m~\DC4e\23254\DC2\1047386\151177\&0Cz5k\SYN\134623\CAN\48946\GS>\SUB:?#U\1091370\&0\73766\STX>=z\US\993438\99576w\2219\ETXC\1079716\STX7\DC4\177545\\ e\47716e(oT" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByScim - } - -testObject_NewUser_user_18 :: NewUser -testObject_NewUser_user_18 = - NewUser - { newUserDisplayName = - Name - { fromName = - "\\`O\DEL7\74892\1030387g\1059572\&2*a'\RS;x v\1005139j\NUL\19731\RS\NAKE\1057705\1021874G!bB\1081174\140812\1112673\"t\1092069\SI.\1083842|\ESC\95004]R\67340O\985926\ETBF\99416\27860d\1015517yLN\19551\DLE&\54976I\EOT\NULT'>>\ag-'|\43335\ACK\34086\v" - }, - newUserUUID = (Just . toUUID) (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - newUserIdentity = Nothing, - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = [(ImageAsset "," (Just AssetComplete)), (ImageAsset "&vJ`!R\tVt-=i" (Just AssetPreview))], - newUserAccentId = Nothing, - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("_Q==")))}), - newUserPhoneCode = Nothing, - newUserOrigin = Nothing, - newUserLabel = Just (CookieLabel {cookieLabelText = "V]#X\1032904\DC3n\1063400\1003348u&HV\f\STX:Ah. 9\n\NUL"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.QU, lCountry = Just (Country {fromCountry = PF})}), - newUserPassword = - Just - ( PlainTextPassword - ",S\162755\EOT\8179\FS*R\vlulO\14862\1025289\987140]\ENQy:\14338M?\1026893X\67856l%@\EOT\"4\1061926(\SOH\n-\1044517\SUB]\139031\v\\\DC1gJ\131484\49582\126218G(&\DC4\DC11\1053916@\EOT\DC4ze\ETB\ETB\NAK:\a*!x5\NULJ\SI>F\FSS>P]\142082|kLmi\DC2*[\9166e\b\NAK\1033976n\1007275p&<2j\v\SOHFZQY\ETB>@uin\DLEcu3\EM%\992833\t-\b\EM/mpW\US@Hb7:\DC3\FS\1107373\f`4zI\1006025y|\US0\EM5y\29897\NAK\180671\RS\160277\t5O\SO\186958\183326{>\1102241\65137\49102~\177218\33079gt\1031163P\SUBqY\r[OO!\1075718#\1006437O\1110156_'v5O\140774\v\72116#]\"I-\131103a\177542:q\17695\57410\41154KK\1061305au/b \t.\aK\1012871N\CAN\1046730\1011543\v\42946l\STXu\NULPiW.u\92280\GS\DC1*\41138YT\183835\68013+\5361\DC2~dZY\"p\EMI\t\38314\RS\30714{\ACK@D\DEL\132232\1058646V\t37\17626\145793,c\1095316\5436\142927\b\SYN?\41011\1037726\SYN\1002654-\1098559\1026435?\ACK\1105385o\171317+\147332\&4US\1053703\1049642\f7\59941/\1030735\&2\95551\ACK|6&\1074134\DLEu\1025878\&0+1M" - ), - newUserExpiresIn = Just (unsafeRange (228513)), - newUserManagedBy = Just ManagedByWire - } - -testObject_NewUser_user_19 :: NewUser -testObject_NewUser_user_19 = - NewUser - { newUserDisplayName = - Name - { fromName = - "=5^QR$\DC2i\42477\150812\DC1\1004643\DEL\ESC\190504#\1071209m\EOT\1007557\125001+\FSa\SYN\1054267\28292T-" - }, - newUserUUID = Nothing, - newUserIdentity = - Just - ( EmailIdentity - ( Email - { emailLocal = "\1002663\1023766\128722U+\SUB\1081252]x\1001382Rz\EOTp\1076639U\1045413", - emailDomain = "5\153285\n>\DC4l\a\6936\1090901\NAKU\1037714\133475\&3tj\SOHDnWz\1054252\NAK\1104563" - } - ) - ), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset "\f\ESC1," (Just AssetPreview)), - (ImageAsset "\171534H\SOHp\SI>6" (Nothing)), - (ImageAsset "W\33286fj\120501xa\SI" (Nothing)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "7\32647#.E\\\64198i/9." (Just AssetComplete)), - (ImageAsset "\\!A" (Just AssetComplete)), - (ImageAsset "\1037883+U\US\67867Pp^" (Just AssetPreview)), - (ImageAsset "\DC1\1085335\RS\984435Q\\2\62427\SI`{\157793W\1103222" (Just AssetComplete)), - (ImageAsset "\ETBv8\CAN\170565X8q\STX\917839V" (Nothing)), - (ImageAsset "\139296}M\133376\ESC\1107091l\STXKu,A" (Just AssetComplete)), - (ImageAsset "1\n\144038-J\ETB" (Just AssetComplete)), - (ImageAsset "d1\143274" (Nothing)), - (ImageAsset "\ETB%1\1032500@`f\ACK %" (Nothing)), - (ImageAsset "\ENQl;w" (Just AssetComplete)), - (ImageAsset "0\1046603\162989m\123209Z\USr-" (Just AssetPreview)), - (ImageAsset ">%?]V\1064825q\50565\STX\DC3\158734" (Just AssetComplete)), - (ImageAsset "EE,t5\29843\fJ-t\989684Ft" (Nothing)), - (ImageAsset "\40430u5\23361\&3" (Just AssetPreview)), - (ImageAsset "" (Nothing)), - (ImageAsset "x\DC4\98335" (Just AssetComplete)), - (ImageAsset "l\RSC\1046285\ENQ\USO\\" (Just AssetPreview)), - (ImageAsset "\SO\26416>G\STX\148093\t" (Just AssetPreview)), - (ImageAsset ">F{^s\1097049\ETB" (Just AssetComplete)), - (ImageAsset "\1075178\&0\5126V3:l'ZuA\1009745s" (Just AssetComplete)), - (ImageAsset ";\US3A\aZ\t\1003327\US\ACKnv\30386;4" (Nothing)), - (ImageAsset "?b)`\68768-c\"\1081739\1090806T" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 28218}), - newUserEmailCode = Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("xW2K")))}), - newUserPhoneCode = - Just (ActivationCode {fromActivationCode = (fromRight undefined (validate ("zRaFKSA7mqei2mjV9w9ON4OLeA==")))}), - newUserOrigin = Nothing, - newUserLabel = Just (CookieLabel {cookieLabelText = "\ACK\b>\1104851\1032167\&73]\26491\&7\1038541&H\\"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.PI, lCountry = Just (Country {fromCountry = CC})}), - newUserPassword = - Just - ( PlainTextPassword - "\f\1011458\ESC\DC1U\1019586\a[Zn |\168315>\ETX\34802\174434\1062058Qq0U7\ESC*e\DC4@[)#\1051903&N-N\1073340J\178288\ACK<\v5>^\EM3\154126\128031M\"Q@_7Y\100429oO\a#x\ESC\61952sU8\ETBf\1067818\100695{ \r&\1083878@\32221'<,X\170604<\SOH\18146>\1010935DP\v!\45479[\1043752\RS\1065218\1001951+&\US{\181954\996815t=Dm\1103746\DELB\1011315t\173322\DLE\fs\ETX`O\b\ACK\10449\DEL:\1016437\n\61531\1061309HXJ~\GS\RS\184012d\183399\1020466\1047778F\1040664&F\a\EOT\1096533H]\NUL*\1080800\a]\1048204V!\FS\9466EyK1\181677\STXv\181963)f\SUB\1103910)#F\1071338:\151005\US Nw\1014336\189368\EOT\1041803\ACKV\RS@k\ETB.\98432F\9782B\ETX\t\99778 SF\180278oy\1079977)\23126\f\fM\40361\54321zw\US_I8j\38042\"\1110702\EOT}\27728m~\12526oea32?\35546d$\EOT\n5\frGK?\35502c\151118\ETBSi\24371]\t\1068362\&1c{:_e'S\DC4\thf\NULG\3375!\bsjmf\EOT\DC3\999255f^\DC1Z]A\1024298\"\48934\1089423p\187852\174541\144201Ax\1064425O\DC4W;\RS\32955H\155553Y\"E\1097133\150775F/H8cV3\SI1A\CAN\DC4\EMi&EZ3Ka7s\1048354yB4\187660\178995MXSQ9\144686\185815q2\t\1051221H\146701g\1012819\1000535(\SOH'\US\147010\151299\EMeg\ENQ,\984983\DC4dF-DnZ;\DLEjz\123200.m~o\n\SUB\1038174~y\1088606\ENQs\GS\vX|}J\STX\NAK$K\v[W6\50762C\1077712C\1019116KA\DLEmL3*\ENQ;C\188594\SUBz\DC1\ACK|\11966%e^\1105640\178046\vr\1003085\DLE`\27889~\1050896R!*\1014406g%P2\184356\180675ugo\54685\SUB\96736\1013445\1105941\SUB\DC3" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Nothing - } - -testObject_NewUser_user_20 :: NewUser -testObject_NewUser_user_20 = - NewUser - { newUserDisplayName = - Name - { fromName = - "\b\1026020z\toeq\1078553}i\STX*RI/B(\SYNjS/L\160185n2\DLEMA\64373\&0\r\173546jS\a\RSt\SYN\143284\&5:*6\173385\GS]\ESC\1052230)\DEL][F\1079027)\ETBu{ \177248mC\GSI\997169vp\GS*\8113F]\DEL.\SOH)\SI\96149\DELp\SO\38583!B!N3'e\38472\1013749\&2\v.3t*IW%\SOc" - }, - newUserUUID = Nothing, - newUserIdentity = Just (PhoneIdentity (Phone {fromPhone = "+60997378240829"})), - newUserPict = Just (Pict {fromPict = []}), - newUserAssets = - [ (ImageAsset " })$" (Just AssetComplete)), - (ImageAsset "=(@S\SUBf4#" (Just AssetPreview)), - (ImageAsset "[P\DEL\1022912\NAKX\1043109\22691\&86!Lg" (Just AssetComplete)), - (ImageAsset "\999657\&1\1046647u`\171370\"&ea\1047833\156776" (Nothing)), - (ImageAsset "\1091622D<\1046398>cc\EOT'" (Nothing)), - (ImageAsset "" (Nothing)), - (ImageAsset "r\RS\1072457\SOR\69997b\985779$#\141996R" (Just AssetPreview)), - (ImageAsset "=\992981N'7I\1046634\SI%" (Just AssetComplete)), - (ImageAsset "X<#$\NUL0\154109\1071362*\1019195" (Just AssetPreview)), - (ImageAsset "D\4854\FSi{" (Nothing)), - (ImageAsset "5p\7627" (Just AssetComplete)), - (ImageAsset "j\SUBG0\1036603\SId\189736:\588" (Just AssetComplete)), - (ImageAsset "5H\RS\1076088;" (Just AssetComplete)) - ], - newUserAccentId = Just (ColourId {fromColourId = 13678}), - newUserEmailCode = - Just - ( ActivationCode - { fromActivationCode = (fromRight undefined (validate ("v2-GQHZFYfDD7eV7gj3dtTZ2RDAqMLpBntdMHg=="))) - } - ), - newUserPhoneCode = Nothing, - newUserOrigin = - Just - ( NewUserOriginInvitationCode - ( InvitationCode - { fromInvitationCode = (fromRight undefined (validate ("529Eo7BC6CKbsX0i9lKIvOFyuxhHig=="))) - } - ) - ), - newUserLabel = Just (CookieLabel {cookieLabelText = "#+EA\58647\&7"}), - newUserLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.KW, lCountry = Just (Country {fromCountry = LU})}), - newUserPassword = - Just - ( PlainTextPassword - "\1005402A\37244\&9\65240 \SYN\1004548]\1074459=\1064969i0\1014470.\v.)_$QYz\1007772s\168133\163502\1002041,f\97688M7\2848\1071977m\63578c\DELO\SOH\f\STX\1003747DQ\fE\62031q={\DLEd\993185\133714\RSz\\\190730\&5.F\EMi<\33839\SIP$\SOi|d,J.\1874\t\SUB\1086095]UA`*\fh\v\STX@K.z\r=\169532\"TG\DC2=X\NULW\1096670x\NULV\77882;\156947}{hRc\b\DC20\1088407:\158813\ACK$6n\78702\1066848\16675\1067648\&6^z{]\t\1111148\36618#W;\FSsp\1063273t\1084107\1039785\n\SO\21412\1034914\100883\993989\168903TW\159567k\997815,J\\!\1089960\989008bs\FS\CANe\989036\186142=\NUL\t\STX\NULs)A\ACK+6z\145155=\SI\a]5\CAN1[O=.\DEL ,\DC3RF\NUL\57649\1029240\125001>\SOHkc5Tvp4'u\177927\SI\128449Y\43223\DC3$\DC4q\20124I8\38402GJ\146945\&6\SUB\DC2\185263<\6278i\175986\1082957XR[G\EOT:\DC1\"\41646\1001574\b$\110872\10362\1013074\SUB\1060318Ga\983903\994043\a6\NUL\166918\"M\CANUz\FS\1112779\SO \DC1\1010755=\EM\52307\GS X?p\SOH]3V\1085215l[ts;P\48909ye\1088437\SI\20936]\1072813\DC4|\1091546>\987019p\987993\166701\136651N<{t\185021\1094830}\28304\t0&\FSuz\CANm\33912\1069311\996754q~S\ETX}KsYVN\t\r8pZ$.p#\25882Qad5\194726\178938n<\1027094\1107931o!\1069932\170881\DC2;?Y\NAK:\DC29{}'\DC38\83222\ETXc\150396\EM\a3aQ~\tl&\\8`\SUB\RS,\31740\EOT\1035767\1001486\46257s\1035518\1001306e\1096342\995856J{`;]\1056856\181520\&2u\12276\1026030\RSsS\1092881x\40261\1098657%z\83035\DLE\1112046N\DC1tSL8]\ACKYi\42440\FSz\n\US\CAN\ETB\ETB'\40035OH\994540M}<\34537\1019547\1056779a\v&$k\172876WP\1048522\CAN\99008\&4oRjU\"\ENQ\1087854\1025289#C\135510'~\1059995\1074987\&3\ETXC\1056389(.T\CANi\DLEw\6262\164158Rp" - ), - newUserExpiresIn = Nothing, - newUserManagedBy = Just ManagedByScim + ( emptyNewUser + (Name {fromName = "test name"}) + ) + { newUserOrigin = Just (NewUserOriginTeamUser (NewTeamMember inv_code)), + newUserIdentity = Just (PhoneIdentity (Phone "+12345678")), + newUserPassword = Just (PlainTextPassword "123456") } diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/UserConnectionList_user.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/UserConnectionList_user.hs index 799afb99489..82d7d9fbce4 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/UserConnectionList_user.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generated/UserConnectionList_user.hs @@ -21,19 +21,10 @@ module Test.Wire.API.Golden.Generated.UserConnectionList_user where import Data.Id (Id (Id)) import Data.Json.Util (readUTCTimeMillis) import qualified Data.UUID as UUID (fromString) -import Imports (Bool (False, True), Maybe (Just, Nothing), fromJust) +import Imports (Bool (..), Maybe (..), fromJust) import Wire.API.Connection - ( Message (Message, messageText), - Relation (Accepted, Pending), - UserConnection - ( UserConnection, - ucConvId, - ucFrom, - ucLastUpdate, - ucMessage, - ucStatus, - ucTo - ), + ( Relation (..), + UserConnection (..), UserConnectionList (..), ) @@ -46,13 +37,6 @@ testObject_UserConnectionList_user_1 = ucTo = Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000")), ucStatus = Pending, ucLastUpdate = fromJust (readUTCTimeMillis "1864-05-09T06:44:37.367Z"), - ucMessage = - Just - ( Message - { messageText = - "\CAN\DEL8\STX\1035092-\1004074z.a&Kho\1002576\1027966}9nF\173234\1056412l\DC4q}\SUB\ETB\1024717m8#\39185A\1099890\1051825}Z\52677\&6r-/D*\USL\1024293\1113794D\1074633\EM\1023212\41115%PZ5\1069612\\}\54494\SI\60922\5521`\1009755'1x\DELNcFhN|*\986465\DLE\t\29903\1024334\&6\DC2/IK\SO\1053777\1017375s\147291\EMBM\60429*a\1036814~j\v#\DC1-D\186618\98625\ENQ7{\189669N\ETBC!~\128543EGS=\ENQ\1000128\SI\1013327\2908b\1018074'K1\NULE\58916\STX\163444J1\NULAI%\53820QV&Z`O\EM~Vu6t\"\1018406_I}a\1031578\&5\1009784Y#\ETB:U\140341\a\1033389\&29^2t\1073180\51546dC\95215\ENQ\EOT\FS,\"5.9;@\b`gl\GSEp5\NAK\EM.VYE_\f\SUB\EOT\FS\ENQbRb;=\1068524\990222a\SOn\NAK1\63452fF" - } - ), ucConvId = Nothing }, UserConnection @@ -60,13 +44,6 @@ testObject_UserConnectionList_user_1 = ucTo = Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000")), ucStatus = Accepted, ucLastUpdate = fromJust (readUTCTimeMillis "1864-05-09T00:43:52.049Z"), - ucMessage = - Just - ( Message - { messageText = - "\20301\NAKO\DEL \RSz\133473\GS\991007\140213\CAN8:\1025282bQ(XKw}\f\t\1111001\&0\17916kx\a0=\1005888;L\f*\DLEko\EMz^x2(\1046242\\ep\46530w\63639\183850\&71\n 3\GS\EOT\EOT?z\154271\17377->\128707a,\133082j;-\64635\DC3\993804(L\DC2\999665\t{\1094858\513533\168146\&60\20575\1070466\159251-\141952\&8\r\181611<\1102854Gvz[\ETB\1112766x\v\1107261H6\1068126\SOH\f0-0dL\1026774E{5\5921i\1039789\988467\&1\\\136616\SUB\SO\afW\33397S\1104118\DC4\ETX\au\187084\STXE\ACK\69915\190154\51438\8403\9315\FSv\f\1061477\&8E\tb5\42467\&8)\SOS\USiy" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [], - profileAccentId = ColourId {fromColourId = -1}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000001"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000001"))) - } - ), - profileHandle = - Just - ( Handle - { fromHandle = - "dauxfkc4f7s4ut0xhxnq9l8zzpeuze998esch51.vh.t56sr1j8bavtco.40te65.sl3b9yzgwxdpxld4_mnoou.adu0lcwxf63lmt8ev8ug7dy39ft31vweb7684k" - } - ), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.OC, lCountry = Just (Country {fromCountry = TC})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-07T13:58:16.443Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000200000002"))), - profileEmail = Just (Email {emailLocal = "\40237", emailDomain = ""}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_5 :: UserProfile -testObject_UserProfile_user_5 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000000-0000-0002-0000-000100000001"))), - qDomain = Domain {_domainText = "awdt-0be-r.7hyxl8mkb.s.lp"} - }, - profileName = - Name - { fromName = - "q0\USe\147265\DC4e78h\DC1!E#}A\GS\177692b,\51312\1075556\179877\&2\SYNP\1075345\166498\1009760,(\DC3O0\94026\31436\nGXJ" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [], - profileAccentId = ColourId {fromColourId = -2}, profileDeleted = False, profileService = Nothing, - profileHandle = - Just - ( Handle - { fromHandle = "2k1t1hdfpvdkxij-0w735w5xniggherg.c8d_be21d3mrasu9bkz38dmbwhca3neuduc0oz8v3n1-bd81z6ocf5d1i" - } - ), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.PT, lCountry = Just (Country {fromCountry = ES})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-07T03:37:18.107Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000000000000"))), - profileEmail = Just (Email {emailLocal = "/\v", emailDomain = "\176812"}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_6 :: UserProfile -testObject_UserProfile_user_6 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000002"))), - qDomain = Domain {_domainText = "87k.iag53"} - }, - profileName = - Name - { fromName = - "L\"v\FSk 2d$\USQm|\135151r\1049028\1056538\138866\1023394-\1008034\DC4+dC/n.\r\USAX\SUBs$B\DC1\32458G\33784pTC\159559Lgs\58928\EM\31200,vz\1022740\23748tYvC\DC3rA0{\100659e!\189204\135095'r&X9k4Z\98253\DC2YW*\177006Wh#\172479_\1080740\1055026r\NAK(\1094630\138346\1090119\FShF\ESCn^\186871=!\STX\1007566]`\1063058\1105955\FS\ETB=9D.x$\ESCU/\STXFJ" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "" (Just AssetPreview)), (ImageAsset "" (Just AssetPreview))], - profileAccentId = ColourId {fromColourId = 0}, - profileDeleted = False, - profileService = Nothing, - profileHandle = - Just (Handle {fromHandle = "frz05jdtt5.dacr3hd-hmayzm93q91g-qbd-4rm2hs2de4jx.80xj9y6k.c70.s_s_85ymq0w.lv_"}), + profileHandle = Nothing, profileLocale = Nothing, - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-11T16:24:39.844Z")), + profileExpire = Nothing, profileTeam = Nothing, - profileEmail = Just (Email {emailLocal = "l", emailDomain = "\74983"}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_7 :: UserProfile -testObject_UserProfile_user_7 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000200000000"))), - qDomain = Domain {_domainText = "uy-m.eb-p-ehu.n.t5p-i84u"} - }, - profileName = - Name - { fromName = - "0\\x\41194\1025998\RS\DLE\41260\177322\988734n\1025166\120094(w\31071J\157859\CAN~W|#!\1101827\110864\1054048\GS\1051711\&7\SUB\1106402/\1100826\147223\&6\1007341\190764]\SO\ENQIRy\186776/H\138633)\166423\1018759jEO\DC1d`]A\GS\"\US\136784\1107857Irh;M\1033302\20834LzC\7977N_\DC2\998835-q1z0\23277\137310\42710);\174333z\SUB5\1099606ZN\1112582\SO5\SYN \54701" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [], - profileAccentId = ColourId {fromColourId = 1}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000100000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000000000001"))) - } - ), - profileHandle = - Just - ( Handle - { fromHandle = - "67-9yy9qo2p25zhd58xripmrgouiuww98mk.m5xfnlvqmpz8wsgjuo7eo149d_0is6w26-2zo4z1kbf6zmkth4n3j139iok0s80ccdfxcb-jy3edziep9hpb2r.glfme2q09t..ehpdjc57dv-9_8nt0f" - } - ), - profileLocale = Nothing, - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-07T08:32:43.292Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000000"))), - profileEmail = Just (Email {emailLocal = "", emailDomain = ""}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_8 :: UserProfile -testObject_UserProfile_user_8 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000002"))), - qDomain = Domain {_domainText = "755m8o7.5-6tg.x48tvxc"} - }, - profileName = - Name - { fromName = - ". \18083\1031749\992124\\\1071115\STX'\SIV\1084248\1091205)\983738\NUL\1059015[EO\180607M\DC2A\175335\1014385O&\r\1086193\171482" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [], - profileAccentId = ColourId {fromColourId = 1}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))) - } - ), - profileHandle = Just (Handle {fromHandle = "dbiy"}), - profileLocale = Nothing, - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-10T15:50:41.047Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0002-0000-000000000002"))), - profileEmail = Just (Email {emailLocal = "\984237", emailDomain = "\DC3F"}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_9 :: UserProfile -testObject_UserProfile_user_9 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000000"))), - qDomain = Domain {_domainText = "p.6u0.jym"} - }, - profileName = Name {fromName = "Xa\SOHtP\"\161415)\23205\DC2\34102y\\]E\v\\G"}, - profilePict = Pict {fromPict = []}, - profileAssets = [], - profileAccentId = ColourId {fromColourId = -1}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000001"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000000000001"))) - } - ), - profileHandle = Just (Handle {fromHandle = "72nnsdja3n"}), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.SV, lCountry = Just (Country {fromCountry = WF})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-07T20:54:55.730Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000200000000"))), - profileEmail = Just (Email {emailLocal = "_", emailDomain = "U\STX"}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_10 :: UserProfile -testObject_UserProfile_user_10 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000002-0000-0000-0000-000000000001"))), - qDomain = Domain {_domainText = "yg0u9.w-7-l.x6"} - }, - profileName = - Name - { fromName = - "E8VP6\\\STX\ETX\1084758\136489\17676\1102237\SUB\DEL\1056983+D`\991577\995184GEl<\GSU8y\1064857\NULguH%XBf}\\\DC4\1095683\163418\STXH(\FS\1111450\140458)$.*(p~n\157707j\ENQn\DC2\ESC]\65223\161758=)\180231\998932Y\ACK\1002339\111345\SYNE\32763\t\110997\8084vLXFigV`Z\SOHwa\133943}=\vS\1004479\40602\1035955EA&r\EMo6\1101427\60026\DLE\188008\GS\1002964v\1038845\128451\996282" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "\US" (Just AssetComplete))], - profileAccentId = ColourId {fromColourId = 2}, - profileDeleted = False, - profileService = Nothing, - profileHandle = Just (Handle {fromHandle = "cxh8m"}), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.MR, lCountry = Just (Country {fromCountry = CL})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-08T12:03:12.917Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000001"))), profileEmail = Nothing, - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_11 :: UserProfile -testObject_UserProfile_user_11 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000200000002"))), - qDomain = Domain {_domainText = "9p4.6cpl.p92"} - }, - profileName = - Name - { fromName = - "\151605\39087Z\n2\DC4y-\v\DELcS\ESC\SI^S:K\v{,}\NUL\161121i\162096\ETB\156507t\24702p};mY\DC1g&\1018745\1081629\USW\1056481\17501\1039160$\SUB6\1018210\1100674\tz\92652+\DC2J\1017525\1090958\1058616\45670\1000384c\45329B}\176309E\48361\ETXXR\1063545B\USW\21733d\SO-\SO\a"}, + profileName = Name {fromName = "si4v\999679\ESC^'\12447k\21889\NAK?\1082547\NULBw;\b3*R/\164149lrI"}, profilePict = Pict {fromPict = []}, profileAssets = [], - profileAccentId = ColourId {fromColourId = 0}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000001"))) - } - ), - profileHandle = Just (Handle {fromHandle = "ml"}), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.KS, lCountry = Just (Country {fromCountry = AG})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-09T20:48:09.740Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000002-0000-0001-0000-000200000001"))), - profileEmail = Nothing, - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_13 :: UserProfile -testObject_UserProfile_user_13 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000100000001"))), - qDomain = Domain {_domainText = "1.z6lionkv7"} - }, - profileName = - Name - { fromName = - "u\DC3\34311T\t\US;\989746[\"n`\"\NULD\r\163171 Vj\SOj>Pb\1050733]\143998\995637I\n\CAN\1078162\&6\SOHx\"p\38430E\CAN@w\1101399\100497R\DEL\vX\157034\176201\1105646@K|K\1039270\&4\51976\166287\STXo9" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "" (Just AssetPreview)), (ImageAsset "" (Just AssetPreview))], - profileAccentId = ColourId {fromColourId = 1}, - profileDeleted = True, - profileService = Nothing, - profileHandle = Nothing, - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.LU, lCountry = Just (Country {fromCountry = VG})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-07T18:04:28.203Z")), - profileTeam = Nothing, - profileEmail = Nothing, - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_14 :: UserProfile -testObject_UserProfile_user_14 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000002-0000-0002-0000-000100000001"))), - qDomain = Domain {_domainText = "9f97og.h2af889e64zw"} - }, - profileName = - Name - { fromName = - "\182072d\1064502xu\41418\EM\STX\a\ETB\DC3.\DEL\t.7k^!5*\1002638iT)\EM\1076820\1031217\55164\r\GS\78808~j\US\DC1X\SOH\DLEf\1070389Vo\FS7]\ESC\171525J\172010\1091730,-K\178947w`\13664\25008\EOT^>A\n\37142C\120407v\1065338R1Q\998858\CANU\ENQP\t\FS8~\CAN\185286\EOT\152846\182973\185538\a_Kdj\50578l\DELN+L?\1005665-\US\1055296wGP\59781.Zm" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "" (Just AssetComplete)), (ImageAsset "" (Just AssetComplete))], - profileAccentId = ColourId {fromColourId = 2}, - profileDeleted = False, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000001"))) - } - ), - profileHandle = Just (Handle {fromHandle = ".0f-ea"}), - profileLocale = Just (Locale {lLanguage = Language Data.LanguageCodes.OJ, lCountry = Nothing}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-08T01:21:51.302Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0002-0000-000000000000"))), - profileEmail = Nothing, - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_15 :: UserProfile -testObject_UserProfile_user_15 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000002-0000-0002-0000-000000000001"))), - qDomain = Domain {_domainText = "q64o7.302d44.yvc0-7.61.v9mv"} - }, - profileName = - Name - { fromName = - "\1021630-\1011751\10544\NAKS\1069392\SUBj\135463tu\\\1009418\180291\t\RS\163835\164989\1008429\FS\ETB\ad\ETBeT\DEL\SO$\1073140YT_e\188102!)\SI\DC2S]\1107330SYm\52680g\NAKpX,GQ\DLEF\SIJ\61777\SO\b\vR\GS\STX\25359\1082212y\CANg\36697J\NAK\"\fMX\994950\&3g\1093512n4\1052736\US\121065\DLE" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "" (Just AssetComplete)), (ImageAsset "" (Just AssetComplete))], - profileAccentId = ColourId {fromColourId = 1}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000001"))) - } - ), - profileHandle = - Just - ( Handle - { fromHandle = - "3ti0segu2s7u294jpsv5lixp_axfvix4h.a9phbpuprb5g1.g5a-5hh7ezf2ur8z.2pms57_cv2pupxv8xdgnvbqyx_eiyk3k0bsky53x1fzivty4j.c79jfo9zr9f8pru1j-ixl67d9cz23b1e-m603_iz8_2uf8neudzfq1vi1ec" - } - ), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.DV, lCountry = Just (Country {fromCountry = MO})}), - profileExpire = Nothing, - profileTeam = Just (Id (fromJust (UUID.fromString "00000002-0000-0001-0000-000200000002"))), - profileEmail = Just (Email {emailLocal = "F", emailDomain = "\NUL"}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_16 :: UserProfile -testObject_UserProfile_user_16 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000002-0000-0000-0000-000100000002"))), - qDomain = Domain {_domainText = "19.i.mwv-7"} - }, - profileName = - Name - { fromName = - "\19513\48782%P\10154\a\1093017\1051048?.\337\52663\SOH%\5578\140305\1010727\140336\42232\1018530\10555`)\1090314(&\1040005W\27963\165377\1086495Sh\NUL\100787\1013554\NAK\EM\NUL\1016363\1029788\EM*vUWp=/H:\SIP\144251K/Q}\1056651(\994178Z\161956)_\1004918O\1033630\CAN0\1047955\999216g>\1025653\SO\SIW\1002557h;\78320\SIyJt\SYN\70205(q}\40502:b\132308/\RSGV\1053156\DEL{r\14107$oo1H\1028116n\b\42587\1104360hBiS\1065487\&6Az\DLE'\1053065=" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "" (Just AssetComplete)), (ImageAsset "" (Nothing))], profileAccentId = ColourId {fromColourId = -1}, - profileDeleted = False, + profileDeleted = True, profileService = Just ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000001"))) + { _serviceRefId = Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000001")), + _serviceRefProvider = Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000001")) } ), profileHandle = Just ( Handle { fromHandle = - "guo2m_9jgnm.snxp7uazht2j6je41-be6p5y9g-0afnnll.k5x0al45l948yuys97uy.7azgirru0r55.h-2ylot.j.y433-1jdw_ecazkzeqpa4lr.zt9.zjjaz7bzvxo4baqtod48_388s6-vxifhn9giwz6nc290fw2589psan" - } - ), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.JA, lCountry = Just (Country {fromCountry = BB})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-07T06:39:38.220Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000002-0000-0000-0000-000100000001"))), - profileEmail = Just (Email {emailLocal = "V", emailDomain = "|"}), - profileLegalholdStatus = UserLegalHoldNoConsent - } - -testObject_UserProfile_user_17 :: UserProfile -testObject_UserProfile_user_17 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000002"))), - qDomain = Domain {_domainText = "94nvo.97j.g83--2e.4-t1g.z"} - }, - profileName = - Name - { fromName = - "@@v\139742}$2^]\983599=\a6\164216\DLE*\f(\CAN(76kCs\ACKX[~\63041\30173\NUL\NUL\1100513\1094624o\51999a\US0E|\"d\152042\SUB{!X\STX\aF`\ETB\EOT*\985434\73863;#tOw\SOHD\1087790 \1068210E\n\CAN\DC3D`>\DC3\ETB965!CL\1107341\1011690B9\US\DLE[\1041774\&0\1093885%\f.y\RS\23872\a\ETB\33686\RS[\32348\1010958\ACKPuC" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "N" (Just AssetPreview))], - profileAccentId = ColourId {fromColourId = -2}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000001"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000001"))) + "emsonpvo3-x_4ys4qjtjtkfgx.mag6pi2ldq.77m5vnsn_tte41r-0vwgklpeejr1t4se0bknu4tsuqs-njzh34-ba_mj8lm5x6aro4o.2wsqe0ldx" } ), - profileHandle = Just (Handle {fromHandle = "uva.d"}), profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.GN, lCountry = Just (Country {fromCountry = GA})}), - profileExpire = Nothing, - profileTeam = Nothing, - profileEmail = Just (Email {emailLocal = "I\t", emailDomain = "%"}), + Just (Locale {lLanguage = Language Data.LanguageCodes.NY, lCountry = Just (Country {fromCountry = MU})}), + profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-09T01:42:22.437Z")), + profileTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0002-0000-000200000002"))), + profileEmail = Just (Email {emailLocal = "\172353 ", emailDomain = ""}), profileLegalholdStatus = UserLegalHoldNoConsent } - -testObject_UserProfile_user_18 :: UserProfile -testObject_UserProfile_user_18 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000001"))), - qDomain = Domain {_domainText = "r71-2.u"} - }, - profileName = - Name - { fromName = - "$\1006024\ETBq\172753\NAK\1003120!\1078351\DC4\990161\EOT+X\190655\997166n\FS\DEL\SUBr0\1087799\1061617z5\191342\&6\992189mBxr\a-H\173621\8826\SYNf\163769\1008130\1069053EMAQ\189593hm\"t\1005327\169220=\NULh$:>\1042739E\26278\120919lz\185436oY\te\DC17B\1077329Be\n\f\1057987/\ETBo\SUBw\1089339\35004\988396\1061645R\161579\EM\DEL\189459\54402\ENQ\39234v\ETB\1090963\63379\180155\US\993694dj=\nZM" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "" (Just AssetComplete)), (ImageAsset "" (Just AssetComplete))], - profileAccentId = ColourId {fromColourId = 1}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000100000001"))) - } - ), - profileHandle = Just (Handle {fromHandle = "50-a8ceq8yfwac.lp."}), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.KR, lCountry = Just (Country {fromCountry = MN})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-08T13:37:48.974Z")), - profileTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000200000000"))), - profileEmail = Nothing, - profileLegalholdStatus = UserLegalHoldEnabled - } - -testObject_UserProfile_user_19 :: UserProfile -testObject_UserProfile_user_19 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000000"))), - qDomain = Domain {_domainText = "00.252-t7.7l7.r478qz0a4.b"} - }, - profileName = - Name - { fromName = - "\v\1041473\ACKW\vKmM3,j\1003909uX\184886\GS\63083\a\SI:\1040232\151396m\ETB@c\1055742ePd=Bhs:\NAK\NAKa(\1051834hyWvEO\1023717Q\US\n\190342\1061646y)\1033452Y\1073361\1601}\\\SI\DLE\RS\177923mP!z\1000637c\aqMFa\ESC\1068568" - }, - profilePict = Pict {fromPict = []}, - profileAssets = [(ImageAsset "" (Just AssetComplete))], - profileAccentId = ColourId {fromColourId = -2}, - profileDeleted = True, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000001"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))) - } - ), - profileHandle = Just (Handle {fromHandle = "2g"}), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.TO, lCountry = Just (Country {fromCountry = SH})}), - profileExpire = Nothing, - profileTeam = Just (Id (fromJust (UUID.fromString "00000002-0000-0001-0000-000100000001"))), - profileEmail = Just (Email {emailLocal = "a", emailDomain = "\b"}), - profileLegalholdStatus = UserLegalHoldPending - } - -testObject_UserProfile_user_20 :: UserProfile -testObject_UserProfile_user_20 = - UserProfile - { profileQualifiedId = - Qualified - { qUnqualified = (Id (fromJust (UUID.fromString "00000002-0000-0000-0000-000200000001"))), - qDomain = Domain {_domainText = "2.ei5-x3"} - }, - profileName = - Name - { fromName = - "fB\DC1\1107358\66001Wg_!\ETB\DC4oZ\180871t<\FS\tI\1073000\2742r`\SOHO\131716+n\121207\4754]`dR\SUB\DC1z2\1084540-.4H~\36039|\98420<\99835\987986^~\1003487gR,\f\NUL x)`D@,\ETBv\160408\1105176\&1%@#R}(C2OCy\t2\7837\SUB\GSgs&d\984681\172116\SOH\1013326^" - }, - profilePict = Pict {fromPict = []}, - profileAssets = - [ (ImageAsset "" (Just AssetComplete)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "" (Nothing)), - (ImageAsset "" (Nothing)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "" (Nothing)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "" (Just AssetComplete)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "" (Just AssetPreview)), - (ImageAsset "" (Nothing)), - (ImageAsset "" (Just AssetComplete)) - ], - profileAccentId = ColourId {fromColourId = -1}, - profileDeleted = False, - profileService = - Just - ( ServiceRef - { _serviceRefId = (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), - _serviceRefProvider = (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000000000001"))) - } - ), - profileHandle = Just (Handle {fromHandle = "zticd1l"}), - profileLocale = - Just (Locale {lLanguage = Language Data.LanguageCodes.RN, lCountry = Just (Country {fromCountry = CI})}), - profileExpire = Just (fromJust (readUTCTimeMillis "1864-05-07T10:18:53.031Z")), - profileTeam = Nothing, - profileEmail = Just (Email {emailLocal = "\1000346!", emailDomain = "|D"}), - profileLegalholdStatus = UserLegalHoldDisabled - } diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generator.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generator.hs index f5df945b1b4..8d6db1e05ea 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Generator.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Generator.hs @@ -151,7 +151,6 @@ generateTestModule = do generateBindingModule @Call.Config.SFTServer "user" ref generateBindingModule @Connection.ConnectionRequest "user" ref generateBindingModule @Connection.Relation "user" ref - generateBindingModule @Connection.Message "user" ref generateBindingModule @Connection.UserConnection "user" ref generateBindingModule @Connection.UserConnectionList "user" ref generateBindingModule @Connection.ConnectionUpdate "user" ref diff --git a/libs/wire-api/test/unit/Test/Wire/API/Golden/Manual/ConversationsResponse.hs b/libs/wire-api/test/unit/Test/Wire/API/Golden/Manual/ConversationsResponse.hs index d4733ff41aa..306222effb6 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Golden/Manual/ConversationsResponse.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Golden/Manual/ConversationsResponse.hs @@ -41,7 +41,6 @@ conv1 = Member { memId = Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000100000000")), memService = Nothing, - memOtrMuted = True, memOtrMutedStatus = Nothing, memOtrMutedRef = Nothing, memOtrArchived = False, @@ -85,7 +84,6 @@ conv2 = Member { memId = Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000001")), memService = Nothing, - memOtrMuted = True, memOtrMutedStatus = Just (MutedStatus {fromMutedStatus = -1}), memOtrMutedRef = Nothing, memOtrArchived = False, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs index a30df7648c0..c16f54fcfbd 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/Aeson.hs @@ -96,7 +96,6 @@ tests = testRoundTrip @Call.Config.SFTServer, testRoundTrip @Connection.ConnectionRequest, testRoundTrip @Connection.Relation, - testRoundTrip @Connection.Message, testRoundTrip @Connection.UserConnection, testRoundTrip @Connection.UserConnectionList, testRoundTrip @Connection.ConnectionUpdate, diff --git a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/ByteString.hs b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/ByteString.hs index 642dfe1f877..d79ed2a6708 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/ByteString.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/Roundtrip/ByteString.hs @@ -40,6 +40,7 @@ import qualified Wire.API.User as User import qualified Wire.API.User.Activation as User.Activation import qualified Wire.API.User.Auth as User.Auth import qualified Wire.API.User.Identity as User.Identity +import qualified Wire.API.User.IdentityProvider as User.IdentityProvider import qualified Wire.API.User.Password as User.Password import qualified Wire.API.User.Profile as User.Profile import qualified Wire.API.User.Search as User.Search @@ -84,7 +85,8 @@ tests = testRoundTrip @Team.Role.Role, testRoundTrip @User.Search.TeamUserSearchSortBy, testRoundTrip @User.Search.TeamUserSearchSortOrder, - testRoundTrip @User.Search.RoleFilter + testRoundTrip @User.Search.RoleFilter, + testRoundTrip @User.IdentityProvider.WireIdPAPIVersion -- FUTUREWORK: -- testCase "Call.Config.TurnUsername (doesn't have FromByteString)" ... -- testCase "User.Activation.ActivationTarget (doesn't have FromByteString)" ... diff --git a/libs/wire-api/wire-api.cabal b/libs/wire-api/wire-api.cabal index dfa774db991..9077503f453 100644 --- a/libs/wire-api/wire-api.cabal +++ b/libs/wire-api/wire-api.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: efca28ca2d2ca3ccfcaf3b543293e01d05d18802dd38283d7658ec50939231d9 +-- hash: b225ee25604ad590c2886cca427ff3612767c72e49039963f1fbafbb94a807bd name: wire-api version: 0.1.0 @@ -55,6 +55,7 @@ library Wire.API.Routes.Public.Galley.Responses Wire.API.Routes.Public.LegalHold Wire.API.Routes.Public.Spar + Wire.API.Routes.Public.Util Wire.API.Routes.QualifiedCapture Wire.API.ServantProto Wire.API.Swagger @@ -248,7 +249,7 @@ test-suite wire-api-tests Test.Wire.API.Golden.Generated.LastPrekey_user Test.Wire.API.Golden.Generated.LegalHoldServiceConfirm_team Test.Wire.API.Golden.Generated.LegalHoldServiceRemove_team - Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_2020_user + Test.Wire.API.Golden.Generated.LimitedQualifiedUserIdList_user Test.Wire.API.Golden.Generated.ListType_team Test.Wire.API.Golden.Generated.Locale_user Test.Wire.API.Golden.Generated.LocaleUpdate_user @@ -260,7 +261,6 @@ test-suite wire-api-tests Test.Wire.API.Golden.Generated.Member_user Test.Wire.API.Golden.Generated.MemberUpdate_user Test.Wire.API.Golden.Generated.MemberUpdateData_user - Test.Wire.API.Golden.Generated.Message_user Test.Wire.API.Golden.Generated.MutedStatus_user Test.Wire.API.Golden.Generated.Name_user Test.Wire.API.Golden.Generated.NameUpdate_user diff --git a/services/brig/src/Brig/API.hs b/services/brig/src/Brig/API.hs index 089a3a3d37e..4e15d4e5022 100644 --- a/services/brig/src/Brig/API.hs +++ b/services/brig/src/Brig/API.hs @@ -23,12 +23,11 @@ where import Brig.API.Handler (Handler) import qualified Brig.API.Internal as Internal import qualified Brig.API.Public as Public -import Brig.Options (Opts) import qualified Data.Swagger.Build.Api as Doc import Network.Wai.Routing (Routes) -sitemap :: Opts -> Routes Doc.ApiBuilder Handler () -sitemap o = do - Public.sitemap o - Public.apiDocs o +sitemap :: Routes Doc.ApiBuilder Handler () +sitemap = do + Public.sitemap + Public.apiDocs Internal.sitemap diff --git a/services/brig/src/Brig/API/Connection.hs b/services/brig/src/Brig/API/Connection.hs index 47144bcad1c..be837b42f98 100644 --- a/services/brig/src/Brig/API/Connection.hs +++ b/services/brig/src/Brig/API/Connection.hs @@ -59,12 +59,13 @@ import System.Logger.Message import Wire.API.Connection (RelationWithHistory (..)) import qualified Wire.API.Conversation as Conv import Wire.API.ErrorDescription +import Wire.API.Routes.Public.Util (ResponseForExistedCreated (..)) createConnection :: UserId -> ConnectionRequest -> ConnId -> - ExceptT ConnectionError AppIO ConnectionResult + ExceptT ConnectionError AppIO (ResponseForExistedCreated UserConnection) createConnection self req conn = createConnectionToLocalUser self (crUser req) req conn @@ -73,8 +74,8 @@ createConnectionToLocalUser :: UserId -> ConnectionRequest -> ConnId -> - ExceptT ConnectionError AppIO ConnectionResult -createConnectionToLocalUser self crUser ConnectionRequest {crName, crMessage} conn = do + ExceptT ConnectionError AppIO (ResponseForExistedCreated UserConnection) +createConnectionToLocalUser self crUser ConnectionRequest {crName} conn = do when (self == crUser) $ throwE $ InvalidUser crUser @@ -97,28 +98,28 @@ createConnectionToLocalUser self crUser ConnectionRequest {crName, crMessage} co Just rs -> rs Nothing -> do checkLimit self - ConnectionCreated <$> insert Nothing Nothing + Created <$> insert Nothing Nothing where insert :: Maybe UserConnection -> Maybe UserConnection -> ExceptT ConnectionError AppIO UserConnection insert s2o o2s = lift $ do Log.info $ logConnection self crUser . msg (val "Creating connection") - cnv <- Intra.createConnectConv self crUser (Just crName) (Just crMessage) (Just conn) - s2o' <- Data.insertConnection self crUser SentWithHistory (Just crMessage) cnv - o2s' <- Data.insertConnection crUser self PendingWithHistory (Just crMessage) cnv + cnv <- Intra.createConnectConv self crUser (Just (fromRange crName)) (Just conn) + s2o' <- Data.insertConnection self crUser SentWithHistory cnv + o2s' <- Data.insertConnection crUser self PendingWithHistory cnv e2o <- ConnectionUpdated o2s' (ucStatus <$> o2s) <$> Data.lookupName self let e2s = ConnectionUpdated s2o' (ucStatus <$> s2o) Nothing mapM_ (Intra.onConnectionEvent self (Just conn)) [e2o, e2s] return s2o' - update :: UserConnection -> UserConnection -> ExceptT ConnectionError AppIO ConnectionResult + update :: UserConnection -> UserConnection -> ExceptT ConnectionError AppIO (ResponseForExistedCreated UserConnection) update s2o o2s = case (ucStatus s2o, ucStatus o2s) of (MissingLegalholdConsent, _) -> throwE $ InvalidTransition self Sent (_, MissingLegalholdConsent) -> throwE $ InvalidTransition self Sent - (Accepted, Accepted) -> return $ ConnectionExists s2o - (Accepted, Blocked) -> return $ ConnectionExists s2o - (Sent, Blocked) -> return $ ConnectionExists s2o + (Accepted, Accepted) -> return $ Existed s2o + (Accepted, Blocked) -> return $ Existed s2o + (Sent, Blocked) -> return $ Existed s2o (Blocked, _) -> throwE $ InvalidTransition self Sent (_, Blocked) -> change s2o SentWithHistory (_, Sent) -> accept s2o o2s @@ -127,7 +128,7 @@ createConnectionToLocalUser self crUser ConnectionRequest {crName, crMessage} co (_, Pending) -> resend s2o o2s (_, Cancelled) -> resend s2o o2s - accept :: UserConnection -> UserConnection -> ExceptT ConnectionError AppIO ConnectionResult + accept :: UserConnection -> UserConnection -> ExceptT ConnectionError AppIO (ResponseForExistedCreated UserConnection) accept s2o o2s = do when (ucStatus s2o `notElem` [Sent, Accepted]) $ checkLimit self @@ -144,9 +145,9 @@ createConnectionToLocalUser self crUser ConnectionRequest {crName, crMessage} co e2o <- lift $ ConnectionUpdated o2s' (Just $ ucStatus o2s) <$> Data.lookupName self let e2s = ConnectionUpdated s2o' (Just $ ucStatus s2o) Nothing lift $ mapM_ (Intra.onConnectionEvent self (Just conn)) [e2o, e2s] - return $ ConnectionExists s2o' + return $ Existed s2o' - resend :: UserConnection -> UserConnection -> ExceptT ConnectionError AppIO ConnectionResult + resend :: UserConnection -> UserConnection -> ExceptT ConnectionError AppIO (ResponseForExistedCreated UserConnection) resend s2o o2s = do when (ucStatus s2o `notElem` [Sent, Accepted]) $ checkLimit self @@ -154,10 +155,10 @@ createConnectionToLocalUser self crUser ConnectionRequest {crName, crMessage} co logConnection self (ucTo s2o) . msg (val "Resending connection request") s2o' <- insert (Just s2o) (Just o2s) - return $ ConnectionExists s2o' + return $ Existed s2o' - change :: UserConnection -> RelationWithHistory -> ExceptT ConnectionError AppIO ConnectionResult - change c s = ConnectionExists <$> lift (Data.updateConnection c s) + change :: UserConnection -> RelationWithHistory -> ExceptT ConnectionError AppIO (ResponseForExistedCreated UserConnection) + change c s = Existed <$> lift (Data.updateConnection c s) belongSameTeam :: AppIO Bool belongSameTeam = do diff --git a/services/brig/src/Brig/API/Error.hs b/services/brig/src/Brig/API/Error.hs index af50a8a7f19..f4c63aa8112 100644 --- a/services/brig/src/Brig/API/Error.hs +++ b/services/brig/src/Brig/API/Error.hs @@ -85,11 +85,11 @@ instance ToJSON Error where -- Error Mapping ---------------------------------------------------------- connError :: ConnectionError -> Error -connError TooManyConnections {} = StdError connectionLimitReached +connError TooManyConnections {} = StdError (errorDescriptionToWai connectionLimitReached) connError InvalidTransition {} = StdError invalidTransition connError NotConnected {} = StdError (errorDescriptionToWai notConnected) -connError InvalidUser {} = StdError invalidUser -connError ConnectNoIdentity {} = StdError (noIdentity 0) +connError InvalidUser {} = StdError (errorDescriptionToWai invalidUser) +connError ConnectNoIdentity {} = StdError (errorDescriptionToWai (noIdentity 0)) connError (ConnectBlacklistedUserKey k) = StdError $ foldKey (const blacklistedEmail) (const blacklistedPhone) k connError (ConnectInvalidEmail _ _) = StdError invalidEmail connError ConnectInvalidPhone {} = StdError invalidPhone @@ -144,14 +144,15 @@ changeEmailError EmailManagedByScim = StdError $ propertyManagedByScim "email" changePhoneError :: ChangePhoneError -> Error changePhoneError (InvalidNewPhone _) = StdError invalidPhone changePhoneError (PhoneExists _) = StdError userKeyExists +changePhoneError (BlacklistedNewPhone _) = StdError blacklistedPhone changePwError :: ChangePasswordError -> Error changePwError InvalidCurrentPassword = StdError badCredentials -changePwError ChangePasswordNoIdentity = StdError (noIdentity 1) +changePwError ChangePasswordNoIdentity = StdError (errorDescriptionToWai (noIdentity 1)) changePwError ChangePasswordMustDiffer = StdError changePasswordMustDiffer changeHandleError :: ChangeHandleError -> Error -changeHandleError ChangeHandleNoIdentity = StdError (noIdentity 2) +changeHandleError ChangeHandleNoIdentity = StdError (errorDescriptionToWai (noIdentity 2)) changeHandleError ChangeHandleExists = StdError handleExists changeHandleError ChangeHandleInvalid = StdError invalidHandle changeHandleError ChangeHandleManagedByScim = StdError $ propertyManagedByScim "handle" @@ -198,7 +199,7 @@ zauthError ZAuth.Unsupported = StdError authTokenUnsupported clientError :: ClientError -> Error clientError ClientNotFound = StdError (errorDescriptionToWai clientNotFound) clientError (ClientDataError e) = clientDataError e -clientError (ClientUserNotFound _) = StdError invalidUser +clientError (ClientUserNotFound _) = StdError (errorDescriptionToWai invalidUser) clientError ClientLegalHoldCannotBeRemoved = StdError can'tDeleteLegalHoldClient clientError ClientLegalHoldCannotBeAdded = StdError can'tAddLegalHoldClient clientError (ClientFederationError e) = fedError e @@ -211,7 +212,7 @@ fedError = StdError . federationErrorToWai idtError :: RemoveIdentityError -> Error idtError LastIdentity = StdError lastIdentity idtError NoPassword = StdError noPassword -idtError NoIdentity = StdError (noIdentity 3) +idtError NoIdentity = StdError (errorDescriptionToWai (noIdentity 3)) propDataError :: PropertiesDataError -> Error propDataError TooManyProperties = StdError tooManyProperties @@ -223,7 +224,7 @@ clientDataError ClientMissingAuth = StdError (errorDescriptionToWai missingAuthE clientDataError MalformedPrekeys = StdError (errorDescriptionToWai malformedPrekeys) deleteUserError :: DeleteUserError -> Error -deleteUserError DeleteUserInvalid = StdError invalidUser +deleteUserError DeleteUserInvalid = StdError (errorDescriptionToWai invalidUser) deleteUserError DeleteUserInvalidCode = StdError invalidCode deleteUserError DeleteUserInvalidPassword = StdError badCredentials deleteUserError DeleteUserMissingPassword = StdError (errorDescriptionToWai missingAuthError) @@ -253,21 +254,12 @@ propertyKeyTooLarge = Wai.mkError status403 "property-key-too-large" "The proper propertyValueTooLarge :: Wai.Error propertyValueTooLarge = Wai.mkError status403 "property-value-too-large" "The property value is too large" -connectionLimitReached :: Wai.Error -connectionLimitReached = Wai.mkError status403 "connection-limit" "Too many sent/accepted connections." - clientCapabilitiesCannotBeRemoved :: Wai.Error clientCapabilitiesCannotBeRemoved = Wai.mkError status409 "client-capabilities-cannot-be-removed" "You can only add capabilities to a client, not remove them." -invalidUser :: Wai.Error -invalidUser = Wai.mkError status400 "invalid-user" "Invalid user." - invalidTransition :: Wai.Error invalidTransition = Wai.mkError status403 "bad-conn-update" "Invalid status transition." -noIdentity :: Int -> Wai.Error -noIdentity i = Wai.mkError status403 "no-identity" ("The user has no verified identity (email or phone number). [code: " <> cs (show i) <> "]") - noEmail :: Wai.Error noEmail = Wai.mkError status403 "no-email" "This operation requires the user to have a verified email address." diff --git a/services/brig/src/Brig/API/Internal.hs b/services/brig/src/Brig/API/Internal.hs index 825c58a7121..8bf0022036a 100644 --- a/services/brig/src/Brig/API/Internal.hs +++ b/services/brig/src/Brig/API/Internal.hs @@ -72,7 +72,7 @@ import Servant.Swagger (HasSwagger (toSwagger)) import Servant.Swagger.Internal.Orphans () import Servant.Swagger.UI import qualified System.Logger.Class as Log -import Wire.API.ErrorDescription (userNotFound) +import Wire.API.ErrorDescription import Wire.API.User import Wire.API.User.Client (UserClientsFull (..)) import Wire.API.User.RichInfo @@ -589,7 +589,7 @@ updateUserNameH (uid ::: _ ::: body) = empty <$ (updateUserName uid =<< parseJso updateUserName :: UserId -> NameUpdate -> Handler () updateUserName uid (NameUpdate nameUpd) = do - name <- either (const $ throwStd invalidUser) pure $ mkName nameUpd + name <- either (const $ throwStd (errorDescriptionToWai invalidUser)) pure $ mkName nameUpd let uu = UserUpdate { uupName = Just name, @@ -599,7 +599,7 @@ updateUserName uid (NameUpdate nameUpd) = do } lift (Data.lookupUser WithPendingInvitations uid) >>= \case Just _ -> API.updateUser uid Nothing uu API.AllowSCIMUpdates !>> updateProfileError - Nothing -> throwStd invalidUser + Nothing -> throwStd (errorDescriptionToWai invalidUser) checkHandleInternalH :: Text -> Handler Response checkHandleInternalH = diff --git a/services/brig/src/Brig/API/Public.hs b/services/brig/src/Brig/API/Public.hs index 5db00dda25e..e2ce8904bac 100644 --- a/services/brig/src/Brig/API/Public.hs +++ b/services/brig/src/Brig/API/Public.hs @@ -98,6 +98,7 @@ import qualified Wire.API.Routes.Public.Brig as BrigAPI import qualified Wire.API.Routes.Public.Galley as GalleyAPI import qualified Wire.API.Routes.Public.LegalHold as LegalHoldAPI import qualified Wire.API.Routes.Public.Spar as SparAPI +import qualified Wire.API.Routes.Public.Util as Public import qualified Wire.API.Swagger as Public.Swagger (models) import qualified Wire.API.Team as Public import Wire.API.Team.LegalHold (LegalholdProtectee (..)) @@ -162,6 +163,63 @@ Okta will ask you to provide two URLs when you set it up for talking to wireapp: #### centrify.com Centrify allows you to upload the metadata xml document that you get from the `/sso/metadata` end-point. You can also enter the metadata url and have centrify retrieve the xml, but to guarantee integrity of the setup, the metadata should be copied from the team settings page and pasted into the centrify setup page without any URL indirections. + +## Federation errors + +Endpoints involving federated calls to other domains can return some extra failure responses, common to all endpoints. Instead of listing them as possible responses for each endpoint, we document them here. + +For errors that are more likely to be transient, we suggest clients to retry whatever request resulted in the error. Transient errors are indicated explicitly below. + +**Note**: when a failure occurs as a result of making a federated RPC to another backend, the error response contains the following extra fields: + + - `domain`: the target backend of the RPC that failed; + - `path`: the path of the RPC that failed. + +### Domain errors + +Errors in this category result from trying to communicate with a backend that is considered non-existent or invalid. They can result from invalid user input or client issues, but they can also be a symptom of misconfiguration in one or multiple backends. + + - **Remote backend not found** (status: 422, label: `srv-record-not-found`): This backend attempted to contact a backend which does not exist or is not properly configured. For the most part, clients can consider this error equivalent to a domain not existing, although it should be noted that certain mistakes in the DNS configuration on a remote backend can lead to the backend not being recognized, and hence to this error. It is therefore not advisable to take any destructive action upon encountering this error, such as deleting remote users from conversations. + - **Federation denied locally** (status: 400, label: `federation-not-allowed`): This backend attempted an RPC to a non-whitelisted backend. Similar considerations as for the previous error apply. + +### Local federation errors + +An error in this category likely indicates an issue with configuration of federation on the local backend. Possibly transient errors are indicated explicitly below. + + - **Federation not enabled** (status: 400, label: `federation-not-enabled`): Federation has not been configured for this backend. This will happen if a federation-aware client tries to talk to a backend for which federation is disabled, or if federation was disabled on the backend after reaching a federation-specific state (e.g. conversations with remote users). There is no way to cleanly recover from these errors at this point. + - **Federation unavailable** (status: 500, label: `federation-not-available`): Federation is configured for this backend, but the local federator cannot be reached. This can be transient, so clients should retry the request. + - **Federation not implemented** (status: 403, label: `federation-not-implemented`): Federated behaviour for a certain endpoint is not yet implemented. + - **Federator discovery failed** (status: 500, label: `srv-lookup-dns-error`): A DNS error occurred during discovery of a remote backend. This can be transient, so clients should retry the request. + - **Too much concurrency** (status: 533, label: `too-much-concurrency`): Too many concurrent requests from this backend. This can be transient, so clients should retry the request. + +### Remote federation errors + +Errors in this category are returned in case of communication issues between the local backend and a remote one, or if the remote side encountered an error while processing an RPC. Some errors in this category might be caused by incorrect client behaviour or wrong user input. All of these errors can be transient, so clients should retry the request that caused them. + + - **gRPC error** (status: 533, label: `grpc-error`): The current federator encountered an error when making an RPC to a remote one. Check the error message for more details. + - **Client RPC error** (status: 500, label: `client-rpc-error`): There was a non-specified error when making a request to another backend. Check the error message for more details. + - **Connection refused** (status: 521, label: `cannot-connect-to-remote-federator`): The local federator could not connect to a remote one. + - **Unknown remote error** (status: 500, label: `unknown-federation-error`): An RPC failed but no specific error was returned by the remote side. Check the error message for more details. + +### Backend compatibility errors + +An error in this category will be returned when this backend makes an invalid or unsupported RPC to another backend. This can indicate some incompatibility between backends or a backend bug. These errors are unlikely to be transient, so retrying requests is *not* advised. + + - **Version mismatch** (status: 531): A remote backend is running an unsupported version of the federator. + - **Invalid method** / **Streaming not supported** (status: 500, label: `federation-invalid-call`): There was an error in the communication between a service on this backend and the local federator. + - **Invalid request** (status: 500, label: `invalid-request-to-federator`): The local federator made an invalid request to a remote one. Check the error message for more details. + - **Invalid content type** (status: 503, label: `federation-invalid-content-type-header`): An RPC to another backend returned an invalid content type. + - **Unsupported content type** (status: 503, label: `federation-unsupported-content-type`): An RPC to another backend returned an unsupported content type. + - **Invalid origin domain** (status: 533, label: `invalid-origin-domain`): The current backend attempted an RPC with an invalid origin domain field. + - **Forbidden endpoint** (status: 533, label: `forbidden-endpoint`): The current backend attempted an RPC to a forbidden or inaccessible remote endpoint. + - **Unknown federation error** (status: 503, label: `unknown-federation-error`): The target of an RPC returned an unexpected reponse. Check the error message for more details. + +### Authentication errors + +The errors in this category relate to authentication or authorization issues between backends. These errors are unlikely to be transient, so retrying requests is *not* advised. + + - **TLS failure**: (status: 525): An error occurred during the TLS handshake between the local federator and a remote one. This is most likely due to an issue with the certificate on the remote end. + - **Federation denied remotely** (status: 532): The current backend made an unauthorized request to a remote one. |] servantSitemap :: ServerT ServantAPI Handler @@ -194,6 +252,7 @@ servantSitemap = BrigAPI.getClient = getClient, BrigAPI.getClientCapabilities = getClientCapabilities, BrigAPI.getClientPrekeys = getClientPrekeys, + BrigAPI.createConnection = createConnection, BrigAPI.searchContacts = Search.search } @@ -204,8 +263,8 @@ servantSitemap = -- - UserDeleted event to contacts of the user -- - MemberLeave event to members for all conversations the user was in (via galley) -sitemap :: Opts -> Routes Doc.ApiBuilder Handler () -sitemap o = do +sitemap :: Routes Doc.ApiBuilder Handler () +sitemap = do -- User Handle API ---------------------------------------------------- post "/users/handles" (continue checkHandlesH) $ @@ -296,7 +355,7 @@ sitemap o = do Doc.description "JSON body" Doc.response 200 "Password changed." Doc.end Doc.errorResponse badCredentials - Doc.errorResponse (noIdentity 4) + Doc.errorResponse (errorDescriptionToWai (noIdentity 4)) put "/self/locale" (continue changeLocaleH) $ zauthUserId @@ -389,33 +448,6 @@ sitemap o = do -- Connection API ----------------------------------------------------- - -- This endpoint can lead to the following events being sent: - -- - ConnectionUpdated event to self and other, if any side's connection state changes - -- - MemberJoin event to self and other, if joining an existing connect conversation (via galley) - -- - ConvCreate event to self, if creating a connect conversation (via galley) - -- - ConvConnect event to self, in some cases (via galley), - -- for details see 'Galley.API.Create.createConnectConversation' - post "/connections" (continue createConnectionH) $ - accept "application" "json" - .&. zauthUserId - .&. zauthConnId - .&. jsonRequest @Public.ConnectionRequest - document "POST" "createConnection" $ do - Doc.summary "Create a connection to another user." - Doc.notes $ - "You can have no more than " - <> Text.pack (show (setUserMaxConnections $ optSettings o)) - <> " connections in accepted or sent state." - Doc.body (Doc.ref Public.modelConnectionRequest) $ - Doc.description "JSON body" - Doc.returns (Doc.ref Public.modelConnection) - Doc.response 200 "The connection exists." Doc.end - Doc.response 201 "The connection was created." Doc.end - Doc.response 412 "The connection cannot be created (eg., due to legalhold policy conflict)." Doc.end - Doc.errorResponse connectionLimitReached - Doc.errorResponse invalidUser - Doc.errorResponse (noIdentity 5) - -- This endpoint is used to test /i/metrics, when this is servantified, please -- make sure some other endpoint is used to test that routes defined in this -- function are recorded and reported correctly in /i/metrics. @@ -456,10 +488,10 @@ sitemap o = do Doc.returns (Doc.ref Public.modelConnection) Doc.response 200 "Connection updated." Doc.end Doc.response 204 "No change." Doc.end - Doc.errorResponse connectionLimitReached + Doc.errorResponse (errorDescriptionToWai connectionLimitReached) Doc.errorResponse invalidTransition Doc.errorResponse (errorDescriptionToWai notConnected) - Doc.errorResponse invalidUser + Doc.errorResponse (errorDescriptionToWai invalidUser) get "/connections/:id" (continue getConnectionH) $ accept "application" "json" @@ -667,12 +699,12 @@ sitemap o = do Team.routesPublic Calling.routesPublic -apiDocs :: Opts -> Routes Doc.ApiBuilder Handler () -apiDocs o = +apiDocs :: Routes Doc.ApiBuilder Handler () +apiDocs = get "/users/api-docs" ( \(_ ::: url) k -> - let doc = mkSwaggerApi (decodeLatin1 url) Public.Swagger.models (sitemap o) + let doc = mkSwaggerApi (decodeLatin1 url) Public.Swagger.models sitemap in k $ json doc ) $ accept "application" "json" @@ -1114,13 +1146,9 @@ customerExtensionCheckBlockedDomains email = do when (domain `elem` blockedDomains) $ throwM $ customerExtensionBlockedDomain domain -createConnectionH :: JSON ::: UserId ::: ConnId ::: JsonRequest Public.ConnectionRequest -> Handler Response -createConnectionH (_ ::: self ::: conn ::: req) = do - cr <- parseJsonBody req - rs <- API.createConnection self cr conn !>> connError - return $ case rs of - ConnectionCreated c -> setStatus status201 $ json (c :: Public.UserConnection) - ConnectionExists c -> json (c :: Public.UserConnection) +createConnection :: UserId -> ConnId -> Public.ConnectionRequest -> Handler (Public.ResponseForExistedCreated Public.UserConnection) +createConnection self conn cr = do + API.createConnection self cr conn !>> connError updateConnectionH :: JSON ::: UserId ::: ConnId ::: UserId ::: JsonRequest Public.ConnectionUpdate -> Handler Response updateConnectionH (_ ::: self ::: conn ::: other ::: req) = do diff --git a/services/brig/src/Brig/API/Types.hs b/services/brig/src/Brig/API/Types.hs index 8241149efb8..10f3a4fc391 100644 --- a/services/brig/src/Brig/API/Types.hs +++ b/services/brig/src/Brig/API/Types.hs @@ -64,10 +64,6 @@ data CreateUserTeam = CreateUserTeam createdTeamName :: !Text } -data ConnectionResult - = ConnectionCreated !UserConnection - | ConnectionExists !UserConnection - data ActivationResult = -- | The key/code was valid and successfully activated. ActivationSuccess !(Maybe UserIdentity) !Bool @@ -165,6 +161,7 @@ data ChangePasswordError data ChangePhoneError = PhoneExists !Phone | InvalidNewPhone !Phone + | BlacklistedNewPhone !Phone data ChangeEmailError = InvalidNewEmail !Email !String diff --git a/services/brig/src/Brig/API/User.hs b/services/brig/src/Brig/API/User.hs index 544da737262..fe6bf6d931f 100644 --- a/services/brig/src/Brig/API/User.hs +++ b/services/brig/src/Brig/API/User.hs @@ -604,19 +604,26 @@ changeEmail u email allowScim = do changePhone :: UserId -> Phone -> ExceptT ChangePhoneError AppIO (Activation, Phone) changePhone u phone = do - ph <- + canonical <- maybe (throwE $ InvalidNewPhone phone) return =<< lift (validatePhone phone) - let pk = userPhoneKey ph + let pk = userPhoneKey canonical available <- lift $ Data.keyAvailable pk (Just u) unless available $ throwE $ PhoneExists phone timeout <- setActivationTimeout <$> view settings + blacklisted <- lift $ Blacklist.exists pk + when blacklisted $ + throwE (BlacklistedNewPhone canonical) + -- check if any prefixes of this phone number are blocked + prefixExcluded <- lift $ Blacklist.existsAnyPrefix canonical + when prefixExcluded $ + throwE (BlacklistedNewPhone canonical) act <- lift $ Data.newActivation pk timeout (Just u) - return (act, ph) + return (act, canonical) ------------------------------------------------------------------------------- -- Remove Email diff --git a/services/brig/src/Brig/Data/Connection.hs b/services/brig/src/Brig/Data/Connection.hs index 6f53afde9ed..e3d83d5d154 100644 --- a/services/brig/src/Brig/Data/Connection.hs +++ b/services/brig/src/Brig/Data/Connection.hs @@ -55,13 +55,12 @@ insertConnection :: -- | To UserId -> RelationWithHistory -> - Maybe Message -> ConvId -> AppIO UserConnection -insertConnection from to status msg cid = do +insertConnection from to status cid = do now <- toUTCTimeMillis <$> liftIO getCurrentTime - retry x5 . write connectionInsert $ params Quorum (from, to, status, now, msg, cid) - return $ toUserConnection (from, to, status, now, msg, Just cid) + retry x5 . write connectionInsert $ params Quorum (from, to, status, now, cid) + return $ toUserConnection (from, to, status, now, Just cid) updateConnection :: UserConnection -> RelationWithHistory -> AppIO UserConnection updateConnection c@UserConnection {..} status = do @@ -153,14 +152,14 @@ deleteConnections u = do -- Queries -connectionInsert :: PrepQuery W (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe Message, ConvId) () -connectionInsert = "INSERT INTO connection (left, right, status, last_update, message, conv) VALUES (?, ?, ?, ?, ?, ?)" +connectionInsert :: PrepQuery W (UserId, UserId, RelationWithHistory, UTCTimeMillis, ConvId) () +connectionInsert = "INSERT INTO connection (left, right, status, last_update, conv) VALUES (?, ?, ?, ?, ?)" connectionUpdate :: PrepQuery W (RelationWithHistory, UTCTimeMillis, UserId, UserId) () connectionUpdate = "UPDATE connection SET status = ?, last_update = ? WHERE left = ? AND right = ?" -connectionSelect :: PrepQuery R (UserId, UserId) (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe Message, Maybe ConvId) -connectionSelect = "SELECT left, right, status, last_update, message, conv FROM connection WHERE left = ? AND right = ?" +connectionSelect :: PrepQuery R (UserId, UserId) (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe ConvId) +connectionSelect = "SELECT left, right, status, last_update, conv FROM connection WHERE left = ? AND right = ?" relationSelect :: PrepQuery R (UserId, UserId) (Identity RelationWithHistory) relationSelect = "SELECT status FROM connection WHERE left = ? AND right = ?" @@ -174,11 +173,11 @@ connectionStatusSelect' = "SELECT left, right, status FROM connection WHERE left contactsSelect :: PrepQuery R (Identity UserId) (UserId, RelationWithHistory) contactsSelect = "SELECT right, status FROM connection WHERE left = ?" -connectionsSelect :: PrepQuery R (Identity UserId) (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe Message, Maybe ConvId) -connectionsSelect = "SELECT left, right, status, last_update, message, conv FROM connection WHERE left = ? ORDER BY right ASC" +connectionsSelect :: PrepQuery R (Identity UserId) (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe ConvId) +connectionsSelect = "SELECT left, right, status, last_update, conv FROM connection WHERE left = ? ORDER BY right ASC" -connectionsSelectFrom :: PrepQuery R (UserId, UserId) (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe Message, Maybe ConvId) -connectionsSelectFrom = "SELECT left, right, status, last_update, message, conv FROM connection WHERE left = ? AND right > ? ORDER BY right ASC" +connectionsSelectFrom :: PrepQuery R (UserId, UserId) (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe ConvId) +connectionsSelectFrom = "SELECT left, right, status, last_update, conv FROM connection WHERE left = ? AND right > ? ORDER BY right ASC" connectionDelete :: PrepQuery W (UserId, UserId) () connectionDelete = "DELETE FROM connection WHERE left = ? AND right = ?" @@ -188,8 +187,8 @@ connectionClear = "DELETE FROM connection WHERE left = ?" -- Conversions -toUserConnection :: (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe Message, Maybe ConvId) -> UserConnection -toUserConnection (l, r, relationDropHistory -> rel, time, msg, cid) = UserConnection l r rel time msg cid +toUserConnection :: (UserId, UserId, RelationWithHistory, UTCTimeMillis, Maybe ConvId) -> UserConnection +toUserConnection (l, r, relationDropHistory -> rel, time, cid) = UserConnection l r rel time cid toConnectionStatus :: (UserId, UserId, RelationWithHistory) -> ConnectionStatus toConnectionStatus (l, r, relationDropHistory -> rel) = ConnectionStatus l r rel diff --git a/services/brig/src/Brig/Data/Instances.hs b/services/brig/src/Brig/Data/Instances.hs index b2822916233..e6b7254b29d 100644 --- a/services/brig/src/Brig/Data/Instances.hs +++ b/services/brig/src/Brig/Data/Instances.hs @@ -48,8 +48,6 @@ deriving instance Cql ColourId deriving instance Cql Phone -deriving instance Cql Message - deriving instance Cql InvitationCode deriving instance Cql PasswordResetKey diff --git a/services/brig/src/Brig/IO/Intra.hs b/services/brig/src/Brig/IO/Intra.hs index 536e7c9a859..951c65c582c 100644 --- a/services/brig/src/Brig/IO/Intra.hs +++ b/services/brig/src/Brig/IO/Intra.hs @@ -532,8 +532,8 @@ createSelfConv u = do . expect2xx -- | Calls 'Galley.API.createConnectConversationH'. -createConnectConv :: UserId -> UserId -> Maybe Text -> Maybe Message -> Maybe ConnId -> AppIO ConvId -createConnectConv from to cname mess conn = do +createConnectConv :: UserId -> UserId -> Maybe Text -> Maybe ConnId -> AppIO ConvId +createConnectConv from to cname conn = do debug $ logConnection from to . remote "galley" @@ -548,7 +548,7 @@ createConnectConv from to cname mess conn = do . zUser from . maybe id (header "Z-Connection" . fromConnId) conn . contentJson - . lbytes (encode $ Connect to (messageText <$> mess) cname Nothing) + . lbytes (encode $ Connect to Nothing cname Nothing) . expect2xx -- | Calls 'Galley.API.acceptConvH'. diff --git a/services/brig/src/Brig/Provider/API.hs b/services/brig/src/Brig/Provider/API.hs index 3840df84b26..55ba100025a 100644 --- a/services/brig/src/Brig/Provider/API.hs +++ b/services/brig/src/Brig/Provider/API.hs @@ -1086,7 +1086,7 @@ maybeInvalidBot :: Maybe a -> Handler a maybeInvalidBot = maybe (throwStd invalidBot) return maybeInvalidUser :: Maybe a -> Handler a -maybeInvalidUser = maybe (throwStd invalidUser) return +maybeInvalidUser = maybe (throwStd (errorDescriptionToWai invalidUser)) return rangeChecked :: Within a n m => a -> Handler (Range n m a) rangeChecked = either (throwStd . invalidRange . fromString) return . checkedEither diff --git a/services/brig/src/Brig/Run.hs b/services/brig/src/Brig/Run.hs index 652db82c14f..7cde35593d1 100644 --- a/services/brig/src/Brig/Run.hs +++ b/services/brig/src/Brig/Run.hs @@ -107,11 +107,11 @@ mkApp o = do return (middleware e $ \reqId -> servantApp (e & requestId .~ reqId), e) where rtree :: Tree (App Handler) - rtree = compile (sitemap o) + rtree = compile sitemap middleware :: Env -> (RequestId -> Wai.Application) -> Wai.Application middleware e = - Metrics.servantPlusWAIPrometheusMiddleware (sitemap o) (Proxy @ServantCombinedAPI) + Metrics.servantPlusWAIPrometheusMiddleware sitemap (Proxy @ServantCombinedAPI) . GZip.gunzip . GZip.gzip GZip.def . catchErrors (e ^. applog) [Right $ e ^. metrics] diff --git a/services/brig/src/Brig/Team/API.hs b/services/brig/src/Brig/Team/API.hs index f1583b7cc58..f3a069dfc38 100644 --- a/services/brig/src/Brig/Team/API.hs +++ b/services/brig/src/Brig/Team/API.hs @@ -64,6 +64,7 @@ import qualified Network.Wai.Utilities.Swagger as Doc import System.Logger (Msg) import qualified System.Logger.Class as Log import Util.Logging (logFunction, logTeam) +import Wire.API.ErrorDescription import qualified Wire.API.Team.Invitation as Public import qualified Wire.API.Team.Role as Public import qualified Wire.API.Team.Size as Public @@ -88,7 +89,7 @@ routesPublic = do Doc.returns (Doc.ref Public.modelTeamInvitation) Doc.response 201 "Invitation was created and sent." Doc.end Doc.errorResponse noEmail - Doc.errorResponse (noIdentity 6) + Doc.errorResponse (errorDescriptionToWai (noIdentity 6)) Doc.errorResponse invalidEmail Doc.errorResponse blacklistedEmail Doc.errorResponse tooManyTeamInvitations @@ -256,7 +257,7 @@ createInvitationPublic uid tid body = do let inviteeRole = fromMaybe Team.defaultRole . irRole $ body inviter <- do let inviteePerms = Team.rolePermissions inviteeRole - idt <- maybe (throwStd (noIdentity 7)) return =<< lift (fetchUserIdentity uid) + idt <- maybe (throwStd (errorDescriptionToWai (noIdentity 7))) return =<< lift (fetchUserIdentity uid) from <- maybe (throwStd noEmail) return (emailIdentity idt) ensurePermissionToAddUser uid tid inviteePerms pure $ CreateInvitationInviter uid from diff --git a/services/brig/test/integration/API/User/Account.hs b/services/brig/test/integration/API/User/Account.hs index f687f1b3ded..a7a4de6b242 100644 --- a/services/brig/test/integration/API/User/Account.hs +++ b/services/brig/test/integration/API/User/Account.hs @@ -105,6 +105,7 @@ tests _ at opts p b c ch g aws = test' aws p "put /self - 200" $ testUserUpdate b c aws, test' aws p "put /access/self/email - 2xx" $ testEmailUpdate b aws, test' aws p "put /self/phone - 202" $ testPhoneUpdate b, + test' aws p "put /self/phone - 403" $ testPhoneUpdateBlacklisted b, test' aws p "head /self/password - 200/404" $ testPasswordSet b, test' aws p "put /self/password - 200" $ testPasswordChange b, test' aws p "put /self/locale - 200" $ testUserLocaleUpdate b aws, @@ -762,6 +763,22 @@ testPhoneUpdate brig = do const 200 === statusCode const (Just phn) === (userPhone <=< responseJsonMaybe) +testPhoneUpdateBlacklisted :: Brig -> Http () +testPhoneUpdateBlacklisted brig = do + uid <- userId <$> randomUser brig + phn <- randomPhone + let prefix = mkPrefix $ T.take 5 (fromPhone phn) + + insertPrefix brig prefix + let phoneUpdate = RequestBodyLBS . encode $ PhoneUpdate phn + put (brig . path "/self/phone" . contentJson . zUser uid . zConn "c" . body phoneUpdate) + !!! (const 403 === statusCode) + + -- check that phone is not updated + get (brig . path "/self" . zUser uid) !!! do + const 200 === statusCode + const (Right Nothing) === fmap userPhone . responseJsonEither + testCreateAccountPendingActivationKey :: Opt.Opts -> Brig -> Http () testCreateAccountPendingActivationKey (Opt.setRestrictUserCreation . Opt.optSettings -> Just True) _ = pure () testCreateAccountPendingActivationKey _ brig = do diff --git a/services/brig/test/integration/Main.hs b/services/brig/test/integration/Main.hs index 5f11bc49f2c..b612166de07 100644 --- a/services/brig/test/integration/Main.hs +++ b/services/brig/test/integration/Main.hs @@ -143,7 +143,7 @@ runTests iConf brigOpts otherArgs = do assertEqual "inconcistent sitemap" mempty - (pathsConsistencyCheck . treeToPaths . compile $ Brig.API.sitemap brigOpts), + (pathsConsistencyCheck . treeToPaths . compile $ Brig.API.sitemap), userApi, providerApi, searchApis, diff --git a/services/brig/test/integration/Util.hs b/services/brig/test/integration/Util.hs index c904204c408..d33c4d61c3c 100644 --- a/services/brig/test/integration/Util.hs +++ b/services/brig/test/integration/Util.hs @@ -54,6 +54,7 @@ import Data.List1 (List1) import qualified Data.List1 as List1 import Data.Misc (PlainTextPassword (..)) import Data.Qualified (Qualified (qDomain, qUnqualified)) +import Data.Range import qualified Data.Text as Text import qualified Data.Text.Ascii as Ascii import Data.Text.Encoding (encodeUtf8) @@ -406,7 +407,7 @@ postConnection brig from to = where payload = RequestBodyLBS . encode $ - ConnectionRequest to "some conv name" (Message "some message") + ConnectionRequest to (unsafeRange "some conv name") putConnection :: Brig -> UserId -> UserId -> Relation -> (MonadIO m, MonadHttp m) => m ResponseLBS putConnection brig from to r = diff --git a/services/brig/test/unit/Test/Brig/API/Error.hs b/services/brig/test/unit/Test/Brig/API/Error.hs index 10ee697bb39..18b21af6353 100644 --- a/services/brig/test/unit/Test/Brig/API/Error.hs +++ b/services/brig/test/unit/Test/Brig/API/Error.hs @@ -32,7 +32,7 @@ testFedError = testCase "when federation call fails due to requesting streaming" $ assertFedErrorStatus (mkFailure FederationClientStreamingUnsupported) 500, testCase "when federation call fails due to discovery failure" $ do - let outwardErr = FederationClientOutwardError (Proto.OutwardError Proto.DiscoveryFailed Nothing) + let outwardErr = FederationClientOutwardError (Proto.OutwardError Proto.DiscoveryFailed "discovery failed") assertFedErrorStatus (mkFailure outwardErr) 500, testCase "when federation call fails due to decode failure" $ assertFedErrorStatus (mkFailure (FederationClientServantError (Servant.DecodeFailure "some failure" emptyRes))) 533, @@ -58,31 +58,23 @@ testOutwardError = assertOutwardErrorStatus Proto.ConnectionRefused 521, testCase "when TLS fails" $ assertOutwardErrorStatus Proto.TLSFailure 525, - testCase "when remote certificate is invalid" $ - assertOutwardErrorStatus Proto.InvalidCertificate 526, testCase "when remote returns version mismatch" $ assertOutwardErrorStatus Proto.VersionMismatch 531, testCase "when remote denies federation" $ assertOutwardErrorStatus Proto.FederationDeniedByRemote 532, testCase "when local federator denies federation" $ assertOutwardErrorStatus Proto.FederationDeniedLocally 400, - testCase "when remote federator errors" $ - assertOutwardErrorStatus Proto.RemoteFederatorError 533, + testCase "when there is too much concurrency" $ + assertOutwardErrorStatus Proto.TooMuchConcurrency 533, + testCase "when gRPC fails" $ + assertOutwardErrorStatus Proto.GrpcError 533, testCase "when federator returns invalid request" $ assertOutwardErrorStatus Proto.InvalidRequest 500 ], - testGroup "label & message" $ - [ testCase "when error payload is specified" $ do - let outwardErr = Proto.OutwardError Proto.TLSFailure . Just $ Proto.ErrorPayload "an-interesting-label" "very interesting message" - waiErr = federationRemoteError outwardErr - assertEqual "label should be copied" (Wai.label waiErr) "an-interesting-label" - assertEqual "message should be copied" (Wai.message waiErr) "very interesting message", - testCase "when error payload is not specified" $ do - let outwardErr = Proto.OutwardError Proto.TLSFailure Nothing - waiErr = federationRemoteError outwardErr - assertEqual "label should be set as unknown" (Wai.label waiErr) "unknown-federation-error" - assertEqual "message should be set as unknown" (Wai.message waiErr) "Unknown federation error" - ] + testCase "error message" $ do + let outwardErr = Proto.OutwardError Proto.TLSFailure "something went wrong" + waiErr = federationRemoteError outwardErr + assertEqual "message should be copied" (Wai.message waiErr) "something went wrong" ] mkFailure :: FederationClientError -> FederationError @@ -95,7 +87,7 @@ assertFedErrorStatus err sts = assertEqual ("http status should be " <> show sts assertOutwardErrorStatus :: HasCallStack => Proto.OutwardErrorType -> Int -> IO () assertOutwardErrorStatus errType sts = - assertEqual ("http status should be " <> show sts) (HTTP.statusCode . Wai.code . federationRemoteError $ Proto.OutwardError errType Nothing) sts + assertEqual ("http status should be " <> show sts) (HTTP.statusCode . Wai.code . federationRemoteError $ Proto.OutwardError errType mempty) sts statusFor :: FederationError -> Int statusFor = HTTP.statusCode . errorStatus . fedError diff --git a/services/federator/federator.cabal b/services/federator/federator.cabal index 30ce16ef3d6..ade0ac73324 100644 --- a/services/federator/federator.cabal +++ b/services/federator/federator.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: aef5b26595440dc41b2afea5b58468827dd4bdc290b406e49e8e2263ad2a81ad +-- hash: 9a181e3a92130220d845ad959ca6e02a217b07a38602513bff4c9376a4ffe145 name: federator version: 1.0.0 @@ -40,6 +40,8 @@ library Federator.Env Federator.ExternalServer Federator.InternalServer + Federator.Monitor + Federator.Monitor.Internal Federator.Options Federator.Remote Federator.Run @@ -59,12 +61,15 @@ library , base , bilge , bytestring + , containers , data-default , dns , dns-util , either , exceptions , extended + , filepath + , hinotify , http-client , http-client-openssl , http-types @@ -90,6 +95,7 @@ library , tinylog , tls , types-common + , unix , unliftio , uri-bytestring , uuid @@ -119,6 +125,7 @@ executable federator , base , bilge , bytestring + , containers , data-default , dns , dns-util @@ -126,6 +133,8 @@ executable federator , exceptions , extended , federator + , filepath + , hinotify , http-client , http-client-openssl , http-types @@ -151,6 +160,7 @@ executable federator , tinylog , tls , types-common + , unix , unliftio , uri-bytestring , uuid @@ -184,6 +194,7 @@ executable federator-integration , base , bilge , bytestring + , containers , cryptonite , data-default , dns @@ -192,6 +203,8 @@ executable federator-integration , exceptions , extended , federator + , filepath + , hinotify , hspec , http-client , http-client-openssl @@ -222,6 +235,7 @@ executable federator-integration , tinylog , tls , types-common + , unix , unliftio , uri-bytestring , uuid @@ -243,6 +257,7 @@ test-suite federator-tests other-modules: Test.Federator.ExternalServer Test.Federator.InternalServer + Test.Federator.Monitor Test.Federator.Options Test.Federator.Remote Test.Federator.Validation @@ -258,13 +273,17 @@ test-suite federator-tests , base , bilge , bytestring + , containers , data-default + , directory , dns , dns-util , either , exceptions , extended , federator + , filepath + , hinotify , http-client , http-client-openssl , http-types @@ -291,10 +310,14 @@ test-suite federator-tests , string-conversions , tasty , tasty-hunit + , tasty-quickcheck + , temporary , text , tinylog , tls + , transformers , types-common + , unix , unliftio , uri-bytestring , uuid diff --git a/services/federator/federator.integration.yaml b/services/federator/federator.integration.yaml index 5e450f0efc0..76077df2b84 100644 --- a/services/federator/federator.integration.yaml +++ b/services/federator/federator.integration.yaml @@ -31,7 +31,7 @@ optSettings: # - wire.com # - example.com - useSystemCAStore: true + useSystemCAStore: false clientCertificate: "test/resources/integration-leaf.pem" clientPrivateKey: "test/resources/integration-leaf-key.pem" diff --git a/services/federator/package.yaml b/services/federator/package.yaml index ceff6710be0..8db0783a9d0 100644 --- a/services/federator/package.yaml +++ b/services/federator/package.yaml @@ -14,12 +14,15 @@ dependencies: - base - bilge - bytestring +- containers - data-default - dns - dns-util - either - exceptions - extended +- filepath +- hinotify - HsOpenSSL - HsOpenSSL-x509-system - http2-client @@ -47,6 +50,7 @@ dependencies: - tinylog - tls - types-common +- unix - unliftio - uri-bytestring - uuid @@ -100,12 +104,16 @@ tests: - -with-rtsopts=-N dependencies: - bytestring + - directory - federator - interpolate - polysemy-mocks - streaming-commons - tasty + - tasty-quickcheck - tasty-hunit + - temporary + - transformers - wai - warp - warp-tls diff --git a/services/federator/src/Federator/Env.hs b/services/federator/src/Federator/Env.hs index 71d1f17817c..b17a3b56591 100644 --- a/services/federator/src/Federator/Env.hs +++ b/services/federator/src/Federator/Env.hs @@ -26,6 +26,7 @@ import Control.Lens (makeLenses) import Data.Metrics (Metrics) import Data.X509.CertificateStore import Federator.Options (RunSettings) +import Imports import Network.DNS.Resolver (Resolver) import qualified Network.HTTP.Client as HTTP import qualified Network.TLS as TLS @@ -45,7 +46,7 @@ data Env = Env _runSettings :: RunSettings, _service :: Component -> RPC.Request, _httpManager :: HTTP.Manager, - _tls :: TLSSettings + _tls :: IORef TLSSettings } makeLenses ''TLSSettings diff --git a/services/federator/src/Federator/InternalServer.hs b/services/federator/src/Federator/InternalServer.hs index 49d77c860b0..936464fc30a 100644 --- a/services/federator/src/Federator/InternalServer.hs +++ b/services/federator/src/Federator/InternalServer.hs @@ -38,15 +38,20 @@ import Mu.GRpc.Client.Record (GRpcReply (..)) import Mu.GRpc.Server (msgProtoBuf, runGRpcAppTrans) import Mu.Server (ServerError, ServerErrorIO, SingleServerT, singleService) import qualified Mu.Server as Mu +import Network.HTTP2.Client.Exceptions (ClientError (..)) +import Network.TLS import Polysemy import qualified Polysemy.Error as Polysemy import Polysemy.IO (embedToMonadIO) +import qualified Polysemy.Input as Polysemy import qualified Polysemy.Reader as Polysemy import Polysemy.TinyLog (TinyLog) import qualified Polysemy.TinyLog as Log +import Wire.API.Federation.GRPC.Client (GrpcClientErr (..)) import Wire.API.Federation.GRPC.Types import Wire.Network.DNS.Effect (DNSLookup) import qualified Wire.Network.DNS.Effect as Lookup +import Wire.Network.DNS.SRV (SrvTarget (..)) callOutward :: Members '[Remote, Polysemy.Reader RunSettings] r => FederatedRequest -> Sem r OutwardResponse callOutward req = do @@ -55,9 +60,9 @@ callOutward req = do allowedRemote <- federateWith (vDomain vReq) if allowedRemote then mkRemoteResponse <$> discoverAndCall vReq - else pure $ mkOutwardErr FederationDeniedLocally "federation-not-allowed" ("federating with domain [" <> domainText (vDomain vReq) <> "] is not allowed (see federator configuration)") + else pure $ mkOutwardErr FederationDeniedLocally ("federating with domain [" <> domainText (vDomain vReq) <> "] is not allowed (see federator configuration)") Failure errs -> - pure $ mkOutwardErr InvalidRequest "invalid-request-to-federator" ("validation failed with: " <> Text.pack (show errs)) + pure $ mkOutwardErr InvalidRequest ("validation failed with: " <> Text.pack (show errs)) -- FUTUREWORK(federation): Make these errors less stringly typed mkRemoteResponse :: Either RemoteError (GRpcReply InwardResponse) -> OutwardResponse @@ -67,26 +72,51 @@ mkRemoteResponse reply = OutwardResponseBody res Right (GRpcOk (InwardResponseError err)) -> OutwardResponseInwardError err Right (GRpcTooMuchConcurrency _) -> - mkOutwardErr RemoteFederatorError "too-much-concurrency" "Too much concurrency" - Right (GRpcErrorCode grpcErr) -> - mkOutwardErr RemoteFederatorError "grpc-error-code" ("code=" <> Text.pack (show grpcErr)) - Right (GRpcErrorString grpcErr) -> - mkOutwardErr RemoteFederatorError "grpc-error-string" ("error=" <> Text.pack grpcErr) - Right (GRpcClientError clientErr) -> - mkOutwardErr RemoteFederatorError "grpc-client-error" ("error=" <> Text.pack (show clientErr)) + mkOutwardErr TooMuchConcurrency "Too much concurrency" + Right (GRpcErrorCode code) -> + mkOutwardErr GrpcError ("code: " <> Text.pack (show code)) + Right (GRpcErrorString msg) -> + mkOutwardErr GrpcError (Text.pack msg) + Right (GRpcClientError EarlyEndOfStream) -> mkOutwardErr GrpcError "Early end of stream" Left (RemoteErrorDiscoveryFailure domain err) -> case err of LookupErrorSrvNotAvailable _srvDomain -> - mkOutwardErr RemoteNotFound "srv-record-not-found" ("domain=" <> domainText domain) + mkOutwardErr RemoteNotFound ("domain=" <> domainText domain) LookupErrorDNSError dnsErr -> - mkOutwardErr DiscoveryFailed "srv-lookup-dns-error" ("domain=" <> domainText domain <> "; error=" <> Text.decodeUtf8 dnsErr) - Left (RemoteErrorClientFailure srvTarget cltErr) -> - mkOutwardErr RemoteFederatorError "cannot-connect-to-remote-federator" ("target=" <> Text.pack (show srvTarget) <> "; error=" <> Text.pack (show cltErr)) - Left (RemoteErrorTLSException srvTarget exc) -> - mkOutwardErr TLSFailure "tls-failure" ("Failed to establish TLS session with remote: target=" <> Text.pack (show srvTarget) <> "; exception=" <> Text.pack (show exc)) + mkOutwardErr DiscoveryFailed ("domain=" <> domainText domain <> " error=" <> Text.decodeUtf8 dnsErr) + Left (RemoteErrorClientFailure (SrvTarget host port) (GrpcClientErr reason)) -> + mkOutwardErr + GrpcError + (reason <> " target=" <> Text.decodeUtf8 host <> ":" <> Text.pack (show port)) + Left (RemoteErrorTLSException (SrvTarget host port) exc) -> + mkOutwardErr + TLSFailure + ( "Failed to establish TLS session with remote (target=" + <> Text.decodeUtf8 host + <> ":" + <> Text.pack (show port) + <> "): " + <> showTLSException exc + ) -mkOutwardErr :: OutwardErrorType -> Text -> Text -> OutwardResponse -mkOutwardErr typ label msg = OutwardResponseError $ OutwardError typ (Just $ ErrorPayload label msg) +showTLSException :: TLSException -> Text +showTLSException (Terminated _ reason err) = Text.pack reason <> ": " <> showTLSError err +showTLSException (HandshakeFailed err) = Text.pack "handshake failed: " <> showTLSError err +showTLSException ConnectionNotEstablished = Text.pack "connection not established" + +showTLSError :: TLSError -> Text +showTLSError (Error_Misc msg) = Text.pack msg +showTLSError (Error_Protocol (msg, _, _)) = "protocol error: " <> Text.pack msg +showTLSError (Error_Certificate msg) = "certificate error: " <> Text.pack msg +showTLSError (Error_HandshakePolicy msg) = "handshake policy error: " <> Text.pack msg +showTLSError Error_EOF = "end-of-file error" +showTLSError (Error_Packet msg) = "packet error: " <> Text.pack msg +showTLSError (Error_Packet_unexpected actual expected) = + "unexpected packet: " <> Text.pack expected <> ", " <> "got " <> Text.pack actual +showTLSError (Error_Packet_Parsing msg) = "packet parsing error: " <> Text.pack msg + +mkOutwardErr :: OutwardErrorType -> Text -> OutwardResponse +mkOutwardErr typ msg = OutwardResponseError $ OutwardError typ msg outward :: (Members '[Remote, Polysemy.Error ServerError, Polysemy.Reader RunSettings] r) => SingleServerT info Outward (Sem r) _ outward = singleService (Mu.method @"call" callOutward) @@ -102,9 +132,9 @@ serveOutward env port = do TinyLog, DNSLookup, Polysemy.Error ServerError, - Embed IO, Polysemy.Reader RunSettings, - Polysemy.Reader TLSSettings, + Polysemy.Input TLSSettings, + Embed IO, Embed Federator ] a -> @@ -112,9 +142,9 @@ serveOutward env port = do transformer action = runAppT env . runM -- Embed Federator - . Polysemy.runReader (view tls env) -- Reader TLSSettings - . Polysemy.runReader (view runSettings env) -- Reader RunSettings . embedToMonadIO @Federator -- Embed IO + . Polysemy.runInputSem (embed @IO (readIORef (view tls env))) -- Input TLSSettings + . Polysemy.runReader (view runSettings env) -- Reader RunSettings . absorbServerError . Lookup.runDNSLookupWithResolver (view dnsResolver env) . Log.runTinyLog (view applog env) diff --git a/services/federator/src/Federator/Monitor.hs b/services/federator/src/Federator/Monitor.hs new file mode 100644 index 00000000000..9e3c5e07444 --- /dev/null +++ b/services/federator/src/Federator/Monitor.hs @@ -0,0 +1,53 @@ +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2021 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + +module Federator.Monitor + ( withMonitor, + mkTLSSettingsOrThrow, + FederationSetupError (..), + ) +where + +import Control.Exception (bracket, throw) +import Federator.Env (TLSSettings (..)) +import Federator.Monitor.Internal +import Federator.Options (RunSettings (..)) +import Imports +import qualified Polysemy +import qualified Polysemy.Error as Polysemy +import System.Logger (Logger) + +mkTLSSettingsOrThrow :: RunSettings -> IO TLSSettings +mkTLSSettingsOrThrow = + Polysemy.runM + . (either (Polysemy.embed @IO . throw) pure =<<) + . Polysemy.runError @FederationSetupError + . mkTLSSettings + +withMonitor :: Logger -> IORef TLSSettings -> RunSettings -> IO a -> IO a +withMonitor logger tlsVar rs action = + bracket + ( runSemDefault + logger + ( mkMonitor + (runSemDefault logger . logAndIgnoreErrors) + tlsVar + rs + ) + ) + (runSemDefault logger . delMonitor) + (const action) diff --git a/services/federator/src/Federator/Monitor/Internal.hs b/services/federator/src/Federator/Monitor/Internal.hs new file mode 100644 index 00000000000..28351d384db --- /dev/null +++ b/services/federator/src/Federator/Monitor/Internal.hs @@ -0,0 +1,372 @@ +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2021 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + +module Federator.Monitor.Internal where + +import Control.Exception (try) +import Data.ByteString (packCStringLen) +import qualified Data.Map as Map +import qualified Data.Set as Set +import qualified Data.Text as Text +import qualified Data.Text.Encoding as Text +import qualified Data.Text.Encoding.Error as Text +import qualified Data.X509 as X509 +import Data.X509.CertificateStore +import Federator.Env (TLSSettings (..)) +import Federator.Options (RunSettings (..)) +import GHC.Foreign (withCStringLen) +import GHC.IO.Encoding (getFileSystemEncoding) +import Imports +import qualified Network.TLS as TLS +import Polysemy (Embed, Member, Members, Sem, embed) +import qualified Polysemy +import qualified Polysemy.Error as Polysemy +import qualified Polysemy.Resource as Polysemy +import Polysemy.TinyLog (TinyLog) +import qualified Polysemy.TinyLog as Log +import System.FilePath +import System.INotify +import System.Logger (Logger) +import qualified System.Logger.Message as Log +import System.Posix.ByteString (RawFilePath) +import System.Posix.Files +import System.X509 +import Wire.API.Arbitrary + +data Monitor = Monitor + { monINotify :: INotify, + monTLS :: IORef TLSSettings, + monWatches :: IORef Watches, + monSettings :: RunSettings, + monHandler :: WatchedPath -> Event -> IO (), + monLock :: MVar () + } + +-- This is needed because the normal Posix file system API uses strings, while +-- the inotify API uses bytestrings. +-- /Note/: File paths are strings obtained using the "file system encoding", +-- which is the same as the locale encoding, but uses some escaping tricks to +-- be able to represent arbitrary data as strings. +rawPath :: FilePath -> IO RawFilePath +rawPath path = do + encoding <- getFileSystemEncoding + withCStringLen encoding path packCStringLen + +data WatchedPath + = WatchedFile RawFilePath + | WatchedDir RawFilePath (Set RawFilePath) + deriving stock (Eq, Ord, Show, Generic) + deriving (Arbitrary) via (GenericUniform WatchedPath) + +mergePaths :: [WatchedPath] -> (Set WatchedPath) +mergePaths = Set.fromList . merge . sort + where + merge [] = [] + merge [w] = [w] + merge (w1 : w2 : ws) = case (w1, w2) of + (_, WatchedFile _) -> w1 : w2 : merge ws + (WatchedDir dir1 paths1, WatchedDir dir2 paths2) + | dir1 == dir2 -> merge (WatchedDir dir1 (paths1 <> paths2) : ws) + _ -> w1 : merge (w2 : ws) + +watchedPath :: WatchedPath -> RawFilePath +watchedPath (WatchedFile path) = path +watchedPath (WatchedDir dir _) = dir + +watchPathEvents :: WatchedPath -> [EventVariety] +watchPathEvents (WatchedFile _) = [CloseWrite] +watchPathEvents (WatchedDir _ _) = [MoveIn, Create] + +-- Since we are watching a filesystem path, and not an inode, we need to replace a +-- file watch when the file gets overwritten. +-- This type is a map of paths to watches used to keep track of both file and +-- directory watches as they get deleted and recreated. +type Watches = Map RawFilePath (WatchDescriptor, WatchedPath) + +runSemDefault :: Logger -> Sem '[TinyLog, Embed IO] a -> IO a +runSemDefault logger = Polysemy.runM . Log.runTinyLog logger + +logErrors :: + Members '[TinyLog, Polysemy.Error FederationSetupError] r => + Sem r a -> + Sem r a +logErrors action = Polysemy.catch action $ \err -> do + Log.err $ + Log.msg ("federation setup error while updating certificates" :: Text) + . Log.field "error" (showFederationSetupError err) + Polysemy.throw err + +logAndIgnoreErrors :: + Member TinyLog r => + Sem (Polysemy.Error FederationSetupError ': r) () -> + Sem r () +logAndIgnoreErrors = void . Polysemy.runError . logErrors + +delMonitor :: + (Members '[TinyLog, Embed IO] r) => + Monitor -> + Sem r () +delMonitor monitor = Polysemy.resourceToIO $ + Polysemy.bracket + (takeMVar (monLock monitor)) + (putMVar (monLock monitor)) + . const + $ do + watches <- readIORef (monWatches monitor) + traverse_ stop watches + where + stop (wd, _) = do + -- ignore exceptions when removing watches + embed . void . try @IOException $ removeWatch wd + Log.debug $ + Log.msg ("stopped watching file" :: Text) + . Log.field "descriptor" (show wd) + +mkMonitor :: + ( Members '[TinyLog, Embed IO] r, + Members '[TinyLog, Embed IO, Polysemy.Error FederationSetupError] r1 + ) => + (Sem r1 () -> IO ()) -> + IORef TLSSettings -> + RunSettings -> + Sem r Monitor +mkMonitor runSem tlsVar rs = do + inotify <- embed initINotify + Log.debug $ + Log.msg ("inotify initialized" :: Text) + . Log.field "inotify" (show inotify) + + lock <- embed @IO $ newMVar () + watchesVar <- embed @IO $ newIORef mempty + + let monitor = + Monitor + { monINotify = inotify, + monTLS = tlsVar, + monWatches = watchesVar, + monSettings = rs, + monHandler = handleEvent runSem monitor, + monLock = lock + } + + paths <- embed $ certificateWatchPaths rs + traverse_ (addWatchedFile monitor) (toList paths) + pure monitor + +data Action = ReplaceWatch RawFilePath | ReloadSettings + deriving (Eq, Ord, Show) + +handleEvent :: + Members '[TinyLog, Embed IO, Polysemy.Error FederationSetupError] r => + (Sem r () -> IO ()) -> + Monitor -> + WatchedPath -> + Event -> + IO () +handleEvent runSem monitor wpath e = do + let actions = getActions wpath e + -- only use runSem when there are some actions + -- this makes it possible to use a special runSem in the tests that is able + -- to detect when some action has taken place + unless (null actions) $ + -- we take the lock here, so that handlers never execute concurrently + withMVar (monLock monitor) $ \_ -> + runSem $ traverse_ (applyAction monitor) actions + +-- Note: it is important that the watch is replaced *before* settings are +-- reloaded, otherwise there is a window of time (after reloading settings, +-- but before the new watch is set) where changes to the settings can go +-- undetected +getActions :: WatchedPath -> Event -> [Action] +getActions (WatchedFile path) (Closed _ mpath True) + | maybe True (== path) mpath = [ReloadSettings] +getActions (WatchedDir dir paths) (MovedIn _ path _) + | Set.member path paths = [ReplaceWatch (dir <> "/" <> path), ReloadSettings] +getActions (WatchedDir dir paths) (Created _ path) + | Set.member path paths = [ReplaceWatch (dir <> "/" <> path), ReloadSettings] +getActions _ _ = [] + +applyAction :: + (Members '[TinyLog, Embed IO, Polysemy.Error FederationSetupError] r) => + Monitor -> + Action -> + Sem r () +applyAction monitor ReloadSettings = do + tls' <- mkTLSSettings (monSettings monitor) + Log.info $ Log.msg ("updating TLS settings" :: Text) + embed @IO $ atomicWriteIORef (monTLS monitor) tls' +applyAction monitor (ReplaceWatch path) = do + watches <- readIORef (monWatches monitor) + case Map.lookup path watches of + Nothing -> pure () + Just (_, wpath) -> do + addWatchedFile monitor wpath + case wpath of + WatchedDir dir paths -> + traverse_ (applyAction monitor . ReplaceWatch . ((dir <> "/") <>)) paths + WatchedFile _ -> pure () + +addWatchedFile :: + Members '[TinyLog, Embed IO] r => + Monitor -> + WatchedPath -> + Sem r () +addWatchedFile monitor wpath = do + r <- + embed . try @SomeException $ + addWatchAndSave + (monINotify monitor) + (watchPathEvents wpath) + (monWatches monitor) + wpath + (monHandler monitor wpath) + let pathText = Text.decodeUtf8With Text.lenientDecode (watchedPath wpath) + case r of + Right w -> + Log.debug $ + Log.msg ("watching file" :: Text) + . Log.field "descriptor" (show w) + . Log.field "path" pathText + Left e -> do + Log.err $ + Log.msg ("error while try to add file watch" :: Text) + . Log.field "path" pathText + . Log.field "error" (displayException e) + +addWatchAndSave :: + INotify -> + [EventVariety] -> + IORef Watches -> + WatchedPath -> + (Event -> IO ()) -> + IO WatchDescriptor +addWatchAndSave inotify events watchesVar wpath handler = do + let path = watchedPath wpath + -- create a new watch + w' <- addWatch inotify events path handler + -- atomically save it in the map, and return the old one + mw <- + atomicModifyIORef watchesVar $ + swap . Map.alterF (,Just (w', wpath)) path + -- remove the old watch + case mw of + Nothing -> pure () + Just (w, _) -> void . try @IOException $ removeWatch w + pure w' + +certificatePaths :: RunSettings -> [FilePath] +certificatePaths rs = + maybeToList (remoteCAStore rs) + ++ [ clientCertificate rs, + clientPrivateKey rs + ] + +certificateWatchPaths :: RunSettings -> IO (Set WatchedPath) +certificateWatchPaths = + fmap (mergePaths . concat) + . traverse (watchedPaths resolveSymlink) + . certificatePaths + +resolveSymlink :: FilePath -> IO (Maybe FilePath) +resolveSymlink path' = do + let path = dropTrailingPathSeparator path' + status <- getSymbolicLinkStatus path + if isSymbolicLink status + then do + target <- readSymbolicLink path + pure . Just $ + if isRelative target + then takeDirectory path target + else target + else pure Nothing + +watchedPaths :: (FilePath -> IO (Maybe FilePath)) -> FilePath -> IO [WatchedPath] +watchedPaths resolve path' = do + path <- makeAbsolute path' + rpath <- rawPath path + dirs <- watchedDirs resolve path + pure $ WatchedFile rpath : dirs + +watchedDirs :: (FilePath -> IO (Maybe FilePath)) -> FilePath -> IO [WatchedPath] +watchedDirs resolve path = do + dirs0 <- resolve path >>= maybe (pure []) (watchedDirs resolve) + let (dir, base) = splitFileName (dropTrailingPathSeparator path) + dirs1 <- + if dir == path + then pure [] -- base case: root directory + else do + wds <- watchedDirs resolve dir + rdir <- rawPath (dropTrailingPathSeparator dir) + rbase <- rawPath base + pure $ WatchedDir rdir (Set.singleton rbase) : wds + pure (dirs0 ++ dirs1) + +data FederationSetupError + = InvalidCAStore FilePath + | InvalidClientCertificate String + deriving (Show) + +instance Exception FederationSetupError + +showFederationSetupError :: FederationSetupError -> Text +showFederationSetupError (InvalidCAStore path) = "invalid CA store: " <> Text.pack path +showFederationSetupError (InvalidClientCertificate msg) = Text.pack msg + +mkTLSSettings :: + Members '[Embed IO, Polysemy.Error FederationSetupError] r => + RunSettings -> + Sem r TLSSettings +mkTLSSettings settings = + TLSSettings + <$> mkCAStore settings + <*> mkCreds settings + +mkCAStore :: + Members '[Embed IO, Polysemy.Error FederationSetupError] r => + RunSettings -> + Sem r CertificateStore +mkCAStore settings = do + customCAStore <- fmap (fromRight mempty) . Polysemy.runError @() $ do + path <- maybe (Polysemy.throw ()) pure $ remoteCAStore settings + embed (readCertificateStore path) + >>= maybe (Polysemy.throw (InvalidCAStore path)) pure + systemCAStore <- + if useSystemCAStore settings + then embed getSystemCertificateStore + else pure mempty + pure (customCAStore <> systemCAStore) + +mkCreds :: + Members '[Embed IO, Polysemy.Error FederationSetupError] r => + RunSettings -> + Sem r TLS.Credential +mkCreds settings = do + creds <- + Polysemy.fromExceptionVia + @SomeException + (InvalidClientCertificate . displayException) + $ TLS.credentialLoadX509 + (clientCertificate settings) + (clientPrivateKey settings) + case creds of + Left e -> Polysemy.throw (InvalidClientCertificate e) + Right (X509.CertificateChain [], _) -> + Polysemy.throw + ( InvalidClientCertificate + "could not read client certificate" + ) + Right x -> pure x diff --git a/services/federator/src/Federator/Remote.hs b/services/federator/src/Federator/Remote.hs index 13ea7d5c7cf..38e6a143f91 100644 --- a/services/federator/src/Federator/Remote.hs +++ b/services/federator/src/Federator/Remote.hs @@ -46,6 +46,7 @@ import Network.TLS as TLS import qualified Network.TLS.Extra.Cipher as TLS import Polysemy import qualified Polysemy.Error as Polysemy +import qualified Polysemy.Input as Polysemy import qualified Polysemy.Reader as Polysemy import Polysemy.TinyLog (TinyLog) import qualified Polysemy.TinyLog as Log @@ -71,7 +72,7 @@ interpretRemote :: DiscoverFederator, TinyLog, Polysemy.Reader RunSettings, - Polysemy.Reader TLSSettings + Polysemy.Input TLSSettings ] r => Sem (Remote ': r) a -> @@ -116,7 +117,7 @@ mkGrpcClient :: Members '[ Embed IO, Polysemy.Error RemoteError, - Polysemy.Reader TLSSettings + Polysemy.Input TLSSettings ] r => SrvTarget -> @@ -127,7 +128,7 @@ mkGrpcClient target@(SrvTarget host port) = do -- let cfg = grpcClientConfigSimple (cs host) (fromInteger $ toInteger port) True - settings <- Polysemy.ask + settings <- Polysemy.input let tlsConfig = (defaultParamsClient (cs host) (cs $ show port)) diff --git a/services/federator/src/Federator/Run.hs b/services/federator/src/Federator/Run.hs index ddae51d8f1f..bd0e786eee1 100644 --- a/services/federator/src/Federator/Run.hs +++ b/services/federator/src/Federator/Run.hs @@ -26,33 +26,29 @@ module Federator.Run -- * App Environment newEnv, - mkTLSSettings, - FederationSetupError (..), closeEnv, + + -- * Re-exports + mkTLSSettingsOrThrow, + FederationSetupError (..), ) where import qualified Bilge as RPC -import Control.Exception (handle, throw) import Control.Lens ((^.)) import Data.Default (def) import qualified Data.Metrics.Middleware as Metrics import Data.Text.Encoding (encodeUtf8) -import qualified Data.X509 as X509 -import Data.X509.CertificateStore import Federator.Env import Federator.ExternalServer (serveInward) import Federator.InternalServer (serveOutward) +import Federator.Monitor import Federator.Options as Opt import Imports import qualified Network.DNS as DNS import qualified Network.HTTP.Client as HTTP -import qualified Network.TLS as TLS -import qualified Polysemy -import qualified Polysemy.Error as Polysemy import qualified System.Logger.Class as Log import qualified System.Logger.Extended as LogExt -import System.X509 import UnliftIO (bracket) import UnliftIO.Async (async, waitAnyCancel) import Util.Options @@ -74,9 +70,10 @@ run opts = do bracket (newEnv opts res) closeEnv $ \env -> do let externalServer = serveInward env portExternal internalServer = serveOutward env portInternal - internalServerThread <- async internalServer - externalServerThread <- async externalServer - void $ waitAnyCancel [internalServerThread, externalServerThread] + withMonitor (env ^. applog) (env ^. tls) (optSettings opts) $ do + internalServerThread <- async internalServer + externalServerThread <- async externalServer + void $ waitAnyCancel [internalServerThread, externalServerThread] where endpointInternal = federatorInternal opts portInternal = fromIntegral $ endpointInternal ^. epPort @@ -96,13 +93,6 @@ run opts = do ------------------------------------------------------------------------------- -- Environment -data FederationSetupError - = InvalidCAStore FilePath - | InvalidClientCertificate String - deriving (Show) - -instance Exception FederationSetupError - newEnv :: Opts -> DNS.Resolver -> IO Env newEnv o _dnsResolver = do _metrics <- Metrics.metrics @@ -112,41 +102,11 @@ newEnv o _dnsResolver = do let _service Brig = mkEndpoint (Opt.brig o) _service Galley = mkEndpoint (Opt.galley o) _httpManager <- initHttpManager - _tls <- mkTLSSettings _runSettings + _tls <- mkTLSSettingsOrThrow _runSettings >>= newIORef return Env {..} where mkEndpoint s = RPC.host (encodeUtf8 (s ^. epHost)) . RPC.port (s ^. epPort) $ RPC.empty -mkCAStore :: RunSettings -> IO CertificateStore -mkCAStore settings = do - customCAStore <- fmap (fromRight mempty) . Polysemy.runM . Polysemy.runError @() $ do - path <- maybe (Polysemy.throw ()) pure $ remoteCAStore settings - Polysemy.embed $ readCertificateStore path >>= maybe (throw $ InvalidCAStore path) pure - systemCAStore <- - if useSystemCAStore settings - then getSystemCertificateStore - else pure mempty - pure (customCAStore <> systemCAStore) - -mkCreds :: RunSettings -> IO TLS.Credential -mkCreds settings = - handle h $ - TLS.credentialLoadX509 (clientCertificate settings) (clientPrivateKey settings) - >>= \case - Left e -> throw (InvalidClientCertificate e) - Right (X509.CertificateChain [], _) -> - throw (InvalidClientCertificate "could not read client certificate") - Right x -> pure x - where - h :: IOException -> IO a - h = throw . InvalidClientCertificate . show - -mkTLSSettings :: RunSettings -> IO TLSSettings -mkTLSSettings settings = - TLSSettings - <$> mkCAStore settings - <*> mkCreds settings - closeEnv :: Env -> IO () closeEnv e = do Log.flush $ e ^. applog diff --git a/services/federator/test/integration/Test/Federator/IngressSpec.hs b/services/federator/test/integration/Test/Federator/IngressSpec.hs index 5d0fe918451..8d87ff53fa5 100644 --- a/services/federator/test/integration/Test/Federator/IngressSpec.hs +++ b/services/federator/test/integration/Test/Federator/IngressSpec.hs @@ -36,6 +36,7 @@ import Network.GRPC.Client.Helpers (_grpcClientConfigTLS) import qualified Network.TLS as TLS import qualified Polysemy import qualified Polysemy.Error as Polysemy +import qualified Polysemy.Input as Polysemy import qualified Polysemy.Reader as Polysemy import Polysemy.TinyLog (discardLogs) import Test.Federator.Util @@ -108,7 +109,7 @@ inwardBrigCallViaIngress requestPath payload = do . Polysemy.runM . Polysemy.runError @RemoteError . discardLogs - . Polysemy.runReader tlsSettings + . Polysemy.runInputConst tlsSettings . Polysemy.runReader runSettings $ mkGrpcClient target client <- case c of diff --git a/services/federator/test/integration/Test/Federator/Util.hs b/services/federator/test/integration/Test/Federator/Util.hs index fd052265cff..bf7835bcda2 100644 --- a/services/federator/test/integration/Test/Federator/Util.hs +++ b/services/federator/test/integration/Test/Federator/Util.hs @@ -45,7 +45,7 @@ import qualified Data.UUID.V4 as UUID import qualified Data.Yaml as Yaml import Federator.Env (TLSSettings (..)) import Federator.Options -import Federator.Run (mkTLSSettings) +import Federator.Run (mkTLSSettingsOrThrow) import Imports import Mu.GRpc.Client.TyApps import qualified Options.Applicative as OPA @@ -144,7 +144,7 @@ mkEnv :: HasCallStack => IntegrationConfig -> Opts -> IO TestEnv mkEnv _teTstOpts _teOpts = do _teMgr :: Manager <- newManager defaultManagerSettings let _teBrig = endpointToReq (cfgBrig _teTstOpts) - _teTLSSettings <- mkTLSSettings (optSettings _teOpts) + _teTLSSettings <- mkTLSSettingsOrThrow (optSettings _teOpts) pure TestEnv {..} destroyEnv :: HasCallStack => TestEnv -> IO () diff --git a/services/federator/test/unit/Main.hs b/services/federator/test/unit/Main.hs index 65efc215a74..7cd09476a6c 100644 --- a/services/federator/test/unit/Main.hs +++ b/services/federator/test/unit/Main.hs @@ -23,6 +23,7 @@ where import Imports import qualified Test.Federator.ExternalServer import qualified Test.Federator.InternalServer +import qualified Test.Federator.Monitor import qualified Test.Federator.Options import qualified Test.Federator.Remote import qualified Test.Federator.Validation as Validation @@ -37,5 +38,6 @@ main = Validation.tests, Test.Federator.InternalServer.tests, Test.Federator.ExternalServer.tests, + Test.Federator.Monitor.tests, Test.Federator.Remote.tests ] diff --git a/services/federator/test/unit/Test/Federator/InternalServer.hs b/services/federator/test/unit/Test/Federator/InternalServer.hs index 6b691de7c56..1d30b640cfb 100644 --- a/services/federator/test/unit/Test/Federator/InternalServer.hs +++ b/services/federator/test/unit/Test/Federator/InternalServer.hs @@ -26,7 +26,7 @@ import Federator.Options (AllowedDomains (..), FederationStrategy (..), RunSetti import Federator.Remote (Remote, RemoteError (RemoteErrorDiscoveryFailure)) import Imports import Mu.GRpc.Client.Record -import Network.HTTP2.Client (TooMuchConcurrency (TooMuchConcurrency)) +import qualified Network.HTTP2.Client as HTTP2 import Polysemy (embed, runM) import qualified Polysemy.Reader as Polysemy import Test.Federator.Options (noClientCertSettings) @@ -78,7 +78,7 @@ federatedRequestFailureTMC :: TestTree federatedRequestFailureTMC = testCase "should respond with error when facing GRpcTooMuchConcurrency" $ runM . evalMock @Remote @IO $ do - mockDiscoverAndCallReturns @IO (const $ pure (Right (GRpcTooMuchConcurrency (TooMuchConcurrency 2)))) + mockDiscoverAndCallReturns @IO (const $ pure (Right (GRpcTooMuchConcurrency (HTTP2.TooMuchConcurrency 2)))) let federatedRequest = FederatedRequest validDomainText (Just validLocalPart) res <- mock @Remote @IO . Polysemy.runReader noClientCertSettings $ callOutward federatedRequest @@ -87,7 +87,7 @@ federatedRequestFailureTMC = let expectedCall = ValidatedFederatedRequest (Domain validDomainText) validLocalPart embed $ do assertEqual "one remote call should be made" [expectedCall] actualCalls - assertResponseErrorWithType RemoteFederatorError res + assertResponseErrorWithType TooMuchConcurrency res federatedRequestFailureErrCode :: TestTree federatedRequestFailureErrCode = @@ -102,7 +102,7 @@ federatedRequestFailureErrCode = let expectedCall = ValidatedFederatedRequest (Domain validDomainText) validLocalPart embed $ do assertEqual "one remote call should be made" [expectedCall] actualCalls - assertResponseErrorWithType RemoteFederatorError res + assertResponseErrorWithType GrpcError res federatedRequestFailureErrStr :: TestTree federatedRequestFailureErrStr = @@ -117,7 +117,7 @@ federatedRequestFailureErrStr = let expectedCall = ValidatedFederatedRequest (Domain validDomainText) validLocalPart embed $ do assertEqual "one remote call should be made" [expectedCall] actualCalls - assertResponseErrorWithType RemoteFederatorError res + assertResponseErrorWithType GrpcError res federatedRequestFailureNoRemote :: TestTree federatedRequestFailureNoRemote = diff --git a/services/federator/test/unit/Test/Federator/Monitor.hs b/services/federator/test/unit/Test/Federator/Monitor.hs new file mode 100644 index 00000000000..4da257e55d2 --- /dev/null +++ b/services/federator/test/unit/Test/Federator/Monitor.hs @@ -0,0 +1,437 @@ +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2021 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + +module Test.Federator.Monitor (tests) where + +import Control.Concurrent.Chan +import Control.Exception (bracket) +import Control.Lens (view) +import Control.Monad.Trans.Cont +import qualified Data.Set as Set +import Data.X509 (CertificateChain (..)) +import Federator.Env (TLSSettings (..), creds) +import Federator.Monitor +import Federator.Monitor.Internal +import Federator.Options +import Imports +import qualified Polysemy +import qualified Polysemy.Error as Polysemy +import qualified Polysemy.TinyLog as Polysemy +import System.FilePath +import System.IO.Temp +import System.Posix (createSymbolicLink, getWorkingDirectory) +import System.Timeout +import Test.Federator.Options (defRunSettings) +import Test.Tasty +import Test.Tasty.HUnit +import Test.Tasty.QuickCheck + +timeoutMicroseconds :: Int +timeoutMicroseconds = 10000000 + +tests :: TestTree +tests = + testGroup + "Federator.Monitor" + [ testMonitorChangeUpdate, + testMonitorReplacedChangeUpdate, + testMonitorOverwriteUpdate, + testMonitorSymlinkUpdate, + testMonitorNestedUpdate, + testMonitorKubernetesUpdate, + testMonitorDeepUpdate, + testMonitorError, + testMergeWatchedPaths, + testDirectoryTraversal + ] + +tempFile :: FilePath -> String -> ContT r IO FilePath +tempFile dir template = + ContT $ \k -> withTempFile dir template (const . k) + +withSettings :: ContT r IO RunSettings +withSettings = do + dir <- liftIO getCanonicalTemporaryDirectory + cert <- tempFile dir "cert.pem" + liftIO $ copyFile "test/resources/unit/localhost.pem" cert + key <- tempFile dir "key.pem" + liftIO $ copyFile "test/resources/unit/localhost-key.pem" key + pure $ defRunSettings cert key + +withSymlinkSettings :: ContT r IO RunSettings +withSymlinkSettings = do + settings <- withSettings + dir <- ContT $ withSystemTempDirectory "conf" + liftIO $ createSymbolicLink (clientCertificate settings) (dir "cert.pem") + liftIO $ createSymbolicLink (clientPrivateKey settings) (dir "key.pem") + pure $ + settings + { clientCertificate = dir "cert.pem", + clientPrivateKey = dir "key.pem" + } + +withNestedSettings :: Int -> ContT r IO RunSettings +withNestedSettings n = do + root <- ContT $ withSystemTempDirectory "conf" + liftIO $ do + forM_ [1 .. n] $ \i -> do + let path = concat ["d" ++ show j ++ "/" | j <- [1 .. i]] + createDirectory (root path) + let dir = root concat ["d" ++ show j ++ "/" | j <- [1 .. n]] + cert = dir "cert.pem" + key = dir "key.pem" + copyFile "test/resources/unit/localhost.pem" cert + copyFile "test/resources/unit/localhost-key.pem" key + pure $ defRunSettings cert key + +withKubernetesSettings :: ContT r IO RunSettings +withKubernetesSettings = do + root <- ContT $ withSystemTempDirectory "secrets" + liftIO $ do + createDirectory (root "..foo") + copyFile "test/resources/unit/localhost.pem" (root "..foo/cert.pem") + copyFile "test/resources/unit/localhost-key.pem" (root "..foo/key.pem") + + createSymbolicLink (root "..foo") (root "..data") + createSymbolicLink (root "..data/cert.pem") (root "cert.pem") + createSymbolicLink (root "..data/key.pem") (root "key.pem") + pure $ defRunSettings (root "cert.pem") (root "key.pem") + +withSilentMonitor :: + Chan (Maybe FederationSetupError) -> + RunSettings -> + ContT r IO (IORef TLSSettings) +withSilentMonitor reloads settings = do + tlsVar <- liftIO $ newIORef (error "TLSSettings not updated before being read") + void . ContT $ + bracket + (runSem (mkMonitor runSemE tlsVar settings)) + (runSem . delMonitor) + pure tlsVar + where + runSem = Polysemy.runM . Polysemy.discardLogs + runSemE action = do + r <- runSem (Polysemy.runError @FederationSetupError action) + writeChan reloads (either Just (const Nothing) r) + +testMonitorChangeUpdate :: TestTree +testMonitorChangeUpdate = + testCase "monitor updates settings on file change" $ do + reloads <- newChan + evalContT $ do + settings <- withSettings + tlsVar <- withSilentMonitor reloads settings + liftIO $ do + appendFile (clientCertificate settings) "" + result <- timeout timeoutMicroseconds (readChan reloads) + case result of + Nothing -> assertFailure "certificate not updated within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + tls <- readIORef tlsVar + case view creds tls of + (CertificateChain [], _) -> + assertFailure "expected non-empty certificate chain" + _ -> pure () + +testMonitorReplacedChangeUpdate :: TestTree +testMonitorReplacedChangeUpdate = + testCase "monitor updates settings on file changed after being replaced" $ do + reloads <- newChan + evalContT $ do + settings <- withSettings + tlsVar <- withSilentMonitor reloads settings + liftIO $ do + -- first replace file with a different one + copyFile + "test/resources/unit/localhost-dot.pem" + (clientCertificate settings) + result1 <- timeout timeoutMicroseconds (readChan reloads) + case result1 of + Nothing -> + assertFailure + "certificate not updated once within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + -- now modify the replaced file + appendFile (clientCertificate settings) "" + result2 <- timeout timeoutMicroseconds (readChan reloads) + case result2 of + Nothing -> + assertFailure + "certificate not updated twice within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + tls <- readIORef tlsVar + case view creds tls of + (CertificateChain [], _) -> + assertFailure "expected non-empty certificate chain" + _ -> pure () + +testMonitorOverwriteUpdate :: TestTree +testMonitorOverwriteUpdate = + testCase "monitor updates settings on file being replaced" $ do + reloads <- newChan + evalContT $ do + settings <- withSettings + tlsVar <- withSilentMonitor reloads settings + liftIO $ do + copyFile + "test/resources/unit/localhost-dot.pem" + (clientCertificate settings) + result <- timeout timeoutMicroseconds (readChan reloads) + case result of + Nothing -> assertFailure "certificate not updated within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + tls <- readIORef tlsVar + case view creds tls of + (CertificateChain [], _) -> + assertFailure "expected non-empty certificate chain" + _ -> pure () + +testMonitorSymlinkUpdate :: TestTree +testMonitorSymlinkUpdate = + testCase "monitor updates settings symlink swap" $ do + reloads <- newChan + evalContT $ do + settings <- withSymlinkSettings + tlsVar <- withSilentMonitor reloads settings + liftIO $ do + removeFile (clientCertificate settings) + wd <- getWorkingDirectory + createSymbolicLink + (wd "test/resources/unit/localhost-dot.pem") + (clientCertificate settings) + result <- timeout timeoutMicroseconds (readChan reloads) + case result of + Nothing -> assertFailure "certificate not updated within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + tls <- readIORef tlsVar + case view creds tls of + (CertificateChain [], _) -> + assertFailure "expected non-empty certificate chain" + _ -> pure () + +testMonitorNestedUpdate :: TestTree +testMonitorNestedUpdate = + testCase "monitor updates when parent directory is replaced" $ do + reloads <- newChan + evalContT $ do + settings <- withNestedSettings 1 + tlsVar <- withSilentMonitor reloads settings + liftIO $ do + -- make a new directory with other credentials + let parent = takeDirectory (clientCertificate settings) + root = takeDirectory parent + createDirectory (root "a1") + let cert = root "a1/cert.pem" + key = root "a1/key.pem" + copyFile "test/resources/unit/localhost-dot.pem" cert + copyFile "test/resources/unit/localhost-dot-key.pem" key + + -- replace the old directory with the new one + renameDirectory (root "d1") (root "b1") + renameDirectory (root "a1") (root "d1") + + result <- timeout timeoutMicroseconds (readChan reloads) + case result of + Nothing -> assertFailure "certificate not updated within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + tls <- readIORef tlsVar + case view creds tls of + (CertificateChain [], _) -> + assertFailure "expected non-empty certificate chain" + _ -> pure () + +testMonitorDeepUpdate :: TestTree +testMonitorDeepUpdate = + testCase "monitor updates when grandparent directory is replaced" $ do + reloads <- newChan + evalContT $ do + settings <- withNestedSettings 2 + tlsVar <- withSilentMonitor reloads settings + liftIO $ do + -- make a new directory with other credentials + let root = takeDirectory (takeDirectory (takeDirectory (clientCertificate settings))) + createDirectory (root "a1") + createDirectory (root "a1/d2") + let cert = root "a1/d2/cert.pem" + key = root "a1/d2/key.pem" + copyFile "test/resources/unit/localhost-dot.pem" cert + copyFile "test/resources/unit/localhost-dot-key.pem" key + + -- replace the old directory with the new one + renameDirectory (root "d1") (root "b1") + renameDirectory (root "a1") (root "d1") + + timeout timeoutMicroseconds (readChan reloads) >>= \case + Nothing -> assertFailure "certificate not updated once within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + + -- test that further changes are seen + appendFile (clientCertificate settings) "" + timeout timeoutMicroseconds (readChan reloads) >>= \case + Nothing -> assertFailure "certificate not updated twice within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + + tls <- readIORef tlsVar + case view creds tls of + (CertificateChain [], _) -> + assertFailure "expected non-empty certificate chain" + _ -> pure () + +testMonitorKubernetesUpdate :: TestTree +testMonitorKubernetesUpdate = do + testCase "monitor updates on a kubernetes secret mount" $ do + reloads <- newChan + evalContT $ do + settings <- withKubernetesSettings + tlsVar <- withSilentMonitor reloads settings + liftIO $ do + let root = takeDirectory (clientCertificate settings) + createDirectory (root "..foo2") + copyFile "test/resources/unit/localhost-dot.pem" (root "..foo2/cert.pem") + copyFile "test/resources/unit/localhost-dot-key.pem" (root "..foo2/key.pem") + + removeFile (root "..data") + createSymbolicLink (root "..foo2") (root "..data") + + timeout timeoutMicroseconds (readChan reloads) >>= \case + Nothing -> assertFailure "certificate not updated once within the allotted time" + Just (Just err) -> + assertFailure + ("unexpected exception " <> displayException err) + _ -> pure () + + tls <- readIORef tlsVar + case view creds tls of + (CertificateChain [], _) -> + assertFailure "expected non-empty certificate chain" + _ -> pure () + +testMonitorError :: TestTree +testMonitorError = + testCase "monitor returns an error when settings cannot be updated" $ do + reloads <- newChan + evalContT $ do + settings <- withSettings + _ <- withSilentMonitor reloads settings + liftIO $ do + writeFile (clientCertificate settings) "not a certificate" + result <- timeout timeoutMicroseconds (readChan reloads) + case result of + Nothing -> assertFailure "no error returned within the allotted time" + Just Nothing -> assertFailure "unexpected success" + _ -> pure () + +testMergeWatchedPaths :: TestTree +testMergeWatchedPaths = + testGroup + "merged paths" + [ testProperty "contain the same files" $ \(wpaths :: [WatchedPath]) -> + let f (WatchedFile path) = [path] + f (WatchedDir _ _) = [] + mergedFiles = Set.fromList (Set.toList (mergePaths wpaths) >>= f) + origFiles = Set.fromList (wpaths >>= f) + in mergedFiles == origFiles, + testProperty "contain the same directories" $ \(wpaths :: [WatchedPath]) -> + let f (WatchedFile _) = [] + f (WatchedDir dir _) = [dir] + mergedDirs = Set.fromList (Set.toList (mergePaths wpaths) >>= f) + origDirs = Set.fromList (wpaths >>= f) + in mergedDirs == origDirs, + testProperty "has no duplicated directories" $ \(wpaths :: [WatchedPath]) -> + let f (WatchedFile _) = [] + f (WatchedDir dir _) = [dir] + mergedDirList = Set.toList (mergePaths wpaths) >>= f + mergedDirs = Set.fromList mergedDirList + in Set.size mergedDirs == length mergedDirList, + testProperty "has lower total count" $ \(wpaths :: [WatchedPath]) -> + let f (WatchedFile _) = 1 + f (WatchedDir _ files) = Set.size files + mergedCount = sum $ map f (Set.toList (mergePaths wpaths)) + origCount = sum (map f wpaths) + in mergedCount <= origCount, + testProperty "has the same paths" $ \(wpaths :: [WatchedPath]) -> + let f (WatchedFile path) = [path] + f (WatchedDir dir files) = map (dir <>) (Set.toList files) + mergedPaths = Set.fromList (Set.toList (mergePaths wpaths) >>= f) + origPaths = Set.fromList (wpaths >>= f) + in mergedPaths == origPaths + ] + +newtype Path = Path {getPath :: FilePath} + +instance Show Path where + show = show . getPath + +instance Arbitrary Path where + arbitrary = Path . intercalate "/" <$> listOf (listOf1 ch) + where + ch = arbitrary `suchThat` (/= '/') + +trivialResolve :: FilePath -> IO (Maybe FilePath) +trivialResolve _ = pure Nothing + +testDirectoryTraversal :: TestTree +testDirectoryTraversal = + testGroup + "directory traversal" + [ testProperty "the number of entries is the same as the number of path components" $ + \(path' :: Path) -> ioProperty $ do + path <- makeAbsolute ("/" <> getPath path') + wpaths <- watchedPaths trivialResolve path + pure (length wpaths == length (splitPath path)), + testProperty "relative paths are resolved correctly" $ + \(path' :: Path) -> ioProperty $ do + dir <- getWorkingDirectory + let path = getPath path' + wpaths <- watchedPaths trivialResolve path + wpaths' <- watchedPaths trivialResolve (dir path) + pure $ wpaths == wpaths', + testCase "symlinked paths are resolved" $ + evalContT $ do + settings <- withKubernetesSettings + liftIO $ do + rroot <- rawPath $ takeDirectory (clientCertificate settings) + wpaths <- mergePaths <$> watchedPaths resolveSymlink (clientCertificate settings) + assertBool "symlink targets should be watched" $ + Set.member + (WatchedDir rroot (Set.fromList ["cert.pem", "..data", "..foo"])) + wpaths + ] diff --git a/services/federator/test/unit/Test/Federator/Options.hs b/services/federator/test/unit/Test/Federator/Options.hs index 6e23016abf3..3bf5930a2dd 100644 --- a/services/federator/test/unit/Test/Federator/Options.hs +++ b/services/federator/test/unit/Test/Federator/Options.hs @@ -131,7 +131,7 @@ testSettings = allowAll: null clientCertificate: test/resources/unit/localhost.pem clientPrivateKey: test/resources/unit/localhost-key.pem|] - void (mkTLSSettings settings), + void (mkTLSSettingsOrThrow settings), testCase "fail on missing client credentials" $ assertParseFailure @RunSettings . B8.pack $ [QQ.i| @@ -161,7 +161,7 @@ testSettings = allowAll: null clientCertificate: non-existent clientPrivateKey: non-existent|] - try @FederationSetupError (mkTLSSettings settings) >>= \case + try @FederationSetupError (mkTLSSettingsOrThrow settings) >>= \case Left (InvalidClientCertificate _) -> pure () Left e -> assertFailure $ @@ -183,7 +183,7 @@ testSettings = allowAll: null clientCertificate: test/resources/unit/invalid.pem clientPrivateKey: test/resources/unit/localhost-key.pem|] - try @FederationSetupError (mkTLSSettings settings) >>= \case + try @FederationSetupError (mkTLSSettingsOrThrow settings) >>= \case Left (InvalidClientCertificate _) -> pure () Left e -> assertFailure $ @@ -205,7 +205,7 @@ testSettings = allowAll: null clientCertificate: test/resources/unit/localhost.pem clientPrivateKey: test/resources/unit/invalid.pem|] - try @FederationSetupError (mkTLSSettings settings) >>= \case + try @FederationSetupError (mkTLSSettingsOrThrow settings) >>= \case Left (InvalidClientCertificate _) -> pure () Left e -> assertFailure $ diff --git a/services/federator/test/unit/Test/Federator/Remote.hs b/services/federator/test/unit/Test/Federator/Remote.hs index abdc59039e7..618c78dc855 100644 --- a/services/federator/test/unit/Test/Federator/Remote.hs +++ b/services/federator/test/unit/Test/Federator/Remote.hs @@ -1,11 +1,28 @@ {-# LANGUAGE NumericUnderscores #-} +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2021 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + module Test.Federator.Remote where import Data.Streaming.Network (bindRandomPortTCP) import Federator.Options import Federator.Remote -import Federator.Run (mkTLSSettings) +import Federator.Run (mkTLSSettingsOrThrow) import Imports import Network.HTTP.Types (status200) import Network.Wai @@ -13,7 +30,7 @@ import qualified Network.Wai.Handler.Warp as Warp import qualified Network.Wai.Handler.WarpTLS as WarpTLS import Polysemy import qualified Polysemy.Error as Polysemy -import qualified Polysemy.Reader as Polysemy +import qualified Polysemy.Input as Polysemy import Test.Federator.Options (defRunSettings) import Test.Tasty import Test.Tasty.HUnit @@ -58,20 +75,20 @@ testValidatesCertificateSuccess = "can get response with valid certificate" [ testCase "when hostname=localhost and certificate-for=localhost" $ do bracket (startMockServer certForLocalhost) (\(serverThread, _) -> Async.cancel serverThread) $ \(_, port) -> do - tlsSettings <- mkTLSSettings settings - void . Polysemy.runM . assertNoError @RemoteError . Polysemy.runReader tlsSettings $ mkGrpcClient (SrvTarget "localhost" (fromIntegral port)), + tlsSettings <- mkTLSSettingsOrThrow settings + void . Polysemy.runM . assertNoError @RemoteError . Polysemy.runInputConst tlsSettings $ mkGrpcClient (SrvTarget "localhost" (fromIntegral port)), testCase "when hostname=localhost. and certificate-for=localhost" $ do bracket (startMockServer certForLocalhost) (\(serverThread, _) -> Async.cancel serverThread) $ \(_, port) -> do - tlsSettings <- mkTLSSettings settings - void . Polysemy.runM . assertNoError @RemoteError . Polysemy.runReader tlsSettings $ mkGrpcClient (SrvTarget "localhost." (fromIntegral port)), + tlsSettings <- mkTLSSettingsOrThrow settings + void . Polysemy.runM . assertNoError @RemoteError . Polysemy.runInputConst tlsSettings $ mkGrpcClient (SrvTarget "localhost." (fromIntegral port)), -- This is a limitation of the TLS library, this test just exists to document that. testCase "when hostname=localhost. and certificate-for=localhost." $ do bracket (startMockServer certForLocalhostDot) (\(serverThread, _) -> Async.cancel serverThread) $ \(_, port) -> do - tlsSettings <- mkTLSSettings settings + tlsSettings <- mkTLSSettingsOrThrow settings eitherClient <- Polysemy.runM . Polysemy.runError @RemoteError - . Polysemy.runReader tlsSettings + . Polysemy.runInputConst tlsSettings $ mkGrpcClient (SrvTarget "localhost." (fromIntegral port)) case eitherClient of Left _ -> pure () @@ -84,11 +101,11 @@ testValidatesCertificateWrongHostname = "refuses to connect with server" [ testCase "when the server's certificate doesn't match the hostname" $ bracket (startMockServer certForWrongDomain) (Async.cancel . fst) $ \(_, port) -> do - tlsSettings <- mkTLSSettings settings + tlsSettings <- mkTLSSettingsOrThrow settings eitherClient <- Polysemy.runM . Polysemy.runError - . Polysemy.runReader tlsSettings + . Polysemy.runInputConst tlsSettings $ mkGrpcClient (SrvTarget "localhost." (fromIntegral port)) case eitherClient of Left (RemoteErrorTLSException _ _) -> pure () @@ -117,7 +134,7 @@ startMockServer tlsSettings = liftIO $ do app _req respond = respond $ responseLBS status200 [] "dragons be here" serverThread <- Async.async $ WarpTLS.runTLSSocket tlsSettings wsettings sock app - serverStartedSignal <- timeout 10_000_000 (takeMVar serverStarted) + serverStartedSignal <- timeout 10_000_000 (readMVar serverStarted) case serverStartedSignal of Nothing -> do maybeException <- Async.poll serverThread diff --git a/services/galley/galley.cabal b/services/galley/galley.cabal index 54a109379f0..0357c2adca0 100644 --- a/services/galley/galley.cabal +++ b/services/galley/galley.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: 8728b07d9aff8cd747ea5ca33259f9168c966ae28ca76825e0a073e166d43213 +-- hash: 0acb724202f4ba39242c1ebbe5f5db555404624b7a6be922d5a4148d38c5786d name: galley version: 0.83.0 @@ -89,6 +89,7 @@ library , brig-types >=0.73.1 , bytestring >=0.9 , bytestring-conversion >=0.2 + , case-insensitive , cassandra-util >=0.16.2 , cassava >=0.5.2 , cereal >=0.4 @@ -167,6 +168,7 @@ executable galley build-depends: HsOpenSSL , base + , case-insensitive , extended , galley , galley-types @@ -299,6 +301,7 @@ executable galley-migrate-data ghc-options: -O2 -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wpartial-fields -fwarn-tabs -optP-Wno-nonportable-include-path build-depends: base + , case-insensitive , cassandra-util , conduit , containers @@ -365,6 +368,7 @@ executable galley-schema ghc-options: -O2 -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wpartial-fields -fwarn-tabs -optP-Wno-nonportable-include-path build-depends: base + , case-insensitive , cassandra-util , extended , imports @@ -397,6 +401,7 @@ test-suite galley-types-tests build-depends: QuickCheck , base + , case-insensitive , containers , extended , galley diff --git a/services/galley/package.yaml b/services/galley/package.yaml index 4b3430c0465..795fe273d0b 100644 --- a/services/galley/package.yaml +++ b/services/galley/package.yaml @@ -11,6 +11,7 @@ license: AGPL-3 dependencies: - imports +- case-insensitive - extended - safe >=0.3 - ssl-util diff --git a/services/galley/schema/src/Main.hs b/services/galley/schema/src/Main.hs index cbe7fb2c4bf..5d2b408c428 100644 --- a/services/galley/schema/src/Main.hs +++ b/services/galley/schema/src/Main.hs @@ -98,6 +98,14 @@ main = do V52_FeatureConferenceCalling.migration -- When adding migrations here, don't forget to update -- 'schemaVersion' in Galley.Data + -- (see also docs/developer/cassandra-interaction.md) + -- + -- FUTUREWORK: once #1726 has made its way to master/production, + -- the 'message' field in connections table can be dropped. + -- See also https://github.com/wireapp/wire-server/pull/1747/files + -- for an explanation + -- FUTUREWORK: once #1751 has made its way to master/production, + -- the 'otr_muted' field in the member table can be dropped. ] `finally` Log.close l where diff --git a/services/galley/src/Galley/API/Create.hs b/services/galley/src/Galley/API/Create.hs index 8167c2551e4..52921e4e5a4 100644 --- a/services/galley/src/Galley/API/Create.hs +++ b/services/galley/src/Galley/API/Create.hs @@ -50,10 +50,8 @@ import Network.Wai.Predicate hiding (setStatus) import Network.Wai.Utilities import qualified Wire.API.Conversation as Public import Wire.API.ErrorDescription (missingLegalholdConsent) -import Wire.API.Routes.Public.Galley - ( ConversationResponse, - ConversationResponseFor (..), - ) +import Wire.API.Routes.Public.Galley (ConversationResponse) +import Wire.API.Routes.Public.Util import Wire.API.Team.LegalHold (LegalholdProtectee (LegalholdPlusFederationNotImplemented)) ---------------------------------------------------------------------------- @@ -305,15 +303,15 @@ createConnectConversation usr conn j = do -- Helpers conversationCreated :: UserId -> Data.Conversation -> Galley ConversationResponse -conversationCreated usr cnv = ConversationCreated <$> conversationView usr cnv +conversationCreated usr cnv = Created <$> conversationView usr cnv conversationExisted :: UserId -> Data.Conversation -> Galley ConversationResponse -conversationExisted usr cnv = ConversationExisted <$> conversationView usr cnv +conversationExisted usr cnv = Existed <$> conversationView usr cnv handleConversationResponse :: ConversationResponse -> Response handleConversationResponse = \case - ConversationCreated cnv -> json cnv & setStatus status201 . location (qUnqualified . cnvQualifiedId $ cnv) - ConversationExisted cnv -> json cnv & setStatus status200 . location (qUnqualified . cnvQualifiedId $ cnv) + Created cnv -> json cnv & setStatus status201 . location (qUnqualified . cnvQualifiedId $ cnv) + Existed cnv -> json cnv & setStatus status200 . location (qUnqualified . cnvQualifiedId $ cnv) notifyCreatedConversation :: Maybe UTCTime -> UserId -> Maybe ConnId -> Data.Conversation -> Galley () notifyCreatedConversation dtime usr conn c = do diff --git a/services/galley/src/Galley/API/Federation.hs b/services/galley/src/Galley/API/Federation.hs index 5bb4c39dee1..a6bbbd27a1b 100644 --- a/services/galley/src/Galley/API/Federation.hs +++ b/services/galley/src/Galley/API/Federation.hs @@ -16,28 +16,37 @@ -- with this program. If not, see . module Galley.API.Federation where +import Control.Lens (itraversed, (<.>)) import Control.Monad.Catch (throwM) import Control.Monad.Except (runExceptT) +import Data.ByteString.Conversion (toByteString') import Data.Containers.ListUtils (nubOrd) import Data.Domain -import Data.Id (ConvId) +import Data.Id (ConvId, UserId) import Data.Json.Util (Base64ByteString (..)) import Data.List1 (list1) +import qualified Data.Map as Map +import Data.Map.Lens (toMapOf) import Data.Qualified (Qualified (..)) +import qualified Data.Set as Set import Data.Tagged import qualified Data.Text.Lazy as LT import Galley.API.Error (invalidPayload) import qualified Galley.API.Mapping as Mapping -import Galley.API.Message (UserType (..), postQualifiedOtrMessage) +import Galley.API.Message (MessageMetadata (..), UserType (..), postQualifiedOtrMessage, sendLocalMessages) import qualified Galley.API.Update as API import Galley.API.Util (fromRegisterConversation, pushConversationEvent, viewFederationDomain) import Galley.App (Galley) import qualified Galley.Data as Data +import Galley.Types.Conversations.Members (InternalMember (..), LocalMember) import Imports import Servant (ServerT) import Servant.API.Generic (ToServantApi) import Servant.Server.Generic (genericServerT) -import Wire.API.Conversation.Member (OtherMember (..), memId) +import qualified System.Logger.Class as Log +import qualified Wire.API.Conversation as Public +import Wire.API.Conversation.Member (OtherMember (..)) +import qualified Wire.API.Conversation.Role as Public import Wire.API.Event.Conversation import Wire.API.Federation.API.Galley ( ConversationMemberUpdate (..), @@ -52,6 +61,7 @@ import Wire.API.Federation.API.Galley ) import qualified Wire.API.Federation.API.Galley as FederationAPIGalley import Wire.API.ServantProto (FromProto (..)) +import Wire.API.User.Client (userClientMap) federationSitemap :: ServerT (ToServantApi FederationAPIGalley.Api) Galley federationSitemap = @@ -83,7 +93,7 @@ registerConversation rc = do (rcOrigUserId rc) (rcTime rc) (EdConversation c) - pushConversationEvent Nothing event [memId mem] [] + pushConversationEvent Nothing event [Public.memId mem] [] getConversations :: GetConversationsRequest -> Galley GetConversationsResponse getConversations (GetConversationsRequest qUid gcrConvIds) = do @@ -144,10 +154,48 @@ leaveConversation requestingDomain lc = do API.removeMemberFromLocalConv leaver Nothing (lcConvId lc) leaver -- FUTUREWORK: report errors to the originating backend +-- FUTUREWORK: error handling for missing / mismatched clients receiveMessage :: Domain -> RemoteMessage ConvId -> Galley () -receiveMessage domain = - API.postRemoteToLocal - . fmap (Tagged . (`Qualified` domain)) +receiveMessage domain rmUnqualified = do + let rm = fmap (Tagged . (`Qualified` domain)) rmUnqualified + let convId = unTagged $ rmConversation rm + msgMetadata = + MessageMetadata + { mmNativePush = rmPush rm, + mmTransient = rmTransient rm, + mmNativePriority = rmPriority rm, + mmData = rmData rm + } + recipientMap = userClientMap $ rmRecipients rm + msgs = toMapOf (itraversed <.> itraversed) recipientMap + (members, allMembers) <- Data.filterRemoteConvMembers (Map.keys recipientMap) convId + unless allMembers $ + Log.warn $ + Log.field "conversation" (toByteString' (qUnqualified convId)) + Log.~~ Log.field "domain" (toByteString' (qDomain convId)) + Log.~~ Log.msg + ( "Attempt to send remote message to local\ + \ users not in the conversation" :: + ByteString + ) + localMembers <- sequence $ Map.fromSet mkLocalMember (Set.fromList members) + void $ sendLocalMessages (rmTime rm) (rmSender rm) (rmSenderClient rm) Nothing convId localMembers msgMetadata msgs + where + -- FUTUREWORK: https://wearezeta.atlassian.net/browse/SQCORE-875 + mkLocalMember :: UserId -> Galley LocalMember + mkLocalMember m = + pure $ + InternalMember + { memId = m, + memService = Nothing, + memOtrMutedStatus = Nothing, + memOtrMutedRef = Nothing, + memOtrArchived = False, + memOtrArchivedRef = Nothing, + memHidden = False, + memHiddenRef = Nothing, + memConvRoleName = Public.roleNameWireMember + } sendMessage :: Domain -> MessageSendRequest -> Galley MessageSendResponse sendMessage originDomain msr = do diff --git a/services/galley/src/Galley/API/Mapping.hs b/services/galley/src/Galley/API/Mapping.hs index 0a79a22bbbe..4eb47d23cbd 100644 --- a/services/galley/src/Galley/API/Mapping.hs +++ b/services/galley/src/Galley/API/Mapping.hs @@ -111,7 +111,6 @@ conversationViewMaybeQualified localDomain qUid Data.Conversation {..} = do Public.Member { memId = qUnqualified (Public.omQualifiedId m), memService = Nothing, - memOtrMuted = False, memOtrMutedStatus = Nothing, memOtrMutedRef = Nothing, memOtrArchived = False, diff --git a/services/galley/src/Galley/API/Message.hs b/services/galley/src/Galley/API/Message.hs index 058142bce08..23ac50dafca 100644 --- a/services/galley/src/Galley/API/Message.hs +++ b/services/galley/src/Galley/API/Message.hs @@ -309,10 +309,10 @@ sendMessages :: Galley QualifiedUserClients sendMessages now sender senderClient mconn conv localMemberMap metadata messages = do localDomain <- viewFederationDomain - let messageMap = byDomain messages + let messageMap = byDomain $ fmap toBase64Text messages let send dom | localDomain == dom = - sendLocalMessages now sender senderClient mconn conv localMemberMap metadata + sendLocalMessages now sender senderClient mconn (Qualified conv localDomain) localMemberMap metadata | otherwise = sendRemoteMessages dom now sender senderClient conv metadata mkQualifiedUserClientsByDomain <$> Map.traverseWithKey send messageMap @@ -328,17 +328,17 @@ sendLocalMessages :: Qualified UserId -> ClientId -> Maybe ConnId -> - ConvId -> + Qualified ConvId -> Map UserId LocalMember -> MessageMetadata -> - Map (UserId, ClientId) ByteString -> + Map (UserId, ClientId) Text -> Galley (Set (UserId, ClientId)) sendLocalMessages now sender senderClient mconn conv localMemberMap metadata localMessages = do localDomain <- viewFederationDomain let events = localMessages & reindexed snd itraversed %@~ newMessageEvent - (Qualified conv localDomain) + conv sender senderClient (mmData metadata) @@ -356,18 +356,18 @@ sendRemoteMessages :: ClientId -> ConvId -> MessageMetadata -> - Map (UserId, ClientId) ByteString -> + Map (UserId, ClientId) Text -> Galley (Set (UserId, ClientId)) sendRemoteMessages domain now sender senderClient conv metadata messages = handle <=< runExceptT $ do let rcpts = foldr - (\((u, c), t) -> Map.insertWith (<>) u (Map.singleton c (toBase64Text t))) + (\((u, c), t) -> Map.insertWith (<>) u (Map.singleton c t)) mempty (Map.assocs messages) rm = FederatedGalley.RemoteMessage { FederatedGalley.rmTime = now, - FederatedGalley.rmData = Just (toBase64Text (mmData metadata)), + FederatedGalley.rmData = mmData metadata, FederatedGalley.rmSender = sender, FederatedGalley.rmSenderClient = senderClient, FederatedGalley.rmConversation = conv, @@ -420,21 +420,29 @@ newUserPush p = MessagePush {userPushes = pure p, botPushes = mempty} newBotPush :: BotMember -> Event -> MessagePush newBotPush b e = MessagePush {userPushes = mempty, botPushes = pure (b, e)} -runMessagePush :: ConvId -> MessagePush -> Galley () +runMessagePush :: Qualified ConvId -> MessagePush -> Galley () runMessagePush cnv mp = do pushSome (userPushes mp) - void . forkIO $ do - gone <- External.deliver (botPushes mp) - mapM_ (deleteBot cnv . botMemId) gone - -newMessageEvent :: Qualified ConvId -> Qualified UserId -> ClientId -> ByteString -> UTCTime -> ClientId -> ByteString -> Event -newMessageEvent convId sender senderClient dat time recieverClient cipherText = + pushToBots (botPushes mp) + where + pushToBots :: [(BotMember, Event)] -> Galley () + pushToBots pushes = do + localDomain <- viewFederationDomain + if localDomain /= qDomain cnv + then unless (null pushes) $ do + Log.warn $ Log.msg ("Ignoring messages for local bots in a remote conversation" :: ByteString) . Log.field "conversation" (show cnv) + else void . forkIO $ do + gone <- External.deliver pushes + mapM_ (deleteBot (qUnqualified cnv) . botMemId) gone + +newMessageEvent :: Qualified ConvId -> Qualified UserId -> ClientId -> Maybe Text -> UTCTime -> ClientId -> Text -> Event +newMessageEvent convId sender senderClient dat time receiverClient cipherText = Event OtrMessageAdd convId sender time . EdOtrMessage $ OtrMessage { otrSender = senderClient, - otrRecipient = recieverClient, - otrCiphertext = toBase64Text cipherText, - otrData = Just $ toBase64Text dat + otrRecipient = receiverClient, + otrCiphertext = cipherText, + otrData = dat } newMessagePush :: @@ -466,7 +474,7 @@ data MessageMetadata = MessageMetadata { mmNativePush :: Bool, mmTransient :: Bool, mmNativePriority :: Maybe Priority, - mmData :: ByteString + mmData :: Maybe Text } deriving (Eq, Ord, Show) @@ -476,7 +484,7 @@ qualifiedNewOtrMetadata msg = { mmNativePush = qualifiedNewOtrNativePush msg, mmTransient = qualifiedNewOtrTransient msg, mmNativePriority = qualifiedNewOtrNativePriority msg, - mmData = qualifiedNewOtrData msg + mmData = Just . toBase64Text $ qualifiedNewOtrData msg } -- unqualified diff --git a/services/galley/src/Galley/API/Public.hs b/services/galley/src/Galley/API/Public.hs index 7f93785ce39..6fb84c56646 100644 --- a/services/galley/src/Galley/API/Public.hs +++ b/services/galley/src/Galley/API/Public.hs @@ -92,6 +92,12 @@ servantSitemap = GalleyAPI.addMembersToConversationV2 = Update.addMembers, GalleyAPI.removeMemberUnqualified = Update.removeMemberUnqualified, GalleyAPI.removeMember = Update.removeMemberQualified, + GalleyAPI.updateConversationNameDeprecated = Update.updateLocalConversationName, + GalleyAPI.updateConversationNameUnqualified = Update.updateLocalConversationName, + GalleyAPI.updateConversationName = Update.updateConversationName, + GalleyAPI.getConversationSelfUnqualified = Query.getLocalSelf, + GalleyAPI.updateConversationSelfUnqualified = Update.updateLocalSelfMember, + GalleyAPI.updateConversationSelf = Update.updateSelfMember, GalleyAPI.getTeamConversationRoles = Teams.getTeamConversationRoles, GalleyAPI.getTeamConversations = Teams.getTeamConversations, GalleyAPI.getTeamConversation = Teams.getTeamConversation, @@ -543,38 +549,6 @@ sitemap = do -- Conversation API --------------------------------------------------- - -- This endpoint can lead to the following events being sent: - -- - ConvRename event to members - put "/conversations/:cnv/name" (continue Update.updateConversationNameH) $ - zauthUserId - .&. zauthConnId - .&. capture "cnv" - .&. jsonRequest @Public.ConversationRename - document "PUT" "updateConversationName" $ do - summary "Update conversation name" - parameter Path "cnv" bytes' $ - description "Conversation ID" - body (ref Public.modelConversationUpdateName) $ - description "JSON body" - returns (ref Public.modelEvent) - errorResponse (Error.errorDescriptionToWai Error.convNotFound) - - -- This endpoint can lead to the following events being sent: - -- - ConvRename event to members - put "/conversations/:cnv" (continue Update.updateConversationDeprecatedH) $ - zauthUserId - .&. zauthConnId - .&. capture "cnv" - .&. jsonRequest @Public.ConversationRename - document "PUT" "updateConversationName" $ do - summary "DEPRECATED! Please use updateConversationName instead!" - parameter Path "cnv" bytes' $ - description "Conversation ID" - body (ref Public.modelConversationUpdateName) $ - description "JSON body" - returns (ref Public.modelEvent) - errorResponse (Error.errorDescriptionToWai Error.convNotFound) - -- This endpoint can lead to the following events being sent: -- - MemberJoin event to members post "/conversations/:cnv/join" (continue Update.joinConversationByIdH) $ @@ -747,32 +721,6 @@ sitemap = do errorResponse (Error.errorDescriptionToWai Error.notConnected) errorResponse (Error.errorDescriptionToWai Error.convAccessDenied) - get "/conversations/:cnv/self" (continue Query.getSelfH) $ - zauthUserId - .&. capture "cnv" - document "GET" "getSelf" $ do - summary "Get self membership properties" - parameter Path "cnv" bytes' $ - description "Conversation ID" - returns (ref Public.modelMember) - errorResponse (Error.errorDescriptionToWai Error.convNotFound) - - -- This endpoint can lead to the following events being sent: - -- - MemberStateUpdate event to self - put "/conversations/:cnv/self" (continue Update.updateSelfMemberH) $ - zauthUserId - .&. zauthConnId - .&. capture "cnv" - .&. jsonRequest @Public.MemberUpdate - document "PUT" "updateSelf" $ do - summary "Update self membership properties" - notes "Even though all fields are optional, at least one needs to be given." - parameter Path "cnv" bytes' $ - description "Conversation ID" - body (ref Public.modelMemberUpdate) $ - description "JSON body" - errorResponse (Error.errorDescriptionToWai Error.convNotFound) - -- This endpoint can lead to the following events being sent: -- - MemberStateUpdate event to members put "/conversations/:cnv/members/:usr" (continue Update.updateOtherMemberH) $ diff --git a/services/galley/src/Galley/API/Query.hs b/services/galley/src/Galley/API/Query.hs index 525b5d991b8..7500ba068a8 100644 --- a/services/galley/src/Galley/API/Query.hs +++ b/services/galley/src/Galley/API/Query.hs @@ -27,7 +27,7 @@ module Galley.API.Query listConversations, listConversationsV2, iterateConversations, - getSelfH, + getLocalSelf, internalGetMemberH, getConversationMetaH, getConversationByReusableCode, @@ -100,15 +100,18 @@ getConversation zusr cnv = do localDomain <- viewFederationDomain if qDomain cnv == localDomain then getUnqualifiedConversation zusr (qUnqualified cnv) - else getRemoteConversation zusr (toRemote cnv) - -getRemoteConversation :: UserId -> Remote ConvId -> Galley Public.Conversation -getRemoteConversation zusr remoteConvId = do - conversations <- getRemoteConversations zusr [remoteConvId] - case conversations of - [] -> throwErrorDescription convNotFound - [conv] -> pure conv - _convs -> throwM (federationUnexpectedBody "expected one conversation, got multiple") + else getRemoteConversation (toRemote cnv) + where + getRemoteConversation :: Remote ConvId -> Galley Public.Conversation + getRemoteConversation remoteConvId = do + foundConvs <- Data.remoteConversationIdOf zusr [remoteConvId] + unless (remoteConvId `elem` foundConvs) $ + throwErrorDescription convNotFound + conversations <- getRemoteConversations zusr [remoteConvId] + case conversations of + [] -> throwErrorDescription convNotFound + [conv] -> pure conv + _convs -> throwM (federationUnexpectedBody "expected one conversation, got multiple") getRemoteConversations :: UserId -> [Remote ConvId] -> Galley [Public.Conversation] getRemoteConversations zusr remoteConvs = do @@ -344,27 +347,16 @@ iterateConversations uid pageSize handleConvs = go Nothing _ -> pure [] pure $ resultHead : resultTail -getSelfH :: UserId ::: ConvId -> Galley Response -getSelfH (zusr ::: cnv) = do - json <$> getSelf zusr cnv - -getSelf :: UserId -> ConvId -> Galley (Maybe Public.Member) -getSelf zusr cnv = - internalGetMember cnv zusr - internalGetMemberH :: ConvId ::: UserId -> Galley Response internalGetMemberH (cnv ::: usr) = do - json <$> internalGetMember cnv usr + json <$> getLocalSelf usr cnv -internalGetMember :: ConvId -> UserId -> Galley (Maybe Public.Member) -internalGetMember cnv usr = do +getLocalSelf :: UserId -> ConvId -> Galley (Maybe Public.Member) +getLocalSelf usr cnv = do alive <- Data.isConvAlive cnv if alive - then do - fmap Mapping.toMember <$> Data.member cnv usr - else do - Data.deleteConversation cnv - pure Nothing + then Mapping.toMember <$$> Data.member cnv usr + else Nothing <$ Data.deleteConversation cnv getConversationMetaH :: ConvId -> Galley Response getConversationMetaH cnv = do diff --git a/services/galley/src/Galley/API/Teams.hs b/services/galley/src/Galley/API/Teams.hs index 587d325ed08..b2f8e53e38f 100644 --- a/services/galley/src/Galley/API/Teams.hs +++ b/services/galley/src/Galley/API/Teams.hs @@ -63,6 +63,7 @@ import Control.Lens import Control.Monad.Catch import Data.ByteString.Conversion hiding (fromList) import Data.ByteString.Lazy.Builder (lazyByteString) +import qualified Data.CaseInsensitive as CI import Data.Csv (EncodeOptions (..), Quoting (QuoteAll), encodeDefaultOrderedByNameWith) import qualified Data.Handle as Handle import Data.Id @@ -488,7 +489,7 @@ getTeamMembersCSVH (zusr ::: tid ::: _) = do samlNamedId :: User -> Maybe Text samlNamedId = userSSOId >=> \case - (UserSSOId _idp nameId) -> SAML.unsafeShowNameID <$> either (const Nothing) pure (SAML.decodeElem (cs nameId)) + (UserSSOId _idp nameId) -> CI.original . SAML.unsafeShowNameID <$> either (const Nothing) pure (SAML.decodeElem (cs nameId)) (UserScimExternalId _) -> Nothing bulkGetTeamMembersH :: UserId ::: TeamId ::: Range 1 Public.HardTruncationLimit Int32 ::: JsonRequest Public.UserIdList ::: JSON -> Galley Response diff --git a/services/galley/src/Galley/API/Update.hs b/services/galley/src/Galley/API/Update.hs index cef95744cef..7d6b656f7e4 100644 --- a/services/galley/src/Galley/API/Update.hs +++ b/services/galley/src/Galley/API/Update.hs @@ -27,7 +27,8 @@ module Galley.API.Update rmCodeH, getCodeH, updateConversationDeprecatedH, - updateConversationNameH, + updateLocalConversationName, + updateConversationName, updateConversationAccessH, updateConversationReceiptModeH, updateConversationMessageTimerH, @@ -35,7 +36,8 @@ module Galley.API.Update -- * Managing Members addMembersH, addMembers, - updateSelfMemberH, + updateLocalSelfMember, + updateSelfMember, updateOtherMemberH, removeMember, removeMemberQualified, @@ -48,7 +50,6 @@ module Galley.API.Update postOtrBroadcastH, postProtoOtrBroadcastH, isTypingH, - postRemoteToLocal, -- * External Services addServiceH, @@ -65,7 +66,6 @@ import Control.Lens import Control.Monad.Catch import Control.Monad.State import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE, withExceptT) -import Data.ByteString.Conversion (toByteString') import Data.Code import Data.Domain (Domain) import Data.Either.Extra (mapRight) @@ -109,7 +109,6 @@ import Network.HTTP.Types import Network.Wai import Network.Wai.Predicate hiding (and, failure, setStatus, _1, _2) import Network.Wai.Utilities -import qualified System.Logger.Class as Log import Wire.API.Conversation (InviteQualified (invQRoleName)) import qualified Wire.API.Conversation as Public import qualified Wire.API.Conversation.Code as Public @@ -123,8 +122,8 @@ import Wire.API.ErrorDescription ) import qualified Wire.API.ErrorDescription as Public import qualified Wire.API.Event.Conversation as Public -import Wire.API.Federation.API.Galley (RemoteMessage (..)) import qualified Wire.API.Federation.API.Galley as FederatedGalley +import Wire.API.Federation.Error (federationNotImplemented) import qualified Wire.API.Message as Public import Wire.API.Routes.Public.Galley (UpdateResult (..)) import Wire.API.Routes.Public.Galley.Responses @@ -281,8 +280,7 @@ uncheckedUpdateConversationAccess body usr zcon conv (currentAccess, targetAcces case removedUsers of [] -> return () x : xs -> do - -- FUTUREWORK: deal with remote members, too, see removeMembers (Jira - -- SQCORE-903) + -- FUTUREWORK: deal with remote members, too, see removeMembers (Jira SQCORE-903) e <- Data.removeLocalMembersFromLocalConv localDomain conv (Qualified usr localDomain) (x :| xs) -- push event to all clients, including zconn -- since updateConversationAccess generates a second (member removal) event here @@ -552,18 +550,17 @@ addMembers zusr zcon convId invite = do checkLHPolicyConflictsRemote :: FutureWork 'LegalholdPlusFederationNotImplemented [Remote UserId] -> Galley () checkLHPolicyConflictsRemote _remotes = pure () -updateSelfMemberH :: UserId ::: ConnId ::: ConvId ::: JsonRequest Public.MemberUpdate -> Galley Response -updateSelfMemberH (zusr ::: zcon ::: cid ::: req) = do - update <- fromJsonBody req - updateSelfMember zusr zcon cid update - return empty +updateSelfMember :: UserId -> ConnId -> Qualified ConvId -> Public.MemberUpdate -> Galley () +updateSelfMember zusr zcon qcnv update = do + localDomain <- viewFederationDomain + if qDomain qcnv == localDomain + then updateLocalSelfMember zusr zcon (qUnqualified qcnv) update + else throwM federationNotImplemented -updateSelfMember :: UserId -> ConnId -> ConvId -> Public.MemberUpdate -> Galley () -updateSelfMember zusr zcon cid update = do +updateLocalSelfMember :: UserId -> ConnId -> ConvId -> Public.MemberUpdate -> Galley () +updateLocalSelfMember zusr zcon cid update = do conv <- getConversationAndCheckMembership zusr cid m <- getSelfMemberFromLocalsLegacy zusr (Data.convLocalMembers conv) - -- Ensure no self role upgrades - for_ (mupConvRoleName update) $ ensureConvRoleNotElevated m void $ processUpdateMemberEvent zusr zcon cid [m] m update updateOtherMemberH :: UserId ::: ConnId ::: ConvId ::: UserId ::: JsonRequest Public.OtherMemberUpdate -> Galley Response @@ -580,7 +577,7 @@ updateOtherMember zusr zcon cid victim update = do let (bots, users) = localBotsAndUsers (Data.convLocalMembers conv) ensureActionAllowedThrowing ModifyOtherConversationMember =<< getSelfMemberFromLocalsLegacy zusr users memTarget <- getOtherMemberLegacy victim users - e <- processUpdateMemberEvent zusr zcon cid users memTarget (memberUpdate {mupConvRoleName = omuConvRoleName update}) + e <- processUpdateMemberEvent zusr zcon cid users memTarget update void . forkIO $ void $ External.deliver (bots `zip` repeat e) -- | A general conversation member removal function used both by the unqualified @@ -820,59 +817,6 @@ postNewOtrMessage utype usr con cnv val msg = do gone <- External.deliver toBots mapM_ (deleteBot cnv . botMemId) gone --- | Locally post a message originating from a remote conversation --- --- FUTUREWORK: error handling for missing / mismatched clients --- (https://wearezeta.atlassian.net/browse/SQCORE-894) -postRemoteToLocal :: RemoteMessage (Remote ConvId) -> Galley () -postRemoteToLocal rm = do - localDomain <- viewFederationDomain - let UserClientMap rcpts = rmRecipients rm - Tagged conv = rmConversation rm - -- FUTUREWORK(authorization) review whether filtering members is appropriate - -- at this stage - (members, allMembers) <- Data.filterRemoteConvMembers (Map.keys rcpts) conv - unless allMembers $ - Log.warn $ - Log.field "conversation" (toByteString' (qUnqualified conv)) - Log.~~ Log.field "domain" (toByteString' (qDomain conv)) - Log.~~ Log.msg - ( "Attempt to send remote message to local\ - \ users not in the conversation" :: - Text - ) - let rcpts' = do - m <- members - (c, t) <- maybe [] Map.assocs (rcpts ^? ix m) - pure (m, c, t) - let remoteToLocalPush (rcpt, rcptc, ciphertext) = - newPush1 - ListComplete - (guard (localDomain == qDomain (rmSender rm)) $> qUnqualified (rmSender rm)) - ( ConvEvent - ( Event - OtrMessageAdd - conv - (rmSender rm) - (rmTime rm) - ( EdOtrMessage - ( OtrMessage - { otrSender = rmSenderClient rm, - otrRecipient = rcptc, - otrCiphertext = ciphertext, - otrData = rmData rm - } - ) - ) - ) - ) - (singleton (userRecipient rcpt)) - -- FUTUREWORK: unify event creation logic after #1634 is merged - & pushNativePriority .~ rmPriority rm - & pushRoute .~ bool RouteDirect RouteAny (rmPush rm) - & pushTransient .~ rmTransient rm - pushSome (map remoteToLocalPush rcpts') - newMessage :: Qualified UserId -> Maybe ConnId -> @@ -911,32 +855,52 @@ newMessage qusr con qcnv msg now (m, c, t) ~(toBots, toUsers) = updateConversationDeprecatedH :: UserId ::: ConnId ::: ConvId ::: JsonRequest Public.ConversationRename -> Galley Response updateConversationDeprecatedH (zusr ::: zcon ::: cnv ::: req) = do convRename <- fromJsonBody req - setStatus status200 . json <$> updateConversationName zusr zcon cnv convRename + setStatus status200 . json <$> updateLocalConversationName zusr zcon cnv convRename -updateConversationNameH :: UserId ::: ConnId ::: ConvId ::: JsonRequest Public.ConversationRename -> Galley Response -updateConversationNameH (zusr ::: zcon ::: cnv ::: req) = do - convRename <- fromJsonBody req - setStatus status200 . json <$> updateConversationName zusr zcon cnv convRename +updateConversationName :: + UserId -> + ConnId -> + Qualified ConvId -> + Public.ConversationRename -> + Galley (Maybe Public.Event) +updateConversationName usr zcon qcnv convRename = do + localDomain <- viewFederationDomain + if qDomain qcnv == localDomain + then updateLocalConversationName usr zcon (qUnqualified qcnv) convRename + else throwM federationNotImplemented + +updateLocalConversationName :: + UserId -> + ConnId -> + ConvId -> + Public.ConversationRename -> + Galley (Maybe Public.Event) +updateLocalConversationName usr zcon cnv convRename = do + alive <- Data.isConvAlive cnv + if alive + then Just <$> updateLiveLocalConversationName usr zcon cnv convRename + else Nothing <$ Data.deleteConversation cnv -updateConversationName :: UserId -> ConnId -> ConvId -> Public.ConversationRename -> Galley Public.Event -updateConversationName zusr zcon cnv convRename = do +updateLiveLocalConversationName :: + UserId -> + ConnId -> + ConvId -> + Public.ConversationRename -> + Galley Public.Event +updateLiveLocalConversationName usr zcon cnv convRename = do localDomain <- viewFederationDomain let qcnv = Qualified cnv localDomain - qusr = Qualified zusr localDomain - alive <- Data.isConvAlive cnv - unless alive $ do - Data.deleteConversation cnv - throwErrorDescription convNotFound + qusr = Qualified usr localDomain (bots, users) <- localBotsAndUsers <$> Data.members cnv - ensureActionAllowedThrowing ModifyConversationName =<< getSelfMemberFromLocalsLegacy zusr users + ensureActionAllowedThrowing ModifyConversationName =<< getSelfMemberFromLocalsLegacy usr users now <- liftIO getCurrentTime cn <- rangeChecked (cupName convRename) Data.updateConversation cnv cn let e = Event ConvRename qcnv qusr now (EdConvRename convRename) - for_ (newPushLocal ListComplete zusr (ConvEvent e) (recipient <$> users)) $ \p -> + for_ (newPushLocal ListComplete usr (ConvEvent e) (recipient <$> users)) $ \p -> push1 $ p & pushConn ?~ zcon void . forkIO $ void $ External.deliver (bots `zip` repeat e) - return e + pure e isTypingH :: UserId ::: ConnId ::: ConvId ::: JsonRequest Public.TypingData -> Galley Response isTypingH (zusr ::: zcon ::: cnv ::: req) = do @@ -1111,12 +1075,13 @@ ensureConvMember users usr = throwErrorDescription convNotFound processUpdateMemberEvent :: + Data.IsMemberUpdate mu => UserId -> ConnId -> ConvId -> [LocalMember] -> LocalMember -> - MemberUpdate -> + mu -> Galley Event processUpdateMemberEvent zusr zcon cid users target update = do localDomain <- viewFederationDomain diff --git a/services/galley/src/Galley/API/Util.hs b/services/galley/src/Galley/API/Util.hs index a9f5a08ca7e..9ae92e72b38 100644 --- a/services/galley/src/Galley/API/Util.hs +++ b/services/galley/src/Galley/API/Util.hs @@ -542,7 +542,6 @@ fromRegisterConversation d MkRegisterConversation {..} = Public.Member { memId = qUnqualified . omQualifiedId $ m, memService = omService m, - memOtrMuted = False, memOtrMutedStatus = Nothing, memOtrMutedRef = Nothing, memOtrArchived = False, diff --git a/services/galley/src/Galley/Data.hs b/services/galley/src/Galley/Data.hs index 520f37dde02..ef4d8f8a4b3 100644 --- a/services/galley/src/Galley/Data.hs +++ b/services/galley/src/Galley/Data.hs @@ -89,7 +89,7 @@ module Galley.Data removeLocalMembersFromLocalConv, removeRemoteMembersFromLocalConv, removeLocalMembersFromRemoteConv, - updateMember, + IsMemberUpdate (..), filterRemoteConvMembers, -- * Conversation Codes @@ -814,8 +814,8 @@ memberLists convs = do insert (Just (conv, mem)) acc = let f = (Just . maybe [mem] (mem :)) in Map.alter f conv acc - mkMem (cnv, usr, srv, prv, st, omu, omus, omur, oar, oarr, hid, hidr, crn) = - fmap (cnv,) <$> toMember (usr, srv, prv, st, omu, omus, omur, oar, oarr, hid, hidr, crn) + mkMem (cnv, usr, srv, prv, st, omus, omur, oar, oarr, hid, hidr, crn) = + fmap (cnv,) <$> toMember (usr, srv, prv, st, omus, omur, oar, oarr, hid, hidr, crn) members :: (MonadClient m, Log.MonadLogger m, MonadThrow m) => ConvId -> m [LocalMember] members conv = join <$> memberLists [conv] @@ -898,33 +898,50 @@ addLocalMembersToRemoteConv users qconv = do Cql.insertUserRemoteConv (u, qDomain qconv, qUnqualified qconv) -updateMember :: MonadClient m => ConvId -> UserId -> MemberUpdate -> m MemberUpdateData -updateMember cid uid mup = do - retry x5 . batch $ do - setType BatchUnLogged - setConsistency Quorum - for_ (mupOtrMute mup) $ \m -> - addPrepQuery Cql.updateOtrMemberMuted (m, mupOtrMuteRef mup, cid, uid) - for_ (mupOtrMuteStatus mup) $ \ms -> - addPrepQuery Cql.updateOtrMemberMutedStatus (ms, mupOtrMuteRef mup, cid, uid) - for_ (mupOtrArchive mup) $ \a -> - addPrepQuery Cql.updateOtrMemberArchived (a, mupOtrArchiveRef mup, cid, uid) - for_ (mupHidden mup) $ \h -> - addPrepQuery Cql.updateMemberHidden (h, mupHiddenRef mup, cid, uid) - for_ (mupConvRoleName mup) $ \r -> - addPrepQuery Cql.updateMemberConvRoleName (r, cid, uid) - return - MemberUpdateData - { misTarget = Just uid, - misOtrMuted = mupOtrMute mup, - misOtrMutedStatus = mupOtrMuteStatus mup, - misOtrMutedRef = mupOtrMuteRef mup, - misOtrArchived = mupOtrArchive mup, - misOtrArchivedRef = mupOtrArchiveRef mup, - misHidden = mupHidden mup, - misHiddenRef = mupHiddenRef mup, - misConvRoleName = mupConvRoleName mup - } +class IsMemberUpdate mu where + updateMember :: MonadClient m => ConvId -> UserId -> mu -> m MemberUpdateData + +instance IsMemberUpdate MemberUpdate where + updateMember cid uid mup = do + retry x5 . batch $ do + setType BatchUnLogged + setConsistency Quorum + for_ (mupOtrMuteStatus mup) $ \ms -> + addPrepQuery Cql.updateOtrMemberMutedStatus (ms, mupOtrMuteRef mup, cid, uid) + for_ (mupOtrArchive mup) $ \a -> + addPrepQuery Cql.updateOtrMemberArchived (a, mupOtrArchiveRef mup, cid, uid) + for_ (mupHidden mup) $ \h -> + addPrepQuery Cql.updateMemberHidden (h, mupHiddenRef mup, cid, uid) + return + MemberUpdateData + { misTarget = Just uid, + misOtrMutedStatus = mupOtrMuteStatus mup, + misOtrMutedRef = mupOtrMuteRef mup, + misOtrArchived = mupOtrArchive mup, + misOtrArchivedRef = mupOtrArchiveRef mup, + misHidden = mupHidden mup, + misHiddenRef = mupHiddenRef mup, + misConvRoleName = Nothing + } + +instance IsMemberUpdate OtherMemberUpdate where + updateMember cid uid omu = do + retry x5 . batch $ do + setType BatchUnLogged + setConsistency Quorum + for_ (omuConvRoleName omu) $ \r -> + addPrepQuery Cql.updateMemberConvRoleName (r, cid, uid) + pure + MemberUpdateData + { misTarget = Just uid, + misOtrMutedStatus = Nothing, + misOtrMutedRef = Nothing, + misOtrArchived = Nothing, + misOtrArchivedRef = Nothing, + misHidden = Nothing, + misHiddenRef = Nothing, + misConvRoleName = omuConvRoleName omu + } -- | Select only the members of a remote conversation from a list of users. -- Return the filtered list and a boolean indicating whether the all the input @@ -1006,7 +1023,6 @@ newMemberWithRole u r = InternalMember { memId = u, memService = Nothing, - memOtrMuted = False, memOtrMutedStatus = Nothing, memOtrMutedRef = Nothing, memOtrArchived = False, @@ -1023,7 +1039,6 @@ toMember :: Maybe ProviderId, Maybe Cql.MemberStatus, -- otr muted - Maybe Bool, Maybe MutedStatus, Maybe Text, -- otr archived @@ -1036,7 +1051,7 @@ toMember :: Maybe RoleName ) -> m (Maybe LocalMember) -- FUTUREWORK: remove monad -toMember (usr, srv, prv, sta, omu, omus, omur, oar, oarr, hid, hidr, crn) = +toMember (usr, srv, prv, sta, omus, omur, oar, oarr, hid, hidr, crn) = pure $ if sta /= Just 0 then Nothing @@ -1045,7 +1060,6 @@ toMember (usr, srv, prv, sta, omu, omus, omur, oar, oarr, hid, hidr, crn) = InternalMember { memId = usr, memService = newServiceRef <$> srv <*> prv, - memOtrMuted = fromMaybe False omu, memOtrMutedStatus = omus, memOtrMutedRef = omur, memOtrArchived = fromMaybe False oar, diff --git a/services/galley/src/Galley/Data/Queries.hs b/services/galley/src/Galley/Data/Queries.hs index 7bf9ad8c928..a54d3dcbf03 100644 --- a/services/galley/src/Galley/Data/Queries.hs +++ b/services/galley/src/Galley/Data/Queries.hs @@ -256,11 +256,11 @@ deleteUserConv = "delete from user where user = ? and conv = ?" type MemberStatus = Int32 -selectMember :: PrepQuery R (ConvId, UserId) (UserId, Maybe ServiceId, Maybe ProviderId, Maybe MemberStatus, Maybe Bool, Maybe MutedStatus, Maybe Text, Maybe Bool, Maybe Text, Maybe Bool, Maybe Text, Maybe RoleName) -selectMember = "select user, service, provider, status, otr_muted, otr_muted_status, otr_muted_ref, otr_archived, otr_archived_ref, hidden, hidden_ref, conversation_role from member where conv = ? and user = ?" +selectMember :: PrepQuery R (ConvId, UserId) (UserId, Maybe ServiceId, Maybe ProviderId, Maybe MemberStatus, Maybe MutedStatus, Maybe Text, Maybe Bool, Maybe Text, Maybe Bool, Maybe Text, Maybe RoleName) +selectMember = "select user, service, provider, status, otr_muted_status, otr_muted_ref, otr_archived, otr_archived_ref, hidden, hidden_ref, conversation_role from member where conv = ? and user = ?" -selectMembers :: PrepQuery R (Identity [ConvId]) (ConvId, UserId, Maybe ServiceId, Maybe ProviderId, Maybe MemberStatus, Maybe Bool, Maybe MutedStatus, Maybe Text, Maybe Bool, Maybe Text, Maybe Bool, Maybe Text, Maybe RoleName) -selectMembers = "select conv, user, service, provider, status, otr_muted, otr_muted_status, otr_muted_ref, otr_archived, otr_archived_ref, hidden, hidden_ref, conversation_role from member where conv in ?" +selectMembers :: PrepQuery R (Identity [ConvId]) (ConvId, UserId, Maybe ServiceId, Maybe ProviderId, Maybe MemberStatus, Maybe MutedStatus, Maybe Text, Maybe Bool, Maybe Text, Maybe Bool, Maybe Text, Maybe RoleName) +selectMembers = "select conv, user, service, provider, status, otr_muted_status, otr_muted_ref, otr_archived, otr_archived_ref, hidden, hidden_ref, conversation_role from member where conv in ?" insertMember :: PrepQuery W (ConvId, UserId, Maybe ServiceId, Maybe ProviderId, RoleName) () insertMember = "insert into member (conv, user, service, provider, status, conversation_role) values (?, ?, ?, ?, 0, ?)" @@ -268,9 +268,6 @@ insertMember = "insert into member (conv, user, service, provider, status, conve removeMember :: PrepQuery W (ConvId, UserId) () removeMember = "delete from member where conv = ? and user = ?" -updateOtrMemberMuted :: PrepQuery W (Bool, Maybe Text, ConvId, UserId) () -updateOtrMemberMuted = "update member set otr_muted = ?, otr_muted_ref = ? where conv = ? and user = ?" - updateOtrMemberMutedStatus :: PrepQuery W (MutedStatus, Maybe Text, ConvId, UserId) () updateOtrMemberMutedStatus = "update member set otr_muted_status = ?, otr_muted_ref = ? where conv = ? and user = ?" diff --git a/services/galley/test/integration/API.hs b/services/galley/test/integration/API.hs index f9502042fce..577a2d6bbe7 100644 --- a/services/galley/test/integration/API.hs +++ b/services/galley/test/integration/API.hs @@ -153,7 +153,11 @@ tests s = test s "fail to add too many members" postTooManyMembersFail, test s "add remote members" testAddRemoteMember, test s "get conversations/:domain/:cnv - local" testGetQualifiedLocalConv, + test s "get conversations/:domain/:cnv - local, not found" testGetQualifiedLocalConvNotFound, + test s "get conversations/:domain/:cnv - local, not participating" testGetQualifiedLocalConvNotParticipating, test s "get conversations/:domain/:cnv - remote" testGetQualifiedRemoteConv, + test s "get conversations/:domain/:cnv - remote, not found" testGetQualifiedRemoteConvNotFound, + test s "get conversations/:domain/:cnv - remote, not found on remote" testGetQualifiedRemoteConvNotFoundOnRemote, test s "post list-conversations" testListRemoteConvs, test s "post conversations/list/v2" testBulkGetQualifiedConvs, test s "add non-existing remote members" testAddRemoteMemberFailure, @@ -169,7 +173,10 @@ tests s = test s "delete conversations/:domain/:cnv/members/:domain/:usr - remote conv, leave conv" leaveRemoteConvQualifiedOk, test s "delete conversations/:domain/:cnv/members/:domain/:usr - remote conv, remove local user, fail" removeLocalMemberConvQualifiedFail, test s "delete conversations/:domain/:cnv/members/:domain/:usr - remote conv, remove remote user, fail" removeRemoteMemberConvQualifiedFail, + test s "rename conversation (deprecated endpoint)" putConvDeprecatedRenameOk, test s "rename conversation" putConvRenameOk, + test s "rename qualified conversation" putQualifiedConvRenameOk, + test s "rename qualified conversation failure" putQualifiedConvRenameFailure, test s "member update (otr mute)" putMemberOtrMuteOk, test s "member update (otr archive)" putMemberOtrArchiveOk, test s "member update (hidden)" putMemberHiddenOk, @@ -1840,6 +1847,24 @@ testGetQualifiedLocalConv = do assertEqual "conversation id" convId (cnvQualifiedId conv) assertEqual "conversation name" (Just "gossip") (cnvName conv) +testGetQualifiedLocalConvNotFound :: TestM () +testGetQualifiedLocalConvNotFound = do + alice <- randomUser + localDomain <- viewFederationDomain + convId <- (`Qualified` localDomain) <$> randomId + getConvQualified alice convId !!! do + const 404 === statusCode + const (Right (Just "no-conversation")) === fmap (view (at "label")) . responseJsonEither @Object + +testGetQualifiedLocalConvNotParticipating :: TestM () +testGetQualifiedLocalConvNotParticipating = do + alice <- randomUser + bob <- randomUser + convId <- decodeQualifiedConvId <$> postConv bob [] (Just "gossip about alice") [] Nothing Nothing + getConvQualified alice convId !!! do + const 403 === statusCode + const (Just "access-denied") === view (at "label") . responseJsonUnsafe @Object + testGetQualifiedRemoteConv :: TestM () testGetQualifiedRemoteConv = do aliceQ <- randomQualifiedUser @@ -1851,7 +1876,7 @@ testGetQualifiedRemoteConv = do remoteConvId = Qualified convId remoteDomain aliceAsOtherMember = OtherMember aliceQ Nothing roleNameWireAdmin bobAsOtherMember = OtherMember bobQ Nothing roleNameWireAdmin - aliceAsMember = Member aliceId Nothing False Nothing Nothing False Nothing False Nothing roleNameWireAdmin + aliceAsMember = Member aliceId Nothing Nothing Nothing False Nothing False Nothing roleNameWireAdmin registerRemoteConv remoteConvId bobQ Nothing (Set.fromList [aliceAsOtherMember]) @@ -1883,6 +1908,35 @@ testGetQualifiedRemoteConv = do -- Alice's membership data stored locally liftIO $ assertEqual "conversation" mockConversation conv +testGetQualifiedRemoteConvNotFound :: TestM () +testGetQualifiedRemoteConvNotFound = do + aliceId <- randomUser + let remoteDomain = Domain "far-away.example.com" + remoteConvId <- (`Qualified` remoteDomain) <$> randomId + -- No need to mock federator as we don't expect a call to be made + getConvQualified aliceId remoteConvId !!! do + const 404 === statusCode + const (Just "no-conversation") === view (at "label") . responseJsonUnsafe @Object + +testGetQualifiedRemoteConvNotFoundOnRemote :: TestM () +testGetQualifiedRemoteConvNotFoundOnRemote = do + aliceQ <- randomQualifiedUser + let aliceId = qUnqualified aliceQ + bobId <- randomId + convId <- randomId + let remoteDomain = Domain "far-away.example.com" + bobQ = Qualified bobId remoteDomain + remoteConvId = Qualified convId remoteDomain + aliceAsOtherMember = OtherMember aliceQ Nothing roleNameWireAdmin + + registerRemoteConv remoteConvId bobQ Nothing (Set.fromList [aliceAsOtherMember]) + + opts <- view tsGConf + void . withTempMockFederator opts remoteDomain (const (GetConversationsResponse [])) $ do + getConvQualified aliceId remoteConvId !!! do + const 404 === statusCode + const (Just "no-conversation") === view (at "label") . responseJsonUnsafe @Object + testListRemoteConvs :: TestM () testListRemoteConvs = do -- alice on local domain @@ -1896,7 +1950,7 @@ testListRemoteConvs = do remoteConvId = Qualified convId remoteDomain let aliceAsOtherMember = OtherMember aliceQ Nothing roleNameWireAdmin - bobAsMember = Member bobId Nothing False Nothing Nothing False Nothing False Nothing roleNameWireAdmin + bobAsMember = Member bobId Nothing Nothing Nothing False Nothing False Nothing roleNameWireAdmin mockConversation = Conversation { cnvQualifiedId = remoteConvId, @@ -1984,7 +2038,7 @@ testBulkGetQualifiedConvs = do registerRemoteConv remoteConvIdBNotFoundOnRemote carlQ Nothing (Set.fromList [aliceAsOtherMember]) registerRemoteConv remoteConvIdCFailure carlQ Nothing (Set.fromList [aliceAsOtherMember]) - let aliceAsSelfMember = Member (qUnqualified aliceQ) Nothing False Nothing Nothing False Nothing False Nothing roleNameWireAdmin + let aliceAsSelfMember = Member (qUnqualified aliceQ) Nothing Nothing Nothing False Nothing False Nothing roleNameWireAdmin bobAsOtherMember = OtherMember bobQ Nothing roleNameWireAdmin carlAsOtherMember = OtherMember carlQ Nothing roleNameWireAdmin mockConversationA = mkConv remoteConvIdA bobId aliceAsSelfMember [bobAsOtherMember] @@ -2010,7 +2064,7 @@ testBulkGetQualifiedConvs = do case F.domain fedReq of d | d == domainText remoteDomainA -> success $ GetConversationsResponse [mockConversationA] d | d == domainText remoteDomainB -> success $ GetConversationsResponse [mockConversationB] - d | d == domainText remoteDomainC -> pure . F.OutwardResponseError $ F.OutwardError F.DiscoveryFailed Nothing + d | d == domainText remoteDomainC -> pure . F.OutwardResponseError $ F.OutwardError F.DiscoveryFailed "discovery failed" _ -> assertFailure $ "Unrecognized domain: " <> show fedReq ) (listConvsV2 alice req) @@ -2418,6 +2472,65 @@ deleteMembersUnqualifiedFailO2O = do o2o <- decodeConvId <$> postO2OConv alice bob (Just "foo") deleteMemberUnqualified alice bob o2o !!! const 403 === statusCode +putQualifiedConvRenameFailure :: TestM () +putQualifiedConvRenameFailure = do + conv <- randomId + qbob <- randomQualifiedUser + let qconv = Qualified conv (qDomain qbob) + putQualifiedConversationName (qUnqualified qbob) qconv "gossip" + !!! do + const 404 === statusCode + const (Just "no-conversation") === fmap label . responseJsonUnsafe + +putQualifiedConvRenameOk :: TestM () +putQualifiedConvRenameOk = do + c <- view tsCannon + alice <- randomUser + qbob <- randomQualifiedUser + let bob = qUnqualified qbob + connectUsers alice (singleton bob) + conv <- decodeConvId <$> postO2OConv alice bob (Just "gossip") + let qconv = Qualified conv (qDomain qbob) + WS.bracketR2 c alice bob $ \(wsA, wsB) -> do + void $ putQualifiedConversationName bob qconv "gossip++" !!! const 200 === statusCode + void . liftIO . WS.assertMatchN (5 # Second) [wsA, wsB] $ \n -> do + let e = List1.head (WS.unpackPayload n) + ntfTransient n @?= False + evtConv e @?= qconv + evtType e @?= ConvRename + evtFrom e @?= qbob + evtData e @?= EdConvRename (ConversationRename "gossip++") + +putConvDeprecatedRenameOk :: TestM () +putConvDeprecatedRenameOk = do + c <- view tsCannon + g <- view tsGalley + alice <- randomUser + qbob <- randomQualifiedUser + let bob = qUnqualified qbob + connectUsers alice (singleton bob) + conv <- decodeConvId <$> postO2OConv alice bob (Just "gossip") + let qconv = Qualified conv (qDomain qbob) + WS.bracketR2 c alice bob $ \(wsA, wsB) -> do + -- This endpoint is deprecated but clients still use it + put + ( g + . paths ["conversations", toByteString' conv] + . zUser bob + . zConn "conn" + . zType "access" + . json (ConversationRename "gossip++") + ) + !!! const 200 + === statusCode + void . liftIO . WS.assertMatchN (5 # Second) [wsA, wsB] $ \n -> do + let e = List1.head (WS.unpackPayload n) + ntfTransient n @?= False + evtConv e @?= qconv + evtType e @?= ConvRename + evtFrom e @?= qbob + evtData e @?= EdConvRename (ConversationRename "gossip++") + putConvRenameOk :: TestM () putConvRenameOk = do c <- view tsCannon @@ -2427,7 +2540,6 @@ putConvRenameOk = do connectUsers alice (singleton bob) conv <- decodeConvId <$> postO2OConv alice bob (Just "gossip") let qconv = Qualified conv (qDomain qbob) - -- This endpoint should be deprecated but clients still use it WS.bracketR2 c alice bob $ \(wsA, wsB) -> do void $ putConversationName bob conv "gossip++" !!! const 200 === statusCode void . liftIO . WS.assertMatchN (5 # Second) [wsA, wsB] $ \n -> do @@ -2440,8 +2552,8 @@ putConvRenameOk = do putMemberOtrMuteOk :: TestM () putMemberOtrMuteOk = do - putMemberOk (memberUpdate {mupOtrMute = Just True, mupOtrMuteStatus = Just 0, mupOtrMuteRef = Just "ref"}) - putMemberOk (memberUpdate {mupOtrMute = Just False}) + putMemberOk (memberUpdate {mupOtrMuteStatus = Just 1, mupOtrMuteRef = Just "ref"}) + putMemberOk (memberUpdate {mupOtrMuteStatus = Just 0}) putMemberOtrArchiveOk :: TestM () putMemberOtrArchiveOk = do @@ -2457,8 +2569,7 @@ putMemberAllOk :: TestM () putMemberAllOk = putMemberOk ( memberUpdate - { mupOtrMute = Just True, - mupOtrMuteStatus = Just 0, + { mupOtrMuteStatus = Just 0, mupOtrMuteRef = Just "mref", mupOtrArchive = Just True, mupOtrArchiveRef = Just "aref", @@ -2482,14 +2593,13 @@ putMemberOk update = do Member { memId = bob, memService = Nothing, - memOtrMuted = Just True == mupOtrMute update, memOtrMutedStatus = mupOtrMuteStatus update, memOtrMutedRef = mupOtrMuteRef update, memOtrArchived = Just True == mupOtrArchive update, memOtrArchivedRef = mupOtrArchiveRef update, memHidden = Just True == mupHidden update, memHiddenRef = mupHiddenRef update, - memConvRoleName = fromMaybe roleNameWireAdmin (mupConvRoleName update) + memConvRoleName = roleNameWireAdmin } -- Update member state & verify push notification WS.bracketR c bob $ \ws -> do @@ -2502,7 +2612,7 @@ putMemberOk update = do evtFrom e @?= qbob case evtData e of EdMemberUpdate mis -> do - assertEqual "otr_muted" (mupOtrMute update) (misOtrMuted mis) + assertEqual "otr_muted_status" (mupOtrMuteStatus update) (misOtrMutedStatus mis) assertEqual "otr_muted_ref" (mupOtrMuteRef update) (misOtrMutedRef mis) assertEqual "otr_archived" (mupOtrArchive update) (misOtrArchived mis) assertEqual "otr_archived_ref" (mupOtrArchiveRef update) (misOtrArchivedRef mis) @@ -2516,12 +2626,12 @@ putMemberOk update = do assertBool "user" (isJust bob') let newBob = fromJust bob' assertEqual "id" (memId memberBob) (memId newBob) - assertEqual "otr_muted" (memOtrMuted memberBob) (memOtrMuted newBob) + assertEqual "otr_muted_status" (memOtrMutedStatus memberBob) (memOtrMutedStatus newBob) assertEqual "otr_muted_ref" (memOtrMutedRef memberBob) (memOtrMutedRef newBob) assertEqual "otr_archived" (memOtrArchived memberBob) (memOtrArchived newBob) assertEqual "otr_archived_ref" (memOtrArchivedRef memberBob) (memOtrArchivedRef newBob) assertEqual "hidden" (memHidden memberBob) (memHidden newBob) - assertEqual "hidden__ref" (memHiddenRef memberBob) (memHiddenRef newBob) + assertEqual "hidden_ref" (memHiddenRef memberBob) (memHiddenRef newBob) putReceiptModeOk :: TestM () putReceiptModeOk = do diff --git a/services/galley/test/integration/API/Federation.hs b/services/galley/test/integration/API/Federation.hs index 9dcc456948e..e11383260ff 100644 --- a/services/galley/test/integration/API/Federation.hs +++ b/services/galley/test/integration/API/Federation.hs @@ -372,8 +372,9 @@ receiveMessage = do bob <- randomId conv <- randomId let fromc = newClientId 0 - alicec = newClientId 0 - evec = newClientId 0 + aliceC1 = newClientId 0 + aliceC2 = newClientId 1 + eveC = newClientId 0 bdom = Domain "bob.example.com" qconv = Qualified conv bdom qbob = Qualified bob bdom @@ -397,7 +398,7 @@ receiveMessage = do msg client = Map.fromList [(client, txt)] rcpts = UserClientMap $ - Map.fromList [(alice, msg alicec), (eve, msg evec)] + Map.fromListWith (<>) [(alice, msg aliceC1), (alice, msg aliceC2), (eve, msg eveC)] rm = FedGalley.RemoteMessage { FedGalley.rmTime = now, @@ -412,18 +413,33 @@ receiveMessage = do } -- send message to alice and check reception - WS.bracketR2 c alice eve $ \(wsA, wsE) -> do + WS.bracketAsClientRN c [(alice, aliceC1), (alice, aliceC2), (eve, eveC)] $ \[wsA1, wsA2, wsE] -> do FedGalley.receiveMessage fedGalleyClient bdom rm liftIO $ do - -- alice should receive the message - WS.assertMatch_ (5 # Second) wsA $ \n -> - do - let e = List1.head (WS.unpackPayload n) - ntfTransient n @?= False - evtConv e @?= qconv - evtType e @?= OtrMessageAdd - evtFrom e @?= qbob - evtData e @?= EdOtrMessage (OtrMessage fromc alicec txt Nothing) + -- alice should receive the message on her first client + WS.assertMatch_ (5 # Second) wsA1 $ \n -> do + let e = List1.head (WS.unpackPayload n) + ntfTransient n @?= False + evtConv e @?= qconv + evtType e @?= OtrMessageAdd + evtFrom e @?= qbob + evtData e @?= EdOtrMessage (OtrMessage fromc aliceC1 txt Nothing) + + -- alice should receive the message on her second client + WS.assertMatch_ (5 # Second) wsA2 $ \n -> do + let e = List1.head (WS.unpackPayload n) + ntfTransient n @?= False + evtConv e @?= qconv + evtType e @?= OtrMessageAdd + evtFrom e @?= qbob + evtData e @?= EdOtrMessage (OtrMessage fromc aliceC2 txt Nothing) + + -- These should be the only events for each device of alice. This verifies + -- that targetted delivery to the clients was used so that client 2 does + -- not receive the message encrypted for client 1 and vice versa. + WS.assertNoEvent (1 # Second) [wsA1] + WS.assertNoEvent (1 # Second) [wsA2] + -- eve should not receive the message WS.assertNoEvent (1 # Second) [wsE] diff --git a/services/galley/test/integration/API/Roles.hs b/services/galley/test/integration/API/Roles.hs index 7d9265e6b3d..72928b13335 100644 --- a/services/galley/test/integration/API/Roles.hs +++ b/services/galley/test/integration/API/Roles.hs @@ -182,7 +182,7 @@ wireAdminChecks cid admin otherAdmin mem = do let activatedAccess = ConversationAccessUpdate [InviteAccess] NonActivatedAccessRole putAccessUpdate admin cid activatedAccess !!! assertActionSucceeded -- Update your own member state - let memUpdate = memberUpdate {mupOtrMute = Just True} + let memUpdate = memberUpdate {mupOtrArchive = Just True} putMember admin memUpdate cid !!! assertActionSucceeded -- You can also leave a conversation deleteMemberUnqualified admin admin cid !!! assertActionSucceeded @@ -218,10 +218,6 @@ wireMemberChecks cid mem admin otherMem = do putOtherMember mem mem sneakyOtherMemberUpdate cid !!! do const 403 === statusCode const (Just "invalid-op") === fmap label . responseJsonUnsafe - let selfMemberUpdate = memberUpdate {mupConvRoleName = Just roleNameWireAdmin} - putMember mem selfMemberUpdate cid !!! do - const 403 === statusCode - const (Just "invalid-actions") === fmap label . responseJsonUnsafe -- No updates for message timer, receipt mode or access putMessageTimerUpdate mem cid (ConversationMessageTimerUpdate Nothing) !!! assertActionDenied putReceiptMode mem cid (ReceiptMode 0) !!! assertActionDenied @@ -230,7 +226,7 @@ wireMemberChecks cid mem admin otherMem = do -- Finally, you can still do the following actions: -- Update your own member state - let memUpdate = memberUpdate {mupOtrMute = Just True} + let memUpdate = memberUpdate {mupOtrArchive = Just True} putMember mem memUpdate cid !!! assertActionSucceeded -- Last option is to leave a conversation deleteMemberUnqualified mem mem cid !!! assertActionSucceeded diff --git a/services/galley/test/integration/API/Util.hs b/services/galley/test/integration/API/Util.hs index 361aede80a0..ae5afebc38b 100644 --- a/services/galley/test/integration/API/Util.hs +++ b/services/galley/test/integration/API/Util.hs @@ -70,7 +70,7 @@ import Data.UUID.V4 import Galley.Intra.User (chunkify) import qualified Galley.Options as Opts import qualified Galley.Run as Run -import Galley.Types hiding (InternalMember, MemberJoin, MemberLeave, memConvRoleName, memId, memOtrArchived, memOtrArchivedRef, memOtrMuted, memOtrMutedRef) +import Galley.Types hiding (InternalMember, MemberJoin, MemberLeave, memConvRoleName, memId, memOtrArchived, memOtrArchivedRef, memOtrMutedRef) import qualified Galley.Types as Conv import Galley.Types.Conversations.Roles hiding (DeleteConversation) import Galley.Types.Teams hiding (Event, EventType (..)) @@ -967,13 +967,31 @@ putOtherMember from to m c = do . zType "access" . json m +putQualifiedConversationName :: UserId -> Qualified ConvId -> Text -> TestM ResponseLBS +putQualifiedConversationName u c n = do + g <- view tsGalley + let update = ConversationRename n + put + ( g + . paths + [ "conversations", + toByteString' (qDomain c), + toByteString' (qUnqualified c), + "name" + ] + . zUser u + . zConn "conn" + . zType "access" + . json update + ) + putConversationName :: UserId -> ConvId -> Text -> TestM ResponseLBS putConversationName u c n = do g <- view tsGalley let update = ConversationRename n put ( g - . paths ["conversations", toByteString' c] + . paths ["conversations", toByteString' c, "name"] . zUser u . zConn "conn" . zType "access" @@ -1235,7 +1253,6 @@ assertConvWithRole r t c s us n mt role = do assertEqual "others" (Just . Set.fromList $ us) (Set.fromList . map (qUnqualified . omQualifiedId) . toList <$> others) assertEqual "creator is always and admin" (Just roleNameWireAdmin) (memConvRoleName <$> _self) assertBool "others role" (all (== role) $ maybe (error "Cannot be null") (map omConvRoleName . toList) others) - assertBool "otr muted not false" (Just False == (memOtrMuted <$> _self)) assertBool "otr muted ref not empty" (isNothing (memOtrMutedRef =<< _self)) assertBool "otr archived not false" (Just False == (memOtrArchived <$> _self)) assertBool "otr archived ref not empty" (isNothing (memOtrArchivedRef =<< _self)) @@ -1460,7 +1477,7 @@ connectUsersWith fn u = mapM connectTo . zUser u . zConn "conn" . path "/connections" - . json (ConnectionRequest v "chat" (Message "Y")) + . json (ConnectionRequest v (unsafeRange "chat")) . fn ) r2 <- @@ -1488,7 +1505,7 @@ postConnection from to = do where payload = RequestBodyLBS . encode $ - ConnectionRequest to "some conv name" (Message "some message") + ConnectionRequest to (unsafeRange "some conv name") -- | A copy of 'putConnection' from Brig integration tests. putConnection :: UserId -> UserId -> Relation -> TestM ResponseLBS @@ -2105,7 +2122,7 @@ makeFedRequestToServant originDomain server fedRequest = if Test.simpleStatus response == status200 then pure (F.OutwardResponseBody (cs (Test.simpleBody response))) else do - pure (F.OutwardResponseError (F.OutwardError F.RemoteFederatorError (Just (F.ErrorPayload "mock-error" (cs (Test.simpleBody response)))))) + pure (F.OutwardResponseError (F.OutwardError F.GrpcError (cs (Test.simpleBody response)))) toRequestWithoutBody :: F.Request -> Wai.Request toRequestWithoutBody req = diff --git a/services/galley/test/unit/Test/Galley/Mapping.hs b/services/galley/test/unit/Test/Galley/Mapping.hs index 7ed75e2df3a..2f77de53b23 100644 --- a/services/galley/test/unit/Test/Galley/Mapping.hs +++ b/services/galley/test/unit/Test/Galley/Mapping.hs @@ -182,7 +182,6 @@ mkMember (Qualified userId _domain) = Member { memId = userId, memService = Nothing, - memOtrMuted = False, memOtrMutedStatus = Nothing, memOtrMutedRef = Nothing, memOtrArchived = False, @@ -197,7 +196,6 @@ mkInternalMember (Qualified userId _domain) = I.InternalMember { I.memId = userId, I.memService = Nothing, - I.memOtrMuted = False, I.memOtrMutedStatus = Nothing, I.memOtrMutedRef = Nothing, I.memOtrArchived = False, diff --git a/services/spar/schema/src/Main.hs b/services/spar/schema/src/Main.hs index d039eb31548..4084b5c10a4 100644 --- a/services/spar/schema/src/Main.hs +++ b/services/spar/schema/src/Main.hs @@ -29,6 +29,7 @@ import qualified V11 import qualified V12 import qualified V13 import qualified V14 +import qualified V15 import qualified V2 import qualified V3 import qualified V4 @@ -61,7 +62,8 @@ main = do V11.migration, V12.migration, V13.migration, - V14.migration + V14.migration, + V15.migration -- When adding migrations here, don't forget to update -- 'schemaVersion' in Spar.Data diff --git a/services/spar/schema/src/V15.hs b/services/spar/schema/src/V15.hs new file mode 100644 index 00000000000..6ead409623a --- /dev/null +++ b/services/spar/schema/src/V15.hs @@ -0,0 +1,43 @@ +-- This file is part of the Wire Server implementation. +-- +-- Copyright (C) 2020 Wire Swiss GmbH +-- +-- This program is free software: you can redistribute it and/or modify it under +-- the terms of the GNU Affero General Public License as published by the Free +-- Software Foundation, either version 3 of the License, or (at your option) any +-- later version. +-- +-- This program is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +-- details. +-- +-- You should have received a copy of the GNU Affero General Public License along +-- with this program. If not, see . + +module V15 + ( migration, + ) +where + +import Cassandra.Schema +import Imports +import Text.RawString.QQ + +migration :: Migration +migration = Migration 15 "Optionally index IdP by teamid (in addition to entityID); add idp api version." $ do + void $ + schema' + [r| + CREATE TABLE if not exists issuer_idp_v2 + ( issuer text + , team uuid + , idp uuid + , PRIMARY KEY (issuer, team) + ) with compaction = {'class': 'LeveledCompactionStrategy'}; + |] + void $ + schema' + [r| + ALTER TABLE idp ADD api_version int; + |] diff --git a/services/spar/spar.cabal b/services/spar/spar.cabal index 884c3ef17e7..ec6623400fb 100644 --- a/services/spar/spar.cabal +++ b/services/spar/spar.cabal @@ -4,7 +4,7 @@ cabal-version: 1.12 -- -- see: https://github.com/sol/hpack -- --- hash: 2afa3a03f475aac5d63ab87ded5843f404fee3d8506ac70390ee37dde18f22d4 +-- hash: 6a8deefc6739b8a56d89eae84bd4333254d31f2b1bf1ab22b830d7d120992bbf name: spar version: 0.1 @@ -364,6 +364,7 @@ executable spar-schema V12 V13 V14 + V15 V2 V3 V4 diff --git a/services/spar/src/Spar/API.hs b/services/spar/src/Spar/API.hs index 4d8dccbc1e3..9b5b6923dec 100644 --- a/services/spar/src/Spar/API.hs +++ b/services/spar/src/Spar/API.hs @@ -85,10 +85,12 @@ api opts = apiSSO :: Opts -> ServerT APISSO Spar apiSSO opts = - SAML.meta appName sparSPIssuer sparResponseURI + SAML.meta appName (sparSPIssuer Nothing) (sparResponseURI Nothing) + :<|> (\tid -> SAML.meta appName (sparSPIssuer (Just tid)) (sparResponseURI (Just tid))) :<|> authreqPrecheck :<|> authreq (maxttlAuthreqDiffTime opts) DoInitiateLogin - :<|> authresp + :<|> authresp Nothing + :<|> authresp . Just :<|> ssoSettings apiIDP :: ServerT APIIDP Spar @@ -130,7 +132,13 @@ authreq _ DoInitiateLogin (Just _) _ _ _ = throwSpar SparInitLoginWithAuth authreq _ DoInitiateBind Nothing _ _ _ = throwSpar SparInitBindWithoutAuth authreq authreqttl _ zusr msucc merr idpid = do vformat <- validateAuthreqParams msucc merr - form@(SAML.FormRedirect _ ((^. SAML.rqID) -> reqid)) <- SAML.authreq authreqttl sparSPIssuer idpid + form@(SAML.FormRedirect _ ((^. SAML.rqID) -> reqid)) <- do + idp :: IdP <- wrapMonadClient (Data.getIdPConfig idpid) >>= maybe (throwSpar (SparIdPNotFound (cs $ show idpid))) pure + let mbtid :: Maybe TeamId + mbtid = case fromMaybe defWireIdPAPIVersion (idp ^. SAML.idpExtraInfo . wiApiVersion) of + WireIdPAPIV1 -> Nothing + WireIdPAPIV2 -> Just $ idp ^. SAML.idpExtraInfo . wiTeam + SAML.authreq authreqttl (sparSPIssuer mbtid) idpid wrapMonadClient $ Data.storeVerdictFormat authreqttl reqid vformat cky <- initializeBindCookie zusr authreqttl SAML.logger SAML.Debug $ "setting bind cookie: " <> show cky @@ -168,15 +176,17 @@ validateRedirectURL uri = do unless ((SBS.length $ URI.serializeURIRef' uri) <= redirectURLMaxLength) $ do throwSpar $ SparBadInitiateLoginQueryParams "url-too-long" -authresp :: Maybe ST -> SAML.AuthnResponseBody -> Spar Void -authresp ckyraw arbody = logErrors $ SAML.authresp sparSPIssuer sparResponseURI go arbody +authresp :: Maybe TeamId -> Maybe ST -> SAML.AuthnResponseBody -> Spar Void +authresp mbtid ckyraw arbody = logErrors $ SAML.authresp mbtid (sparSPIssuer mbtid) (sparResponseURI mbtid) go arbody where cky :: Maybe BindCookie cky = ckyraw >>= bindCookieFromHeader + go :: SAML.AuthnResponse -> SAML.AccessVerdict -> Spar Void go resp verdict = do - result :: SAML.ResponseVerdict <- verdictHandler cky resp verdict + result :: SAML.ResponseVerdict <- verdictHandler cky mbtid resp verdict throwError $ SAML.CustomServant result + logErrors :: Spar Void -> Spar Void logErrors = flip catchError $ \case e@(SAML.CustomServant _) -> throwError e @@ -206,7 +216,7 @@ idpGetRaw zusr idpid = do _ <- authorizeIdP zusr idp wrapMonadClient (Data.getIdPRawMetadata idpid) >>= \case Just txt -> pure $ RawIdPMetadata txt - Nothing -> throwSpar SparIdPNotFound + Nothing -> throwSpar $ SparIdPNotFound (cs $ show idpid) idpGetAll :: Maybe UserId -> Spar IdPList idpGetAll zusr = withDebugLog "idpGetAll" (const Nothing) $ do @@ -267,21 +277,25 @@ idpDelete zusr idpid (fromMaybe False -> purge) = withDebugLog "idpDelete" (cons updateReplacingIdP :: IdP -> Spar () updateReplacingIdP idp = forM_ (idp ^. SAML.idpExtraInfo . wiOldIssuers) $ \oldIssuer -> do wrapMonadClient $ do - iid <- Data.getIdPIdByIssuer oldIssuer - mapM_ (Data.clearReplacedBy . Data.Replaced) iid + Data.getIdPIdByIssuer oldIssuer (idp ^. SAML.idpExtraInfo . wiTeam) >>= \case + Data.GetIdPFound iid -> Data.clearReplacedBy $ Data.Replaced iid + Data.GetIdPNotFound -> pure () + Data.GetIdPDanglingId _ -> pure () + Data.GetIdPNonUnique _ -> pure () + Data.GetIdPWrongTeam _ -> pure () -- | This handler only does the json parsing, and leaves all authorization checks and -- application logic to 'idpCreateXML'. -idpCreate :: Maybe UserId -> IdPMetadataInfo -> Maybe SAML.IdPId -> Spar IdP -idpCreate zusr (IdPMetadataValue raw xml) midpid = idpCreateXML zusr raw xml midpid +idpCreate :: Maybe UserId -> IdPMetadataInfo -> Maybe SAML.IdPId -> Maybe WireIdPAPIVersion -> Spar IdP +idpCreate zusr (IdPMetadataValue raw xml) midpid apiversion = idpCreateXML zusr raw xml midpid apiversion -- | We generate a new UUID for each IdP used as IdPConfig's path, thereby ensuring uniqueness. -idpCreateXML :: Maybe UserId -> Text -> SAML.IdPMetadata -> Maybe SAML.IdPId -> Spar IdP -idpCreateXML zusr raw idpmeta mReplaces = withDebugLog "idpCreate" (Just . show . (^. SAML.idpId)) $ do +idpCreateXML :: Maybe UserId -> Text -> SAML.IdPMetadata -> Maybe SAML.IdPId -> Maybe WireIdPAPIVersion -> Spar IdP +idpCreateXML zusr raw idpmeta mReplaces (fromMaybe defWireIdPAPIVersion -> apiversion) = withDebugLog "idpCreate" (Just . show . (^. SAML.idpId)) $ do teamid <- Brig.getZUsrCheckPerm zusr CreateUpdateDeleteIdp Galley.assertSSOEnabled teamid assertNoScimOrNoIdP teamid - idp <- validateNewIdP idpmeta teamid mReplaces + idp <- validateNewIdP apiversion idpmeta teamid mReplaces wrapMonadClient $ Data.storeIdPRawMetadata (idp ^. SAML.idpId) raw SAML.storeIdPConfig idp forM_ mReplaces $ \replaces -> wrapMonadClient $ do @@ -320,23 +334,61 @@ assertNoScimOrNoIdP teamid = do validateNewIdP :: forall m. (HasCallStack, m ~ Spar) => + WireIdPAPIVersion -> SAML.IdPMetadata -> TeamId -> Maybe SAML.IdPId -> m IdP -validateNewIdP _idpMetadata teamId mReplaces = do +validateNewIdP apiversion _idpMetadata teamId mReplaces = withDebugLog "validateNewIdP" (Just . show . (^. SAML.idpId)) $ do _idpId <- SAML.IdPId <$> SAML.createUUID oldIssuers :: [SAML.Issuer] <- case mReplaces of Nothing -> pure [] Just replaces -> do - idp <- wrapMonadClient (Data.getIdPConfig replaces) >>= maybe (throwSpar SparIdPNotFound) pure + idp <- wrapMonadClient (Data.getIdPConfig replaces) >>= maybe (throwSpar (SparIdPNotFound (cs $ show mReplaces))) pure pure $ (idp ^. SAML.idpMetadata . SAML.edIssuer) : (idp ^. SAML.idpExtraInfo . wiOldIssuers) let requri = _idpMetadata ^. SAML.edRequestURI - _idpExtraInfo = WireIdP teamId oldIssuers Nothing + _idpExtraInfo = WireIdP teamId (Just apiversion) oldIssuers Nothing enforceHttps requri - wrapMonadClient (Data.getIdPIdByIssuer (_idpMetadata ^. SAML.edIssuer)) >>= \case - Nothing -> pure () - Just _ -> throwSpar SparNewIdPAlreadyInUse + idp <- wrapMonadClient (Data.getIdPConfigByIssuer (_idpMetadata ^. SAML.edIssuer) teamId) + SAML.logger SAML.Debug $ show (apiversion, _idpMetadata, teamId, mReplaces) + SAML.logger SAML.Debug $ show (_idpId, oldIssuers, idp) + + let handleIdPClash :: Either SAML.IdPId IdP -> m () + handleIdPClash = case apiversion of + WireIdPAPIV1 -> const $ do + throwSpar $ SparNewIdPAlreadyInUse "you can't create an IdP with api-version v1 if the issuer is already in use on the wire instance." + WireIdPAPIV2 -> \case + (Right idp') -> do + guardSameTeam idp' + guardReplaceeV2 + (Left id') -> do + idp' <- do + let err = throwSpar $ SparIdPNotFound (cs $ show id') -- database inconsistency + wrapMonadClient (Data.getIdPConfig id') >>= maybe err pure + handleIdPClash (Right idp') + + guardSameTeam :: IdP -> m () + guardSameTeam idp' = do + when ((idp' ^. SAML.idpExtraInfo . wiTeam) == teamId) $ do + throwSpar $ SparNewIdPAlreadyInUse "if the exisitng IdP is registered for a team, the new one can't have it." + + guardReplaceeV2 :: m () + guardReplaceeV2 = forM_ mReplaces $ \rid -> do + ridp <- do + let err = throwSpar $ SparIdPNotFound (cs $ show rid) -- database inconsistency + wrapMonadClient (Data.getIdPConfig rid) >>= maybe err pure + when (fromMaybe defWireIdPAPIVersion (ridp ^. SAML.idpExtraInfo . wiApiVersion) /= WireIdPAPIV2) $ do + throwSpar $ + SparNewIdPAlreadyInUse + (cs $ "api-version mismatch: " <> show ((ridp ^. SAML.idpExtraInfo . wiApiVersion), WireIdPAPIV2)) + + case idp of + Data.GetIdPFound idp' {- same team -} -> handleIdPClash (Right idp') + Data.GetIdPNotFound -> pure () + res@(Data.GetIdPDanglingId _) -> throwSpar . SparIdPNotFound . cs . show $ res -- database inconsistency + res@(Data.GetIdPNonUnique _) -> throwSpar . SparIdPNotFound . cs . show $ res -- impossible + Data.GetIdPWrongTeam id' {- different team -} -> handleIdPClash (Left id') + pure SAML.IdPConfig {..} -- | FUTUREWORK: 'idpUpdateXML' is only factored out of this function for symmetry with @@ -367,7 +419,7 @@ validateIdPUpdate :: SAML.IdPMetadata -> SAML.IdPId -> m (TeamId, IdP) -validateIdPUpdate zusr _idpMetadata _idpId = do +validateIdPUpdate zusr _idpMetadata _idpId = withDebugLog "validateNewIdP" (Just . show . (_2 %~ (^. SAML.idpId))) $ do previousIdP <- wrapMonadClient (Data.getIdPConfig _idpId) >>= \case Nothing -> throwError errUnknownIdPId @@ -381,10 +433,13 @@ validateIdPUpdate zusr _idpMetadata _idpId = do if previousIssuer == newIssuer then pure $ previousIdP ^. SAML.idpExtraInfo else do - foundConfig <- wrapMonadClient (Data.getIdPConfigByIssuer newIssuer) - let notInUseByOthers = case foundConfig of - Nothing -> True - Just c -> c ^. SAML.idpId == _idpId + foundConfig <- wrapMonadClient (Data.getIdPConfigByIssuerAllowOld newIssuer (Just teamId)) + notInUseByOthers <- case foundConfig of + Data.GetIdPFound c -> pure $ c ^. SAML.idpId == _idpId + Data.GetIdPNotFound -> pure True + res@(Data.GetIdPDanglingId _) -> throwSpar . SparIdPNotFound . cs . show $ res -- impossible + res@(Data.GetIdPNonUnique _) -> throwSpar . SparIdPNotFound . cs . show $ res -- impossible (because team id was used in lookup) + Data.GetIdPWrongTeam _ -> pure False if notInUseByOthers then pure $ (previousIdP ^. SAML.idpExtraInfo) & wiOldIssuers %~ nub . (previousIssuer :) else throwSpar SparIdPIssuerInUse @@ -445,7 +500,7 @@ internalPutSsoSettings SsoSettings {defaultSsoCode = Just code} = do -- this will return a 404, which is not quite right, -- but it's an internal endpoint and the message clearly says -- "Could not find IdP". - throwSpar SparIdPNotFound + throwSpar $ SparIdPNotFound mempty Just _ -> do wrapMonadClient $ Data.storeDefaultSsoCode code pure NoContent diff --git a/services/spar/src/Spar/App.hs b/services/spar/src/Spar/App.hs index 340c8d5cf3a..2e243d33d64 100644 --- a/services/spar/src/Spar/App.hs +++ b/services/spar/src/Spar/App.hs @@ -29,8 +29,6 @@ module Spar.App getUserByUref, getUserByScimExternalId, insertUser, - autoprovisionSamlUser, - autoprovisionSamlUserWithId, validateEmailIfExists, errorPage, ) @@ -48,6 +46,7 @@ import Control.Monad.Except import Data.Aeson as Aeson (encode, object, (.=)) import Data.Aeson.Text as Aeson (encodeToLazyText) import qualified Data.ByteString.Builder as Builder +import qualified Data.CaseInsensitive as CI import Data.Id import Data.String.Conversions import Data.Text.Ascii (encodeBase64, toText) @@ -77,6 +76,7 @@ import SAML2.WebSSO uidTenant, ) import qualified SAML2.WebSSO as SAML +import qualified SAML2.WebSSO.Types.Email as SAMLEmail import Servant import qualified Servant.Multipart as Multipart import qualified Spar.Data as Data @@ -146,15 +146,22 @@ instance SPStoreID Assertion Spar where instance SPStoreIdP SparError Spar where type IdPConfigExtra Spar = WireIdP + type IdPConfigSPId Spar = TeamId storeIdPConfig :: IdP -> Spar () storeIdPConfig idp = wrapMonadClient $ Data.storeIdPConfig idp getIdPConfig :: IdPId -> Spar IdP - getIdPConfig = (>>= maybe (throwSpar SparIdPNotFound) pure) . wrapMonadClientWithEnv . Data.getIdPConfig + getIdPConfig = (>>= maybe (throwSpar (SparIdPNotFound mempty)) pure) . wrapMonadClientWithEnv . Data.getIdPConfig - getIdPConfigByIssuer :: Issuer -> Spar IdP - getIdPConfigByIssuer = (>>= maybe (throwSpar SparIdPNotFound) pure) . wrapMonadClientWithEnv . Data.getIdPConfigByIssuer + getIdPConfigByIssuerOptionalSPId :: Issuer -> Maybe TeamId -> Spar IdP + getIdPConfigByIssuerOptionalSPId issuer mbteam = do + wrapMonadClientWithEnv (Data.getIdPConfigByIssuerAllowOld issuer mbteam) >>= \case + Data.GetIdPFound idp -> pure idp + Data.GetIdPNotFound -> throwSpar $ SparIdPNotFound mempty + res@(Data.GetIdPDanglingId _) -> throwSpar $ SparIdPNotFound (cs $ show res) + res@(Data.GetIdPNonUnique _) -> throwSpar $ SparIdPNotFound (cs $ show res) + res@(Data.GetIdPWrongTeam _) -> throwSpar $ SparIdPNotFound (cs $ show res) -- | 'wrapMonadClient' with an 'Env' in a 'ReaderT', and exceptions. If you -- don't need either of those, 'wrapMonadClient' will suffice. @@ -229,47 +236,53 @@ getUserByScimExternalId tid email = do -- FUTUREWORK: once we support , brig will refuse to delete -- users that have an sso id, unless the request comes from spar. then we can make users -- undeletable in the team admin page, and ask admins to go talk to their IdP system. -createSamlUserWithId :: UserId -> SAML.UserRef -> ManagedBy -> Spar () -createSamlUserWithId buid suid managedBy = do - teamid <- (^. idpExtraInfo . wiTeam) <$> getIdPConfigByIssuer (suid ^. uidTenant) +createSamlUserWithId :: IdP -> UserId -> SAML.UserRef -> Spar () +createSamlUserWithId idp buid suid = do + let teamid = idp ^. idpExtraInfo . wiTeam uname <- either (throwSpar . SparBadUserName . cs) pure $ Intra.mkUserName Nothing (UrefOnly suid) - buid' <- Intra.createBrigUserSAML suid buid teamid uname managedBy + buid' <- Intra.createBrigUserSAML suid buid teamid uname ManagedByWire assert (buid == buid') $ pure () insertUser suid buid -- | If the team has no scim token, call 'createSamlUser'. Otherwise, raise "invalid -- credentials". -autoprovisionSamlUser :: SAML.UserRef -> ManagedBy -> Spar UserId -autoprovisionSamlUser suid managedBy = do +autoprovisionSamlUser :: Maybe TeamId -> SAML.UserRef -> Spar UserId +autoprovisionSamlUser mbteam suid = do buid <- Id <$> liftIO UUID.nextRandom - autoprovisionSamlUserWithId buid suid managedBy + autoprovisionSamlUserWithId mbteam buid suid pure buid -- | Like 'autoprovisionSamlUser', but for an already existing 'UserId'. -autoprovisionSamlUserWithId :: UserId -> SAML.UserRef -> ManagedBy -> Spar () -autoprovisionSamlUserWithId buid suid managedBy = do - idp <- getIdPConfigByIssuer (suid ^. uidTenant) - unless (isNothing $ idp ^. idpExtraInfo . wiReplacedBy) $ do - throwSpar $ SparCannotCreateUsersOnReplacedIdP (cs . SAML.idPIdToST $ idp ^. idpId) - let teamid = idp ^. idpExtraInfo . wiTeam - scimtoks <- wrapMonadClient $ Data.getScimTokens teamid - if null scimtoks - then do - createSamlUserWithId buid suid managedBy - validateEmailIfExists buid suid - else - throwError . SAML.Forbidden $ - "bad credentials (note that your team uses SCIM, " - <> "which disables saml auto-provisioning)" +autoprovisionSamlUserWithId :: Maybe TeamId -> UserId -> SAML.UserRef -> Spar () +autoprovisionSamlUserWithId mbteam buid suid = do + idp <- getIdPConfigByIssuerOptionalSPId (suid ^. uidTenant) mbteam + guardReplacedIdP idp + guardScimTokens idp + createSamlUserWithId idp buid suid + validateEmailIfExists buid suid + where + -- Replaced IdPs are not allowed to create new wire accounts. + guardReplacedIdP :: IdP -> Spar () + guardReplacedIdP idp = do + unless (isNothing $ idp ^. idpExtraInfo . wiReplacedBy) $ do + throwSpar $ SparCannotCreateUsersOnReplacedIdP (cs . SAML.idPIdToST $ idp ^. idpId) + + -- IdPs in teams with scim tokens are not allowed to auto-provision. + guardScimTokens :: IdP -> Spar () + guardScimTokens idp = do + let teamid = idp ^. idpExtraInfo . wiTeam + scimtoks <- wrapMonadClient $ Data.getScimTokens teamid + unless (null scimtoks) $ do + throwSpar SparSamlCredentialsNotFound -- | If user's 'NameID' is an email address and the team has email validation for SSO enabled, -- make brig initiate the email validate procedure. validateEmailIfExists :: UserId -> SAML.UserRef -> Spar () validateEmailIfExists uid = \case - (SAML.UserRef _ (view SAML.nameID -> UNameIDEmail email)) -> doValidate email + (SAML.UserRef _ (view SAML.nameID -> UNameIDEmail email)) -> doValidate (CI.original email) _ -> pure () where - doValidate :: SAML.Email -> Spar () + doValidate :: SAMLEmail.Email -> Spar () doValidate email = do enabled <- do tid <- Intra.getBrigUserTeam Intra.NoPendingInvitations uid @@ -288,7 +301,13 @@ bindUser buid userref = do oldStatus <- do let err :: Spar a err = throwSpar . SparBindFromWrongOrNoTeam . cs . show $ buid - teamid :: TeamId <- (^. idpExtraInfo . wiTeam) <$> getIdPConfigByIssuer (userref ^. uidTenant) + teamid :: TeamId <- + wrapMonadClient (Data.getIdPConfigByIssuerAllowOld (userref ^. uidTenant) Nothing) >>= \case + Data.GetIdPFound idp -> pure $ idp ^. idpExtraInfo . wiTeam + Data.GetIdPNotFound -> err + Data.GetIdPDanglingId _ -> err -- database inconsistency + Data.GetIdPNonUnique is -> throwSpar $ SparUserRefInMultipleTeams (cs $ show (buid, is)) + Data.GetIdPWrongTeam _ -> err -- impossible acc <- Intra.getBrigUserAccount Intra.WithPendingInvitations buid >>= maybe err pure teamid' :: TeamId <- userTeam (accountUser acc) & maybe err pure unless (teamid' == teamid) err @@ -342,21 +361,24 @@ instance Intra.MonadSparToGalley Spar where -- signed in-response-to info in the assertions matches the unsigned in-response-to field in the -- 'SAML.Response', and fills in the response id in the header if missing, we can just go for the -- latter. -verdictHandler :: HasCallStack => Maybe BindCookie -> SAML.AuthnResponse -> SAML.AccessVerdict -> Spar SAML.ResponseVerdict -verdictHandler cky aresp verdict = do +verdictHandler :: HasCallStack => Maybe BindCookie -> Maybe TeamId -> SAML.AuthnResponse -> SAML.AccessVerdict -> Spar SAML.ResponseVerdict +verdictHandler cky mbteam aresp verdict = do -- [3/4.1.4.2] -- [...] If the containing message is in response to an , then -- the InResponseTo attribute MUST match the request's ID. + SAML.logger SAML.Debug $ "entering verdictHandler: " <> show (fromBindCookie <$> cky, aresp, verdict) reqid <- either (throwSpar . SparNoRequestRefInResponse . cs) pure $ SAML.rspInResponseTo aresp format :: Maybe VerdictFormat <- wrapMonadClient $ Data.getVerdictFormat reqid - case format of + resp <- case format of Just (VerdictFormatWeb) -> - verdictHandlerResult cky verdict >>= verdictHandlerWeb + verdictHandlerResult cky mbteam verdict >>= verdictHandlerWeb Just (VerdictFormatMobile granted denied) -> - verdictHandlerResult cky verdict >>= verdictHandlerMobile granted denied - Nothing -> throwSpar SparNoSuchRequest - --- (this shouldn't happen too often, see 'storeVerdictFormat') + verdictHandlerResult cky mbteam verdict >>= verdictHandlerMobile granted denied + Nothing -> + -- (this shouldn't happen too often, see 'storeVerdictFormat') + throwSpar SparNoSuchRequest + SAML.logger SAML.Debug $ "leaving verdictHandler: " <> show resp + pure resp data VerdictHandlerResult = VerifyHandlerGranted {_vhrCookie :: SetCookie, _vhrUserId :: UserId} @@ -364,10 +386,11 @@ data VerdictHandlerResult | VerifyHandlerError {_vhrLabel :: ST, _vhrMessage :: ST} deriving (Eq, Show) -verdictHandlerResult :: HasCallStack => Maybe BindCookie -> SAML.AccessVerdict -> Spar VerdictHandlerResult -verdictHandlerResult bindCky verdict = do - result <- catchVerdictErrors $ verdictHandlerResultCore bindCky verdict - SAML.logger SAML.Debug (show result) +verdictHandlerResult :: HasCallStack => Maybe BindCookie -> Maybe TeamId -> SAML.AccessVerdict -> Spar VerdictHandlerResult +verdictHandlerResult bindCky mbteam verdict = do + SAML.logger SAML.Debug $ "entering verdictHandlerResult: " <> show (fromBindCookie <$> bindCky) + result <- catchVerdictErrors $ verdictHandlerResultCore bindCky mbteam verdict + SAML.logger SAML.Debug $ "leaving verdictHandlerResult" <> show result pure result catchVerdictErrors :: Spar VerdictHandlerResult -> Spar VerdictHandlerResult @@ -384,9 +407,9 @@ catchVerdictErrors = (`catchError` hndlr) -- | If a user attempts to login presenting a new IdP issuer, but there is no entry in -- @"spar.user"@ for her: lookup @"old_issuers"@ from @"spar.idp"@ for the new IdP, and -- traverse the old IdPs in search for the old entry. Return that old entry. -findUserWithOldIssuer :: SAML.UserRef -> Spar (Maybe (SAML.UserRef, UserId)) -findUserWithOldIssuer (SAML.UserRef issuer subject) = do - idp <- getIdPConfigByIssuer issuer +findUserWithOldIssuer :: Maybe TeamId -> SAML.UserRef -> Spar (Maybe (SAML.UserRef, UserId)) +findUserWithOldIssuer mbteam (SAML.UserRef issuer subject) = do + idp <- getIdPConfigByIssuerOptionalSPId issuer mbteam let tryFind :: Maybe (SAML.UserRef, UserId) -> Issuer -> Spar (Maybe (SAML.UserRef, UserId)) tryFind found@(Just _) _ = pure found tryFind Nothing oldIssuer = (uref,) <$$> getUserByUref uref @@ -402,8 +425,8 @@ moveUserToNewIssuer oldUserRef newUserRef uid = do Intra.setBrigUserVeid uid (UrefOnly newUserRef) wrapMonadClient $ Data.deleteSAMLUser uid oldUserRef -verdictHandlerResultCore :: HasCallStack => Maybe BindCookie -> SAML.AccessVerdict -> Spar VerdictHandlerResult -verdictHandlerResultCore bindCky = \case +verdictHandlerResultCore :: HasCallStack => Maybe BindCookie -> Maybe TeamId -> SAML.AccessVerdict -> Spar VerdictHandlerResult +verdictHandlerResultCore bindCky mbteam = \case SAML.AccessDenied reasons -> do pure $ VerifyHandlerDenied reasons SAML.AccessGranted userref -> do @@ -416,12 +439,12 @@ verdictHandlerResultCore bindCky = \case viaSparCassandraOldIssuer <- if isJust viaSparCassandra then pure Nothing - else findUserWithOldIssuer userref + else findUserWithOldIssuer mbteam userref case (viaBindCookie, viaSparCassandra, viaSparCassandraOldIssuer) of -- This is the first SSO authentication, so we auto-create a user. We know the user -- has not been created via SCIM because then we would've ended up in the - -- "reauthentication" branch, so we pass 'ManagedByWire'. - (Nothing, Nothing, Nothing) -> autoprovisionSamlUser userref ManagedByWire + -- "reauthentication" branch. + (Nothing, Nothing, Nothing) -> autoprovisionSamlUser mbteam userref -- If the user is only found under an old (previous) issuer, move it here. (Nothing, Nothing, Just (oldUserRef, uid)) -> moveUserToNewIssuer oldUserRef userref uid >> pure uid -- SSO re-authentication (the most common case). diff --git a/services/spar/src/Spar/Data.hs b/services/spar/src/Spar/Data.hs index a84d0b132f9..bbe5c2ca8cb 100644 --- a/services/spar/src/Spar/Data.hs +++ b/services/spar/src/Spar/Data.hs @@ -56,9 +56,12 @@ module Spar.Data Replacing (..), setReplacedBy, clearReplacedBy, + GetIdPResult (..), getIdPConfig, getIdPConfigByIssuer, + getIdPConfigByIssuerAllowOld, getIdPIdByIssuer, + getIdPIdByIssuerAllowOld, getIdPConfigsByTeam, deleteIdPConfig, deleteTeam, @@ -94,6 +97,7 @@ import Control.Arrow (Arrow ((&&&))) import Control.Lens import Control.Monad.Except import Data.CaseInsensitive (foldCase) +import qualified Data.CaseInsensitive as CI import Data.Id import Data.Json.Util (UTCTimeMillis, toUTCTimeMillis) import qualified Data.List.NonEmpty as NL @@ -104,8 +108,8 @@ import GHC.TypeLits (KnownSymbol) import Imports import SAML2.Util (renderURI) import qualified SAML2.WebSSO as SAML +import qualified SAML2.WebSSO.Types.Email as SAMLEmail import Spar.Data.Instances (VerdictFormatCon, VerdictFormatRow, fromVerdictFormat, toVerdictFormat) -import qualified Text.Email.Parser as Email import Text.RawString.QQ import URI.ByteString import qualified Web.Cookie as Cky @@ -119,7 +123,7 @@ import qualified Prelude -- | A lower bound: @schemaVersion <= whatWeFoundOnCassandra@, not @==@. schemaVersion :: Int32 -schemaVersion = 14 +schemaVersion = 15 ---------------------------------------------------------------------- -- helpers @@ -283,7 +287,7 @@ normalizeUnqualifiedNameId = NormalizedUNameID . foldCase . nameIdTxt where nameIdTxt :: SAML.UnqualifiedNameID -> ST nameIdTxt (SAML.UNameIDUnspecified txt) = SAML.unsafeFromXmlText txt - nameIdTxt (SAML.UNameIDEmail (SAML.Email txt)) = cs $ Email.toByteString txt + nameIdTxt (SAML.UNameIDEmail email) = SAMLEmail.render $ CI.original email nameIdTxt (SAML.UNameIDX509 txt) = SAML.unsafeFromXmlText txt nameIdTxt (SAML.UNameIDWindows txt) = SAML.unsafeFromXmlText txt nameIdTxt (SAML.UNameIDKerberos txt) = SAML.unsafeFromXmlText txt @@ -321,6 +325,11 @@ getSAMLSomeUsersByIssuer issuer = sel :: PrepQuery R (Identity SAML.Issuer) (SAML.NameID, UserId) sel = "SELECT sso_id, uid FROM user_v2 WHERE issuer = ? LIMIT 2000" +-- | Lookup a brig 'UserId' by IdP issuer and NameID. +-- +-- NB: It is not allowed for two distinct wire users from two different teams to have the same +-- 'UserRef'. RATIONALE: this allows us to implement 'getSAMLUser' without adding 'TeamId' to +-- 'UserRef' (which in turn would break the (admittedly leaky) abstarctions of saml2-web-sso). getSAMLUser :: (HasCallStack, MonadClient m) => SAML.UserRef -> m (Maybe UserId) getSAMLUser uref = do mbUid <- getSAMLUserNew uref @@ -408,7 +417,7 @@ lookupBindCookie (cs . fromBindCookie -> ckyval :: ST) = ---------------------------------------------------------------------- -- idp -type IdPConfigRow = (SAML.IdPId, SAML.Issuer, URI, SignedCertificate, [SignedCertificate], TeamId, [SAML.Issuer], Maybe SAML.IdPId) +type IdPConfigRow = (SAML.IdPId, SAML.Issuer, URI, SignedCertificate, [SignedCertificate], TeamId, Maybe WireIdPAPIVersion, [SAML.Issuer], Maybe SAML.IdPId) -- FUTUREWORK: should be called 'insertIdPConfig' for consistency. -- FUTUREWORK: enforce that wiReplacedby is Nothing, or throw an error. there is no @@ -430,12 +439,14 @@ storeIdPConfig idp = retry x5 . batch $ do NL.tail (idp ^. SAML.idpMetadata . SAML.edCertAuthnResponse), -- (the 'List1' is split up into head and tail to make migration from one-element-only easier.) idp ^. SAML.idpExtraInfo . wiTeam, + idp ^. SAML.idpExtraInfo . wiApiVersion, idp ^. SAML.idpExtraInfo . wiOldIssuers, idp ^. SAML.idpExtraInfo . wiReplacedBy ) addPrepQuery byIssuer ( idp ^. SAML.idpId, + idp ^. SAML.idpExtraInfo . wiTeam, idp ^. SAML.idpMetadata . SAML.edIssuer ) addPrepQuery @@ -445,9 +456,12 @@ storeIdPConfig idp = retry x5 . batch $ do ) where ins :: PrepQuery W IdPConfigRow () - ins = "INSERT INTO idp (idp, issuer, request_uri, public_key, extra_public_keys, team, old_issuers, replaced_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" - byIssuer :: PrepQuery W (SAML.IdPId, SAML.Issuer) () - byIssuer = "INSERT INTO issuer_idp (idp, issuer) VALUES (?, ?)" + ins = "INSERT INTO idp (idp, issuer, request_uri, public_key, extra_public_keys, team, api_version, old_issuers, replaced_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" + + -- FUTUREWORK: migrate `spar.issuer_idp` away, `spar.issuer_idp_v2` is enough. + byIssuer :: PrepQuery W (SAML.IdPId, TeamId, SAML.Issuer) () + byIssuer = "INSERT INTO issuer_idp_v2 (idp, team, issuer) VALUES (?, ?, ?)" + byTeam :: PrepQuery W (SAML.IdPId, TeamId) () byTeam = "INSERT INTO team_idp (idp, team) VALUES (?, ?)" @@ -496,37 +510,121 @@ getIdPConfig idpid = certsTail, -- extras teamId, + apiVersion, oldIssuers, replacedBy ) = do let _edCertAuthnResponse = certsHead NL.:| certsTail _idpMetadata = SAML.IdPMetadata {..} - _idpExtraInfo = WireIdP teamId oldIssuers replacedBy + _idpExtraInfo = WireIdP teamId apiVersion oldIssuers replacedBy pure $ SAML.IdPConfig {..} sel :: PrepQuery R (Identity SAML.IdPId) IdPConfigRow - sel = "SELECT idp, issuer, request_uri, public_key, extra_public_keys, team, old_issuers, replaced_by FROM idp WHERE idp = ?" + sel = "SELECT idp, issuer, request_uri, public_key, extra_public_keys, team, api_version, old_issuers, replaced_by FROM idp WHERE idp = ?" + +data GetIdPResult a + = GetIdPFound a + | GetIdPNotFound + | -- | IdPId has been found, but no IdPConfig matching that Id. (Database + -- inconsistency or race condition.) + GetIdPDanglingId SAML.IdPId + | -- | You were looking for an idp by just providing issuer, not teamid, and `issuer_idp_v2` + -- has more than one entry (for different teams). + GetIdPNonUnique [SAML.IdPId] + | -- | An IdP was found, but it lives in another team than the one you were looking for. + -- This should be handled similarly to NotFound in most cases. + GetIdPWrongTeam SAML.IdPId + deriving (Eq, Show) + +-- | (There are probably category theoretical models for what we're doing here, but it's more +-- straight-forward to just handle the one instance we need.) +mapGetIdPResult :: (HasCallStack, MonadClient m) => GetIdPResult SAML.IdPId -> m (GetIdPResult IdP) +mapGetIdPResult (GetIdPFound i) = getIdPConfig i <&> maybe (GetIdPDanglingId i) GetIdPFound +mapGetIdPResult GetIdPNotFound = pure GetIdPNotFound +mapGetIdPResult (GetIdPDanglingId i) = pure (GetIdPDanglingId i) +mapGetIdPResult (GetIdPNonUnique is) = pure (GetIdPNonUnique is) +mapGetIdPResult (GetIdPWrongTeam i) = pure (GetIdPWrongTeam i) +-- | See 'getIdPIdByIssuer'. getIdPConfigByIssuer :: (HasCallStack, MonadClient m) => SAML.Issuer -> - m (Maybe IdP) -getIdPConfigByIssuer issuer = do - getIdPIdByIssuer issuer >>= \case - Nothing -> pure Nothing - Just idpid -> getIdPConfig idpid + TeamId -> + m (GetIdPResult IdP) +getIdPConfigByIssuer issuer = + getIdPIdByIssuer issuer >=> mapGetIdPResult +-- | See 'getIdPIdByIssuerAllowOld'. +getIdPConfigByIssuerAllowOld :: + (HasCallStack, MonadClient m) => + SAML.Issuer -> + Maybe TeamId -> + m (GetIdPResult IdP) +getIdPConfigByIssuerAllowOld issuer = do + getIdPIdByIssuerAllowOld issuer >=> mapGetIdPResult + +-- | Lookup idp in table `issuer_idp_v2` (using both issuer entityID and teamid); if nothing +-- is found there or if teamid is 'Nothing', lookup under issuer in `issuer_idp`. getIdPIdByIssuer :: (HasCallStack, MonadClient m) => SAML.Issuer -> - m (Maybe SAML.IdPId) -getIdPIdByIssuer issuer = do - retry x1 (query1 sel $ params Quorum (Identity issuer)) <&> \case - Nothing -> Nothing - Just (Identity idpid) -> Just idpid + TeamId -> + m (GetIdPResult SAML.IdPId) +getIdPIdByIssuer issuer = getIdPIdByIssuerAllowOld issuer . Just + +-- | Like 'getIdPIdByIssuer', but do not require a 'TeamId'. If none is provided, see if a +-- single solution can be found without. +getIdPIdByIssuerAllowOld :: + (HasCallStack, MonadClient m) => + SAML.Issuer -> + Maybe TeamId -> + m (GetIdPResult SAML.IdPId) +getIdPIdByIssuerAllowOld issuer mbteam = do + mbv2 <- maybe (pure Nothing) (getIdPIdByIssuerWithTeam issuer) mbteam + mbv1v2 <- maybe (getIdPIdByIssuerWithoutTeam issuer) (pure . GetIdPFound) mbv2 + case (mbv1v2, mbteam) of + (GetIdPFound idpid, Just team) -> do + getIdPConfig idpid >>= \case + Nothing -> do + pure $ GetIdPDanglingId idpid + Just idp -> + pure $ + if idp ^. SAML.idpExtraInfo . wiTeam /= team + then GetIdPWrongTeam idpid + else mbv1v2 + _ -> pure mbv1v2 + +-- | Find 'IdPId' without team. Search both `issuer_idp` and `issuer_idp_v2`; in the latter, +-- make sure the result is unique (no two IdPs for two different teams). +getIdPIdByIssuerWithoutTeam :: + (HasCallStack, MonadClient m) => + SAML.Issuer -> + m (GetIdPResult SAML.IdPId) +getIdPIdByIssuerWithoutTeam issuer = do + (runIdentity <$$> retry x1 (query1 sel $ params Quorum (Identity issuer))) >>= \case + Just idpid -> pure $ GetIdPFound idpid + Nothing -> + (runIdentity <$$> retry x1 (query selv2 $ params Quorum (Identity issuer))) >>= \case + [] -> pure GetIdPNotFound + [idpid] -> pure $ GetIdPFound idpid + idpids@(_ : _ : _) -> pure $ GetIdPNonUnique idpids where sel :: PrepQuery R (Identity SAML.Issuer) (Identity SAML.IdPId) sel = "SELECT idp FROM issuer_idp WHERE issuer = ?" + selv2 :: PrepQuery R (Identity SAML.Issuer) (Identity SAML.IdPId) + selv2 = "SELECT idp FROM issuer_idp_v2 WHERE issuer = ?" + +getIdPIdByIssuerWithTeam :: + (HasCallStack, MonadClient m) => + SAML.Issuer -> + TeamId -> + m (Maybe SAML.IdPId) +getIdPIdByIssuerWithTeam issuer tid = do + runIdentity <$$> retry x1 (query1 sel $ params Quorum (issuer, tid)) + where + sel :: PrepQuery R (SAML.Issuer, TeamId) (Identity SAML.IdPId) + sel = "SELECT idp FROM issuer_idp_v2 WHERE issuer = ? and team = ?" + getIdPConfigsByTeam :: (HasCallStack, MonadClient m) => TeamId -> @@ -550,14 +648,21 @@ deleteIdPConfig idp issuer team = retry x5 . batch $ do addPrepQuery delDefaultIdp (Identity idp) addPrepQuery delIdp (Identity idp) addPrepQuery delIssuerIdp (Identity issuer) + addPrepQuery delIssuerIdpV2 (Identity issuer) addPrepQuery delTeamIdp (team, idp) where delDefaultIdp :: PrepQuery W (Identity SAML.IdPId) () delDefaultIdp = "DELETE FROM default_idp WHERE partition_key_always_default = 'default' AND idp = ?" + delIdp :: PrepQuery W (Identity SAML.IdPId) () delIdp = "DELETE FROM idp WHERE idp = ?" + delIssuerIdp :: PrepQuery W (Identity SAML.Issuer) () delIssuerIdp = "DELETE FROM issuer_idp WHERE issuer = ?" + + delIssuerIdpV2 :: PrepQuery W (Identity SAML.Issuer) () + delIssuerIdpV2 = "DELETE FROM issuer_idp_v2 WHERE issuer = ?" + delTeamIdp :: PrepQuery W (TeamId, SAML.IdPId) () delTeamIdp = "DELETE FROM team_idp WHERE team = ? and idp = ?" diff --git a/services/spar/src/Spar/Error.hs b/services/spar/src/Spar/Error.hs index e9920b9be23..ddbc57321c0 100644 --- a/services/spar/src/Spar/Error.hs +++ b/services/spar/src/Spar/Error.hs @@ -68,7 +68,8 @@ throwSpar :: MonadError SparError m => SparCustomError -> m a throwSpar = throwError . SAML.CustomError data SparCustomError - = SparIdPNotFound + = SparIdPNotFound LT + | SparSamlCredentialsNotFound | SparMissingZUsr | SparNotInTeam | SparNoPermission LT @@ -83,6 +84,7 @@ data SparCustomError | SparBindFromWrongOrNoTeam LT | SparBindFromBadAccountStatus LT | SparBindUserRefTaken + | SparUserRefInMultipleTeams LT | SparBadUserName LT | SparCannotCreateUsersOnReplacedIdP LT | SparCouldNotParseRfcResponse LT LT @@ -92,7 +94,7 @@ data SparCustomError | SparCassandraTTLError TTLError | SparNewIdPBadMetadata LT | SparNewIdPPubkeyMismatch - | SparNewIdPAlreadyInUse + | SparNewIdPAlreadyInUse LT | SparNewIdPWantHttps LT | SparIdPHasBoundUsers | SparIdPIssuerInUse @@ -139,6 +141,7 @@ renderSparError (SAML.CustomError (SparBadInitiateLoginQueryParams label)) = Rig renderSparError (SAML.CustomError (SparBindFromWrongOrNoTeam msg)) = Right $ Wai.mkError status403 "bad-team" ("Forbidden: wrong user team " <> msg) renderSparError (SAML.CustomError (SparBindFromBadAccountStatus msg)) = Right $ Wai.mkError status403 "bad-account-status" ("Forbidden: user has account status " <> msg <> "; only Active, PendingInvitation are supported") renderSparError (SAML.CustomError SparBindUserRefTaken) = Right $ Wai.mkError status403 "subject-id-taken" "Forbidden: SubjectID is used by another wire user. If you have an old user bound to this IdP, unbind or delete that user." +renderSparError (SAML.CustomError (SparUserRefInMultipleTeams msg)) = Right $ Wai.mkError status403 "bad-team" ("Forbidden: multiple teams for same UserRef " <> msg) renderSparError (SAML.CustomError (SparBadUserName msg)) = Right $ Wai.mkError status400 "bad-username" ("Bad UserName in SAML response, except len [1, 128]: " <> msg) renderSparError (SAML.CustomError (SparCannotCreateUsersOnReplacedIdP replacingIdPId)) = Right $ Wai.mkError status400 "cannont-provision-on-replaced-idp" ("This IdP has been replaced, users can only be auto-provisioned on the replacing IdP " <> replacingIdPId) -- RFC-specific errors @@ -157,7 +160,9 @@ renderSparError SAML.BadSamlResponseIssuerMissing = Right $ Wai.mkError status40 renderSparError SAML.BadSamlResponseNoAssertions = Right $ Wai.mkError status400 "bad-response-saml" ("Bad response: no assertions in AuthnResponse") renderSparError SAML.BadSamlResponseAssertionWithoutID = Right $ Wai.mkError status400 "bad-response-saml" ("Bad response: assertion without ID") renderSparError (SAML.BadSamlResponseInvalidSignature msg) = Right $ Wai.mkError status400 "bad-response-signature" (cs msg) -renderSparError (SAML.CustomError SparIdPNotFound) = Right $ Wai.mkError status404 "not-found" "Could not find IdP." +renderSparError (SAML.CustomError (SparIdPNotFound "")) = Right $ Wai.mkError status404 "not-found" "Could not find IdP." +renderSparError (SAML.CustomError (SparIdPNotFound msg)) = Right $ Wai.mkError status404 "not-found" ("Could not find IdP: " <> msg) +renderSparError (SAML.CustomError SparSamlCredentialsNotFound) = Right $ Wai.mkError status404 "not-found" "Could not find SAML credentials, and auto-provisioning is disabled." renderSparError (SAML.CustomError SparMissingZUsr) = Right $ Wai.mkError status400 "client-error" "[header] 'Z-User' required" renderSparError (SAML.CustomError SparNotInTeam) = Right $ Wai.mkError status403 "no-team-member" "Requesting user is not a team member or not a member of this team." renderSparError (SAML.CustomError (SparNoPermission perm)) = Right $ Wai.mkError status403 "insufficient-permissions" ("You need permission " <> cs perm <> ".") @@ -170,7 +175,7 @@ renderSparError (SAML.InvalidCert msg) = Right $ Wai.mkError status500 "invalid- -- Errors related to IdP creation renderSparError (SAML.CustomError (SparNewIdPBadMetadata msg)) = Right $ Wai.mkError status400 "invalid-metadata" msg renderSparError (SAML.CustomError SparNewIdPPubkeyMismatch) = Right $ Wai.mkError status400 "key-mismatch" "public keys in body, metadata do not match" -renderSparError (SAML.CustomError SparNewIdPAlreadyInUse) = Right $ Wai.mkError status400 "idp-already-in-use" "an idp issuer can only be used within one team" +renderSparError (SAML.CustomError (SparNewIdPAlreadyInUse msg)) = Right $ Wai.mkError status400 "idp-already-in-use" msg renderSparError (SAML.CustomError (SparNewIdPWantHttps msg)) = Right $ Wai.mkError status400 "idp-must-be-https" ("an idp request uri must be https, not http or other: " <> msg) renderSparError (SAML.CustomError SparIdPHasBoundUsers) = Right $ Wai.mkError status412 "idp-has-bound-users" "an idp can only be deleted if it is empty" renderSparError (SAML.CustomError SparIdPIssuerInUse) = Right $ Wai.mkError status400 "idp-issuer-in-use" "The issuer of your IdP is already in use. Remove the entry in the team that uses it, or construct a new IdP issuer." diff --git a/services/spar/src/Spar/Intra/Brig.hs b/services/spar/src/Spar/Intra/Brig.hs index 13e25bbf997..751911f3fdd 100644 --- a/services/spar/src/Spar/Intra/Brig.hs +++ b/services/spar/src/Spar/Intra/Brig.hs @@ -67,6 +67,7 @@ import Brig.Types.User.Auth (SsoLogin (..)) import Control.Lens import Control.Monad.Except import Data.ByteString.Conversion +import qualified Data.CaseInsensitive as CI import Data.Handle (Handle (Handle, fromHandle)) import Data.Id (Id (Id), TeamId, UserId) import Data.Misc (PlainTextPassword) @@ -76,10 +77,10 @@ import Imports import Network.HTTP.Types.Method import qualified Network.Wai.Utilities.Error as Wai import qualified SAML2.WebSSO as SAML +import qualified SAML2.WebSSO.Types.Email as SAMLEmail import Spar.Error import Spar.Intra.Galley as Galley (MonadSparToGalley, assertHasPermission) import qualified System.Logger.Class as Log -import qualified Text.Email.Parser import Web.Cookie import Wire.API.User import Wire.API.User.RichInfo as RichInfo @@ -111,11 +112,11 @@ veidFromUserSSOId = \case (parseEmail email) urefToExternalId :: SAML.UserRef -> Maybe Text -urefToExternalId = SAML.shortShowNameID . view SAML.uidSubject +urefToExternalId = fmap CI.original . SAML.shortShowNameID . view SAML.uidSubject urefToEmail :: SAML.UserRef -> Maybe Email urefToEmail uref = case uref ^. SAML.uidSubject . SAML.nameID of - SAML.UNameIDEmail email -> Just $ emailFromSAML email + SAML.UNameIDEmail email -> Just . emailFromSAML . CI.original $ email _ -> Nothing -- | If the brig user has a 'UserSSOId', transform that into a 'ValidExternalId' (this is a @@ -140,7 +141,7 @@ mkUserName :: Maybe Text -> ValidExternalId -> Either String Name mkUserName (Just n) = const $ mkName n mkUserName Nothing = runValidExternalId - (\uref -> mkName (SAML.unsafeShowNameID $ uref ^. SAML.uidSubject)) + (\uref -> mkName (CI.original . SAML.unsafeShowNameID $ uref ^. SAML.uidSubject)) (\email -> mkName (fromEmail email)) renderValidExternalId :: ValidExternalId -> Maybe Text @@ -157,18 +158,11 @@ respToCookie resp = do unless (statusCode resp == 200) crash maybe crash (pure . parseSetCookie) $ getHeader "Set-Cookie" resp -emailFromSAML :: HasCallStack => SAML.Email -> Email -emailFromSAML = - fromJust . parseEmail . cs - . Text.Email.Parser.toByteString - . SAML.fromEmail +emailFromSAML :: HasCallStack => SAMLEmail.Email -> Email +emailFromSAML = fromJust . parseEmail . SAMLEmail.render -emailToSAML :: HasCallStack => Email -> SAML.Email -emailToSAML brigEmail = - SAML.Email $ - Text.Email.Parser.unsafeEmailAddress - (cs $ emailLocal brigEmail) - (cs $ emailDomain brigEmail) +emailToSAML :: HasCallStack => Email -> SAMLEmail.Email +emailToSAML = CI.original . fromRight (error "emailToSAML") . SAMLEmail.validate . toByteString -- | FUTUREWORK(fisx): if saml2-web-sso exported the 'NameID' constructor, we could make this -- function total without all that praying and hoping. @@ -177,7 +171,7 @@ emailToSAMLNameID = fromRight (error "impossible") . SAML.emailNameID . fromEmai emailFromSAMLNameID :: HasCallStack => SAML.NameID -> Maybe Email emailFromSAMLNameID nid = case nid ^. SAML.nameID of - SAML.UNameIDEmail email -> Just $ emailFromSAML email + SAML.UNameIDEmail email -> Just . emailFromSAML . CI.original $ email _ -> Nothing ---------------------------------------------------------------------- diff --git a/services/spar/src/Spar/Options.hs b/services/spar/src/Spar/Options.hs index 27bfdff16b9..55d040520d6 100644 --- a/services/spar/src/Spar/Options.hs +++ b/services/spar/src/Spar/Options.hs @@ -53,7 +53,10 @@ getOpts = do deriveOpts :: OptsRaw -> IO Opts deriveOpts raw = do derived <- do - let respuri = runWithConfig raw sparResponseURI + let respuri = + -- respuri is only needed for 'derivedOptsBindCookiePath'; we want the prefix of the + -- V2 path that includes the team id. + runWithConfig raw (sparResponseURI Nothing) derivedOptsBindCookiePath = URI.uriPath respuri -- We could also make this selectable in the config file, but it seems easier to derive it from -- the SAML base uri. diff --git a/services/spar/test-integration/Spec.hs b/services/spar/test-integration/Spec.hs index 32c0b1bf92a..f74c9dc513e 100644 --- a/services/spar/test-integration/Spec.hs +++ b/services/spar/test-integration/Spec.hs @@ -29,7 +29,7 @@ -- the solution: https://github.com/hspec/hspec/pull/397. module Main where -import Control.Lens ((^.)) +import Control.Lens ((.~), (^.)) import Data.String.Conversions import Data.Text (pack) import Imports @@ -53,10 +53,14 @@ import Wire.API.User.Scim main :: IO () main = do (wireArgs, hspecArgs) <- partitionArgs <$> getArgs - env <- withArgs wireArgs mkEnvFromOptions + let env = withArgs wireArgs mkEnvFromOptions withArgs hspecArgs . hspec $ do - beforeAll (pure env) . afterAll destroyEnv $ mkspec - mkspec' env + for_ [minBound ..] $ \idpApiVersion -> do + describe (show idpApiVersion) . beforeAll (env <&> teWireIdPAPIVersion .~ idpApiVersion) . afterAll destroyEnv $ do + mkspecMisc + mkspecSaml + mkspecScim + mkspecHscimAcceptance env destroyEnv partitionArgs :: [String] -> ([String], [String]) partitionArgs = go [] [] @@ -66,23 +70,30 @@ partitionArgs = go [] [] go wireArgs hspecArgs (x : xs) = go wireArgs (hspecArgs <> [x]) xs go wireArgs hspecArgs [] = (wireArgs, hspecArgs) -mkspec :: SpecWith TestEnv -mkspec = do +mkspecMisc :: SpecWith TestEnv +mkspecMisc = do describe "Logging" Test.LoggingSpec.spec describe "Metrics" Test.MetricsSpec.spec + +mkspecSaml :: SpecWith TestEnv +mkspecSaml = do describe "Spar.API" Test.Spar.APISpec.spec describe "Spar.App" Test.Spar.AppSpec.spec describe "Spar.Data" Test.Spar.DataSpec.spec describe "Spar.Intra.Brig" Test.Spar.Intra.BrigSpec.spec + +mkspecScim :: SpecWith TestEnv +mkspecScim = do describe "Spar.Scim.Auth" Test.Spar.Scim.AuthSpec.spec describe "Spar.Scim.User" Test.Spar.Scim.UserSpec.spec -mkspec' :: TestEnv -> Spec -mkspec' env = do +mkspecHscimAcceptance :: IO TestEnv -> (TestEnv -> IO ()) -> Spec +mkspecHscimAcceptance mkenv _destroyenv = do describe "hscim acceptance tests" $ microsoftAzure @SparTag AcceptanceConfig {..} where scimAppAndConfig = do + env <- mkenv (app, _) <- mkApp (env ^. teOpts) scimAuthToken <- toHeader . fst <$> registerIdPAndScimToken `runReaderT` env let queryConfig = AcceptanceQueryConfig {..} diff --git a/services/spar/test-integration/Test/Spar/APISpec.hs b/services/spar/test-integration/Test/Spar/APISpec.hs index 0aef29526a7..e932ffa42d5 100644 --- a/services/spar/test-integration/Test/Spar/APISpec.hs +++ b/services/spar/test-integration/Test/Spar/APISpec.hs @@ -23,6 +23,7 @@ module Test.Spar.APISpec where import Bilge +import Brig.Types.Intra (AccountStatus (Deleted)) import Brig.Types.User import Cassandra hiding (Value) import Control.Lens hiding ((.=)) @@ -54,6 +55,7 @@ import SAML2.WebSSO edCertAuthnResponse, edIssuer, edRequestURI, + fromIssuer, getUserRef, idPIdToST, idpExtraInfo, @@ -61,6 +63,7 @@ import SAML2.WebSSO idpMetadata, mkNameID, parseFromDocument, + rqIssuer, (-/), ) import qualified SAML2.WebSSO as SAML @@ -70,6 +73,7 @@ import SAML2.WebSSO.Test.Util import qualified Spar.Data as Data import qualified Spar.Intra.Brig as Intra import Text.XML.DSig (SignPrivCreds, mkSignCredsWithCert) +import qualified URI.ByteString as URI import URI.ByteString.QQ (uri) import Util.Core import qualified Util.Scim as ScimT @@ -79,6 +83,7 @@ import qualified Web.Scim.Schema.User as Scim import Wire.API.Cookie import Wire.API.Routes.Public.Spar import Wire.API.User.IdentityProvider +import qualified Wire.API.User.Saml as WireAPI (saml) import Wire.API.User.Scim spec :: SpecWith TestEnv @@ -122,7 +127,7 @@ specMisc = do pure $ nonfresh & edIssuer .~ issuer env <- ask uid <- fst <$> call (createUserWithTeam (env ^. teBrig) (env ^. teGalley)) - resp <- call $ callIdpCreate' (env ^. teSpar) (Just uid) somemeta + resp <- call $ callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just uid) somemeta liftIO $ statusCode resp `shouldBe` if isHttps then 201 else 400 it "does not trigger on https urls" $ check True it "does trigger on http urls" $ check False @@ -130,17 +135,25 @@ specMisc = do specMetadata :: SpecWith TestEnv specMetadata = do describe "metadata" $ do - it "metadata" $ do - env <- ask - get ((env ^. teSpar) . path "/sso/metadata" . expect2xx) - `shouldRespondWith` ( \(responseBody -> Just (cs -> bdy)) -> - all - (`isInfixOf` bdy) - [ "md:SPSSODescriptor", - "validUntil", - "WantAssertionsSigned=\"true\"" - ] - ) + let mkit :: String -> String -> SpecWith TestEnv + mkit mdpath finalizepath = do + it ("metadata (" <> mdpath <> ")") $ do + env <- ask + let sparHost = env ^. teOpts . to WireAPI.saml . SAML.cfgSPSsoURI . to (cs . SAML.renderURI) + fragments = + [ "md:SPSSODescriptor", + "validUntil", + "WantAssertionsSigned=\"true\"", + " sparHost + <> finalizepath + <> "\" index=\"0\" isDefault=\"true\"/>" + ] + get ((env ^. teSpar) . path (cs mdpath) . expect2xx) + `shouldRespondWith` (\(responseBody -> Just (cs -> bdy)) -> all (`isInfixOf` bdy) fragments) + + mkit "/sso/metadata" "/finalize-login" + mkit "/sso/metadata/208f5cc4-14cd-11ec-b969-db4fdf0173d5" "/finalize-login/208f5cc4-14cd-11ec-b969-db4fdf0173d5" specInitiateLogin :: SpecWith TestEnv specInitiateLogin = do @@ -186,11 +199,11 @@ specFinalizeLogin = do describe "POST /sso/finalize-login" $ do context "access denied" $ do it "responds with a very peculiar 'forbidden' HTTP response" $ do - (_, _, idp, (_, privcreds)) <- registerTestIdPWithMeta + (_, tid, idp, (_, privcreds)) <- registerTestIdPWithMeta authnreq <- negotiateAuthnRequest idp - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid authnresp <- runSimpleSP $ mkAuthnResponse privcreds idp spmeta authnreq False - sparresp <- submitAuthnResponse authnresp + sparresp <- submitAuthnResponse tid authnresp liftIO $ do -- import Text.XML -- putStrLn $ unlines @@ -224,20 +237,49 @@ specFinalizeLogin = do hasPersistentCookieHeader sparresp `shouldBe` Right () context "happy flow" $ do it "responds with a very peculiar 'allowed' HTTP response" $ do - (_, _, idp, (_, privcreds)) <- registerTestIdPWithMeta - spmeta <- getTestSPMetadata + env <- ask + let apiVersion = env ^. teWireIdPAPIVersion + (_, tid, idp, (_, privcreds)) <- registerTestIdPWithMeta + liftIO $ fromMaybe defWireIdPAPIVersion (idp ^. idpExtraInfo . wiApiVersion) `shouldBe` apiVersion + spmeta <- getTestSPMetadata tid authnreq <- negotiateAuthnRequest idp + let audiencePath = case apiVersion of + WireIdPAPIV1 -> "/sso/finalize-login" + WireIdPAPIV2 -> "/sso/finalize-login/" <> toByteString' tid + liftIO $ authnreq ^. rqIssuer . fromIssuer . to URI.uriPath `shouldBe` audiencePath authnresp <- runSimpleSP $ mkAuthnResponse privcreds idp spmeta authnreq True - loginSuccess =<< submitAuthnResponse authnresp + loginSuccess =<< submitAuthnResponse tid authnresp + context "happy flow (two teams, fixed IdP entityID)" $ do + it "works" $ do + skipIdPAPIVersions + [ WireIdPAPIV1 + -- (In fact, to get this to work was the reason to introduce 'WireIdPAPIVesion'.) + ] + env <- ask + (_, tid1, idp1, (IdPMetadataValue _ metadata, privcreds)) <- registerTestIdPWithMeta + (tid2, idp2) <- liftIO . runHttpT (env ^. teMgr) $ do + (owner2, tid2) <- createUserWithTeam (env ^. teBrig) (env ^. teGalley) + idp2 :: IdP <- callIdpCreate (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner2) metadata + pure (tid2, idp2) + do + spmeta <- getTestSPMetadata tid1 + authnreq <- negotiateAuthnRequest idp1 + authnresp <- runSimpleSP $ mkAuthnResponse privcreds idp1 spmeta authnreq True + loginSuccess =<< submitAuthnResponse tid1 authnresp + do + spmeta <- getTestSPMetadata tid2 + authnreq <- negotiateAuthnRequest idp2 + authnresp <- runSimpleSP $ mkAuthnResponse privcreds idp2 spmeta authnreq True + loginSuccess =<< submitAuthnResponse tid2 authnresp context "user is created once, then deleted in team settings, then can login again." $ do it "responds with 'allowed'" $ do (ownerid, teamid, idp, (_, privcreds)) <- registerTestIdPWithMeta - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata teamid -- first login newUserAuthnResp :: SignedAuthnResponse <- do authnreq <- negotiateAuthnRequest idp authnresp <- runSimpleSP $ mkAuthnResponse privcreds idp spmeta authnreq True - loginSuccess =<< submitAuthnResponse authnresp + loginSuccess =<< submitAuthnResponse teamid authnresp pure $ authnresp let newUserRef@(UserRef _ subj) = either (error . show) (^. userRefL) $ @@ -270,7 +312,7 @@ specFinalizeLogin = do do authnreq <- negotiateAuthnRequest idp authnresp <- runSimpleSP $ mkAuthnResponseWithSubj subj privcreds idp spmeta authnreq True - loginSuccess =<< submitAuthnResponse authnresp + loginSuccess =<< submitAuthnResponse teamid authnresp context "unknown user" $ do it "creates the user" $ do pending @@ -285,9 +327,9 @@ specFinalizeLogin = do pending context "unknown IdP Issuer" $ do it "rejects" $ do - (_, _, idp, (_, privcreds)) <- registerTestIdPWithMeta + (_, teamid, idp, (_, privcreds)) <- registerTestIdPWithMeta authnreq <- negotiateAuthnRequest idp - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata teamid authnresp <- runSimpleSP $ mkAuthnResponse @@ -296,7 +338,7 @@ specFinalizeLogin = do spmeta authnreq True - sparresp <- submitAuthnResponse authnresp + sparresp <- submitAuthnResponse teamid authnresp let shouldContainInBase64 :: String -> String -> Expectation shouldContainInBase64 hay needle = cs hay'' `shouldContain` needle where @@ -314,7 +356,7 @@ specFinalizeLogin = do statusCode sparresp `shouldBe` 404 -- body should contain the error label in the title, the verbatim haskell error, and the request: (cs . fromJust . responseBody $ sparresp) `shouldContain` "wire:sso:error:not-found" - (cs . fromJust . responseBody $ sparresp) `shouldContainInBase64` "CustomError SparIdPNotFound" + (cs . fromJust . responseBody $ sparresp) `shouldContainInBase64` "CustomError (SparIdPNotFound" (cs . fromJust . responseBody $ sparresp) `shouldContainInBase64` "Input {iName = \"SAMLResponse\"" -- TODO(arianvp): Ask Matthias what this even means context "AuthnResponse does not match any request" $ do @@ -327,7 +369,7 @@ specFinalizeLogin = do context "IdP changes response format" $ do it "treats NameId case-insensitively" $ do (_ownerid, tid, idp, (_, privcreds)) <- registerTestIdPWithMeta - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid let loginSuccess :: HasCallStack => ResponseLBS -> TestSpar () loginSuccess sparresp = liftIO $ do @@ -336,7 +378,7 @@ specFinalizeLogin = do let loginWithSubject subj = do authnreq <- negotiateAuthnRequest idp authnresp <- runSimpleSP $ mkAuthnResponseWithSubj subj privcreds idp spmeta authnreq True - loginSuccess =<< submitAuthnResponse authnresp + loginSuccess =<< submitAuthnResponse tid authnresp ssoid <- getSsoidViaAuthResp authnresp ssoToUidSpar tid ssoid @@ -438,20 +480,24 @@ specBindingUsers = describe "binding existing users to sso identities" $ do liftIO $ ('s', ssoidViaSelf) `shouldBe` ('s', ssoidViaAuthResp) Just uidViaSpar <- ssoToUidSpar tid ssoidViaAuthResp liftIO $ ('u', uidViaSpar) `shouldBe` ('u', uid) + checkGrantingAuthnResp' :: HasCallStack => ResponseLBS -> TestSpar () checkGrantingAuthnResp' sparresp = do liftIO $ do (cs @_ @String . fromJust . responseBody $ sparresp) `shouldContain` "wire:sso:success" hasPersistentCookieHeader sparresp `shouldBe` Right () + checkDenyingAuthnResp :: HasCallStack => ResponseLBS -> ST -> TestSpar () checkDenyingAuthnResp sparresp errorlabel = do liftIO $ do (cs @_ @String . fromJust . responseBody $ sparresp) `shouldContain` ("wire:sso:error:" <> cs errorlabel <> "") hasPersistentCookieHeader sparresp `shouldBe` Left "no set-cookie header" + initialBind :: HasCallStack => UserId -> IdP -> SignPrivCreds -> TestSpar (NameID, SignedAuthnResponse, ResponseLBS) initialBind = initialBind' Just + initialBind' :: HasCallStack => (Cky.Cookies -> Maybe Cky.Cookies) -> @@ -463,8 +509,10 @@ specBindingUsers = describe "binding existing users to sso identities" $ do subj <- nextSubject (authnResp, sparAuthnResp) <- reBindSame' tweakcookies uid idp privcreds subj pure (subj, authnResp, sparAuthnResp) + reBindSame :: HasCallStack => UserId -> IdP -> SignPrivCreds -> NameID -> TestSpar (SignedAuthnResponse, ResponseLBS) reBindSame = reBindSame' Just + reBindSame' :: HasCallStack => (Cky.Cookies -> Maybe Cky.Cookies) -> @@ -476,19 +524,21 @@ specBindingUsers = describe "binding existing users to sso identities" $ do reBindSame' tweakcookies uid idp privCreds subj = do (authnReq, Just (SetBindCookie (SimpleSetCookie bindCky))) <- do negotiateAuthnRequest' DoInitiateBind idp (header "Z-User" $ toByteString' uid) - spmeta <- getTestSPMetadata + let tid = idp ^. idpExtraInfo . wiTeam + spmeta <- getTestSPMetadata tid authnResp <- runSimpleSP $ mkAuthnResponseWithSubj subj privCreds idp spmeta authnReq True let cookiehdr = case tweakcookies [(Cky.setCookieName bindCky, Cky.setCookieValue bindCky)] of Just val -> header "Cookie" . cs . LB.toLazyByteString . Cky.renderCookies $ val Nothing -> id sparAuthnResp :: ResponseLBS <- - submitAuthnResponse' cookiehdr authnResp + submitAuthnResponse' cookiehdr tid authnResp pure (authnResp, sparAuthnResp) + reBindDifferent :: HasCallStack => UserId -> TestSpar (SignedAuthnResponse, ResponseLBS) reBindDifferent uid = do env <- ask (SampleIdP metadata privcreds _ _) <- makeSampleIdPMetadata - idp <- call $ callIdpCreate (env ^. teSpar) (Just uid) metadata + idp <- call $ callIdpCreate (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just uid) metadata (_, authnResp, sparAuthnResp) <- initialBind uid idp privcreds pure (authnResp, sparAuthnResp) context "initial bind" $ do @@ -593,10 +643,10 @@ testGetPutDelete whichone = do -- the team, which is the original owner.) mkSsoOwner :: UserId -> TeamId -> IdP -> SignPrivCreds -> TestSpar UserId mkSsoOwner firstOwner tid idp privcreds = do - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid authnreq <- negotiateAuthnRequest idp authnresp <- runSimpleSP $ mkAuthnResponse privcreds idp spmeta authnreq True - loginresp <- submitAuthnResponse authnresp + loginresp <- submitAuthnResponse tid authnresp liftIO $ responseStatus loginresp `shouldBe` status200 [ssoOwner] <- filter (/= firstOwner) <$> getTeamMembers firstOwner tid promoteTeamMember firstOwner tid ssoOwner @@ -747,7 +797,7 @@ specCRUDIdentityProvider = do env <- ask (owner1, _, (^. idpId) -> idpid1, (IdPMetadataValue _ idpmeta1, _)) <- registerTestIdPWithMeta (SampleIdP idpmeta2 _ _ _) <- makeSampleIdPMetadata - _ <- call $ callIdpCreate (env ^. teSpar) (Just owner1) idpmeta2 + _ <- call $ callIdpCreate (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner1) idpmeta2 let idpmeta1' = idpmeta1 & edIssuer .~ (idpmeta2 ^. edIssuer) callIdpUpdate' (env ^. teSpar) (Just owner1) idpid1 (IdPMetadataValue (cs $ SAML.encode idpmeta1') undefined) `shouldRespondWith` checkErrHspec 400 "idp-issuer-in-use" @@ -897,12 +947,13 @@ specCRUDIdentityProvider = do check :: HasCallStack => Bool -> Int -> String -> Either String () -> TestSpar () check useNewPrivKey expectedStatus expectedHtmlTitle expectedCookie = do (idp, oldPrivKey, newPrivKey) <- initidp + let tid = idp ^. idpExtraInfo . wiTeam env <- ask (_, authnreq) <- call $ callAuthnReq (env ^. teSpar) (idp ^. idpId) - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid let privkey = if useNewPrivKey then newPrivKey else oldPrivKey idpresp <- runSimpleSP $ mkAuthnResponse privkey idp spmeta authnreq True - sparresp <- submitAuthnResponse idpresp + sparresp <- submitAuthnResponse tid idpresp liftIO $ do statusCode sparresp `shouldBe` expectedStatus let bdy = maybe "" (cs @LBS @String) (responseBody sparresp) @@ -926,7 +977,7 @@ specCRUDIdentityProvider = do env <- ask (uid, _tid) <- call $ createUserWithTeamDisableSSO (env ^. teBrig) (env ^. teGalley) (SampleIdP metadata _ _ _) <- makeSampleIdPMetadata - callIdpCreate' (env ^. teSpar) (Just uid) metadata + callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just uid) metadata `shouldRespondWith` checkErrHspec 403 "sso-disabled" context "bad xml" $ do it "responds with a 'client error'" $ do @@ -937,14 +988,14 @@ specCRUDIdentityProvider = do it "responds with 'client error'" $ do env <- ask (SampleIdP idpmeta _ _ _) <- makeSampleIdPMetadata - callIdpCreate' (env ^. teSpar) Nothing idpmeta + callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) Nothing idpmeta `shouldRespondWith` checkErrHspec 400 "client-error" context "zuser has no team" $ do it "responds with 'no team member'" $ do env <- ask (uid, _) <- call $ createRandomPhoneUser (env ^. teBrig) (SampleIdP idpmeta _ _ _) <- makeSampleIdPMetadata - callIdpCreate' (env ^. teSpar) (Just uid) idpmeta + callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just uid) idpmeta `shouldRespondWith` checkErrHspec 403 "no-team-member" context "zuser is a team member, but not a team owner" $ do it "responds with 'insufficient-permissions' and a helpful message" $ do @@ -953,7 +1004,7 @@ specCRUDIdentityProvider = do newmember <- let perms = Galley.noPermissions in call $ createTeamMember (env ^. teBrig) (env ^. teGalley) tid perms - callIdpCreate' (env ^. teSpar) (Just newmember) (idp ^. idpMetadata) + callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just newmember) (idp ^. idpMetadata) `shouldRespondWith` checkErrHspec 403 "insufficient-permissions" context "idp (identified by issuer) is in use by other team" $ do it "rejects" $ do @@ -961,21 +1012,31 @@ specCRUDIdentityProvider = do (SampleIdP newMetadata _ _ _) <- makeSampleIdPMetadata (uid1, _) <- call $ createUserWithTeam (env ^. teBrig) (env ^. teGalley) (uid2, _) <- call $ createUserWithTeam (env ^. teBrig) (env ^. teGalley) - resp1 <- call $ callIdpCreate' (env ^. teSpar) (Just uid1) newMetadata - resp2 <- call $ callIdpCreate' (env ^. teSpar) (Just uid1) newMetadata - resp3 <- call $ callIdpCreate' (env ^. teSpar) (Just uid2) newMetadata + -- first idp + resp1 <- call $ callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just uid1) newMetadata + -- same idp issuer, same team + resp2 <- call $ callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just uid1) newMetadata + -- same idp issuer, different team + resp3 <- call $ callIdpCreate' (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just uid2) newMetadata liftIO $ do statusCode resp1 `shouldBe` 201 - statusCode resp2 `shouldBe` 400 - responseJsonEither resp2 `shouldBe` Right (TestErrorLabel "idp-already-in-use") - statusCode resp3 `shouldBe` 400 - responseJsonEither resp3 `shouldBe` Right (TestErrorLabel "idp-already-in-use") + do + -- always fail if we're trying same (SP entityID, IdP entityID, team) + statusCode resp2 `shouldBe` 400 + responseJsonEither resp2 `shouldBe` Right (TestErrorLabel "idp-already-in-use") + case env ^. teWireIdPAPIVersion of + -- fail in the old api only if we're trying same (SP entityID, IdP entityID) on different teams + WireIdPAPIV1 -> do + statusCode resp3 `shouldBe` 400 + responseJsonEither resp3 `shouldBe` Right (TestErrorLabel "idp-already-in-use") + WireIdPAPIV2 -> do + statusCode resp3 `shouldBe` 201 context "client is owner with email" $ do it "responds with 2xx; makes IdP available for GET /identity-providers/" $ do env <- ask (owner, _) <- call $ createUserWithTeam (env ^. teBrig) (env ^. teGalley) (SampleIdP metadata _ _ _) <- makeSampleIdPMetadata - idp <- call $ callIdpCreate (env ^. teSpar) (Just owner) metadata + idp <- call $ callIdpCreate (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner) metadata idp' <- call $ callIdpGet (env ^. teSpar) (Just owner) (idp ^. idpId) rawmeta <- call $ callIdpGetRaw (env ^. teSpar) (Just owner) (idp ^. idpId) liftIO $ do @@ -1010,7 +1071,7 @@ specCRUDIdentityProvider = do issuer2 <- makeIssuer idp2 <- let idpmeta2 = idpmeta1 & edIssuer .~ issuer2 - in call $ callIdpCreateReplace (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) + in call $ callIdpCreateReplace (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) idp1' <- call $ callIdpGet (env ^. teSpar) (Just owner1) (idp1 ^. SAML.idpId) idp2' <- call $ callIdpGet (env ^. teSpar) (Just owner1) (idp2 ^. SAML.idpId) liftIO $ do @@ -1040,7 +1101,7 @@ specCRUDIdentityProvider = do issuer2 <- makeIssuer _ <- let idpmeta2 = idpmeta1 & edIssuer .~ issuer2 - in call $ callIdpCreateReplace (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) + in call $ callIdpCreateReplace (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) newuref <- tryLogin privkey1 idp1 userSubject newuid <- getUserIdViaRef' newuref liftIO $ do @@ -1059,7 +1120,7 @@ specCRUDIdentityProvider = do issuer2 <- makeIssuer idp2 <- let idpmeta2 = idpmeta1 & edIssuer .~ issuer2 - in call $ callIdpCreateReplace (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) + in call $ callIdpCreateReplace (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) newuref <- tryLogin privkey2 idp2 userSubject newuid <- getUserIdViaRef' newuref liftIO $ do @@ -1076,7 +1137,7 @@ specCRUDIdentityProvider = do issuer2 <- makeIssuer idp2 <- let idpmeta2 = idpmeta1 & edIssuer .~ issuer2 - in call $ callIdpCreateReplace (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) + in call $ callIdpCreateReplace (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) newuref <- tryLogin privkey2 idp2 userSubject newuid <- getUserIdViaRef' newuref liftIO $ do @@ -1098,7 +1159,7 @@ specDeleteCornerCases = describe "delete corner cases" $ do uref `shouldBe` (SAML.UserRef issuer1 userSubject) idp2 <- let idpmeta2 = idpmeta1 & edIssuer .~ issuer2 - in call $ callIdpCreateReplace (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) + in call $ callIdpCreateReplace (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) call $ callIdpDelete (env ^. teSpar) (pure owner1) (idp2 ^. idpId) uref' <- tryLogin privkey1 idp1 userSubject uid' <- getUserIdViaRef' uref' @@ -1112,7 +1173,7 @@ specDeleteCornerCases = describe "delete corner cases" $ do issuer2 <- makeIssuer idp2 <- let idpmeta2 = idpmeta1 & edIssuer .~ issuer2 - in call $ callIdpCreateReplace (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) + in call $ callIdpCreateReplace (env ^. teWireIdPAPIVersion) (env ^. teSpar) (Just owner1) idpmeta2 (idp1 ^. SAML.idpId) call $ callIdpDelete (env ^. teSpar) (pure owner1) (idp2 ^. idpId) let userSubject = SAML.unspecifiedNameID "bloob" uref <- tryLogin privkey1 idp1 userSubject @@ -1156,14 +1217,17 @@ specDeleteCornerCases = describe "delete corner cases" $ do samlUserShouldSatisfy uref property = do muid <- getUserIdViaRef' uref liftIO $ muid `shouldSatisfy` property + createViaSamlResp :: HasCallStack => IdP -> SignPrivCreds -> SAML.UserRef -> TestSpar ResponseLBS createViaSamlResp idp privCreds (SAML.UserRef _ subj) = do + let tid = idp ^. idpExtraInfo . wiTeam authnReq <- negotiateAuthnRequest idp - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid authnResp <- runSimpleSP $ mkAuthnResponseWithSubj subj privCreds idp spmeta authnReq True - createResp <- submitAuthnResponse authnResp + createResp <- submitAuthnResponse tid authnResp liftIO $ responseStatus createResp `shouldBe` status200 pure createResp + createViaSaml :: HasCallStack => IdP -> SignPrivCreds -> SAML.UserRef -> TestSpar (Maybe UserId) createViaSaml idp privcreds uref = do resp <- createViaSamlResp idp privcreds uref @@ -1171,18 +1235,20 @@ specDeleteCornerCases = describe "delete corner cases" $ do maybe (error "no body") cs (responseBody resp) `shouldContain` "wire:sso:success" getUserIdViaRef' uref + deleteViaBrig :: UserId -> TestSpar () deleteViaBrig uid = do brig <- view teBrig - resp <- (call . delete $ brig . paths ["i", "users", toByteString' uid]) + resp <- call . delete $ brig . paths ["i", "users", toByteString' uid] liftIO $ responseStatus resp `shouldBe` status202 + void $ aFewTimes (runSpar $ Intra.getStatus uid) (== Deleted) specScimAndSAML :: SpecWith TestEnv specScimAndSAML = do it "SCIM and SAML work together and SCIM-created users can login" $ do env <- ask -- create a user via scim - (tok, (_, _, idp, (_, privcreds))) <- ScimT.registerIdPAndScimTokenWithMeta + (tok, (_, tid, idp, (_, privcreds))) <- ScimT.registerIdPAndScimTokenWithMeta (usr, subj) <- ScimT.randomScimUserWithSubject scimStoredUser <- ScimT.createUser tok usr let userid :: UserId = ScimT.scimUserId scimStoredUser @@ -1198,9 +1264,9 @@ specScimAndSAML = do liftIO $ ('r', preview veidUref <$$> (Intra.veidFromUserSSOId <$> userssoid)) `shouldBe` ('r', Just (Right (Just userref))) -- login a user for the first time with the scim-supplied credentials authnreq <- negotiateAuthnRequest idp - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid authnresp :: SignedAuthnResponse <- runSimpleSP $ mkAuthnResponseWithSubj subject privcreds idp spmeta authnreq True - sparresp :: ResponseLBS <- submitAuthnResponse authnresp + sparresp :: ResponseLBS <- submitAuthnResponse tid authnresp -- user should receive a cookie liftIO $ statusCode sparresp `shouldBe` 200 setcky :: SAML.SimpleSetCookie "zuid" <- @@ -1240,7 +1306,7 @@ specScimAndSAML = do mkNameID subj (Just "https://federation.foobar.com/nidp/saml2/metadata") (Just "https://prod-nginz-https.wire.com/sso/finalize-login") Nothing authnreq <- negotiateAuthnRequest idp - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata (idp ^. idpExtraInfo . wiTeam) authnresp :: SignedAuthnResponse <- runSimpleSP $ mkAuthnResponseWithSubj subjectWithQualifier privcreds idp spmeta authnreq True ssoid <- getSsoidViaAuthResp authnresp @@ -1375,7 +1441,7 @@ specSparUserMigration = do env <- ask (_ownerid, tid, idp, (_, privcreds)) <- registerTestIdPWithMeta - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid (issuer, subject) <- do suffix <- cs <$> replicateM 7 (getRandomR ('a', 'z')) @@ -1398,7 +1464,7 @@ specSparUserMigration = do mbUserId <- do authnreq <- negotiateAuthnRequest idp authnresp <- runSimpleSP $ mkAuthnResponseWithSubj subject privcreds idp spmeta authnreq True - sparresp <- submitAuthnResponse authnresp + sparresp <- submitAuthnResponse tid authnresp liftIO $ statusCode sparresp `shouldBe` 200 ssoid <- getSsoidViaAuthResp authnresp ssoToUidSpar tid ssoid diff --git a/services/spar/test-integration/Test/Spar/AppSpec.hs b/services/spar/test-integration/Test/Spar/AppSpec.hs index 4e8b84468c8..a357d2b4091 100644 --- a/services/spar/test-integration/Test/Spar/AppSpec.hs +++ b/services/spar/test-integration/Test/Spar/AppSpec.hs @@ -43,6 +43,7 @@ import URI.ByteString.QQ (uri) import Util import Web.Cookie import Wire.API.User.IdentityProvider (IdP) +import qualified Wire.API.User.IdentityProvider as User spec :: SpecWith TestEnv spec = describe "accessVerdict" $ do @@ -152,7 +153,7 @@ requestAccessVerdict idp isGranted mkAuthnReq = do raw <- mkAuthnReq (idp ^. SAML.idpId) bdy <- maybe (error "authreq") pure $ responseBody raw either (error . show) pure $ Servant.mimeUnrender (Servant.Proxy @SAML.HTML) bdy - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata (idp ^. idpExtraInfo . User.wiTeam) (privKey, _, _) <- DSig.mkSignCredsWithCert Nothing 96 authnresp :: SAML.AuthnResponse <- do case authnreq of @@ -165,7 +166,12 @@ requestAccessVerdict idp isGranted mkAuthnReq = do if isGranted then SAML.AccessGranted uref else SAML.AccessDenied [DeniedNoBearerConfSubj, DeniedNoAuthnStatement] - outcome :: ResponseVerdict <- runSpar $ Spar.verdictHandler Nothing authnresp verdict + outcome :: ResponseVerdict <- do + mbteam <- + asks (^. teWireIdPAPIVersion) <&> \case + User.WireIdPAPIV1 -> Nothing + User.WireIdPAPIV2 -> Just (idp ^. SAML.idpExtraInfo . User.wiTeam) + runSpar $ Spar.verdictHandler Nothing mbteam authnresp verdict let loc :: URI.URI loc = maybe (error "no location") (either error id . SAML.parseURI' . cs) diff --git a/services/spar/test-integration/Test/Spar/DataSpec.hs b/services/spar/test-integration/Test/Spar/DataSpec.hs index bc4d8f418a4..0662956fc69 100644 --- a/services/spar/test-integration/Test/Spar/DataSpec.hs +++ b/services/spar/test-integration/Test/Spar/DataSpec.hs @@ -170,22 +170,24 @@ spec = do it "getIdPConfigByIssuer works" $ do idp <- makeTestIdP () <- runSparCass $ Data.storeIdPConfig idp - midp <- runSparCass $ Data.getIdPConfigByIssuer (idp ^. idpMetadata . edIssuer) - liftIO $ midp `shouldBe` Just idp + midp <- runSparCass $ Data.getIdPConfigByIssuer (idp ^. idpMetadata . edIssuer) (idp ^. SAML.idpExtraInfo . wiTeam) + liftIO $ midp `shouldBe` GetIdPFound idp it "getIdPIdByIssuer works" $ do idp <- makeTestIdP () <- runSparCass $ Data.storeIdPConfig idp - midp <- runSparCass $ Data.getIdPIdByIssuer (idp ^. idpMetadata . edIssuer) - liftIO $ midp `shouldBe` Just (idp ^. idpId) + midp <- runSparCass $ Data.getIdPIdByIssuer (idp ^. idpMetadata . edIssuer) (idp ^. SAML.idpExtraInfo . wiTeam) + liftIO $ midp `shouldBe` GetIdPFound (idp ^. idpId) it "getIdPConfigsByTeam works" $ do + skipIdPAPIVersions [WireIdPAPIV1] teamid <- nextWireId - idp <- makeTestIdP <&> idpExtraInfo .~ (WireIdP teamid [] Nothing) + idp <- makeTestIdP <&> idpExtraInfo .~ (WireIdP teamid Nothing [] Nothing) () <- runSparCass $ Data.storeIdPConfig idp idps <- runSparCass $ Data.getIdPConfigsByTeam teamid liftIO $ idps `shouldBe` [idp] it "deleteIdPConfig works" $ do teamid <- nextWireId - idp <- makeTestIdP <&> idpExtraInfo .~ (WireIdP teamid [] Nothing) + idpApiVersion <- asks (^. teWireIdPAPIVersion) + idp <- makeTestIdP <&> idpExtraInfo .~ (WireIdP teamid (Just idpApiVersion) [] Nothing) () <- runSparCass $ Data.storeIdPConfig idp do midp <- runSparCass $ Data.getIdPConfig (idp ^. idpId) @@ -195,11 +197,11 @@ spec = do midp <- runSparCass $ Data.getIdPConfig (idp ^. idpId) liftIO $ midp `shouldBe` Nothing do - midp <- runSparCass $ Data.getIdPConfigByIssuer (idp ^. idpMetadata . edIssuer) - liftIO $ midp `shouldBe` Nothing + midp <- runSparCass $ Data.getIdPConfigByIssuer (idp ^. idpMetadata . edIssuer) (idp ^. SAML.idpExtraInfo . wiTeam) + liftIO $ midp `shouldBe` GetIdPNotFound do - midp <- runSparCass $ Data.getIdPIdByIssuer (idp ^. idpMetadata . edIssuer) - liftIO $ midp `shouldBe` Nothing + midp <- runSparCass $ Data.getIdPIdByIssuer (idp ^. idpMetadata . edIssuer) (idp ^. SAML.idpExtraInfo . wiTeam) + liftIO $ midp `shouldBe` GetIdPNotFound do idps <- runSparCass $ Data.getIdPConfigsByTeam teamid liftIO $ idps `shouldBe` [] @@ -302,8 +304,8 @@ testDeleteTeam = it "cleans up all the right tables after deletion" $ do -- The config from 'issuer_idp': do let issuer = idp ^. SAML.idpMetadata . SAML.edIssuer - mbIdp <- runSparCass $ Data.getIdPIdByIssuer issuer - liftIO $ mbIdp `shouldBe` Nothing + mbIdp <- runSparCass $ Data.getIdPIdByIssuer issuer (idp ^. SAML.idpExtraInfo . wiTeam) + liftIO $ mbIdp `shouldBe` GetIdPNotFound -- The config from 'team_idp': do idps <- runSparCass $ Data.getIdPConfigsByTeam tid diff --git a/services/spar/test-integration/Test/Spar/Scim/AuthSpec.hs b/services/spar/test-integration/Test/Spar/Scim/AuthSpec.hs index 2e9056cea2a..5be4bc24a2c 100644 --- a/services/spar/test-integration/Test/Spar/Scim/AuthSpec.hs +++ b/services/spar/test-integration/Test/Spar/Scim/AuthSpec.hs @@ -133,9 +133,10 @@ testNumIdPs = do let addSomeIdP :: TestSpar () addSomeIdP = do - spar <- asks (view teSpar) + let spar = env ^. teSpar + apiversion = env ^. teWireIdPAPIVersion SAML.SampleIdP metadata _ _ _ <- SAML.makeSampleIdPMetadata - void $ call $ Util.callIdpCreate spar (Just owner) metadata + void $ call $ Util.callIdpCreate apiversion spar (Just owner) metadata createToken owner (CreateScimToken "eins" (Just defPassword)) >>= deleteToken owner . stiId . createScimTokenResponseInfo diff --git a/services/spar/test-integration/Test/Spar/Scim/UserSpec.hs b/services/spar/test-integration/Test/Spar/Scim/UserSpec.hs index 21865f2be1e..4ade02f3eb9 100644 --- a/services/spar/test-integration/Test/Spar/Scim/UserSpec.hs +++ b/services/spar/test-integration/Test/Spar/Scim/UserSpec.hs @@ -46,6 +46,7 @@ import Data.Aeson.QQ (aesonQQ) import Data.Aeson.Types (fromJSON, toJSON) import qualified Data.Bifunctor as Bifunctor import Data.ByteString.Conversion +import qualified Data.CaseInsensitive as CI import qualified Data.Csv as Csv import Data.Handle (Handle (Handle), fromHandle) import Data.Id (TeamId, UserId, randomId) @@ -77,6 +78,7 @@ import qualified Web.Scim.Schema.User as Scim.User import qualified Wire.API.Team.Export as CsvExport import Wire.API.Team.Invitation (Invitation (..)) import Wire.API.User.IdentityProvider (IdP) +import qualified Wire.API.User.IdentityProvider as User import Wire.API.User.RichInfo import qualified Wire.API.User.Saml as Spar.Types import qualified Wire.API.User.Scim as Spar.Types @@ -260,7 +262,7 @@ testCsvData tid owner uid mbeid mbsaml = do let haveSubject :: Text haveSubject = case mbsaml of - Just (UserSSOId _ subject) -> either (error . show) SAML.unsafeShowNameID $ SAML.decodeElem (cs subject) + Just (UserSSOId _ subject) -> either (error . show) (CI.original . SAML.unsafeShowNameID) $ SAML.decodeElem (cs subject) Just (UserScimExternalId _) -> "" Nothing -> "" ('n', CsvExport.tExportSAMLNamedId export) `shouldBe` ('n', haveSubject) @@ -359,6 +361,11 @@ testCreateUserNoIdP = do let eid = Scim.User.externalId scimUser sml = Nothing in testCsvData tid owner userid eid sml + + -- members table contains an entry + -- (this really shouldn't be tested here, but by the type system!) + members <- getTeamMembers userid tid + liftIO $ members `shouldContain` [userid] where -- cloned from brig's integration tests @@ -431,6 +438,11 @@ testCreateUserWithSamlIdP = do sml = fromJust $ userIdentity >=> ssoIdentity $ brigUser in testCsvData tid owner uid eid (Just sml) + -- members table contains an entry + -- (this really shouldn't be tested here, but by the type system!) + members <- getTeamMembers userid tid + liftIO $ members `shouldContain` [userid] + -- | Test that Wire-specific schemas are added to the SCIM user record, even if the schemas -- were not present in the original record during creation. testSchemaIsAdded :: TestSpar () @@ -670,20 +682,24 @@ testScimCreateVsUserRef = do samlUserShouldSatisfy uref property = do muid <- getUserIdViaRef' uref liftIO $ muid `shouldSatisfy` property + createViaSamlResp :: HasCallStack => IdP -> SAML.SignPrivCreds -> SAML.UserRef -> TestSpar ResponseLBS createViaSamlResp idp privCreds (SAML.UserRef _ subj) = do authnReq <- negotiateAuthnRequest idp - spmeta <- getTestSPMetadata + let tid = idp ^. SAML.idpExtraInfo . User.wiTeam + spmeta <- getTestSPMetadata tid authnResp <- runSimpleSP $ SAML.mkAuthnResponseWithSubj subj privCreds idp spmeta authnReq True - submitAuthnResponse authnResp IdP -> SAML.SignPrivCreds -> SAML.UserRef -> TestSpar () createViaSamlFails idp privCreds uref = do resp <- createViaSamlResp idp privCreds uref liftIO $ do maybe (error "no body") cs (responseBody resp) - `shouldContain` "wire:sso:error:forbidden" + `shouldNotContain` "wire:sso:error:success" + createViaSaml :: HasCallStack => IdP -> SAML.SignPrivCreds -> SAML.UserRef -> TestSpar (Maybe UserId) createViaSaml idp privCreds uref = do resp <- createViaSamlResp idp privCreds uref @@ -691,6 +707,7 @@ testScimCreateVsUserRef = do maybe (error "no body") cs (responseBody resp) `shouldContain` "wire:sso:success" getUserIdViaRef' uref + deleteViaBrig :: UserId -> TestSpar () deleteViaBrig uid = do brig <- view teBrig @@ -821,7 +838,7 @@ testFindSamlAutoProvisionedUserMigratedWithEmailInTeamWithSSO = do veidToText :: MonadError String m => ValidExternalId -> m Text veidToText veid = runValidExternalId - (\(SAML.UserRef _ subj) -> maybe (throwError "bad uref from brig") pure $ SAML.shortShowNameID subj) + (\(SAML.UserRef _ subj) -> maybe (throwError "bad uref from brig") (pure . CI.original) $ SAML.shortShowNameID subj) (pure . fromEmail) veid diff --git a/services/spar/test-integration/Util/Core.hs b/services/spar/test-integration/Util/Core.hs index a31d8cab8b0..03bda6dc4b1 100644 --- a/services/spar/test-integration/Util/Core.hs +++ b/services/spar/test-integration/Util/Core.hs @@ -253,6 +253,7 @@ mkEnv _teTstOpts _teOpts = do _teGalley = endpointToReq (cfgGalley _teTstOpts) _teSpar = endpointToReq (cfgSpar _teTstOpts) _teSparEnv = Spar.Env {..} + _teWireIdPAPIVersion = WireIdPAPIV2 sparCtxOpts = _teOpts sparCtxCas = _teCql sparCtxHttpManager = _teMgr @@ -497,7 +498,7 @@ deleteUserOnBrig :: m () deleteUserOnBrig brigreq uid = do deleteUserNoWait brigreq uid - recoverAll (exponentialBackoff 30000 <> limitRetries 5) $ \_ -> do + recoverAll (exponentialBackoff 500000 <> limitRetries 5) $ \_ -> do profile <- getSelfProfile brigreq uid liftIO $ selfUser profile `shouldSatisfy` Brig.userDeleted @@ -520,8 +521,8 @@ deleteUserNoWait brigreq uid = nextWireId :: MonadIO m => m (Id a) nextWireId = Id <$> liftIO UUID.nextRandom -nextWireIdP :: MonadIO m => m WireIdP -nextWireIdP = WireIdP <$> (Id <$> liftIO UUID.nextRandom) <*> pure [] <*> pure Nothing +nextWireIdP :: MonadIO m => WireIdPAPIVersion -> m WireIdP +nextWireIdP version = WireIdP <$> (Id <$> liftIO UUID.nextRandom) <*> pure (Just version) <*> pure [] <*> pure Nothing nextSAMLID :: MonadIO m => m (ID a) nextSAMLID = mkID . UUID.toText <$> liftIO UUID.nextRandom @@ -736,18 +737,26 @@ call req = ask >>= \env -> liftIO $ runHttpT (env ^. teMgr) req ping :: (Request -> Request) -> Http () ping req = void . get $ req . path "/i/status" . expect2xx -makeTestIdP :: (HasCallStack, MonadRandom m, MonadIO m) => m (IdPConfig WireIdP) +makeTestIdP :: (HasCallStack, MonadReader TestEnv m, MonadRandom m, MonadIO m) => m (IdPConfig WireIdP) makeTestIdP = do + apiversion <- asks (^. teWireIdPAPIVersion) SampleIdP md _ _ _ <- makeSampleIdPMetadata IdPConfig <$> (IdPId <$> liftIO UUID.nextRandom) <*> (pure md) - <*> nextWireIdP + <*> nextWireIdP apiversion -getTestSPMetadata :: (HasCallStack, MonadReader TestEnv m, MonadIO m) => m SPMetadata -getTestSPMetadata = do +getTestSPMetadata :: (HasCallStack, MonadReader TestEnv m, MonadIO m) => TeamId -> m SPMetadata +getTestSPMetadata tid = do env <- ask - resp <- call . get $ (env ^. teSpar) . path "/sso/metadata" . expect2xx + resp <- + call . get $ + (env ^. teSpar) + . ( case env ^. teWireIdPAPIVersion of + WireIdPAPIV1 -> path "/sso/metadata" + WireIdPAPIV2 -> paths ["/sso/metadata", toByteString' tid] + ) + . expect2xx raw <- maybe (crash_ "no body") (pure . cs) $ responseBody resp either (crash_ . show) pure (SAML.decode raw) where @@ -774,7 +783,7 @@ registerTestIdPWithMeta = do -- | Helper for 'registerTestIdP'. registerTestIdPFrom :: - (HasCallStack, MonadIO m) => + (HasCallStack, MonadIO m, MonadReader TestEnv m) => IdPMetadata -> Manager -> BrigReq -> @@ -782,9 +791,10 @@ registerTestIdPFrom :: SparReq -> m (UserId, TeamId, IdP) registerTestIdPFrom metadata mgr brig galley spar = do + apiVersion <- asks (^. teWireIdPAPIVersion) liftIO . runHttpT mgr $ do (uid, tid) <- createUserWithTeam brig galley - (uid,tid,) <$> callIdpCreate spar (Just uid) metadata + (uid,tid,) <$> callIdpCreate apiVersion spar (Just uid) metadata getCookie :: KnownSymbol name => proxy name -> ResponseLBS -> Either String (SAML.SimpleSetCookie name) getCookie proxy rsp = do @@ -838,10 +848,11 @@ isSetBindCookie (SetBindCookie (SimpleSetCookie cky)) = do tryLogin :: HasCallStack => SignPrivCreds -> IdP -> NameID -> TestSpar SAML.UserRef tryLogin privkey idp userSubject = do env <- ask - spmeta <- getTestSPMetadata + let tid = idp ^. idpExtraInfo . wiTeam + spmeta <- getTestSPMetadata tid (_, authnreq) <- call $ callAuthnReq (env ^. teSpar) (idp ^. SAML.idpId) idpresp <- runSimpleSP $ mkAuthnResponseWithSubj userSubject privkey idp spmeta authnreq True - sparresp <- submitAuthnResponse idpresp + sparresp <- submitAuthnResponse tid idpresp liftIO $ do statusCode sparresp `shouldBe` 200 let bdy = maybe "" (cs @LBS @String) (responseBody sparresp) @@ -852,10 +863,11 @@ tryLogin privkey idp userSubject = do tryLoginFail :: HasCallStack => SignPrivCreds -> IdP -> NameID -> String -> TestSpar () tryLoginFail privkey idp userSubject bodyShouldContain = do env <- ask - spmeta <- getTestSPMetadata + let tid = idp ^. idpExtraInfo . wiTeam + spmeta <- getTestSPMetadata tid (_, authnreq) <- call $ callAuthnReq (env ^. teSpar) (idp ^. SAML.idpId) idpresp <- runSimpleSP $ mkAuthnResponseWithSubj userSubject privkey idp spmeta authnreq True - sparresp <- submitAuthnResponse idpresp + sparresp <- submitAuthnResponse tid idpresp liftIO $ do let bdy = maybe "" (cs @LBS @String) (responseBody sparresp) bdy `shouldContain` bodyShouldContain @@ -899,6 +911,7 @@ negotiateAuthnRequest' (doInitiatePath -> doInit) idp modreq = do submitAuthnResponse :: (HasCallStack, MonadIO m, MonadReader TestEnv m) => + TeamId -> SignedAuthnResponse -> m ResponseLBS submitAuthnResponse = submitAuthnResponse' id @@ -906,13 +919,18 @@ submitAuthnResponse = submitAuthnResponse' id submitAuthnResponse' :: (HasCallStack, MonadIO m, MonadReader TestEnv m) => (Request -> Request) -> + TeamId -> SignedAuthnResponse -> m ResponseLBS -submitAuthnResponse' reqmod (SignedAuthnResponse authnresp) = do +submitAuthnResponse' reqmod tid (SignedAuthnResponse authnresp) = do env <- ask req :: Request <- formDataBody [partLBS "SAMLResponse" . EL.encode . XML.renderLBS XML.def $ authnresp] empty - call $ post' req (reqmod . (env ^. teSpar) . path "/sso/finalize-login/") + let p = + case env ^. teWireIdPAPIVersion of + WireIdPAPIV1 -> path "/sso/finalize-login/" + WireIdPAPIV2 -> paths ["/sso/finalize-login", toByteString' tid] + call $ post' req (reqmod . (env ^. teSpar) . p) loginSsoUserFirstTime :: (HasCallStack, MonadIO m, MonadReader TestEnv m) => @@ -938,10 +956,11 @@ loginCreatedSsoUser :: m (UserId, Cookie) loginCreatedSsoUser nameid idp privCreds = do env <- ask + let tid = idp ^. idpExtraInfo . wiTeam authnReq <- negotiateAuthnRequest idp - spmeta <- getTestSPMetadata + spmeta <- getTestSPMetadata tid authnResp <- runSimpleSP $ mkAuthnResponseWithSubj nameid privCreds idp spmeta authnReq True - sparAuthnResp <- submitAuthnResponse authnResp + sparAuthnResp <- submitAuthnResponse tid authnResp let wireCookie = maybe (error (show sparAuthnResp)) id . lookup "Set-Cookie" $ responseHeaders sparAuthnResp accessResp :: ResponseLBS <- @@ -1051,18 +1070,26 @@ callIdpGetAll' :: (MonadIO m, MonadHttp m) => SparReq -> Maybe UserId -> m Respo callIdpGetAll' sparreq_ muid = do get $ sparreq_ . maybe id zUser muid . path "/identity-providers" -callIdpCreate :: (MonadIO m, MonadHttp m) => SparReq -> Maybe UserId -> SAML.IdPMetadata -> m IdP -callIdpCreate sparreq_ muid metadata = do - resp <- callIdpCreate' (sparreq_ . expect2xx) muid metadata +callIdpCreate :: (MonadIO m, MonadHttp m) => WireIdPAPIVersion -> SparReq -> Maybe UserId -> SAML.IdPMetadata -> m IdP +callIdpCreate apiversion sparreq_ muid metadata = do + resp <- callIdpCreate' apiversion (sparreq_ . expect2xx) muid metadata either (liftIO . throwIO . ErrorCall . show) pure $ responseJsonEither @IdP resp -callIdpCreate' :: (MonadIO m, MonadHttp m) => SparReq -> Maybe UserId -> SAML.IdPMetadata -> m ResponseLBS -callIdpCreate' sparreq_ muid metadata = do +callIdpCreate' :: (MonadIO m, MonadHttp m) => WireIdPAPIVersion -> SparReq -> Maybe UserId -> SAML.IdPMetadata -> m ResponseLBS +callIdpCreate' apiversion sparreq_ muid metadata = do + explicitQueryParam <- do + -- `&api-version=v1` is implicit and can be omitted from the query, but we want to test + -- both, and not spend extra time on it. + liftIO $ randomRIO (True, False) post $ sparreq_ . maybe id zUser muid . path "/identity-providers/" + . ( case apiversion of + WireIdPAPIV1 -> Bilge.query [("api-version", Just "v1") | explicitQueryParam] + WireIdPAPIV2 -> Bilge.query [("api-version", Just "v2")] + ) . body (RequestBodyLBS . cs $ SAML.encode metadata) . header "Content-Type" "application/xml" @@ -1081,20 +1108,34 @@ callIdpCreateRaw' sparreq_ muid ctyp metadata = do . body (RequestBodyLBS metadata) . header "Content-Type" ctyp -callIdpCreateReplace :: (MonadIO m, MonadHttp m) => SparReq -> Maybe UserId -> IdPMetadata -> IdPId -> m IdP -callIdpCreateReplace sparreq_ muid metadata idpid = do - resp <- callIdpCreateReplace' (sparreq_ . expect2xx) muid metadata idpid +callIdpCreateReplace :: (MonadIO m, MonadHttp m) => WireIdPAPIVersion -> SparReq -> Maybe UserId -> IdPMetadata -> IdPId -> m IdP +callIdpCreateReplace apiversion sparreq_ muid metadata idpid = do + resp <- callIdpCreateReplace' apiversion (sparreq_ . expect2xx) muid metadata idpid either (liftIO . throwIO . ErrorCall . show) pure $ responseJsonEither @IdP resp -callIdpCreateReplace' :: (MonadIO m, MonadHttp m) => SparReq -> Maybe UserId -> IdPMetadata -> IdPId -> m ResponseLBS -callIdpCreateReplace' sparreq_ muid metadata idpid = do +callIdpCreateReplace' :: (HasCallStack, MonadIO m, MonadHttp m) => WireIdPAPIVersion -> SparReq -> Maybe UserId -> IdPMetadata -> IdPId -> m ResponseLBS +callIdpCreateReplace' apiversion sparreq_ muid metadata idpid = do + explicitQueryParam <- do + -- `&api-version=v1` is implicit and can be omitted from the query, but we want to test + -- both, and not spend extra time on it. + liftIO $ randomRIO (True, False) post $ sparreq_ . maybe id zUser muid . path "/identity-providers/" + . Bilge.query + ( [ ( "api-version", + case apiversion of + WireIdPAPIV1 -> if explicitQueryParam then Just "v1" else Nothing + WireIdPAPIV2 -> Just "v2" + ), + ( "replaces", + Just . cs . idPIdToST $ idpid + ) + ] + ) . body (RequestBodyLBS . cs $ SAML.encode metadata) - . queryItem "replaces" (cs $ idPIdToST idpid) . header "Content-Type" "application/xml" callIdpUpdate' :: (MonadIO m, MonadHttp m) => SparReq -> Maybe UserId -> IdPId -> IdPMetadataInfo -> m ResponseLBS diff --git a/services/spar/test-integration/Util/Types.hs b/services/spar/test-integration/Util/Types.hs index a727e80382e..67b5631d623 100644 --- a/services/spar/test-integration/Util/Types.hs +++ b/services/spar/test-integration/Util/Types.hs @@ -31,17 +31,19 @@ module Util.Types teSparEnv, teOpts, teTstOpts, + teWireIdPAPIVersion, Select, ResponseLBS, IntegrationConfig (..), TestErrorLabel (..), + skipIdPAPIVersions, ) where import Bilge import Cassandra as Cas import Control.Exception -import Control.Lens (makeLenses) +import Control.Lens (makeLenses, (^.)) import Crypto.Random.Types (MonadRandom (..)) import Data.Aeson import qualified Data.Aeson as Aeson @@ -51,7 +53,9 @@ import Imports import SAML2.WebSSO.Types.TH (deriveJSONOptions) import Spar.API () import qualified Spar.App as Spar +import Test.Hspec (pendingWith) import Util.Options +import Wire.API.User.IdentityProvider (WireIdPAPIVersion) import Wire.API.User.Saml type BrigReq = Request -> Request @@ -76,7 +80,14 @@ data TestEnv = TestEnv -- | spar config _teOpts :: Opts, -- | integration test config - _teTstOpts :: IntegrationConfig + _teTstOpts :: IntegrationConfig, + -- | If True, run tests against legacy SAML API where team is derived from idp issuer + -- instead of teamid. See Section "using the same IdP (same entityID, or Issuer) with + -- different teams" in "/docs/reference/spar-braindump.md" for more details. + -- + -- NB: this has no impact on the tested spar code; the rest API supports both legacy and + -- multi-sp mode. this falg merely determines how the rest API is used. + _teWireIdPAPIVersion :: WireIdPAPIVersion } type Select = TestEnv -> (Request -> Request) @@ -108,3 +119,8 @@ _unitTestTestErrorLabel = do unless (val == Right "not-found") $ throwIO . ErrorCall . show $ val + +skipIdPAPIVersions :: (MonadIO m, MonadReader TestEnv m) => [WireIdPAPIVersion] -> m () +skipIdPAPIVersions skip = do + asks (^. teWireIdPAPIVersion) >>= \vers -> when (vers `elem` skip) . liftIO $ do + pendingWith $ "skipping " <> show vers <> " for this test case (behavior covered by other versions)" diff --git a/services/spar/test/Arbitrary.hs b/services/spar/test/Arbitrary.hs index f80bac9baa2..f48e5722fc5 100644 --- a/services/spar/test/Arbitrary.hs +++ b/services/spar/test/Arbitrary.hs @@ -41,7 +41,7 @@ instance Arbitrary IdPList where pure $ IdPList {..} instance Arbitrary WireIdP where - arbitrary = WireIdP <$> arbitrary <*> arbitrary <*> arbitrary + arbitrary = WireIdP <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary deriving instance Arbitrary ScimToken diff --git a/stack.yaml b/stack.yaml index e39daebbcc5..33dd3747547 100644 --- a/stack.yaml +++ b/stack.yaml @@ -70,7 +70,7 @@ extra-deps: # a version > 1.0.0 of wai-middleware-prometheus is available # (required: https://github.com/fimad/prometheus-haskell/pull/45) - git: https://github.com/wireapp/saml2-web-sso - commit: ac88b934bb4a91d4d4bb90c620277188e4087043 # https://github.com/wireapp/saml2-web-sso/pull/73 (Feb 18, 2021) + commit: 60398f375987b74d6b855b5d225e45dc3a96ac06 # https://github.com/wireapp/saml2-web-sso/pull/75 (Sep 10, 2021) - git: https://github.com/kim/hs-collectd commit: 885da222be2375f78c7be36127620ed772b677c9 @@ -243,6 +243,12 @@ extra-deps: - git: https://github.com/wireapp/snappy commit: b0e5c08af48911caecffa4fa6a3e74872018b258 # master (Sep 03, 2021) +# Error handling fix: https://github.com/vincenthz/hs-certificate/pull/125 +- git: https://github.com/wireapp/hs-certificate + commit: e3ea2e1166f0569982a85aad9bc9de8f5b2994c1 # master (Aug 31, 2021) + subdirs: + - x509-store + ############################################################ # Development tools ############################################################ diff --git a/stack.yaml.lock b/stack.yaml.lock index e17149372df..6fc195e0dfe 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -22,12 +22,12 @@ packages: version: '0.18' git: https://github.com/wireapp/saml2-web-sso pantry-tree: - size: 4815 - sha256: 04b922847a5e37d578bb9b43c4ea0694e0b731c710362957b12ac19f49b95264 - commit: ac88b934bb4a91d4d4bb90c620277188e4087043 + size: 4887 + sha256: 29e0138ca6bc33500b87cd6c06bbd899fe4ddaadcfd5117b211e7769f9f80161 + commit: 60398f375987b74d6b855b5d225e45dc3a96ac06 original: git: https://github.com/wireapp/saml2-web-sso - commit: ac88b934bb4a91d4d4bb90c620277188e4087043 + commit: 60398f375987b74d6b855b5d225e45dc3a96ac06 - completed: name: collectd version: 0.0.0.2 @@ -520,10 +520,10 @@ packages: original: hackage: tls-1.5.5 - completed: - hackage: cryptonite-0.28@sha256:b6c75e62b4c655d4cb1bcbb80d01430d136aac32bd6962c86c84738935cc8f9d,18195 + hackage: cryptonite-0.28@sha256:edf00c7b00b9a1c07a178c0fe446c6ebe462637d498590757c8eac2075bb0b43,18215 pantry-tree: size: 23132 - sha256: d80d7be9b1d0799a8e401ca5d4f4f424e0d8c42d4a30cc37bf6f82970232bfcf + sha256: 3737ee32d6629b4b915c01911fdb9dc0e255b96233799479c29420d986634726 original: hackage: cryptonite-0.28 - completed: @@ -796,6 +796,19 @@ packages: original: git: https://github.com/wireapp/snappy commit: b0e5c08af48911caecffa4fa6a3e74872018b258 +- completed: + subdir: x509-store + name: x509-store + version: 1.6.7 + git: https://github.com/wireapp/hs-certificate + pantry-tree: + size: 398 + sha256: 96deca9a5358118057cd145f198b5be06d88019eae46b263bee86c76b2fc574d + commit: e3ea2e1166f0569982a85aad9bc9de8f5b2994c1 + original: + subdir: x509-store + git: https://github.com/wireapp/hs-certificate + commit: e3ea2e1166f0569982a85aad9bc9de8f5b2994c1 - completed: hackage: ormolu-0.1.4.1@sha256:ed404eac6e4eb64da1ca5fb749e0f99907431a9633e6ba34e44d260e7d7728ba,6499 pantry-tree: diff --git a/tools/api-simulations/lib/src/Network/Wire/Simulations.hs b/tools/api-simulations/lib/src/Network/Wire/Simulations.hs index ccbf6a6567c..eaa80350402 100644 --- a/tools/api-simulations/lib/src/Network/Wire/Simulations.hs +++ b/tools/api-simulations/lib/src/Network/Wire/Simulations.hs @@ -50,6 +50,7 @@ import Data.ByteString.Conversion import Data.Id (ConvId, UserId) import qualified Data.Map.Strict as Map import Data.Qualified (qUnqualified) +import Data.Range import Data.Serialize import qualified Data.Set as Set import qualified Data.Text as Text @@ -98,7 +99,7 @@ connectIfNeeded = go 6 -- six turns should be enough case s of -- If no connection: initiate one Nothing -> do - void $ connectTo (ConnectionRequest (botId b) (fromMaybe "" (botEmail a)) (Message "Hi there!")) + void $ connectTo (ConnectionRequest (botId b) (unsafeRange (fromMaybe "" (botEmail a)))) assertConnectRequested a b return False -- If there's a pending connection to us: accept it diff --git a/tools/api-simulations/smoketest/src/Network/Wire/Simulations/SmokeTest.hs b/tools/api-simulations/smoketest/src/Network/Wire/Simulations/SmokeTest.hs index f4a08202f40..56ed6bf0ddf 100644 --- a/tools/api-simulations/smoketest/src/Network/Wire/Simulations/SmokeTest.hs +++ b/tools/api-simulations/smoketest/src/Network/Wire/Simulations/SmokeTest.hs @@ -29,6 +29,7 @@ import qualified Data.ByteString.Lazy as LBS import Data.Id (ConvId) import Data.List1 import Data.Qualified (qUnqualified) +import Data.Range import Imports import Network.Wire.Bot import Network.Wire.Bot.Assert @@ -64,8 +65,7 @@ mainBotNet n = do connectTo ConnectionRequest { crUser = botId user, - crName = fromMaybe "" (botEmail ally), - crMessage = Message "Hi there!" + crName = unsafeRange $ fromMaybe "" (botEmail ally) } assertConnectRequested ally user requireMaybe (ucConvId conn) "conv_id not set after connection request" @@ -96,7 +96,6 @@ mainBotNet n = do let update = MemberUpdateData { misTarget = Just $ botId bill, - misOtrMuted = Nothing, misOtrMutedStatus = Nothing, misOtrMutedRef = Nothing, misOtrArchived = Just True,