{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Network.AWS.CloudFront.SignedCookies.Policy
(
Policy (..)
, simplePolicy
, Resource (..)
, StartTime (..)
, EndTime (..)
, Lifespan (..)
, IpAddress (..)
, policyJSON
) where
import Network.AWS.CloudFront.SignedCookies.Types
import qualified Data.Aeson as A
import Data.Semigroup ((<>))
import qualified Data.ByteString.Lazy as LBS
import Data.Time.Clock.POSIX (getPOSIXTime)
import qualified Data.HashMap.Strict as Map
import qualified Data.Vector as Vec
policyJSON :: Policy -> ByteString
policyJSON =
LBS.toStrict . A.encode . policyValue
policyValue :: Policy -> A.Value
policyValue policy =
A.Object $ Map.singleton "Statement" $
A.Array $ Vec.singleton $
A.Object $ "Resource" .= resourceValue policy <>
"Condition" .= conditionValue policy
resourceValue :: Policy -> A.Value
resourceValue (Policy (Resource x) _ _ _) = A.String x
conditionValue :: Policy -> A.Value
conditionValue (Policy _ start end ip) =
A.Object $ startCondition <> endCondition <> ipCondition
where
startCondition :: A.Object =
case start of
StartImmediately -> mempty
StartTime x -> "DateGreaterThan" .= posixTimeValue x
endCondition :: A.Object =
case end of
EndTime x -> "DateLessThan" .= posixTimeValue x
ipCondition :: A.Object =
case ip of
AnyIp -> mempty
IpAddress x -> "IpAddress" .= sourceIpValue x
posixTimeValue :: POSIXTime -> A.Value
posixTimeValue =
A.Object . ("AWS:EpochTime" .=) . A.Number . fromInteger . round
sourceIpValue :: Text -> A.Value
sourceIpValue =
A.Object . ("AWS:SourceIp" .=) . A.String
(.=) :: Text -> A.Value -> A.Object
(.=) = Map.singleton
simplePolicy
:: Resource
-> Lifespan
-> IO Policy
simplePolicy res life = do
now :: POSIXTime <- getPOSIXTime
let end = case life of Lifespan x -> EndTime (now + x)
pure
Policy
{ policyResource = res
, policyEnd = end
, policyStart = StartImmediately
, policyIpAddress = AnyIp
}