module Ecluse.Core.Package (
Scope,
mkScope,
unScope,
renderScope,
PackageName,
mkPackageName,
pkgEcosystem,
pkgNamespace,
pkgCanonical,
pkgDisplay,
renderPackageName,
unscopedName,
CodeExecSignal (..),
Trust (..),
TrustEvidence (..),
Availability (..),
Artifact (..),
ArtifactKind (..),
Hash,
hashAlg,
hashValue,
mkHash,
HashAlg (..),
renderHashAlg,
parseHashAlg,
sriPrefix,
sriBody,
sriAlgorithm,
computeDigest,
isComputable,
Person (..),
PackageDetails (..),
PackageInfo (..),
InvalidEntry (..),
InvalidEntryKind (..),
) where
import Crypto.Hash (Blake2b_512, Digest, MD5, SHA1, SHA256, SHA384, SHA512, digestFromByteString, hashlazy)
import Data.Aeson (Value)
import Data.ByteArray (convert)
import Data.ByteArray.Encoding (Base (Base16, Base64), convertFromBase)
import Data.Text qualified as T
import Data.Text.Short (ShortText)
import Data.Text.Short qualified as TS
import Data.Time (UTCTime)
import Ecluse.Core.Ecosystem (Ecosystem (..))
import Ecluse.Core.Version (Version)
newtype Scope = Scope ShortText
deriving stock (Scope -> Scope -> Bool
(Scope -> Scope -> Bool) -> (Scope -> Scope -> Bool) -> Eq Scope
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Scope -> Scope -> Bool
== :: Scope -> Scope -> Bool
$c/= :: Scope -> Scope -> Bool
/= :: Scope -> Scope -> Bool
Eq, Eq Scope
Eq Scope =>
(Scope -> Scope -> Ordering)
-> (Scope -> Scope -> Bool)
-> (Scope -> Scope -> Bool)
-> (Scope -> Scope -> Bool)
-> (Scope -> Scope -> Bool)
-> (Scope -> Scope -> Scope)
-> (Scope -> Scope -> Scope)
-> Ord Scope
Scope -> Scope -> Bool
Scope -> Scope -> Ordering
Scope -> Scope -> Scope
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Scope -> Scope -> Ordering
compare :: Scope -> Scope -> Ordering
$c< :: Scope -> Scope -> Bool
< :: Scope -> Scope -> Bool
$c<= :: Scope -> Scope -> Bool
<= :: Scope -> Scope -> Bool
$c> :: Scope -> Scope -> Bool
> :: Scope -> Scope -> Bool
$c>= :: Scope -> Scope -> Bool
>= :: Scope -> Scope -> Bool
$cmax :: Scope -> Scope -> Scope
max :: Scope -> Scope -> Scope
$cmin :: Scope -> Scope -> Scope
min :: Scope -> Scope -> Scope
Ord, Int -> Scope -> ShowS
[Scope] -> ShowS
Scope -> String
(Int -> Scope -> ShowS)
-> (Scope -> String) -> ([Scope] -> ShowS) -> Show Scope
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Scope -> ShowS
showsPrec :: Int -> Scope -> ShowS
$cshow :: Scope -> String
show :: Scope -> String
$cshowList :: [Scope] -> ShowS
showList :: [Scope] -> ShowS
Show)
mkScope :: Text -> Scope
mkScope :: Text -> Scope
mkScope Text
raw = ShortText -> Scope
Scope (Text -> ShortText
TS.fromText (Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
raw (Text -> Text -> Maybe Text
T.stripPrefix Text
"@" Text
raw)))
unScope :: Scope -> Text
unScope :: Scope -> Text
unScope (Scope ShortText
s) = ShortText -> Text
TS.toText ShortText
s
renderScope :: Scope -> Text
renderScope :: Scope -> Text
renderScope (Scope ShortText
s) = Text
"@" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ShortText -> Text
TS.toText ShortText
s
data PackageName = PackageName
{ PackageName -> Ecosystem
pkgEcosystem :: Ecosystem
, PackageName -> Maybe Scope
pkgNamespace :: Maybe Scope
, PackageName -> ShortText
pkgCanonical :: ShortText
, PackageName -> ShortText
pkgDisplay :: ShortText
}
deriving stock (Int -> PackageName -> ShowS
[PackageName] -> ShowS
PackageName -> String
(Int -> PackageName -> ShowS)
-> (PackageName -> String)
-> ([PackageName] -> ShowS)
-> Show PackageName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PackageName -> ShowS
showsPrec :: Int -> PackageName -> ShowS
$cshow :: PackageName -> String
show :: PackageName -> String
$cshowList :: [PackageName] -> ShowS
showList :: [PackageName] -> ShowS
Show)
nameKey :: PackageName -> (Ecosystem, Maybe Scope, ShortText)
nameKey :: PackageName -> (Ecosystem, Maybe Scope, ShortText)
nameKey PackageName
n = (PackageName -> Ecosystem
pkgEcosystem PackageName
n, PackageName -> Maybe Scope
pkgNamespace PackageName
n, PackageName -> ShortText
pkgCanonical PackageName
n)
instance Eq PackageName where
PackageName
a == :: PackageName -> PackageName -> Bool
== PackageName
b = PackageName -> (Ecosystem, Maybe Scope, ShortText)
nameKey PackageName
a (Ecosystem, Maybe Scope, ShortText)
-> (Ecosystem, Maybe Scope, ShortText) -> Bool
forall a. Eq a => a -> a -> Bool
== PackageName -> (Ecosystem, Maybe Scope, ShortText)
nameKey PackageName
b
instance Ord PackageName where
compare :: PackageName -> PackageName -> Ordering
compare PackageName
a PackageName
b = (Ecosystem, Maybe Scope, ShortText)
-> (Ecosystem, Maybe Scope, ShortText) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (PackageName -> (Ecosystem, Maybe Scope, ShortText)
nameKey PackageName
a) (PackageName -> (Ecosystem, Maybe Scope, ShortText)
nameKey PackageName
b)
mkPackageName :: Ecosystem -> Maybe Scope -> Text -> PackageName
mkPackageName :: Ecosystem -> Maybe Scope -> Text -> PackageName
mkPackageName Ecosystem
eco Maybe Scope
ns Text
raw =
PackageName
{ pkgEcosystem :: Ecosystem
pkgEcosystem = Ecosystem
eco
, pkgNamespace :: Maybe Scope
pkgNamespace = Maybe Scope
ns
, pkgCanonical :: ShortText
pkgCanonical = Text -> ShortText
TS.fromText (Ecosystem -> Text -> Text
canonicalise Ecosystem
eco Text
display)
, pkgDisplay :: ShortText
pkgDisplay = Text -> ShortText
TS.fromText Text
display
}
where
display :: Text
display = case Maybe Scope
ns of
Just Scope
s -> Scope -> Text
renderScope Scope
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
raw
Maybe Scope
Nothing -> Text
raw
canonicalise :: Ecosystem -> Text -> Text
canonicalise :: Ecosystem -> Text -> Text
canonicalise = \case
Ecosystem
Npm -> Text -> Text
forall a. a -> a
id
Ecosystem
RubyGems -> Text -> Text
forall a. a -> a
id
Ecosystem
PyPI -> Text -> Text
normalisePyPI
normalisePyPI :: Text -> Text
normalisePyPI :: Text -> Text
normalisePyPI Text
t =
Text -> [Text] -> Text
T.intercalate Text
"-"
([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
T.null)
([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> [Text]
Text -> Text -> [Text]
T.splitOn Text
"-"
(Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ (Char -> Char) -> Text -> Text
T.map (\Char
c -> if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.' then Char
'-' else Char
c) (Text -> Text
T.toLower Text
t)
renderPackageName :: PackageName -> Text
renderPackageName :: PackageName -> Text
renderPackageName = ShortText -> Text
TS.toText (ShortText -> Text)
-> (PackageName -> ShortText) -> PackageName -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> ShortText
pkgDisplay
unscopedName :: PackageName -> Text
unscopedName :: PackageName -> Text
unscopedName PackageName
name = case PackageName -> Maybe Scope
pkgNamespace PackageName
name of
Just Scope
_ -> Int -> Text -> Text
T.drop Int
1 ((Text, Text) -> Text
forall a b. (a, b) -> b
snd (HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
T.breakOn Text
"/" (PackageName -> Text
renderPackageName PackageName
name)))
Maybe Scope
Nothing -> PackageName -> Text
renderPackageName PackageName
name
data CodeExecSignal
=
NoCodeOnInstall
|
RunsCodeOnInstall Text
|
CodeExecUnknown
deriving stock (CodeExecSignal -> CodeExecSignal -> Bool
(CodeExecSignal -> CodeExecSignal -> Bool)
-> (CodeExecSignal -> CodeExecSignal -> Bool) -> Eq CodeExecSignal
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CodeExecSignal -> CodeExecSignal -> Bool
== :: CodeExecSignal -> CodeExecSignal -> Bool
$c/= :: CodeExecSignal -> CodeExecSignal -> Bool
/= :: CodeExecSignal -> CodeExecSignal -> Bool
Eq, Int -> CodeExecSignal -> ShowS
[CodeExecSignal] -> ShowS
CodeExecSignal -> String
(Int -> CodeExecSignal -> ShowS)
-> (CodeExecSignal -> String)
-> ([CodeExecSignal] -> ShowS)
-> Show CodeExecSignal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CodeExecSignal -> ShowS
showsPrec :: Int -> CodeExecSignal -> ShowS
$cshow :: CodeExecSignal -> String
show :: CodeExecSignal -> String
$cshowList :: [CodeExecSignal] -> ShowS
showList :: [CodeExecSignal] -> ShowS
Show)
data Trust
=
Trusted (NonEmpty TrustEvidence)
|
Untrusted
|
TrustUnknown
deriving stock (Trust -> Trust -> Bool
(Trust -> Trust -> Bool) -> (Trust -> Trust -> Bool) -> Eq Trust
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Trust -> Trust -> Bool
== :: Trust -> Trust -> Bool
$c/= :: Trust -> Trust -> Bool
/= :: Trust -> Trust -> Bool
Eq, Int -> Trust -> ShowS
[Trust] -> ShowS
Trust -> String
(Int -> Trust -> ShowS)
-> (Trust -> String) -> ([Trust] -> ShowS) -> Show Trust
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Trust -> ShowS
showsPrec :: Int -> Trust -> ShowS
$cshow :: Trust -> String
show :: Trust -> String
$cshowList :: [Trust] -> ShowS
showList :: [Trust] -> ShowS
Show)
data TrustEvidence
=
Signed
|
Attested
|
MfaPublished
|
OtherEvidence Text
deriving stock (TrustEvidence -> TrustEvidence -> Bool
(TrustEvidence -> TrustEvidence -> Bool)
-> (TrustEvidence -> TrustEvidence -> Bool) -> Eq TrustEvidence
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TrustEvidence -> TrustEvidence -> Bool
== :: TrustEvidence -> TrustEvidence -> Bool
$c/= :: TrustEvidence -> TrustEvidence -> Bool
/= :: TrustEvidence -> TrustEvidence -> Bool
Eq, Int -> TrustEvidence -> ShowS
[TrustEvidence] -> ShowS
TrustEvidence -> String
(Int -> TrustEvidence -> ShowS)
-> (TrustEvidence -> String)
-> ([TrustEvidence] -> ShowS)
-> Show TrustEvidence
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TrustEvidence -> ShowS
showsPrec :: Int -> TrustEvidence -> ShowS
$cshow :: TrustEvidence -> String
show :: TrustEvidence -> String
$cshowList :: [TrustEvidence] -> ShowS
showList :: [TrustEvidence] -> ShowS
Show)
data Availability
=
Available
|
Deprecated Text
|
Yanked (Maybe Text)
deriving stock (Availability -> Availability -> Bool
(Availability -> Availability -> Bool)
-> (Availability -> Availability -> Bool) -> Eq Availability
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Availability -> Availability -> Bool
== :: Availability -> Availability -> Bool
$c/= :: Availability -> Availability -> Bool
/= :: Availability -> Availability -> Bool
Eq, Int -> Availability -> ShowS
[Availability] -> ShowS
Availability -> String
(Int -> Availability -> ShowS)
-> (Availability -> String)
-> ([Availability] -> ShowS)
-> Show Availability
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Availability -> ShowS
showsPrec :: Int -> Availability -> ShowS
$cshow :: Availability -> String
show :: Availability -> String
$cshowList :: [Availability] -> ShowS
showList :: [Availability] -> ShowS
Show)
data HashAlg
= SHA1
| SHA256
| SHA384
| SHA512
| MD5
| Blake2b
|
SRI
deriving stock (HashAlg
HashAlg -> HashAlg -> Bounded HashAlg
forall a. a -> a -> Bounded a
$cminBound :: HashAlg
minBound :: HashAlg
$cmaxBound :: HashAlg
maxBound :: HashAlg
Bounded, Int -> HashAlg
HashAlg -> Int
HashAlg -> [HashAlg]
HashAlg -> HashAlg
HashAlg -> HashAlg -> [HashAlg]
HashAlg -> HashAlg -> HashAlg -> [HashAlg]
(HashAlg -> HashAlg)
-> (HashAlg -> HashAlg)
-> (Int -> HashAlg)
-> (HashAlg -> Int)
-> (HashAlg -> [HashAlg])
-> (HashAlg -> HashAlg -> [HashAlg])
-> (HashAlg -> HashAlg -> [HashAlg])
-> (HashAlg -> HashAlg -> HashAlg -> [HashAlg])
-> Enum HashAlg
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: HashAlg -> HashAlg
succ :: HashAlg -> HashAlg
$cpred :: HashAlg -> HashAlg
pred :: HashAlg -> HashAlg
$ctoEnum :: Int -> HashAlg
toEnum :: Int -> HashAlg
$cfromEnum :: HashAlg -> Int
fromEnum :: HashAlg -> Int
$cenumFrom :: HashAlg -> [HashAlg]
enumFrom :: HashAlg -> [HashAlg]
$cenumFromThen :: HashAlg -> HashAlg -> [HashAlg]
enumFromThen :: HashAlg -> HashAlg -> [HashAlg]
$cenumFromTo :: HashAlg -> HashAlg -> [HashAlg]
enumFromTo :: HashAlg -> HashAlg -> [HashAlg]
$cenumFromThenTo :: HashAlg -> HashAlg -> HashAlg -> [HashAlg]
enumFromThenTo :: HashAlg -> HashAlg -> HashAlg -> [HashAlg]
Enum, HashAlg -> HashAlg -> Bool
(HashAlg -> HashAlg -> Bool)
-> (HashAlg -> HashAlg -> Bool) -> Eq HashAlg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: HashAlg -> HashAlg -> Bool
== :: HashAlg -> HashAlg -> Bool
$c/= :: HashAlg -> HashAlg -> Bool
/= :: HashAlg -> HashAlg -> Bool
Eq, Eq HashAlg
Eq HashAlg =>
(HashAlg -> HashAlg -> Ordering)
-> (HashAlg -> HashAlg -> Bool)
-> (HashAlg -> HashAlg -> Bool)
-> (HashAlg -> HashAlg -> Bool)
-> (HashAlg -> HashAlg -> Bool)
-> (HashAlg -> HashAlg -> HashAlg)
-> (HashAlg -> HashAlg -> HashAlg)
-> Ord HashAlg
HashAlg -> HashAlg -> Bool
HashAlg -> HashAlg -> Ordering
HashAlg -> HashAlg -> HashAlg
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: HashAlg -> HashAlg -> Ordering
compare :: HashAlg -> HashAlg -> Ordering
$c< :: HashAlg -> HashAlg -> Bool
< :: HashAlg -> HashAlg -> Bool
$c<= :: HashAlg -> HashAlg -> Bool
<= :: HashAlg -> HashAlg -> Bool
$c> :: HashAlg -> HashAlg -> Bool
> :: HashAlg -> HashAlg -> Bool
$c>= :: HashAlg -> HashAlg -> Bool
>= :: HashAlg -> HashAlg -> Bool
$cmax :: HashAlg -> HashAlg -> HashAlg
max :: HashAlg -> HashAlg -> HashAlg
$cmin :: HashAlg -> HashAlg -> HashAlg
min :: HashAlg -> HashAlg -> HashAlg
Ord, Int -> HashAlg -> ShowS
[HashAlg] -> ShowS
HashAlg -> String
(Int -> HashAlg -> ShowS)
-> (HashAlg -> String) -> ([HashAlg] -> ShowS) -> Show HashAlg
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HashAlg -> ShowS
showsPrec :: Int -> HashAlg -> ShowS
$cshow :: HashAlg -> String
show :: HashAlg -> String
$cshowList :: [HashAlg] -> ShowS
showList :: [HashAlg] -> ShowS
Show)
data Hash = Hash
{ Hash -> HashAlg
hashAlg :: HashAlg
, Hash -> Text
hashValue :: Text
}
deriving stock (Hash -> Hash -> Bool
(Hash -> Hash -> Bool) -> (Hash -> Hash -> Bool) -> Eq Hash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Hash -> Hash -> Bool
== :: Hash -> Hash -> Bool
$c/= :: Hash -> Hash -> Bool
/= :: Hash -> Hash -> Bool
Eq, Int -> Hash -> ShowS
[Hash] -> ShowS
Hash -> String
(Int -> Hash -> ShowS)
-> (Hash -> String) -> ([Hash] -> ShowS) -> Show Hash
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Hash -> ShowS
showsPrec :: Int -> Hash -> ShowS
$cshow :: Hash -> String
show :: Hash -> String
$cshowList :: [Hash] -> ShowS
showList :: [Hash] -> ShowS
Show)
mkHash :: HashAlg -> Text -> Either Text Hash
mkHash :: HashAlg -> Text -> Either Text Hash
mkHash HashAlg
alg Text
value
| HashAlg -> Text -> Bool
wellFormed HashAlg
alg Text
value = Hash -> Either Text Hash
forall a b. b -> Either a b
Right (HashAlg -> Text -> Hash
Hash HashAlg
alg Text
value)
| Bool
otherwise = Text -> Either Text Hash
forall a b. a -> Either a b
Left (Text
"malformed " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> HashAlg -> Text
renderHashAlg HashAlg
alg Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" digest")
wellFormed :: HashAlg -> Text -> Bool
wellFormed :: HashAlg -> Text -> Bool
wellFormed = \case
HashAlg
SRI -> Text -> Bool
wellFormedSri
HashAlg
alg -> HashAlg -> Text -> Bool
wellFormedHex HashAlg
alg
wellFormedHex :: HashAlg -> Text -> Bool
wellFormedHex :: HashAlg -> Text -> Bool
wellFormedHex HashAlg
alg Text
t =
case Base -> ByteString -> Either String ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> Either String bout
convertFromBase Base
Base16 (Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 (Text -> Text
T.toLower Text
t) :: ByteString) :: Either String ByteString of
Left String
_ -> Bool
False
Right ByteString
bytes -> HashAlg -> ByteString -> Bool
hexDigestOk HashAlg
alg ByteString
bytes
hexDigestOk :: HashAlg -> ByteString -> Bool
hexDigestOk :: HashAlg -> ByteString -> Bool
hexDigestOk HashAlg
alg ByteString
bytes = case HashAlg
alg of
HashAlg
SHA1 -> Maybe (Digest SHA1) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @SHA1 ByteString
bytes)
HashAlg
SHA256 -> Maybe (Digest SHA256) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @SHA256 ByteString
bytes)
HashAlg
SHA384 -> Maybe (Digest SHA384) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @SHA384 ByteString
bytes)
HashAlg
SHA512 -> Maybe (Digest SHA512) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @SHA512 ByteString
bytes)
HashAlg
MD5 -> Maybe (Digest MD5) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @MD5 ByteString
bytes)
HashAlg
Blake2b -> Maybe (Digest Blake2b_512) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @Blake2b_512 ByteString
bytes)
HashAlg
SRI -> Bool
False
computeDigest :: HashAlg -> Maybe (LByteString -> ByteString)
computeDigest :: HashAlg -> Maybe (LByteString -> ByteString)
computeDigest = \case
HashAlg
SHA1 -> (LByteString -> ByteString) -> Maybe (LByteString -> ByteString)
forall a. a -> Maybe a
Just (Digest SHA1 -> ByteString
forall a. Digest a -> ByteString
digestBytes (Digest SHA1 -> ByteString)
-> (LByteString -> Digest SHA1) -> LByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HashAlgorithm a => LByteString -> Digest a
hashlazy @SHA1)
HashAlg
SHA256 -> (LByteString -> ByteString) -> Maybe (LByteString -> ByteString)
forall a. a -> Maybe a
Just (Digest SHA256 -> ByteString
forall a. Digest a -> ByteString
digestBytes (Digest SHA256 -> ByteString)
-> (LByteString -> Digest SHA256) -> LByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HashAlgorithm a => LByteString -> Digest a
hashlazy @SHA256)
HashAlg
SHA384 -> (LByteString -> ByteString) -> Maybe (LByteString -> ByteString)
forall a. a -> Maybe a
Just (Digest SHA384 -> ByteString
forall a. Digest a -> ByteString
digestBytes (Digest SHA384 -> ByteString)
-> (LByteString -> Digest SHA384) -> LByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HashAlgorithm a => LByteString -> Digest a
hashlazy @SHA384)
HashAlg
SHA512 -> (LByteString -> ByteString) -> Maybe (LByteString -> ByteString)
forall a. a -> Maybe a
Just (Digest SHA512 -> ByteString
forall a. Digest a -> ByteString
digestBytes (Digest SHA512 -> ByteString)
-> (LByteString -> Digest SHA512) -> LByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HashAlgorithm a => LByteString -> Digest a
hashlazy @SHA512)
HashAlg
Blake2b -> (LByteString -> ByteString) -> Maybe (LByteString -> ByteString)
forall a. a -> Maybe a
Just (Digest Blake2b_512 -> ByteString
forall a. Digest a -> ByteString
digestBytes (Digest Blake2b_512 -> ByteString)
-> (LByteString -> Digest Blake2b_512) -> LByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HashAlgorithm a => LByteString -> Digest a
hashlazy @Blake2b_512)
HashAlg
MD5 -> Maybe (LByteString -> ByteString)
forall a. Maybe a
Nothing
HashAlg
SRI -> Maybe (LByteString -> ByteString)
forall a. Maybe a
Nothing
where
digestBytes :: Digest a -> ByteString
digestBytes :: forall a. Digest a -> ByteString
digestBytes = Digest a -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert
isComputable :: HashAlg -> Bool
isComputable :: HashAlg -> Bool
isComputable = Maybe (LByteString -> ByteString) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (LByteString -> ByteString) -> Bool)
-> (HashAlg -> Maybe (LByteString -> ByteString))
-> HashAlg
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashAlg -> Maybe (LByteString -> ByteString)
computeDigest
wellFormedSri :: Text -> Bool
wellFormedSri :: Text -> Bool
wellFormedSri Text
t = case Text -> [Text]
T.words Text
t of
[] -> Bool
False
[Text]
comps -> (Text -> Bool) -> [Text] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Text -> Bool
wellFormedSriComponent [Text]
comps
wellFormedSriComponent :: Text -> Bool
wellFormedSriComponent :: Text -> Bool
wellFormedSriComponent Text
comp
| Text -> Bool
T.null (Text -> Text
sriBody Text
comp) = Bool
False
| Bool
otherwise = Text -> Text -> Bool
sriBodyOk (Text -> Text
sriPrefix Text
comp) (Text -> Text
sriBody Text
comp)
sriBodyOk :: Text -> Text -> Bool
sriBodyOk :: Text -> Text -> Bool
sriBodyOk Text
algName Text
body =
case Base -> ByteString -> Either String ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> Either String bout
convertFromBase Base
Base64 (Text -> ByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 Text
body :: ByteString) :: Either String ByteString of
Left String
_ -> Bool
False
Right ByteString
bytes -> case Text
algName of
Text
"sha256" -> Maybe (Digest SHA256) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @SHA256 ByteString
bytes)
Text
"sha384" -> Maybe (Digest SHA384) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @SHA384 ByteString
bytes)
Text
"sha512" -> Maybe (Digest SHA512) -> Bool
forall a. Maybe a -> Bool
isJust (forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString @SHA512 ByteString
bytes)
Text
_ -> Bool
False
renderHashAlg :: HashAlg -> Text
renderHashAlg :: HashAlg -> Text
renderHashAlg = \case
HashAlg
MD5 -> Text
"md5"
HashAlg
SHA1 -> Text
"sha1"
HashAlg
SHA256 -> Text
"sha256"
HashAlg
SHA384 -> Text
"sha384"
HashAlg
SHA512 -> Text
"sha512"
HashAlg
Blake2b -> Text
"blake2b"
HashAlg
SRI -> Text
"sri"
parseHashAlg :: Text -> Either Text HashAlg
parseHashAlg :: Text -> Either Text HashAlg
parseHashAlg Text
raw = case (Char -> Bool) -> Text -> Text
T.filter (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'-') (Text -> Text
T.toLower (Text -> Text
T.strip Text
raw)) of
Text
"md5" -> HashAlg -> Either Text HashAlg
forall a b. b -> Either a b
Right HashAlg
MD5
Text
"sha1" -> HashAlg -> Either Text HashAlg
forall a b. b -> Either a b
Right HashAlg
SHA1
Text
"sha256" -> HashAlg -> Either Text HashAlg
forall a b. b -> Either a b
Right HashAlg
SHA256
Text
"sha384" -> HashAlg -> Either Text HashAlg
forall a b. b -> Either a b
Right HashAlg
SHA384
Text
"sha512" -> HashAlg -> Either Text HashAlg
forall a b. b -> Either a b
Right HashAlg
SHA512
Text
"blake2b" -> HashAlg -> Either Text HashAlg
forall a b. b -> Either a b
Right HashAlg
Blake2b
Text
_ -> Text -> Either Text HashAlg
forall a b. a -> Either a b
Left (Text
"unknown integrity algorithm: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
raw)
sriPrefix :: Text -> Text
sriPrefix :: Text -> Text
sriPrefix = (Text, Text) -> Text
forall a b. (a, b) -> a
fst ((Text, Text) -> Text) -> (Text -> (Text, Text)) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
T.breakOn Text
"-"
sriBody :: Text -> Text
sriBody :: Text -> Text
sriBody = Int -> Text -> Text
T.drop Int
1 (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, Text) -> Text
forall a b. (a, b) -> b
snd ((Text, Text) -> Text) -> (Text -> (Text, Text)) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
T.breakOn Text
"-"
sriAlgorithm :: Text -> Maybe HashAlg
sriAlgorithm :: Text -> Maybe HashAlg
sriAlgorithm Text
sri = case Text -> Text
sriPrefix Text
sri of
Text
"sha256" -> HashAlg -> Maybe HashAlg
forall a. a -> Maybe a
Just HashAlg
SHA256
Text
"sha384" -> HashAlg -> Maybe HashAlg
forall a. a -> Maybe a
Just HashAlg
SHA384
Text
"sha512" -> HashAlg -> Maybe HashAlg
forall a. a -> Maybe a
Just HashAlg
SHA512
Text
_ -> Maybe HashAlg
forall a. Maybe a
Nothing
data ArtifactKind
=
Tarball
|
Sdist
|
Wheel Text
|
Gem Text
deriving stock (ArtifactKind -> ArtifactKind -> Bool
(ArtifactKind -> ArtifactKind -> Bool)
-> (ArtifactKind -> ArtifactKind -> Bool) -> Eq ArtifactKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ArtifactKind -> ArtifactKind -> Bool
== :: ArtifactKind -> ArtifactKind -> Bool
$c/= :: ArtifactKind -> ArtifactKind -> Bool
/= :: ArtifactKind -> ArtifactKind -> Bool
Eq, Int -> ArtifactKind -> ShowS
[ArtifactKind] -> ShowS
ArtifactKind -> String
(Int -> ArtifactKind -> ShowS)
-> (ArtifactKind -> String)
-> ([ArtifactKind] -> ShowS)
-> Show ArtifactKind
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ArtifactKind -> ShowS
showsPrec :: Int -> ArtifactKind -> ShowS
$cshow :: ArtifactKind -> String
show :: ArtifactKind -> String
$cshowList :: [ArtifactKind] -> ShowS
showList :: [ArtifactKind] -> ShowS
Show)
data Artifact = Artifact
{ Artifact -> Text
artFilename :: Text
, Artifact -> Text
artUrl :: Text
, Artifact -> ArtifactKind
artKind :: ArtifactKind
, Artifact -> [Hash]
artHashes :: [Hash]
, Artifact -> Maybe Int
artSize :: Maybe Int
, Artifact -> Maybe Text
artInterpreter :: Maybe Text
, Artifact -> Bool
artYanked :: Bool
, Artifact -> Maybe Text
artProvenance :: Maybe Text
}
deriving stock (Artifact -> Artifact -> Bool
(Artifact -> Artifact -> Bool)
-> (Artifact -> Artifact -> Bool) -> Eq Artifact
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Artifact -> Artifact -> Bool
== :: Artifact -> Artifact -> Bool
$c/= :: Artifact -> Artifact -> Bool
/= :: Artifact -> Artifact -> Bool
Eq, Int -> Artifact -> ShowS
[Artifact] -> ShowS
Artifact -> String
(Int -> Artifact -> ShowS)
-> (Artifact -> String) -> ([Artifact] -> ShowS) -> Show Artifact
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Artifact -> ShowS
showsPrec :: Int -> Artifact -> ShowS
$cshow :: Artifact -> String
show :: Artifact -> String
$cshowList :: [Artifact] -> ShowS
showList :: [Artifact] -> ShowS
Show)
data Person = Person
{ Person -> Text
personName :: Text
, Person -> Maybe Text
personEmail :: Maybe Text
, Person -> Maybe Text
personUrl :: Maybe Text
}
deriving stock (Person -> Person -> Bool
(Person -> Person -> Bool)
-> (Person -> Person -> Bool) -> Eq Person
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Person -> Person -> Bool
== :: Person -> Person -> Bool
$c/= :: Person -> Person -> Bool
/= :: Person -> Person -> Bool
Eq, Eq Person
Eq Person =>
(Person -> Person -> Ordering)
-> (Person -> Person -> Bool)
-> (Person -> Person -> Bool)
-> (Person -> Person -> Bool)
-> (Person -> Person -> Bool)
-> (Person -> Person -> Person)
-> (Person -> Person -> Person)
-> Ord Person
Person -> Person -> Bool
Person -> Person -> Ordering
Person -> Person -> Person
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Person -> Person -> Ordering
compare :: Person -> Person -> Ordering
$c< :: Person -> Person -> Bool
< :: Person -> Person -> Bool
$c<= :: Person -> Person -> Bool
<= :: Person -> Person -> Bool
$c> :: Person -> Person -> Bool
> :: Person -> Person -> Bool
$c>= :: Person -> Person -> Bool
>= :: Person -> Person -> Bool
$cmax :: Person -> Person -> Person
max :: Person -> Person -> Person
$cmin :: Person -> Person -> Person
min :: Person -> Person -> Person
Ord, Int -> Person -> ShowS
[Person] -> ShowS
Person -> String
(Int -> Person -> ShowS)
-> (Person -> String) -> ([Person] -> ShowS) -> Show Person
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Person -> ShowS
showsPrec :: Int -> Person -> ShowS
$cshow :: Person -> String
show :: Person -> String
$cshowList :: [Person] -> ShowS
showList :: [Person] -> ShowS
Show)
data PackageDetails = PackageDetails
{ PackageDetails -> PackageName
pkgName :: PackageName
, PackageDetails -> Version
pkgVersion :: Version
, PackageDetails -> Maybe UTCTime
pkgPublishedAt :: Maybe UTCTime
, PackageDetails -> CodeExecSignal
pkgInstallCode :: CodeExecSignal
, PackageDetails -> Trust
pkgTrust :: Trust
, PackageDetails -> Availability
pkgAvailability :: Availability
, PackageDetails -> NonEmpty Artifact
pkgArtifacts :: NonEmpty Artifact
, PackageDetails -> [Text]
pkgLicenses :: [Text]
, PackageDetails -> Maybe Person
pkgPublisher :: Maybe Person
}
deriving stock (PackageDetails -> PackageDetails -> Bool
(PackageDetails -> PackageDetails -> Bool)
-> (PackageDetails -> PackageDetails -> Bool) -> Eq PackageDetails
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PackageDetails -> PackageDetails -> Bool
== :: PackageDetails -> PackageDetails -> Bool
$c/= :: PackageDetails -> PackageDetails -> Bool
/= :: PackageDetails -> PackageDetails -> Bool
Eq, Int -> PackageDetails -> ShowS
[PackageDetails] -> ShowS
PackageDetails -> String
(Int -> PackageDetails -> ShowS)
-> (PackageDetails -> String)
-> ([PackageDetails] -> ShowS)
-> Show PackageDetails
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PackageDetails -> ShowS
showsPrec :: Int -> PackageDetails -> ShowS
$cshow :: PackageDetails -> String
show :: PackageDetails -> String
$cshowList :: [PackageDetails] -> ShowS
showList :: [PackageDetails] -> ShowS
Show)
data PackageInfo = PackageInfo
{ PackageInfo -> PackageName
infoName :: PackageName
, PackageInfo -> Map Text PackageDetails
infoVersions :: Map Text PackageDetails
, PackageInfo -> Map Text Version
infoDistTags :: Map Text Version
, PackageInfo -> [InvalidEntry]
infoInvalidEntries :: [InvalidEntry]
}
deriving stock (PackageInfo -> PackageInfo -> Bool
(PackageInfo -> PackageInfo -> Bool)
-> (PackageInfo -> PackageInfo -> Bool) -> Eq PackageInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PackageInfo -> PackageInfo -> Bool
== :: PackageInfo -> PackageInfo -> Bool
$c/= :: PackageInfo -> PackageInfo -> Bool
/= :: PackageInfo -> PackageInfo -> Bool
Eq, Int -> PackageInfo -> ShowS
[PackageInfo] -> ShowS
PackageInfo -> String
(Int -> PackageInfo -> ShowS)
-> (PackageInfo -> String)
-> ([PackageInfo] -> ShowS)
-> Show PackageInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PackageInfo -> ShowS
showsPrec :: Int -> PackageInfo -> ShowS
$cshow :: PackageInfo -> String
show :: PackageInfo -> String
$cshowList :: [PackageInfo] -> ShowS
showList :: [PackageInfo] -> ShowS
Show)
data InvalidEntry = InvalidEntry
{ InvalidEntry -> InvalidEntryKind
invalidKind :: InvalidEntryKind
, InvalidEntry -> Text
invalidKey :: Text
, InvalidEntry -> Value
invalidValue :: Value
, InvalidEntry -> Text
invalidReason :: Text
}
deriving stock (InvalidEntry -> InvalidEntry -> Bool
(InvalidEntry -> InvalidEntry -> Bool)
-> (InvalidEntry -> InvalidEntry -> Bool) -> Eq InvalidEntry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InvalidEntry -> InvalidEntry -> Bool
== :: InvalidEntry -> InvalidEntry -> Bool
$c/= :: InvalidEntry -> InvalidEntry -> Bool
/= :: InvalidEntry -> InvalidEntry -> Bool
Eq, Int -> InvalidEntry -> ShowS
[InvalidEntry] -> ShowS
InvalidEntry -> String
(Int -> InvalidEntry -> ShowS)
-> (InvalidEntry -> String)
-> ([InvalidEntry] -> ShowS)
-> Show InvalidEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InvalidEntry -> ShowS
showsPrec :: Int -> InvalidEntry -> ShowS
$cshow :: InvalidEntry -> String
show :: InvalidEntry -> String
$cshowList :: [InvalidEntry] -> ShowS
showList :: [InvalidEntry] -> ShowS
Show)
data InvalidEntryKind
=
InvalidVersionManifest
|
InvalidDistTag
|
InvalidPublishTime
deriving stock (InvalidEntryKind -> InvalidEntryKind -> Bool
(InvalidEntryKind -> InvalidEntryKind -> Bool)
-> (InvalidEntryKind -> InvalidEntryKind -> Bool)
-> Eq InvalidEntryKind
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InvalidEntryKind -> InvalidEntryKind -> Bool
== :: InvalidEntryKind -> InvalidEntryKind -> Bool
$c/= :: InvalidEntryKind -> InvalidEntryKind -> Bool
/= :: InvalidEntryKind -> InvalidEntryKind -> Bool
Eq, Int -> InvalidEntryKind -> ShowS
[InvalidEntryKind] -> ShowS
InvalidEntryKind -> String
(Int -> InvalidEntryKind -> ShowS)
-> (InvalidEntryKind -> String)
-> ([InvalidEntryKind] -> ShowS)
-> Show InvalidEntryKind
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InvalidEntryKind -> ShowS
showsPrec :: Int -> InvalidEntryKind -> ShowS
$cshow :: InvalidEntryKind -> String
show :: InvalidEntryKind -> String
$cshowList :: [InvalidEntryKind] -> ShowS
showList :: [InvalidEntryKind] -> ShowS
Show)