diff --git a/yesod-auth-oauth/Yesod/Auth/OAuth.hs b/yesod-auth-oauth/Yesod/Auth/OAuth.hs
index 7efd9dfe..8d2598de 100644
--- a/yesod-auth-oauth/Yesod/Auth/OAuth.hs
+++ b/yesod-auth-oauth/Yesod/Auth/OAuth.hs
@@ -5,6 +5,7 @@ module Yesod.Auth.OAuth
, oauthUrl
, authTwitter
, twitterUrl
+ , module Web.Authenticate.OAuth
) where
#include "qq.h"
@@ -16,71 +17,75 @@ import Yesod.Widget
import Text.Hamlet (shamlet)
import Web.Authenticate.OAuth
import Data.Maybe
-import Data.String
-import Data.ByteString.Char8 (pack)
import Control.Arrow ((***))
-import Data.Text (Text, unpack)
+import Data.Text (Text)
+import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8, decodeUtf8With)
import Data.Text.Encoding.Error (lenientDecode)
import Data.ByteString (ByteString)
import Control.Applicative ((<$>), (<*>))
+import Data.Conduit
oauthUrl :: Text -> AuthRoute
oauthUrl name = PluginR name ["forward"]
-authOAuth :: YesodAuth m =>
- Text -- ^ 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
+authOAuth :: YesodAuth m
+ => OAuth -- ^ 'OAuth' data-type for signing.
+ -> (Credential -> IO (Creds m)) -- ^ How to extract ident.
-> AuthPlugin m
-authOAuth name ident reqUrl accUrl authUrl key sec = AuthPlugin name dispatch login
+authOAuth oauth mkCreds = AuthPlugin name dispatch login
where
+ name = T.pack $ oauthServerName oauth
url = PluginR name []
- oauth = OAuth { oauthServerName = unpack name, oauthRequestUri = reqUrl
- , oauthAccessTokenUri = accUrl, oauthAuthorizeUri = authUrl
- , oauthSignatureMethod = HMACSHA1
- , oauthConsumerKey = fromString key, oauthConsumerSecret = fromString sec
- , oauthCallback = Nothing
- , oauthRealm = Nothing
- }
+ lookupTokenSecret = bsToText . fromMaybe "" . lookup "oauth_token_secret" . unCredential
+ oauthSessionName = "__oauth_token_secret"
dispatch "GET" ["forward"] = do
render <- getUrlRender
tm <- getRouteToMaster
let oauth' = oauth { oauthCallback = Just $ encodeUtf8 $ render $ tm url }
master <- getYesod
tok <- lift $ getTemporaryCredential oauth' (authHttpManager master)
+ setSession oauthSessionName $ lookupTokenSecret tok
redirect $ authorizeUrl oauth' tok
dispatch "GET" [] = do
(verifier, oaTok) <- runInputGet $ (,)
<$> ireq textField "oauth_verifier"
<*> ireq textField "oauth_token"
- let reqTok = Credential [ ("oauth_verifier", encodeUtf8 verifier), ("oauth_token", encodeUtf8 oaTok)
+ tokSec <- fromJust <$> lookupSession oauthSessionName
+ deleteSession oauthSessionName
+ let reqTok = Credential [ ("oauth_verifier", encodeUtf8 verifier)
+ , ("oauth_token", encodeUtf8 oaTok)
+ , ("oauth_token_secret", encodeUtf8 tokSec)
]
master <- getYesod
accTok <- lift $ getAccessToken oauth reqTok (authHttpManager master)
- let crId = decodeUtf8With lenientDecode $ fromJust $ lookup (pack ident) $ unCredential accTok
- creds = Creds name crId $ map (bsToText *** bsToText ) $ unCredential accTok
+ creds <- resourceLiftBase $ mkCreds accTok
setCreds True creds
dispatch _ _ = notFound
login tm = do
render <- lift getUrlRender
let oaUrl = render $ tm $ oauthUrl name
addHtml
- [QQ(shamlet)| Login with #{name} |]
+ [QQ(shamlet)| Login via #{name} |]
-authTwitter :: YesodAuth m =>
- String -- ^ Consumer Key
- -> String -- ^ Consumer Secret
+authTwitter :: YesodAuth m
+ => ByteString -- ^ Consumer Key
+ -> ByteString -- ^ 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"
+authTwitter key secret = authOAuth
+ (newOAuth { oauthServerName = "twitter"
+ , oauthRequestUri = "https://api.twitter.com/oauth/request_token"
+ , oauthAccessTokenUri = "https://api.twitter.com/oauth/access_token"
+ , oauthAuthorizeUri = "https://api.twitter.com/oauth/authorize"
+ , oauthSignatureMethod = HMACSHA1
+ , oauthConsumerKey = key
+ , oauthConsumerSecret = secret
+ })
+ extractCreds
+ where
+ extractCreds (Credential dic) = do
+ let crId = decodeUtf8With lenientDecode $ fromJust $ lookup "screen_name" dic
+ return $ Creds "twitter" crId $ map (bsToText *** bsToText ) dic
twitterUrl :: AuthRoute
twitterUrl = oauthUrl "twitter"
diff --git a/yesod-auth-oauth/yesod-auth-oauth.cabal b/yesod-auth-oauth/yesod-auth-oauth.cabal
index 171f7dcd..f86efd85 100644
--- a/yesod-auth-oauth/yesod-auth-oauth.cabal
+++ b/yesod-auth-oauth/yesod-auth-oauth.cabal
@@ -27,6 +27,7 @@ library
, yesod-auth >= 0.8 && < 0.9
, text >= 0.7 && < 0.12
, hamlet >= 0.10 && < 0.11
+ , conduit >= 0.2 && < 0.3
, yesod-form >= 0.4 && < 0.5
exposed-modules: Yesod.Auth.OAuth