diff --git a/changelog.d/5-internal/WPB-21964-delete-conv b/changelog.d/5-internal/WPB-21964-delete-conv new file mode 100644 index 00000000000..fad71aabe92 --- /dev/null +++ b/changelog.d/5-internal/WPB-21964-delete-conv @@ -0,0 +1,9 @@ +- Moved conversation deletion logic from `Wire.ConversationSubsystem.Action` to `Wire.ConversationSubsystem.Interpreter` +- Relocated remote member deletion utilities: + - `Wire.ConversationSubsystem.Action.deleteMembersInRemoteConversation` → `Wire.ConversationSubsystem.Util.deleteMembersInRemoteConversation` +- Updated conversation deletion implementation to handle: + - MLS group cleanup (clients and proposals) + - Sub-conversation removal + - Code key cleanup + - Team conversation vs regular conversation handling +- Added tests for conversation deletion edge cases diff --git a/charts/background-worker/templates/configmap.yaml b/charts/background-worker/templates/configmap.yaml index 2ca739b4d61..f0404e9445d 100644 --- a/charts/background-worker/templates/configmap.yaml +++ b/charts/background-worker/templates/configmap.yaml @@ -110,4 +110,15 @@ data: {{- if .postgresMigration }} postgresMigration: {{- toYaml .postgresMigration | nindent 6 }} {{- end }} + settings: + {{- if .settings.conversationCodeURI }} + conversationCodeURI: {{ .settings.conversationCodeURI | quote }} + {{- else if .settings.multiIngress }} + multiIngress: {{- toYaml .settings.multiIngress | nindent 8 }} + {{- else }} + {{ fail "Either settings.conversationCodeURI or settings.multiIngress have to be set"}} + {{- end }} + {{- if (and .settings.conversationCodeURI .settings.multiIngress) }} + {{ fail "settings.conversationCodeURI and settings.multiIngress are mutually exclusive" }} + {{- end }} {{- end }} diff --git a/charts/background-worker/values.yaml b/charts/background-worker/values.yaml index 4e8fe290473..d21fb4d62e1 100644 --- a/charts/background-worker/values.yaml +++ b/charts/background-worker/values.yaml @@ -84,6 +84,20 @@ config: migrateConversationsOptions: pageSize: 10000 parallelism: 2 + + settings: + # Either `conversationCodeURI` or `multiIngress` must be set + # conversationCodeURI is the URI prefix for conversation invitation links + # It should be of form https://{ACCOUNT_PAGES}/conversation-join/ + conversationCodeURI: null + # multiIngress is a Z-Host dependent setting of conversationCodeURI. + # Use this only if you want to expose the instance on multiple ingresses. + # If set it must be a map from Z-Host to URI prefix + # Example: + # multiIngress: + # wire.example: https://accounts.wire.example/conversation-join/ + # example.net: https://accounts.example.net/conversation-join/ + multiIngress: null # This will start the migration of conversation codes. # It's important to set `settings.postgresMigration.conversationCodes` to `migration-to-postgresql` # before starting the migration. diff --git a/hack/helm_vars/wire-server/values.yaml.gotmpl b/hack/helm_vars/wire-server/values.yaml.gotmpl index 3745be436a9..88a4adcc3f7 100644 --- a/hack/helm_vars/wire-server/values.yaml.gotmpl +++ b/hack/helm_vars/wire-server/values.yaml.gotmpl @@ -677,6 +677,8 @@ background-worker: conversation: {{ .Values.conversationStore }} conversationCodes: {{ .Values.conversationCodesStore }} teamFeatures: {{ .Values.teamFeaturesStore }} + settings: + conversationCodeURI: https://kube-staging-nginz-https.zinfra.io/conversation-join/ rabbitmq: port: 5671 adminPort: 15671 diff --git a/libs/wire-subsystems/default.nix b/libs/wire-subsystems/default.nix index c731826f787..89e07e2ece6 100644 --- a/libs/wire-subsystems/default.nix +++ b/libs/wire-subsystems/default.nix @@ -23,6 +23,7 @@ , bytestring-conversion , case-insensitive , cassandra-util +, comonad , conduit , constraints , containers @@ -66,6 +67,7 @@ , imports , iproute , iso639 +, kan-extensions , lens , lib , lrucaching @@ -158,6 +160,7 @@ mkDerivation { bytestring-conversion case-insensitive cassandra-util + comonad conduit constraints containers @@ -197,6 +200,7 @@ mkDerivation { imports iproute iso639 + kan-extensions lens lrucaching memory @@ -279,6 +283,7 @@ mkDerivation { bytestring-conversion case-insensitive cassandra-util + comonad conduit constraints containers @@ -319,6 +324,7 @@ mkDerivation { imports iproute iso639 + kan-extensions lens lrucaching memory diff --git a/libs/wire-subsystems/src/Wire/ConversationSubsystem.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem.hs index 0fe3d35b1d3..a7c16c1a645 100644 --- a/libs/wire-subsystems/src/Wire/ConversationSubsystem.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem.hs @@ -67,5 +67,7 @@ data ConversationSubsystem m a where ConvId -> UserId -> ConversationSubsystem m (Maybe LocalMember) + DeleteConversation :: ConvId -> ConversationSubsystem m () + InternalDeleteConversation :: ConvId -> ConversationSubsystem m () makeSem ''ConversationSubsystem diff --git a/services/galley/src/Galley/API/Action.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action.hs similarity index 98% rename from services/galley/src/Galley/API/Action.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Action.hs index f0858b49e9b..3173747e95a 100644 --- a/services/galley/src/Galley/API/Action.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Action +module Wire.ConversationSubsystem.Action ( -- * Conversation action types ConversationActionTag (..), ConversationJoin (..), @@ -61,17 +61,6 @@ import Data.Set qualified as Set import Data.Singletons import Data.Time.Clock import GHC.TypeLits (KnownNat) -import Galley.API.Action.Kick -import Galley.API.Action.Leave -import Galley.API.Action.Notify -import Galley.API.Action.Reset -import Galley.API.MLS.Conversation -import Galley.API.MLS.Migration -import Galley.API.MLS.Removal -import Galley.API.Teams.Features.Get -import Galley.Effects -import Galley.Env (Env) -import Galley.Options (Opts) import Galley.Types.Error import Imports hiding ((\\)) import Polysemy @@ -106,23 +95,41 @@ import Wire.API.Team.LegalHold import Wire.API.Team.Member import Wire.API.Team.Permission (Perm (AddRemoveConvMember, ModifyConvName)) import Wire.API.User as User +import Wire.BackendNotificationQueueAccess +import Wire.BrigAPIAccess import Wire.BrigAPIAccess qualified as E import Wire.CodeStore import Wire.CodeStore qualified as E +import Wire.ConversationStore import Wire.ConversationStore qualified as E import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action.Kick +import Wire.ConversationSubsystem.Action.Leave +import Wire.ConversationSubsystem.Action.Notify +import Wire.ConversationSubsystem.Action.Reset +import Wire.ConversationSubsystem.MLS.Conversation +import Wire.ConversationSubsystem.MLS.Migration +import Wire.ConversationSubsystem.MLS.Removal import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess import Wire.FeaturesConfigSubsystem +import Wire.FederationAPIAccess import Wire.FederationAPIAccess qualified as E import Wire.FederationSubsystem +import Wire.FireAndForget import Wire.FireAndForget qualified as E +import Wire.LegalHoldStore import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.ProposalStore qualified as E import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now +import Wire.Sem.Random import Wire.StoredConversation import Wire.StoredConversation qualified as Data import Wire.TeamCollaboratorsSubsystem +import Wire.TeamFeatureStore +import Wire.TeamStore import Wire.TeamSubsystem (TeamSubsystem) import Wire.TeamSubsystem qualified as TeamSubsystem import Wire.UserList @@ -166,7 +173,6 @@ type family HasConversationActionEffects (tag :: ConversationActionTag) r :: Con Member (FederationAPIAccess FederatorClient) r, Member NotificationSubsystem r, Member Now r, - Member (Input Env) r, Member (Input ConversationSubsystemConfig) r, Member ProposalStore r, Member ConversationStore r, @@ -177,7 +183,6 @@ type family HasConversationActionEffects (tag :: ConversationActionTag) r :: Con ( Member (Error NoChanges) r, Member ConversationStore r, Member ProposalStore r, - Member (Input Env) r, Member (Input ConversationSubsystemConfig) r, Member Now r, Member ExternalAccess r, @@ -220,7 +225,6 @@ type family HasConversationActionEffects (tag :: ConversationActionTag) r :: Con Member (FederationAPIAccess FederatorClient) r, Member FireAndForget r, Member NotificationSubsystem r, - Member (Input Env) r, Member (Input ConversationSubsystemConfig) r, Member ProposalStore r, Member TeamStore r, @@ -251,8 +255,6 @@ type family HasConversationActionEffects (tag :: ConversationActionTag) r :: Con Member ExternalAccess r, Member (FederationAPIAccess FederatorClient) r, Member NotificationSubsystem r, - Member (Input Env) r, - Member (Input Opts) r, Member Now r, Member ProposalStore r, Member Random r, @@ -266,8 +268,7 @@ type family HasConversationActionEffects (tag :: ConversationActionTag) r :: Con Member (ErrorS 'InvalidTargetAccess) r ) HasConversationActionEffects 'ConversationResetTag r = - ( Member (Input Env) r, - Member Now r, + ( Member Now r, Member (ErrorS ConvNotFound) r, Member (ErrorS InvalidOperation) r, Member ConversationStore r, @@ -311,7 +312,7 @@ type family HasConversationActionGalleyErrors (tag :: ConversationActionTag) :: ErrorS 'ConvMemberNotFound ] HasConversationActionGalleyErrors 'ConversationDeleteTag = - '[ ErrorS ('ActionDenied 'DeleteConversation), + '[ ErrorS ('ActionDenied Wire.API.Conversation.Role.DeleteConversation), ErrorS 'NotATeamMember, ErrorS 'InvalidOperation, ErrorS 'ConvNotFound @@ -661,7 +662,7 @@ performConversationJoin qusr lconv (ConversationJoin invited role joinType) = do -- - ensure that a consented conv admin exists -- - and kick all existing members that do not consent to LH from the conversation -- See also: "Brig.API.Connection.checkLegalholdPolicyConflict" - -- and "Galley.API.LegalHold.Conflicts.guardLegalholdPolicyConflictsUid". + -- and "Wire.LegalHoldStore.Conflicts.guardLegalholdPolicyConflictsUid". checkLHPolicyConflictsLocal :: [UserId] -> Sem r () diff --git a/services/galley/src/Galley/API/Action/Kick.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Kick.hs similarity index 88% rename from services/galley/src/Galley/API/Action/Kick.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Kick.hs index 4e9d09487be..481379b6a23 100644 --- a/services/galley/src/Galley/API/Action/Kick.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Kick.hs @@ -15,15 +15,12 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Action.Kick where +module Wire.ConversationSubsystem.Action.Kick where import Data.Default import Data.Id import Data.Qualified import Data.Singletons -import Galley.API.Action.Leave -import Galley.API.Action.Notify -import Galley.Effects import Imports hiding ((\\)) import Polysemy import Polysemy.Error @@ -34,10 +31,17 @@ import Wire.API.Conversation.Action import Wire.API.Conversation.Config (ConversationSubsystemConfig) import Wire.API.Event.LeaveReason import Wire.API.Federation.Error +import Wire.BackendNotificationQueueAccess +import Wire.ConversationStore import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action.Leave +import Wire.ConversationSubsystem.Action.Notify import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.Sem.Now (Now) +import Wire.Sem.Random import Wire.StoredConversation -- | Kick a user from a conversation and send notifications. diff --git a/services/galley/src/Galley/API/Action/Leave.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Leave.hs similarity index 86% rename from services/galley/src/Galley/API/Action/Leave.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Leave.hs index a4e397a92e5..372d44efd97 100644 --- a/services/galley/src/Galley/API/Action/Leave.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Leave.hs @@ -15,13 +15,12 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Action.Leave (leaveConversation) where +module Wire.ConversationSubsystem.Action.Leave (leaveConversation) where import Control.Lens import Data.Id import Data.Qualified -import Galley.API.MLS.Removal -import Galley.Effects +-- import Galley.Effects import Imports hiding ((\\)) import Polysemy import Polysemy.Error @@ -29,9 +28,15 @@ import Polysemy.Input import Polysemy.TinyLog import Wire.API.Conversation.Config (ConversationSubsystemConfig) import Wire.API.Federation.Error +import Wire.BackendNotificationQueueAccess +import Wire.ConversationStore +import Wire.ConversationSubsystem.MLS.Removal import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.Sem.Now (Now) +import Wire.Sem.Random import Wire.StoredConversation import Wire.UserList diff --git a/services/galley/src/Galley/API/Action/Notify.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Notify.hs similarity index 95% rename from services/galley/src/Galley/API/Action/Notify.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Notify.hs index 6ede2e2cc22..3f8635bf7da 100644 --- a/services/galley/src/Galley/API/Action/Notify.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Notify.hs @@ -15,12 +15,12 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Action.Notify where +module Wire.ConversationSubsystem.Action.Notify where import Data.Id import Data.Qualified import Data.Singletons -import Galley.Effects +-- import Galley.Effects import Imports hiding ((\\)) import Polysemy import Wire.API.Conversation hiding (Conversation, Member) diff --git a/services/galley/src/Galley/API/Action/Reset.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Reset.hs similarity index 94% rename from services/galley/src/Galley/API/Action/Reset.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Reset.hs index 492146ac15a..d238a818629 100644 --- a/services/galley/src/Galley/API/Action/Reset.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Action/Reset.hs @@ -15,16 +15,13 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Action.Reset (resetLocalMLSMainConversation) where +module Wire.ConversationSubsystem.Action.Reset (resetLocalMLSMainConversation) where import Control.Monad.Codensity hiding (reset) import Data.Aeson qualified as A import Data.ByteString.Conversion (toByteString') import Data.Id import Data.Qualified -import Galley.API.Action.Kick -import Galley.API.MLS.Util -import Galley.Effects import Imports import Polysemy import Polysemy.Error @@ -46,12 +43,18 @@ import Wire.API.MLS.Group.Serialisation qualified as Group import Wire.API.MLS.SubConversation import Wire.API.Routes.Public.Galley.MLS import Wire.API.VersionInfo +import Wire.BackendNotificationQueueAccess import Wire.ConversationStore import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action.Kick +import Wire.ConversationSubsystem.MLS.Util import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess import Wire.FederationAPIAccess import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.Sem.Now (Now) +import Wire.Sem.Random import Wire.StoredConversation as Data resetLocalMLSMainConversation :: diff --git a/libs/wire-subsystems/src/Wire/ConversationSubsystem/Interpreter.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Interpreter.hs index 0fe59a7476b..f47bbb434ce 100644 --- a/libs/wire-subsystems/src/Wire/ConversationSubsystem/Interpreter.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Interpreter.hs @@ -25,6 +25,7 @@ import Control.Lens hiding ((??)) import Data.Default import Data.Id import Data.Json.Util (ToJSONObject (toJSONObject)) +import Data.Map.Strict qualified as Map import Data.Misc (FutureWork (FutureWork)) import Data.Qualified import Data.Range @@ -44,6 +45,7 @@ import Wire.API.Conversation qualified as Public import Wire.API.Conversation.Action import Wire.API.Conversation.CellsState import Wire.API.Conversation.Config +import Wire.API.Conversation.Protocol (ConversationMLSData (cnvmlsGroupId)) import Wire.API.Conversation.Role import Wire.API.Error import Wire.API.Error.Galley @@ -65,6 +67,8 @@ import Wire.API.Team.Permission hiding (self) import Wire.API.User import Wire.BackendNotificationQueueAccess (BackendNotificationQueueAccess, enqueueNotificationsConcurrently) import Wire.BrigAPIAccess +import Wire.CodeStore (CodeStore) +import Wire.CodeStore qualified as CodeStore import Wire.ConversationStore (ConversationStore) import Wire.ConversationStore qualified as ConvStore import Wire.ConversationSubsystem @@ -76,6 +80,8 @@ import Wire.FeaturesConfigSubsystem import Wire.FederationAPIAccess (FederationAPIAccess) import Wire.LegalHoldStore (LegalHoldStore) import Wire.NotificationSubsystem as NS +import Wire.ProposalStore (ProposalStore) +import Wire.ProposalStore qualified as ProposalStore import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now import Wire.Sem.Random (Random) @@ -126,7 +132,9 @@ interpretConversationSubsystem :: Member (Input ConversationSubsystemConfig) r, Member LegalHoldStore r, Member TeamStore r, - Member UserClientIndexStore r + Member UserClientIndexStore r, + Member CodeStore r, + Member ProposalStore r ) => Sem (ConversationSubsystem : r) a -> Sem r a @@ -145,6 +153,10 @@ interpretConversationSubsystem = interpret $ \case internalGetClientIdsImpl uids ConversationSubsystem.InternalGetLocalMember cid uid -> ConvStore.getLocalMember cid uid + ConversationSubsystem.DeleteConversation cid -> + deleteConversationImpl cid + ConversationSubsystem.InternalDeleteConversation cid -> + internalDeleteConversationImpl cid createGroupConversationGeneric :: forall r. @@ -820,3 +832,41 @@ internalGetClientIdsImpl users = do if isInternal then fromUserClients <$> lookupClients users else UserClientIndexStore.getClients users + +deleteConversationImpl :: + ( Member ConversationStore r, + Member CodeStore r, + Member ProposalStore r + ) => + ConvId -> + Sem r () +deleteConversationImpl cid = do + internalDeleteConversationImpl cid + +internalDeleteConversationImpl :: + ( Member ConversationStore r, + Member CodeStore r, + Member ProposalStore r + ) => + ConvId -> + Sem r () +internalDeleteConversationImpl cid = do + mConv <- ConvStore.getConversation cid + forM_ mConv $ \storedConv -> do + let deleteGroup groupId = do + ConvStore.removeAllMLSClients groupId + ProposalStore.deleteAllProposals groupId + + for_ (storedConv & mlsMetadata <&> cnvmlsGroupId . fst) $ \gidParent -> do + sconvs <- ConvStore.listSubConversations cid + for_ (Map.assocs sconvs) $ \(subid, mlsData) -> do + let gidSub = cnvmlsGroupId mlsData + ConvStore.deleteSubConversation cid subid + deleteGroup gidSub + deleteGroup gidParent + + key <- CodeStore.makeKey cid + CodeStore.deleteCode key + case Data.convTeam storedConv of + Nothing -> ConvStore.deleteConversation cid + Just tid -> ConvStore.deleteTeamConversation tid cid diff --git a/services/galley/src/Galley/API/MLS.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS.hs similarity index 91% rename from services/galley/src/Galley/API/MLS.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS.hs index 0d0d5abe601..52bf2ad97bc 100644 --- a/services/galley/src/Galley/API/MLS.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS +module Wire.ConversationSubsystem.MLS ( isMLSEnabled, assertMLSEnabled, postMLSMessage, @@ -27,9 +27,6 @@ module Galley.API.MLS where import Data.Default -import Galley.API.MLS.Enabled -import Galley.API.MLS.Message -import Galley.Env import Galley.Types.Error import Imports import Polysemy @@ -38,9 +35,11 @@ import Polysemy.Input import Wire.API.Error import Wire.API.Error.Galley import Wire.API.MLS.Keys +import Wire.ConversationSubsystem.MLS.Enabled +import Wire.ConversationSubsystem.MLS.Message getMLSPublicKeys :: - ( Member (Input Env) r, + ( Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (ErrorS 'MLSNotEnabled) r, Member (Error InternalError) r ) => diff --git a/services/galley/src/Galley/API/MLS/CheckClients.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/CheckClients.hs similarity index 96% rename from services/galley/src/Galley/API/MLS/CheckClients.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/CheckClients.hs index 9a834fd708d..84e50278689 100644 --- a/services/galley/src/Galley/API/MLS/CheckClients.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/CheckClients.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.CheckClients +module Wire.ConversationSubsystem.MLS.CheckClients ( checkClients, getClientData, ClientData (..), @@ -29,8 +29,6 @@ import Data.Map qualified as Map import Data.Qualified import Data.Set qualified as Set import Data.Tuple.Extra -import Galley.API.MLS.Commit.Core -import Galley.Effects import Imports import Polysemy import Polysemy.Error @@ -42,7 +40,10 @@ import Wire.API.MLS.CipherSuite import Wire.API.MLS.KeyPackage import Wire.API.MLS.LeafNode import Wire.API.User.Client +import Wire.BrigAPIAccess import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS.Commit.Core +import Wire.FederationAPIAccess checkClients :: ( Member BrigAPIAccess r, diff --git a/services/galley/src/Galley/API/MLS/Commit.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit.hs similarity index 80% rename from services/galley/src/Galley/API/MLS/Commit.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit.hs index 39088273b8b..fa685febd2e 100644 --- a/services/galley/src/Galley/API/MLS/Commit.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Commit +module Wire.ConversationSubsystem.MLS.Commit ( getCommitData, getExternalCommitData, processInternalCommit, @@ -23,6 +23,6 @@ module Galley.API.MLS.Commit ) where -import Galley.API.MLS.Commit.Core -import Galley.API.MLS.Commit.ExternalCommit -import Galley.API.MLS.Commit.InternalCommit +import Wire.ConversationSubsystem.MLS.Commit.Core +import Wire.ConversationSubsystem.MLS.Commit.ExternalCommit +import Wire.ConversationSubsystem.MLS.Commit.InternalCommit diff --git a/services/galley/src/Galley/API/MLS/Commit/Core.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/Core.hs similarity index 96% rename from services/galley/src/Galley/API/MLS/Commit/Core.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/Core.hs index 124a1c4d5b8..44b7982cbf6 100644 --- a/services/galley/src/Galley/API/MLS/Commit/Core.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/Core.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Commit.Core +module Wire.ConversationSubsystem.MLS.Commit.Core ( getCommitData, incrementEpoch, getClientInfo, @@ -31,12 +31,6 @@ where import Control.Comonad import Data.Id import Data.Qualified -import Galley.API.MLS.Conversation -import Galley.API.MLS.IncomingMessage -import Galley.API.MLS.Proposal -import Galley.Effects -import Galley.Env -import Galley.Options import Galley.Types.Error import Imports import Polysemy @@ -65,13 +59,22 @@ import Wire.API.MLS.SubConversation import Wire.API.MLS.Validation import Wire.API.MLS.Validation.Error (toText) import Wire.API.User.Client +import Wire.BackendNotificationQueueAccess import Wire.BrigAPIAccess import Wire.ConversationStore import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS.Conversation +import Wire.ConversationSubsystem.MLS.IncomingMessage +import Wire.ConversationSubsystem.MLS.Proposal +import Wire.ExternalAccess import Wire.FederationAPIAccess +import Wire.LegalHoldStore import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.Sem.Now (Now) +import Wire.Sem.Random import Wire.TeamCollaboratorsSubsystem +import Wire.TeamStore type HasProposalActionEffects r = ( Member BackendNotificationQueueAccess r, @@ -91,8 +94,6 @@ type HasProposalActionEffects r = Member ExternalAccess r, Member (FederationAPIAccess FederatorClient) r, Member (Input ConversationSubsystemConfig) r, - Member (Input Env) r, - Member (Input Opts) r, Member Now r, Member LegalHoldStore r, Member ProposalStore r, diff --git a/services/galley/src/Galley/API/MLS/Commit/ExternalCommit.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/ExternalCommit.hs similarity index 96% rename from services/galley/src/Galley/API/MLS/Commit/ExternalCommit.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/ExternalCommit.hs index c8f2bacd57c..10fa4e6bd58 100644 --- a/services/galley/src/Galley/API/MLS/Commit/ExternalCommit.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/ExternalCommit.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Commit.ExternalCommit +module Wire.ConversationSubsystem.MLS.Commit.ExternalCommit ( ExternalCommitAction (..), getExternalCommitData, processExternalCommit, @@ -28,12 +28,6 @@ import Control.Monad.Codensity import Data.Map qualified as Map import Data.Qualified import Data.Set qualified as Set -import Galley.API.MLS.Commit.Core -import Galley.API.MLS.IncomingMessage -import Galley.API.MLS.Proposal -import Galley.API.MLS.Removal -import Galley.API.MLS.Util -import Galley.Effects import Imports import Polysemy import Polysemy.Error @@ -52,6 +46,11 @@ import Wire.API.MLS.ProposalTag import Wire.API.MLS.SubConversation import Wire.ConversationStore import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS.Commit.Core +import Wire.ConversationSubsystem.MLS.IncomingMessage +import Wire.ConversationSubsystem.MLS.Proposal +import Wire.ConversationSubsystem.MLS.Removal +import Wire.ConversationSubsystem.MLS.Util data ExternalCommitAction = ExternalCommitAction { add :: LeafIndex, diff --git a/services/galley/src/Galley/API/MLS/Commit/InternalCommit.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/InternalCommit.hs similarity index 96% rename from services/galley/src/Galley/API/MLS/Commit/InternalCommit.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/InternalCommit.hs index e2152e2ebb5..a328b2331d2 100644 --- a/services/galley/src/Galley/API/MLS/Commit/InternalCommit.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Commit/InternalCommit.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Commit.InternalCommit (processInternalCommit) where +module Wire.ConversationSubsystem.MLS.Commit.InternalCommit (processInternalCommit) where import Control.Comonad import Control.Error.Util (hush) @@ -29,15 +29,6 @@ import Data.Map qualified as Map import Data.Qualified import Data.Set qualified as Set import Data.Tuple.Extra -import Galley.API.Action -import Galley.API.MLS.CheckClients -import Galley.API.MLS.Commit.Core -import Galley.API.MLS.Conversation -import Galley.API.MLS.IncomingMessage -import Galley.API.MLS.One2One -import Galley.API.MLS.Proposal -import Galley.API.MLS.Util -import Galley.Effects import Galley.Types.Error import Imports import Polysemy @@ -62,9 +53,18 @@ import Wire.API.Unreachable import Wire.ConversationStore import Wire.ConversationStore.MLS.Types import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action +import Wire.ConversationSubsystem.MLS.CheckClients +import Wire.ConversationSubsystem.MLS.Commit.Core +import Wire.ConversationSubsystem.MLS.Conversation +import Wire.ConversationSubsystem.MLS.IncomingMessage +import Wire.ConversationSubsystem.MLS.One2One +import Wire.ConversationSubsystem.MLS.Proposal +import Wire.ConversationSubsystem.MLS.Util import Wire.ConversationSubsystem.Util import Wire.FederationSubsystem import Wire.ProposalStore +import Wire.Sem.Random import Wire.StoredConversation import Wire.TeamSubsystem (TeamSubsystem) diff --git a/services/galley/src/Galley/API/MLS/Conversation.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Conversation.hs similarity index 97% rename from services/galley/src/Galley/API/MLS/Conversation.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Conversation.hs index 0b979880816..b129d31c00e 100644 --- a/services/galley/src/Galley/API/MLS/Conversation.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Conversation.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Conversation +module Wire.ConversationSubsystem.MLS.Conversation ( mkMLSConversation, newMLSConversation, mcConv, diff --git a/services/galley/src/Galley/API/MLS/Enabled.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Enabled.hs similarity index 74% rename from services/galley/src/Galley/API/MLS/Enabled.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Enabled.hs index ec1bd099baa..3a0aaefc1da 100644 --- a/services/galley/src/Galley/API/MLS/Enabled.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Enabled.hs @@ -15,10 +15,8 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Enabled where +module Wire.ConversationSubsystem.MLS.Enabled where -import Control.Lens (view) -import Galley.Env import Imports hiding (getFirst) import Polysemy import Polysemy.Input @@ -26,21 +24,23 @@ import Wire.API.Error import Wire.API.Error.Galley import Wire.API.MLS.Keys -isMLSEnabled :: (Member (Input Env) r) => Sem r Bool -isMLSEnabled = inputs (isJust . view mlsKeys) +isMLSEnabled :: + (Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r) => + Sem r Bool +isMLSEnabled = inputs @(Maybe (MLSKeysByPurpose MLSPrivateKeys)) isJust -- | Fail if MLS is not enabled. Only use this function at the beginning of an -- MLS endpoint, NOT in utility functions. assertMLSEnabled :: - ( Member (Input Env) r, + ( Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (ErrorS 'MLSNotEnabled) r ) => Sem r () assertMLSEnabled = void getMLSPrivateKeys getMLSPrivateKeys :: - ( Member (Input Env) r, + ( Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (ErrorS 'MLSNotEnabled) r ) => Sem r (MLSKeysByPurpose MLSPrivateKeys) -getMLSPrivateKeys = noteS @'MLSNotEnabled =<< inputs (view mlsKeys) +getMLSPrivateKeys = noteS @'MLSNotEnabled =<< input @(Maybe (MLSKeysByPurpose MLSPrivateKeys)) diff --git a/services/galley/src/Galley/API/MLS/GroupInfo.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/GroupInfo.hs similarity index 88% rename from services/galley/src/Galley/API/MLS/GroupInfo.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/GroupInfo.hs index f09a21db861..15406371a18 100644 --- a/services/galley/src/Galley/API/MLS/GroupInfo.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/GroupInfo.hs @@ -15,15 +15,11 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.GroupInfo where +module Wire.ConversationSubsystem.MLS.GroupInfo where import Data.Id as Id import Data.Json.Util import Data.Qualified -import Galley.API.MLS.Enabled -import Galley.API.MLS.Util -import Galley.Effects -import Galley.Env import Imports import Polysemy import Polysemy.Error @@ -35,9 +31,13 @@ import Wire.API.Federation.API.Galley import Wire.API.Federation.Client (FederatorClient) import Wire.API.Federation.Error import Wire.API.MLS.GroupInfo +import Wire.API.MLS.Keys (MLSKeysByPurpose, MLSPrivateKeys) import Wire.API.MLS.SubConversation import Wire.ConversationStore qualified as E +import Wire.ConversationSubsystem.MLS.Enabled +import Wire.ConversationSubsystem.MLS.Util import Wire.ConversationSubsystem.Util +import Wire.FederationAPIAccess import Wire.FederationAPIAccess qualified as E type MLSGroupInfoStaticErrors = @@ -47,10 +47,10 @@ type MLSGroupInfoStaticErrors = ] getGroupInfo :: - ( Member ConversationStore r, + ( Member E.ConversationStore r, Member (Error FederationError) r, Member (FederationAPIAccess FederatorClient) r, - Member (Input Env) r + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r ) => (Members MLSGroupInfoStaticErrors r) => Local UserId -> @@ -65,7 +65,7 @@ getGroupInfo lusr qcnvId = do qcnvId getGroupInfoFromLocalConv :: - (Member ConversationStore r) => + (Member E.ConversationStore r) => (Members MLSGroupInfoStaticErrors r) => Qualified UserId -> Local ConvId -> diff --git a/services/galley/src/Galley/API/MLS/GroupInfoCheck.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/GroupInfoCheck.hs similarity index 88% rename from services/galley/src/Galley/API/MLS/GroupInfoCheck.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/GroupInfoCheck.hs index 798345adf3a..ba74cc393f7 100644 --- a/services/galley/src/Galley/API/MLS/GroupInfoCheck.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/GroupInfoCheck.hs @@ -15,18 +15,15 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.GroupInfoCheck +module Wire.ConversationSubsystem.MLS.GroupInfoCheck ( checkGroupState, GroupInfoMismatch (..), + GroupInfoCheckEnabled (..), ) where -import Control.Lens (view) import Data.Bifunctor import Data.Id -import Galley.API.Teams.Features.Get -import Galley.Effects -import Galley.Options import Imports import Polysemy import Polysemy.Error @@ -46,18 +43,23 @@ import Wire.API.Team.Feature import Wire.ConversationStore import Wire.ConversationStore.MLS.Types import Wire.FeaturesConfigSubsystem (FeaturesConfigSubsystem) +import Wire.FeaturesConfigSubsystem.Get data GroupInfoMismatch = GroupInfoMismatch {clients :: [(Int, ClientIdentity)]} - deriving (Show) + deriving stock (Show) + +newtype GroupInfoCheckEnabled + = GroupInfoCheckEnabled {unGroupInfoCheckEnabled :: Bool} + deriving stock (Eq, Ord, Show) checkGroupState :: forall r. ( Member (Error GroupInfoMismatch) r, - Member (Input Opts) r, Member (Error MLSProtocolError) r, Member ConversationStore r, - Member FeaturesConfigSubsystem r + Member FeaturesConfigSubsystem r, + Member (Input (Maybe GroupInfoCheckEnabled)) r ) => ConvOrSubConv -> IndexMap -> @@ -103,14 +105,12 @@ existingGroupStateMismatch convOrSub = Right m -> pure m isGroupInfoCheckEnabled :: - ( Member FeaturesConfigSubsystem r, - Member (Input Opts) r - ) => + (Member FeaturesConfigSubsystem r, Member (Input (Maybe GroupInfoCheckEnabled)) r) => Maybe TeamId -> Sem r Bool isGroupInfoCheckEnabled Nothing = pure False isGroupInfoCheckEnabled (Just tid) = fmap isJust . runNonDetMaybe $ do - global <- inputs (view $ settings . checkGroupInfo) + global <- inputs $ fmap unGroupInfoCheckEnabled guard (global == Just True) mls <- getFeatureForTeam @_ @MLSConfig tid guard (getAny mls.config.mlsGroupInfoDiagnostics) diff --git a/services/galley/src/Galley/API/MLS/IncomingMessage.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/IncomingMessage.hs similarity index 98% rename from services/galley/src/Galley/API/MLS/IncomingMessage.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/IncomingMessage.hs index 3a3fba62514..b88c90fbf7d 100644 --- a/services/galley/src/Galley/API/MLS/IncomingMessage.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/IncomingMessage.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.IncomingMessage +module Wire.ConversationSubsystem.MLS.IncomingMessage ( IncomingMessage (..), IncomingMessageContent (..), IncomingPublicMessageContent (..), diff --git a/services/galley/src/Galley/API/MLS/Keys.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Keys.hs similarity index 95% rename from services/galley/src/Galley/API/MLS/Keys.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Keys.hs index ddafc4e0e2d..b5a84d89f50 100644 --- a/services/galley/src/Galley/API/MLS/Keys.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Keys.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Keys (getMLSRemovalKey, SomeKeyPair (..)) where +module Wire.ConversationSubsystem.MLS.Keys (getMLSRemovalKey, SomeKeyPair (..)) where import Control.Error.Util (hush) import Data.Proxy diff --git a/services/galley/src/Galley/API/MLS/Message.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Message.hs similarity index 94% rename from services/galley/src/Galley/API/MLS/Message.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Message.hs index e3868743bce..1b241ef01e2 100644 --- a/services/galley/src/Galley/API/MLS/Message.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Message.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Message +module Wire.ConversationSubsystem.MLS.Message ( IncomingBundle (..), mkIncomingBundle, IncomingMessage (..), @@ -40,22 +40,6 @@ import Data.Set qualified as Set import Data.Tagged import Data.Text.Lazy qualified as LT import Data.Tuple.Extra -import Galley.API.Action -import Galley.API.LegalHold.Get (getUserStatus) -import Galley.API.MLS.Commit.Core (getCommitData) -import Galley.API.MLS.Commit.ExternalCommit -import Galley.API.MLS.Commit.InternalCommit -import Galley.API.MLS.Conversation -import Galley.API.MLS.Enabled -import Galley.API.MLS.GroupInfoCheck -import Galley.API.MLS.IncomingMessage -import Galley.API.MLS.One2One -import Galley.API.MLS.OutOfSync -import Galley.API.MLS.Propagate -import Galley.API.MLS.Proposal -import Galley.API.MLS.Util -import Galley.API.MLS.Welcome (sendWelcomes) -import Galley.Effects import Galley.Types.Error import Imports import Polysemy @@ -79,21 +63,40 @@ import Wire.API.MLS.Commit hiding (output) import Wire.API.MLS.CommitBundle import Wire.API.MLS.Credential import Wire.API.MLS.GroupInfo +import Wire.API.MLS.Keys (MLSKeysByPurpose, MLSPrivateKeys) import Wire.API.MLS.Message import Wire.API.MLS.OutOfSync import Wire.API.MLS.Serialisation import Wire.API.MLS.SubConversation import Wire.API.Routes.Version import Wire.API.Team.LegalHold +import Wire.BrigAPIAccess import Wire.ConversationStore import Wire.ConversationStore.MLS.Types import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action +import Wire.ConversationSubsystem.MLS.Commit.Core (getCommitData) +import Wire.ConversationSubsystem.MLS.Commit.ExternalCommit +import Wire.ConversationSubsystem.MLS.Commit.InternalCommit +import Wire.ConversationSubsystem.MLS.Conversation +import Wire.ConversationSubsystem.MLS.Enabled +import Wire.ConversationSubsystem.MLS.GroupInfoCheck +import Wire.ConversationSubsystem.MLS.IncomingMessage +import Wire.ConversationSubsystem.MLS.One2One +import Wire.ConversationSubsystem.MLS.OutOfSync +import Wire.ConversationSubsystem.MLS.Propagate +import Wire.ConversationSubsystem.MLS.Proposal +import Wire.ConversationSubsystem.MLS.Util +import Wire.ConversationSubsystem.MLS.Welcome (sendWelcomes) import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess import Wire.FeaturesConfigSubsystem import Wire.FederationAPIAccess import Wire.FederationSubsystem +import Wire.LegalHoldStore.Get (getUserStatus) import Wire.NotificationSubsystem import Wire.Sem.Now qualified as Now +import Wire.Sem.Random import Wire.StoredConversation import Wire.TeamStore qualified as TeamStore import Wire.TeamSubsystem (TeamSubsystem) @@ -154,7 +157,8 @@ postMLSMessageFromLocalUser :: Member (ErrorS 'MLSSubConvClientNotInParent) r, Member (ErrorS MLSInvalidLeafNodeSignature) r, Member (Error MLSOutOfSyncError) r, - Member (Error GroupInfoDiagnostics) r + Member (Error GroupInfoDiagnostics) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r ) => Version -> Local UserId -> @@ -189,7 +193,8 @@ postMLSCommitBundle :: Member FederationSubsystem r, Member TeamSubsystem r, Member (Input ConversationSubsystemConfig) r, - Member FeaturesConfigSubsystem r + Member FeaturesConfigSubsystem r, + Member (Input (Maybe GroupInfoCheckEnabled)) r ) => Local x -> Qualified UserId -> @@ -221,7 +226,9 @@ postMLSCommitBundleFromLocalUser :: Member FederationSubsystem r, Member TeamSubsystem r, Member (Input ConversationSubsystemConfig) r, - Member FeaturesConfigSubsystem r + Member FeaturesConfigSubsystem r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, + Member (Input (Maybe GroupInfoCheckEnabled)) r ) => Version -> Local UserId -> @@ -257,7 +264,8 @@ postMLSCommitBundleToLocalConv :: Member FederationSubsystem r, Member TeamSubsystem r, Member (Input ConversationSubsystemConfig) r, - Member FeaturesConfigSubsystem r + Member FeaturesConfigSubsystem r, + Member (Input (Maybe GroupInfoCheckEnabled)) r ) => Qualified UserId -> ClientId -> diff --git a/services/galley/src/Galley/API/MLS/Migration.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Migration.hs similarity index 97% rename from services/galley/src/Galley/API/MLS/Migration.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Migration.hs index 64bc3741ae6..8b9d1e92324 100644 --- a/services/galley/src/Galley/API/MLS/Migration.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Migration.hs @@ -15,9 +15,9 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Migration where +module Wire.ConversationSubsystem.MLS.Migration where -import Brig.Types.Intra +-- import Brig.Types.Intra import Data.Qualified import Data.Set qualified as Set import Data.Time diff --git a/services/galley/src/Galley/API/MLS/One2One.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/One2One.hs similarity index 99% rename from services/galley/src/Galley/API/MLS/One2One.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/One2One.hs index 3f8550b4b94..3082a3dc257 100644 --- a/services/galley/src/Galley/API/MLS/One2One.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/One2One.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.One2One +module Wire.ConversationSubsystem.MLS.One2One ( localMLSOne2OneConversation, localMLSOne2OneConversationAsRemote, localMLSOne2OneConversationMetadata, diff --git a/services/galley/src/Galley/API/MLS/OutOfSync.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/OutOfSync.hs similarity index 95% rename from services/galley/src/Galley/API/MLS/OutOfSync.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/OutOfSync.hs index e12aaddf65e..a253d81f706 100644 --- a/services/galley/src/Galley/API/MLS/OutOfSync.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/OutOfSync.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.OutOfSync +module Wire.ConversationSubsystem.MLS.OutOfSync ( checkConversationOutOfSync, updateOutOfSyncFlag, ) @@ -25,8 +25,6 @@ import Data.Id import Data.Map qualified as Map import Data.Qualified import Data.Set qualified as Set -import Galley.API.MLS.CheckClients -import Galley.Effects import Imports import Polysemy import Polysemy.Error @@ -37,8 +35,11 @@ import Wire.API.MLS.CipherSuite import Wire.API.MLS.Credential import Wire.API.MLS.OutOfSync import Wire.API.MLS.SubConversation +import Wire.BrigAPIAccess import Wire.ConversationStore import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS.CheckClients +import Wire.FederationAPIAccess import Wire.StoredConversation checkConversationOutOfSync :: diff --git a/services/galley/src/Galley/API/MLS/Propagate.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Propagate.hs similarity index 97% rename from services/galley/src/Galley/API/MLS/Propagate.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Propagate.hs index a8a656a4677..9a119a02a70 100644 --- a/services/galley/src/Galley/API/MLS/Propagate.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Propagate.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Propagate where +module Wire.ConversationSubsystem.MLS.Propagate where import Control.Comonad import Data.Id @@ -23,8 +23,6 @@ import Data.Json.Util import Data.List.NonEmpty (NonEmpty, nonEmpty) import Data.Map qualified as Map import Data.Qualified -import Galley.API.Push -import Galley.Effects import Imports import Network.AMQP qualified as Q import Polysemy @@ -42,7 +40,9 @@ import Wire.API.Message import Wire.API.Push.V2 (RecipientClients (..)) import Wire.BackendNotificationQueueAccess import Wire.ConversationStore.MLS.Types +import Wire.ExternalAccess import Wire.NotificationSubsystem +import Wire.NotificationSubsystem.PushUtils import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now import Wire.StoredConversation diff --git a/services/galley/src/Galley/API/MLS/Proposal.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Proposal.hs similarity index 96% rename from services/galley/src/Galley/API/MLS/Proposal.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Proposal.hs index a66a0f9144e..f33b59ccd26 100644 --- a/services/galley/src/Galley/API/MLS/Proposal.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Proposal.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Proposal +module Wire.ConversationSubsystem.MLS.Proposal ( -- * Proposal processing derefOrCheckProposal, checkProposal, @@ -38,10 +38,9 @@ import Data.Id import Data.Map qualified as Map import Data.Qualified import Data.Set qualified as Set -import Galley.API.MLS.IncomingMessage -import Galley.Effects -import Galley.Env -import Galley.Options +-- import Galley.Effects +-- import Galley.Env +-- import Galley.Options import Galley.Types.Error import Imports import Polysemy @@ -66,13 +65,20 @@ import Wire.API.MLS.Serialisation import Wire.API.MLS.Validation import Wire.API.MLS.Validation.Error (toText) import Wire.API.Message +import Wire.BackendNotificationQueueAccess import Wire.BrigAPIAccess +import Wire.ConversationStore import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS.IncomingMessage import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess +import Wire.FederationAPIAccess +import Wire.LegalHoldStore import Wire.NotificationSubsystem import Wire.ProposalStore import Wire.Sem.Now (Now) import Wire.TeamCollaboratorsSubsystem +import Wire.TeamStore data ProposalAction = ProposalAction { paAdd :: ClientMap (LeafIndex, Maybe KeyPackage), @@ -129,9 +135,7 @@ type HasProposalEffects r = Member (Error UnreachableBackends) r, Member ExternalAccess r, Member (FederationAPIAccess FederatorClient) r, - Member (Input Env) r, Member (Input (Local ())) r, - Member (Input Opts) r, Member Now r, Member LegalHoldStore r, Member ProposalStore r, diff --git a/services/galley/src/Galley/API/MLS/Removal.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Removal.hs similarity index 97% rename from services/galley/src/Galley/API/MLS/Removal.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Removal.hs index 33a87c2a384..3daa9b661ed 100644 --- a/services/galley/src/Galley/API/MLS/Removal.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Removal.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Removal +module Wire.ConversationSubsystem.MLS.Removal ( createAndSendRemoveProposals, removeExtraneousClients, removeClient, @@ -31,10 +31,6 @@ import Data.Map qualified as Map import Data.Proxy import Data.Qualified import Data.Set qualified as Set -import Galley.API.MLS.Conversation -import Galley.API.MLS.Keys -import Galley.API.MLS.Propagate -import Galley.Effects import Imports import Polysemy import Polysemy.Error @@ -52,8 +48,13 @@ import Wire.API.MLS.Message import Wire.API.MLS.Proposal import Wire.API.MLS.Serialisation import Wire.API.MLS.SubConversation +import Wire.BackendNotificationQueueAccess import Wire.ConversationStore import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS.Conversation +import Wire.ConversationSubsystem.MLS.Keys +import Wire.ConversationSubsystem.MLS.Propagate +import Wire.ExternalAccess import Wire.NotificationSubsystem import Wire.ProposalStore import Wire.Sem.Now (Now) diff --git a/services/galley/src/Galley/API/MLS/Reset.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Reset.hs similarity index 89% rename from services/galley/src/Galley/API/MLS/Reset.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Reset.hs index 5bd236d4dff..4c7edcb9c1f 100644 --- a/services/galley/src/Galley/API/MLS/Reset.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Reset.hs @@ -15,16 +15,10 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Reset (resetMLSConversation) where +module Wire.ConversationSubsystem.MLS.Reset (resetMLSConversation) where import Data.Id import Data.Qualified -import Galley.API.Action -import Galley.API.MLS.Enabled -import Galley.API.MLS.Util -import Galley.API.Update -import Galley.Effects -import Galley.Env import Galley.Types.Error import Imports import Polysemy @@ -38,18 +32,29 @@ import Wire.API.Error import Wire.API.Error.Galley import Wire.API.Federation.Client (FederatorClient) import Wire.API.Federation.Error +import Wire.API.MLS.Keys (MLSKeysByPurpose, MLSPrivateKeys) import Wire.API.MLS.SubConversation import Wire.API.Routes.Public.Galley.MLS +import Wire.BackendNotificationQueueAccess +import Wire.BrigAPIAccess import Wire.ConversationStore import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action +import Wire.ConversationSubsystem.MLS.Enabled +import Wire.ConversationSubsystem.MLS.Util +import Wire.ConversationSubsystem.Update +import Wire.ExternalAccess +import Wire.FederationAPIAccess import Wire.FederationSubsystem import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.Sem.Now (Now) +import Wire.Sem.Random import Wire.TeamCollaboratorsSubsystem import Wire.TeamSubsystem (TeamSubsystem) resetMLSConversation :: - ( Member (Input Env) r, + ( Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member Now r, Member (Input (Local ())) r, Member (ErrorS MLSNotEnabled) r, diff --git a/services/galley/src/Galley/API/MLS/SubConversation.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/SubConversation.hs similarity index 94% rename from services/galley/src/Galley/API/MLS/SubConversation.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/SubConversation.hs index 23b88ff07c1..45f2025f8e3 100644 --- a/services/galley/src/Galley/API/MLS/SubConversation.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/SubConversation.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.SubConversation +module Wire.ConversationSubsystem.MLS.SubConversation ( getSubConversation, getLocalSubConversation, deleteSubConversation, @@ -35,13 +35,6 @@ import Control.Arrow import Control.Monad.Codensity hiding (reset) import Data.Id import Data.Qualified -import Galley.API.MLS -import Galley.API.MLS.Conversation -import Galley.API.MLS.GroupInfo -import Galley.API.MLS.Removal -import Galley.API.MLS.Util -import Galley.App (Env) -import Galley.Effects import Imports import Polysemy import Polysemy.Error @@ -61,14 +54,25 @@ import Wire.API.MLS.Credential import Wire.API.MLS.Group.Serialisation import Wire.API.MLS.Group.Serialisation qualified as Group import Wire.API.MLS.GroupInfo +import Wire.API.MLS.Keys (MLSKeysByPurpose, MLSPrivateKeys) import Wire.API.MLS.SubConversation import Wire.API.Routes.Public.Galley.MLS +import Wire.BackendNotificationQueueAccess +import Wire.ConversationStore (ConversationStore) import Wire.ConversationStore qualified as Eff import Wire.ConversationStore.MLS.Types as Eff +import Wire.ConversationSubsystem.MLS +import Wire.ConversationSubsystem.MLS.Conversation +import Wire.ConversationSubsystem.MLS.GroupInfo +import Wire.ConversationSubsystem.MLS.Removal +import Wire.ConversationSubsystem.MLS.Util import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess import Wire.FederationAPIAccess import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.Sem.Now (Now) +import Wire.Sem.Random import Wire.StoredConversation import Wire.StoredConversation qualified as Data import Wire.TeamSubsystem (TeamSubsystem) @@ -166,7 +170,7 @@ getSubConversationGroupInfo :: '[ ConversationStore, Error FederationError, FederationAPIAccess FederatorClient, - Input Env + Input (Maybe (MLSKeysByPurpose MLSPrivateKeys)) ] r, Members MLSGroupInfoStaticErrors r @@ -210,7 +214,7 @@ deleteSubConversation :: Member (ErrorS 'MLSStaleMessage) r, Member (Error FederationError) r, Member (FederationAPIAccess FederatorClient) r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member Resource r, Member Eff.MLSCommitLockStore r, Member TeamSubsystem r @@ -264,7 +268,7 @@ type HasLeaveSubConversationEffects r = Member ExternalAccess r, Member (FederationAPIAccess FederatorClient) r, Member NotificationSubsystem r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member Now r, Member ProposalStore r, Member Random r, diff --git a/services/galley/src/Galley/API/MLS/Util.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Util.hs similarity index 98% rename from services/galley/src/Galley/API/MLS/Util.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Util.hs index 8fed49aa54c..dfd399279d2 100644 --- a/services/galley/src/Galley/API/MLS/Util.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Util.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Util where +module Wire.ConversationSubsystem.MLS.Util where import Control.Comonad import Control.Monad.Codensity @@ -24,7 +24,6 @@ import Data.Id import Data.Qualified import Data.Set qualified as Set import Data.Text qualified as T -import Galley.Effects import Imports import Polysemy import Polysemy.Error diff --git a/services/galley/src/Galley/API/MLS/Welcome.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Welcome.hs similarity index 98% rename from services/galley/src/Galley/API/MLS/Welcome.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Welcome.hs index 115ad8faab1..aebf8969026 100644 --- a/services/galley/src/Galley/API/MLS/Welcome.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/MLS/Welcome.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.MLS.Welcome +module Wire.ConversationSubsystem.MLS.Welcome ( sendWelcomes, sendLocalWelcomes, ) @@ -29,7 +29,6 @@ import Data.Json.Util import Data.Map qualified as Map import Data.Qualified import Data.Time -import Galley.API.Push import Imports import Network.Wai.Utilities.JSONResponse import Polysemy @@ -52,6 +51,7 @@ import Wire.API.Push.V2 (RecipientClients (..)) import Wire.ExternalAccess import Wire.FederationAPIAccess import Wire.NotificationSubsystem +import Wire.NotificationSubsystem.PushUtils import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now diff --git a/services/galley/src/Galley/API/Message.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Message.hs similarity index 98% rename from services/galley/src/Galley/API/Message.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Message.hs index 1c033d83ac9..28c28f8e5e8 100644 --- a/services/galley/src/Galley/API/Message.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Message.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Message +module Wire.ConversationSubsystem.Message ( UserType (..), sendLocalMessages, postQualifiedOtrMessage, @@ -25,6 +25,7 @@ module Galley.API.Message Unqualify (..), userToProtectee, MessageMetadata (..), + IntraListing (..), -- * Only exported for tests checkMessageClients, @@ -49,11 +50,8 @@ import Data.Range import Data.Set qualified as Set import Data.Set.Lens import Data.Time.Clock (UTCTime) -import Galley.API.LegalHold.Conflicts -import Galley.API.Push -import Galley.Effects -import Galley.Options import Galley.Types.Clients qualified as Clients +import Wire.ExternalAccess import Imports hiding (forkIO) import Network.AMQP qualified as Q import Polysemy hiding (send) @@ -72,7 +70,7 @@ import Wire.API.Federation.Client (FederatorClient) import Wire.API.Federation.Error import Wire.API.Message import Wire.API.Routes.Public.Galley.Messaging -import Wire.API.Team.FeatureFlags (FanoutLimit) +import Wire.API.Team.FeatureFlags (FanoutLimit, FeatureFlags) import Wire.API.Team.LegalHold import Wire.API.Team.Member import Wire.API.User.Client @@ -83,7 +81,9 @@ import Wire.ConversationStore import Wire.ConversationSubsystem qualified as ConvSubsystem import Wire.ConversationSubsystem.Util import Wire.FederationAPIAccess +import Wire.LegalHoldStore.Conflicts import Wire.NotificationSubsystem (NotificationSubsystem) +import Wire.NotificationSubsystem.PushUtils import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now import Wire.StoredConversation @@ -94,6 +94,10 @@ import Wire.UserClientIndexStore data UserType = User | Bot -- FUTUREWORK: there is UserType in Wire.API.User now, should we use that? (there is also UserType variant for searcho/contacts, but there is a good reason for that one.) +newtype IntraListing + = IntraListing { unIntraListing :: Bool } + deriving stock (Eq, Ord, Show) + userToProtectee :: UserType -> UserId -> LegalholdProtectee userToProtectee User user = ProtectedUser user userToProtectee Bot _ = UnprotectedBot @@ -261,7 +265,7 @@ postBroadcast :: Member (ErrorS 'NonBindingTeam) r, Member (ErrorS 'BroadcastLimitExceeded) r, Member ExternalAccess r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, Member Now r, Member TeamStore r, Member P.TinyLog r, @@ -374,7 +378,8 @@ postQualifiedOtrMessage :: Member (FederationAPIAccess FederatorClient) r, Member BackendNotificationQueueAccess r, Member ExternalAccess r, - Member (Input Opts) r, + Member (Input IntraListing) r, + Member (Input FeatureFlags) r, Member Now r, Member P.TinyLog r, Member NotificationSubsystem r, @@ -413,7 +418,7 @@ postQualifiedOtrMessage senderType sender mconn lcnv msg = Set.fromList $ map (tUntagged . qualifyAs lcnv) localMemberIds <> map (tUntagged . (.id_)) conv.remoteMembers - isInternal <- view (settings . intraListing) <$> input + isInternal <- inputs unIntraListing -- check if the sender is part of the conversation unless (Set.member sender members) $ @@ -535,7 +540,7 @@ postQualifiedOtrMessage senderType sender mconn lcnv msg = guardQualifiedLegalholdPolicyConflictsWrapper :: ( Member BrigAPIAccess r, Member (Error (MessageNotSent MessageSendingStatus)) r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, Member P.TinyLog r, Member TeamSubsystem r ) => diff --git a/services/galley/src/Galley/API/Query.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Query.hs similarity index 93% rename from services/galley/src/Galley/API/Query.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Query.hs index 6904de09b2b..1b8cb64c3e6 100644 --- a/services/galley/src/Galley/API/Query.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Query.hs @@ -18,7 +18,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Query +module Wire.ConversationSubsystem.Query ( getBotConversation, getUnqualifiedOwnConversation, getOwnConversation, @@ -66,14 +66,6 @@ import Data.Qualified import Data.Range import Data.Set qualified as Set import Data.Tagged -import Galley.API.MLS -import Galley.API.MLS.Enabled -import Galley.API.MLS.One2One -import Galley.API.Mapping -import Galley.API.Mapping qualified as Mapping -import Galley.API.Teams.Features.Get -import Galley.Effects -import Galley.Env import Galley.Types.Error import Imports import Polysemy @@ -103,14 +95,20 @@ import Wire.API.Routes.MultiTablePaging qualified as Public import Wire.API.Team.Feature as Public import Wire.API.Team.Member (HiddenPerm (..), TeamMember) import Wire.API.User +import Wire.BrigAPIAccess import Wire.CodeStore import Wire.CodeStore.Code (Code (codeConversation)) import Wire.CodeStore.Code qualified as Data +import Wire.ConversationStore (ConversationStore) import Wire.ConversationStore qualified as E import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS +import Wire.ConversationSubsystem.MLS.Enabled +import Wire.ConversationSubsystem.MLS.One2One import Wire.ConversationSubsystem.One2One import Wire.ConversationSubsystem.Util import Wire.FeaturesConfigSubsystem +import Wire.FederationAPIAccess import Wire.FederationAPIAccess qualified as E import Wire.HashPassword (HashPassword) import Wire.RateLimit @@ -118,6 +116,7 @@ import Wire.Sem.Paging.Cassandra import Wire.StoredConversation import Wire.StoredConversation qualified as Data import Wire.TeamCollaboratorsSubsystem +import Wire.TeamStore import Wire.TeamSubsystem (TeamSubsystem) import Wire.TeamSubsystem qualified as TeamSubsystem import Wire.UserList @@ -151,16 +150,13 @@ getUnqualifiedOwnConversation :: ( Member ConversationStore r, Member (ErrorS 'ConvNotFound) r, Member (ErrorS 'ConvAccessDenied) r, - Member (Error InternalError) r, - Member P.TinyLog r, Member TeamSubsystem r ) => Local UserId -> ConvId -> - Sem r Public.OwnConversation -getUnqualifiedOwnConversation lusr cnv = do - c <- getConversationAsMember (tUntagged lusr) (qualifyAs lusr cnv) - Mapping.conversationViewV9 lusr c + Sem r StoredConversation +getUnqualifiedOwnConversation lusr cnv = + getConversationAsMember (tUntagged lusr) (qualifyAs lusr cnv) getUnqualifiedConversation :: forall r. @@ -171,10 +167,9 @@ getUnqualifiedConversation :: ) => Local UserId -> ConvId -> - Sem r Public.Conversation + Sem r ConvView getUnqualifiedConversation lusr cnv = - Mapping.conversationView (qualifyAs lusr ()) (Just lusr) . (.conv) - <$> getConversationAsViewer (tUntagged lusr) (qualifyAs lusr cnv) + getConversationAsViewer (tUntagged lusr) (qualifyAs lusr cnv) getConversation :: forall r. @@ -188,12 +183,12 @@ getConversation :: ) => Local UserId -> Qualified ConvId -> - Sem r Public.Conversation + Sem r ConvView getConversation lusr cnv = foldQualified lusr (getUnqualifiedConversation lusr . tUnqualified) - (fmap fromOwnConversation . getRemoteConversation lusr) + (error "TODO: gdf" . getRemoteConversation @r lusr) cnv getOwnConversation :: @@ -202,19 +197,18 @@ getOwnConversation :: Member (ErrorS 'ConvNotFound) r, Member (ErrorS 'ConvAccessDenied) r, Member (Error FederationError) r, - Member (Error InternalError) r, Member (FederationAPIAccess FederatorClient) r, Member P.TinyLog r, Member TeamSubsystem r ) => Local UserId -> Qualified ConvId -> - Sem r Public.OwnConversation + Sem r StoredConversation getOwnConversation lusr cnv = do foldQualified lusr (getUnqualifiedOwnConversation lusr . tUnqualified) - (getRemoteConversation lusr) + (error "TODO: gdf" . getRemoteConversation @r lusr) cnv getRemoteConversation :: @@ -256,11 +250,10 @@ getLocalConversationInternal :: Member ConversationStore r ) => ConvId -> - Sem r Conversation + Sem r StoredConversation getLocalConversationInternal cid = do lcid <- qualifyLocal cid - conv <- getConversationWithError lcid - pure $ conversationView (qualifyAs lcid ()) Nothing conv + getConversationWithError lcid data FailedGetConversationReason = FailedGetConversationLocally @@ -317,15 +310,16 @@ getRemoteConversationsWithFailures lusr convs = do -- get self member statuses from the database statusMap <- E.getRemoteConversationStatus (tUnqualified lusr) convs let remoteView :: Remote RemoteConversationV2 -> OwnConversation - remoteView rconv = - Mapping.remoteConversationView - lusr - ( Map.findWithDefault - defMemberStatus - ((.id) <$> rconv) - statusMap - ) - rconv + remoteView _rconv = + -- Mapping.remoteConversationView + -- lusr + -- ( Map.findWithDefault + -- defMemberStatus + -- ((.id) <$> rconv) + -- statusMap + -- ) + -- rconv + error "TODO: gdf" (locallyFound, locallyNotFound) = partition (flip Map.member statusMap) convs localFailures | null locallyNotFound = [] @@ -435,9 +429,7 @@ conversationIdsPageFromV2 listGlobalSelf lusr Public.GetMultiTablePageRequest {. conversationIdsPageFrom :: forall r. ( Member ConversationStore r, - Member (Error InternalError) r, - Member (Input Env) r, - Member P.TinyLog r + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r ) => Local UserId -> Public.GetPaginatedConversationIds -> @@ -455,18 +447,15 @@ conversationIdsPageFrom lusr state = do conversationIdsPageFromV2 ListGlobalSelf lusr state getConversations :: - ( Member (Error InternalError) r, - Member ConversationStore r, - Member P.TinyLog r - ) => + (Member ConversationStore r) => Local UserId -> Maybe (Range 1 32 (CommaSeparatedList ConvId)) -> Maybe ConvId -> Maybe (Range 1 500 Int32) -> - Sem r (Public.ConversationList Public.OwnConversation) + Sem r (Bool, [StoredConversation]) getConversations luser mids mstart msize = do ConversationList cs more <- getConversationsInternal luser mids mstart msize - flip ConversationList more <$> mapM (Mapping.conversationViewV9 luser) cs + pure (more, cs) getConversationsInternal :: (Member ConversationStore r) => @@ -502,7 +491,6 @@ getConversationsInternal luser mids mstart msize = do listConversations :: ( Member ConversationStore r, - Member (Error InternalError) r, Member (FederationAPIAccess FederatorClient) r, Member P.TinyLog r ) => @@ -517,7 +505,7 @@ listConversations luser (Public.ListConversations ids) = do localInternalConversations <- E.getConversations foundLocalIds >>= filterM (\c -> pure $ isMember (tUnqualified luser) c.localMembers) - localConversations <- mapM (Mapping.conversationViewV9 luser) localInternalConversations + localConversations <- (error "TODO: gdf") localInternalConversations (remoteFailures, remoteConversations) <- getRemoteConversationsWithFailures luser remoteIds let (failedConvsLocally, failedConvsRemotely) = partitionGetConversationFailures remoteFailures @@ -708,13 +696,11 @@ getConversationGuestLinksFeatureStatus (Just tid) = getFeatureForTeam tid getMLSSelfConversationWithError :: forall r. ( Member ConversationStore r, - Member (Error InternalError) r, Member (ErrorS 'MLSNotEnabled) r, - Member (Input Env) r, - Member P.TinyLog r + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r ) => Local UserId -> - Sem r OwnConversation + Sem r StoredConversation getMLSSelfConversationWithError lusr = do assertMLSEnabled getMLSSelfConversation lusr @@ -727,17 +713,13 @@ getMLSSelfConversationWithError lusr = do -- number. getMLSSelfConversation :: forall r. - ( Member ConversationStore r, - Member (Error InternalError) r, - Member P.TinyLog r - ) => + (Member ConversationStore r) => Local UserId -> - Sem r OwnConversation + Sem r StoredConversation getMLSSelfConversation lusr = do let selfConvId = mlsSelfConvId . tUnqualified $ lusr mconv <- E.getConversation selfConvId - cnv <- maybe (createMLSSelfConversation lusr) pure mconv - conversationViewV9 lusr cnv + maybe (createMLSSelfConversation lusr) pure mconv createMLSSelfConversation :: (Member ConversationStore r) => @@ -767,7 +749,7 @@ createMLSSelfConversation lusr = do getMLSOne2OneConversationV5 :: ( Member BrigAPIAccess r, Member ConversationStore r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (Error FederationError) r, Member (Error InternalError) r, Member (ErrorS 'MLSNotEnabled) r, @@ -791,7 +773,7 @@ getMLSOne2OneConversationInternal :: forall r. ( Member BrigAPIAccess r, Member ConversationStore r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (Error FederationError) r, Member (Error InternalError) r, Member (ErrorS 'MLSNotEnabled) r, @@ -812,7 +794,7 @@ getMLSOne2OneConversationV6 :: forall r. ( Member BrigAPIAccess r, Member ConversationStore r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (Error FederationError) r, Member (Error InternalError) r, Member (ErrorS 'MLSNotEnabled) r, @@ -839,7 +821,7 @@ getMLSOne2OneConversationV6 lself qother = do getMLSOne2OneConversation :: ( Member BrigAPIAccess r, Member ConversationStore r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (Error FederationError) r, Member (Error InternalError) r, Member (ErrorS 'MLSNotEnabled) r, @@ -861,9 +843,7 @@ getMLSOne2OneConversation lself qother fmt = do getLocalMLSOne2OneConversation :: ( Member ConversationStore r, - Member (Error InternalError) r, - Member P.TinyLog r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (ErrorS MLSNotEnabled) r ) => Local UserId -> @@ -874,7 +854,7 @@ getLocalMLSOne2OneConversation lself lconv = do keys <- mlsKeysToPublic <$$> getMLSPrivateKeys conv <- case mconv of Nothing -> pure (localMLSOne2OneConversation lself lconv) - Just conv -> conversationViewV9 lself conv + Just conv -> (error "TODO: gdf") conv pure $ MLSOne2OneConversation { conversation = conv, @@ -938,7 +918,7 @@ getRemoteMLSOne2OneConversation lself qother rconv = do -- two is responsible for hosting the conversation. isMLSOne2OneEstablished :: ( Member ConversationStore r, - Member (Input Env) r, + Member (Input (Maybe (MLSKeysByPurpose MLSPrivateKeys))) r, Member (Error FederationError) r, Member (Error InternalError) r, Member (ErrorS 'MLSNotEnabled) r, diff --git a/services/galley/src/Galley/API/Update.hs b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Update.hs similarity index 96% rename from services/galley/src/Galley/API/Update.hs rename to libs/wire-subsystems/src/Wire/ConversationSubsystem/Update.hs index 8df0cb3c142..69409d6f8d2 100644 --- a/services/galley/src/Galley/API/Update.hs +++ b/libs/wire-subsystems/src/Wire/ConversationSubsystem/Update.hs @@ -18,7 +18,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Update +module Wire.ConversationSubsystem.Update ( -- * Managing Conversations acceptConv, blockConv, @@ -74,11 +74,15 @@ module Galley.API.Update addBot, rmBot, postBotMessageUnqualified, + + -- * Configuration + GuestLinkTTLSeconds (..), ) where import Control.Error.Util (hush) import Control.Lens +import Data.Aeson import Data.Code import Data.Default import Data.Id @@ -90,15 +94,7 @@ import Data.Qualified import Data.Set qualified as Set import Data.Singletons import Data.Vector qualified as V -import Galley.API.Action -import Galley.API.Action.Kick (kickMember) -import Galley.API.Mapping -import Galley.API.Message -import Galley.API.Query qualified as Query -import Galley.API.Teams.Features.Get -import Galley.App -import Galley.Effects -import Galley.Options +import Wire.ConversationSubsystem.Message import Galley.Types.Error import Imports hiding (forkIO) import Polysemy @@ -128,51 +124,80 @@ import Wire.API.Routes.Public.Galley.Messaging import Wire.API.Routes.Public.Util (UpdateResult (..)) import Wire.API.ServantProto (RawProto (..)) import Wire.API.Team.Feature -import Wire.API.Team.FeatureFlags (FanoutLimit) +import Wire.API.Team.FeatureFlags (FanoutLimit, FeatureFlags) import Wire.API.Team.Member import Wire.API.User.Client import Wire.API.UserGroup +import Wire.BackendNotificationQueueAccess +import Wire.BrigAPIAccess import Wire.CodeStore (CodeStore) import Wire.CodeStore qualified as E import Wire.CodeStore.Code +import Wire.ConversationStore (ConversationStore) import Wire.ConversationStore qualified as E -import Wire.ConversationSubsystem +import Wire.ConversationSubsystem (ConversationSubsystem) +import Wire.ConversationSubsystem.Action +import Wire.ConversationSubsystem.Action.Kick (kickMember) +import Wire.ConversationSubsystem.Query qualified as Query import Wire.ConversationSubsystem.Util +import Wire.ExternalAccess import Wire.ExternalAccess qualified as E import Wire.FeaturesConfigSubsystem +import Wire.FederationAPIAccess import Wire.FederationAPIAccess qualified as E import Wire.FederationSubsystem +import Wire.FireAndForget import Wire.HashPassword as HashPassword +import Wire.LegalHoldStore import Wire.NotificationSubsystem +import Wire.ProposalStore import Wire.RateLimit import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now +import Wire.Sem.Random import Wire.StoredConversation import Wire.TeamCollaboratorsSubsystem +import Wire.TeamFeatureStore (TeamFeatureStore) +import Wire.TeamStore import Wire.TeamSubsystem (TeamSubsystem) import Wire.TeamSubsystem qualified as TeamSubsystem +import Wire.UserClientIndexStore import Wire.UserClientIndexStore qualified as E import Wire.UserGroupStore (UserGroupStore, getUserGroupsForConv) import Wire.UserList +newtype GuestLinkTTLSeconds = GuestLinkTTLSeconds + { unGuestLinkTTLSeconds :: Int + } + deriving (Show, Generic) + +instance FromJSON GuestLinkTTLSeconds where + parseJSON x = do + n <- parseJSON x + if n > 0 && n <= 31536000 + then pure $ GuestLinkTTLSeconds n + else fail "GuestLinkTTLSeconds must be in (0, 31536000]" + +-- | Default guest link TTL in days. 365 days if not set. +defGuestLinkTTLSeconds :: GuestLinkTTLSeconds +defGuestLinkTTLSeconds = GuestLinkTTLSeconds $ 60 * 60 * 24 * 365 -- 1 year + acceptConv :: ( Member ConversationStore r, Member (Error InternalError) r, Member (ErrorS 'ConvNotFound) r, Member (ErrorS 'InvalidOperation) r, Member NotificationSubsystem r, - Member Now r, - Member TinyLog r + Member Now r ) => Local UserId -> Maybe ConnId -> ConvId -> - Sem r OwnConversation + Sem r StoredConversation acceptConv lusr conn cnv = do conv <- E.getConversation cnv >>= noteS @'ConvNotFound - conv' <- acceptOne2One lusr conv conn - conversationViewV9 lusr conv' + acceptOne2One lusr conv conn blockConv :: ( Member ConversationStore r, @@ -222,8 +247,7 @@ unblockConv :: Member (ErrorS 'ConvNotFound) r, Member (ErrorS 'InvalidOperation) r, Member NotificationSubsystem r, - Member Now r, - Member TinyLog r + Member Now r ) => Local UserId -> Maybe ConnId -> @@ -241,20 +265,18 @@ unblockConvUnqualified :: Member (ErrorS 'ConvNotFound) r, Member (ErrorS 'InvalidOperation) r, Member NotificationSubsystem r, - Member Now r, - Member TinyLog r + Member Now r ) => Local UserId -> Maybe ConnId -> ConvId -> - Sem r OwnConversation + Sem r StoredConversation unblockConvUnqualified lusr conn cnv = do conv <- E.getConversation cnv >>= noteS @'ConvNotFound unless (convType conv `elem` [ConnectConv, One2OneConv]) $ throwS @'InvalidOperation - conv' <- acceptOne2One lusr conv conn - conversationViewV9 lusr conv' + acceptOne2One lusr conv conn unblockRemoteConv :: (Member ConversationStore r) => @@ -284,7 +306,7 @@ type UpdateConversationAccessEffects = FireAndForget, NotificationSubsystem, ConversationSubsystem, - Input Env, + -- Input Env, Input ConversationSubsystemConfig, ProposalStore, Random, @@ -570,7 +592,7 @@ addCodeUnqualifiedWithReqBody :: Member (Input (Local ())) r, Member Now r, Member HashPassword r, - Member (Input Opts) r, + Member (Input (Maybe GuestLinkTTLSeconds)) r, Member FeaturesConfigSubsystem r, Member RateLimit r, Member TeamSubsystem r @@ -595,7 +617,7 @@ addCodeUnqualified :: Member NotificationSubsystem r, Member (Input (Local ())) r, Member Now r, - Member (Input Opts) r, + Member (Input (Maybe GuestLinkTTLSeconds)) r, Member HashPassword r, Member FeaturesConfigSubsystem r, Member RateLimit r, @@ -624,7 +646,7 @@ addCode :: Member HashPassword r, Member NotificationSubsystem r, Member Now r, - Member (Input Opts) r, + Member (Input (Maybe GuestLinkTTLSeconds)) r, Member FeaturesConfigSubsystem r, Member RateLimit r, Member TeamSubsystem r @@ -646,7 +668,7 @@ addCode lusr mbZHost mZcon lcnv mReq = do key <- E.makeKey (tUnqualified lcnv) E.getCode key >>= \case Nothing -> do - ttl <- realToFrac . unGuestLinkTTLSeconds . fromMaybe defGuestLinkTTLSeconds . view (settings . guestLinkTTLSeconds) <$> input + ttl <- inputs $ realToFrac . unGuestLinkTTLSeconds . fromMaybe defGuestLinkTTLSeconds code <- E.generateCode (tUnqualified lcnv) (Timeout ttl) mPw <- for (mReq >>= (.password)) $ HashPassword.hashPassword8 (RateLimitUser (tUnqualified lusr)) E.createCode code mPw @@ -773,9 +795,9 @@ updateConversationProtocolWithLocalUser :: Member (ErrorS 'TeamNotFound) r, Member (Error InternalError) r, Member Now r, - Member (Input Env) r, + -- Member (Input Env) r, Member (Input (Local ())) r, - Member (Input Opts) r, + -- Member (Input Opts) r, Member BackendNotificationQueueAccess r, Member BrigAPIAccess r, Member ConversationStore r, @@ -1132,7 +1154,7 @@ replaceMembers :: Member ExternalAccess r, Member (FederationAPIAccess FederatorClient) r, Member NotificationSubsystem r, - Member (Input Env) r, + -- Member (Input Env) r, Member Now r, Member LegalHoldStore r, Member ProposalStore r, @@ -1365,7 +1387,7 @@ removeMemberUnqualified :: Member (FederationAPIAccess FederatorClient) r, Member NotificationSubsystem r, Member ConversationSubsystem r, - Member (Input Env) r, + -- Member (Input Env) r, Member Now r, Member ProposalStore r, Member Random r, @@ -1398,7 +1420,7 @@ removeMemberQualified :: Member (FederationAPIAccess FederatorClient) r, Member NotificationSubsystem r, Member ConversationSubsystem r, - Member (Input Env) r, + -- Member (Input Env) r, Member Now r, Member ProposalStore r, Member Random r, @@ -1479,7 +1501,7 @@ removeMemberFromLocalConv :: Member (FederationAPIAccess FederatorClient) r, Member NotificationSubsystem r, Member ConversationSubsystem r, - Member (Input Env) r, + -- Member (Input Env) r, Member Now r, Member ProposalStore r, Member Random r, @@ -1522,7 +1544,7 @@ removeMemberFromLocalConv lcnv lusr con victim removeMemberFromChannel :: forall r. ( Member (ErrorS 'ConvNotFound) r, - Member (Input Env) r, + -- Member (Input Env) r, Member (Error NoChanges) r, Member ProposalStore r, Member Now r, @@ -1566,7 +1588,8 @@ postProteusMessage :: Member BackendNotificationQueueAccess r, Member NotificationSubsystem r, Member ExternalAccess r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, + Member (Input IntraListing) r, Member Now r, Member TinyLog r, Member TeamSubsystem r @@ -1590,7 +1613,7 @@ postProteusBroadcast :: Member (ErrorS 'BroadcastLimitExceeded) r, Member NotificationSubsystem r, Member ExternalAccess r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, Member Now r, Member TeamStore r, Member TinyLog r, @@ -1644,7 +1667,8 @@ postBotMessageUnqualified :: Member BackendNotificationQueueAccess r, Member NotificationSubsystem r, Member (Input (Local ())) r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, + Member (Input IntraListing) r, Member TinyLog r, Member Now r, Member TeamSubsystem r @@ -1672,7 +1696,7 @@ postOtrBroadcastUnqualified :: Member (ErrorS 'BroadcastLimitExceeded) r, Member NotificationSubsystem r, Member ExternalAccess r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, Member Now r, Member TeamStore r, Member TinyLog r, @@ -1699,7 +1723,8 @@ postOtrMessageUnqualified :: Member BackendNotificationQueueAccess r, Member ExternalAccess r, Member NotificationSubsystem r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, + Member (Input IntraListing) r, Member Now r, Member TinyLog r, Member TeamSubsystem r diff --git a/services/galley/src/Galley/API/Teams/Features/Get.hs b/libs/wire-subsystems/src/Wire/FeaturesConfigSubsystem/Get.hs similarity index 98% rename from services/galley/src/Galley/API/Teams/Features/Get.hs rename to libs/wire-subsystems/src/Wire/FeaturesConfigSubsystem/Get.hs index b22a9bff7b0..e2a574cf209 100644 --- a/services/galley/src/Galley/API/Teams/Features/Get.hs +++ b/libs/wire-subsystems/src/Wire/FeaturesConfigSubsystem/Get.hs @@ -17,7 +17,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Teams.Features.Get +module Wire.FeaturesConfigSubsystem.Get ( getFeature, getFeatureInternal, getAllTeamFeaturesForServer, @@ -37,7 +37,6 @@ import Control.Error (hush) import Data.Id import Data.SOP import Data.Tagged -import Galley.Effects import Imports import Polysemy import Polysemy.Error @@ -50,6 +49,7 @@ import Wire.ConversationStore as ConversationStore import Wire.ConversationSubsystem.Util import Wire.FeaturesConfigSubsystem import Wire.FeaturesConfigSubsystem.Types +import Wire.TeamStore import Wire.TeamStore qualified as TeamStore import Wire.TeamSubsystem (TeamSubsystem) import Wire.TeamSubsystem qualified as TeamSubsystem diff --git a/services/galley/src/Galley/API/LegalHold/Conflicts.hs b/libs/wire-subsystems/src/Wire/LegalHoldStore/Conflicts.hs similarity index 95% rename from services/galley/src/Galley/API/LegalHold/Conflicts.hs rename to libs/wire-subsystems/src/Wire/LegalHoldStore/Conflicts.hs index 08857a060e5..2b3a7368d44 100644 --- a/services/galley/src/Galley/API/LegalHold/Conflicts.hs +++ b/libs/wire-subsystems/src/Wire/LegalHoldStore/Conflicts.hs @@ -17,7 +17,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.LegalHold.Conflicts +module Wire.LegalHoldStore.Conflicts ( guardQualifiedLegalholdPolicyConflicts, guardLegalholdPolicyConflicts, LegalholdConflicts (LegalholdConflicts), @@ -25,7 +25,7 @@ module Galley.API.LegalHold.Conflicts ) where -import Control.Lens (to, view, (^.)) +import Control.Lens ((^.)) import Data.ByteString.Conversion (toByteString') import Data.Id import Data.LegalHold (UserLegalHoldStatus (..)) @@ -33,8 +33,6 @@ import Data.Map qualified as Map import Data.Misc import Data.Qualified import Data.Set qualified as Set -import Galley.Effects -import Galley.Options import Imports import Polysemy import Polysemy.Error @@ -60,7 +58,7 @@ guardQualifiedLegalholdPolicyConflicts :: ( Member BrigAPIAccess r, Member (Error LegalholdConflicts) r, Member (Input (Local ())) r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, Member P.TinyLog r, Member TeamSubsystem r ) => @@ -84,7 +82,7 @@ guardQualifiedLegalholdPolicyConflicts protectee qclients = do guardLegalholdPolicyConflicts :: ( Member BrigAPIAccess r, Member (Error LegalholdConflicts) r, - Member (Input Opts) r, + Member (Input FeatureFlags) r, Member P.TinyLog r, Member TeamSubsystem r ) => @@ -94,8 +92,8 @@ guardLegalholdPolicyConflicts :: guardLegalholdPolicyConflicts LegalholdPlusFederationNotImplemented _otherClients = pure () guardLegalholdPolicyConflicts UnprotectedBot _otherClients = pure () guardLegalholdPolicyConflicts (ProtectedUser self) otherClients = do - opts <- input - case view (settings . featureFlags . to npProject) opts of + opts <- input @FeatureFlags + case npProject opts of FeatureLegalHoldDisabledPermanently -> case FutureWork @'LegalholdPlusFederationNotImplemented () of FutureWork () -> -- FUTUREWORK: once we support federation and LH in combination, we still need to run @@ -108,7 +106,7 @@ guardLegalholdPolicyConflicts (ProtectedUser self) otherClients = do -- | Guard notification handling against legal-hold policy conflicts. -- Ensures that if any user has a LH client then no user can be missing consent. -- See also: "Brig.API.Connection.checkLegalholdPolicyConflict" --- and "Galley.API.Action.checkLHPolicyConflictsLocal". +-- and "Wire.ConversationSubsystem.Action.checkLHPolicyConflictsLocal". guardLegalholdPolicyConflictsUid :: forall r. ( Member BrigAPIAccess r, diff --git a/services/galley/src/Galley/API/LegalHold/Get.hs b/libs/wire-subsystems/src/Wire/LegalHoldStore/Get.hs similarity index 97% rename from services/galley/src/Galley/API/LegalHold/Get.hs rename to libs/wire-subsystems/src/Wire/LegalHoldStore/Get.hs index 37c90544250..05afa7c1750 100644 --- a/services/galley/src/Galley/API/LegalHold/Get.hs +++ b/libs/wire-subsystems/src/Wire/LegalHoldStore/Get.hs @@ -15,14 +15,13 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.LegalHold.Get (getUserStatus) where +module Wire.LegalHoldStore.Get (getUserStatus) where import Control.Lens (view) import Data.ByteString.Conversion (toByteString') import Data.Id import Data.LegalHold (UserLegalHoldStatus (..)) import Data.Qualified -import Galley.Effects import Galley.Types.Error import Imports import Polysemy @@ -35,6 +34,7 @@ import Wire.API.Team.LegalHold import Wire.API.Team.LegalHold qualified as Public import Wire.API.Team.Member import Wire.API.User.Client.Prekey +import Wire.LegalHoldStore import Wire.LegalHoldStore qualified as LegalHoldData import Wire.TeamSubsystem (TeamSubsystem) import Wire.TeamSubsystem qualified as TeamSubsystem diff --git a/services/galley/src/Galley/API/Push.hs b/libs/wire-subsystems/src/Wire/NotificationSubsystem/PushUtils.hs similarity index 98% rename from services/galley/src/Galley/API/Push.hs rename to libs/wire-subsystems/src/Wire/NotificationSubsystem/PushUtils.hs index 404506590d9..e37f98925df 100644 --- a/services/galley/src/Galley/API/Push.hs +++ b/libs/wire-subsystems/src/Wire/NotificationSubsystem/PushUtils.hs @@ -18,7 +18,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Galley.API.Push +module Wire.NotificationSubsystem.PushUtils ( -- * Message pushes MessagePush (..), diff --git a/libs/wire-subsystems/wire-subsystems.cabal b/libs/wire-subsystems/wire-subsystems.cabal index 77419041f76..92977503a93 100644 --- a/libs/wire-subsystems/wire-subsystems.cabal +++ b/libs/wire-subsystems/wire-subsystems.cabal @@ -102,6 +102,7 @@ common common-all , bytestring-conversion , case-insensitive , cassandra-util + , comonad , conduit , constraints , containers @@ -139,6 +140,7 @@ common common-all , imports , iproute , iso639 + , kan-extensions , lens , lrucaching , memory @@ -248,8 +250,39 @@ library Wire.ConversationStore.MLS.Types Wire.ConversationStore.Postgres Wire.ConversationSubsystem + Wire.ConversationSubsystem.Action + Wire.ConversationSubsystem.Action.Kick + Wire.ConversationSubsystem.Action.Leave + Wire.ConversationSubsystem.Action.Notify + Wire.ConversationSubsystem.Action.Reset Wire.ConversationSubsystem.Interpreter + Wire.ConversationSubsystem.Message + Wire.ConversationSubsystem.MLS + Wire.ConversationSubsystem.MLS.CheckClients + Wire.ConversationSubsystem.MLS.Commit + Wire.ConversationSubsystem.MLS.Commit.Core + Wire.ConversationSubsystem.MLS.Commit.ExternalCommit + Wire.ConversationSubsystem.MLS.Commit.InternalCommit + Wire.ConversationSubsystem.MLS.Conversation + Wire.ConversationSubsystem.MLS.Enabled + Wire.ConversationSubsystem.MLS.GroupInfo + Wire.ConversationSubsystem.MLS.GroupInfoCheck + Wire.ConversationSubsystem.MLS.IncomingMessage + Wire.ConversationSubsystem.MLS.Keys + Wire.ConversationSubsystem.MLS.Message + Wire.ConversationSubsystem.MLS.Migration + Wire.ConversationSubsystem.MLS.One2One + Wire.ConversationSubsystem.MLS.OutOfSync + Wire.ConversationSubsystem.MLS.Propagate + Wire.ConversationSubsystem.MLS.Proposal + Wire.ConversationSubsystem.MLS.Removal + Wire.ConversationSubsystem.MLS.Reset + Wire.ConversationSubsystem.MLS.SubConversation + Wire.ConversationSubsystem.MLS.Util + Wire.ConversationSubsystem.MLS.Welcome + Wire.ConversationSubsystem.Query Wire.ConversationSubsystem.One2One + Wire.ConversationSubsystem.Update Wire.ConversationSubsystem.Util Wire.DeleteQueue Wire.DeleteQueue.InMemory @@ -274,6 +307,7 @@ library Wire.ExternalAccess Wire.ExternalAccess.External Wire.FeaturesConfigSubsystem + Wire.FeaturesConfigSubsystem.Get Wire.FeaturesConfigSubsystem.Interpreter Wire.FeaturesConfigSubsystem.Types Wire.FeaturesConfigSubsystem.Utils @@ -311,7 +345,9 @@ library Wire.LegalHoldStore Wire.LegalHoldStore.Cassandra Wire.LegalHoldStore.Cassandra.Queries + Wire.LegalHoldStore.Conflicts Wire.LegalHoldStore.Env + Wire.LegalHoldStore.Get Wire.ListItems Wire.MeetingsStore Wire.MeetingsStore.Postgres @@ -321,6 +357,7 @@ library Wire.MigrationLock Wire.NotificationSubsystem Wire.NotificationSubsystem.Interpreter + Wire.NotificationSubsystem.PushUtils Wire.PaginationState Wire.ParseException Wire.PasswordResetCodeStore diff --git a/services/background-worker/background-worker.cabal b/services/background-worker/background-worker.cabal index 67f15e28abc..ac5b616af5a 100644 --- a/services/background-worker/background-worker.cabal +++ b/services/background-worker/background-worker.cabal @@ -39,6 +39,7 @@ library , bytestring-conversion , cassandra-util , containers + , cql-io , data-timeout , exceptions , extended diff --git a/services/background-worker/background-worker.integration.yaml b/services/background-worker/background-worker.integration.yaml index 167dfc498b9..1abe7b359e4 100644 --- a/services/background-worker/background-worker.integration.yaml +++ b/services/background-worker/background-worker.integration.yaml @@ -83,3 +83,17 @@ postgresMigration: conversation: postgresql conversationCodes: postgresql teamFeatures: postgresql + + settings: + # Either `conversationCodeURI` or `multiIngress` must be set + # conversationCodeURI is the URI prefix for conversation invitation links + # It should be of form https://{ACCOUNT_PAGES}/conversation-join/ + conversationCodeURI: https://account.wire.com/conversation-join/ + # multiIngress is a Z-Host dependent setting of conversationCodeURI. + # Use this only if you want to expose the instance on multiple ingresses. + # If set it must be a map from Z-Host to URI prefix + # Example: + # multiIngress: + # wire.example: https://accounts.wire.example/conversation-join/ + # example.net: https://accounts.example.net/conversation-join/ + multiIngress: null diff --git a/services/background-worker/default.nix b/services/background-worker/default.nix index df8fcd9b573..1d40f9dc9f0 100644 --- a/services/background-worker/default.nix +++ b/services/background-worker/default.nix @@ -11,6 +11,7 @@ , bytestring-conversion , cassandra-util , containers +, cql-io , data-default , data-timeout , exceptions @@ -70,6 +71,7 @@ mkDerivation { bytestring-conversion cassandra-util containers + cql-io data-timeout exceptions extended diff --git a/services/background-worker/src/Wire/BackgroundWorker/Env.hs b/services/background-worker/src/Wire/BackgroundWorker/Env.hs index 4af2a9df1bc..a4015c08507 100644 --- a/services/background-worker/src/Wire/BackgroundWorker/Env.hs +++ b/services/background-worker/src/Wire/BackgroundWorker/Env.hs @@ -1,5 +1,4 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE RecordWildCards #-} -- This file is part of the Wire Server implementation. -- @@ -26,7 +25,8 @@ import Control.Monad.Base import Control.Monad.Catch import Control.Monad.Trans.Control import Data.Domain (Domain) -import Data.Map.Strict qualified as Map +import Data.Map qualified as Map +import Data.Misc (HttpsUrl) import HTTP2.Client.Manager import Hasql.Pool qualified as Hasql import Hasql.Pool.Extended @@ -86,7 +86,8 @@ data Env = Env gundeckEndpoint :: Endpoint, sparEndpoint :: Endpoint, galleyEndpoint :: Endpoint, - brigEndpoint :: Endpoint + brigEndpoint :: Endpoint, + convCodeURI :: Either HttpsUrl (Map Text HttpsUrl) } data BackendNotificationMetrics = BackendNotificationMetrics @@ -106,6 +107,14 @@ mkWorkerRunningGauge :: IO (Vector Text Gauge) mkWorkerRunningGauge = register (vector "worker" $ gauge $ Prometheus.Info "wire_background_worker_running_workers" "Set to 1 when a worker is running") +validateSettings :: Opts -> IO (Either HttpsUrl (Map Text HttpsUrl)) +validateSettings opts = + case (opts.settings.conversationCodeURI, opts.settings.multiIngress) of + (Nothing, Nothing) -> error "Either settings.conversationCodeURI or settings.multiIngress must be set" + (Just uri, Nothing) -> pure (Left uri) + (Nothing, Just mi) -> pure (Right mi) + (Just _, Just _) -> error "settings.conversationCodeURI and settings.multiIngress are mutually exclusive" + mkEnv :: Opts -> IO Env mkEnv opts = do logger <- Log.mkLogger opts.logLevel Nothing opts.logFormat @@ -129,6 +138,8 @@ mkEnv opts = do (BackgroundJobConsumer, False) ] backendNotificationMetrics <- mkBackendNotificationMetrics + convCodeURI <- validateSettings opts + workerRunningGauge <- mkWorkerRunningGauge let backendNotificationsConfig = opts.backendNotificationPusher backgroundJobsConfig = opts.backgroundJobs federationDomain = opts.federationDomain @@ -137,7 +148,6 @@ mkEnv opts = do galleyEndpoint = opts.galley gundeckEndpoint = opts.gundeck sparEndpoint = opts.spar - workerRunningGauge <- mkWorkerRunningGauge hasqlPool <- initPostgresPool opts.postgresqlPool opts.postgresql opts.postgresqlPassword amqpJobsPublisherChannel <- mkRabbitMqChannelMVar logger (Just "background-worker-jobs-publisher") $ @@ -145,7 +155,34 @@ mkEnv opts = do amqpBackendNotificationsChannel <- mkRabbitMqChannelMVar logger (Just "background-worker-backend-notifications") $ either id demoteOpts opts.rabbitmq.unRabbitMqOpts - pure Env {..} + pure + Env + { http2Manager, + rabbitmqAdminClient, + rabbitmqVHost, + logger, + federatorInternal, + httpManager, + defederationTimeout, + backendNotificationMetrics, + backendNotificationsConfig, + backgroundJobsConfig, + workerRunningGauge, + statuses, + cassandra, + cassandraGalley, + cassandraBrig, + hasqlPool, + amqpJobsPublisherChannel, + amqpBackendNotificationsChannel, + federationDomain, + postgresMigration, + convCodeURI, + gundeckEndpoint, + sparEndpoint, + galleyEndpoint, + brigEndpoint + } initHttp2Manager :: IO Http2Manager initHttp2Manager = do diff --git a/services/background-worker/src/Wire/BackgroundWorker/Jobs/Registry.hs b/services/background-worker/src/Wire/BackgroundWorker/Jobs/Registry.hs index ee2ab48773b..521ca6a4727 100644 --- a/services/background-worker/src/Wire/BackgroundWorker/Jobs/Registry.hs +++ b/services/background-worker/src/Wire/BackgroundWorker/Jobs/Registry.hs @@ -32,8 +32,9 @@ import Data.Qualified import Data.Tagged (Tagged) import Data.Text qualified as T import Data.Text.Lazy qualified as TL +import Database.CQL.IO (ClientState) import Galley.Types.Error (InternalError, InvalidInput, internalErrorDescription, legalHoldServiceUnavailable) -import Hasql.Pool (UsageError) +import Hasql.Pool (Pool, UsageError) import Imports import Network.HTTP.Client qualified as Http import OpenSSL.Session qualified as SSL @@ -59,6 +60,10 @@ import Wire.BackgroundJobsRunner (runJob) import Wire.BackgroundJobsRunner.Interpreter hiding (runJob) import Wire.BackgroundWorker.Env (AppT, Env (..)) import Wire.BrigAPIAccess.Rpc +import Wire.CodeStore (CodeStore) +import Wire.CodeStore.Cassandra +import Wire.CodeStore.DualWrite +import Wire.CodeStore.Postgres import Wire.ConversationStore.Cassandra import Wire.ConversationStore.Postgres (interpretConversationStoreToPostgres) import Wire.ConversationSubsystem.Interpreter (interpretConversationSubsystem) @@ -76,6 +81,7 @@ import Wire.LegalHoldStore.Env (LegalHoldEnv (..)) import Wire.NotificationSubsystem.Interpreter import Wire.ParseException import Wire.PostgresMigrationOpts +import Wire.ProposalStore.Cassandra (interpretProposalStoreToCassandra) import Wire.Rpc import Wire.Sem.Concurrency (ConcurrencySafety (Unsafe)) import Wire.Sem.Concurrency.IO (unsafelyPerformConcurrency) @@ -174,6 +180,19 @@ dispatchJob job = do let makeReq fpr url rb = makeVerifiedRequestIO env.logger extEnv fpr url rb makeReqFresh fpr url rb = makeVerifiedRequestFreshManagerIO env.logger fpr url rb in LegalHoldEnv {makeVerifiedRequest = makeReq, makeVerifiedRequestFreshManager = makeReqFresh} + convCodesStoreInterpreter :: + ( Member (Input (Either HttpsUrl (Map Text HttpsUrl))) r, + Member (Input Pool) r, + Member (Error UsageError) r, + Member (Input ClientState) r, + Member (Embed IO) r + ) => + InterpreterFor CodeStore r + convCodesStoreInterpreter = + case env.postgresMigration.conversationCodes of + CassandraStorage -> interpretCodeStoreToCassandra + MigrationToPostgresql -> interpretCodeStoreToCassandraAndPostgres + PostgresqlStorage -> interpretCodeStoreToPostgres runFinal @IO . unsafelyPerformConcurrency @_ @'Unsafe . embedToFinal @IO @@ -212,6 +231,7 @@ dispatchJob job = do . runInputConst env.cassandraGalley . runInputConst legalHoldEnv . runInputConst (ExposeInvitationURLsAllowlist []) + . runInputConst env.convCodeURI . interpretServiceStoreToCassandra env.cassandraBrig . interpretUserStoreCassandra env.cassandraBrig . interpretUserGroupStoreToPostgres @@ -244,6 +264,8 @@ dispatchJob job = do . runFeaturesConfigSubsystem . runInputSem getAllTeamFeaturesForServer . interpretTeamCollaboratorsSubsystem + . convCodesStoreInterpreter + . interpretProposalStoreToCassandra . interpretConversationSubsystem . interpretBackgroundJobsRunner diff --git a/services/background-worker/src/Wire/BackgroundWorker/Options.hs b/services/background-worker/src/Wire/BackgroundWorker/Options.hs index 981fc7538d7..458c23c23c0 100644 --- a/services/background-worker/src/Wire/BackgroundWorker/Options.hs +++ b/services/background-worker/src/Wire/BackgroundWorker/Options.hs @@ -19,13 +19,14 @@ module Wire.BackgroundWorker.Options where import Data.Aeson import Data.Domain (Domain) +import Data.Map import Data.Misc import Data.Range (Range) import GHC.Generics import Hasql.Pool.Extended import Imports import Network.AMQP.Extended -import System.Logger.Extended +import System.Logger.Extended hiding (Settings) import Util.Options import Wire.Migration import Wire.PostgresMigrationOpts @@ -57,7 +58,8 @@ data Opts = Opts migrateConversationCodes :: !Bool, migrateTeamFeatures :: !Bool, backgroundJobs :: BackgroundJobsConfig, - federationDomain :: Domain + federationDomain :: Domain, + settings :: !Settings } deriving (Show, Generic) deriving (FromJSON) via Generically Opts @@ -99,3 +101,13 @@ data BackgroundJobsConfig = BackgroundJobsConfig } deriving (Show, Generic) deriving (FromJSON) via Generically BackgroundJobsConfig + +data Settings = Settings + { -- | URI prefix for conversations with access mode 'code' + conversationCodeURI :: !(Maybe HttpsUrl), + -- | Map from Z-Host header to URI prefix for conversations with access mode 'code' + -- conversationCodeURI and multiIngress are mutually exclusive. One of both must be configured. + multiIngress :: !(Maybe (Map Text HttpsUrl)) + } + deriving (Show, Generic) + deriving (FromJSON) via Generically Settings diff --git a/services/background-worker/test/Test/Wire/BackendNotificationPusherSpec.hs b/services/background-worker/test/Test/Wire/BackendNotificationPusherSpec.hs index bb326d7ff0d..fdd9c63de66 100644 --- a/services/background-worker/test/Test/Wire/BackendNotificationPusherSpec.hs +++ b/services/background-worker/test/Test/Wire/BackendNotificationPusherSpec.hs @@ -371,6 +371,7 @@ spec = do brigEndpoint = undefined sparEndpoint = undefined galleyEndpoint = undefined + convCodeURI = undefined backendNotificationMetrics <- mkBackendNotificationMetrics workerRunningGauge <- mkWorkerRunningGauge @@ -412,6 +413,7 @@ spec = do brigEndpoint = undefined sparEndpoint = undefined galleyEndpoint = undefined + convCodeURI = undefined backendNotificationMetrics <- mkBackendNotificationMetrics workerRunningGauge <- mkWorkerRunningGauge domainsThread <- async $ runAppT Env {..} $ getRemoteDomains (fromJust rabbitmqAdminClient) diff --git a/services/background-worker/test/Test/Wire/Util.hs b/services/background-worker/test/Test/Wire/Util.hs index 9810b9c2659..ad47dca48c0 100644 --- a/services/background-worker/test/Test/Wire/Util.hs +++ b/services/background-worker/test/Test/Wire/Util.hs @@ -68,6 +68,7 @@ testEnv = do brigEndpoint = undefined sparEndpoint = Endpoint "localhost" 0 galleyEndpoint = undefined + convCodeURI = undefined pure Env {..} runTestAppT :: AppT IO a -> Int -> IO a diff --git a/services/brig/src/Brig/API/Connection.hs b/services/brig/src/Brig/API/Connection.hs index ce2390f04cc..8afae3246b8 100644 --- a/services/brig/src/Brig/API/Connection.hs +++ b/services/brig/src/Brig/API/Connection.hs @@ -196,8 +196,8 @@ createConnectionToLocalUser self conn target = do -- | Guard local connection creation against legal-hold consent conflicts. -- Rejects when one user is `no_consent` while the other has LH enabled. --- See also: "Galley.API.LegalHold.Conflicts.guardLegalholdPolicyConflictsUid" --- and "Galley.API.Action.checkLHPolicyConflictsLocal". +-- See also: "Wire.LegalHoldStore.Conflicts.guardLegalholdPolicyConflictsUid" +-- and "Wire.ConversationSubsystem.Action.checkLHPolicyConflictsLocal". -- -- FUTUREWORK: we may want to move this to the LH application logic, so we can recycle it for -- group conv creation and possibly other situations. diff --git a/services/galley/galley.cabal b/services/galley/galley.cabal index f0586d727e9..b0549e07f9e 100644 --- a/services/galley/galley.cabal +++ b/services/galley/galley.cabal @@ -73,46 +73,15 @@ library -- cabal-fmt: expand src exposed-modules: - Galley.API.Action - Galley.API.Action.Kick - Galley.API.Action.Leave - Galley.API.Action.Notify - Galley.API.Action.Reset Galley.API.Clients Galley.API.Create Galley.API.CustomBackend Galley.API.Federation Galley.API.Internal Galley.API.LegalHold - Galley.API.LegalHold.Conflicts - Galley.API.LegalHold.Get Galley.API.LegalHold.Team Galley.API.Mapping Galley.API.Meetings - Galley.API.Message - Galley.API.MLS - Galley.API.MLS.CheckClients - Galley.API.MLS.Commit - Galley.API.MLS.Commit.Core - Galley.API.MLS.Commit.ExternalCommit - Galley.API.MLS.Commit.InternalCommit - Galley.API.MLS.Conversation - Galley.API.MLS.Enabled - Galley.API.MLS.GroupInfo - Galley.API.MLS.GroupInfoCheck - Galley.API.MLS.IncomingMessage - Galley.API.MLS.Keys - Galley.API.MLS.Message - Galley.API.MLS.Migration - Galley.API.MLS.One2One - Galley.API.MLS.OutOfSync - Galley.API.MLS.Propagate - Galley.API.MLS.Proposal - Galley.API.MLS.Removal - Galley.API.MLS.Reset - Galley.API.MLS.SubConversation - Galley.API.MLS.Util - Galley.API.MLS.Welcome Galley.API.Public.Bot Galley.API.Public.Conversation Galley.API.Public.CustomBackend @@ -126,12 +95,9 @@ library Galley.API.Public.TeamConversation Galley.API.Public.TeamMember Galley.API.Public.TeamNotification - Galley.API.Push - Galley.API.Query Galley.API.Teams Galley.API.Teams.Export Galley.API.Teams.Features - Galley.API.Teams.Features.Get Galley.API.Teams.Notifications Galley.API.Update Galley.App @@ -554,7 +520,7 @@ test-suite galley-tests other-modules: Paths_galley Run - Test.Galley.API.Message + Test.Wire.ConversationSubsystem.Message Test.Galley.API.One2One Test.Galley.Mapping diff --git a/services/galley/src/Galley/API/Clients.hs b/services/galley/src/Galley/API/Clients.hs index ef167dcf500..b3813e7c313 100644 --- a/services/galley/src/Galley/API/Clients.hs +++ b/services/galley/src/Galley/API/Clients.hs @@ -25,8 +25,6 @@ import Data.Id import Data.Proxy import Data.Qualified import Data.Range -import Galley.API.MLS.Removal -import Galley.API.Query qualified as Query import Galley.Effects import Galley.Env import Galley.Types.Clients (clientIds) @@ -47,6 +45,8 @@ import Wire.API.Routes.MultiTablePaging import Wire.BackendNotificationQueueAccess import Wire.ConversationStore (getConversation) import Wire.ConversationSubsystem qualified as ConvSubsystem +import Wire.ConversationSubsystem.MLS.Removal +import Wire.ConversationSubsystem.Query qualified as Query import Wire.ConversationSubsystem.Util import Wire.NotificationSubsystem import Wire.Sem.Now (Now) diff --git a/services/galley/src/Galley/API/Federation.hs b/services/galley/src/Galley/API/Federation.hs index f5daa7ff3d5..c1b013a9a37 100644 --- a/services/galley/src/Galley/API/Federation.hs +++ b/services/galley/src/Galley/API/Federation.hs @@ -36,20 +36,9 @@ import Data.Set qualified as Set import Data.Singletons (SingI (..), demote, sing) import Data.Tagged import Data.Text.Lazy qualified as LT -import Galley.API.Action -import Galley.API.MLS -import Galley.API.MLS.Enabled -import Galley.API.MLS.GroupInfo -import Galley.API.MLS.Message -import Galley.API.MLS.One2One -import Galley.API.MLS.Removal -import Galley.API.MLS.SubConversation hiding (leaveSubConversation) -import Galley.API.MLS.Util -import Galley.API.MLS.Welcome import Galley.API.Mapping import Galley.API.Mapping qualified as Mapping -import Galley.API.Message -import Galley.API.Push +import Wire.ConversationSubsystem.Message import Galley.App import Galley.Effects import Galley.Options @@ -96,11 +85,22 @@ import Wire.API.User (BaseProtocolTag (..)) import Wire.CodeStore import Wire.ConversationStore qualified as E import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action +import Wire.ConversationSubsystem.MLS +import Wire.ConversationSubsystem.MLS.Enabled +import Wire.ConversationSubsystem.MLS.GroupInfo +import Wire.ConversationSubsystem.MLS.Message +import Wire.ConversationSubsystem.MLS.One2One +import Wire.ConversationSubsystem.MLS.Removal +import Wire.ConversationSubsystem.MLS.SubConversation hiding (leaveSubConversation) +import Wire.ConversationSubsystem.MLS.Util +import Wire.ConversationSubsystem.MLS.Welcome import Wire.ConversationSubsystem.Util import Wire.FeaturesConfigSubsystem import Wire.FederationSubsystem (FederationSubsystem) import Wire.FireAndForget qualified as E import Wire.NotificationSubsystem +import Wire.NotificationSubsystem.PushUtils import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now import Wire.StoredConversation diff --git a/services/galley/src/Galley/API/Internal.hs b/services/galley/src/Galley/API/Internal.hs index d1e146b7537..78dbe271680 100644 --- a/services/galley/src/Galley/API/Internal.hs +++ b/services/galley/src/Galley/API/Internal.hs @@ -37,18 +37,13 @@ import Data.Qualified import Data.Range import Data.Singletons import Data.Time -import Galley.API.Action import Galley.API.Clients qualified as Clients import Galley.API.Create qualified as Create import Galley.API.LegalHold (unsetTeamLegalholdWhitelistedH) -import Galley.API.LegalHold.Conflicts -import Galley.API.MLS.Removal import Galley.API.Public.Servant -import Galley.API.Query qualified as Query import Galley.API.Teams import Galley.API.Teams qualified as Teams import Galley.API.Teams.Features -import Galley.API.Teams.Features.Get import Galley.API.Update qualified as Update import Galley.App import Galley.Effects @@ -92,11 +87,16 @@ import Wire.ConversationStore import Wire.ConversationStore qualified as E import Wire.ConversationStore.MLS.Types import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action +import Wire.ConversationSubsystem.MLS.Removal import Wire.ConversationSubsystem.One2One +import Wire.ConversationSubsystem.Query qualified as Query import Wire.ConversationSubsystem.Util import Wire.FeaturesConfigSubsystem (FeaturesConfigSubsystem) +import Wire.FeaturesConfigSubsystem.Get import Wire.FederationSubsystem (getFederationStatus) import Wire.LegalHoldStore as LegalHoldStore +import Wire.LegalHoldStore.Conflicts import Wire.NotificationSubsystem import Wire.Sem.Now (Now) import Wire.Sem.Now qualified as Now diff --git a/services/galley/src/Galley/API/LegalHold.hs b/services/galley/src/Galley/API/LegalHold.hs index 322ae323194..a6f58031162 100644 --- a/services/galley/src/Galley/API/LegalHold.hs +++ b/services/galley/src/Galley/API/LegalHold.hs @@ -41,9 +41,7 @@ import Data.Misc import Data.Proxy (Proxy (Proxy)) import Data.Qualified import Data.Range (toRange) -import Galley.API.LegalHold.Get import Galley.API.LegalHold.Team -import Galley.API.Query (iterateConversations) import Galley.API.Update (removeMemberFromLocalConv) import Galley.App import Galley.Effects @@ -79,11 +77,13 @@ import Wire.API.User.Client.Prekey import Wire.BrigAPIAccess import Wire.ConversationStore import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Query (iterateConversations) import Wire.ConversationSubsystem.Util import Wire.FeaturesConfigSubsystem import Wire.FederationSubsystem (FederationSubsystem) import Wire.FireAndForget import Wire.LegalHoldStore qualified as LegalHoldData +import Wire.LegalHoldStore.Get import Wire.NotificationSubsystem import Wire.Sem.Now (Now) import Wire.Sem.Paging diff --git a/services/galley/src/Galley/API/Public/Bot.hs b/services/galley/src/Galley/API/Public/Bot.hs index 1a28c98dfe3..0eca89c6e31 100644 --- a/services/galley/src/Galley/API/Public/Bot.hs +++ b/services/galley/src/Galley/API/Public/Bot.hs @@ -19,7 +19,6 @@ module Galley.API.Public.Bot where import Data.Id import Data.Qualified -import Galley.API.Query qualified as Query import Galley.API.Teams.Features qualified as Features import Galley.API.Update import Galley.App @@ -33,6 +32,7 @@ import Wire.API.Event.Team qualified as Public () import Wire.API.Provider.Bot import Wire.API.Routes.API import Wire.API.Routes.Public.Galley.Bot +import Wire.ConversationSubsystem.Query qualified as Query import Wire.FeaturesConfigSubsystem (FeaturesConfigSubsystem) import Wire.TeamSubsystem (TeamSubsystem) diff --git a/services/galley/src/Galley/API/Public/Conversation.hs b/services/galley/src/Galley/API/Public/Conversation.hs index cbab0c5663a..6bf80a3c9ee 100644 --- a/services/galley/src/Galley/API/Public/Conversation.hs +++ b/services/galley/src/Galley/API/Public/Conversation.hs @@ -18,15 +18,15 @@ module Galley.API.Public.Conversation where import Galley.API.Create -import Galley.API.MLS.GroupInfo -import Galley.API.MLS.SubConversation -import Galley.API.Query import Galley.API.Update import Galley.App import Imports import Wire.API.Routes.API import Wire.API.Routes.Public.Galley.Conversation import Wire.ConversationStore.MLS.Types +import Wire.ConversationSubsystem.MLS.GroupInfo +import Wire.ConversationSubsystem.MLS.SubConversation +import Wire.ConversationSubsystem.Query conversationAPI :: API ConversationAPI GalleyEffects conversationAPI = diff --git a/services/galley/src/Galley/API/Public/Feature.hs b/services/galley/src/Galley/API/Public/Feature.hs index 81f8d6247c8..2da3040e7ab 100644 --- a/services/galley/src/Galley/API/Public/Feature.hs +++ b/services/galley/src/Galley/API/Public/Feature.hs @@ -22,7 +22,6 @@ module Galley.API.Public.Feature where import Galley.API.Teams import Galley.API.Teams.Features -import Galley.API.Teams.Features.Get import Galley.App import Imports import Wire.API.Routes.API @@ -30,6 +29,7 @@ import Wire.API.Routes.Public.Galley.Feature import Wire.API.Routes.Version import Wire.API.Team.Feature import Wire.FeaturesConfigSubsystem (getAllTeamFeaturesForTeamMember) +import Wire.FeaturesConfigSubsystem.Get featureAPIGetPut :: forall cfg r. (_) => API (FeatureAPIGetPut cfg) r featureAPIGetPut = diff --git a/services/galley/src/Galley/API/Public/MLS.hs b/services/galley/src/Galley/API/Public/MLS.hs index 687d9e48276..418b004ba36 100644 --- a/services/galley/src/Galley/API/Public/MLS.hs +++ b/services/galley/src/Galley/API/Public/MLS.hs @@ -17,12 +17,12 @@ module Galley.API.Public.MLS where -import Galley.API.MLS -import Galley.API.MLS.Reset import Galley.App import Imports import Wire.API.Routes.API import Wire.API.Routes.Public.Galley.MLS +import Wire.ConversationSubsystem.MLS +import Wire.ConversationSubsystem.MLS.Reset mlsAPI :: API MLSAPI GalleyEffects mlsAPI = diff --git a/services/galley/src/Galley/API/Public/Team.hs b/services/galley/src/Galley/API/Public/Team.hs index 7b8575c0e13..ced198ad83d 100644 --- a/services/galley/src/Galley/API/Public/Team.hs +++ b/services/galley/src/Galley/API/Public/Team.hs @@ -17,11 +17,11 @@ module Galley.API.Public.Team where -import Galley.API.Query import Galley.API.Teams import Galley.App import Wire.API.Routes.API import Wire.API.Routes.Public.Galley.Team +import Wire.ConversationSubsystem.Query teamAPI :: API TeamAPI GalleyEffects teamAPI = diff --git a/services/galley/src/Galley/API/Teams.hs b/services/galley/src/Galley/API/Teams.hs index fa73ab30a53..2d31b764523 100644 --- a/services/galley/src/Galley/API/Teams.hs +++ b/services/galley/src/Galley/API/Teams.hs @@ -76,9 +76,7 @@ import Data.Range as Range import Data.Set qualified as Set import Data.Singletons import Data.Time.Clock (UTCTime) -import Galley.API.Action import Galley.API.LegalHold.Team -import Galley.API.Teams.Features.Get import Galley.API.Teams.Notifications qualified as APITeamQueue import Galley.API.Update qualified as API import Galley.App @@ -130,8 +128,10 @@ import Wire.BrigAPIAccess qualified as E import Wire.CodeStore import Wire.ConversationStore qualified as E import Wire.ConversationSubsystem +import Wire.ConversationSubsystem.Action import Wire.ConversationSubsystem.Util import Wire.FeaturesConfigSubsystem +import Wire.FeaturesConfigSubsystem.Get import Wire.FederationSubsystem import Wire.ListItems qualified as E import Wire.NotificationSubsystem diff --git a/services/galley/src/Galley/API/Teams/Features.hs b/services/galley/src/Galley/API/Teams/Features.hs index e77605c31e1..0243fba8d13 100644 --- a/services/galley/src/Galley/API/Teams/Features.hs +++ b/services/galley/src/Galley/API/Teams/Features.hs @@ -43,7 +43,6 @@ import Data.Kind import Data.Qualified (Local) import Galley.API.LegalHold qualified as LegalHold import Galley.API.LegalHold.Team qualified as LegalHold -import Galley.API.Teams.Features.Get import Galley.App import Galley.Effects import Galley.Effects.SearchVisibilityStore qualified as SearchVisibilityData @@ -71,6 +70,7 @@ import Wire.ConversationStore (MLSCommitLockStore) import Wire.ConversationSubsystem import Wire.ConversationSubsystem.Util (assertTeamExists, getTeamMembersForFanout, permissionCheck) import Wire.FeaturesConfigSubsystem (FeaturesConfigSubsystem, getDbFeatureRawInternal) +import Wire.FeaturesConfigSubsystem.Get import Wire.FeaturesConfigSubsystem.Types (GetFeatureConfigEffects) import Wire.FeaturesConfigSubsystem.Utils (resolveServerFeature) import Wire.FederationSubsystem (FederationSubsystem) diff --git a/services/galley/src/Galley/Options.hs b/services/galley/src/Galley/Options.hs index 4af6462a1a3..7dd20fb175c 100644 --- a/services/galley/src/Galley/Options.hs +++ b/services/galley/src/Galley/Options.hs @@ -90,18 +90,6 @@ import Wire.API.Team.Member import Wire.PostgresMigrationOpts import Wire.RateLimit.Interpreter (RateLimitConfig) -newtype GuestLinkTTLSeconds = GuestLinkTTLSeconds - { unGuestLinkTTLSeconds :: Int - } - deriving (Show, Generic) - -instance FromJSON GuestLinkTTLSeconds where - parseJSON x = do - n <- parseJSON x - if n > 0 && n <= 31536000 - then pure $ GuestLinkTTLSeconds n - else fail "GuestLinkTTLSeconds must be in (0, 31536000]" - data Settings = Settings { -- | Number of connections for the HTTP client pool _httpPoolSize :: !Int, @@ -184,10 +172,6 @@ makeLenses ''MeetingsConfig defConcurrentDeletionEvents :: Int defConcurrentDeletionEvents = 128 --- | Default guest link TTL in days. 365 days if not set. -defGuestLinkTTLSeconds :: GuestLinkTTLSeconds -defGuestLinkTTLSeconds = GuestLinkTTLSeconds $ 60 * 60 * 24 * 365 -- 1 year - data JournalOpts = JournalOpts { -- | SQS queue name to send team events _queueName :: !Text, diff --git a/services/galley/test/unit/Run.hs b/services/galley/test/unit/Run.hs index 486fea4a91f..8fe24c96be2 100644 --- a/services/galley/test/unit/Run.hs +++ b/services/galley/test/unit/Run.hs @@ -21,7 +21,7 @@ module Run where import Imports -import Test.Galley.API.Message qualified +import Test.Wire.ConversationSubsystem.Message qualified import Test.Galley.API.One2One qualified import Test.Galley.Mapping qualified import Test.Tasty @@ -31,7 +31,7 @@ main = defaultMain $ testGroup "Tests" - [ Test.Galley.API.Message.tests, + [ Test.Wire.ConversationSubsystem.Message.tests, Test.Galley.API.One2One.tests, Test.Galley.Mapping.tests ] diff --git a/services/galley/test/unit/Test/Galley/API/Message.hs b/services/galley/test/unit/Test/Galley/API/Message.hs index 18c9512c665..583d5077bb8 100644 --- a/services/galley/test/unit/Test/Galley/API/Message.hs +++ b/services/galley/test/unit/Test/Galley/API/Message.hs @@ -15,7 +15,7 @@ -- You should have received a copy of the GNU Affero General Public License along -- with this program. If not, see . -module Test.Galley.API.Message where +module Test.Wire.ConversationSubsystem.Message where import Control.Lens import Data.Domain @@ -24,7 +24,7 @@ import Data.Map qualified as Map import Data.Set qualified as Set import Data.Set.Lens import Data.UUID.Types -import Galley.API.Message +import Wire.ConversationSubsystem.Message import Imports import Test.Tasty import Test.Tasty.QuickCheck @@ -34,7 +34,7 @@ import Wire.API.User.Client (QualifiedUserClients (..)) tests :: TestTree tests = testGroup - "Galley.API.Message" + "Wire.ConversationSubsystem.Message" [ testGroup "checkMessageClients" [ checkMessageClientSuccess,