packages feed

ms-graph-api 0.4.0.0 → 0.5.0.0

raw patch · 5 files changed

+42/−9 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ MSGraphAPI.Internal.Common: getE :: FromJSON a => [Text] -> Option 'Https -> AccessToken -> Req (Either HttpException a)
+ MSGraphAPI.Internal.Common: postE :: (ToJSON a, FromJSON b) => [Text] -> Option 'Https -> a -> AccessToken -> Req (Either HttpException b)
+ MSGraphAPI.Internal.Common: tryReq :: Req a -> Req (Either HttpException a)
- MSGraphAPI.Internal.Common: post :: (FromJSON b, ToJSON a) => [Text] -> Option 'Https -> a -> AccessToken -> Req b
+ MSGraphAPI.Internal.Common: post :: (ToJSON a, FromJSON b) => [Text] -> Option 'Https -> a -> AccessToken -> Req b

Files

CHANGELOG.md view
@@ -8,6 +8,10 @@  ## Unreleased +## 0.5.0.0++Add 'getE', 'postE', 'tryReq' to pattern match against HTTP exceptions+ ## 0.4.0.0  Add Session.tokensToList and Session.newTokens
ms-graph-api.cabal view
@@ -1,5 +1,5 @@ name:                ms-graph-api-version:             0.4.0.0+version:             0.5.0.0 synopsis:            Microsoft Graph API description:         Bindings to the Microsoft Graph API homepage:            https://github.com/unfoldml/ms-graph-api
src/MSGraphAPI/Internal/Common.hs view
@@ -7,10 +7,15 @@   -- * GET   get   , getLbs+  -- ** catch HTTP exceptions+  , getE   -- * POST   , post+    -- ** catch HTTP exceptions+  , postE   -- * running requests   , runReq+  , tryReq   -- * JSON : aeson helpers   , Collection(..)   , aesonOptions@@ -38,17 +43,27 @@ -- modern-uri import Text.URI (URI, mkURI) -- req-import Network.HTTP.Req (Req, runReq, defaultHttpConfig, req, Option, (=:), GET(..), POST(..), Url, Scheme(..), useHttpsURI, https, (/:), ReqBodyJson(..), NoReqBody(..), oAuth2Bearer, HttpResponse(..), jsonResponse, JsonResponse, lbsResponse, LbsResponse, bsResponse, BsResponse, responseBody)+import Network.HTTP.Req (Req, runReq, HttpException(..), defaultHttpConfig, req, Option, (=:), GET(..), POST(..), Url, Scheme(..), useHttpsURI, https, (/:), ReqBodyJson(..), NoReqBody(..), oAuth2Bearer, HttpResponse(..), jsonResponse, JsonResponse, lbsResponse, LbsResponse, bsResponse, BsResponse, responseBody) -- text import Data.Text (Text, pack, unpack)+-- unliftio+import UnliftIO (MonadUnliftIO(..))+import UnliftIO.Exception (try)  import Network.OAuth2.Session (Tokens)  +-- | Specialized version of 'try' to 'HttpException's+--+-- This can be used to catch exceptions of composite 'Req' statements, e.g. around a @do@ block+tryReq :: Req a -> Req (Either HttpException a)+tryReq = try++ -- -- GET, POST   -- | @POST https:\/\/graph.microsoft.com\/v1.0\/...@-post :: (A.FromJSON b, A.ToJSON a) =>+post :: (A.ToJSON a, A.FromJSON b) =>         [Text] -- ^ URI path segments      -> Option 'Https      -> a -- ^ request body@@ -59,6 +74,12 @@     opts = auth <> params     (url, auth) = msGraphReqConfig tok paths +-- | Like 'post' but catches 'HttpException's to allow pattern matching+postE :: (A.ToJSON a, A.FromJSON b) =>+         [Text] -- ^ URI path segments+      -> Option 'Https -> a -> AccessToken -> Req (Either HttpException b)+postE paths params bdy tok = tryReq (post paths params bdy tok)+ -- | @GET https:\/\/graph.microsoft.com\/v1.0\/...@ get :: A.FromJSON a =>        [Text] -- ^ URI path segments@@ -69,6 +90,12 @@   where     opts = auth <> params     (url, auth) = msGraphReqConfig tok paths++-- | Like 'get' but catches 'HttpException's to allow pattern matching+getE :: (A.FromJSON a) =>+        [Text] -- ^ URI path segments+     -> Option 'Https -> AccessToken -> Req (Either HttpException a)+getE paths params tok = tryReq (get paths params tok)  -- | @GET https:\/\/graph.microsoft.com\/v1.0\/...@ --
src/Network/OAuth2/Provider/AzureAD.hs view
@@ -34,6 +34,7 @@  type instance IdpUserInfo AzureAD = AzureADUser +-- | Configuration object of the OAuth2 application data OAuthCfg = OAuthCfg {   oacAppName :: TL.Text -- ^ application name   , oacClientId :: ClientId -- ^ app client ID : see https://stackoverflow.com/a/70670961@@ -43,7 +44,7 @@   , oacRedirectURI :: URI -- ^ OAuth2 redirect URI                          } --- | NB : OIDC scopes @openid@ and @offline_access@ are ALWAYS requested since the library assumes we have access to refresh tokens and ID tokens+-- | NB : scopes @openid@ and @offline_access@ are ALWAYS requested since the library assumes we have access to refresh tokens and ID tokens azureADApp :: OAuthCfg -- ^ OAuth configuration            -> IdpApplication 'AuthorizationCode AzureAD azureADApp (OAuthCfg appname clid sec scopes authstate reduri) = defaultAzureADApp{
src/Network/OAuth2/Session.hs view
@@ -136,7 +136,7 @@           IdpApplication 'AuthorizationCode AzureAD        -> Action m () loginH idpApp = do-  setHeader "Location" (mkAuthorizeRequest idpApp) -- $ azureADApp oacfg)+  setHeader "Location" (mkAuthorizeRequest idpApp) -- redirect to OAuth consent screen   status status302  -- | The identity provider redirects the client to the 'reply' endpoint as part of the OAuth flow : https://learn.microsoft.com/en-us/graph/auth-v2-user?view=graph-rest-1.0&tabs=http#authorization-response@@ -165,7 +165,7 @@              etoken = ExchangeToken $ TL.toStrict codeP            _ <- fetchUpdateToken ts idpApp mgr etoken            pure ()-         Nothing -> throwE OASEExchangeTokenNotFound -- $ T.pack $ unwords ["cannot decode token"]+         Nothing -> throwE OASEExchangeTokenNotFound  -- @@ -183,7 +183,7 @@                  -> IdpApplication 'AuthorizationCode AzureAD                  -> Manager                  -> ExchangeToken -- ^ also called 'code'. Expires in 10 minutes-                 -> ExceptT OAuthSessionError m OAuth2Token -- IO (Either T.Text OAuth2Token)+                 -> ExceptT OAuthSessionError m OAuth2Token fetchUpdateToken ts idpApp mgr etoken = ExceptT $ do   tokenResp <- runExceptT $ conduitTokenRequest idpApp mgr etoken -- OAuth2 token   case tokenResp of@@ -195,14 +195,15 @@           Right uid -> do             _ <- refreshLoop ts idpApp mgr uid oat -- fork a thread and start refresh loop for this user             pure $ Right oat-          Left es -> pure $ Left (OASEJWTException es) -- $ T.pack (show e) -- ^ id token validation failed+          Left es -> pure $ Left (OASEJWTException es) -- id token validation failed     Left es -> pure $ Left (OASEOAuth2Errors es) +-- | 2) fork a thread and start token refresh loop for user @uid@ refreshLoop :: (MonadUnliftIO m, Ord uid, HasRefreshTokenRequest a) =>                Tokens uid OAuth2Token             -> IdpApplication a i             -> Manager-            -> uid+            -> uid -- ^ user ID             -> OAuth2Token             -> m ThreadId refreshLoop ts idpApp mgr uid oaToken = forkFinally (act oaToken) cleanup