-- This file is part of the Wire Server implementation.
--
-- Copyright (C) 2022 Wire Swiss GmbH <opensource@wire.com>
--
-- This program is free software: you can redistribute it and/or modify it under
-- the terms of the GNU Affero General Public License as published by the Free
-- Software Foundation, either version 3 of the License, or (at your option) any
-- later version.
--
-- This program is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-- details.
--
-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.

module Galley.Intra.Effects
  ( interpretBrigAccess,
    interpretSparAccess,
    interpretBotAccess,
  )
where

import Galley.API.Error
import Galley.Cassandra.Util
import Galley.Effects.BotAccess (BotAccess (..))
import Galley.Effects.BrigAccess (BrigAccess (..))
import Galley.Effects.SparAccess (SparAccess (..))
import Galley.Env
import Galley.Intra.Client
import Galley.Intra.Spar
import Galley.Intra.Team
import Galley.Intra.User
import Galley.Monad
import Imports
import Polysemy
import Polysemy.Error
import Polysemy.Input
import Polysemy.TinyLog
import UnliftIO qualified

interpretBrigAccess ::
  ( Member (Embed IO) r,
    Member (Error InternalError) r,
    Member TinyLog r,
    Member (Input Env) r
  ) =>
  Sem (BrigAccess ': r) a ->
  Sem r a
interpretBrigAccess :: forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Error InternalError) r,
 Member TinyLog r, Member (Input Env) r) =>
Sem (BrigAccess : r) a -> Sem r a
interpretBrigAccess = (forall (rInitial :: EffectRow) x.
 BrigAccess (Sem rInitial) x -> Sem r x)
-> Sem (BrigAccess : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret ((forall (rInitial :: EffectRow) x.
  BrigAccess (Sem rInitial) x -> Sem r x)
 -> Sem (BrigAccess : r) a -> Sem r a)
-> (forall (rInitial :: EffectRow) x.
    BrigAccess (Sem rInitial) x -> Sem r x)
-> Sem (BrigAccess : r) a
-> Sem r a
forall a b. (a -> b) -> a -> b
$ \case
  GetConnectionsUnqualified [UserId]
uids Maybe [UserId]
muids Maybe Relation
mrel -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetConnectionsUnqualified"
    App [ConnectionStatus] -> Sem r [ConnectionStatus]
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App [ConnectionStatus] -> Sem r [ConnectionStatus])
-> App [ConnectionStatus] -> Sem r [ConnectionStatus]
forall a b. (a -> b) -> a -> b
$ [UserId]
-> Maybe [UserId] -> Maybe Relation -> App [ConnectionStatus]
getConnectionsUnqualified [UserId]
uids Maybe [UserId]
muids Maybe Relation
mrel
  GetConnectionsUnqualifiedBidi [UserId]
uids1 [UserId]
uids2 Maybe Relation
mrel1 Maybe Relation
mrel2 -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetConnectionsUnqualifiedBidi"
    App x -> Sem r x
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App x -> Sem r x) -> App x -> Sem r x
forall a b. (a -> b) -> a -> b
$
      App [ConnectionStatus]
-> App [ConnectionStatus]
-> App ([ConnectionStatus], [ConnectionStatus])
forall (m :: * -> *) a b. MonadUnliftIO m => m a -> m b -> m (a, b)
UnliftIO.concurrently
        ([UserId]
-> Maybe [UserId] -> Maybe Relation -> App [ConnectionStatus]
getConnectionsUnqualified [UserId]
uids1 ([UserId] -> Maybe [UserId]
forall a. a -> Maybe a
Just [UserId]
uids2) Maybe Relation
mrel1)
        ([UserId]
-> Maybe [UserId] -> Maybe Relation -> App [ConnectionStatus]
getConnectionsUnqualified [UserId]
uids2 ([UserId] -> Maybe [UserId]
forall a. a -> Maybe a
Just [UserId]
uids1) Maybe Relation
mrel2)
  GetConnections [UserId]
uids Maybe [Qualified UserId]
mquids Maybe Relation
mrel -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetConnections"
    App [ConnectionStatusV2] -> Sem r [ConnectionStatusV2]
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App [ConnectionStatusV2] -> Sem r [ConnectionStatusV2])
-> App [ConnectionStatusV2] -> Sem r [ConnectionStatusV2]
forall a b. (a -> b) -> a -> b
$
      [UserId]
-> Maybe [Qualified UserId]
-> Maybe Relation
-> App [ConnectionStatusV2]
getConnections [UserId]
uids Maybe [Qualified UserId]
mquids Maybe Relation
mrel
  PutConnectionInternal UpdateConnectionsInternal
uc -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.PutConnectionInternal"
    App Status -> Sem r Status
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App Status -> Sem r Status) -> App Status -> Sem r Status
forall a b. (a -> b) -> a -> b
$ UpdateConnectionsInternal -> App Status
putConnectionInternal UpdateConnectionsInternal
uc
  ReauthUser UserId
uid ReAuthUser
reauth -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.ReauthUser"
    App (Either AuthenticationError ())
-> Sem r (Either AuthenticationError ())
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App (Either AuthenticationError ())
 -> Sem r (Either AuthenticationError ()))
-> App (Either AuthenticationError ())
-> Sem r (Either AuthenticationError ())
forall a b. (a -> b) -> a -> b
$ UserId -> ReAuthUser -> App (Either AuthenticationError ())
reAuthUser UserId
uid ReAuthUser
reauth
  LookupActivatedUsers [UserId]
uids -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.LookupActivatedUsers"
    App [User] -> Sem r [User]
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App [User] -> Sem r [User]) -> App [User] -> Sem r [User]
forall a b. (a -> b) -> a -> b
$ [UserId] -> App [User]
lookupActivatedUsers [UserId]
uids
  GetUsers [UserId]
uids -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetUsers"
    App [UserAccount] -> Sem r [UserAccount]
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App [UserAccount] -> Sem r [UserAccount])
-> App [UserAccount] -> Sem r [UserAccount]
forall a b. (a -> b) -> a -> b
$ [UserId] -> App [UserAccount]
getUsers [UserId]
uids
  DeleteUser UserId
uid -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.DeleteUser"
    App () -> Sem r ()
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App () -> Sem r ()) -> App () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ UserId -> App ()
deleteUser UserId
uid
  GetContactList UserId
uid -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetContactList"
    App [UserId] -> Sem r [UserId]
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App [UserId] -> Sem r [UserId]) -> App [UserId] -> Sem r [UserId]
forall a b. (a -> b) -> a -> b
$ UserId -> App [UserId]
getContactList UserId
uid
  GetRichInfoMultiUser [UserId]
uids -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetRichInfoMultiUser"
    App [(UserId, RichInfo)] -> Sem r [(UserId, RichInfo)]
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App [(UserId, RichInfo)] -> Sem r [(UserId, RichInfo)])
-> App [(UserId, RichInfo)] -> Sem r [(UserId, RichInfo)]
forall a b. (a -> b) -> a -> b
$ [UserId] -> App [(UserId, RichInfo)]
getRichInfoMultiUser [UserId]
uids
  GetSize TeamId
tid -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetSize"
    App TeamSize -> Sem r TeamSize
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App TeamSize -> Sem r TeamSize) -> App TeamSize -> Sem r TeamSize
forall a b. (a -> b) -> a -> b
$ TeamId -> App TeamSize
getSize TeamId
tid
  LookupClients [UserId]
uids -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.LookupClients"
    App UserClients -> Sem r UserClients
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App UserClients -> Sem r UserClients)
-> App UserClients -> Sem r UserClients
forall a b. (a -> b) -> a -> b
$ [UserId] -> App UserClients
lookupClients [UserId]
uids
  LookupClientsFull [UserId]
uids -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.LookupClientsFull"
    App UserClientsFull -> Sem r UserClientsFull
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App UserClientsFull -> Sem r UserClientsFull)
-> App UserClientsFull -> Sem r UserClientsFull
forall a b. (a -> b) -> a -> b
$ [UserId] -> App UserClientsFull
lookupClientsFull [UserId]
uids
  NotifyClientsAboutLegalHoldRequest UserId
self UserId
other LastPrekey
pk -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.NotifyClientsAboutLegalHoldRequest"
    App () -> Sem r ()
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App () -> Sem r ()) -> App () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ UserId -> UserId -> LastPrekey -> App ()
notifyClientsAboutLegalHoldRequest UserId
self UserId
other LastPrekey
pk
  GetLegalHoldAuthToken UserId
uid Maybe PlainTextPassword6
mpwd -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetLegalHoldAuthToken"
    UserId -> Maybe PlainTextPassword6 -> Sem r OpaqueAuthToken
forall (r :: EffectRow).
(Member (Embed IO) r, Member (Error InternalError) r,
 Member TinyLog r, Member (Input Env) r) =>
UserId -> Maybe PlainTextPassword6 -> Sem r OpaqueAuthToken
getLegalHoldAuthToken UserId
uid Maybe PlainTextPassword6
mpwd
  AddLegalHoldClientToUserEither UserId
uid ConnId
conn [Prekey]
pks LastPrekey
lpk -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.AddLegalHoldClientToUserEither"
    App (Either AuthenticationError ClientId)
-> Sem r (Either AuthenticationError ClientId)
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App (Either AuthenticationError ClientId)
 -> Sem r (Either AuthenticationError ClientId))
-> App (Either AuthenticationError ClientId)
-> Sem r (Either AuthenticationError ClientId)
forall a b. (a -> b) -> a -> b
$ UserId
-> ConnId
-> [Prekey]
-> LastPrekey
-> App (Either AuthenticationError ClientId)
addLegalHoldClientToUser UserId
uid ConnId
conn [Prekey]
pks LastPrekey
lpk
  RemoveLegalHoldClientFromUser UserId
uid -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.RemoveLegalHoldClientFromUser"
    App () -> Sem r ()
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App () -> Sem r ()) -> App () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ UserId -> App ()
removeLegalHoldClientFromUser UserId
uid
  GetAccountConferenceCallingConfigClient UserId
uid -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetAccountConferenceCallingConfigClient"
    App (Feature ConferenceCallingConfig)
-> Sem r (Feature ConferenceCallingConfig)
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App (Feature ConferenceCallingConfig)
 -> Sem r (Feature ConferenceCallingConfig))
-> App (Feature ConferenceCallingConfig)
-> Sem r (Feature ConferenceCallingConfig)
forall a b. (a -> b) -> a -> b
$ HasCallStack => UserId -> App (Feature ConferenceCallingConfig)
UserId -> App (Feature ConferenceCallingConfig)
getAccountConferenceCallingConfigClient UserId
uid
  GetLocalMLSClients Local UserId
qusr CipherSuiteTag
ss -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.GetLocalMLSClients"
    App (Set ClientInfo) -> Sem r (Set ClientInfo)
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App (Set ClientInfo) -> Sem r (Set ClientInfo))
-> App (Set ClientInfo) -> Sem r (Set ClientInfo)
forall a b. (a -> b) -> a -> b
$ Local UserId -> CipherSuiteTag -> App (Set ClientInfo)
getLocalMLSClients Local UserId
qusr CipherSuiteTag
ss
  UpdateSearchVisibilityInbound TeamStatus SearchVisibilityInboundConfig
status -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BrigAccess.UpdateSearchVisibilityInbound"
    App () -> Sem r ()
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App () -> Sem r ()) -> App () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ TeamStatus SearchVisibilityInboundConfig -> App ()
updateSearchVisibilityInbound TeamStatus SearchVisibilityInboundConfig
status

interpretSparAccess ::
  ( Member (Embed IO) r,
    Member (Input Env) r,
    Member TinyLog r
  ) =>
  Sem (SparAccess ': r) a ->
  Sem r a
interpretSparAccess :: forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r, Member TinyLog r) =>
Sem (SparAccess : r) a -> Sem r a
interpretSparAccess = (forall (rInitial :: EffectRow) x.
 SparAccess (Sem rInitial) x -> Sem r x)
-> Sem (SparAccess : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret ((forall (rInitial :: EffectRow) x.
  SparAccess (Sem rInitial) x -> Sem r x)
 -> Sem (SparAccess : r) a -> Sem r a)
-> (forall (rInitial :: EffectRow) x.
    SparAccess (Sem rInitial) x -> Sem r x)
-> Sem (SparAccess : r) a
-> Sem r a
forall a b. (a -> b) -> a -> b
$ \case
  DeleteTeam TeamId
tid -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"SparAccess.DeleteTeam"
    App () -> Sem r ()
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App () -> Sem r ()) -> App () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ TeamId -> App ()
deleteTeam TeamId
tid
  LookupScimUserInfos [UserId]
uids -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"SparAccess.LookupScimUserInfos"
    App [ScimUserInfo] -> Sem r [ScimUserInfo]
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App [ScimUserInfo] -> Sem r [ScimUserInfo])
-> App [ScimUserInfo] -> Sem r [ScimUserInfo]
forall a b. (a -> b) -> a -> b
$ [UserId] -> App [ScimUserInfo]
lookupScimUserInfos [UserId]
uids

interpretBotAccess ::
  ( Member (Embed IO) r,
    Member (Input Env) r,
    Member TinyLog r
  ) =>
  Sem (BotAccess ': r) a ->
  Sem r a
interpretBotAccess :: forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r, Member TinyLog r) =>
Sem (BotAccess : r) a -> Sem r a
interpretBotAccess = (forall (rInitial :: EffectRow) x.
 BotAccess (Sem rInitial) x -> Sem r x)
-> Sem (BotAccess : r) a -> Sem r a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret ((forall (rInitial :: EffectRow) x.
  BotAccess (Sem rInitial) x -> Sem r x)
 -> Sem (BotAccess : r) a -> Sem r a)
-> (forall (rInitial :: EffectRow) x.
    BotAccess (Sem rInitial) x -> Sem r x)
-> Sem (BotAccess : r) a
-> Sem r a
forall a b. (a -> b) -> a -> b
$ \case
  DeleteBot ConvId
cid BotId
bid -> do
    ByteString -> Sem r ()
forall (r :: EffectRow). Member TinyLog r => ByteString -> Sem r ()
logEffect ByteString
"BotAccess.DeleteBot"
    App () -> Sem r ()
forall (r :: EffectRow) a.
(Member (Embed IO) r, Member (Input Env) r) =>
App a -> Sem r a
embedApp (App () -> Sem r ()) -> App () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ ConvId -> BotId -> App ()
deleteBot ConvId
cid BotId
bid