6 -- |Manipulation of WWW authorization.
7 module Network.HTTP.Lucu.Authorization
18 import Data.Ascii (Ascii)
19 import qualified Data.Ascii as A
20 import Data.Attoparsec.Char8
21 import qualified Data.ByteString.Base64 as B64
22 import qualified Data.ByteString.Char8 as C8
23 import Data.Monoid.Unicode
24 import Network.HTTP.Lucu.Parser.Http
25 import Network.HTTP.Lucu.Utils
26 import Prelude.Unicode
28 -- |Authorization challenge to be sent to client with
29 -- \"WWW-Authenticate\" header. See
30 -- 'Network.HTTP.Lucu.Resource.setWWWAuthenticate'.
32 = BasicAuthChallenge !Realm
35 -- |'Realm' is just a string which must not contain any non-ASCII letters.
38 -- |Authorization credential to be sent by client with
39 -- \"Authorization\" header. See
40 -- 'Network.HTTP.Lucu.Resource.getAuthorization'.
42 = BasicAuthCredential !UserID !Password
45 -- |'UserID' is just a string which must not contain colon and any
49 -- |'Password' is just a string which must not contain any non-ASCII
53 -- |Convert an 'AuthChallenge' to 'Ascii'.
54 printAuthChallenge ∷ AuthChallenge → Ascii
55 printAuthChallenge (BasicAuthChallenge realm)
56 = A.fromAsciiBuilder $
57 A.toAsciiBuilder "Basic realm=" ⊕ quoteStr realm
59 authCredentialP ∷ Parser AuthCredential
61 = do _ ← string "Basic"
63 b64 ← takeWhile1 base64
64 case C8.break (≡ ':') (B64.decodeLenient b64) of
67 → fail "no colons in the basic auth credential"
70 p ← asc (C8.tail cPassword)
71 return (BasicAuthCredential u p)
74 base64 = inClass "a-zA-Z0-9+/="
76 asc ∷ C8.ByteString → Parser Ascii
77 asc bs = case A.fromByteString bs of
79 Nothing → fail "Non-ascii character in auth credential"