{-# OPTIONS_HADDOCK prune #-} -- |Manipulation of WWW authorization. module Network.HTTP.Lucu.Authorization ( AuthChallenge(..) , AuthCredential(..) , Realm , UserID , Password , authCredentialP -- private ) where import qualified Codec.Binary.Base64 as B64 import Data.Maybe import Network.HTTP.Lucu.Parser import Network.HTTP.Lucu.Parser.Http import Network.HTTP.Lucu.Utils -- |Authorization challenge to be sent to client with -- \"WWW-Authenticate\" header. See -- 'Network.HTTP.Lucu.Resource.setWWWAuthenticate'. data AuthChallenge = BasicAuthChallenge Realm deriving (Eq) -- |'Realm' is just a string which must not contain any non-ASCII letters. type Realm = String -- |Authorization credential to be sent by client with -- \"Authorization\" header. See -- 'Network.HTTP.Lucu.Resource.getAuthorization'. data AuthCredential = BasicAuthCredential UserID Password deriving (Show, Eq) -- |'UserID' is just a string which must not contain colon and any -- non-ASCII letters. type UserID = String -- |'Password' is just a string which must not contain any non-ASCII -- letters. type Password = String instance Show AuthChallenge where show (BasicAuthChallenge realm) = "Basic realm=" ++ quoteStr realm authCredentialP :: Parser AuthCredential authCredentialP = allowEOF $! do _ <- string "Basic" _ <- many1 lws b64 <- many1 $ satisfy (\ c -> (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=') let decoded = map (toEnum . fromEnum) (fromJust $ B64.decode b64) case break (== ':') decoded of (uid, ':' : password) -> return (BasicAuthCredential uid password) _ -> failP