module Ecluse.Core.Package.Admission (
ArtifactAdmission (..),
admissionTransience,
admitArtifact,
admitArtifactWithEvidence,
) where
import Ecluse.Core.Package (Artifact, Hash, PackageDetails, artFilename, artHashes, pkgArtifacts)
import Ecluse.Core.Package.Integrity (
MinIntegrity,
VersionIntegrity (BelowFloor, MeetsFloor, NoIntegrity),
classifyArtifacts,
)
import Ecluse.Core.Rules (PreparedRule, evalRules)
import Ecluse.Core.Rules.Types (
Decision (Admitted, Blocked, BlockedByDefault, Undecidable),
EvalContext,
SkippedCheck,
Transience (WontResolve),
completeEvidence,
skippedChecks,
)
import Ecluse.Core.Server.Path (Filename, unFilename)
data ArtifactAdmission
=
AdmissionAdmit Filename Artifact (NonEmpty Hash)
|
AdmissionDenied Decision
|
AdmissionUndecidable Decision
|
AdmissionFileAbsent
|
AdmissionIntegrityMissing
|
AdmissionBelowFloor
deriving stock (Int -> ArtifactAdmission -> ShowS
[ArtifactAdmission] -> ShowS
ArtifactAdmission -> String
(Int -> ArtifactAdmission -> ShowS)
-> (ArtifactAdmission -> String)
-> ([ArtifactAdmission] -> ShowS)
-> Show ArtifactAdmission
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ArtifactAdmission -> ShowS
showsPrec :: Int -> ArtifactAdmission -> ShowS
$cshow :: ArtifactAdmission -> String
show :: ArtifactAdmission -> String
$cshowList :: [ArtifactAdmission] -> ShowS
showList :: [ArtifactAdmission] -> ShowS
Show)
admitArtifact ::
EvalContext ->
[PreparedRule] ->
MinIntegrity ->
Filename ->
PackageDetails ->
IO ArtifactAdmission
admitArtifact :: EvalContext
-> [PreparedRule]
-> MinIntegrity
-> Filename
-> PackageDetails
-> IO ArtifactAdmission
admitArtifact EvalContext
ctx [PreparedRule]
rules MinIntegrity
minIntegrity Filename
file PackageDetails
details =
(ArtifactAdmission, [SkippedCheck]) -> ArtifactAdmission
forall a b. (a, b) -> a
fst ((ArtifactAdmission, [SkippedCheck]) -> ArtifactAdmission)
-> IO (ArtifactAdmission, [SkippedCheck]) -> IO ArtifactAdmission
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EvalContext
-> [PreparedRule]
-> MinIntegrity
-> Filename
-> PackageDetails
-> IO (ArtifactAdmission, [SkippedCheck])
admitArtifactWithEvidence EvalContext
ctx [PreparedRule]
rules MinIntegrity
minIntegrity Filename
file PackageDetails
details
admitArtifactWithEvidence ::
EvalContext ->
[PreparedRule] ->
MinIntegrity ->
Filename ->
PackageDetails ->
IO (ArtifactAdmission, [SkippedCheck])
admitArtifactWithEvidence :: EvalContext
-> [PreparedRule]
-> MinIntegrity
-> Filename
-> PackageDetails
-> IO (ArtifactAdmission, [SkippedCheck])
admitArtifactWithEvidence EvalContext
ctx [PreparedRule]
rules MinIntegrity
minIntegrity Filename
file PackageDetails
details = do
decision <- EvalContext -> [PreparedRule] -> RuleEvidence -> IO Decision
evalRules EvalContext
ctx [PreparedRule]
rules (PackageDetails -> RuleEvidence
completeEvidence PackageDetails
details)
pure (admissionOf minIntegrity file details decision, skippedChecks decision)
admissionOf :: MinIntegrity -> Filename -> PackageDetails -> Decision -> ArtifactAdmission
admissionOf :: MinIntegrity
-> Filename -> PackageDetails -> Decision -> ArtifactAdmission
admissionOf MinIntegrity
minIntegrity Filename
file PackageDetails
details Decision
decision =
case Decision
decision of
Admitted{} -> MinIntegrity -> Filename -> PackageDetails -> ArtifactAdmission
admitFile MinIntegrity
minIntegrity Filename
file PackageDetails
details
Blocked{} -> Decision -> ArtifactAdmission
AdmissionDenied Decision
decision
BlockedByDefault{} -> Decision -> ArtifactAdmission
AdmissionDenied Decision
decision
Undecidable{} -> Decision -> ArtifactAdmission
AdmissionUndecidable Decision
decision
admitFile :: MinIntegrity -> Filename -> PackageDetails -> ArtifactAdmission
admitFile :: MinIntegrity -> Filename -> PackageDetails -> ArtifactAdmission
admitFile MinIntegrity
minIntegrity Filename
file PackageDetails
details = case Filename -> PackageDetails -> Maybe Artifact
artifactFor Filename
file PackageDetails
details of
Maybe Artifact
Nothing -> ArtifactAdmission
AdmissionFileAbsent
Just Artifact
artifact -> case MinIntegrity -> NonEmpty Artifact -> VersionIntegrity
forall floor.
IntegrityFloor floor =>
floor -> NonEmpty Artifact -> VersionIntegrity
classifyArtifacts MinIntegrity
minIntegrity (Artifact
artifact Artifact -> [Artifact] -> NonEmpty Artifact
forall a. a -> [a] -> NonEmpty a
:| []) of
VersionIntegrity
MeetsFloor ->
ArtifactAdmission
-> (NonEmpty Hash -> ArtifactAdmission)
-> Maybe (NonEmpty Hash)
-> ArtifactAdmission
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ArtifactAdmission
AdmissionIntegrityMissing (Filename -> Artifact -> NonEmpty Hash -> ArtifactAdmission
AdmissionAdmit Filename
file Artifact
artifact) ([Hash] -> Maybe (NonEmpty Hash)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty (Artifact -> [Hash]
artHashes Artifact
artifact))
VersionIntegrity
BelowFloor -> ArtifactAdmission
AdmissionBelowFloor
VersionIntegrity
NoIntegrity -> ArtifactAdmission
AdmissionIntegrityMissing
admissionTransience :: ArtifactAdmission -> Maybe Transience
admissionTransience :: ArtifactAdmission -> Maybe Transience
admissionTransience = \case
AdmissionUndecidable (Undecidable Transience
transience Text
_) -> Transience -> Maybe Transience
forall a. a -> Maybe a
Just Transience
transience
AdmissionUndecidable Decision
_ -> Transience -> Maybe Transience
forall a. a -> Maybe a
Just Transience
WontResolve
AdmissionAdmit{} -> Maybe Transience
forall a. Maybe a
Nothing
AdmissionDenied{} -> Maybe Transience
forall a. Maybe a
Nothing
ArtifactAdmission
AdmissionFileAbsent -> Maybe Transience
forall a. Maybe a
Nothing
ArtifactAdmission
AdmissionIntegrityMissing -> Maybe Transience
forall a. Maybe a
Nothing
ArtifactAdmission
AdmissionBelowFloor -> Maybe Transience
forall a. Maybe a
Nothing
artifactFor :: Filename -> PackageDetails -> Maybe Artifact
artifactFor :: Filename -> PackageDetails -> Maybe Artifact
artifactFor Filename
file PackageDetails
details =
(Artifact -> Bool) -> NonEmpty Artifact -> Maybe Artifact
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Filename -> Text
unFilename Filename
file) (Text -> Bool) -> (Artifact -> Text) -> Artifact -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Artifact -> Text
artFilename) (PackageDetails -> NonEmpty Artifact
pkgArtifacts PackageDetails
details)