google-oauth2-jwt 0.1.1.1 → 0.1.2.0
raw patch · 3 files changed
+35/−23 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- README.md +2/−4
- google-oauth2-jwt.cabal +1/−1
- src/Network/Google/OAuth2/JWT.hs +32/−18
README.md view
@@ -1,10 +1,8 @@-#Google-oauth-jwt+# Google-oauth-jwt [](https://travis-ci.org/MichelBoucey/google-oauth2-jwt) Google-oauth-jwt implements the creation of the signed JWT for Google Service Accounts, to make authorized calls to Google APIs from server to server. All details here: -- https://developers.google.com/identity/protocols/OAuth2ServiceAccount+- [https://developers.google.com/identity/protocols/OAuth2ServiceAccount](https://developers.google.com/identity/protocols/OAuth2ServiceAccount) Advice: be sure that the machine time is well synchronized to successfully make the access token request and get a Bearer token.--Improvements and bug reports are welcome!
google-oauth2-jwt.cabal view
@@ -1,5 +1,5 @@ name: google-oauth2-jwt-version: 0.1.1.1+version: 0.1.2.0 synopsis: Get a signed JWT for Google Service Accounts description: Please see README.md homepage: https://github.com/MichelBoucey/google-oauth2-jwt
src/Network/Google/OAuth2/JWT.hs view
@@ -6,8 +6,18 @@ -- For all details : https://developers.google.com/identity/protocols/OAuth2ServiceAccount -- -module Network.Google.OAuth2.JWT where+module Network.Google.OAuth2.JWT+ (+ Email+ , Scope+ , getSignedJWT + -- * Utils+ , fromPEMString+ , fromPEMFile++ ) where+ import Codec.Crypto.RSA.Pure import qualified Data.ByteString as B import Data.ByteString.Base64.URL (encode)@@ -27,13 +37,16 @@ type Email = T.Text --- |Get the private key obtained from+-- | Get the private key obtained from the -- the Google API Console from a PEM file. fromPEMFile :: FilePath -> IO PrivateKey fromPEMFile f = readFile f >>= fromPEMString --- |Get the private key obtained from--- the Google API Console from a PEM 'String'.+-- | Get the private key obtained from the+-- Google API Console from a PEM 'String'.+--+-- >fromPEMString "-----BEGIN PRIVATE KEY-----\nB9e ... bMdF\n-----END PRIVATE KEY-----\n"+-- > fromPEMString :: String -> IO PrivateKey fromPEMString s = fromJust . toKeyPair <$> readPrivateKey s PwNone@@ -62,26 +75,27 @@ -- ^ The email address of the user for which the -- application is requesting delegated access. -> [Scope]- -- ^The list of the permissions that the application requests.+ -- ^ The list of the permissions that the application requests. -> Maybe Int -- ^ Expiration time (maximun and default value is an hour, 3600). -> PrivateKey- -- ^ The private key obtained from the Google API Console.+ -- ^ The private key gotten from the PEM string obtained from the+ -- Google API Console. -> IO (Either String B.ByteString) -- ^ Either an error message or a signed JWT.-getSignedJWT iss msub scopes mexp privateKey = do- let expt = fromIntegral $ fromMaybe 3600 mexp- cs <- jwtClaimsSet- (maybe T.empty (\s -> "\"sub\":\"" <> s <> "\",") msub) expt- let i = jwtHeader <> "." <> cs- return $- if expt > 0 && expt <= 3600 then- case rsassa_pkcs1_v1_5_sign hashSHA256 privateKey (fromStrict i) of- Right s -> Right $ i <> "." <> encode (toStrict s)- Left _ -> Left "RSAError"- else Left "Bad expiration time"+getSignedJWT iss msub scopes met privateKey = do+ let et = fromIntegral $ fromMaybe 3600 met+ if et < 1 || et > 3600+ then return $ Left "Bad expiration time"+ else do+ cs <- jwtClaimsSet+ (maybe T.empty (\s -> "\"sub\":\"" <> s <> "\",") msub) et+ let i = toJWT "{\"alg\":\"RS256\",\"typ\":\"JWT\"}" <> "." <> cs+ return $+ case rsassa_pkcs1_v1_5_sign hashSHA256 privateKey (fromStrict i) of+ Right s -> Right $ i <> "." <> encode (toStrict s)+ Left _ -> Left "RSAError" where- jwtHeader = toJWT "{\"alg\":\"RS256\",\"typ\":\"JWT\"}" jwtClaimsSet s e = do (exp',iat') <- getUnixTime >>= \t ->