{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Database.CQL.IO.Connection.Settings
( ConnectionSettings
, ConnId (..)
, defSettings
, defKeyspace
, compression
, tlsContext
, Milliseconds (..)
, connectTimeout
, sendTimeout
, responseTimeout
, maxStreams
, maxRecvBuffer
, authenticators
, AuthMechanism (..)
, Authenticator (..)
, AuthContext (..)
, authConnId
, authHost
, passwordAuthenticator
, AuthUser (..)
, AuthPass (..)
) where
import Control.Lens (makeLenses)
import Data.Hashable
import Data.HashMap.Strict (HashMap)
import Data.String
import Data.Text (Text)
import Data.Unique
import Database.CQL.Protocol
import Database.CQL.IO.Cluster.Host
import OpenSSL.Session (SSLContext)
import qualified Data.ByteString.Lazy.Char8 as Char8
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text.Lazy as Lazy
import qualified Data.Text.Lazy.Encoding as Lazy
newtype Milliseconds = Ms { ms :: Int }
deriving (Eq, Show)
newtype ConnId = ConnId Unique deriving (Eq, Ord)
instance Hashable ConnId where
hashWithSalt _ (ConnId u) = hashUnique u
data ConnectionSettings = ConnectionSettings
{ _connectTimeout :: !Milliseconds
, _sendTimeout :: !Milliseconds
, _responseTimeout :: !Milliseconds
, _maxStreams :: !Int
, _compression :: !Compression
, _defKeyspace :: !(Maybe Keyspace)
, _maxRecvBuffer :: !Int
, _tlsContext :: !(Maybe SSLContext)
, _authenticators :: !(HashMap AuthMechanism Authenticator)
}
data AuthContext = AuthContext
{ _authConnId :: !ConnId
, _authHost :: !InetAddr
}
newtype AuthMechanism = AuthMechanism Text
deriving (Eq, Ord, Show, IsString, Hashable)
data Authenticator = forall s. Authenticator
{ authMechanism :: !AuthMechanism
, authOnRequest :: AuthContext -> IO (AuthResponse, s)
, authOnChallenge :: Maybe (s -> AuthChallenge -> IO (AuthResponse, s))
, authOnSuccess :: s -> AuthSuccess -> IO ()
}
makeLenses ''AuthContext
makeLenses ''ConnectionSettings
newtype AuthUser = AuthUser Lazy.Text
newtype AuthPass = AuthPass Lazy.Text
passwordAuthenticator :: AuthUser -> AuthPass -> Authenticator
passwordAuthenticator (AuthUser u) (AuthPass p) = Authenticator
{ authMechanism = "org.apache.cassandra.auth.PasswordAuthenticator"
, authOnChallenge = Nothing
, authOnSuccess = \() _ -> return ()
, authOnRequest = \_ctx ->
let user = Lazy.encodeUtf8 u
pass = Lazy.encodeUtf8 p
resp = AuthResponse (Char8.concat ["\0", user, "\0", pass])
in return (resp, ())
}
defSettings :: ConnectionSettings
defSettings =
ConnectionSettings (Ms 5000)
(Ms 3000)
(Ms 10000)
128
noCompression
Nothing
16384
Nothing
HashMap.empty