packages feed

goggles 0.2 → 0.3

raw patch · 6 files changed

+57/−59 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Network.Goggles: OAuth2Token :: Int -> Text -> Maybe Text -> OAuth2Token
+ Network.Goggles: [oaTokenExpirySeconds] :: OAuth2Token -> Int
+ Network.Goggles: [oaTokenString] :: OAuth2Token -> Text
+ Network.Goggles: [oaTokenType] :: OAuth2Token -> Maybe Text
+ Network.Goggles: accessToken :: (HasToken c) => WebApiM c (TokenContent c)
+ Network.Goggles: class HasToken c where {
+ Network.Goggles: data OAuth2Token
+ Network.Goggles: getLbs :: (HasCredentials c, MonadHttp (WebApiM c)) => Url scheme -> Option scheme -> WebApiM c LbsResponse
+ Network.Goggles: putLbs :: (HasCredentials c, MonadHttp (WebApiM c)) => Url scheme -> Option scheme -> ByteString -> WebApiM c LbsResponse
+ Network.Goggles: refreshToken :: HasToken c => WebApiM c (Token c)
+ Network.Goggles: urlEncode :: String -> String
+ Network.Goggles.Auth: OAuth2Token :: Int -> Text -> Maybe Text -> OAuth2Token
+ Network.Goggles.Auth: OAuth2TokenUTC :: UTCTime -> Text -> Maybe Text -> OAuth2TokenUTC
+ Network.Goggles.Auth: [oaTokenExpirySeconds] :: OAuth2Token -> Int
+ Network.Goggles.Auth: [oaTokenString] :: OAuth2Token -> Text
+ Network.Goggles.Auth: [oaTokenType] :: OAuth2Token -> Maybe Text
+ Network.Goggles.Auth: [oauTokenExpiry] :: OAuth2TokenUTC -> UTCTime
+ Network.Goggles.Auth: [oauTokenString] :: OAuth2TokenUTC -> Text
+ Network.Goggles.Auth: [oauTokenType] :: OAuth2TokenUTC -> Maybe Text
+ Network.Goggles.Auth: data OAuth2Token
+ Network.Goggles.Auth: data OAuth2TokenUTC
+ Network.Goggles.Auth: mkOAuth2TokenUTC :: (MonadIO m, Integral t) => t -> OAuth2Token -> m OAuth2TokenUTC
+ Network.Goggles.Auth: requestOAuth2Token :: (MonadHttp m, MonadThrow m) => Url scheme -> [(Text, Text)] -> Option scheme -> m OAuth2Token
- Network.Goggles: liftWebApiIO :: HasCredentials c => IO a -> WebApiM c a
+ Network.Goggles: liftWebApiIO :: IO a -> WebApiM c a
- Network.Goggles: tokenFetch :: HasCredentials c => WebApiM c (Token c)
+ Network.Goggles: tokenFetch :: HasToken c => WebApiM c (Token c)
- Network.Goggles: type family TokenContent c;
+ Network.Goggles: type family Options c;

Files

CHANGELOG.md view
@@ -1,3 +1,6 @@+	0.3+	* Split HasCredentials into HasCredentials, HasToken+ 	0.2 	* Rename Cloud to WebApiM 	* Stackage LTS 10.5 (ghc 8.2.2)
goggles.cabal view
@@ -1,7 +1,7 @@ name:                goggles-version:             0.2-synopsis:            Interface to Google Cloud APIs-description:         High-level, extensible interface to Google Cloud APIs. +version:             0.3+synopsis:            Extensible interface to Web APIs+description:         `goggles` helps with exchanging data with APIs that require authentication. In particular, it handles the details of expiring session tokens, so the user does not have to implement this logic in her program. homepage:            https://github.com/ocramz/goggles license:             BSD3 license-file:        LICENSE@@ -23,12 +23,12 @@                        Network.Goggles.Auth   other-modules:       Data.Keys                        Network.Goggles.Cloud-                       Network.Utils.HTTP                        Network.Goggles.Types+                       Network.Goggles.Control.Exceptions+                       Network.Utils.HTTP                                                  -- Network.Goggles.Auth.JWT                        Network.Goggles.Auth.OAuth2                        -- Network.Goggles.Auth.TokenExchange-                       Network.Goggles.Control.Exceptions   build-depends:       base >= 4.7 && < 5                      , binary                      , scientific
src/Network/Goggles.hs view
@@ -1,66 +1,42 @@ {-|-== /Dependencies/ -The examples require the following declarations (which in turn mean that the @req@ and @bytestring@ libraries are imported by the user's project). You will also need the @OverloadedStrings@ language extension :--> import qualified Data.ByteString.Lazy as LB-> import Network.HTTP.Req (responseBody)-> import Network.Goggles--== /Examples/--This first example, @listBucket@, reads content from a cloud storage bucket:--1. it loads the GCP credentials (username and RSA key),-2. retrieves a token via OAuth2,-3. performs a single call to the Cloud Storage API endpoint that lists the metadata related to the contents of a storage bucket, and-4. returns the raw API data to the user as a lazy ByteString.--> listBucket :: IO LB.ByteString-> listBucket = do->   let usr = "...iam.gserviceaccount.com"->       bucket = "<my-gcs-bucket>"->       key = "<rsa_key>"->   pvtkey <- parseRSAPrivateKey key->   let creds = GCPServiceAccount pvtkey usr Nothing ""->   hdl <- createHandle creds scopesDefault->   responseBody <$> evalWebApiIO hdl (listObjects bucket)-- -} module Network.Goggles (   -- ** Running WebApiM programs     createHandle       , evalWebApiIO-  -- *** "Lifting" IO programs into 'WebApiM'+  -- *** Lifting IO programs into 'WebApiM'   , liftWebApiIO   -- * Types-  -- , GCP-  -- , GCPServiceAccount(..)-  -- , GCPTokenOptions(..)   , WebApiM(..)   -- ** Authentication   , HasCredentials(..)+  , HasToken(..)   , Token(..)-  -- , accessToken-  -- , refreshToken+  , accessToken+  , refreshToken   , Handle(..)   -- * Private key    , parseRSAPrivateKey+  -- * OAuth2 related+  , OAuth2Token(..)   -- * Exceptions   , KeyException(..)   , JWTError(..)   , TokenExchangeException(..)-  , CloudException(..)  +  , CloudException(..)+  -- * Utilities+  , putLbs, getLbs, urlEncode   ) where   import Network.Goggles.Control.Exceptions  import Network.Goggles.Cloud-import Network.Goggles.Types--- import Network.Goggles.Auth.TokenExchange+import Network.Goggles.Auth+-- import Network.Goggles.Types+import Network.Utils.HTTP import Data.Keys --- import System.Environment (lookupEnv)+   
src/Network/Goggles/Auth.hs view
@@ -1,6 +1,13 @@ {-# language OverloadedStrings, GeneralizedNewtypeDeriving, MultiParamTypeClasses #-} {-# language RankNTypes #-}-module Network.Goggles.Auth where+module Network.Goggles.Auth+  (+    requestOAuth2Token+  , OAuth2Token(..)+  , OAuth2TokenUTC(..)+  , mkOAuth2TokenUTC+                                )+where  import Network.Goggles.Auth.OAuth2--- import Network.Goggles.Auth.JWT+
src/Network/Goggles/Cloud.hs view
@@ -1,11 +1,22 @@ {-# language OverloadedStrings, TypeFamilies, GeneralizedNewtypeDeriving #-} {-# language FlexibleContexts, MultiParamTypeClasses, DeriveDataTypeable #-} {-# language UndecidableInstances #-}++{-|+Module      : Network.Goggles.Cloud+Description : WebApiM and related functionality+Copyright   : (c) Marco Zocca, 2018+License     : GPL-3+Maintainer  : zocca.marco gmail+Stability   : experimental+Portability : POSIX+-} module Network.Goggles.Cloud (     WebApiM(..)   , evalWebApiIO   , liftWebApiIO   , HasCredentials(..)+  , HasToken(..)   , Token(..)   , accessToken   , refreshToken@@ -27,11 +38,12 @@ import Network.Goggles.Control.Exceptions  --- | This class  class HasCredentials c where   type Credentials c-  type Options c-  type TokenContent c ++class HasToken c where+  type TokenContent c+  type Options c     tokenFetch :: WebApiM c (Token c)  -- | An authentication 'Token' with an expiry date@@ -86,8 +98,8 @@ liftWebApiIO_ m = WebApiM $ ReaderT (const m)  -- | Lift an `IO a` action into the 'WebApiM' monad, and catch synchronous exceptions, while rethrowing the asynchronous ones to IO-liftWebApiIO :: HasCredentials c => IO a -> WebApiM c a-liftWebApiIO m = do+liftWebApiIO :: IO a -> WebApiM c a+liftWebApiIO m =    liftWebApiIO_ m `catch` \e -> case fromException e of      Just asy -> throwM (asy :: AsyncException)     Nothing -> throwM $ IOError (show e)@@ -107,13 +119,13 @@   -instance HasCredentials c => MonadIO (WebApiM c) where+instance MonadIO (WebApiM c) where   liftIO = liftWebApiIO -instance HasCredentials c => MonadThrow (WebApiM c) where+instance MonadThrow (WebApiM c) where   throwM = liftIO . throwM -instance HasCredentials c => MonadCatch (WebApiM c) where+instance MonadCatch (WebApiM c) where   catch (WebApiM (ReaderT m)) c =     WebApiM $ ReaderT $ \r -> m r `catch` \e -> runReaderT (runWebApiM $ c e) r   @@ -123,10 +135,10 @@   handleHttpException = throwM -} -instance HasCredentials c => MonadRandom (WebApiM c) where+instance MonadRandom (WebApiM c) where   getRandomBytes = liftIO . getEntropy -instance HasCredentials c => MonadReader (Handle c) (WebApiM c) where+instance MonadReader (Handle c) (WebApiM c) where   ask = WebApiM RT.ask   local f m = WebApiM $ RT.local f (runWebApiM m) @@ -135,7 +147,7 @@  -- | `cacheToken tok hdl` : Overwrite the token TVar `tv` containing a token if `tok` carries a more recent timestamp. cacheToken ::-  HasCredentials c => Token c -> WebApiM c (Token c)+  HasToken c => Token c -> WebApiM c (Token c) cacheToken tok = do   tv <- asks token   liftWebApiIO $ atomically $ do@@ -146,20 +158,20 @@     writeTVar tv (Just new)     return new -refreshToken :: HasCredentials c => WebApiM c (Token c)+refreshToken :: HasToken c => WebApiM c (Token c) refreshToken = tokenFetch >>= cacheToken    -- | Extract the token content (needed to authenticate subsequent requests). The token will be valid for at least 60 seconds-accessToken :: HasCredentials c => WebApiM c (TokenContent c)+accessToken :: (HasToken c) => WebApiM c (TokenContent c) accessToken = do     tokenTVar <- asks token      mbToken <- liftWebApiIO $ atomically $ readTVar tokenTVar     tToken <$> case mbToken of         Nothing -> refreshToken          Just t -> do-            now <- liftWebApiIO $ getCurrentTime+            now <- liftWebApiIO getCurrentTime             if now > addUTCTime (- 60) (tTime t)                 then refreshToken                  else return t  
src/Network/Goggles/Types.hs view
@@ -1,5 +1,5 @@ {-# language TypeFamilies, FlexibleInstances #-} module Network.Goggles.Types where -import qualified Data.Text as T+-- import qualified Data.Text as T