packages feed

wai-middleware-auth 0.1.1.2 → 0.1.2.0

raw patch · 3 files changed

+104/−13 lines, 3 filesdep +uri-bytestringdep ~hoauth2PVP ok

version bump matches the API change (PVP)

Dependencies added: uri-bytestring

Dependency ranges changed: hoauth2

API changes (from Hackage documentation)

+ Network.Wai.Middleware.Auth.OAuth2: URIParseException :: URIParseError -> URIParseException
+ Network.Wai.Middleware.Auth.OAuth2: data URIParseException
+ Network.Wai.Middleware.Auth.OAuth2: instance GHC.Exception.Exception Network.Wai.Middleware.Auth.OAuth2.URIParseException
+ Network.Wai.Middleware.Auth.OAuth2: instance GHC.Show.Show Network.Wai.Middleware.Auth.OAuth2.URIParseException
+ Network.Wai.Middleware.Auth.OAuth2: parseAbsoluteURI :: MonadThrow m => Text -> m URI

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+0.1.2.0+=======++* Implemented compatibility with hoauth2 >= 1.0.0 - fixed: [#3](https://github.com/fpco/wai-middleware-auth/issues/3)+ 0.1.1.2 ======= 
src/Network/Wai/Middleware/Auth/OAuth2.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP               #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-} {-# LANGUAGE TemplateHaskell   #-}@@ -5,11 +6,15 @@ module Network.Wai.Middleware.Auth.OAuth2   ( OAuth2(..)   , oAuth2Parser+  , URIParseException(..)+  , parseAbsoluteURI   ) where +import           Control.Monad.Catch import           Data.Aeson.TH                        (defaultOptions,                                                        deriveJSON,                                                        fieldLabelModifier)+import qualified Data.ByteString                      as S import qualified Data.ByteString.Lazy                 as SL import           Data.Monoid                          ((<>)) import           Data.Proxy                           (Proxy (..))@@ -22,8 +27,17 @@ import           Network.Wai                          (queryString, responseLBS) import           Network.Wai.Auth.Tools               (toLowerUnderscore) import           Network.Wai.Middleware.Auth.Provider+import qualified URI.ByteString                       as U +#if MIN_VERSION_hoauth2(1,0,0)+import           Data.Text.Encoding                   (decodeUtf8With)+import           Data.Text.Encoding.Error             (lenientDecode)+import           URI.ByteString                       (URI)+#else+type URI = OA2.URI+#endif +-- | General OAuth2 authentication `Provider`. data OAuth2 = OAuth2   { oa2ClientId            :: T.Text   , oa2ClientSecret        :: T.Text@@ -33,7 +47,74 @@   , oa2ProviderInfo        :: ProviderInfo   } +-- | Used for validating proper url structure. Can be thrown by+-- `parseAbsoluteURI` and consequently by `handleLogin` for `OAuth2` `Provider`+-- instance.+--+-- @since 0.1.2.0+data URIParseException = URIParseException U.URIParseError deriving Show +instance Exception URIParseException++-- | Parse absolute URI and throw `URIParseException` in case it is malformed+--+-- @since 0.1.2.0+parseAbsoluteURI :: MonadThrow m => T.Text -> m U.URI+parseAbsoluteURI urlTxt = do+  case U.parseURI U.strictURIParserOptions (encodeUtf8 urlTxt) of+    Left err  -> throwM $ URIParseException err+    Right url -> return url+++#if MIN_VERSION_hoauth2(1,0,0)++parseAbsoluteURI' :: MonadThrow m => T.Text -> m U.URI+parseAbsoluteURI' = parseAbsoluteURI++getExchangeToken :: S.ByteString -> OA2.ExchangeToken+getExchangeToken = OA2.ExchangeToken . decodeUtf8With lenientDecode++appendQueryParams :: URI -> [(S.ByteString, S.ByteString)] -> URI+appendQueryParams uri params =+  OA2.appendQueryParams params uri++getClientId :: T.Text -> T.Text+getClientId = id++getClientSecret :: T.Text -> T.Text+getClientSecret = id++getRedirectURI :: U.URIRef a -> S.ByteString+getRedirectURI = U.serializeURIRef'++getAccessToken :: OA2.OAuth2Token -> S.ByteString+getAccessToken = encodeUtf8 . OA2.atoken . OA2.accessToken++#else++parseAbsoluteURI' :: MonadThrow m => T.Text -> m URI+parseAbsoluteURI' urlTxt = U.serializeURIRef' <$> parseAbsoluteURI urlTxt++getExchangeToken :: S.ByteString -> S.ByteString+getExchangeToken = id++appendQueryParams :: URI -> [(S.ByteString, S.ByteString)] -> URI+appendQueryParams uri params = OA2.appendQueryParam uri params++getClientId :: T.Text -> S.ByteString+getClientId = encodeUtf8++getClientSecret :: T.Text -> S.ByteString+getClientSecret = encodeUtf8++getRedirectURI :: URI -> S.ByteString+getRedirectURI = id++getAccessToken :: OA2.AccessToken -> S.ByteString+getAccessToken = OA2.accessToken++#endif+ -- | Aeson parser for `OAuth2` provider. -- -- @since 0.1.0@@ -45,21 +126,25 @@   getProviderName _ = "oauth2"   getProviderInfo = oa2ProviderInfo   handleLogin oa2@OAuth2 {..} req suffix renderUrl onSuccess onFailure = do+    authEndpointURI <- parseAbsoluteURI' oa2AuthorizeEndpoint+    accessTokenEndpointURI <- parseAbsoluteURI' oa2AccessTokenEndpoint+    callbackURI <- parseAbsoluteURI' $ renderUrl (ProviderUrl ["complete"]) []     let oauth2 =           OA2.OAuth2-          { oauthClientId = encodeUtf8 oa2ClientId-          , oauthClientSecret = encodeUtf8 oa2ClientSecret-          , oauthOAuthorizeEndpoint = encodeUtf8 oa2AuthorizeEndpoint-          , oauthAccessTokenEndpoint = encodeUtf8 oa2AccessTokenEndpoint-          , oauthCallback =-              Just $ encodeUtf8 $ renderUrl (ProviderUrl ["complete"]) []+          { oauthClientId = getClientId oa2ClientId+          , oauthClientSecret = getClientSecret oa2ClientSecret+          , oauthOAuthorizeEndpoint = authEndpointURI+          , oauthAccessTokenEndpoint = accessTokenEndpointURI+          , oauthCallback = Just callbackURI           }     case suffix of       [] -> do         let scope = (encodeUtf8 . T.intercalate ",") <$> oa2Scope         let redirectUrl =-              OA2.appendQueryParam (OA2.authorizationUrl oauth2) $-              maybe [] ((: []) . ("scope", )) scope+              getRedirectURI $+              appendQueryParams+                (OA2.authorizationUrl oauth2)+                (maybe [] ((: []) . ("scope", )) scope)         return $           responseLBS             status303@@ -70,10 +155,10 @@         in case lookup "code" params of              Just (Just code) -> do                man <- getGlobalManager-               eRes <- OA2.fetchAccessToken man oauth2 code+               eRes <- OA2.fetchAccessToken man oauth2 $ getExchangeToken code                case eRes of                  Left err    -> onFailure status501 $ SL.toStrict err-                 Right token -> onSuccess $ OA2.accessToken token+                 Right token -> onSuccess $ getAccessToken token              _ ->                case lookup "error" params of                  (Just (Just "access_denied")) ->
wai-middleware-auth.cabal view
@@ -1,5 +1,5 @@ name:                wai-middleware-auth-version:             0.1.1.2+version:             0.1.2.0 synopsis:            Authentication middleware that secures WAI application description:         See README license:             MIT@@ -24,7 +24,7 @@                        Network.Wai.Auth.ClientSession                        Network.Wai.Auth.Tools   build-depends:       aeson-                     , base              >= 4.7 && < 5+                     , base                 >= 4.7 && < 5                      , base64-bytestring                      , binary                      , blaze-builder@@ -35,7 +35,7 @@                      , clientsession                      , cookie                      , exceptions-                     , hoauth2+                     , hoauth2              >= 0.5.0                      , http-client                      , http-client-tls                      , http-conduit@@ -47,6 +47,7 @@                      , text                      , unix-compat                      , unordered-containers+                     , uri-bytestring                      , vault                      , wai                  >= 3.0 && < 4                      , wai-app-static