-
Notifications
You must be signed in to change notification settings - Fork 0
/
HawkServer.hs
57 lines (49 loc) · 2.08 KB
/
HawkServer.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
module HawkServer where
import Control.Monad.IO.Class (liftIO)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as S8
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Char8 as L8
import Data.Default
import qualified Data.Map as M
import Data.Monoid
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import Network.HTTP.Types.Header
import Network.HTTP.Types.Status
import Network.Wai
import Network.Wai.Handler.Warp
import Common
import Network.Hawk.Types
import qualified Network.Hawk.Server as Hawk
import qualified Network.Hawk.Server.Nonce as Hawk
serverMain :: IO ()
serverMain = do
opts <- Hawk.nonceOptsReq 60
run 8000 (app opts)
auth :: ClientId -> IO (Either String (Hawk.Credentials, Text))
auth id = return $ Right (Hawk.Credentials sharedKey (HawkAlgo SHA256), "Steve")
app :: Hawk.AuthReqOpts -> Application
app opts req respond = do
payload <- lazyRequestBody req
res <- Hawk.authenticateRequest opts auth req (Just payload)
respond $ case res of
Right (Hawk.AuthSuccess creds artifacts user) -> let
ext = decodeUtf8 <$> haExt artifacts
payload = textPayload $ "Hello " <> user <> maybe "" (" " <>) ext
(ok, autho) = Hawk.header res (Just payload)
in responseLBS ok [payloadCt payload, autho] (payloadData payload)
Left f -> let
(status, hdr) = Hawk.header res Nothing
msg = case f of
Hawk.AuthFailBadRequest e _ -> e
Hawk.AuthFailUnauthorized e _ _ -> "Shoosh!"
Hawk.AuthFailStaleTimeStamp e _ _ _ -> e
in responseLBS status [plain, hdr] (L8.pack msg)
textPayload :: Text -> PayloadInfo
textPayload = PayloadInfo (snd plain) . BL.fromStrict . encodeUtf8
payloadCt :: PayloadInfo -> Header
payloadCt (PayloadInfo ct _) = (hContentType, ct)
plain :: Header
plain = (hContentType, "text/plain")