{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE TemplateHaskell #-} module Neptune.Session where import Control.Concurrent (ThreadId) import Control.Lens import Control.Monad.Except import qualified Data.Aeson as Aeson import Data.Aeson.Lens import qualified Data.ByteString.Base64 as Base64 import qualified Network.HTTP.Client as NH import RIO hiding (Lens', (^.)) import qualified RIO.Text as T import System.Envy (FromEnv (..), Parser, env) import Neptune.Backend.Core import Neptune.Backend.MimeTypes import Neptune.Backend.Model import Neptune.OAuth data ClientToken = ClientToken { _ct_token :: Text , _ct_api_address :: Text , _ct_api_url :: Text , _ct_api_key :: Text } deriving (Generic, Show) instance FromEnv ClientToken where fromEnv _ = do token <- env "NEPTUNE_API_TOKEN" jsraw <- either throwError return $ Base64.decode $ T.encodeUtf8 token js <- either throwError return $ Aeson.eitherDecodeStrict' jsraw :: Parser Aeson.Value return $ ClientToken token (js ^?! key "api_address" . _String) (js ^?! key "api_url" . _String) (js ^?! key "api_key" . _String) type Dispatcher = forall req contentType res accept . (Produces req accept, MimeUnrender accept res, MimeType contentType, HasCallStack) => NeptuneBackendRequest req contentType res accept -> IO res data NeptuneSession = NeptuneSession { _neptune_http_manager :: NH.Manager , _neptune_client_token :: ClientToken , _neptune_config :: NeptuneBackendConfig , _neptune_oauth2 :: MVar OAuth2Session , _neptune_oauth2_refresh :: ThreadId , _neptune_project :: ProjectWithRoleDTO , _neptune_dispatch :: Dispatcher }