jwt 0.4.4 → 0.5.0
raw patch · 7 files changed
+24/−84 lines, 7 filesdep +semigroupsdep +vector
Dependencies added: semigroups, vector
Files
- changelog +5/−12
- jwt.cabal +7/−4
- src/Data/Text/Additions.hs +0/−17
- src/Web/JWT.hs +12/−15
- tests/src/Data/Text/AdditionsTests.hs +0/−30
- tests/src/TestRunner.hs +0/−2
- tests/src/Web/JWTTests.hs +0/−4
changelog view
@@ -1,17 +1,10 @@-2015-01-19 0.4.4-================-- * Add the missing `other-modules` field to the .cabal file so that - all the tests are present in the source distribution. Thanks to - Richard Wallace for reporting this.--2015-01-17 0.4.3+2014-12-01 0.5.0 ================ - * Tim McLean pointed out that comparing signatures may be susceptible to- a timing attack in the way the signatures were compared (using the default- Eq instance). Both `Signature` and `Secret` now have an `Eq` instance that- uses a constant time comparison function. Thanks Tim for reporting this.+ * Rev. 17 of the JWT Draft changed the audience claim from being an+ optional String to being either an optional `StringOrURI`s or an optional list of+ `StringOrURI`s. Thanks to Aaron Levin for reporting and implementing the+ change. This change breaks backwards compatibility (in regard to 0.4.x). 2014-10-15 0.4.2 ================
jwt.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: jwt-version: 0.4.4+version: 0.5.0 synopsis: JSON Web Token (JWT) decoding and encoding license: MIT license-file: LICENSE@@ -33,7 +33,7 @@ library exposed-modules: Web.JWT- other-modules: Web.Base64, Data.Text.Additions+ other-modules: Web.Base64 build-depends: base >= 4.6 && < 4.8 , cryptohash >= 0.11 , base64-bytestring >= 1.0@@ -46,6 +46,8 @@ , data-default >= 0.5 , http-types >= 0.8 , time >= 1.1+ , vector >= 0.7.1+ , semigroups >= 0.15.4 if flag(network-uri) build-depends: network-uri >= 2.6@@ -66,8 +68,7 @@ default-language: Haskell2010 type: exitcode-stdio-1.0 main-is: TestRunner.hs- -- Make sure the tests are listed here so that they will be part of the source distribution- other-modules: Web.Base64Tests, Web.JWTTests, Data.Text.AdditionsTests+ other-modules: Web.JWTTests, Web.Base64Tests hs-source-dirs: tests/src, src build-depends: base < 5 && >= 4.4 , tasty >= 0.7@@ -87,6 +88,8 @@ , data-default , http-types , time >= 1.1+ , vector >= 0.7.1+ , semigroups >= 0.15.4 if flag(network-uri) build-depends: network-uri >= 2.6
− src/Data/Text/Additions.hs
@@ -1,17 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Data.Text.Additions (- constTimeCompare-) where--import Control.Applicative ((<$>))-import Data.Bits-import Data.Char-import Data.Function (on)-import Data.List (foldl')-import qualified Data.Text as T--constTimeCompare :: T.Text -> T.Text -> Bool-constTimeCompare l r = T.length l == T.length r && comp' l r- where- comp' a b = 0 == foldl' (.|.) 0 (uncurry (on xor ord) <$> T.zip a b)
src/Web/JWT.hs view
@@ -48,6 +48,7 @@ , header , signature -- ** JWT claims set+ , auds , intDate , stringOrURI , stringOrURIToText@@ -76,7 +77,6 @@ import qualified Data.ByteString.Lazy.Char8 as BL (fromStrict, toStrict) import qualified Data.Text as T import qualified Data.Text.Encoding as TE-import qualified Data.Text.Additions as TA import Control.Applicative import Control.Monad@@ -98,18 +98,9 @@ type JSON = T.Text -- | The secret used for calculating the message signature-newtype Secret = Secret T.Text--instance Eq Secret where- (Secret s1) == (Secret s2) = s1 `TA.constTimeCompare` s2--instance Show Secret where- show _ = "<secret>"--newtype Signature = Signature T.Text deriving (Show)+newtype Secret = Secret T.Text deriving (Eq, Show) -instance Eq Signature where- (Signature s1) == (Signature s2) = s1 `TA.constTimeCompare` s2+newtype Signature = Signature T.Text deriving (Eq, Show) -- | JSON Web Token without signature verification data UnverifiedJWT@@ -195,8 +186,8 @@ -- | The sub (subject) claim identifies the principal that is the subject of the JWT. , sub :: Maybe StringOrURI - -- | The aud (audience) claim identifies the audiences that the JWT is intended for- , aud :: Maybe StringOrURI+ -- | The aud (audience) claim identifies the audiences that the JWT is intended for according to draft 18 of the JWT spec, the aud claim is option and may be present in singular or as a list.+ , aud :: Maybe (Either StringOrURI [StringOrURI]) -- | The exp (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. Its value MUST be a number containing an IntDate value. , exp :: Maybe IntDate@@ -371,6 +362,13 @@ stringOrURIToText (S t) = t stringOrURIToText (U uri) = T.pack $ URI.uriToString id uri (""::String) +-- | Convert the `aud` claim in a `JWTClaimsSet` into a `[StringOrURI]`+auds :: JWTClaimsSet -> [StringOrURI]+auds jwt = case aud jwt of+ Nothing -> []+ Just (Left a) -> [a]+ Just (Right as) -> as+ -- ================================================================================= encodeJWT :: ToJSON a => a -> T.Text@@ -423,7 +421,6 @@ <*> o .:? "iat" <*> o .:? "jti" <*> pure (removeRegisteredClaims $ fromHashMap o))- instance FromJSON JWTHeader where
− tests/src/Data/Text/AdditionsTests.hs
@@ -1,30 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TemplateHaskell #-}-module Data.Text.AdditionsTests- (- main- , defaultTestGroup-) where--import Control.Applicative-import Data.String (fromString)-import qualified Data.Text as T-import Data.Text.Additions-import qualified Test.QuickCheck as QC-import Test.Tasty-import Test.Tasty.QuickCheck-import Test.Tasty.TH--defaultTestGroup :: TestTree-defaultTestGroup = $(testGroupGenerator)--main :: IO ()-main = defaultMain defaultTestGroup--prop_constTimeCompare :: T.Text -> T.Text -> Bool-prop_constTimeCompare a b = (a == b) == (a `constTimeCompare` b)--instance Arbitrary T.Text where- arbitrary = fromString <$> (arbitrary :: QC.Gen String)-
tests/src/TestRunner.hs view
@@ -2,7 +2,6 @@ import qualified Web.JWTTests import qualified Web.Base64Tests-import qualified Data.Text.AdditionsTests import Test.Tasty main :: IO ()@@ -12,6 +11,5 @@ tests = testGroup "JWT Tests" [ Web.JWTTests.defaultTestGroup , Web.Base64Tests.defaultTestGroup- , Data.Text.AdditionsTests.defaultTestGroup ]
tests/src/Web/JWTTests.hs view
@@ -19,8 +19,6 @@ import Data.Maybe import Data.String (fromString, IsString) import Data.Time-- import Web.JWT defaultTestGroup :: TestTree@@ -28,8 +26,6 @@ main :: IO () main = defaultMain defaultTestGroup-- case_stringOrURIString = do let str = "foo bar baz 2312j!@&^#^*!(*@"