{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DeriveDataTypeable #-} {- A simple OAuth2 http client. -} module Network.OAuth2.HTTP.HttpClient ( requestAccessToken , doRequest , signRequest ) where import Control.Monad.Trans.Resource import Data.Aeson import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as BSL import Data.List import Data.Maybe import Network.HTTP.Types (renderSimpleQuery, parseSimpleQuery) import qualified Network.HTTP.Types as HT import Network.HTTP.Conduit import Control.Exception import Control.Applicative ((<$>)) import Network.OAuth2.OAuth2 -------------------------------------------------- -- | Request (POST method) access token URL in order to get @AccessToken@. -- FIXME: what if @requestAccessToken'@ return error? requestAccessToken :: OAuth2 -> BS.ByteString -- ^ Authentication code gained after authorization -> IO (Maybe AccessToken) requestAccessToken oa code = decode <$> requestAccessToken' oa code requestAccessToken' :: OAuth2 -> BS.ByteString -> IO BSL.ByteString requestAccessToken' oa code = doRequest req >>= retOrError where req = urlEncodedBody body $ toReq' uri (uri, body) = accessTokenUrl oa code retOrError rsp = if (HT.statusCode . statusCode) rsp == 200 then return $ responseBody rsp else throwIO . OAuthException $ "Gaining access_token failed: " ++ BSL.unpack (responseBody rsp) -- | insert access token into the request signRequest :: OAuth2 -> Request m -> Request m signRequest oa req = req { queryString = renderSimpleQuery False newQuery } where newQuery = case oauthAccessToken oa of Just at -> insert ("access_token", at) oldQuery _ -> insert ("client_id", oauthClientId oa) . insert ("client_secret", oauthClientSecret oa) $ oldQuery oldQuery = parseSimpleQuery (queryString req) -------------------------------------------------- -- UTIL toReq' :: BS.ByteString -> Request a toReq' = fromJust . parseUrl . BS.unpack -- | Performance a http @Request@ doRequest :: ResourceIO m => Request m -> m (Response BSL.ByteString) doRequest = withManager . httpLbs