Support binary (b64) JWT secrets (#772)

This commit is contained in:
Trevor Basinger
2016-12-11 09:01:03 -08:00
committed by Joe Nelson
parent 649a841ef4
commit e364cbc3ff
9 changed files with 112 additions and 41 deletions
+21
View File
@@ -0,0 +1,21 @@
module Feature.BinaryJwtSecretSpec where
-- {{{ Imports
import Test.Hspec
import Test.Hspec.Wai
import Network.HTTP.Types
import SpecHelper
import Network.Wai (Application)
import Protolude hiding (get)
-- }}}
spec :: SpecWith Application
spec = describe "server started with binary JWT secret" $
-- this test will stop working 9999999999s after the UNIX EPOCH
it "succeeds with jwt token encoded with a binary secret" $ do
let auth = authHeaderJWT "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjk5OTk5OTk5OTksInJvbGUiOiJwb3N0Z3Jlc3RfdGVzdF9hdXRob3IiLCJpZCI6Impkb2UifQ.l_EcSRWeNtL4OKUTIplrHyioNrff9Rd0MV7RXNCxCyk"
request methodGet "/authors_only" [auth] ""
`shouldRespondWith` 200
+11 -5
View File
@@ -13,6 +13,7 @@ import Data.IORef
import Data.Time.Clock.POSIX (getPOSIXTime)
import qualified Feature.AuthSpec
import qualified Feature.BinaryJwtSecretSpec
import qualified Feature.ConcurrentSpec
import qualified Feature.CorsSpec
import qualified Feature.DeleteSpec
@@ -39,11 +40,12 @@ main = do
result <- P.use pool $ getDbStructure "test"
refDbStructure <- newIORef $ either (panic.show) id result
let withApp = return $ postgrest (testCfg testDbConn) refDbStructure pool getTime
ltdApp = return $ postgrest (testLtdRowsCfg testDbConn) refDbStructure pool getTime
unicodeApp = return $ postgrest (testUnicodeCfg testDbConn) refDbStructure pool getTime
proxyApp = return $ postgrest (testProxyCfg testDbConn) refDbStructure pool getTime
noJwtApp = return $ postgrest (testCfgNoJWT testDbConn) refDbStructure pool getTime
let withApp = return $ postgrest (testCfg testDbConn) refDbStructure pool getTime
ltdApp = return $ postgrest (testLtdRowsCfg testDbConn) refDbStructure pool getTime
unicodeApp = return $ postgrest (testUnicodeCfg testDbConn) refDbStructure pool getTime
proxyApp = return $ postgrest (testProxyCfg testDbConn) refDbStructure pool getTime
noJwtApp = return $ postgrest (testCfgNoJWT testDbConn) refDbStructure pool getTime
binaryJwtApp = return $ postgrest (testCfgBinaryJWT testDbConn) refDbStructure pool getTime
let reset = resetDb testDbConn
hspec $ do
@@ -65,6 +67,10 @@ main = do
beforeAll_ reset . before noJwtApp $
describe "Feature.NoJwtSpec" Feature.NoJwtSpec.spec
-- this test runs with a binary JWT secret
beforeAll_ reset . before binaryJwtApp $
describe "Feature.BinaryJwtSecretSpec" Feature.BinaryJwtSecretSpec.spec
where
specs = map (uncurry describe) [
("Feature.AuthSpec" , Feature.AuthSpec.spec)
+22 -12
View File
@@ -5,7 +5,7 @@ import Control.Monad (void)
import qualified System.IO.Error as E
import System.Environment (getEnv)
import Codec.Binary.Base64.String (encode)
import qualified Data.ByteString.Base64 as B64 (encode, decodeLenient)
import Data.CaseInsensitive (CI(..))
import Data.List (lookup)
import Text.Regex.TDFA ((=~))
@@ -54,25 +54,35 @@ getEnvVarWithDefault var def = do
varValue <- getEnv (toS var) `E.catchIOError` const (return $ toS def)
return $ toS varValue
_baseCfg :: AppConfig
_baseCfg = -- Connection Settings
AppConfig mempty "postgrest_test_anonymous" Nothing "test" "localhost" 3000
-- Jwt settings
(Just $ encodeUtf8 "safe") False
-- Connection Modifiers
10 Nothing (Just "test.switch_role")
-- Debug Settings
True
testCfg :: Text -> AppConfig
testCfg testDbConn =
AppConfig testDbConn "postgrest_test_anonymous" Nothing "test" "localhost" 3000 (Just "safe") 10 Nothing (Just "test.switch_role") True
testCfg testDbConn = _baseCfg { configDatabase = testDbConn }
testCfgNoJWT :: Text -> AppConfig
testCfgNoJWT testDbConn =
AppConfig testDbConn "postgrest_test_anonymous" Nothing "test" "localhost" 3000 Nothing 10 Nothing Nothing True
testCfgNoJWT testDbConn = (testCfg testDbConn) { configJwtSecret = Nothing }
testUnicodeCfg :: Text -> AppConfig
testUnicodeCfg testDbConn =
AppConfig testDbConn "postgrest_test_anonymous" Nothing "تست" "localhost" 3000 (Just "safe") 10 Nothing Nothing True
testUnicodeCfg testDbConn = (testCfg testDbConn) { configSchema = "تست" }
testLtdRowsCfg :: Text -> AppConfig
testLtdRowsCfg testDbConn =
AppConfig testDbConn "postgrest_test_anonymous" Nothing "test" "localhost" 3000 (Just "safe") 10 (Just 2) Nothing True
testLtdRowsCfg testDbConn = (testCfg testDbConn) { configMaxRows = Just 2 }
testProxyCfg :: Text -> AppConfig
testProxyCfg testDbConn =
AppConfig testDbConn "postgrest_test_anonymous" (Just "https://postgrest.com/openapi.json") "test" "localhost" 3000 (Just "safe") 10 Nothing Nothing True
testProxyCfg testDbConn = (testCfg testDbConn) { configProxyUri = Just "https://postgrest.com/openapi.json" }
testCfgBinaryJWT :: Text -> AppConfig
testCfgBinaryJWT testDbConn = (testCfg testDbConn) { configJwtSecret = Just secretBs }
where secretBs = B64.decodeLenient "h2CGB1FoBd51aQooCS2g+UmRgYQfTPQ6v3+9ALbaqM4="
resetDb :: Text -> IO ()
resetDb dbConn = loadFixture dbConn "data"
@@ -99,7 +109,7 @@ matchHeader name valRegex headers =
authHeaderBasic :: BS.ByteString -> BS.ByteString -> Header
authHeaderBasic u p =
(hAuthorization, "Basic " <> (toS . encode . toS $ u <> ":" <> p))
(hAuthorization, "Basic " <> (toS . B64.encode . toS $ u <> ":" <> p))
authHeaderJWT :: BS.ByteString -> Header
authHeaderJWT token =