Hello community,

here is the log from the commit of package ghc-gogol for openSUSE:Factory 
checked in at 2017-08-31 20:51:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-gogol (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-gogol.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-gogol"

Thu Aug 31 20:51:23 2017 rev:2 rq:513260 version:0.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-gogol/ghc-gogol.changes      2017-05-10 
20:42:02.730573318 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-gogol.new/ghc-gogol.changes 2017-08-31 
20:51:24.442031855 +0200
@@ -1,0 +2,5 @@
+Thu Jul 27 14:07:30 UTC 2017 - [email protected]
+
+- Update to version 0.3.0.
+
+-------------------------------------------------------------------

Old:
----
  gogol-0.1.1.tar.gz

New:
----
  gogol-0.3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-gogol.spec ++++++
--- /var/tmp/diff_new_pack.Y14c9g/_old  2017-08-31 20:51:25.485885328 +0200
+++ /var/tmp/diff_new_pack.Y14c9g/_new  2017-08-31 20:51:25.497883644 +0200
@@ -18,7 +18,7 @@
 
 %global pkg_name gogol
 Name:           ghc-%{pkg_name}
-Version:        0.1.1
+Version:        0.3.0
 Release:        0
 Summary:        Comprehensive Google Services SDK
 License:        MPL-2.0

++++++ gogol-0.1.1.tar.gz -> gogol-0.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gogol-0.1.1/CHANGELOG.md new/gogol-0.3.0/CHANGELOG.md
--- old/gogol-0.1.1/CHANGELOG.md        2016-11-03 14:21:01.000000000 +0100
+++ new/gogol-0.3.0/CHANGELOG.md        2017-07-12 16:45:05.000000000 +0200
@@ -1,5 +1,41 @@
 # Change Log
 
+## [0.3.0](https://github.com/brendanhay/gogol/tree/0.3.0)
+
+Released: **12 July, 2017**, Compare: 
[0.3.0](https://github.com/brendanhay/gogol/compare/0.2.0...0.3.0)
+
+### Added
+
+- Addition of offline mode and save + refresh for credentials. 
[\#66](https://github.com/brendanhay/gogol/pull/66)
+
+### Fixed
+
+- Corrected `Duration` type serialisation. 
[\#68](https://github.com/brendanhay/gogol/pull/68)
+
+
+## [0.2.0](https://github.com/brendanhay/gogol/tree/0.2.0)
+
+Released: **12 February, 2017**, Compare: 
[0.1.1](https://github.com/brendanhay/gogol/compare/0.1.1...0.2.0)
+
+### Fixed
+
+- Removal of 'smart'-deserialisation of Base64-encoded byte streams. 
[\#47](https://github.com/brendanhay/gogol/issues/47) 
[\#58](https://github.com/brendanhay/gogol/pull/58)
+- Various fixes for Installed Application AuthN/AuthZ example. 
[\#39](https://github.com/brendanhay/gogol/pull/39)
+- Various fixes for token-based refresh requests. 
[\#37](https://github.com/brendanhay/gogol/pull/37) 
[\#53](https://github.com/brendanhay/gogol/pull/53) 
[\#55](https://github.com/brendanhay/gogol/pull/55) 
[\#57](https://github.com/brendanhay/gogol/pull/57)
+- CSV quote parameters in BigQuery should be optional. 
[\#52](https://github.com/brendanhay/gogol/issues/52)
+- Fixed the incocrrect construction of URL's containing mode suffixes, such as 
`:commit`. [\#33](https://github.com/brendanhay/gogol/issues/33) 
[\#34](https://github.com/brendanhay/gogol/pull/34) 
[\#49](https://github.com/brendanhay/gogol/issues/49)
+
+### New Libraries
+
+- `gogol-manufacturers`: 
[Manage](https://developers.google.com/manufacturers/) your product listings 
for [Google Manufacturer 
Center](https://www.google.com/retail/manufacturer-center/).
+- `gogol-slides`: [Slides 
Overview](https://developers.google.com/slides/how-tos/overview).
+- `gogol-language`: [Natural Language 
Overview](https://cloud.google.com/natural-language/).
+
+### Updated Service Definitions
+
+- All service definitions have been updated to their latest respective 
versions.
+
+
 ## [0.1.1](https://github.com/brendanhay/gogol/tree/0.1.1)
 Released: **03 November, 2016**, Compare: 
[0.1.0](https://github.com/brendanhay/gogol/compare/0.1.0...0.1.1)
 
@@ -9,7 +45,6 @@
 - Correcting `/computeMetadta/V1` path prefix for metadata token refresh URLs. 
[\#37](https://github.com/brendanhay/gogol/pull/37)
 - Fixes for Installed Application authentication flow. 
[\#39](https://github.com/brendanhay/gogol/pull/34)
 
-
 ### Updated Service Definitions
 
 - All service definitions have been updated to their latest respective 
versions.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gogol-0.1.1/gogol.cabal new/gogol-0.3.0/gogol.cabal
--- old/gogol-0.1.1/gogol.cabal 2016-11-03 14:21:01.000000000 +0100
+++ new/gogol-0.3.0/gogol.cabal 2017-07-12 16:45:05.000000000 +0200
@@ -1,5 +1,5 @@
 name:                  gogol
-version:               0.1.1
+version:               0.3.0
 synopsis:              Comprehensive Google Services SDK.
 homepage:              https://github.com/brendanhay/gogol
 bug-reports:           https://github.com/brendanhay/gogol/issues
@@ -66,7 +66,7 @@
         , directory            >= 1.2
         , exceptions           >= 0.6
         , filepath             >= 1.2
-        , gogol-core           == 0.1.1.*
+        , gogol-core           == 0.3.0.*
         , http-client          >= 0.5 && < 1
         , http-conduit         >= 2.2 && < 3
         , http-media           >= 0.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gogol-0.1.1/src/Network/Google/Auth/ApplicationDefault.hs 
new/gogol-0.3.0/src/Network/Google/Auth/ApplicationDefault.hs
--- old/gogol-0.1.1/src/Network/Google/Auth/ApplicationDefault.hs       
2016-11-03 14:21:01.000000000 +0100
+++ new/gogol-0.3.0/src/Network/Google/Auth/ApplicationDefault.hs       
2017-07-12 16:45:05.000000000 +0200
@@ -20,20 +20,21 @@
 
 import           Control.Applicative
 import           Control.Exception.Lens          (catching, throwingM)
-import           Control.Monad                   (unless)
+import           Control.Monad                   (unless, when)
 import           Control.Monad.Catch
 import           Control.Monad.IO.Class          (MonadIO (..))
 import           Data.Aeson
 import           Data.Aeson.Types                (parseEither)
 import qualified Data.ByteString.Lazy            as LBS
+import           Data.Maybe                      (maybe)
 import qualified Data.Text                       as Text
 import           Network.Google.Compute.Metadata (isGCE)
 import           Network.Google.Internal.Auth
 
 import Network.HTTP.Conduit (Manager)
-import System.Directory     (doesFileExist, getHomeDirectory)
+import System.Directory     (doesFileExist, getHomeDirectory, 
createDirectoryIfMissing)
 import System.Environment   (lookupEnv)
-import System.FilePath      ((</>))
+import System.FilePath      ((</>), takeDirectory)
 import System.Info          (os)
 
 -- | The environment variable name which is used to specify the directory
@@ -126,6 +127,30 @@
     either (throwM . InvalidFileError f . Text.pack) pure
            (fromJSONCredentials bs)
 
+-- | Save 'AuthorizedUser'
+-- /See:/ 'cloudSDKConfigPath', 'defaultCredentialsPath'.
+saveAuthorizedUserToWellKnownPath :: (MonadIO m, MonadCatch m)
+                                  => Bool            -- ^ Force to save if True
+                                  -> AuthorizedUser
+                                  -> m ()
+saveAuthorizedUserToWellKnownPath b a = do
+    d <- defaultCredentialsPath
+    f <- maybe cloudSDKConfigPath pure d
+    liftIO $ createDirectoryIfMissing True $ takeDirectory f
+    saveAuthorizedUser f b a
+
+-- | Save 'AuthorizedUser'
+saveAuthorizedUser :: (MonadIO m, MonadCatch m)
+                   => FilePath
+                   -> Bool            -- ^ Force to save if True
+                   -> AuthorizedUser
+                   -> m ()
+saveAuthorizedUser f b a = do
+    p  <- liftIO (doesFileExist f)
+    when (p && not b) $
+        throwM (FileExistError f)
+    liftIO (LBS.writeFile f $ encode a)
+
 -- | Attempt to parse either a @service_account@ or @authorized_user@ formatted
 -- JSON value to obtain credentials.
 fromJSONCredentials :: LBS.ByteString -> Either String (Credentials s)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gogol-0.1.1/src/Network/Google/Auth/InstalledApplication.hs 
new/gogol-0.3.0/src/Network/Google/Auth/InstalledApplication.hs
--- old/gogol-0.1.1/src/Network/Google/Auth/InstalledApplication.hs     
2016-11-03 14:21:01.000000000 +0100
+++ new/gogol-0.3.0/src/Network/Google/Auth/InstalledApplication.hs     
2017-07-12 16:45:05.000000000 +0200
@@ -22,9 +22,12 @@
     ( installedApplication
 
     -- * Forming the URL
+    , AccessType (..)
     , redirectURI
     , formURL
+    , formAccessTypeURL
     , formURLWith
+    , formAccessTypeURLWith
 
     -- * Internal Exchange and Refresh
     , exchangeCode
@@ -33,6 +36,7 @@
 
 import           Control.Monad.Catch            (MonadCatch)
 import           Control.Monad.IO.Class         (MonadIO)
+import qualified Data.Text                      as Text
 import qualified Data.Text.Encoding             as Text
 import           GHC.TypeLits                   (Symbol)
 import           Network.Google.Auth.Scope      (AllowScopes (..),
@@ -77,6 +81,9 @@
 installedApplication :: OAuthClient -> OAuthCode s -> Credentials s
 installedApplication = FromClient
 
+-- /See:/ 
<https://developers.google.com/identity/protocols/OAuth2WebServer#offline>
+data AccessType = Online | Offline deriving (Show, Eq)
+
 -- | The redirection URI used in 'formURL': @urn:ietf:wg:oauth:2.0:oob@.
 redirectURI :: Text
 redirectURI = "urn:ietf:wg:oauth:2.0:oob"
@@ -88,6 +95,12 @@
 formURL :: AllowScopes (s :: [Symbol]) => OAuthClient -> proxy s -> Text
 formURL c = formURLWith c . allowScopes
 
+-- | 'formURL' for 'AccessType'
+--
+-- /See:/ 'formUrl'.
+formAccessTypeURL :: AllowScopes (s :: [Symbol]) => OAuthClient -> AccessType 
-> proxy s -> Text
+formAccessTypeURL c a = formAccessTypeURLWith c a . allowScopes
+
 -- | Form a URL using 'OAuthScope' values.
 --
 -- /See:/ 'formURL'.
@@ -98,6 +111,13 @@
     <> "&redirect_uri=" <> redirectURI
     <> "&scope="        <> Text.decodeUtf8 (queryEncodeScopes ss)
 
+-- | 'formURLWith' for 'AccessType'
+--
+-- /See:/ 'formURLWith'.
+formAccessTypeURLWith :: OAuthClient -> AccessType -> [OAuthScope] -> Text
+formAccessTypeURLWith c a ss = formURLWith c ss
+    <> "&access_type="  <> (Text.toLower . Text.pack $ show a)
+
 -- | Exchange 'OAuthClient' details and the received 'OAuthCode' for a new
 -- 'OAuthToken'.
 --
@@ -109,7 +129,7 @@
              -> Manager
              -> m (OAuthToken s)
 exchangeCode c n = refreshRequest $
-    accountsRequest
+    tokenRequest
         { Client.requestBody = textBody $
                "grant_type=authorization_code"
             <> "&client_id="     <> toQueryParam (_clientId     c)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/gogol-0.1.1/src/Network/Google/Auth/ServiceAccount.hs 
new/gogol-0.3.0/src/Network/Google/Auth/ServiceAccount.hs
--- old/gogol-0.1.1/src/Network/Google/Auth/ServiceAccount.hs   2016-11-03 
14:21:01.000000000 +0100
+++ new/gogol-0.3.0/src/Network/Google/Auth/ServiceAccount.hs   2017-07-12 
16:45:05.000000000 +0200
@@ -68,7 +68,7 @@
                     -> Manager
                     -> m (OAuthToken s)
 authorizedUserToken u r = refreshRequest $
-    accountsRequest
+    tokenRequest
         { Client.requestBody = textBody $
                "grant_type=refresh_token"
             <> "&client_id="     <> toQueryParam (_userId     u)
@@ -86,7 +86,7 @@
                     -> m (OAuthToken s)
 serviceAccountToken s p l m = do
     b <- encodeBearerJWT s p
-    let rq = accountsRequest
+    let rq = tokenRequest
            { Client.requestBody = RequestBodyBS $
                   "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer"
                <> "&assertion="
@@ -126,7 +126,7 @@
             ]
 
         payload = base64Encode
-            [ "aud"   .= accountsURL
+            [ "aud"   .= tokenURL
             , "scope" .= concatScopes (allowScopes p)
             , "iat"   .= n
             , "exp"   .= (n + seconds maxTokenLifetime)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gogol-0.1.1/src/Network/Google/Auth.hs 
new/gogol-0.3.0/src/Network/Google/Auth.hs
--- old/gogol-0.1.1/src/Network/Google/Auth.hs  2016-11-03 14:21:01.000000000 
+0100
+++ new/gogol-0.3.0/src/Network/Google/Auth.hs  2017-07-12 16:45:05.000000000 
+0200
@@ -22,6 +22,8 @@
     , getApplicationDefault
     , fromWellKnownPath
     , fromFilePath
+    , saveAuthorizedUserToWellKnownPath
+    , saveAuthorizedUser
 
     -- ** Installed Application Credentials
     , installedApplication
@@ -33,8 +35,10 @@
     -- ** Thread-safe Storage
     , Store
     , initStore
+    , retrieveAuthFromStore
 
     , Auth           (..)
+    , authToAuthorizedUser
     , exchange
     , refresh
 
@@ -81,6 +85,19 @@
 import qualified Network.HTTP.Conduit                     as Client
 import           Network.HTTP.Types                       (hAuthorization)
 
+-- | 'authToAuthorizedUser' converts 'Auth' into an 'AuthorizedUser'
+--  by returning 'Right' if there is a 'FromClient'-constructed
+--  Credentials and a refreshed token; otherwise, returning
+--  'Left' with error message.
+authToAuthorizedUser :: AllowScopes s => Auth s -> Either Text AuthorizedUser
+authToAuthorizedUser a = AuthorizedUser
+                   <$>  (_clientId <$> getClient)
+                   <*>  maybe (Left "no refresh token") Right (_tokenRefresh 
(_token a))
+                   <*>  (_clientSecret <$> getClient)
+                        where getClient = case _credentials a of
+                                            FromClient c _ -> Right c
+                                            _ -> Left "not FromClient"
+
 -- | An 'OAuthToken' that can potentially be expired, with the original
 -- credentials that can be used to perform a refresh.
 data Auth (s :: [Symbol]) = Auth
@@ -110,6 +127,12 @@
           -> m (Store s)
 initStore c l m = exchange c l m >>= fmap Store . liftIO . newMVar
 
+-- | Retrieve auth from storage
+retrieveAuthFromStore :: (MonadIO m, MonadCatch m, AllowScopes s)
+             => Store s
+             -> m (Auth s)
+retrieveAuthFromStore (Store s) = liftIO (readMVar s)
+
 -- | Concurrently read the current token, and if expired, then
 -- safely perform a single serial refresh.
 getToken :: (MonadIO m, MonadCatch m, AllowScopes s)
@@ -145,7 +168,7 @@
         FromClient   x n  -> exchangeCode        x n
         FromUser     u    -> authorizedUserToken u Nothing
 
--- | Refresh an existing 'OAuthToken' using
+-- | Refresh an existing 'OAuthToken'.
 refresh :: forall m s. (MonadIO m, MonadCatch m, AllowScopes s)
         => Auth s
         -> Logger
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gogol-0.1.1/src/Network/Google/Internal/Auth.hs 
new/gogol-0.3.0/src/Network/Google/Internal/Auth.hs
--- old/gogol-0.1.1/src/Network/Google/Internal/Auth.hs 2016-11-03 
14:21:01.000000000 +0100
+++ new/gogol-0.3.0/src/Network/Google/Internal/Auth.hs 2017-07-12 
16:45:05.000000000 +0200
@@ -129,6 +129,13 @@
     , _userSecret  :: !Secret
     } deriving (Eq, Show)
 
+instance ToJSON AuthorizedUser where
+    toJSON (AuthorizedUser i r s) =
+        object [ "client_id"     .= i
+               , "refresh_token" .= r
+               , "client_secret" .= s
+               ]
+
 instance FromJSON AuthorizedUser where
     parseJSON = withObject "authorized_user" $ \o -> AuthorizedUser
         <$> o .: "client_id"
@@ -175,12 +182,13 @@
     toQueryParam (OAuthCode c) = c
     toHeader     (OAuthCode c) = Text.encodeUtf8 c
 
--- | An error thrown when attempting to read AuthN/AuthZ information.
+-- | An error thrown when attempting to read/write AuthN/AuthZ information.
 data AuthError
     = RetrievalError    HttpException
     | MissingFileError  FilePath
     | InvalidFileError  FilePath Text
     | TokenRefreshError Status Text (Maybe Text)
+    | FileExistError    FilePath
       deriving (Show, Typeable)
 
 instance Exception AuthError
@@ -258,6 +266,22 @@
     , Client.requestHeaders =
         [ (hContentType, "application/x-www-form-urlencoded")
         ]
+    }
+
+-- | @https://www.googleapis.com/oauth2/v4/token@.
+tokenURL :: Text
+tokenURL = "https://www.googleapis.com/oauth2/v4/token";
+
+tokenRequest :: Client.Request
+tokenRequest = Client.defaultRequest
+    { Client.host           = "www.googleapis.com"
+    , Client.port           = 443
+    , Client.secure         = True
+    , Client.method         = "POST"
+    , Client.path           = "/oauth2/v4/token"
+    , Client.requestHeaders =
+        [ (hContentType, "application/x-www-form-urlencoded")
+        ]
     }
 
 refreshRequest :: (MonadIO m, MonadCatch m)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/gogol-0.1.1/src/Network/Google.hs 
new/gogol-0.3.0/src/Network/Google.hs
--- old/gogol-0.1.1/src/Network/Google.hs       2016-11-03 14:21:01.000000000 
+0100
+++ new/gogol-0.3.0/src/Network/Google.hs       2017-07-12 16:45:05.000000000 
+0200
@@ -312,7 +312,7 @@
 >         bkt = "my-storage-bucket"
 >
 >     runResourceT . runGoogle env $                                           
 >     -- (5)
->         upload (objectsInsert bkt object' & oiName ?~ key) bkt
+>         upload (objectsInsert bkt object' & oiName ?~ key) body
 
 Breaking down the above example, we have the following points of interest:
 


Reply via email to