73 lines
2.0 KiB
Haskell
73 lines
2.0 KiB
Haskell
-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>
|
|
--
|
|
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
|
|
|
module Settings.Cookies
|
|
( CookieSettings(..)
|
|
, HasCookieSettings(..)
|
|
, cookieSettingsToSetCookie
|
|
) where
|
|
|
|
import ClassyPrelude
|
|
|
|
import Web.Cookie
|
|
import Web.Cookie.Instances ()
|
|
|
|
import Utils.PathPiece
|
|
|
|
import Data.Time.Clock
|
|
import Data.Time.Clock.Instances ()
|
|
|
|
import qualified Data.Text as Text
|
|
import qualified Data.HashMap.Strict as HashMap
|
|
import qualified Data.CaseInsensitive as CI
|
|
|
|
import Data.Aeson
|
|
import Data.Aeson.TH
|
|
|
|
import Control.Lens ((&))
|
|
import Control.Monad.Fail
|
|
|
|
|
|
data CookieSettings = CookieSettings
|
|
{ cookieExpires :: Maybe NominalDiffTime
|
|
, cookieSameSite :: Maybe SameSiteOption
|
|
, cookieHttpOnly
|
|
, cookieSecure :: Maybe Bool
|
|
} deriving (Eq, Show, Generic)
|
|
deriving anyclass (Hashable)
|
|
|
|
instance FromJSON SameSiteOption where
|
|
parseJSON = withText "SameSiteOption" $ \(CI.mk -> ciT) -> HashMap.lookup ciT options
|
|
& maybe (fail . unpack $ "Expected one of: " <> Text.intercalate ", " (map CI.original $ HashMap.keys options)) return
|
|
where options = mconcat
|
|
[ singletonMap "Lax" sameSiteLax
|
|
, singletonMap "Strict" sameSiteStrict
|
|
, singletonMap "None" sameSiteNone
|
|
]
|
|
|
|
deriveFromJSON defaultOptions
|
|
{ omitNothingFields = True
|
|
, fieldLabelModifier = camelToPathPiece' 1
|
|
} ''CookieSettings
|
|
|
|
|
|
class HasCookieSettings ident app | app -> ident where
|
|
getCookieSettings :: app -> ident -> CookieSettings
|
|
|
|
instance HasCookieSettings ident (ident -> CookieSettings) where
|
|
getCookieSettings = id
|
|
|
|
|
|
cookieSettingsToSetCookie :: MonadIO m => CookieSettings -> m SetCookie
|
|
cookieSettingsToSetCookie CookieSettings{..} = do
|
|
now <- liftIO getCurrentTime
|
|
return def
|
|
{ setCookieExpires = addUTCTime <$> cookieExpires <*> pure now
|
|
, setCookieSameSite = cookieSameSite
|
|
, setCookieHttpOnly = fromMaybe (setCookieHttpOnly def) cookieHttpOnly
|
|
, setCookieSecure = fromMaybe (setCookieSecure def) cookieSecure
|
|
}
|