Compare commits

..
4 Commits
Author SHA1 Message Date
Joe Nelson 2c635cfde8 Optimization when auth role coincides with anon role
No need to set/reset role because it is already correct
2014-12-29 09:39:13 -08:00
Joe Nelson 24f70f5bdf Add @casalaina's awesome logo 2014-12-29 08:58:35 -08:00
Joe Nelson d7d5473664 Link to load test graph 2014-12-28 21:13:58 -08:00
Joe Nelson d7e0fb948e Tweak future features 2014-12-28 11:11:33 -08:00
6 changed files with 17 additions and 27 deletions
+5 -5
View File
@@ -1,4 +1,4 @@
## Serve a RESTful API from any Postgres database ![Logo](static/logo.png "Logo")
[![Build Status](https://circleci.com/gh/begriffs/postgrest.png?circle-token=f723c01686abf0364de1e2eaae5aff1f68bd3ff2)](https://circleci.com/gh/begriffs/postgrest/tree/master) [![Build Status](https://circleci.com/gh/begriffs/postgrest.png?circle-token=f723c01686abf0364de1e2eaae5aff1f68bd3ff2)](https://circleci.com/gh/begriffs/postgrest/tree/master)
@@ -50,7 +50,7 @@ guide](https://github.com/begriffs/postgrest/wiki/Security-and-Permissions).
If you're used to servers written in interpreted languages (or named If you're used to servers written in interpreted languages (or named
after precious gems), prepare to be pleasantly surprised by PostgREST after precious gems), prepare to be pleasantly surprised by PostgREST
performance. performance. ([see the load test](https://github.com/begriffs/postgrest/wiki/Performance-and-Scaling))
Three factors contribute to the speed. First the server is written Three factors contribute to the speed. First the server is written
in [Haskell](https://new-www.haskell.org/) using the in [Haskell](https://new-www.haskell.org/) using the
@@ -125,12 +125,12 @@ and the [guide to routing](https://github.com/begriffs/postgrest/wiki/Routing).
* Watching endpoint changes with sockets and Postgres pubsub * Watching endpoint changes with sockets and Postgres pubsub
* Specifying per-view HTTP caching * Specifying per-view HTTP caching
* Inferring good default caching policies from the Postgres stats * Inferring good default caching policies from the Postgres stats collector
* Generating mock data to test clients * Generating mock data for test clients
* Maintaining separate connection pools per role to avoid "set/reset * Maintaining separate connection pools per role to avoid "set/reset
role" performance penalty role" performance penalty
* Describe more relationships with Link headers * Describe more relationships with Link headers
* Depending on accept headers, render OPTIONS as [RAML] or a * Depending on accept headers, render OPTIONS as [RAML](http://raml.org/) or a
relational diagram relational diagram
* Add two-legged auth with OAuth 1.0a(?) * Add two-legged auth with OAuth 1.0a(?)
* ... the other [issues](https://github.com/begriffs/postgrest/issues) * ... the other [issues](https://github.com/begriffs/postgrest/issues)
+1 -1
View File
@@ -1,5 +1,5 @@
name: postgrest name: postgrest
version: 0.2.4.8 version: 0.2.4.9
synopsis: The database is your api synopsis: The database is your api
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
+2 -1
View File
@@ -49,13 +49,14 @@ main = do
. gzip def . cors corsPolicy . gzip def . cors corsPolicy
. staticPolicy (only [("favicon.ico", "static/favicon.ico")]) . staticPolicy (only [("favicon.ico", "static/favicon.ico")])
anonRole = cs $ configAnonRole conf anonRole = cs $ configAnonRole conf
currRole = cs $ configDbUser conf
H.session pgSettings sessSettings $ H.sessionUnlifter >>= \unlift -> H.session pgSettings sessSettings $ H.sessionUnlifter >>= \unlift ->
liftIO $ runSettings appSettings $ middle $ \req respond -> do liftIO $ runSettings appSettings $ middle $ \req respond -> do
body <- strictRequestBody req body <- strictRequestBody req
respond =<< catchJust isSqlError respond =<< catchJust isSqlError
(unlift $ H.tx Nothing (unlift $ H.tx Nothing
$ authenticated anonRole (app body) req) $ authenticated currRole anonRole (app body) req)
(return . sqlError) (return . sqlError)
where where
+6 -18
View File
@@ -22,30 +22,18 @@ import Network.URI (URI(..), parseURI)
import Auth (LoginAttempt(..), signInRole, setRole, resetRole) import Auth (LoginAttempt(..), signInRole, setRole, resetRole)
import Codec.Binary.Base64.String (decode) import Codec.Binary.Base64.String (decode)
-- data Environment = Test | Production deriving (Eq) authenticated :: forall s. Text -> Text ->
(Request -> H.Tx H.Postgres s Response) ->
-- safeAction :: Request -> Bool Request -> H.Tx H.Postgres s Response
-- safeAction = (`notElem` ["PATCH", "PUT"]) . requestMethod authenticated currentRole anon app req = do
-- withSavepoint :: Environment -> (Connection -> Application) ->
-- Connection -> Application
-- withSavepoint env app conn req respond =
-- if env == Production && safeAction req
-- then go
-- else Database.PostgreSQL.Simple.withSavepoint conn go
-- where go = app conn req respond
authenticated :: forall s. Text -> (Request -> H.Tx H.Postgres s Response) ->
Request -> H.Tx H.Postgres s Response
authenticated anon app req = do
attempt <- httpRequesterRole (requestHeaders req) attempt <- httpRequesterRole (requestHeaders req)
case attempt of case attempt of
MalformedAuth -> MalformedAuth ->
return $ responseLBS status400 [] "Malformed basic auth header" return $ responseLBS status400 [] "Malformed basic auth header"
LoginFailed -> LoginFailed ->
return $ responseLBS status401 [] "Invalid username or password" return $ responseLBS status401 [] "Invalid username or password"
LoginSuccess role -> runInRole role LoginSuccess role -> if role /= currentRole then runInRole role else app req
NoCredentials -> runInRole anon NoCredentials -> if anon /= currentRole then runInRole anon else app req
where where
httpRequesterRole :: RequestHeaders -> H.Tx H.Postgres s LoginAttempt httpRequesterRole :: RequestHeaders -> H.Tx H.Postgres s LoginAttempt
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+3 -2
View File
@@ -44,14 +44,15 @@ pgSettings = H.ParamSettings "localhost" 5432 "postgrest_test" "" "postgrest_tes
withApp :: ActionWith Application -> IO () withApp :: ActionWith Application -> IO ()
withApp perform = withApp perform =
let anonRole = cs $ configAnonRole cfg in let anonRole = cs $ configAnonRole cfg
currRole = cs $ configDbUser cfg in
perform $ middle $ \req resp -> perform $ middle $ \req resp ->
H.session pgSettings testSettings $ H.sessionUnlifter >>= \unlift -> H.session pgSettings testSettings $ H.sessionUnlifter >>= \unlift ->
liftIO $ do liftIO $ do
body <- strictRequestBody req body <- strictRequestBody req
resp =<< catchJust isSqlError resp =<< catchJust isSqlError
(unlift $ H.tx Nothing (unlift $ H.tx Nothing
$ authenticated anonRole (app body) req) $ authenticated currRole anonRole (app body) req)
(return . sqlError) (return . sqlError)
where middle = cors corsPolicy where middle = cors corsPolicy