blockfrost-api-0.1.0.0: src/Blockfrost/Auth.hs
-- | Blockfrost authentication schemes
{-# LANGUAGE PolyKinds #-}
module Blockfrost.Auth
( APIKeyInHeader
, APIKeyInHeaderSettings (..)
, Env (..)
, Project (..)
, ProjectAuth
, mkProject
, mkProjectEnv
) where
import Data.Kind (Type)
import Data.Proxy (Proxy (..))
import Data.Text as Text
import GHC.Generics (Generic)
import GHC.TypeLits
import Servant.API (HasLink (..), (:>))
import qualified Data.Text
import Data.String (IsString (..))
import Blockfrost.Env
-- * Authentication result and clients token
data Project = Project {
projectEnv :: Env
, projectId :: Text
}
deriving (Eq, Show, Generic)
-- | Parse @Project@ from @Text@
mkProject' :: Text -> Either Text Project
mkProject' t =
let st = Data.Text.strip t
tEnv = Data.Text.dropEnd 32 st
token = Data.Text.drop (Data.Text.length tEnv) st
in Project <$> parseEnv tEnv <*> pure token
-- | Parse @Project@ from @Text@ or fail with error
mkProject :: Text -> Project
mkProject = either (error . Data.Text.unpack) id . mkProject'
-- | @Project@ constructor
mkProjectEnv :: Env -> Text -> Project
mkProjectEnv = Project
instance IsString Project where
fromString = mkProject . Data.Text.pack
-- * Common
-- | The type of Auth scheme.
data APIKeyInHeader (headerName :: Symbol)
-- | Auth scheme settings
-- Needs IO action to verify passed in token and maybe return Project
newtype APIKeyInHeaderSettings =
APIKeyInHeaderSettings
{ apiKeySettingsQueryProject :: Text -> IO (Maybe Project)
}
-- * Custom Auth
-- we use custom ProjectAuth instead of Auth from servant-auth
-- to get rid of superfluous Contexts like JWTSettings and CookiesSettings
data ProjectAuth (auths :: [Type]) val
instance HasLink sub => HasLink (ProjectAuth (tag :: [Type]) value :> sub) where
type MkLink (ProjectAuth (tag :: [Type]) value :> sub) r = MkLink sub r
toLink toA _ = toLink toA (Proxy @sub)