{-# LANGUAGE ExistentialQuantification #-}
module Ecluse.Core.Server.Context (
ServeRuntime (..),
PackumentDeps (..),
pdPrivateBaseUrl,
pdPublicBaseUrl,
pdMirror,
pdTarballHostGate,
tarballHostHonoured,
PublishDeps (..),
RouteAction (..),
ResponseAction (..),
MountRouter,
MountBinding (..),
RequestCtx (..),
Handler,
runHandler,
) where
import Data.IP (IPRange)
import Data.Time (UTCTime)
import Katip (Katip, KatipContext, LogEnv, SimpleLogPayload)
import Katip.Monadic (KatipContextT, runKatipContextT)
import Network.HTTP.Client (Manager)
import Network.HTTP.Types (Method)
import Network.HTTP.Types.Header (RequestHeaders)
import Network.Wai (ResponseReceived)
import Network.Wai qualified as Wai
import UnliftIO (MonadUnliftIO)
import Ecluse.Core.Credential (Secret)
import Ecluse.Core.Cve.Types (DbEtag)
import Ecluse.Core.Package (PackageName)
import Ecluse.Core.Package.Integrity (MinIntegrity, MinTrustedIntegrity)
import Ecluse.Core.Queue (MirrorQueue)
import Ecluse.Core.Registry.Adapter.Capability (AdapterArtifact, AdapterMetadata, AdapterPublish, ProjectName)
import Ecluse.Core.Registry.Request (CredentialMapping)
import Ecluse.Core.Rules (PreparedRule)
import Ecluse.Core.Rules.Outage (AdmissionIdentity)
import Ecluse.Core.Security (HostPort, Limits, Origin, TarballHostGate, tarballHostAllowed, thgAllowlist, thgEcosystemHosts)
import Ecluse.Core.Security.Egress (RegistryUrl)
import Ecluse.Core.Server.Admission (ServeAdmission)
import Ecluse.Core.Server.Admission.Bytes (ByteAdmission)
import Ecluse.Core.Server.Admission.Meter (MemoryMeter)
import Ecluse.Core.Server.Cache (MetadataCache)
import Ecluse.Core.Server.Contract (ResponseContract)
import Ecluse.Core.Server.Response (HelpMessage)
import Ecluse.Core.Server.Upstream (
MirrorServePlan,
MountUpstreams,
upstreamMirror,
upstreamPrivateBaseUrl,
upstreamPublicBaseUrl,
upstreamTarballHostGate,
)
import Ecluse.Core.Telemetry.Record (MetricsPort)
import Ecluse.Core.Telemetry.Span (TracingPort)
data ServeRuntime = ServeRuntime
{ ServeRuntime -> ServeAdmission
srAdmission :: ServeAdmission
, ServeRuntime -> MemoryMeter
srMemoryMeter :: MemoryMeter
, ServeRuntime -> Manager
srPublicManager :: Manager
, ServeRuntime -> Manager
srPrivateManager :: Manager
, ServeRuntime -> MetadataCache
srMetadataCache :: MetadataCache
, ServeRuntime -> MirrorQueue
srQueue :: MirrorQueue
, ServeRuntime -> MetricsPort
srMetrics :: MetricsPort
, ServeRuntime -> TracingPort
srTracing :: TracingPort
}
data PackumentDeps = PackumentDeps
{ PackumentDeps -> MountUpstreams
pdUpstreams :: MountUpstreams
, PackumentDeps -> PackageName -> Bool
pdFirstParty :: PackageName -> Bool
, PackumentDeps -> Text
pdMountBaseUrl :: Text
, PackumentDeps -> [PreparedRule]
pdRules :: [PreparedRule]
, PackumentDeps -> [IPRange]
pdAdditionalBlockedRanges :: [IPRange]
, PackumentDeps -> Limits
pdLimits :: Limits
, PackumentDeps -> Maybe Secret
pdInboundToken :: Maybe Secret
, PackumentDeps -> IO UTCTime
pdNow :: IO UTCTime
, PackumentDeps -> IO (Maybe DbEtag)
pdAdvisoryEtag :: IO (Maybe DbEtag)
, PackumentDeps -> AdmissionIdentity -> IO Bool
pdNoteAdmission :: AdmissionIdentity -> IO Bool
, PackumentDeps -> Maybe HelpMessage
pdHelp :: Maybe HelpMessage
, PackumentDeps -> MinIntegrity
pdMinIntegrity :: MinIntegrity
, PackumentDeps -> MinTrustedIntegrity
pdMinTrustedIntegrity :: MinTrustedIntegrity
, PackumentDeps -> AdapterMetadata
pdMetadata :: AdapterMetadata
, PackumentDeps -> AdapterArtifact
pdArtifact :: AdapterArtifact
, PackumentDeps -> Text -> Either Text RegistryUrl
pdEgressUrl :: Text -> Either Text RegistryUrl
}
pdPrivateBaseUrl :: PackumentDeps -> Maybe RegistryUrl
pdPrivateBaseUrl :: PackumentDeps -> Maybe RegistryUrl
pdPrivateBaseUrl = MountUpstreams -> Maybe RegistryUrl
upstreamPrivateBaseUrl (MountUpstreams -> Maybe RegistryUrl)
-> (PackumentDeps -> MountUpstreams)
-> PackumentDeps
-> Maybe RegistryUrl
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackumentDeps -> MountUpstreams
pdUpstreams
pdPublicBaseUrl :: PackumentDeps -> RegistryUrl
pdPublicBaseUrl :: PackumentDeps -> RegistryUrl
pdPublicBaseUrl = MountUpstreams -> RegistryUrl
upstreamPublicBaseUrl (MountUpstreams -> RegistryUrl)
-> (PackumentDeps -> MountUpstreams)
-> PackumentDeps
-> RegistryUrl
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackumentDeps -> MountUpstreams
pdUpstreams
pdMirror :: PackumentDeps -> MirrorServePlan
pdMirror :: PackumentDeps -> MirrorServePlan
pdMirror = MountUpstreams -> MirrorServePlan
upstreamMirror (MountUpstreams -> MirrorServePlan)
-> (PackumentDeps -> MountUpstreams)
-> PackumentDeps
-> MirrorServePlan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackumentDeps -> MountUpstreams
pdUpstreams
pdTarballHostGate :: PackumentDeps -> TarballHostGate
pdTarballHostGate :: PackumentDeps -> TarballHostGate
pdTarballHostGate = MountUpstreams -> TarballHostGate
upstreamTarballHostGate (MountUpstreams -> TarballHostGate)
-> (PackumentDeps -> MountUpstreams)
-> PackumentDeps
-> TarballHostGate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackumentDeps -> MountUpstreams
pdUpstreams
tarballHostHonoured :: Origin -> PackumentDeps -> Maybe HostPort -> Maybe HostPort -> Bool
tarballHostHonoured :: Origin -> PackumentDeps -> Maybe HostPort -> Maybe HostPort -> Bool
tarballHostHonoured Origin
origin PackumentDeps
deps =
AllowedHostPorts
-> Origin
-> AllowedHostPorts
-> [IPRange]
-> Maybe HostPort
-> Maybe HostPort
-> Bool
tarballHostAllowed
(TarballHostGate -> AllowedHostPorts
thgEcosystemHosts (PackumentDeps -> TarballHostGate
pdTarballHostGate PackumentDeps
deps))
Origin
origin
(TarballHostGate -> AllowedHostPorts
thgAllowlist (PackumentDeps -> TarballHostGate
pdTarballHostGate PackumentDeps
deps))
(PackumentDeps -> [IPRange]
pdAdditionalBlockedRanges PackumentDeps
deps)
data PublishDeps = PublishDeps
{ PublishDeps -> RegistryUrl
pubTargetUrl :: RegistryUrl
, PublishDeps -> PackageName -> Bool
pubAllowed :: PackageName -> Bool
, PublishDeps -> Maybe Secret
pubStaticToken :: Maybe Secret
, PublishDeps -> Maybe Secret
pubInboundToken :: Maybe Secret
, PublishDeps -> Limits
pubLimits :: Limits
, PublishDeps -> ByteAdmission
pubBodyBudget :: ByteAdmission
, PublishDeps -> Maybe HelpMessage
pubHelp :: Maybe HelpMessage
, PublishDeps -> ProjectName
pubProjectName :: ProjectName
, PublishDeps -> AdapterPublish
pubAdapter :: AdapterPublish
}
data ResponseAction response
=
AnswerLocally response
|
AnswerRefusal (Maybe HelpMessage -> response)
|
RunPipeline response (Wai.Request -> (response -> IO ResponseReceived) -> Handler ResponseReceived)
data RouteAction = forall response. RouteAction (ResponseContract response) (ResponseAction response)
type MountRouter = Method -> RequestHeaders -> [Text] -> RouteAction
data MountBinding = MountBinding
{ MountBinding -> NonEmpty Text
bindingPrefix :: NonEmpty Text
, MountBinding -> MountRouter
bindingRouter :: MountRouter
, MountBinding -> CredentialMapping
bindingCredential :: CredentialMapping
, MountBinding -> PackumentDeps
bindingPackumentDeps :: PackumentDeps
, MountBinding -> Maybe PublishDeps
bindingPublishDeps :: Maybe PublishDeps
}
data RequestCtx = RequestCtx
{ RequestCtx -> ServeRuntime
ctxRuntime :: ServeRuntime
, RequestCtx -> MountBinding
ctxMount :: MountBinding
}
newtype Handler a = Handler
{ forall a. Handler a -> ReaderT RequestCtx (KatipContextT IO) a
unHandler :: ReaderT RequestCtx (KatipContextT IO) a
}
deriving newtype
( (forall a b. (a -> b) -> Handler a -> Handler b)
-> (forall a b. a -> Handler b -> Handler a) -> Functor Handler
forall a b. a -> Handler b -> Handler a
forall a b. (a -> b) -> Handler a -> Handler b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Handler a -> Handler b
fmap :: forall a b. (a -> b) -> Handler a -> Handler b
$c<$ :: forall a b. a -> Handler b -> Handler a
<$ :: forall a b. a -> Handler b -> Handler a
Functor
, Functor Handler
Functor Handler =>
(forall a. a -> Handler a)
-> (forall a b. Handler (a -> b) -> Handler a -> Handler b)
-> (forall a b c.
(a -> b -> c) -> Handler a -> Handler b -> Handler c)
-> (forall a b. Handler a -> Handler b -> Handler b)
-> (forall a b. Handler a -> Handler b -> Handler a)
-> Applicative Handler
forall a. a -> Handler a
forall a b. Handler a -> Handler b -> Handler a
forall a b. Handler a -> Handler b -> Handler b
forall a b. Handler (a -> b) -> Handler a -> Handler b
forall a b c. (a -> b -> c) -> Handler a -> Handler b -> Handler c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> Handler a
pure :: forall a. a -> Handler a
$c<*> :: forall a b. Handler (a -> b) -> Handler a -> Handler b
<*> :: forall a b. Handler (a -> b) -> Handler a -> Handler b
$cliftA2 :: forall a b c. (a -> b -> c) -> Handler a -> Handler b -> Handler c
liftA2 :: forall a b c. (a -> b -> c) -> Handler a -> Handler b -> Handler c
$c*> :: forall a b. Handler a -> Handler b -> Handler b
*> :: forall a b. Handler a -> Handler b -> Handler b
$c<* :: forall a b. Handler a -> Handler b -> Handler a
<* :: forall a b. Handler a -> Handler b -> Handler a
Applicative
, Applicative Handler
Applicative Handler =>
(forall a b. Handler a -> (a -> Handler b) -> Handler b)
-> (forall a b. Handler a -> Handler b -> Handler b)
-> (forall a. a -> Handler a)
-> Monad Handler
forall a. a -> Handler a
forall a b. Handler a -> Handler b -> Handler b
forall a b. Handler a -> (a -> Handler b) -> Handler b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall a b. Handler a -> (a -> Handler b) -> Handler b
>>= :: forall a b. Handler a -> (a -> Handler b) -> Handler b
$c>> :: forall a b. Handler a -> Handler b -> Handler b
>> :: forall a b. Handler a -> Handler b -> Handler b
$creturn :: forall a. a -> Handler a
return :: forall a. a -> Handler a
Monad
, Monad Handler
Monad Handler => (forall a. IO a -> Handler a) -> MonadIO Handler
forall a. IO a -> Handler a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
$cliftIO :: forall a. IO a -> Handler a
liftIO :: forall a. IO a -> Handler a
MonadIO
, MonadReader RequestCtx
, MonadIO Handler
MonadIO Handler =>
(forall b. ((forall a. Handler a -> IO a) -> IO b) -> Handler b)
-> MonadUnliftIO Handler
forall b. ((forall a. Handler a -> IO a) -> IO b) -> Handler b
forall (m :: * -> *).
MonadIO m =>
(forall b. ((forall a. m a -> IO a) -> IO b) -> m b)
-> MonadUnliftIO m
$cwithRunInIO :: forall b. ((forall a. Handler a -> IO a) -> IO b) -> Handler b
withRunInIO :: forall b. ((forall a. Handler a -> IO a) -> IO b) -> Handler b
MonadUnliftIO
, MonadIO Handler
Handler LogEnv
MonadIO Handler =>
Handler LogEnv
-> (forall a. (LogEnv -> LogEnv) -> Handler a -> Handler a)
-> Katip Handler
forall a. (LogEnv -> LogEnv) -> Handler a -> Handler a
forall (m :: * -> *).
MonadIO m =>
m LogEnv -> (forall a. (LogEnv -> LogEnv) -> m a -> m a) -> Katip m
$cgetLogEnv :: Handler LogEnv
getLogEnv :: Handler LogEnv
$clocalLogEnv :: forall a. (LogEnv -> LogEnv) -> Handler a -> Handler a
localLogEnv :: forall a. (LogEnv -> LogEnv) -> Handler a -> Handler a
Katip
, Katip Handler
Handler Namespace
Handler LogContexts
Katip Handler =>
Handler LogContexts
-> (forall a.
(LogContexts -> LogContexts) -> Handler a -> Handler a)
-> Handler Namespace
-> (forall a. (Namespace -> Namespace) -> Handler a -> Handler a)
-> KatipContext Handler
forall a. (Namespace -> Namespace) -> Handler a -> Handler a
forall a. (LogContexts -> LogContexts) -> Handler a -> Handler a
forall (m :: * -> *).
Katip m =>
m LogContexts
-> (forall a. (LogContexts -> LogContexts) -> m a -> m a)
-> m Namespace
-> (forall a. (Namespace -> Namespace) -> m a -> m a)
-> KatipContext m
$cgetKatipContext :: Handler LogContexts
getKatipContext :: Handler LogContexts
$clocalKatipContext :: forall a. (LogContexts -> LogContexts) -> Handler a -> Handler a
localKatipContext :: forall a. (LogContexts -> LogContexts) -> Handler a -> Handler a
$cgetKatipNamespace :: Handler Namespace
getKatipNamespace :: Handler Namespace
$clocalKatipNamespace :: forall a. (Namespace -> Namespace) -> Handler a -> Handler a
localKatipNamespace :: forall a. (Namespace -> Namespace) -> Handler a -> Handler a
KatipContext
)
runHandler :: LogEnv -> SimpleLogPayload -> RequestCtx -> Handler a -> IO a
runHandler :: forall a.
LogEnv -> SimpleLogPayload -> RequestCtx -> Handler a -> IO a
runHandler LogEnv
logEnv SimpleLogPayload
initialContext RequestCtx
ctx Handler a
action =
LogEnv
-> SimpleLogPayload -> Namespace -> KatipContextT IO a -> IO a
forall c (m :: * -> *) a.
LogItem c =>
LogEnv -> c -> Namespace -> KatipContextT m a -> m a
runKatipContextT LogEnv
logEnv SimpleLogPayload
initialContext Namespace
forall a. Monoid a => a
mempty (ReaderT RequestCtx (KatipContextT IO) a
-> RequestCtx -> KatipContextT IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (Handler a -> ReaderT RequestCtx (KatipContextT IO) a
forall a. Handler a -> ReaderT RequestCtx (KatipContextT IO) a
unHandler Handler a
action) RequestCtx
ctx)