fix for one of the failing tests (acl for tables added)

This commit is contained in:
Ruslan Talpa
2015-09-22 18:17:24 +03:00
parent a7b883c922
commit 6f55e1d389
6 changed files with 64 additions and 10 deletions
+11 -3
View File
@@ -50,8 +50,8 @@ import PostgREST.PgStructure
import Prelude import Prelude
app :: [Table] -> [Relation] -> [Column] -> [PrimaryKey] -> AppConfig -> BL.ByteString -> Request -> H.Tx P.Postgres s Response app :: DbStructure -> AppConfig -> BL.ByteString -> DbRole -> Request -> H.Tx P.Postgres s Response
app allTables allRelations allColumns allPrimaryKeys conf reqBody req = app dbstructure conf reqBody role req =
case (path, verb) of case (path, verb) of
-- ([], _) -> do -- ([], _) -> do
-- body <- encode <$> tables (cs schema) -- body <- encode <$> tables (cs schema)
@@ -65,7 +65,7 @@ app allTables allRelations allColumns allPrimaryKeys conf reqBody req =
-- $ encode (TableOptions cols pkey) -- $ encode (TableOptions cols pkey)
([], _) -> do ([], _) -> do
let body = encode $ filter (((cs schema)==).tableSchema) allTables let body = encode $ filter (filterTableAcl allTablesAcl role) $ filter (((cs schema)==).tableSchema) allTables
return $ responseLBS status200 [jsonH, ("Custom", "header")] $ cs body return $ responseLBS status200 [jsonH, ("Custom", "header")] $ cs body
([table], "OPTIONS") -> do ([table], "OPTIONS") -> do
@@ -257,8 +257,16 @@ app allTables allRelations allColumns allPrimaryKeys conf reqBody req =
return $ responseLBS status404 [] "" return $ responseLBS status404 [] ""
where where
allTables = tables dbstructure
allRelations = relations dbstructure
allColumns = columns dbstructure
allPrimaryKeys = primaryKeys dbstructure
allTablesAcl = tablesAcl dbstructure
filterCol schema table (Column{colSchema=s, colTable=t}) = s==schema && table==t filterCol schema table (Column{colSchema=s, colTable=t}) = s==schema && table==t
filterPk schema table (PrimaryKey{pkSchema=s, pkTable=t}) = s==schema && table==t filterPk schema table (PrimaryKey{pkSchema=s, pkTable=t}) = s==schema && table==t
filterTableAcl :: [(Text, Text, Text)] -> Text -> Table -> Bool
filterTableAcl acl r (Table{tableSchema=s, tableName=n}) = isJust $ find (\(as,an,ar)->as==s && an==n && ar==r) acl
path = pathInfo req path = pathInfo req
verb = requestMethod req verb = requestMethod req
qq = queryString req qq = queryString req
+12 -1
View File
@@ -99,10 +99,21 @@ main = do
pkRes <- H.session pool $ H.tx txParam $ allprimaryKeys pkRes <- H.session pool $ H.tx txParam $ allprimaryKeys
let allPrimaryKeys = either (fail . show) id pkRes let allPrimaryKeys = either (fail . show) id pkRes
tableAclRes <- H.session pool $ H.tx txParam $ alltablesAcl
let allTablesAcl = either (fail . show) id tableAclRes
let dbstructure = DbStructure {
tables=allTables,
columns=allColumns,
relations=allRelations,
primaryKeys=allPrimaryKeys,
tablesAcl=allTablesAcl}
runSettings appSettings $ middle $ \ req respond -> do runSettings appSettings $ middle $ \ req respond -> do
body <- strictRequestBody req body <- strictRequestBody req
resOrError <- liftIO $ H.session pool $ H.tx (Just (H.ReadCommitted, Just True)) $ resOrError <- liftIO $ H.session pool $ H.tx (Just (H.ReadCommitted, Just True)) $
authenticated conf (app allTables allRelations allColumns allPrimaryKeys conf body) req authenticated conf (app dbstructure conf body) req
either (respond . errResponse) respond resOrError either (respond . errResponse) respond resOrError
where where
+5 -4
View File
@@ -26,11 +26,12 @@ import PostgREST.Config (AppConfig(..), corsPolicy)
import PostgREST.Auth (LoginAttempt(..), signInRole, signInWithJWT, setRole, setUserId) import PostgREST.Auth (LoginAttempt(..), signInRole, signInWithJWT, setRole, setUserId)
import PostgREST.App (contentTypeForAccept) import PostgREST.App (contentTypeForAccept)
import Codec.Binary.Base64.String (decode) import Codec.Binary.Base64.String (decode)
import PostgREST.Auth (DbRole)
import Prelude import Prelude
authenticated :: forall s. AppConfig -> authenticated :: forall s. AppConfig ->
(Request -> H.Tx P.Postgres s Response) -> (DbRole -> Request -> H.Tx P.Postgres s Response) ->
Request -> H.Tx P.Postgres s Response Request -> H.Tx P.Postgres s Response
authenticated conf app req = do authenticated conf app req = do
attempt <- httpRequesterRole (requestHeaders req) attempt <- httpRequesterRole (requestHeaders req)
@@ -39,8 +40,8 @@ authenticated conf app req = do
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 uid -> if role /= currentRole then runInRole role uid else app req LoginSuccess role uid -> if role /= currentRole then runInRole role uid else app currentRole req
NoCredentials -> if anon /= currentRole then runInRole anon "" else app req NoCredentials -> if anon /= currentRole then runInRole anon "" else app currentRole req
where where
jwtSecret = cs $ configJwtSecret conf jwtSecret = cs $ configJwtSecret conf
@@ -62,7 +63,7 @@ authenticated conf app req = do
runInRole r uid = do runInRole r uid = do
setUserId uid setUserId uid
setRole r setRole r
app req app r req
redirectInsecure :: Application -> Application redirectInsecure :: Application -> Application
+14
View File
@@ -311,3 +311,17 @@ allprimaryKeys = do
AND kc.table_schema NOT IN ('pg_catalog', 'information_schema') AND kc.table_schema NOT IN ('pg_catalog', 'information_schema')
|] |]
return $ map pkFromRow pks return $ map pkFromRow pks
alltablesAcl :: H.Tx P.Postgres s [(Text, Text, Text)]
alltablesAcl = do
acl <- H.listEx $ [H.stmt|
SELECT
table_schema,
table_name,
grantee as role
FROM information_schema.role_table_grants
WHERE
table_schema NOT IN ('pg_catalog', 'information_schema') AND
privilege_type = 'SELECT'
|]
return acl
+8
View File
@@ -1,6 +1,14 @@
module PostgREST.Types where module PostgREST.Types where
import Data.Text import Data.Text
data DbStructure = DbStructure {
tables :: [Table]
, columns :: [Column]
, relations :: [Relation]
, primaryKeys :: [PrimaryKey]
, tablesAcl :: [(Text, Text, Text)]
}
data Table = Table { data Table = Table {
tableSchema :: Text tableSchema :: Text
, tableName :: Text , tableName :: Text
+13 -1
View File
@@ -31,6 +31,7 @@ import PostgREST.Config (AppConfig(..))
import PostgREST.Middleware import PostgREST.Middleware
import PostgREST.Error(errResponse) import PostgREST.Error(errResponse)
import PostgREST.PgStructure import PostgREST.PgStructure
import PostgREST.Types
isLeft :: Either a b -> Bool isLeft :: Either a b -> Bool
isLeft (Left _ ) = True isLeft (Left _ ) = True
@@ -68,11 +69,22 @@ withApp perform = do
pkRes <- H.session pool $ H.tx txParam $ allprimaryKeys pkRes <- H.session pool $ H.tx txParam $ allprimaryKeys
let allPrimaryKeys = either (fail . show) id pkRes let allPrimaryKeys = either (fail . show) id pkRes
tableAclRes <- H.session pool $ H.tx txParam $ alltablesAcl
let allTablesAcl = either (fail . show) id tableAclRes
let dbstructure = DbStructure {
tables=allTables,
columns=allColumns,
relations=allRelations,
primaryKeys=allPrimaryKeys,
tablesAcl=allTablesAcl}
perform $ middle $ \req resp -> do perform $ middle $ \req resp -> do
body <- strictRequestBody req body <- strictRequestBody req
result <- liftIO $ H.session pool $ H.tx (Just (H.ReadCommitted, Just True)) result <- liftIO $ H.session pool $ H.tx (Just (H.ReadCommitted, Just True))
$ authenticated cfg (app allTables allRelations allColumns allPrimaryKeys cfg body) req $ authenticated cfg (app dbstructure cfg body) req
either (resp . errResponse) resp result either (resp . errResponse) resp result
where middle = defaultMiddle False where middle = defaultMiddle False