ms-graph-api 0.7.0.0 → 0.8.0.0
raw patch · 10 files changed
+242/−62 lines, 10 filesdep +http-client-tlsPVP ok
version bump matches the API change (PVP)
Dependencies added: http-client-tls
API changes (from Hackage documentation)
- MSGraphAPI.Files.DriveItem: instance GHC.Classes.Eq MSGraphAPI.Files.DriveItem.DriveItem
- MSGraphAPI.Files.DriveItem: instance GHC.Classes.Ord MSGraphAPI.Files.DriveItem.DriveItem
- MSGraphAPI.Internal.Common: Collection :: [a] -> Collection a
- MSGraphAPI.Internal.Common: [cValue] :: Collection a -> [a]
- MSGraphAPI.Internal.Common: aesonOptions :: String -> Options
- MSGraphAPI.Internal.Common: data Collection a
- MSGraphAPI.Internal.Common: get :: FromJSON a => [Text] -> Option 'Https -> AccessToken -> Req a
- MSGraphAPI.Internal.Common: getE :: FromJSON a => [Text] -> Option 'Https -> AccessToken -> Req (Either HttpException a)
- MSGraphAPI.Internal.Common: getLbs :: [Text] -> Option 'Https -> AccessToken -> Req ByteString
- MSGraphAPI.Internal.Common: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (MSGraphAPI.Internal.Common.Collection a)
- MSGraphAPI.Internal.Common: instance GHC.Classes.Eq a => GHC.Classes.Eq (MSGraphAPI.Internal.Common.Collection a)
- MSGraphAPI.Internal.Common: instance GHC.Generics.Generic (MSGraphAPI.Internal.Common.Collection a)
- MSGraphAPI.Internal.Common: instance GHC.Show.Show a => GHC.Show.Show (MSGraphAPI.Internal.Common.Collection a)
- MSGraphAPI.Internal.Common: post :: (ToJSON a, FromJSON b) => [Text] -> Option 'Https -> a -> AccessToken -> Req b
- MSGraphAPI.Internal.Common: postE :: (ToJSON a, FromJSON b) => [Text] -> Option 'Https -> a -> AccessToken -> Req (Either HttpException b)
- MSGraphAPI.Internal.Common: runReq :: MonadIO m => HttpConfig -> Req a -> m a
- MSGraphAPI.Internal.Common: tryReq :: Req a -> Req (Either HttpException a)
+ MSGraphAPI: Collection :: [a] -> Maybe Text -> Collection a
+ MSGraphAPI: [cNextLink] :: Collection a -> Maybe Text
+ MSGraphAPI: [cValue] :: Collection a -> [a]
+ MSGraphAPI: data Collection a
+ MSGraphAPI: run :: MonadIO m => HttpConfig -> Req a -> m (Either HttpException a)
+ MSGraphAPI: tryReq :: Req a -> Req (Either HttpException a)
+ MSGraphAPI: withTLS :: MonadIO m => (HttpConfig -> m b) -> m b
+ MSGraphAPI.ChangeNotifications.Subscription: ChangeNotification :: ChangeType -> Text -> Text -> Text -> Maybe a -> Text -> Text -> ChangeNotification a
+ MSGraphAPI.ChangeNotifications.Subscription: [cnChangeType] :: ChangeNotification a -> ChangeType
+ MSGraphAPI.ChangeNotifications.Subscription: [cnClientState] :: ChangeNotification a -> Text
+ MSGraphAPI.ChangeNotifications.Subscription: [cnId] :: ChangeNotification a -> Text
+ MSGraphAPI.ChangeNotifications.Subscription: [cnResourceData] :: ChangeNotification a -> Maybe a
+ MSGraphAPI.ChangeNotifications.Subscription: [cnResource] :: ChangeNotification a -> Text
+ MSGraphAPI.ChangeNotifications.Subscription: [cnSubscriptionId] :: ChangeNotification a -> Text
+ MSGraphAPI.ChangeNotifications.Subscription: [cnTenantId] :: ChangeNotification a -> Text
+ MSGraphAPI.ChangeNotifications.Subscription: data ChangeNotification a
+ MSGraphAPI.ChangeNotifications.Subscription: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (MSGraphAPI.ChangeNotifications.Subscription.ChangeNotification a)
+ MSGraphAPI.ChangeNotifications.Subscription: instance GHC.Classes.Eq a => GHC.Classes.Eq (MSGraphAPI.ChangeNotifications.Subscription.ChangeNotification a)
+ MSGraphAPI.ChangeNotifications.Subscription: instance GHC.Generics.Generic (MSGraphAPI.ChangeNotifications.Subscription.ChangeNotification a)
+ MSGraphAPI.ChangeNotifications.Subscription: instance GHC.Show.Show a => GHC.Show.Show (MSGraphAPI.ChangeNotifications.Subscription.ChangeNotification a)
+ MSGraphAPI.Files.DriveItem: DIIBundle :: DIItem
+ MSGraphAPI.Files.DriveItem: DIIFile :: File -> DIItem
+ MSGraphAPI.Files.DriveItem: DIIFolder :: Folder -> DIItem
+ MSGraphAPI.Files.DriveItem: DIIPackage :: Package -> DIItem
+ MSGraphAPI.Files.DriveItem: DIIPhoto :: DIItem
+ MSGraphAPI.Files.DriveItem: DIIRemoteItem :: DIItem
+ MSGraphAPI.Files.DriveItem: DIIVideo :: DIItem
+ MSGraphAPI.Files.DriveItem: File :: Text -> File
+ MSGraphAPI.Files.DriveItem: Folder :: Int32 -> Folder
+ MSGraphAPI.Files.DriveItem: Package :: Text -> Package
+ MSGraphAPI.Files.DriveItem: [diItem] :: DriveItem -> DIItem
+ MSGraphAPI.Files.DriveItem: [difiMimeType] :: File -> Text
+ MSGraphAPI.Files.DriveItem: [difoChildCount] :: Folder -> Int32
+ MSGraphAPI.Files.DriveItem: [dipType] :: Package -> Text
+ MSGraphAPI.Files.DriveItem: data DIItem
+ MSGraphAPI.Files.DriveItem: data File
+ MSGraphAPI.Files.DriveItem: data Folder
+ MSGraphAPI.Files.DriveItem: data Package
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.FromJSON.FromJSON MSGraphAPI.Files.DriveItem.File
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.FromJSON.FromJSON MSGraphAPI.Files.DriveItem.Folder
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.FromJSON.FromJSON MSGraphAPI.Files.DriveItem.Package
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.ToJSON.ToJSON MSGraphAPI.Files.DriveItem.DIItem
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.ToJSON.ToJSON MSGraphAPI.Files.DriveItem.DriveItem
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.ToJSON.ToJSON MSGraphAPI.Files.DriveItem.File
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.ToJSON.ToJSON MSGraphAPI.Files.DriveItem.Folder
+ MSGraphAPI.Files.DriveItem: instance Data.Aeson.Types.ToJSON.ToJSON MSGraphAPI.Files.DriveItem.Package
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Eq MSGraphAPI.Files.DriveItem.DIItem
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Eq MSGraphAPI.Files.DriveItem.File
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Eq MSGraphAPI.Files.DriveItem.Folder
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Eq MSGraphAPI.Files.DriveItem.Package
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Ord MSGraphAPI.Files.DriveItem.DIItem
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Ord MSGraphAPI.Files.DriveItem.File
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Ord MSGraphAPI.Files.DriveItem.Folder
+ MSGraphAPI.Files.DriveItem: instance GHC.Classes.Ord MSGraphAPI.Files.DriveItem.Package
+ MSGraphAPI.Files.DriveItem: instance GHC.Generics.Generic MSGraphAPI.Files.DriveItem.DIItem
+ MSGraphAPI.Files.DriveItem: instance GHC.Generics.Generic MSGraphAPI.Files.DriveItem.File
+ MSGraphAPI.Files.DriveItem: instance GHC.Generics.Generic MSGraphAPI.Files.DriveItem.Folder
+ MSGraphAPI.Files.DriveItem: instance GHC.Generics.Generic MSGraphAPI.Files.DriveItem.Package
+ MSGraphAPI.Files.DriveItem: instance GHC.Show.Show MSGraphAPI.Files.DriveItem.DIItem
+ MSGraphAPI.Files.DriveItem: instance GHC.Show.Show MSGraphAPI.Files.DriveItem.File
+ MSGraphAPI.Files.DriveItem: instance GHC.Show.Show MSGraphAPI.Files.DriveItem.Folder
+ MSGraphAPI.Files.DriveItem: instance GHC.Show.Show MSGraphAPI.Files.DriveItem.Package
+ MSGraphAPI.Files.DriveItem: listGroupItemChildren :: Text -> Text -> AccessToken -> Req (Collection DriveItem)
+ MSGraphAPI.Files.DriveItem: listRootChildrenMe :: AccessToken -> Req (Collection DriveItem)
+ MSGraphAPI.Users.Group: getMeJoinedTeams :: AccessToken -> Req (Collection Group)
+ MSGraphAPI.Users.Group: instance Data.Aeson.Types.ToJSON.ToJSON MSGraphAPI.Users.Group.Group
- MSGraphAPI.Files.DriveItem: DriveItem :: Text -> Text -> LocalTime -> DriveItem
+ MSGraphAPI.Files.DriveItem: DriveItem :: Text -> Text -> ZonedTime -> DIItem -> DriveItem
- MSGraphAPI.Files.DriveItem: [diLastModifiedDateTime] :: DriveItem -> LocalTime
+ MSGraphAPI.Files.DriveItem: [diLastModifiedDateTime] :: DriveItem -> ZonedTime
Files
- CHANGELOG.md +6/−0
- README.md +3/−2
- ms-graph-api.cabal +6/−26
- src/MSGraphAPI.hs +5/−0
- src/MSGraphAPI/Auth.hs +0/−2
- src/MSGraphAPI/ChangeNotifications/Subscription.hs +27/−2
- src/MSGraphAPI/Files/DriveItem.hs +119/−6
- src/MSGraphAPI/Internal/Common.hs +55/−20
- src/MSGraphAPI/Users/Group.hs +20/−3
- src/MSGraphAPI/Users/User.hs +1/−1
CHANGELOG.md view
@@ -10,6 +10,12 @@ +## 0.8.0.0++MSGraphAPI.Files.DriveItem+++ ## 0.7.0.0
README.md view
@@ -9,9 +9,9 @@ ## Introduction -This library provides both the client interface (under the `MSGraphAPI` namespace) as well as helpers to integrate with Microsoft infrastructure, e.g. using ActiveDirectory as an OAuth2 identity provider.+This library provides both client interface to the MS Grapi API (under the `MSGraphAPI` namespace). -With the provided auth functions (see `Network.OAuth2.Session`) you can easily implement OAuth2 for your application, and the resulting token store is thread-safe and automatically renews before expiring.+Authentication can be implemented with the `ms-auth` library. ## Status @@ -26,6 +26,7 @@ We adhere to the [Package Versioning Policy](https://pvp.haskell.org/): major breaking changes or API refactors are signaled by increasing the first major version number (i.e. 0.0.0.0 -> 1.0.0.0 ) whereas less significant ones are indicated by increasing the second one (0.0.0.0 -> 0.1.0.0) +Significant changes in the SDK will be documented in the respective CHANGELOG. ## Copyright
ms-graph-api.cabal view
@@ -1,8 +1,8 @@ name: ms-graph-api-version: 0.7.0.0+version: 0.8.0.0 synopsis: Microsoft Graph API description: Bindings to the Microsoft Graph API-homepage: https://github.com/unfoldml/ms-api+homepage: https://github.com/unfoldml/ms-graph-api license: BSD3 license-file: LICENSE author: Marco Zocca@@ -18,19 +18,20 @@ library default-language: Haskell2010 hs-source-dirs: src- exposed-modules: MSGraphAPI.ChangeNotifications.Subscription+ exposed-modules: MSGraphAPI+ MSGraphAPI.ChangeNotifications.Subscription MSGraphAPI.User MSGraphAPI.Users.User MSGraphAPI.Users.Group MSGraphAPI.Drive MSGraphAPI.Files.DriveItem- MSGraphAPI.Internal.Common- other-modules: MSGraphAPI.Auth+ other-modules: MSGraphAPI.Internal.Common build-depends: base >= 4.7 && < 5 , aeson , bytestring , containers , hoauth2 == 2.6.0+ , http-client-tls >= 0.3 , http-types , modern-uri , req@@ -47,27 +48,6 @@ DeriveFunctor DerivingStrategies LambdaCase----- test-suite spec--- default-language: Haskell2010--- type: exitcode-stdio-1.0--- hs-source-dirs: test--- main-is: Spec.hs--- other-modules: LibSpec--- build-depends: base--- , ms-graph-api--- , hspec--- , QuickCheck--- ghc-options: -Wall--- -Wcompat--- -Widentities--- -Wincomplete-record-updates--- -Wincomplete-uni-patterns--- -Wmissing-export-lists--- -Wmissing-home-modules--- -Wpartial-fields--- -Wredundant-constraints source-repository head type: git
+ src/MSGraphAPI.hs view
@@ -0,0 +1,5 @@+module MSGraphAPI (+ Collection(..), run, tryReq, withTLS+ ) where++import MSGraphAPI.Internal.Common (Collection(..), run, tryReq, withTLS)
− src/MSGraphAPI/Auth.hs
@@ -1,2 +0,0 @@-module MSGraphAPI.Auth where-
src/MSGraphAPI/ChangeNotifications/Subscription.hs view
@@ -1,3 +1,8 @@+-- | Subscription to change notifications through webhooks+--+-- see <https://learn.microsoft.com/en-us/graph/webhooks#supported-resources> for a list of resources that can produce change notifications+--+-- see <https://learn.microsoft.com/en-us/graph/change-notifications-delivery-webhooks?tabs=http> for protocol details module MSGraphAPI.ChangeNotifications.Subscription where import Data.List.NonEmpty (NonEmpty)@@ -14,11 +19,31 @@ import Data.Text (Text, pack, unpack) -- time import Data.Time (LocalTime)+-- import Data.UUID.Types (UUID) import qualified MSGraphAPI.Internal.Common as MSG (Collection(..), get, post, aesonOptions) import MSGraphAPI.Files.DriveItem (DriveItem) --- | Creating a subscription requires read scope to the resource. For example, to get change notifications on messages, your app needs the Mail.Read permission.+-- | Represents the notification sent to the subscriber. https://learn.microsoft.com/en-us/graph/api/resources/changenotification?view=graph-rest-1.0+--+-- +data ChangeNotification a = ChangeNotification {+ cnChangeType :: ChangeType+ , cnClientState :: Text+ , cnId :: Text+ , cnResource :: Text+ , cnResourceData :: Maybe a+ , cnSubscriptionId :: Text+ , cnTenantId :: Text+ } deriving (Eq, Show, Generic)+instance A.FromJSON a => A.FromJSON (ChangeNotification a) where+ parseJSON = A.genericParseJSON (MSG.aesonOptions "cn")++-- | Create a subscription https://learn.microsoft.com/en-us/graph/api/subscription-post-subscriptions?view=graph-rest-1.0&tabs=http+--+-- @ POST https:\/\/graph.microsoft.com\/v1.0\/subscriptions@+--+-- Creating a subscription requires read scope to the resource. For example, to get change notifications on messages, your app needs the @Mail.Read@ permission. createSubscription :: (A.FromJSON b) => Subscription -> AccessToken -> Req b createSubscription = MSG.post ["subscriptions"] mempty @@ -31,7 +56,7 @@ , cnsClientState :: Text , cnsExpirationDateTime :: LocalTime , cnsNotificationUrl :: Text -- ^ The URL of the endpoint that will receive the change notifications. This URL must make use of the HTTPS protocol. Any query string parameter included in the notificationUrl property will be included in the HTTP POST request when Microsoft Graph sends the change notifications.- , cnsResource :: Text -- ^ Specifies the resource that will be monitored for changes. Do not include the base URL (https://graph.microsoft.com/v1.0/)+ , cnsResource :: Text -- ^ Specifies the resource that will be monitored for changes. Do not include the base URL (@https:\/\/graph.microsoft.com\/v1.0\/@) , cnsLatestSupportedTLSVersion :: LatestTLSVer } deriving (Eq, Show, Generic) instance A.FromJSON Subscription where
src/MSGraphAPI/Files/DriveItem.hs view
@@ -1,9 +1,24 @@-module MSGraphAPI.Files.DriveItem where+module MSGraphAPI.Files.DriveItem (+ -- * list items+ listRootChildrenMe+ , listGroupItemChildren+ -- , listGroupRootChildren+ -- * download items+ , downloadFile+ , downloadFileMe+ -- * types+ , DriveItem(..)+ , DIItem(..)+ , File(..), Folder(..), Package(..)+ ) where +import Control.Applicative (Alternative(..))+import Data.Int (Int32) import GHC.Generics (Generic(..)) -- aeson-import qualified Data.Aeson as A (ToJSON(..), FromJSON(..), genericParseJSON)+import qualified Data.Aeson as A (ToJSON(..), FromJSON(..), Value, genericParseJSON, (.:), (.:?), Object, withObject, Key)+import qualified Data.Aeson.Types as A (Parser) -- bytestring import qualified Data.ByteString.Lazy as LBS (ByteString) -- hoauth@@ -13,19 +28,89 @@ -- text import Data.Text (Text, pack, unpack) -- time-import Data.Time (LocalTime)+import Data.Time (LocalTime, ZonedTime) import qualified MSGraphAPI.Internal.Common as MSG (get, getLbs, post, Collection, aesonOptions) +-- | The 'DriveItem' resource represents a file, folder, or other item stored in a drive.+--+-- All file system objects in OneDrive and SharePoint are returned as driveItem resources. +--+-- https://learn.microsoft.com/en-us/graph/api/resources/driveitem?view=graph-rest-1.0 data DriveItem = DriveItem { diId :: Text , diName :: Text- , diLastModifiedDateTime :: LocalTime- } deriving (Eq, Ord, Show, Generic)+ , diLastModifiedDateTime :: ZonedTime -- 2022-11-28T09:18:45Z+ , diItem :: DIItem+ } deriving (Show, Generic)+instance A.ToJSON DriveItem+ instance A.FromJSON DriveItem where- parseJSON = A.genericParseJSON (MSG.aesonOptions "di")+ parseJSON = A.withObject "DriveItem" $ \o -> DriveItem <$>+ o A..: "id" <*>+ o A..: "name" <*>+ o A..: "lastModifiedDateTime" <*>+ diItemP o +diItemP :: A.Object -> A.Parser DIItem+diItemP o =+ (DIIFile <$> o A..: "file") <|>+ (DIIFolder <$> o A..: "folder") <|>+ (DIIRemoteItem <$ o .: "remoteItem") <|>+ (DIIPhoto <$ o .: "photo") <|>+ (DIIVideo <$ o .: "video") <|>+ (DIIBundle <$ o .: "bundle") <|>+ (DIIPackage <$> o A..: "package") ++(.:) :: A.Object -> A.Key -> A.Parser ()+(.:) = (A..:)++-- | A sum type for the various drive item types+--+-- This is a departure from the original API but makes it convenient to pattern match on constructors+data DIItem = DIIFile File+ | DIIFolder Folder+ | DIIRemoteItem+ | DIIPhoto+ | DIIVideo+ | DIIBundle+ | DIIPackage Package+ deriving (Eq, Ord, Show, Generic)+instance A.ToJSON DIItem where+ toJSON = \case+ DIIFile f -> A.toJSON f+ DIIFolder f -> A.toJSON f+ DIIPackage f -> A.toJSON f+ e -> A.toJSON $ drop 3 (show e) -- FIXME hack++-- | The Folder resource groups folder-related data on an item into a single structure. DriveItems with a non-null folder facet are containers for other DriveItems.+--+-- https://learn.microsoft.com/en-us/graph/api/resources/folder?view=graph-rest-1.0+data Folder = Folder {+ difoChildCount :: Int32+ } deriving (Eq, Ord, Show, Generic)+instance A.FromJSON Folder where+ parseJSON = A.genericParseJSON (MSG.aesonOptions "difo")+instance A.ToJSON Folder++-- | The File resource groups file-related data items into a single structure.+--+-- https://learn.microsoft.com/en-us/graph/api/resources/file?view=graph-rest-1.0+data File = File {+ difiMimeType :: Text+ } deriving (Eq, Ord, Show, Generic)+instance A.FromJSON File where+ parseJSON = A.genericParseJSON (MSG.aesonOptions "difi")+instance A.ToJSON File++data Package = Package {+ dipType :: Text+ } deriving (Eq, Ord, Show, Generic)+instance A.FromJSON Package where+ parseJSON = A.genericParseJSON (MSG.aesonOptions "dip")+instance A.ToJSON Package+ -- | download a complete file from user's directory -- -- @GET \/me\/drive\/items\/{item-id}\/content@@@ -44,3 +129,31 @@ -> Text -- ^ file ID -> AccessToken -> Req LBS.ByteString downloadFile did itemId = MSG.getLbs ["drives", did, "items", itemId, "content"] mempty++-- | List children in the root of the current user's drive+--+-- @GET \/me\/drive\/root\/children@+--+-- https://learn.microsoft.com/en-us/graph/api/driveitem-list-children?view=graph-rest-1.0&tabs=http#list-children-in-the-root-of-the-current-users-drive+listRootChildrenMe :: AccessToken -> Req (MSG.Collection DriveItem)+listRootChildrenMe = MSG.get ["me", "drive", "root", "children"] mempty+++-- | List children of an item of a group drive+--+-- @GET \/groups\/{group-id}\/drive\/items\/{item-id}\/children@+--+-- https://learn.microsoft.com/en-us/graph/api/driveitem-list-children?view=graph-rest-1.0&tabs=http+listGroupItemChildren :: Text -- ^ group ID+ -> Text -- ^ item ID+ -> AccessToken -> Req (MSG.Collection DriveItem)+listGroupItemChildren gid iid =+ MSG.get ["groups", gid, "drive", "items", iid, "children"] mempty++-- -- | List children of the root item of a group drive+-- --+-- -- @GET \/groups\/{group-id}\/drive\/root\/children@+-- listGroupRootChildren :: Text -- ^ group ID+-- -> AccessToken -> Req (MSG.Collection DriveItem)+-- listGroupRootChildren gid =+-- MSG.get ["groups", gid, "drive", "root", "children"] mempty -- TODO DOUBLE CHECK PATH
src/MSGraphAPI/Internal/Common.hs view
@@ -4,18 +4,23 @@ -- -- https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0&preserve-view=true module MSGraphAPI.Internal.Common (+ -- * PUT+ put -- * GET- get+ , get , getLbs- -- ** catch HTTP exceptions- , getE+ -- -- ** catch HTTP exceptions+ -- , getE -- * POST , post- -- ** catch HTTP exceptions- , postE+ -- -- ** catch HTTP exceptions+ -- , postE -- * running requests+ , run , runReq , tryReq+ -- * HTTP(S) connections+ , withTLS -- * JSON : aeson helpers , Collection(..) , aesonOptions@@ -40,10 +45,12 @@ -- hoauth2 import Network.OAuth.OAuth2 (OAuth2Token(..)) import Network.OAuth.OAuth2.Internal (AccessToken(..), ExchangeToken(..), RefreshToken(..), OAuth2Error, IdToken(..))+-- http-client-tls+import Network.HTTP.Client.TLS (newTlsManager) -- modern-uri import Text.URI (URI, mkURI) -- req-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)+import Network.HTTP.Req (Req, runReq, HttpException(..), HttpConfig(..), defaultHttpConfig, req, Option, (=:), GET(..), POST(..), PUT(..), Url, Scheme(..), useHttpsURI, https, (/:), ReqBodyJson(..), NoReqBody(..), oAuth2Bearer, HttpResponse(..), jsonResponse, JsonResponse, lbsResponse, LbsResponse, bsResponse, BsResponse, responseBody) -- text import Data.Text (Text, pack, unpack) -- unliftio@@ -59,12 +66,36 @@ tryReq = try --- -- GET, POST +-- | Create a new TLS manager, which should be reused throughout the program+withTLS :: MonadIO m =>+ (HttpConfig -> m b) -- ^ user program+ -> m b+withTLS act = do+ mgr <- newTlsManager+ let+ hc = defaultHttpConfig { httpConfigAltManager = Just mgr }+ act hc +-- | Run a 'Req' computation+run :: MonadIO m =>+ HttpConfig -> Req a -> m (Either HttpException a)+run hc = runReq hc . tryReq+++-- * REST verbs++put :: (A.FromJSON b, A.ToJSON a) =>+ [Text]+ -> Option 'Https -> a -> AccessToken -> Req b+put paths params bdy tok = responseBody <$> req PUT url (ReqBodyJson bdy) jsonResponse opts+ where+ opts = auth <> params+ (url, auth) = msGraphReqConfig tok paths+ -- | @POST https:\/\/graph.microsoft.com\/v1.0\/...@ post :: (A.ToJSON a, A.FromJSON b) => [Text] -- ^ URI path segments- -> Option 'Https+ -> Option 'Https -- ^ request parameters etc. -> a -- ^ request body -> AccessToken -> Req b@@ -73,16 +104,16 @@ 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)+-- -- | 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- -> Option 'Https+ -> Option 'Https -- ^ request parameters etc. -> AccessToken -> Req a get paths params tok = responseBody <$> req GET url NoReqBody jsonResponse opts@@ -90,11 +121,11 @@ 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)+-- -- | 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\/...@ --@@ -122,9 +153,13 @@ -- | a collection of items with key @value@ data Collection a = Collection { cValue :: [a]+ , cNextLink :: Maybe Text } deriving (Eq, Show, Generic)+instance A.ToJSON a => A.ToJSON (Collection a) instance A.FromJSON a => A.FromJSON (Collection a) where- parseJSON = A.genericParseJSON (aesonOptions "c")+ parseJSON = A.withObject "Collection" $ \o -> Collection <$>+ o A..: "value" <*>+ o A..:? "@odata.nextLink" -- | drop the prefix and lowercase first character --
src/MSGraphAPI/Users/Group.hs view
@@ -1,5 +1,13 @@--- | User-module MSGraphAPI.Users.Group where+-- | Users.Group+module MSGraphAPI.Users.Group (+ -- * Teams+ getUserJoinedTeams+ , getMeJoinedTeams+ -- * Drive items+ , getGroupsDriveItems+ -- * types+ , Group(..)+ )where import GHC.Generics (Generic(..)) @@ -25,8 +33,9 @@ } deriving (Eq, Ord, Show, Generic) instance A.FromJSON Group where parseJSON = A.genericParseJSON (MSG.aesonOptions "g")+instance A.ToJSON Group --- | Get the teams in Microsoft Teams that the user is a direct member of.+-- | Get the teams in Microsoft Teams that the given user is a direct member of. -- -- @GET \/users\/{id | user-principal-name}\/joinedTeams@ --@@ -34,6 +43,14 @@ getUserJoinedTeams :: Text -- ^ User ID -> AccessToken -> Req (MSG.Collection Group) getUserJoinedTeams uid = MSG.get ["users", uid, "joinedTeams"] mempty++-- | Get the teams in Microsoft Teams that the current user is a direct member of.+--+-- @GET \/me\/joinedTeams@+--+-- https://learn.microsoft.com/en-us/graph/api/user-list-joinedteams?view=graph-rest-1.0&tabs=http+getMeJoinedTeams :: AccessToken -> Req (MSG.Collection Group)+getMeJoinedTeams = MSG.get ["me", "joinedTeams"] mempty -- | Get the 'DriveItem's in the 'Group' storage, starting from the root item --
src/MSGraphAPI/Users/User.hs view
@@ -1,4 +1,4 @@--- | User+-- | Users.User module MSGraphAPI.Users.User where import GHC.Generics (Generic(..))