diff --git a/changelog.d/0-release-notes/add-type-field-to-contact b/changelog.d/0-release-notes/add-type-field-to-contact new file mode 100644 index 0000000000..10d7af72c0 --- /dev/null +++ b/changelog.d/0-release-notes/add-type-field-to-contact @@ -0,0 +1,3 @@ +Since the index mapping has been updated, the elastic search index +needs to be refilled from Cassandra, see +https://docs.wire.com/latest/developer/reference/elastic-search.html?h=index#refill-es-documents-from-cassandra \ No newline at end of file diff --git a/changelog.d/1-api-changes/add-get-app-endpoint b/changelog.d/1-api-changes/add-get-app-endpoint deleted file mode 100644 index e433e9cc22..0000000000 --- a/changelog.d/1-api-changes/add-get-app-endpoint +++ /dev/null @@ -1 +0,0 @@ -Add "get app" endpoint to Brig (`GET /teams/:tid/apps/:id`) \ No newline at end of file diff --git a/changelog.d/1-api-changes/add-type-field-to-contact b/changelog.d/1-api-changes/add-type-field-to-contact new file mode 100644 index 0000000000..cb58adb825 --- /dev/null +++ b/changelog.d/1-api-changes/add-type-field-to-contact @@ -0,0 +1 @@ +Add `type` field to search results received from `GET /search/contacts` \ No newline at end of file diff --git a/integration/test/Test/Apps.hs b/integration/test/Test/Apps.hs index 4af7b903b3..14991a5375 100644 --- a/integration/test/Test/Apps.hs +++ b/integration/test/Test/Apps.hs @@ -73,7 +73,7 @@ testCreateApp = do (resp.json %. "category") `shouldMatch` "ai" -- A teamless user can't get the app - outsideUser <- randomUser OwnDomain def + outsideUser <- randomUser domain def bindResponse (getApp outsideUser tid appId) $ \resp -> do resp.status `shouldMatchInt` 403 resp.json %. "label" `shouldMatch` "app-no-permission" @@ -88,13 +88,19 @@ testCreateApp = do void $ bindResponse (createApp owner tid new {category = "notinenum"}) $ \resp -> do resp.status `shouldMatchInt` 400 + let foundUserType exactMatchTerm aType = + searchContacts owner exactMatchTerm OwnDomain `bindResponse` \resp -> do + resp.status `shouldMatchInt` 200 + foundDoc <- resp.json %. "documents" >>= asList >>= assertOne + foundDoc %. "type" `shouldMatch` aType + -- App's user is findable from /search/contacts - BrigI.refreshIndex OwnDomain - searchContacts owner new.name OwnDomain `bindResponse` \resp -> do - resp.status `shouldMatchInt` 200 - docs <- resp.json %. "documents" >>= asList - foundUids <- for docs objId - foundUids `shouldMatch` [appId] + BrigI.refreshIndex domain + foundUserType new.name "app" + + -- Regular members still have the type "regular" + memberName <- regularMember %. "name" & asString + foundUserType memberName "regular" testRefreshAppCookie :: (HasCallStack) => App () testRefreshAppCookie = do diff --git a/libs/wire-api/src/Wire/API/User.hs b/libs/wire-api/src/Wire/API/User.hs index 138ded4356..defa322a59 100644 --- a/libs/wire-api/src/Wire/API/User.hs +++ b/libs/wire-api/src/Wire/API/User.hs @@ -472,6 +472,7 @@ instance (1 <= max) => ToJSON (LimitedQualifiedUserIdList max) where data UserType = UserTypeRegular | UserTypeApp | UserTypeBot deriving (Eq, Show, Generic) deriving (Arbitrary) via (GenericUniform UserType) + deriving (A.FromJSON, A.ToJSON) via (Schema UserType) instance Default UserType where def = UserTypeRegular @@ -714,34 +715,32 @@ instance FromJSON (EmailVisibility ()) where "visible_to_self" -> pure EmailVisibleToSelf _ -> fail "unexpected value for EmailVisibility settings" -mkUserProfileWithEmail :: Maybe EmailAddress -> User -> UserLegalHoldStatus -> UserProfile -mkUserProfileWithEmail memail u legalHoldStatus = - let ty = case userService u of - Nothing -> UserTypeRegular - Just _ -> UserTypeBot - in -- This profile would be visible to any other user. When a new field is - -- added, please make sure it is OK for other users to have access to it. - UserProfile - { profileQualifiedId = userQualifiedId u, - profileHandle = userHandle u, - profileName = userDisplayName u, - profileTextStatus = userTextStatus u, - profilePict = userPict u, - profileAssets = userAssets u, - profileAccentId = userAccentId u, - profileService = userService u, - profileDeleted = userDeleted u, - profileExpire = userExpire u, - profileTeam = userTeam u, - profileEmail = memail, - profileLegalholdStatus = legalHoldStatus, - profileSupportedProtocols = userSupportedProtocols u, - profileType = ty, - profileSearchable = userSearchable u - } +-- | Create profile, overwriting the email field. Called `mkUserProfile`. +mkUserProfileWithEmail :: Maybe EmailAddress -> UserType -> User -> UserLegalHoldStatus -> UserProfile +mkUserProfileWithEmail memail userType u legalHoldStatus = + -- This profile would be visible to any other user. When a new field is + -- added, please make sure it is OK for other users to have access to it. + UserProfile + { profileQualifiedId = userQualifiedId u, + profileHandle = userHandle u, + profileName = userDisplayName u, + profileTextStatus = userTextStatus u, + profilePict = userPict u, + profileAssets = userAssets u, + profileAccentId = userAccentId u, + profileService = userService u, + profileDeleted = userDeleted u, + profileExpire = userExpire u, + profileTeam = userTeam u, + profileEmail = memail, + profileLegalholdStatus = legalHoldStatus, + profileSupportedProtocols = userSupportedProtocols u, + profileType = userType, + profileSearchable = userSearchable u + } -mkUserProfile :: EmailVisibilityConfigWithViewer -> User -> UserLegalHoldStatus -> UserProfile -mkUserProfile emailVisibilityConfigAndViewer u legalHoldStatus = +mkUserProfile :: EmailVisibilityConfigWithViewer -> UserType -> User -> UserLegalHoldStatus -> UserProfile +mkUserProfile emailVisibilityConfigAndViewer userType u legalHoldStatus = let isEmailVisible = case emailVisibilityConfigAndViewer of EmailVisibleToSelf -> False EmailVisibleIfOnTeam -> isJust (userTeam u) @@ -749,7 +748,7 @@ mkUserProfile emailVisibilityConfigAndViewer u legalHoldStatus = EmailVisibleIfOnSameTeam (Just (viewerTeamId, viewerMembership)) -> Just viewerTeamId == userTeam u && TeamMember.hasPermission viewerMembership TeamMember.ViewSameTeamEmails - in mkUserProfileWithEmail (if isEmailVisible then userEmail u else Nothing) u legalHoldStatus + in mkUserProfileWithEmail (if isEmailVisible then userEmail u else Nothing) userType u legalHoldStatus -------------------------------------------------------------------------------- -- NewUser diff --git a/libs/wire-api/src/Wire/API/User/Search.hs b/libs/wire-api/src/Wire/API/User/Search.hs index bddf084994..96e01c24fe 100644 --- a/libs/wire-api/src/Wire/API/User/Search.hs +++ b/libs/wire-api/src/Wire/API/User/Search.hs @@ -42,8 +42,7 @@ import Data.Aeson hiding (object, (.=)) import Data.Aeson qualified as Aeson import Data.Attoparsec.ByteString.Char8 (string) import Data.ByteString.Char8 qualified as C8 -import Data.ByteString.Conversion -import Data.ByteString.Conversion qualified as BS +import Data.ByteString.Conversion as BS import Data.Id (TeamId, UserGroupId, UserId) import Data.Json.Util (UTCTimeMillis) import Data.OpenApi (ToParamSchema (..)) @@ -59,7 +58,7 @@ import Imports import Servant.API (FromHttpApiData, ToHttpApiData (..)) import Web.Internal.HttpApiData (parseQueryParam) import Wire.API.Team.Role (Role) -import Wire.API.User (ManagedBy) +import Wire.API.User (ManagedBy, UserType) import Wire.API.User.Identity (EmailAddress) import Wire.Arbitrary (Arbitrary, GenericUniform (..)) @@ -138,14 +137,15 @@ deriving via (Schema (SearchResult TeamContact)) instance S.ToSchema (SearchResu -------------------------------------------------------------------------------- -- Contact --- | Returned by 'searchIndex' under @/contacts/search@. +-- | Returned by 'searchIndex' under @/search/contacts@. -- This is a subset of 'User' and json instances should reflect that. data Contact = Contact { contactQualifiedId :: Qualified UserId, contactName :: Text, contactColorId :: Maybe Int, contactHandle :: Maybe Text, - contactTeam :: Maybe TeamId + contactTeam :: Maybe TeamId, + contactType :: UserType } deriving stock (Eq, Show, Generic) deriving (Arbitrary) via (GenericUniform Contact) @@ -161,6 +161,7 @@ instance ToSchema Contact where <*> contactColorId .= optField "accent_id" (maybeWithDefault Aeson.Null schema) <*> contactHandle .= optField "handle" (maybeWithDefault Aeson.Null schema) <*> contactTeam .= optField "team" (maybeWithDefault Aeson.Null schema) + <*> contactType .= field "type" schema -------------------------------------------------------------------------------- -- TeamContact diff --git a/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/Contact_user.hs b/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/Contact_user.hs index b3f7c67e29..88b04796f6 100644 --- a/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/Contact_user.hs +++ b/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/Contact_user.hs @@ -22,6 +22,7 @@ import Data.Id (Id (Id)) import Data.Qualified (Qualified (Qualified, qDomain, qUnqualified)) import Data.UUID qualified as UUID (fromString) import Imports (Maybe (Just, Nothing), fromJust) +import Wire.API.User import Wire.API.User.Search (Contact (..)) testObject_Contact_user_1 :: Contact @@ -35,7 +36,8 @@ testObject_Contact_user_1 = contactName = "", contactColorId = Just 6, contactHandle = Just "\1089530\NUL|\SO", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } testObject_Contact_user_2 :: Contact @@ -49,7 +51,8 @@ testObject_Contact_user_2 = contactName = "\SYND", contactColorId = Just (-5), contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000002-0000-0008-0000-000400000002"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000002-0000-0008-0000-000400000002"))), + contactType = UserTypeApp } testObject_Contact_user_3 :: Contact @@ -63,7 +66,8 @@ testObject_Contact_user_3 = contactName = "S\1037187D\GS", contactColorId = Just (-4), contactHandle = Just "\175177~\35955c", - contactTeam = Just (Id (fromJust (UUID.fromString "00000006-0000-0005-0000-000700000008"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000006-0000-0005-0000-000700000008"))), + contactType = UserTypeBot } testObject_Contact_user_4 :: Contact @@ -77,7 +81,8 @@ testObject_Contact_user_4 = contactName = "@=\ETX", contactColorId = Nothing, contactHandle = Just "6", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000500000004"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000500000004"))), + contactType = UserTypeRegular } testObject_Contact_user_5 :: Contact @@ -91,7 +96,8 @@ testObject_Contact_user_5 = contactName = "5m~\DC4`", contactColorId = Nothing, contactHandle = Nothing, - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } testObject_Contact_user_6 :: Contact @@ -105,7 +111,8 @@ testObject_Contact_user_6 = contactName = "Cst\995547U", contactColorId = Nothing, contactHandle = Just "qI", - contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0004-0000-000600000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0004-0000-000600000000"))), + contactType = UserTypeRegular } testObject_Contact_user_7 :: Contact @@ -119,7 +126,8 @@ testObject_Contact_user_7 = contactName = "\b74\ENQ", contactColorId = Just 5, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000008-0000-0001-0000-000400000008"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000008-0000-0001-0000-000400000008"))), + contactType = UserTypeRegular } testObject_Contact_user_8 :: Contact @@ -133,7 +141,8 @@ testObject_Contact_user_8 = contactName = "w\1050194\993461#\\", contactColorId = Just (-2), contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0007-0000-000500000002"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0007-0000-000500000002"))), + contactType = UserTypeRegular } testObject_Contact_user_9 :: Contact @@ -147,7 +156,8 @@ testObject_Contact_user_9 = contactName = ",\1041199 \v\1077257", contactColorId = Just 5, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0002-0000-000500000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0002-0000-000500000000"))), + contactType = UserTypeRegular } testObject_Contact_user_10 :: Contact @@ -161,7 +171,8 @@ testObject_Contact_user_10 = contactName = "(\1103086\1105553H/", contactColorId = Just 0, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0006-0000-000700000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0006-0000-000700000000"))), + contactType = UserTypeRegular } testObject_Contact_user_11 :: Contact @@ -175,7 +186,8 @@ testObject_Contact_user_11 = contactName = "+\DC4\1063683<", contactColorId = Just 6, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000007-0000-0008-0000-000600000004"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000007-0000-0008-0000-000600000004"))), + contactType = UserTypeRegular } testObject_Contact_user_12 :: Contact @@ -189,7 +201,8 @@ testObject_Contact_user_12 = contactName = "l\DC1\ETB`\ETX", contactColorId = Just (-4), contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } testObject_Contact_user_13 :: Contact @@ -203,7 +216,8 @@ testObject_Contact_user_13 = contactName = "\SYN\1030541\v8z", contactColorId = Just (-3), contactHandle = Just "E\EM\US[58", - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0003-0000-000000000005"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0003-0000-000000000005"))), + contactType = UserTypeRegular } testObject_Contact_user_14 :: Contact @@ -217,7 +231,8 @@ testObject_Contact_user_14 = contactName = "7", contactColorId = Just (-2), contactHandle = Just "h\CAN", - contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0008-0000-000700000008"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000005-0000-0008-0000-000700000008"))), + contactType = UserTypeRegular } testObject_Contact_user_15 :: Contact @@ -231,7 +246,8 @@ testObject_Contact_user_15 = contactName = "U6\ESC*\SO", contactColorId = Nothing, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000006-0000-0006-0000-000800000006"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000006-0000-0006-0000-000800000006"))), + contactType = UserTypeRegular } testObject_Contact_user_16 :: Contact @@ -245,7 +261,8 @@ testObject_Contact_user_16 = contactName = "l", contactColorId = Nothing, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0006-0000-000200000007"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0006-0000-000200000007"))), + contactType = UserTypeRegular } testObject_Contact_user_17 :: Contact @@ -259,7 +276,8 @@ testObject_Contact_user_17 = contactName = "fI\8868\&3z", contactColorId = Nothing, contactHandle = Just "3", - contactTeam = Just (Id (fromJust (UUID.fromString "00000004-0000-0007-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000004-0000-0007-0000-000000000001"))), + contactType = UserTypeRegular } testObject_Contact_user_18 :: Contact @@ -273,7 +291,8 @@ testObject_Contact_user_18 = contactName = "\"jC\74801\144577\DC2", contactColorId = Nothing, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0002-0000-000000000007"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0002-0000-000000000007"))), + contactType = UserTypeRegular } testObject_Contact_user_19 :: Contact @@ -287,7 +306,8 @@ testObject_Contact_user_19 = contactName = "I", contactColorId = Just (-1), contactHandle = Just "\"7\ACK!", - contactTeam = Just (Id (fromJust (UUID.fromString "00000006-0000-0004-0000-000000000003"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000006-0000-0004-0000-000000000003"))), + contactType = UserTypeRegular } testObject_Contact_user_20 :: Contact @@ -301,5 +321,6 @@ testObject_Contact_user_20 = contactName = "|K\n\n\t", contactColorId = Nothing, contactHandle = Nothing, - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } diff --git a/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/SearchResult_20Contact_user.hs b/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/SearchResult_20Contact_user.hs index bb79681738..1b9dc63b00 100644 --- a/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/SearchResult_20Contact_user.hs +++ b/libs/wire-api/test/golden/Test/Wire/API/Golden/Generated/SearchResult_20Contact_user.hs @@ -24,6 +24,7 @@ import Data.Id (Id (Id)) import Data.Qualified (Qualified (Qualified, qDomain, qUnqualified)) import Data.UUID qualified as UUID (fromString) import Imports (Bool (..), Maybe (Just, Nothing), fromJust) +import Wire.API.User (UserType (UserTypeRegular)) import Wire.API.User.Search (Contact (..), FederatedUserSearchPolicy (ExactHandleSearch, FullSearch), PagingState (..), SearchResult (..)) testObject_SearchResult_20Contact_user_1 :: SearchResult Contact @@ -66,7 +67,8 @@ testObject_SearchResult_20Contact_user_3 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000000"))), + contactType = UserTypeRegular } ], searchPolicy = FullSearch, @@ -90,7 +92,8 @@ testObject_SearchResult_20Contact_user_4 = contactName = "", contactColorId = Nothing, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000100000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000100000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -101,7 +104,8 @@ testObject_SearchResult_20Contact_user_4 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000000"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -112,7 +116,8 @@ testObject_SearchResult_20Contact_user_4 = contactName = "", contactColorId = Just 0, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -123,7 +128,8 @@ testObject_SearchResult_20Contact_user_4 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -134,7 +140,8 @@ testObject_SearchResult_20Contact_user_4 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000000"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -145,7 +152,8 @@ testObject_SearchResult_20Contact_user_4 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), + contactType = UserTypeRegular } ], searchPolicy = FullSearch, @@ -169,7 +177,8 @@ testObject_SearchResult_20Contact_user_5 = contactName = "z", contactColorId = Just 1, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000100000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000100000001"))), + contactType = UserTypeRegular } ], searchPolicy = FullSearch, @@ -205,7 +214,8 @@ testObject_SearchResult_20Contact_user_7 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -216,7 +226,8 @@ testObject_SearchResult_20Contact_user_7 = contactName = "", contactColorId = Just 0, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))), + contactType = UserTypeRegular } ], searchPolicy = FullSearch, @@ -240,7 +251,8 @@ testObject_SearchResult_20Contact_user_8 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))), + contactType = UserTypeRegular } ], searchPolicy = FullSearch, @@ -288,7 +300,8 @@ testObject_SearchResult_20Contact_user_11 = contactName = "", contactColorId = Just 0, contactHandle = Nothing, - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -299,7 +312,8 @@ testObject_SearchResult_20Contact_user_11 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } ], searchPolicy = ExactHandleSearch, @@ -335,7 +349,8 @@ testObject_SearchResult_20Contact_user_13 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000000"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -346,7 +361,8 @@ testObject_SearchResult_20Contact_user_13 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -357,7 +373,8 @@ testObject_SearchResult_20Contact_user_13 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -368,7 +385,8 @@ testObject_SearchResult_20Contact_user_13 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } ], searchPolicy = ExactHandleSearch, @@ -392,7 +410,8 @@ testObject_SearchResult_20Contact_user_14 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000000"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -403,7 +422,8 @@ testObject_SearchResult_20Contact_user_14 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } ], searchPolicy = ExactHandleSearch, @@ -475,7 +495,8 @@ testObject_SearchResult_20Contact_user_19 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -486,7 +507,8 @@ testObject_SearchResult_20Contact_user_19 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000001"))), + contactType = UserTypeRegular } ], searchPolicy = ExactHandleSearch, @@ -510,7 +532,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -521,7 +544,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000100000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -532,7 +556,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -543,7 +568,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -554,7 +580,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0000-0000-000000000000"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -565,7 +592,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000001-0000-0001-0000-000000000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -576,7 +604,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0000-0000-000000000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -587,7 +616,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -598,7 +628,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Nothing, contactHandle = Just "", - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -609,7 +640,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000001"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000001"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -620,7 +652,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -631,7 +664,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Just "", - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000000000000"))), + contactType = UserTypeRegular }, Contact { contactQualifiedId = @@ -642,7 +676,8 @@ testObject_SearchResult_20Contact_user_20 = contactName = "", contactColorId = Just 0, contactHandle = Nothing, - contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))) + contactTeam = Just (Id (fromJust (UUID.fromString "00000000-0000-0001-0000-000100000000"))), + contactType = UserTypeRegular } ], searchPolicy = ExactHandleSearch, diff --git a/libs/wire-api/test/golden/Test/Wire/API/Golden/Manual/Contact.hs b/libs/wire-api/test/golden/Test/Wire/API/Golden/Manual/Contact.hs index 513f6d30af..3b2bc6fed9 100644 --- a/libs/wire-api/test/golden/Test/Wire/API/Golden/Manual/Contact.hs +++ b/libs/wire-api/test/golden/Test/Wire/API/Golden/Manual/Contact.hs @@ -22,6 +22,7 @@ import Data.Id (Id (Id)) import Data.Qualified (Qualified (Qualified)) import Data.UUID qualified as UUID import Imports +import Wire.API.User (UserType (UserTypeRegular)) import Wire.API.User.Search (Contact (..)) testObject_Contact_1 :: Contact @@ -31,7 +32,8 @@ testObject_Contact_1 = contactName = "Foobar", contactColorId = Just 1, contactHandle = Just "foobar1", - contactTeam = Just $ Id (fromJust (UUID.fromString "00000018-0000-0020-0000-000e00000002")) + contactTeam = Just $ Id (fromJust (UUID.fromString "00000018-0000-0020-0000-000e00000002")), + contactType = UserTypeRegular } testObject_Contact_2 :: Contact @@ -41,5 +43,6 @@ testObject_Contact_2 = contactName = "Foobar2", contactColorId = Nothing, contactHandle = Nothing, - contactTeam = Nothing + contactTeam = Nothing, + contactType = UserTypeRegular } diff --git a/libs/wire-api/test/golden/testObject_Contact_1.json b/libs/wire-api/test/golden/testObject_Contact_1.json index fb1bdac6dd..01906d05a2 100644 --- a/libs/wire-api/test/golden/testObject_Contact_1.json +++ b/libs/wire-api/test/golden/testObject_Contact_1.json @@ -7,5 +7,6 @@ "domain": "example.com", "id": "00000018-0000-0020-0000-000e00000002" }, - "team": "00000018-0000-0020-0000-000e00000002" + "team": "00000018-0000-0020-0000-000e00000002", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_2.json b/libs/wire-api/test/golden/testObject_Contact_2.json index aca2362249..a7171d11e6 100644 --- a/libs/wire-api/test/golden/testObject_Contact_2.json +++ b/libs/wire-api/test/golden/testObject_Contact_2.json @@ -7,5 +7,6 @@ "domain": "another.example.com", "id": "00000018-0000-0020-0000-000e00000003" }, - "team": null + "team": null, + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_1.json b/libs/wire-api/test/golden/testObject_Contact_user_1.json index 825287dc78..44a3c28869 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_1.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_1.json @@ -7,5 +7,6 @@ "domain": "j00.8y.yr3isy2m", "id": "00000007-0000-0003-0000-000300000005" }, - "team": null + "team": null, + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_10.json b/libs/wire-api/test/golden/testObject_Contact_user_10.json index 7618387345..57c4e71fa2 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_10.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_10.json @@ -7,5 +7,6 @@ "domain": "avs-82k0.quv1k-5", "id": "00000000-0000-0000-0000-000800000007" }, - "team": "00000005-0000-0006-0000-000700000000" + "team": "00000005-0000-0006-0000-000700000000", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_11.json b/libs/wire-api/test/golden/testObject_Contact_user_11.json index f6831f331b..dfd13cc9a2 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_11.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_11.json @@ -7,5 +7,6 @@ "domain": "156y.t.qxp-y26x", "id": "00000002-0000-0005-0000-000700000004" }, - "team": "00000007-0000-0008-0000-000600000004" + "team": "00000007-0000-0008-0000-000600000004", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_12.json b/libs/wire-api/test/golden/testObject_Contact_user_12.json index 38ca139c60..0c504b2229 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_12.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_12.json @@ -7,5 +7,6 @@ "domain": "d2wnzbn.8.k2d4-103", "id": "00000004-0000-0002-0000-000300000003" }, - "team": null + "team": null, + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_13.json b/libs/wire-api/test/golden/testObject_Contact_user_13.json index 3ee4544fc4..81835b8a16 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_13.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_13.json @@ -7,5 +7,6 @@ "domain": "902cigj.v2t56", "id": "00000002-0000-0006-0000-000800000006" }, - "team": "00000001-0000-0003-0000-000000000005" + "team": "00000001-0000-0003-0000-000000000005", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_14.json b/libs/wire-api/test/golden/testObject_Contact_user_14.json index 876b00ee25..14ef9ebd56 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_14.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_14.json @@ -7,5 +7,6 @@ "domain": "6z.ml.80ps6j5r.l", "id": "00000000-0000-0003-0000-000300000006" }, - "team": "00000005-0000-0008-0000-000700000008" + "team": "00000005-0000-0008-0000-000700000008", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_15.json b/libs/wire-api/test/golden/testObject_Contact_user_15.json index 5664eab786..619c62f22a 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_15.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_15.json @@ -7,5 +7,6 @@ "domain": "739.e-h8g", "id": "00000002-0000-0000-0000-000200000002" }, - "team": "00000006-0000-0006-0000-000800000006" + "team": "00000006-0000-0006-0000-000800000006", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_16.json b/libs/wire-api/test/golden/testObject_Contact_user_16.json index a04c2bf386..1ba59c042a 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_16.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_16.json @@ -7,5 +7,6 @@ "domain": "t82.x5i8-i", "id": "00000000-0000-0006-0000-000500000006" }, - "team": "00000000-0000-0006-0000-000200000007" + "team": "00000000-0000-0006-0000-000200000007", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_17.json b/libs/wire-api/test/golden/testObject_Contact_user_17.json index fd68c31c3a..54bb4c0fab 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_17.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_17.json @@ -7,5 +7,6 @@ "domain": "o5b0hrjp3x0b96.v1gxp3", "id": "00000003-0000-0008-0000-000700000002" }, - "team": "00000004-0000-0007-0000-000000000001" + "team": "00000004-0000-0007-0000-000000000001", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_18.json b/libs/wire-api/test/golden/testObject_Contact_user_18.json index b5f25e02fc..5c2357f91b 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_18.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_18.json @@ -7,5 +7,6 @@ "domain": "72n2x7x0.ztb0s51", "id": "00000004-0000-0006-0000-000800000006" }, - "team": "00000001-0000-0002-0000-000000000007" + "team": "00000001-0000-0002-0000-000000000007", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_19.json b/libs/wire-api/test/golden/testObject_Contact_user_19.json index 7cf17bc4f5..799bff0386 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_19.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_19.json @@ -7,5 +7,6 @@ "domain": "h664l.dio6", "id": "00000005-0000-0003-0000-000700000007" }, - "team": "00000006-0000-0004-0000-000000000003" + "team": "00000006-0000-0004-0000-000000000003", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_2.json b/libs/wire-api/test/golden/testObject_Contact_user_2.json index 4ad15e595a..523e300330 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_2.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_2.json @@ -7,5 +7,6 @@ "domain": "z.l--66-i8g8a9", "id": "00000006-0000-0004-0000-000100000007" }, - "team": "00000002-0000-0008-0000-000400000002" + "team": "00000002-0000-0008-0000-000400000002", + "type": "app" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_20.json b/libs/wire-api/test/golden/testObject_Contact_user_20.json index 079817785a..0021c4f0b6 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_20.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_20.json @@ -7,5 +7,6 @@ "domain": "pam223.b6", "id": "00000000-0000-0000-0000-000500000001" }, - "team": null + "team": null, + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_3.json b/libs/wire-api/test/golden/testObject_Contact_user_3.json index e8cb5a2eee..d5a5f47407 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_3.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_3.json @@ -7,5 +7,6 @@ "domain": "h.y-2k71.rh", "id": "00000005-0000-0003-0000-000700000003" }, - "team": "00000006-0000-0005-0000-000700000008" + "team": "00000006-0000-0005-0000-000700000008", + "type": "bot" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_4.json b/libs/wire-api/test/golden/testObject_Contact_user_4.json index 13b1b0c89a..c9f77f4eaa 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_4.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_4.json @@ -7,5 +7,6 @@ "domain": "2347.cye2i7.sn.r2z83.d03", "id": "00000003-0000-0002-0000-000000000004" }, - "team": "00000000-0000-0000-0000-000500000004" + "team": "00000000-0000-0000-0000-000500000004", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_5.json b/libs/wire-api/test/golden/testObject_Contact_user_5.json index 4442242a90..ac359467ef 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_5.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_5.json @@ -7,5 +7,6 @@ "domain": "v0u29n3.er", "id": "00000004-0000-0000-0000-000300000005" }, - "team": null + "team": null, + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_6.json b/libs/wire-api/test/golden/testObject_Contact_user_6.json index 9ca25db0d5..c5a1adbc52 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_6.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_6.json @@ -7,5 +7,6 @@ "domain": "6k.p", "id": "00000003-0000-0001-0000-000400000000" }, - "team": "00000005-0000-0004-0000-000600000000" + "team": "00000005-0000-0004-0000-000600000000", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_7.json b/libs/wire-api/test/golden/testObject_Contact_user_7.json index df0499cc7e..093a117d6f 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_7.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_7.json @@ -7,5 +7,6 @@ "domain": "yr.e1-d", "id": "00000001-0000-0002-0000-000800000008" }, - "team": "00000008-0000-0001-0000-000400000008" + "team": "00000008-0000-0001-0000-000400000008", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_8.json b/libs/wire-api/test/golden/testObject_Contact_user_8.json index 67ad84dfe7..be0997d3be 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_8.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_8.json @@ -7,5 +7,6 @@ "domain": "51r9in-k6i5l8-7y6.t205p-gl2", "id": "00000002-0000-0002-0000-000600000008" }, - "team": "00000001-0000-0007-0000-000500000002" + "team": "00000001-0000-0007-0000-000500000002", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_Contact_user_9.json b/libs/wire-api/test/golden/testObject_Contact_user_9.json index 9318c77233..862db1f6de 100644 --- a/libs/wire-api/test/golden/testObject_Contact_user_9.json +++ b/libs/wire-api/test/golden/testObject_Contact_user_9.json @@ -7,5 +7,6 @@ "domain": "37-p6v67.g", "id": "00000000-0000-0000-0000-000600000008" }, - "team": "00000005-0000-0002-0000-000500000000" + "team": "00000005-0000-0002-0000-000500000000", + "type": "regular" } diff --git a/libs/wire-api/test/golden/testObject_SearchResultContact_1.json b/libs/wire-api/test/golden/testObject_SearchResultContact_1.json index 3dfe76acce..78b27a72f0 100644 --- a/libs/wire-api/test/golden/testObject_SearchResultContact_1.json +++ b/libs/wire-api/test/golden/testObject_SearchResultContact_1.json @@ -9,7 +9,8 @@ "domain": "example.com", "id": "00000018-0000-0020-0000-000e00000002" }, - "team": "00000018-0000-0020-0000-000e00000002" + "team": "00000018-0000-0020-0000-000e00000002", + "type": "regular" }, { "accent_id": null, @@ -20,7 +21,8 @@ "domain": "another.example.com", "id": "00000018-0000-0020-0000-000e00000003" }, - "team": null + "team": null, + "type": "regular" } ], "found": 2, diff --git a/libs/wire-api/test/golden/testObject_SearchResultContact_2.json b/libs/wire-api/test/golden/testObject_SearchResultContact_2.json index 01117c7003..875534f79a 100644 --- a/libs/wire-api/test/golden/testObject_SearchResultContact_2.json +++ b/libs/wire-api/test/golden/testObject_SearchResultContact_2.json @@ -9,7 +9,8 @@ "domain": "example.com", "id": "00000018-0000-0020-0000-000e00000002" }, - "team": "00000018-0000-0020-0000-000e00000002" + "team": "00000018-0000-0020-0000-000e00000002", + "type": "regular" }, { "accent_id": null, @@ -20,7 +21,8 @@ "domain": "another.example.com", "id": "00000018-0000-0020-0000-000e00000003" }, - "team": null + "team": null, + "type": "regular" } ], "found": 2, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_11.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_11.json index e373317287..b05e65f929 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_11.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_11.json @@ -9,7 +9,8 @@ "domain": "bza.j", "id": "00000000-0000-0000-0000-000000000001" }, - "team": null + "team": null, + "type": "regular" }, { "accent_id": 0, @@ -20,7 +21,8 @@ "domain": "zwv.u6-f", "id": "00000001-0000-0000-0000-000000000001" }, - "team": null + "team": null, + "type": "regular" } ], "found": -1, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_13.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_13.json index 01c6c1eee8..1148666947 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_13.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_13.json @@ -9,7 +9,8 @@ "domain": "795n1zf6-he8-97ur4w.o7r---053", "id": "00000000-0000-0001-0000-000000000000" }, - "team": "00000000-0000-0000-0000-000100000000" + "team": "00000000-0000-0000-0000-000100000000", + "type": "regular" }, { "accent_id": 0, @@ -20,7 +21,8 @@ "domain": "v-t6qc.e.so7jqwv", "id": "00000000-0000-0001-0000-000000000000" }, - "team": "00000000-0000-0001-0000-000000000001" + "team": "00000000-0000-0001-0000-000000000001", + "type": "regular" }, { "accent_id": 0, @@ -31,7 +33,8 @@ "domain": "335.a3.p49c--e-fjz337", "id": "00000000-0000-0000-0000-000100000001" }, - "team": "00000000-0000-0001-0000-000000000001" + "team": "00000000-0000-0001-0000-000000000001", + "type": "regular" }, { "accent_id": null, @@ -42,7 +45,8 @@ "domain": "g.g3n", "id": "00000001-0000-0000-0000-000000000000" }, - "team": null + "team": null, + "type": "regular" } ], "found": 3, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_14.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_14.json index 7e80395ae6..daf4f793c8 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_14.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_14.json @@ -9,7 +9,8 @@ "domain": "c00y0ks9-6.q", "id": "00000000-0000-0001-0000-000100000000" }, - "team": "00000000-0000-0000-0000-000000000000" + "team": "00000000-0000-0000-0000-000000000000", + "type": "regular" }, { "accent_id": null, @@ -20,7 +21,8 @@ "domain": "g.44.s3dq77", "id": "00000001-0000-0001-0000-000000000001" }, - "team": null + "team": null, + "type": "regular" } ], "found": 1, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_19.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_19.json index c34194c529..2c656608d4 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_19.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_19.json @@ -9,7 +9,8 @@ "domain": "5de.v-6", "id": "00000000-0000-0001-0000-000100000001" }, - "team": null + "team": null, + "type": "regular" }, { "accent_id": null, @@ -20,7 +21,8 @@ "domain": "z76.kcuxql-9", "id": "00000000-0000-0001-0000-000100000000" }, - "team": "00000000-0000-0000-0000-000000000001" + "team": "00000000-0000-0000-0000-000000000001", + "type": "regular" } ], "found": 4, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_20.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_20.json index 471a9a11c8..f5fe22a975 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_20.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_20.json @@ -9,7 +9,8 @@ "domain": "66h.j", "id": "00000000-0000-0001-0000-000000000000" }, - "team": null + "team": null, + "type": "regular" }, { "accent_id": 0, @@ -20,7 +21,8 @@ "domain": "7s.k881-q-42", "id": "00000000-0000-0000-0000-000100000000" }, - "team": "00000000-0000-0000-0000-000100000001" + "team": "00000000-0000-0000-0000-000100000001", + "type": "regular" }, { "accent_id": 0, @@ -31,7 +33,8 @@ "domain": "1ux.dy", "id": "00000001-0000-0001-0000-000100000001" }, - "team": "00000000-0000-0001-0000-000000000001" + "team": "00000000-0000-0001-0000-000000000001", + "type": "regular" }, { "accent_id": null, @@ -42,7 +45,8 @@ "domain": "o.xi", "id": "00000001-0000-0000-0000-000000000000" }, - "team": null + "team": null, + "type": "regular" }, { "accent_id": null, @@ -53,7 +57,8 @@ "domain": "x5c.v", "id": "00000000-0000-0001-0000-000100000000" }, - "team": "00000001-0000-0000-0000-000000000000" + "team": "00000001-0000-0000-0000-000000000000", + "type": "regular" }, { "accent_id": 0, @@ -64,7 +69,8 @@ "domain": "9p-8z5.i", "id": "00000001-0000-0000-0000-000100000001" }, - "team": "00000001-0000-0001-0000-000000000001" + "team": "00000001-0000-0001-0000-000000000001", + "type": "regular" }, { "accent_id": 0, @@ -75,7 +81,8 @@ "domain": "h1t7.9.j492", "id": "00000000-0000-0000-0000-000100000000" }, - "team": "00000000-0000-0000-0000-000000000001" + "team": "00000000-0000-0000-0000-000000000001", + "type": "regular" }, { "accent_id": 0, @@ -86,7 +93,8 @@ "domain": "p9.y", "id": "00000000-0000-0000-0000-000100000001" }, - "team": null + "team": null, + "type": "regular" }, { "accent_id": null, @@ -97,7 +105,8 @@ "domain": "saz.d0v8", "id": "00000000-0000-0000-0000-000100000001" }, - "team": null + "team": null, + "type": "regular" }, { "accent_id": 0, @@ -108,7 +117,8 @@ "domain": "gpz.28--u.1646.v5", "id": "00000000-0000-0001-0000-000000000000" }, - "team": "00000000-0000-0001-0000-000100000001" + "team": "00000000-0000-0001-0000-000100000001", + "type": "regular" }, { "accent_id": 0, @@ -119,7 +129,8 @@ "domain": "8p.5.x11-s", "id": "00000001-0000-0000-0000-000100000001" }, - "team": "00000000-0000-0001-0000-000100000000" + "team": "00000000-0000-0001-0000-000100000000", + "type": "regular" }, { "accent_id": 0, @@ -130,7 +141,8 @@ "domain": "q4x5z.mwi3", "id": "00000000-0000-0001-0000-000000000001" }, - "team": "00000000-0000-0001-0000-000000000000" + "team": "00000000-0000-0001-0000-000000000000", + "type": "regular" }, { "accent_id": 0, @@ -141,7 +153,8 @@ "domain": "38.b7", "id": "00000000-0000-0000-0000-000000000000" }, - "team": "00000000-0000-0001-0000-000100000000" + "team": "00000000-0000-0001-0000-000100000000", + "type": "regular" } ], "found": 7, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_3.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_3.json index d3a743390b..eb3ce536ab 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_3.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_3.json @@ -9,7 +9,8 @@ "domain": "guh.e", "id": "00000001-0000-0001-0000-000100000000" }, - "team": "00000000-0000-0000-0000-000100000000" + "team": "00000000-0000-0000-0000-000100000000", + "type": "regular" } ], "found": 4, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_4.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_4.json index b635210594..5118eee5c3 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_4.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_4.json @@ -9,7 +9,8 @@ "domain": "2.60--1n1.ds", "id": "00000000-0000-0000-0000-000000000000" }, - "team": "00000001-0000-0000-0000-000100000001" + "team": "00000001-0000-0000-0000-000100000001", + "type": "regular" }, { "accent_id": null, @@ -20,7 +21,8 @@ "domain": "onrg.u", "id": "00000000-0000-0000-0000-000100000001" }, - "team": "00000000-0000-0000-0000-000100000000" + "team": "00000000-0000-0000-0000-000100000000", + "type": "regular" }, { "accent_id": 0, @@ -31,7 +33,8 @@ "domain": "660.v1.8z2.a-4dv.y", "id": "00000001-0000-0000-0000-000000000000" }, - "team": "00000000-0000-0001-0000-000100000001" + "team": "00000000-0000-0001-0000-000100000001", + "type": "regular" }, { "accent_id": null, @@ -42,7 +45,8 @@ "domain": "t102d9m3.tb-dryc9.ws300w5xc4", "id": "00000001-0000-0001-0000-000000000001" }, - "team": null + "team": null, + "type": "regular" }, { "accent_id": 0, @@ -53,7 +57,8 @@ "domain": "54up.l8h-b-g-i.x-c.9-7.we35781l0b", "id": "00000000-0000-0000-0000-000100000000" }, - "team": "00000000-0000-0001-0000-000000000000" + "team": "00000000-0000-0001-0000-000000000000", + "type": "regular" }, { "accent_id": 0, @@ -64,7 +69,8 @@ "domain": "a.h9-1", "id": "00000000-0000-0001-0000-000100000000" }, - "team": "00000000-0000-0000-0000-000000000000" + "team": "00000000-0000-0000-0000-000000000000", + "type": "regular" } ], "found": -5, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_5.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_5.json index c958b20589..318d927d81 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_5.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_5.json @@ -9,7 +9,8 @@ "domain": "1b-y90e265f.l-c", "id": "00000001-0000-0000-0000-000000000001" }, - "team": "00000001-0000-0000-0000-000100000001" + "team": "00000001-0000-0000-0000-000100000001", + "type": "regular" } ], "found": -6, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_7.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_7.json index 4ec4137a7f..a978842e1b 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_7.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_7.json @@ -9,7 +9,8 @@ "domain": "1386---3-nddry.o", "id": "00000001-0000-0000-0000-000000000000" }, - "team": "00000001-0000-0000-0000-000000000001" + "team": "00000001-0000-0000-0000-000000000001", + "type": "regular" }, { "accent_id": 0, @@ -20,7 +21,8 @@ "domain": "j-cz923pu.l6.73-6.qq05n.4ig.dl3", "id": "00000001-0000-0000-0000-000100000001" }, - "team": "00000000-0000-0001-0000-000100000000" + "team": "00000000-0000-0001-0000-000100000000", + "type": "regular" } ], "found": 7, diff --git a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_8.json b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_8.json index e2881a4de6..302b38265d 100644 --- a/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_8.json +++ b/libs/wire-api/test/golden/testObject_SearchResult_20Contact_user_8.json @@ -9,7 +9,8 @@ "domain": "6n.n08ejr-a", "id": "00000001-0000-0001-0000-000100000001" }, - "team": "00000000-0000-0001-0000-000100000000" + "team": "00000000-0000-0001-0000-000100000000", + "type": "regular" } ], "found": -7, diff --git a/libs/wire-api/test/unit/Test/Wire/API/User.hs b/libs/wire-api/test/unit/Test/Wire/API/User.hs index 11ce3d914e..684a5f9fb8 100644 --- a/libs/wire-api/test/unit/Test/Wire/API/User.hs +++ b/libs/wire-api/test/unit/Test/Wire/API/User.hs @@ -63,7 +63,7 @@ testEmailVisibleToSelf :: TestTree testEmailVisibleToSelf = testProperty "should not contain email when email visibility is EmailVisibleToSelf" $ \user lhStatus -> - let profile = mkUserProfile EmailVisibleToSelf user lhStatus + let profile = mkUserProfile EmailVisibleToSelf UserTypeRegular user lhStatus in profileEmail profile === Nothing .&&. profileLegalholdStatus profile === lhStatus @@ -71,7 +71,7 @@ testEmailVisibleIfOnTeam :: TestTree testEmailVisibleIfOnTeam = testProperty "should contain email only if the user has one and is part of a team when email visibility is EmailVisibleIfOnTeam" $ \user lhStatus -> - let profile = mkUserProfile EmailVisibleIfOnTeam user lhStatus + let profile = mkUserProfile EmailVisibleIfOnTeam UserTypeRegular user lhStatus in (profileEmail profile === (userTeam user *> userEmail user)) .&&. profileLegalholdStatus profile === lhStatus @@ -81,13 +81,13 @@ testEmailVisibleIfOnSameTeam = where testNoViewerTeam = testProperty "should not contain email when viewer is not part of a team" $ \user lhStatus -> - let profile = mkUserProfile (EmailVisibleIfOnSameTeam Nothing) user lhStatus + let profile = mkUserProfile (EmailVisibleIfOnSameTeam Nothing) UserTypeRegular user lhStatus in (profileEmail profile === Nothing) .&&. profileLegalholdStatus profile === lhStatus testViewerDifferentTeam = testProperty "should not contain email when viewer is not part of the same team" $ \viewerTeamId viewerMembership user lhStatus -> - let profile = mkUserProfile (EmailVisibleIfOnSameTeam (Just (viewerTeamId, viewerMembership))) user lhStatus + let profile = mkUserProfile (EmailVisibleIfOnSameTeam (Just (viewerTeamId, viewerMembership))) UserTypeRegular user lhStatus in Just viewerTeamId /= userTeam user ==> ( profileEmail profile === Nothing .&&. profileLegalholdStatus profile === lhStatus @@ -97,7 +97,7 @@ testEmailVisibleIfOnSameTeam = \viewerTeamId (viewerMembershipNoRole :: TeamMember) userNoTeam lhStatus -> let user = userNoTeam {userTeam = Just viewerTeamId} viewerMembership = viewerMembershipNoRole & TeamMember.permissions .~ TeamMember.rolePermissions RoleExternalPartner - profile = mkUserProfile (EmailVisibleIfOnSameTeam (Just (viewerTeamId, viewerMembership))) user lhStatus + profile = mkUserProfile (EmailVisibleIfOnSameTeam (Just (viewerTeamId, viewerMembership))) UserTypeRegular user lhStatus in ( profileEmail profile === Nothing .&&. profileLegalholdStatus profile === lhStatus ) @@ -106,7 +106,7 @@ testEmailVisibleIfOnSameTeam = \viewerTeamId (viewerMembershipNoRole :: TeamMember) viewerRole userNoTeam lhStatus -> let user = userNoTeam {userTeam = Just viewerTeamId} viewerMembership = viewerMembershipNoRole & TeamMember.permissions .~ TeamMember.rolePermissions viewerRole - profile = mkUserProfile (EmailVisibleIfOnSameTeam (Just (viewerTeamId, viewerMembership))) user lhStatus + profile = mkUserProfile (EmailVisibleIfOnSameTeam (Just (viewerTeamId, viewerMembership))) UserTypeRegular user lhStatus in viewerRole /= RoleExternalPartner ==> ( profileEmail profile === userEmail user .&&. profileLegalholdStatus profile === lhStatus diff --git a/libs/wire-subsystems/src/Wire/IndexedUserStore/Bulk/ElasticSearch.hs b/libs/wire-subsystems/src/Wire/IndexedUserStore/Bulk/ElasticSearch.hs index 84c137d9c3..e5585735bd 100644 --- a/libs/wire-subsystems/src/Wire/IndexedUserStore/Bulk/ElasticSearch.hs +++ b/libs/wire-subsystems/src/Wire/IndexedUserStore/Bulk/ElasticSearch.hs @@ -34,6 +34,7 @@ import System.Logger.Message qualified as Log import Wire.API.Team.Feature import Wire.API.Team.Member.Info import Wire.API.Team.Role +import Wire.API.User import Wire.GalleyAPIAccess import Wire.IndexedUserStore (IndexedUserStore) import Wire.IndexedUserStore qualified as IndexedUserStore @@ -108,15 +109,29 @@ syncAllUsersWithVersion mkVersion = mkUserDocs :: ConduitT [IndexUser] [(ES.DocId, UserDoc, ES.VersionControl)] (Sem r) () mkUserDocs = Conduit.mapM $ \page -> do + -- FUTUREWORK: extract team visibilities, roles and user type + -- more efficiently sending one query per page + + -- FUTUREWORK: introduce type ExtendedUser (or something), which + -- contains User, Maybe Role, UserType, ..., and pass around + -- ExtendedUser. this should make the code less convoluted. + let teams :: Map TeamId [IndexUser] = Map.fromListWith (<>) $ mapMaybe (\u -> (,[u]) . value <$> u.teamId) page teamIds = Map.keys teams visMap <- fmap Map.fromList . unsafePooledForConcurrentlyN 16 teamIds $ \t -> (t,) <$> teamSearchVisibilityInbound t + userTypes :: Map UserId UserType <- fmap Map.fromList . unsafePooledForConcurrentlyN 16 page $ \iu -> + (iu.userId,) <$> getUserType iu roles :: Map UserId (WithWritetime Role) <- fmap (Map.fromList . concat) . unsafePooledForConcurrentlyN 16 (Map.toList teams) $ \(t, us) -> do tms <- (.members) <$> selectTeamMemberInfos t (fmap (.userId) us) pure $ mapMaybe mkRoleWithWriteTime tms let vis indexUser = fromMaybe defaultSearchVisibilityInbound $ (flip Map.lookup visMap . value =<< indexUser.teamId) - mkUserDoc indexUser = indexUserToDoc (vis indexUser) ((.value) <$> Map.lookup indexUser.userId roles) indexUser + mkUserDoc indexUser = + indexUserToDoc + (vis indexUser) + (Map.lookup indexUser.userId userTypes) + ((.value) <$> Map.lookup indexUser.userId roles) + indexUser mkDocVersion u = mkVersion . ES.ExternalDocVersion . docVersion $ indexUserToVersion (Map.lookup u.userId roles) u pure $ map (\u -> (userIdToDocId u.userId, mkUserDoc u, mkDocVersion u)) page @@ -165,3 +180,22 @@ teamSearchVisibilityInbound :: (Member GalleyAPIAccess r) => TeamId -> Sem r Sea teamSearchVisibilityInbound tid = searchVisibilityInboundFromFeatureStatus . (.status) <$> getFeatureConfigForTeam @_ @SearchVisibilityInboundConfig tid + +-- | FUTUREWORK: this is duplicated code from UserSubsystem, we should +-- probably expose it as an action there. +getUserType :: + forall r. + IndexUser -> + Sem r UserType +getUserType iu = case iu.serviceId of + Just _ -> pure UserTypeBot + Nothing -> do + {- + FUTUREWORK: *correct* type fields from search are coming in a separate PR: + + mmApp <- mapM (getApp iu.userId) (iu.teamId <&> (.value)) + case join mmApp of + Just _ -> pure UserTypeApp + Nothing -> pure UserTypeRegular + -} + pure UserTypeRegular diff --git a/libs/wire-subsystems/src/Wire/UserSearch/Types.hs b/libs/wire-subsystems/src/Wire/UserSearch/Types.hs index 317a309def..28b766f0db 100644 --- a/libs/wire-subsystems/src/Wire/UserSearch/Types.hs +++ b/libs/wire-subsystems/src/Wire/UserSearch/Types.hs @@ -29,6 +29,7 @@ import Data.ByteString.Lazy import Data.Handle import Data.Id import Data.Json.Util +import Data.Qualified import Data.Text.Encoding import Database.Bloodhound.Types import Imports @@ -61,6 +62,7 @@ mkIndexVersion writetimes = -- consequently removed from the index. data UserDoc = UserDoc { udId :: UserId, + udType :: Maybe UserType, udTeam :: Maybe TeamId, udName :: Maybe Name, udNormalized :: Maybe Text, @@ -85,6 +87,7 @@ instance ToJSON UserDoc where toJSON ud = object [ "id" .= udId ud, + "type" .= udType ud, "team" .= udTeam ud, "name" .= udName ud, "normalized" .= udNormalized ud, @@ -107,6 +110,7 @@ instance FromJSON UserDoc where parseJSON = withObject "UserDoc" $ \o -> UserDoc <$> o .: "id" + <*> o .:? "type" <*> o .:? "team" <*> o .:? "name" <*> o .:? "normalized" @@ -127,6 +131,27 @@ instance FromJSON UserDoc where searchVisibilityInboundFieldName :: Key searchVisibilityInboundFieldName = "search_visibility_inbound" +-- Qualified UserId is not included in `UserDoc`, so it needs to be +-- provided here. Monad will most likely be Identity (I promise we'll +-- always make up some name if missing) or Maybe (if no name, then no +-- contact). +userDocToContact :: (Monad m) => Qualified UserId -> (Maybe Name -> m Text) -> UserDoc -> m Contact +userDocToContact contactQualifiedId getName userDoc = + getName userDoc.udName <&> \name -> + Contact + { contactQualifiedId, + contactName = name, + contactColorId = fromIntegral . fromColourId <$> userDoc.udColourId, + contactHandle = fromHandle <$> userDoc.udHandle, + contactTeam = userDoc.udTeam, + contactType = + -- NB: after wire release upgrade and before ES reindexing, + -- apps may identify as regular users in the search result. + -- this is an accepted limitation and will be fixed in + -- https://github.com/wireapp/wire-server/pull/4947 + fromMaybe UserTypeRegular userDoc.udType + } + userDocToTeamContact :: [UserGroupId] -> UserDoc -> TeamContact userDocToTeamContact userGroups UserDoc {..} = TeamContact diff --git a/libs/wire-subsystems/src/Wire/UserStore/IndexUser.hs b/libs/wire-subsystems/src/Wire/UserStore/IndexUser.hs index b833bbfaad..824fe49e24 100644 --- a/libs/wire-subsystems/src/Wire/UserStore/IndexUser.hs +++ b/libs/wire-subsystems/src/Wire/UserStore/IndexUser.hs @@ -149,12 +149,14 @@ indexUserToVersion role IndexUser {..} = const () <$$> writeTimeBumper ] -indexUserToDoc :: SearchVisibilityInbound -> Maybe Role -> IndexUser -> UserDoc -indexUserToDoc searchVisInbound mRole IndexUser {..} = +indexUserToDoc :: SearchVisibilityInbound -> Maybe UserType -> Maybe Role -> IndexUser -> UserDoc +indexUserToDoc searchVisInbound mUserType mRole IndexUser {..} = if shouldIndex then UserDoc - { udSearchable = value <$> searchable, + { udId = userId, + udType = mUserType, + udSearchable = value <$> searchable, udEmailUnvalidated = value <$> unverifiedEmail, udSso = sso . value =<< ssoId, udScimExternalId = join $ scimExternalId <$> (value <$> managedBy) <*> (value <$> ssoId), @@ -169,8 +171,7 @@ indexUserToDoc searchVisInbound mRole IndexUser {..} = udHandle = value <$> handle, udNormalized = Just $ normalized name.value.fromName, udName = Just name.value, - udTeam = value <$> teamId, - udId = userId + udTeam = value <$> teamId } else -- We insert a tombstone-style user here, as it's easier than -- deleting the old one. It's mostly empty, but having the status here @@ -214,7 +215,8 @@ normalized = transliterate (trans "Any-Latin; Latin-ASCII; Lower") emptyUserDoc :: UserId -> UserDoc emptyUserDoc uid = UserDoc - { udSearchable = Nothing, + { udType = Nothing, + udSearchable = Nothing, udEmailUnvalidated = Nothing, udSso = Nothing, udScimExternalId = Nothing, diff --git a/libs/wire-subsystems/src/Wire/UserSubsystem/Interpreter.hs b/libs/wire-subsystems/src/Wire/UserSubsystem/Interpreter.hs index 86be662b3c..c6524d8e6b 100644 --- a/libs/wire-subsystems/src/Wire/UserSubsystem/Interpreter.hs +++ b/libs/wire-subsystems/src/Wire/UserSubsystem/Interpreter.hs @@ -451,13 +451,11 @@ getLocalUserProfileImpl emailVisibilityConfigWithViewer luid = do lhs :: UserLegalHoldStatus <- do teamMember <- lift $ join <$> (internalGetTeamMember storedUser.id `mapM` storedUser.teamId) pure $ maybe defUserLegalHoldStatus (view legalHoldStatus) teamMember + userType <- lift $ getUserType storedUser.id storedUser.teamId storedUser.serviceId let user = mkUserFromStored domain locale storedUser - usrProfile = mkUserProfile emailVisibilityConfigWithViewer user lhs - app <- lift $ mapM (getApp storedUser.id) storedUser.teamId + usrProfile = mkUserProfile emailVisibilityConfigWithViewer userType user lhs lift $ deleteLocalIfExpired user - pure $ case join app of - Nothing -> usrProfile - Just _ -> usrProfile {profileType = UserTypeApp} + pure $ usrProfile getSelfProfileImpl :: ( Member (Input UserSubsystemConfig) r, @@ -578,6 +576,7 @@ guardLockedHandleField user updateOrigin handle = do updateUserProfileImpl :: ( Member UserStore r, + Member AppStore r, Member (Error UserSubsystemError) r, Member Events r, Member GalleyAPIAccess r, @@ -642,6 +641,7 @@ updateHandleImpl :: Member GalleyAPIAccess r, Member Events r, Member UserStore r, + Member AppStore r, Member IndexedUserStore r, Member Metrics r ) => @@ -708,13 +708,14 @@ checkHandlesImpl check num = reverse <$> collectFree [] check num syncUserIndex :: forall r. ( Member UserStore r, + Member AppStore r, Member GalleyAPIAccess r, Member IndexedUserStore r, Member Metrics r ) => UserId -> Sem r () -syncUserIndex uid = do +syncUserIndex uid = getIndexUser uid >>= maybe deleteFromIndex upsert where @@ -731,8 +732,9 @@ syncUserIndex uid = do (teamSearchVisibilityInbound . value) indexUser.teamId tm <- maybe (pure Nothing) (selectTeamMember . value) indexUser.teamId + userType <- getUserType indexUser.userId (indexUser.teamId <&> (.value)) (indexUser.serviceId <&> (.value)) let mRole = tm >>= mkRoleWithWriteTime - userDoc = indexUserToDoc vis (value <$> mRole) indexUser + userDoc = indexUserToDoc vis (Just userType) (value <$> mRole) indexUser version = ES.ExternalGT . ES.ExternalDocVersion . docVersion $ indexUserToVersion mRole indexUser Metrics.incCounter indexUpdateCounter IndexedUserStore.upsert (userIdToDocId uid) userDoc version @@ -760,6 +762,7 @@ searchUsersImpl :: forall r fedM. ( Member UserStore r, Member GalleyAPIAccess r, + Member AppStore r, Member (Error UserSubsystemError) r, Member IndexedUserStore r, Member FederationConfigStore r, @@ -795,6 +798,7 @@ searchUsersImpl searcherId searchTerm maybeDomain maybeMaxResults = do searchLocally :: forall r. ( Member GalleyAPIAccess r, + Member AppStore r, Member UserStore r, Member IndexedUserStore r, Member (Input UserSubsystemConfig) r @@ -823,7 +827,7 @@ searchLocally searcher searchTerm maybeMaxResults = do esMaxResults else pure $ SearchResult 0 0 0 [] FullSearch Nothing Nothing - let esContacts = map userDocToContact (searchResults esResult) + let esContacts = map userDocToContact' (searchResults esResult) -- Prepend results matching exact handle and results from ES. allContacts = case maybeExactHandleMatch of Nothing -> esContacts @@ -839,15 +843,13 @@ searchLocally searcher searchTerm maybeMaxResults = do handleTeamVisibility _ SearchVisibilityStandard = AllUsers handleTeamVisibility t SearchVisibilityNoNameOutsideTeam = TeamOnly t - userDocToContact :: UserDoc -> Contact - userDocToContact userDoc = - Contact - { contactQualifiedId = tUntagged $ qualifyAs searcher userDoc.udId, - contactName = maybe "" fromName userDoc.udName, - contactColorId = fromIntegral . fromColourId <$> userDoc.udColourId, - contactHandle = Handle.fromHandle <$> userDoc.udHandle, - contactTeam = userDoc.udTeam - } + userDocToContact' :: UserDoc -> Contact + userDocToContact' userDoc = + runIdentity $ + userDocToContact + (tUntagged $ qualifyAs searcher userDoc.udId) + (Identity . maybe "" fromName) + userDoc mkTeamSearchInfo :: Maybe TeamId -> Sem r TeamSearchInfo mkTeamSearchInfo searcherTeamId = do @@ -864,27 +866,26 @@ searchLocally searcher searchTerm maybeMaxResults = do exactHandleSearch :: Sem r (Maybe Contact) exactHandleSearch = runMaybeT $ do - handle <- MaybeT . pure $ Handle.parseHandle searchTerm + handle <- hoistMaybe $ Handle.parseHandle searchTerm owner <- MaybeT $ UserStore.lookupHandle handle storedUser <- MaybeT $ UserStore.getUser owner config <- lift input - let contact = contactFromStoredUser (tDomain searcher) storedUser - isContactVisible = + let isContactVisible = (config.searchSameTeamOnly && (snd . tUnqualified $ searcher) == storedUser.teamId) || (not config.searchSameTeamOnly) if isContactVisible && fromMaybe True storedUser.searchable - then pure contact - else MaybeT $ pure Nothing - - contactFromStoredUser :: Domain -> StoredUser -> Contact - contactFromStoredUser domain storedUser = - Contact - { contactQualifiedId = Qualified storedUser.id domain, - contactName = fromName storedUser.name, - contactHandle = Handle.fromHandle <$> storedUser.handle, - contactColorId = Just . fromIntegral . fromColourId $ storedUser.accentId, - contactTeam = storedUser.teamId - } + then do + userType <- lift $ getUserType storedUser.id storedUser.teamId storedUser.serviceId + pure $ + Contact + { contactQualifiedId = Qualified storedUser.id (tDomain searcher), + contactName = fromName storedUser.name, + contactHandle = Handle.fromHandle <$> storedUser.handle, + contactColorId = Just . fromIntegral . fromColourId $ storedUser.accentId, + contactTeam = storedUser.teamId, + contactType = userType + } + else hoistMaybe Nothing searchRemotely :: ( Member FederationConfigStore r, @@ -1053,6 +1054,7 @@ getAccountsByImpl (tSplit -> (domain, GetBy {includePendingInvitations, getByHan acceptTeamInvitationImpl :: ( Member (Input UserSubsystemConfig) r, Member UserStore r, + Member AppStore r, Member GalleyAPIAccess r, Member (Error UserSubsystemError) r, Member InvitationStore r, @@ -1117,6 +1119,7 @@ getUserExportDataImpl uid = fmap hush . runError @() $ do removeEmailEitherImpl :: ( Member UserKeyStore r, Member UserStore r, + Member AppStore r, Member Events r, Member IndexedUserStore r, Member (Input UserSubsystemConfig) r, @@ -1151,6 +1154,7 @@ checkUserIsAdminImpl uid = do setUserSearchableImpl :: ( Member UserStore r, + Member AppStore r, Member (Error UserSubsystemError) r, Member TeamSubsystem r, Member GalleyAPIAccess r, @@ -1166,3 +1170,20 @@ setUserSearchableImpl luid uid searchable = do ensurePermissions (tUnqualified luid) tid [SetMemberSearchable] UserStore.setUserSearchable uid searchable syncUserIndex uid + +-- * Helpers + +getUserType :: + forall r. + (Member AppStore r) => + UserId -> + Maybe TeamId -> + Maybe ServiceId -> + Sem r UserType +getUserType uid mTid mbServiceId = case mbServiceId of + Just _ -> pure UserTypeBot + Nothing -> do + mmApp <- mapM (getApp uid) mTid + case join mmApp of + Just _ -> pure UserTypeApp + Nothing -> pure UserTypeRegular diff --git a/libs/wire-subsystems/test/unit/Wire/AuthenticationSubsystem/InterpreterSpec.hs b/libs/wire-subsystems/test/unit/Wire/AuthenticationSubsystem/InterpreterSpec.hs index 1ff35582da..dfb4329076 100644 --- a/libs/wire-subsystems/test/unit/Wire/AuthenticationSubsystem/InterpreterSpec.hs +++ b/libs/wire-subsystems/test/unit/Wire/AuthenticationSubsystem/InterpreterSpec.hs @@ -42,6 +42,7 @@ import Wire.API.User import Wire.API.User qualified as User import Wire.API.User.Auth import Wire.API.User.Password +import Wire.AppStore import Wire.AuthenticationSubsystem import Wire.AuthenticationSubsystem.Config import Wire.AuthenticationSubsystem.Interpreter @@ -81,7 +82,8 @@ type AllEffects = EmailSubsystem, UserStore, State [StoredUser], - State (Map EmailAddress [SentMail]) + State (Map EmailAddress [SentMail]), + State [StoredApp] ] runAllEffects :: Domain -> [User] -> Maybe [Text] -> Sem AllEffects a -> Either AuthenticationSubsystemError a @@ -92,6 +94,7 @@ runAllEffects localDomain preexistingUsers mAllowedEmailDomains = local = toLocalUnsafe localDomain () } in run + . evalState mempty . evalState mempty . evalState mempty . inMemoryUserStoreInterpreter diff --git a/libs/wire-subsystems/test/unit/Wire/MiniBackend.hs b/libs/wire-subsystems/test/unit/Wire/MiniBackend.hs index 204fc5ed73..fbd01bdd5b 100644 --- a/libs/wire-subsystems/test/unit/Wire/MiniBackend.hs +++ b/libs/wire-subsystems/test/unit/Wire/MiniBackend.hs @@ -522,10 +522,17 @@ miniGetAllProfiles :: Sem r [UserProfile] miniGetAllProfiles = do users <- gets (.users) + apps <- gets (.apps) dom <- input pure $ map - (\u -> mkUserProfileWithEmail Nothing (mkUserFromStored dom miniLocale u) defUserLegalHoldStatus) + ( \u -> + let userType + | any ((== u.id) . (.id)) apps = UserTypeApp + | isJust u.serviceId = UserTypeBot + | otherwise = UserTypeRegular + in mkUserProfileWithEmail Nothing userType (mkUserFromStored dom miniLocale u) defUserLegalHoldStatus + ) users miniGetUsersByIds :: [UserId] -> MiniFederationMonad 'Brig [UserProfile] diff --git a/libs/wire-subsystems/test/unit/Wire/MockInterpreters/IndexedUserStore.hs b/libs/wire-subsystems/test/unit/Wire/MockInterpreters/IndexedUserStore.hs index 85b27a86b3..f481ed7367 100644 --- a/libs/wire-subsystems/test/unit/Wire/MockInterpreters/IndexedUserStore.hs +++ b/libs/wire-subsystems/test/unit/Wire/MockInterpreters/IndexedUserStore.hs @@ -30,10 +30,7 @@ import Polysemy.State import Wire.API.Team.Size import Wire.API.User.Search import Wire.IndexedUserStore -import Wire.MockInterpreters.UserStore (storedUserToIndexUser) -import Wire.StoredUser import Wire.UserSearch.Types -import Wire.UserStore.IndexUser newtype OrdDocId = OrdDocId Text deriving (Show, Eq, Ord) @@ -54,17 +51,6 @@ emptyIndex = docs = mempty } -storedUserToDoc :: StoredUser -> UserDoc -storedUserToDoc user = - let indexUser = storedUserToIndexUser user - in indexUserToDoc defaultSearchVisibilityInbound Nothing indexUser - -indexFromStoredUsers :: [StoredUser] -> UserIndex -indexFromStoredUsers storedUsers = do - run . execState emptyIndex . inMemoryIndexedUserStoreInterpreter $ do - for_ storedUsers $ \storedUser -> - upsert (userIdToDocId storedUser.id) (storedUserToDoc storedUser) ES.NoVersionControl - runInMemoryIndexedUserStoreIntepreter :: InterpreterFor IndexedUserStore r runInMemoryIndexedUserStoreIntepreter = evalState emptyIndex diff --git a/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserStore.hs b/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserStore.hs index 391e8305d1..6e2086242c 100644 --- a/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserStore.hs +++ b/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserStore.hs @@ -63,8 +63,9 @@ inMemoryUserStoreInterpreter = interpret $ \case if u.id == uid then u {emailUnvalidated = Just email} :: StoredUser else u - GetIndexUser uid -> - gets $ fmap storedUserToIndexUser . find (\user -> user.id == uid) + GetIndexUser uid -> do + mUser <- gets @[StoredUser] $ find (\user -> user.id == uid) + pure $ storedUserToIndexUser <$> mUser GetIndexUsersPaginated _pageSize _pagingState -> error "GetIndexUsersPaginated not implemented in inMemoryUserStoreInterpreter" UpdateUserHandleEither uid hUpdate -> runError $ modifyLocalUsers (traverse doUpdate) @@ -72,7 +73,7 @@ inMemoryUserStoreInterpreter = interpret $ \case doUpdate :: StoredUser -> Sem (Error StoredUserUpdateError : r) StoredUser doUpdate u | u.id == uid = do - handles <- gets $ mapMaybe (.handle) + handles <- gets @[StoredUser] $ mapMaybe (.handle) when ( hUpdate.old /= Just hUpdate.new @@ -87,7 +88,7 @@ inMemoryUserStoreInterpreter = interpret $ \case us <- get us' <- f us put us' - DeleteUser user -> modify $ filter (\u -> u.id /= User.userId user) + DeleteUser user -> modify @[StoredUser] $ filter (\u -> u.id /= User.userId user) LookupHandle h -> lookupHandleImpl h GlimpseHandle h -> lookupHandleImpl h LookupStatus uid -> lookupStatusImpl uid @@ -105,7 +106,7 @@ inMemoryUserStoreInterpreter = interpret $ \case doUpdate :: StoredUser -> StoredUser doUpdate u = if u.id == uid then u {email = Nothing} else u GetUserTeam uid -> do - gets $ \users -> do + gets @[StoredUser] $ \users -> do user <- find (\user -> user.id == uid) users user.teamId SetUserSearchable uid (SetSearchable searchable) -> modify $ map f diff --git a/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserSubsystem.hs b/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserSubsystem.hs index 71dc964440..fe979c1cf1 100644 --- a/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserSubsystem.hs +++ b/libs/wire-subsystems/test/unit/Wire/MockInterpreters/UserSubsystem.hs @@ -69,4 +69,4 @@ userSubsystemTestInterpreter initialUsers = SetUserSearchable {} -> error "SetUserSearchable: implement on demand (userSubsystemInterpreter)" toProfile :: User -> UserProfile -toProfile u = mkUserProfileWithEmail (userEmail u) u UserLegalHoldDisabled +toProfile u = mkUserProfileWithEmail (userEmail u) UserTypeRegular u UserLegalHoldDisabled diff --git a/libs/wire-subsystems/test/unit/Wire/UserSearch/TypesSpec.hs b/libs/wire-subsystems/test/unit/Wire/UserSearch/TypesSpec.hs index 4fae73f196..a09d56bd8f 100644 --- a/libs/wire-subsystems/test/unit/Wire/UserSearch/TypesSpec.hs +++ b/libs/wire-subsystems/test/unit/Wire/UserSearch/TypesSpec.hs @@ -64,7 +64,8 @@ userDoc1 = udScimExternalId = Nothing, udSso = Nothing, udEmailUnvalidated = Nothing, - udSearchable = Nothing + udSearchable = Nothing, + udType = Nothing } -- Dont touch this. This represents serialized legacy data. diff --git a/libs/wire-subsystems/test/unit/Wire/UserSubsystem/InterpreterSpec.hs b/libs/wire-subsystems/test/unit/Wire/UserSubsystem/InterpreterSpec.hs index edfb8af1f8..3c93c88d4d 100644 --- a/libs/wire-subsystems/test/unit/Wire/UserSubsystem/InterpreterSpec.hs +++ b/libs/wire-subsystems/test/unit/Wire/UserSubsystem/InterpreterSpec.hs @@ -38,6 +38,7 @@ import Data.Set (insert, member, notMember) import Data.Set qualified as S import Data.String.Conversions (cs) import Data.Text.Encoding (encodeUtf8) +import Database.Bloodhound.Internal.Client qualified as ES import Imports import Polysemy import Polysemy.Error @@ -60,6 +61,7 @@ import Wire.API.User.Search import Wire.API.UserEvent import Wire.AuthenticationSubsystem.Error import Wire.DomainRegistrationStore qualified as DRS +import Wire.IndexedUserStore qualified as IU import Wire.InvitationStore (InsertInvitation, StoredInvitation) import Wire.InvitationStore qualified as InvitationStore import Wire.MiniBackend @@ -67,6 +69,8 @@ import Wire.MockInterpreters import Wire.RateLimit import Wire.StoredUser import Wire.UserKeyStore +import Wire.UserSearch.Types +import Wire.UserStore.IndexUser import Wire.UserSubsystem import Wire.UserSubsystem.Error import Wire.UserSubsystem.HandleBlacklist @@ -100,6 +104,7 @@ spec = describe "UserSubsystem.Interpreter" do mkExpectedProfiles domain users = [ mkUserProfileWithEmail Nothing + (if isJust targetUser.serviceId then UserTypeBot else UserTypeRegular) (mkUserFromStored domain miniLocale targetUser) defUserLegalHoldStatus | targetUser <- users @@ -159,6 +164,7 @@ spec = describe "UserSubsystem.Interpreter" do in retrievedProfiles === [ mkUserProfile (fmap (const $ (,) <$> viewer.teamId <*> Just teamMember) config.emailVisibilityConfig) + (if isJust targetUser.serviceId then UserTypeBot else UserTypeRegular) (mkUserFromStored domain config.defaultLocale targetUser) defUserLegalHoldStatus ] @@ -175,6 +181,7 @@ spec = describe "UserSubsystem.Interpreter" do in retrievedProfile === [ mkUserProfile (fmap (const Nothing) config.emailVisibilityConfig) + (if isJust targetUser.serviceId then UserTypeBot else UserTypeRegular) (mkUserFromStored domain config.defaultLocale targetUser) defUserLegalHoldStatus ] @@ -1091,6 +1098,19 @@ spec = describe "UserSubsystem.Interpreter" do \(ActiveStoredUser searcheeNoHandle) (searcheeHandle :: Handle) (ActiveStoredUser searcher) localDomain configBase -> let teamMember = mkTeamMember searcher.id fullPermissions Nothing defUserLegalHoldStatus searchee = searcheeNoHandle {handle = Just searcheeHandle} :: StoredUser + + storedUserToDoc :: StoredUser -> UserDoc + storedUserToDoc user = + let indexUser = storedUserToIndexUser user + userType = if isJust user.serviceId then UserTypeBot else UserTypeRegular + in indexUserToDoc defaultSearchVisibilityInbound (Just userType) Nothing indexUser + + indexFromStoredUsers :: [StoredUser] -> UserIndex + indexFromStoredUsers storedUsers = do + run . execState emptyIndex . inMemoryIndexedUserStoreInterpreter $ do + for_ storedUsers $ \storedUser -> + IU.upsert (userIdToDocId storedUser.id) (storedUserToDoc storedUser) ES.NoVersionControl + localBackend = def { users = [searchee, searcher], @@ -1111,6 +1131,7 @@ spec = describe "UserSubsystem.Interpreter" do contactQualifiedId = Qualified searchee.id localDomain, contactName = fromName searchee.name, contactHandle = fromHandle <$> searchee.handle, - contactColorId = Just . fromIntegral $ searchee.accentId.fromColourId + contactColorId = Just . fromIntegral $ searchee.accentId.fromColourId, + contactType = UserTypeRegular } pure $ result.searchResults === [expectedContact | fromMaybe True searchee.searchable] diff --git a/postgres-schema.sql b/postgres-schema.sql index 378195989b..8cfc62bd5d 100644 --- a/postgres-schema.sql +++ b/postgres-schema.sql @@ -9,8 +9,8 @@ \restrict 79bbfb4630959c48307653a5cd3d83f2582b3c2210f75f10d79e3ebf0015620 --- Dumped from database version 17.6 --- Dumped by pg_dump version 17.6 +-- Dumped from database version 17.7 +-- Dumped by pg_dump version 17.7 SET statement_timeout = 0; SET lock_timeout = 0; diff --git a/services/brig/src/Brig/Index/Eval.hs b/services/brig/src/Brig/Index/Eval.hs index dbc6a74f95..ad58b6d53f 100644 --- a/services/brig/src/Brig/Index/Eval.hs +++ b/services/brig/src/Brig/Index/Eval.hs @@ -39,6 +39,7 @@ import Data.Credentials (Credentials (..)) import Data.Id import Database.Bloodhound qualified as ES import Database.Bloodhound.Internal.Client (BHEnv (..)) +import Hasql.Pool import Imports import Polysemy import Polysemy.Embed (runEmbedded) @@ -46,7 +47,7 @@ import Polysemy.Error import Polysemy.TinyLog hiding (Logger) import System.Logger qualified as Log import System.Logger.Class (Logger) -import Util.Options (initCredentials) +import Util.Options import Wire.API.Federation.Client (FederatorClient) import Wire.API.Federation.Error import Wire.BlockListStore (BlockListStore) @@ -97,6 +98,7 @@ type BrigIndexEffectStack = Metrics, TinyLog, Concurrency 'Unsafe, + Error UsageError, Embed IO, Final IO ] @@ -125,6 +127,7 @@ runSem esConn cas galleyEndpoint logger action = do migrationIndexName = fromMaybe defaultMigrationIndexName (esMigrationIndexName esConn) runFinal . embedToFinal + . throwErrorToIOFinal @UsageError . unsafelyPerformConcurrency . loggerToTinyLogReqId reqId logger . ignoreMetrics diff --git a/services/brig/src/Brig/Provider/API.hs b/services/brig/src/Brig/Provider/API.hs index 603aeaa5e4..86c7ffb13e 100644 --- a/services/brig/src/Brig/Provider/API.hs +++ b/services/brig/src/Brig/Provider/API.hs @@ -898,7 +898,7 @@ guardConvAdmin conv = do botGetSelf :: BotId -> (Handler r) Public.UserProfile botGetSelf bot = do p <- lift $ wrapClient $ User.lookupUser NoPendingInvitations (botUserId bot) - maybe (throwStd (errorToWai @'E.UserNotFound)) (\u -> pure $ Public.mkUserProfile EmailVisibleToSelf u UserLegalHoldNoConsent) p + maybe (throwStd (errorToWai @'E.UserNotFound)) (\u -> pure $ Public.mkUserProfile EmailVisibleToSelf UserTypeBot u UserLegalHoldNoConsent) p botGetClient :: (Member GalleyAPIAccess r) => BotId -> (Handler r) (Maybe Public.Client) botGetClient bot = do diff --git a/services/brig/src/Brig/User/API/Handle.hs b/services/brig/src/Brig/User/API/Handle.hs index 0b97637255..ecad744a94 100644 --- a/services/brig/src/Brig/User/API/Handle.hs +++ b/services/brig/src/Brig/User/API/Handle.hs @@ -101,5 +101,6 @@ contactFromProfile profile = contactName = fromName $ profileName profile, contactHandle = fromHandle <$> profileHandle profile, contactColorId = Just . fromIntegral . fromColourId $ profileAccentId profile, - contactTeam = profileTeam profile + contactTeam = profileTeam profile, + contactType = profileType profile } diff --git a/services/brig/src/Brig/User/Search/Index.hs b/services/brig/src/Brig/User/Search/Index.hs index 634f059559..4c4919729d 100644 --- a/services/brig/src/Brig/User/Search/Index.hs +++ b/services/brig/src/Brig/User/Search/Index.hs @@ -466,6 +466,14 @@ indexMapping = mpIndex = True, mpAnalyzer = Nothing, mpFields = mempty + }, + "type" + .= MappingProperty + { mpType = MPKeyword, + mpStore = False, + mpIndex = True, + mpAnalyzer = Nothing, + mpFields = mempty } ] ] diff --git a/services/brig/src/Brig/User/Search/SearchIndex.hs b/services/brig/src/Brig/User/Search/SearchIndex.hs index da1458aa41..b648bb0cf7 100644 --- a/services/brig/src/Brig/User/Search/SearchIndex.hs +++ b/services/brig/src/Brig/User/Search/SearchIndex.hs @@ -1,4 +1,3 @@ -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE StrictData #-} -- This file is part of the Wire Server implementation. @@ -30,12 +29,11 @@ import Control.Lens hiding (setting, (#), (.=)) import Control.Monad.Catch (MonadThrow, throwM) import Data.Aeson.Key qualified as Key import Data.Domain (Domain) -import Data.Handle (Handle (fromHandle)) import Data.Id import Data.Qualified (Qualified (Qualified)) import Database.Bloodhound qualified as ES import Imports hiding (log, searchable) -import Wire.API.User (ColourId (..), Name (fromName)) +import Wire.API.User (Name (fromName)) import Wire.API.User.Search import Wire.IndexedUserStore (IndexedUserStoreError (..)) import Wire.IndexedUserStore.ElasticSearch (mappingName) @@ -80,7 +78,7 @@ queryIndex (IndexQuery q f _) s = do r <- ES.searchByType idx mappingName search >>= ES.parseEsResponse @_ @(ES.SearchResult UserDoc) - either (throwM . IndexLookupError) (traverse (userDocToContact localDomain) . mkResult) r + either (throwM . IndexLookupError) (traverse (userDocToContact' localDomain) . mkResult) r where mkResult es = let results = mapMaybe ES.hitSource . ES.hits . ES.searchHits $ es @@ -94,14 +92,12 @@ queryIndex (IndexQuery q f _) s = do searchHasMore = Nothing } -userDocToContact :: (MonadThrow m) => Domain -> UserDoc -> m Contact -userDocToContact localDomain UserDoc {..} = do - let contactQualifiedId = Qualified udId localDomain - contactName <- maybe (throwM $ IndexError "Name not found") (pure . fromName) udName - let contactColorId = fromIntegral . fromColourId <$> udColourId - contactHandle = fromHandle <$> udHandle - contactTeam = udTeam - pure $ Contact {..} + userDocToContact' :: (MonadThrow m) => Domain -> UserDoc -> m Contact + userDocToContact' localDomain userDoc = do + userDocToContact + (Qualified userDoc.udId localDomain) + (maybe (throwM $ IndexError "Name not found") (pure . fromName)) + userDoc -- | The default or canonical 'IndexQuery'. -- diff --git a/services/brig/test/integration/API/Search.hs b/services/brig/test/integration/API/Search.hs index a4809993f0..1e87cb4b7a 100644 --- a/services/brig/test/integration/API/Search.hs +++ b/services/brig/test/integration/API/Search.hs @@ -40,7 +40,7 @@ import Brig.App (initHttpManagerWithTLSConfig) import Brig.Index.Eval (initIndex, runCommand) import Brig.Index.Options import Brig.Index.Options qualified as IndexOpts -import Brig.Options (ElasticSearchOpts) +import Brig.Options import Brig.Options qualified as Opt import Brig.Options qualified as Opts import Brig.User.Search.Index diff --git a/services/federator/test/integration/Test/Federator/IngressSpec.hs b/services/federator/test/integration/Test/Federator/IngressSpec.hs index 41b9f42af3..be2b1c1627 100644 --- a/services/federator/test/integration/Test/Federator/IngressSpec.hs +++ b/services/federator/test/integration/Test/Federator/IngressSpec.hs @@ -59,7 +59,7 @@ spec env = do brig <- view teBrig <$> ask user <- randomUser brig - let expectedProfile = mkUserProfile EmailVisibleToSelf user UserLegalHoldNoConsent + let expectedProfile = mkUserProfile EmailVisibleToSelf UserTypeRegular user UserLegalHoldNoConsent runTestSem $ do resp <- liftToCodensity diff --git a/services/federator/test/integration/Test/Federator/InwardSpec.hs b/services/federator/test/integration/Test/Federator/InwardSpec.hs index 1daee8e77e..180d41b981 100644 --- a/services/federator/test/integration/Test/Federator/InwardSpec.hs +++ b/services/federator/test/integration/Test/Federator/InwardSpec.hs @@ -70,7 +70,7 @@ spec env = brig <- view teBrig <$> ask user <- randomUser brig - let expectedProfile = mkUserProfile EmailVisibleToSelf user UserLegalHoldNoConsent + let expectedProfile = mkUserProfile EmailVisibleToSelf UserTypeRegular user UserLegalHoldNoConsent bdy <- responseJsonError =<< inwardCall "/federation/brig/get-users-by-ids" (encode [userId user])