fix insert permission views are not unique for long role names (fix #3444) (#3486)

* fix insert permission views are not unique for long role names, fix #3444
* Use GHC notes reference and improve comments
This commit is contained in:
Rakesh Emmadi 2019-12-10 04:53:06 +05:30 committed by Alexis King
parent fa0af9728d
commit 3f8a1d9ebf
6 changed files with 57 additions and 17 deletions

View File

@ -98,10 +98,17 @@ data Cohort
-- result changed, then merge them in the map of existing subscribers
}
{- Note [Blake2b faster than SHA-256]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At the time of writing, from https://blake2.net, it is stated,
"BLAKE2 is a cryptographic hash function faster than MD5, SHA-1, SHA-2, and SHA-3,
yet is at least as secure as the latest standard SHA-3".
-}
-- | A hash used to determine if the result changed without having to keep the entire result in
-- memory. Using a cryptographic hash ensures that a hash collision is almost impossible: with 256
-- bits, even if a subscription changes once per second for an entire year, the probability of a
-- hash collision is ~4.294417×10-63. We use Blake2b because it is faster than SHA-256
-- hash collision is ~4.294417×10-63. See Note [Blake2b faster than SHA-256].
newtype ResponseHash = ResponseHash { unResponseHash :: CH.Digest CH.Blake2b_256 }
deriving (Show, Eq)

View File

@ -66,6 +66,7 @@ import Data.Aeson.Casing
import Data.Aeson.TH
import Language.Haskell.TH.Syntax (Lift)
import qualified Crypto.Hash as CH
import qualified Data.HashMap.Strict as HM
import qualified Data.HashSet as HS
import qualified Data.Text as T
@ -84,12 +85,15 @@ type InsPermDef = PermDef InsPerm
type CreateInsPerm = CreatePerm InsPerm
buildViewName :: QualifiedTable -> RoleName -> PermType -> QualifiedTable
buildViewName (QualifiedObject sn tn) rn pt =
QualifiedObject hdbViewsSchema $ TableName
(roleNameToTxt rn <> "__" <> T.pack (show pt) <> "__" <> snTxt <> "__" <> tnTxt)
buildViewName qt rn pt = QualifiedObject hdbViewsSchema tableName
where
snTxt = getSchemaTxt sn
tnTxt = getTableTxt tn
-- Generate a unique hash for view name from role name, permission type and qualified table.
-- See Note [Postgres identifier length limitations].
-- Black2b_224 generates 56 character hash. See Note [Blake2b faster than SHA-256].
-- Refer https://github.com/hasura/graphql-engine/issues/3444.
tableName = TableName $ T.pack $ show hash
hash :: CH.Digest CH.Blake2b_224 =
CH.hash $ txtToBs $ roleNameToTxt rn <> "__" <> T.pack (show pt) <> "__" <> qualObjectToText qt
buildView :: QualifiedTable -> QualifiedTable -> Q.Query
buildView tn vn =

View File

@ -8,11 +8,14 @@ import Hasura.Prelude
import qualified Hasura.SQL.DML as S
import Hasura.SQL.Types (Iden (..))
{- Note [Postgres identifier length limitations]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Postgres truncates identifiers to a maximum of 63 characters by default (see
https://www.postgresql.org/docs/12/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS).
-}
-- add an int as a prefix to all aliases.
-- This is needed in cases identifiers exceed 63 chars
-- as postgres only considers first 63 chars of
-- an identifier
-- Prefix an Int to all aliases to preserve the uniqueness of identifiers.
-- See Note [Postgres identifier length limitations].
prefixNumToAliases :: S.Select -> S.Select
prefixNumToAliases s =
uSelect s `evalState` UniqSt 0 Map.empty

View File

@ -0,0 +1,27 @@
- description: Create insert permission for author table with long (> 63 chars) role
url: /v1/query
status: 200
response:
message: success
query:
type: create_insert_permission
args:
table: author
role: this.is.really.a.very.long.and.long.role.more.than.63.characters.one
permission:
columns: '*'
check: {}
- description: Create insert permission for author table with long (> 63 chars) role
url: /v1/query
status: 200
response:
message: success
query:
type: create_insert_permission
args:
table: author
role: this.is.really.a.very.long.and.long.role.more.than.63.characters.two
permission:
columns: '*'
check: {}

View File

@ -4,10 +4,6 @@ args:
- type: run_sql
args:
sql: |
drop table article
- type: run_sql
args:
sql: |
drop table author
DROP TABLE article;
DROP TABLE author;
cascade: true

View File

@ -629,6 +629,9 @@ class TestCreatePermission(DefaultTestQueries):
def test_create_permission_user_role_error(self, hge_ctx):
check_query_f(hge_ctx, self.dir() + '/create_article_permission_role_user.yaml')
def test_create_author_insert_permission_long_role(self, hge_ctx):
check_query_f(hge_ctx, self.dir() + '/create_author_insert_permission_long_role.yaml')
@classmethod
def dir(cls):
return "queries/v1/permissions"