{-# LANGUAGE CPP, QuasiQuotes #-} module Yesod.Helpers.Auth.OAuth ( authOAuth , oauthUrl , authTwitter , twitterUrl ) where import Yesod import Yesod.Helpers.Auth import Network.OAuth.Consumer import Network.OAuth.Http.Request hiding (replace) import qualified Network.OAuth.Http.Request as OA import Network.OAuth.Http.CurlHttpClient import Data.Maybe import Data.String oauthUrl :: String -> AuthRoute oauthUrl name = PluginR name ["forward"] authOAuth :: YesodAuth m => String -- ^ Service Name -> String -- ^ OAuth Parameter Name to use for identify -> String -- ^ Request URL -> String -- ^ Access Token URL -> String -- ^ Authorize URL -> String -- ^ Consumer Key -> String -- ^ Consumer Secret -> AuthPlugin m authOAuth name ident reqUrl accUrl authUrl key sec = AuthPlugin name dispatch login where url = PluginR name [] dispatch "GET" ["forward"] = do render <- getUrlRender tm <- getRouteToMaster let app = Application key sec (URL $ render $ tm url) tok <- runOAuthM (fromApplication app) $ do signRq2 HMACSHA1 Nothing (fromJust . parseURL $ reqUrl) >>= oauthRequest CurlClient let oaUrl = fromString $ concat [ authUrl , "?oauth_token=" , findWithDefault ("oauth_token", "ERR") $ oauthParams tok ] redirectString RedirectTemporary oaUrl dispatch "GET" [] = do render <- getUrlRender tm <- getRouteToMaster let app = Application key sec (URL $ render $ tm url) verifier <- runFormGet' $ stringInput "oauth_verifier" oaTok <- runFormGet' $ stringInput "oauth_token" let appTok = fromApplication app params = OA.replace ("oauth_token", oaTok) $ oauthParams appTok reqTok = injectOAuthVerifier verifier $ ReqToken app params accTok <- runOAuthM reqTok $ do signRq2 HMACSHA1 Nothing (fromJust . parseURL $ accUrl) >>= oauthRequest CurlClient let crId = findWithDefault (ident, error "oops!") $ oauthParams accTok creds = Creds name crId $ toList $ oauthParams accTok setCreds True creds dispatch _ _ = notFound login tm = do render <- lift getUrlRender let oaUrl = render $ tm $ oauthUrl name addHtml #if GHC7 [hamlet| #else [$hamlet| #endif !href=$oaUrl$ Login with $name$ |] authTwitter :: YesodAuth m => String -- ^ Consumer Key -> String -- ^ Consumer Secret -> AuthPlugin m authTwitter = authOAuth "twitter" "screen_name" "http://twitter.com/oauth/request_token" "http://twitter.com/oauth/access_token" "http://twitter.com/oauth/authorize" twitterUrl :: AuthRoute twitterUrl = oauthUrl "twitter"