module Ldap.Client.Bind
( Password(..)
, bind
, bindEither
, bindAsync
, bindAsyncSTM
, externalBind
, externalBindEither
, externalBindAsync
, externalBindAsyncSTM
, Async
, wait
, waitSTM
) where
import Control.Monad.STM (STM, atomically)
import Data.ByteString (ByteString)
import Data.Text (Text)
import Data.List.NonEmpty (NonEmpty((:|)))
import qualified Ldap.Asn1.Type as Type
import Ldap.Client.Internal
newtype Password = Password ByteString
deriving (Show, Eq)
bind :: Ldap -> Dn -> Password -> IO ()
bind l username password =
eitherToIO =<< bindEither l username password
bindEither :: Ldap -> Dn -> Password -> IO (Either ResponseError ())
bindEither l username password =
wait =<< bindAsync l username password
bindAsync :: Ldap -> Dn -> Password -> IO (Async ())
bindAsync l username password =
atomically (bindAsyncSTM l username password)
bindAsyncSTM :: Ldap -> Dn -> Password -> STM (Async ())
bindAsyncSTM l username password =
let req = bindRequest username password in sendRequest l (bindResult req) req
bindRequest :: Dn -> Password -> Request
bindRequest (Dn username) (Password password) =
Type.BindRequest ldapVersion
(Type.LdapDn (Type.LdapString username))
(Type.Simple password)
where
ldapVersion = 3
bindResult :: Request -> Response -> Either ResponseError ()
bindResult req (Type.BindResponse (Type.LdapResult code (Type.LdapDn (Type.LdapString dn))
(Type.LdapString msg) _) _ :| [])
| Type.Success <- code = Right ()
| otherwise = Left (ResponseErrorCode req code (Dn dn) msg)
bindResult req res = Left (ResponseInvalid req res)
externalBind :: Ldap -> Dn -> Maybe Text -> IO ()
externalBind l username mCredentials =
eitherToIO =<< externalBindEither l username mCredentials
externalBindEither :: Ldap -> Dn -> Maybe Text -> IO (Either ResponseError ())
externalBindEither l username mCredentials =
wait =<< externalBindAsync l username mCredentials
externalBindAsync :: Ldap -> Dn -> Maybe Text -> IO (Async ())
externalBindAsync l username mCredentials =
atomically (externalBindAsyncSTM l username mCredentials)
externalBindAsyncSTM :: Ldap -> Dn -> Maybe Text -> STM (Async ())
externalBindAsyncSTM l username mCredentials =
let req = externalBindRequest username mCredentials in sendRequest l (bindResult req) req
externalBindRequest :: Dn -> Maybe Text -> Request
externalBindRequest (Dn username) mCredentials =
Type.BindRequest ldapVersion
(Type.LdapDn (Type.LdapString username))
(Type.Sasl Type.External mCredentials)
where
ldapVersion = 3