{-# LANGUAGE OverloadedStrings #-} module Snap.Snaplet.OAuth.Internal.Handlers ( loginWithOauthH , oauthCallbackH ) where import Control.Monad.CatchIO (throw) import qualified Data.ByteString as BS import Data.Maybe import Network.OAuth.OAuth2 import Network.OAuth.OAuth2.HttpClient import Prelude hiding ((.)) import Snap import Snap.Snaplet.OAuth.Internal.Types import Snap.Snaplet.OAuth.Internal.Utils ---------------------------------------------------------------------- -- | Login via OAuth. Redirect user for authorization. -- loginWithOauthH :: HasOAuth b => OAuthKey -> Maybe BS.ByteString -- ^ Maybe extra query parameters,e.g., 'scope' param for google oauth. -> Handler b v () loginWithOauthH key param = withOAuthH key fn where extraP (Just x) = "&" `BS.append` x extraP Nothing = "" fn oauth = redirect $ authorizationUrl oauth `BS.append` extraP param ---------------------------------------------------------------------- -- | Callback for oauth provider. -- oauthCallbackH :: HasOAuth b => OAuthKey -> Handler b v OAuthValue oauthCallbackH key = withOAuthH key fn where fn oauth = do codeParam <- decodedParam accessTokenKey maybeToken <- liftIO $ requestAccessToken oauth codeParam case maybeToken of Just token -> liftIO $ modifyAccessToken token oauth _ -> throw (OAuthException $ "Failed to request Access Token." ++ show key) >> return oauth modifyAccessToken :: AccessToken -> OAuth2 -> IO OAuth2 modifyAccessToken (AccessToken at _) origin = return $ origin { oauthAccessToken = Just at } accessTokenKey :: BS.ByteString accessTokenKey = "code" ---------------------------------------------------------------------- -- | Perform an action with a full initilized @OAuth2@. -- withOAuthH :: HasOAuth b => OAuthKey -> (OAuthValue -> Handler b v a) -> Handler b v a withOAuthH key fn = do value <- lookupOAuth key case value of Nothing -> failure Just oauth -> fn oauth where failure = throw $ OAuthException $ "oauth data has not been init of: " ++ show key -- checkLogin :: HasOAuth b => OAuth2 -> Handler b v () -- checkLogin oa = when (isNothing $ oauthAccessToken oa) $ redirect "weibo"