Merge remote-tracking branch 'begriffs/v3' into v3
This commit is contained in:
@@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
### Removed
|
### Removed
|
||||||
- API versioning feature - @calebmer
|
- API versioning feature - @calebmer
|
||||||
- `--db-x` command line arguments - @calebmer
|
- `--db-x` command line arguments - @calebmer
|
||||||
|
- Remove secure flag - @calebmer
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Tolerate a missing role in user creation - @calebmer
|
- Tolerate a missing role in user creation - @calebmer
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ data AppConfig = AppConfig {
|
|||||||
, configPort :: Int
|
, configPort :: Int
|
||||||
, configAnonRole :: String
|
, configAnonRole :: String
|
||||||
, configSchema :: String
|
, configSchema :: String
|
||||||
, configSecure :: Bool
|
|
||||||
, configJwtSecret :: String
|
, configJwtSecret :: String
|
||||||
, configPool :: Int
|
, configPool :: Int
|
||||||
}
|
}
|
||||||
@@ -49,8 +48,7 @@ argParser = AppConfig
|
|||||||
|
|
||||||
<*> option auto (long "port" <> short 'p' <> help "port number on which to run HTTP server" <> metavar "PORT" <> value 3000 <> showDefault)
|
<*> option auto (long "port" <> short 'p' <> help "port number on which to run HTTP server" <> metavar "PORT" <> value 3000 <> showDefault)
|
||||||
<*> strOption (long "anonymous" <> short 'a' <> help "postgres role to use for non-authenticated requests" <> metavar "ROLE")
|
<*> strOption (long "anonymous" <> short 'a' <> help "postgres role to use for non-authenticated requests" <> metavar "ROLE")
|
||||||
<*> strOption (long "schema" <> short 'S' <> help "schema to use for API routes" <> metavar "NAME" <> value "1" <> showDefault)
|
<*> strOption (long "schema" <> short 's' <> help "schema to use for API routes" <> metavar "NAME" <> value "1" <> showDefault)
|
||||||
<*> switch (long "secure" <> short 's' <> help "redirect all requests to HTTPS")
|
|
||||||
<*> strOption (long "jwt-secret" <> short 'j' <> help "secret used to encrypt and decrypt JWT tokens" <> metavar "SECRET" <> value "secret" <> showDefault)
|
<*> strOption (long "jwt-secret" <> short 'j' <> help "secret used to encrypt and decrypt JWT tokens" <> metavar "SECRET" <> value "secret" <> showDefault)
|
||||||
<*> option auto (long "pool" <> short 'o' <> help "max connections in database pool" <> metavar "COUNT" <> value 10 <> showDefault)
|
<*> option auto (long "pool" <> short 'o' <> help "max connections in database pool" <> metavar "COUNT" <> value 10 <> showDefault)
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ main = do
|
|||||||
conf <- readOptions
|
conf <- readOptions
|
||||||
let port = configPort conf
|
let port = configPort conf
|
||||||
|
|
||||||
unless (configSecure conf) $
|
|
||||||
putStrLn "WARNING, running in insecure mode, auth will be in plaintext"
|
|
||||||
unless ("secret" /= configJwtSecret conf) $
|
unless ("secret" /= configJwtSecret conf) $
|
||||||
putStrLn "WARNING, running in insecure mode, JWT secret is the default value"
|
putStrLn "WARNING, running in insecure mode, JWT secret is the default value"
|
||||||
Prelude.putStrLn $ "Listening on port " ++
|
Prelude.putStrLn $ "Listening on port " ++
|
||||||
@@ -57,7 +55,7 @@ main = do
|
|||||||
appSettings = setPort port
|
appSettings = setPort port
|
||||||
. setServerName (cs $ "postgrest/" <> prettyVersion)
|
. setServerName (cs $ "postgrest/" <> prettyVersion)
|
||||||
$ defaultSettings
|
$ defaultSettings
|
||||||
middle = logStdout . defaultMiddle (configSecure conf)
|
middle = logStdout . defaultMiddle
|
||||||
|
|
||||||
poolSettings <- maybe (fail "Improper session settings") return $
|
poolSettings <- maybe (fail "Improper session settings") return $
|
||||||
H.poolSettings (fromIntegral $ configPool conf) 30
|
H.poolSettings (fromIntegral $ configPool conf) 30
|
||||||
|
|||||||
@@ -54,8 +54,6 @@ main = do
|
|||||||
conf <- readOptions
|
conf <- readOptions
|
||||||
let port = configPort conf
|
let port = configPort conf
|
||||||
|
|
||||||
unless (configSecure conf) $
|
|
||||||
putStrLn "WARNING, running in insecure mode, auth will be in plaintext"
|
|
||||||
unless ("secret" /= configJwtSecret conf) $
|
unless ("secret" /= configJwtSecret conf) $
|
||||||
putStrLn "WARNING, running in insecure mode, JWT secret is the default value"
|
putStrLn "WARNING, running in insecure mode, JWT secret is the default value"
|
||||||
Prelude.putStrLn $ "Listening on port " ++
|
Prelude.putStrLn $ "Listening on port " ++
|
||||||
@@ -65,7 +63,7 @@ main = do
|
|||||||
appSettings = setPort port
|
appSettings = setPort port
|
||||||
. setServerName (cs $ "postgrest/" <> prettyVersion)
|
. setServerName (cs $ "postgrest/" <> prettyVersion)
|
||||||
$ defaultSettings
|
$ defaultSettings
|
||||||
middle = logStdout . defaultMiddle (configSecure conf)
|
middle = logStdout . defaultMiddle
|
||||||
|
|
||||||
poolSettings <- maybe (fail "Improper session settings") return $
|
poolSettings <- maybe (fail "Improper session settings") return $
|
||||||
H.poolSettings (fromIntegral $ configPool conf) 30
|
H.poolSettings (fromIntegral $ configPool conf) 30
|
||||||
|
|||||||
@@ -4,20 +4,15 @@
|
|||||||
module PostgREST.Middleware where
|
module PostgREST.Middleware where
|
||||||
|
|
||||||
import Data.Maybe (fromMaybe, isNothing)
|
import Data.Maybe (fromMaybe, isNothing)
|
||||||
import Data.Monoid
|
|
||||||
import Data.Text
|
import Data.Text
|
||||||
import Data.String.Conversions (cs)
|
import Data.String.Conversions (cs)
|
||||||
import qualified Hasql as H
|
import qualified Hasql as H
|
||||||
import qualified Hasql.Postgres as P
|
import qualified Hasql.Postgres as P
|
||||||
|
|
||||||
import Network.HTTP.Types.Header (hAccept, hAuthorization,
|
import Network.HTTP.Types.Header (hAccept, hAuthorization)
|
||||||
hLocation)
|
import Network.HTTP.Types.Status (status415)
|
||||||
import Network.HTTP.Types.Status (status301, status400, status415)
|
import Network.Wai (Application, Request (..), Response,
|
||||||
import Network.URI (URI (..), parseURI)
|
requestHeaders, responseLBS)
|
||||||
import Network.Wai (Application, Request (..),
|
|
||||||
Response, isSecure, rawPathInfo,
|
|
||||||
rawQueryString, requestHeaders,
|
|
||||||
responseLBS)
|
|
||||||
import Network.Wai.Middleware.Cors (cors)
|
import Network.Wai.Middleware.Cors (cors)
|
||||||
import Network.Wai.Middleware.Gzip (def, gzip)
|
import Network.Wai.Middleware.Gzip (def, gzip)
|
||||||
import Network.Wai.Middleware.Static (only, staticPolicy)
|
import Network.Wai.Middleware.Static (only, staticPolicy)
|
||||||
@@ -54,27 +49,6 @@ runWithClaims conf app req = do
|
|||||||
else setRole anon : jwtEnv
|
else setRole anon : jwtEnv
|
||||||
jwtEnv = claimsToSQL claims
|
jwtEnv = claimsToSQL claims
|
||||||
|
|
||||||
redirectInsecure :: Application -> Application
|
|
||||||
redirectInsecure app req respond = do
|
|
||||||
let hdrs = requestHeaders req
|
|
||||||
host = lookup "host" hdrs
|
|
||||||
uriM = parseURI . cs =<< mconcat [
|
|
||||||
Just "https://",
|
|
||||||
host,
|
|
||||||
Just $ rawPathInfo req,
|
|
||||||
Just $ rawQueryString req]
|
|
||||||
isHerokuSecure = lookup "x-forwarded-proto" hdrs == Just "https"
|
|
||||||
|
|
||||||
if not (isSecure req || isHerokuSecure)
|
|
||||||
then case uriM of
|
|
||||||
Just uri ->
|
|
||||||
respond $ responseLBS status301 [
|
|
||||||
(hLocation, cs . show $ uri { uriScheme = "https:" })
|
|
||||||
] ""
|
|
||||||
Nothing ->
|
|
||||||
respond $ responseLBS status400 [] "SSL is required"
|
|
||||||
else app req respond
|
|
||||||
|
|
||||||
unsupportedAccept :: Application -> Application
|
unsupportedAccept :: Application -> Application
|
||||||
unsupportedAccept app req respond = do
|
unsupportedAccept app req respond = do
|
||||||
let
|
let
|
||||||
@@ -83,8 +57,9 @@ unsupportedAccept app req respond = do
|
|||||||
then respond $ responseLBS status415 [] "Unsupported Accept header, try: application/json"
|
then respond $ responseLBS status415 [] "Unsupported Accept header, try: application/json"
|
||||||
else app req respond
|
else app req respond
|
||||||
|
|
||||||
defaultMiddle :: Bool -> Application -> Application
|
defaultMiddle :: Application -> Application
|
||||||
defaultMiddle secure = (if secure then redirectInsecure else id)
|
defaultMiddle =
|
||||||
. gzip def . cors corsPolicy
|
gzip def
|
||||||
|
. cors corsPolicy
|
||||||
. staticPolicy (only [("favicon.ico", "static/favicon.ico")])
|
. staticPolicy (only [("favicon.ico", "static/favicon.ico")])
|
||||||
. unsupportedAccept
|
. unsupportedAccept
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ doesProcReturnJWT = doesProc [H.stmt|
|
|||||||
ON pronamespace = n.oid
|
ON pronamespace = n.oid
|
||||||
WHERE nspname = ?
|
WHERE nspname = ?
|
||||||
AND proname = ?
|
AND proname = ?
|
||||||
AND pg_catalog.pg_get_function_result(p.oid) = 'jwt_claims'
|
AND pg_catalog.pg_get_function_result(p.oid) like '%jwt_claims'
|
||||||
|]
|
|]
|
||||||
|
|
||||||
tableFromRow :: (Text, Text, Bool) -> Table
|
tableFromRow :: (Text, Text, Bool) -> Table
|
||||||
|
|||||||
+2
-2
@@ -41,7 +41,7 @@ isLeft (Left _ ) = True
|
|||||||
isLeft _ = False
|
isLeft _ = False
|
||||||
|
|
||||||
cfg :: AppConfig
|
cfg :: AppConfig
|
||||||
cfg = AppConfig dbString 3000 "postgrest_anonymous" "test" False "safe" 10
|
cfg = AppConfig dbString 3000 "postgrest_anonymous" "test" "safe" 10
|
||||||
|
|
||||||
testPoolOpts :: PoolSettings
|
testPoolOpts :: PoolSettings
|
||||||
testPoolOpts = fromMaybe (error "bad settings") $ H.poolSettings 1 30
|
testPoolOpts = fromMaybe (error "bad settings") $ H.poolSettings 1 30
|
||||||
@@ -76,7 +76,7 @@ withApp perform = do
|
|||||||
$ runWithClaims cfg (app dbstructure cfg body) req
|
$ runWithClaims cfg (app dbstructure cfg body) req
|
||||||
either (resp . errResponse) resp result
|
either (resp . errResponse) resp result
|
||||||
|
|
||||||
where middle = defaultMiddle False
|
where middle = defaultMiddle
|
||||||
|
|
||||||
|
|
||||||
resetDb :: IO ()
|
resetDb :: IO ()
|
||||||
|
|||||||
Reference in New Issue
Block a user