on develop help sign in
Tidying up Haddock and exposing everything except helper/utilities.
d22f2fcBrendan Hay
gogol/src/Network/Google/Auth.hs+110−97
@@ -19,56 +19,75 @@
19--
19--
20-- Explicitly specify your Google credentials, or retrieve them
20-- Explicitly specify your Google credentials, or retrieve them
21-- from the underlying OS.
21-- from the underlying OS.
22−module Network.Google.Auth where
22+module Network.Google.Auth
23− -- (
23+ (
24− -- -- * Authentication
24+ -- * Credentials
25− -- -- ** Retrieving Authentication
25+ -- ** Discovery
26− -- getAuth
26+ , discover
27+ , fromFile
28+ , fromFilePath
29+ , fromJSONCredentials
30+
27− -- , Credentials (..)
31+ , Credentials (..)
28− -- , Auth
32+ , Auth (..)
29−
33+
34+ -- ** Thread-safe Storage
35+ , Store
36+ , emptyStore
37+
30− -- -- ** Authorising Requests
38+ -- ** Authorizing Requests
31− -- , authorize
39+ , authorize
32−
40+
41+ -- ** Constructing Callback URLs
42+ , formURL
43+ , redirectURI
44+ , accountsURL
45+
33− -- -- ** Default Constants
46+ -- ** Default Constants
34− -- -- *** Google Compute Engine
47+ -- *** Google Compute Engine
35− -- , checkGCEVar
48+ , checkGCEVar
36−
49+
37− -- -- *** Cloud SDK
50+ -- *** Cloud SDK
38− -- , cloudSDKConfigDir
51+ , cloudSDKConfigDir
39− -- , cloudSDKConfigPath
52+ , cloudSDKConfigPath
40−
53+
41− -- -- *** Application Default Credentials
54+ -- *** Application Default Credentials
42− -- , defaultCredentialsFile
55+ , defaultCredentialsFile
43− -- , defaultCredentialsPath
56+ , defaultCredentialsPath
44−
57+
45− -- -- ** Credential Styles
46− -- , fromMetadata
47− -- , fromFile
48− -- , fromFilePath
49−
50− -- -- *** OAuth Token
51− -- , Bearer (..)
52− -- , fromToken
53−
54− -- -- *** Authorized User
55− -- , AuthorizedUser (..)
56− -- , fromAuthorizedUser
57−
58− -- -- *** Service Account
59− -- , ServiceAccount (..)
60− -- , fromServiceAccount
61−
62− -- -- ** Handling Errors
58+ -- ** Handling Errors
63− -- , AsAuthError (..)
59+ , AsAuthError (..)
64− -- , AuthError (..)
60+ , AuthError (..)
65−
61+
62+ -- * Credential Types
63+ , ServiceAccount (..)
64+ , AuthorizedUser (..)
65+
66+ -- * OAuth Types
67+ , OAuthClient (..)
68+ , OAuthCode (..)
69+ , OAuthScope (..)
70+ , OAuthToken (..)
71+
66− -- -- ** Re-exported Types
72+ -- * Re-exported Types
67− -- , Scope (..)
68− -- , OAuthToken (..)
69− -- , ServiceId (..)
73+ , ServiceId (..)
70− -- , ClientId (..)
74+ , ClientId (..)
75+ , AccessToken (..)
76+ , RefreshToken (..)
77+ , Secret (..)
78+
79+ -- * Exchange and Refresh Internals
80+ , getToken
81+ , validateToken
82+
83+ , exchange
84+ , exchangeCode
85+
86+ , refresh
87+ , refreshMetadata
88+ , refreshToken
89+ , refreshAssertion
71− -- ) where
90+ ) where
72
91
73import Control.Applicative
92import Control.Applicative
74import Control.Concurrent
93import Control.Concurrent
@@ -213,15 +232,21 @@ getConfigDirectory = do
213 then pure h
232 then pure h
214 else pure $! h </> ".config"
233 else pure $! h </> ".config"
215
234
216−data RefreshError = RefreshError
235+-- | Given a client identifier, client secret, and a list of scopes to authorize,
217− { _error :: !Text
236+-- construct a URL that can be used to obtain the 'OAuthCode' required to
218− , _description :: !(Maybe Text)
237+-- instantiate 'FromClient'-style credentials.
219− }
238+formURL :: OAuthClient -> [OAuthScope] -> Text
239+formURL OAuthClient{..} ss =
240+ LText.toStrict . LText.decodeUtf8 . Build.toLazyByteString $
241+ buildText accountsURL
242+ <> "?response_type=code"
243+ <> "&client_id=" <> buildText _clientId
244+ <> "&redirect_uri=" <> buildText redirectURI
245+ <> "&scope=" <> queryEncodeScopes ss
220
246
221−instance FromJSON RefreshError where
247+-- | @urn:ietf:wg:oauth:2.0:oob@.
222− parseJSON = withObject "refresh_error" $ \o -> RefreshError
248+redirectURI :: Text
223− <$> o .: "error"
249+redirectURI = "urn:ietf:wg:oauth:2.0:oob"
224− <*> o .:? "error_description"
225
250
226{-| Service Account credentials which are typically generated/download
251{-| Service Account credentials which are typically generated/download
227from the Google Developer console of the following form:
252from the Google Developer console of the following form:
@@ -369,21 +394,11 @@ data Auth
369
394
370type Store = MVar Auth
395type Store = MVar Auth
371
396
397+-- | Construct storage containing the credentials which have not yet been
398+-- exchanged or refreshed.
372emptyStore :: MonadIO m => Credentials -> m Store
399emptyStore :: MonadIO m => Credentials -> m Store
373emptyStore !c = liftIO . newMVar $ Exchange c
400emptyStore !c = liftIO . newMVar $ Exchange c
374
401
375−-- FIXME: support for generating the url using scopes to obtain the OAuthCode.
376−
377−-- FIXME:
378−-- The parameter is include_granted_scopes and the allowed values are true and
379−-- false (the default is false). When the value is true, the effect is that if
380−-- your scope authorization request is granted, the Google authorization server
381−-- will roll this authorization together with all the previous authorizations
382−-- granted to the requesting user from the requesting app.
383−
384−-- FIXME: Get around to replacing the threading of Logger, Manager through
385−-- every exchange/refresh call.
386−
387-- | Attempt credentials discovery via the following steps:
402-- | Attempt credentials discovery via the following steps:
388--
403--
389-- * Read the default credentials from a file specified by
404-- * Read the default credentials from a file specified by
@@ -521,18 +536,6 @@ exchange c l m =
521 FromUser AuthorizedUser{..} ->
536 FromUser AuthorizedUser{..} ->
522 refreshToken _userId _userSecret (Just _userRefresh) l m
537 refreshToken _userId _userSecret (Just _userRefresh) l m
523
538
524−formURL :: OAuthClient -> [OAuthScope] -> Text
525−formURL OAuthClient{..} ss =
526− LText.toStrict . LText.decodeUtf8 . Build.toLazyByteString $
527− buildText accountsURL
528− <> "?response_type=code"
529− <> "&client_id=" <> buildText _clientId
530− <> "&redirect_uri=" <> buildText redirectURI
531− <> "&scope=" <> queryEncodeScopes ss
532−
533−redirectURI :: Text
534−redirectURI = "urn:ietf:wg:oauth:2.0:oob"
535−
536exchangeCode :: (MonadIO m, MonadCatch m)
539exchangeCode :: (MonadIO m, MonadCatch m)
537 => OAuthClient
540 => OAuthClient
538 -> OAuthCode
541 -> OAuthCode
@@ -646,21 +649,6 @@ encodeJWTBearer s ss = liftIO $ do
646 , "iss" .= _serviceEmail s
649 , "iss" .= _serviceEmail s
647 ]
650 ]
648
651
649−queryEncodeScopes :: [OAuthScope] -> Build.Builder
650−queryEncodeScopes =
651− mconcat
652− . intersperse "+"
653− . map (urlEncodeBuilder True . Text.encodeUtf8)
654− . coerce
655−
656−concatScopes :: [OAuthScope] -> LText.Text
657−concatScopes =
658− TBuild.toLazyText
659− . mconcat
660− . intersperse " "
661− . map TBuild.fromText
662− . coerce
663−
664accountsURL :: Text
652accountsURL :: Text
665accountsURL = "https://accounts.google.com/o/oauth2/token"
653accountsURL = "https://accounts.google.com/o/oauth2/token"
666
654
@@ -737,3 +725,28 @@ buildBody = RequestBodyLBS . Build.toLazyByteString
737
725
738buildText :: ToText a => a -> Builder
726buildText :: ToText a => a -> Builder
739buildText = build . toText
727buildText = build . toText
728+
729+queryEncodeScopes :: [OAuthScope] -> Build.Builder
730+queryEncodeScopes =
731+ mconcat
732+ . intersperse "+"
733+ . map (urlEncodeBuilder True . Text.encodeUtf8)
734+ . coerce
735+
736+concatScopes :: [OAuthScope] -> LText.Text
737+concatScopes =
738+ TBuild.toLazyText
739+ . mconcat
740+ . intersperse " "
741+ . map TBuild.fromText
742+ . coerce
743+
744+data RefreshError = RefreshError
745+ { _error :: !Text
746+ , _description :: !(Maybe Text)
747+ }
748+
749+instance FromJSON RefreshError where
750+ parseJSON = withObject "refresh_error" $ \o -> RefreshError
751+ <$> o .: "error"
752+ <*> o .:? "error_description"