{"action":"closed","number":2866,"pull_request":{"url":"https://api.github.com/repos/getredash/redash/pulls/2866","id":218698534,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE4Njk4NTM0","html_url":"https://github.com/getredash/redash/pull/2866","diff_url":"https://github.com/getredash/redash/pull/2866.diff","patch_url":"https://github.com/getredash/redash/pull/2866.patch","issue_url":"https://api.github.com/repos/getredash/redash/issues/2866","number":2866,"state":"closed","locked":false,"title":"feat(redshift): hide tables the configured user cannot access","user":{"login":"sjakthol","id":10127907,"node_id":"MDQ6VXNlcjEwMTI3OTA3","avatar_url":"https://avatars1.githubusercontent.com/u/10127907?v=4","gravatar_id":"","url":"https://api.github.com/users/sjakthol","html_url":"https://github.com/sjakthol","followers_url":"https://api.github.com/users/sjakthol/followers","following_url":"https://api.github.com/users/sjakthol/following{/other_user}","gists_url":"https://api.github.com/users/sjakthol/gists{/gist_id}","starred_url":"https://api.github.com/users/sjakthol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sjakthol/subscriptions","organizations_url":"https://api.github.com/users/sjakthol/orgs","repos_url":"https://api.github.com/users/sjakthol/repos","events_url":"https://api.github.com/users/sjakthol/events{/privacy}","received_events_url":"https://api.github.com/users/sjakthol/received_events","type":"User","site_admin":false},"body":"The SVV_COLUMNS table used to determine the tables of a\r\nRedshift database includes all tables, even those the\r\ncurrent user cannot access, by default. These tables clutter\r\nthe schema browser and make it harder for users to determine\r\nwhich tables they should have access to.\r\n\r\nThese changes modify the Redshift query runner so that\r\ntables the configured user cannot access are filtered\r\nout from the database schema. The checks are two-fold:\r\n\r\n* First, the query uses HAS_SCHEMA_PRIVILEGE to check if the\r\n  current user has USAGE rights on a schema the given table\r\n  belongs to. This privilege is required to access any of\r\n  the tables in a schema.\r\n\r\n* Second, the query tries to determine if the current user\r\n  has SELECT access to the given table. Two cases need to\r\n  be considered here:\r\n\r\n  * First, we need to check if the table is part of an\r\n    external schema. Access to tables in external schema\r\n    is controlled at schema level - you cannot grant or\r\n    revoke access to specific external tables. Additionally,\r\n    the HAS_TABLE_PRIVILEGE returns an error if it is asked\r\n    to give a verdict for an external table.\r\n\r\n    Hence, the query checks if the schema a specific table\r\n    belongs to is an external schema and if it is, the table\r\n    is included in the list (if we got here the user already\r\n    had USAGE on the given schema). This check short-circuits\r\n    the table-level access check for external tables which\r\n    means they are never passed to HAS_TABLE_PRIVILEGE().\r\n\r\n  * Then, if the table was not part of an external schema,\r\n    the HAS_TABLE_PRIVILEGE() function is used to determine\r\n    if the user has SELECT access to the given table. The\r\n    table is included in the schema if this check passes.\r\n\r\nTogether this condition ensures that tables the user definitely\r\ncannot access are not included in the schema browser.\r\n\r\nThese changes have been tested to work in an environment that\r\nincludes normal and external schemas, normal and late-binding\r\nviews, and normal and external tables.","created_at":"2018-09-27T15:35:41Z","updated_at":"2018-11-08T08:53:05Z","closed_at":"2018-11-08T08:53:05Z","merged_at":"2018-11-08T08:53:05Z","merge_commit_sha":"43f82007070e3ad5a5ff16960f49faf6872915bb","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/getredash/redash/pulls/2866/commits","review_comments_url":"https://api.github.com/repos/getredash/redash/pulls/2866/comments","review_comment_url":"https://api.github.com/repos/getredash/redash/pulls/comments{/number}","comments_url":"https://api.github.com/repos/getredash/redash/issues/2866/comments","statuses_url":"https://api.github.com/repos/getredash/redash/statuses/f212456074f8261ad1aad43f9f08bc5ec4c951e2","head":{"label":"sjakthol:redshift-hide-unaccessible-tables","ref":"redshift-hide-unaccessible-tables","sha":"f212456074f8261ad1aad43f9f08bc5ec4c951e2","user":{"login":"sjakthol","id":10127907,"node_id":"MDQ6VXNlcjEwMTI3OTA3","avatar_url":"https://avatars1.githubusercontent.com/u/10127907?v=4","gravatar_id":"","url":"https://api.github.com/users/sjakthol","html_url":"https://github.com/sjakthol","followers_url":"https://api.github.com/users/sjakthol/followers","following_url":"https://api.github.com/users/sjakthol/following{/other_user}","gists_url":"https://api.github.com/users/sjakthol/gists{/gist_id}","starred_url":"https://api.github.com/users/sjakthol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sjakthol/subscriptions","organizations_url":"https://api.github.com/users/sjakthol/orgs","repos_url":"https://api.github.com/users/sjakthol/repos","events_url":"https://api.github.com/users/sjakthol/events{/privacy}","received_events_url":"https://api.github.com/users/sjakthol/received_events","type":"User","site_admin":false},"repo":{"id":116507035,"node_id":"MDEwOlJlcG9zaXRvcnkxMTY1MDcwMzU=","name":"redash","full_name":"sjakthol/redash","private":false,"owner":{"login":"sjakthol","id":10127907,"node_id":"MDQ6VXNlcjEwMTI3OTA3","avatar_url":"https://avatars1.githubusercontent.com/u/10127907?v=4","gravatar_id":"","url":"https://api.github.com/users/sjakthol","html_url":"https://github.com/sjakthol","followers_url":"https://api.github.com/users/sjakthol/followers","following_url":"https://api.github.com/users/sjakthol/following{/other_user}","gists_url":"https://api.github.com/users/sjakthol/gists{/gist_id}","starred_url":"https://api.github.com/users/sjakthol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sjakthol/subscriptions","organizations_url":"https://api.github.com/users/sjakthol/orgs","repos_url":"https://api.github.com/users/sjakthol/repos","events_url":"https://api.github.com/users/sjakthol/events{/privacy}","received_events_url":"https://api.github.com/users/sjakthol/received_events","type":"User","site_admin":false},"html_url":"https://github.com/sjakthol/redash","description":"Make Your Company Data Driven. Connect to any data source, easily visualize and share your data.","fork":true,"url":"https://api.github.com/repos/sjakthol/redash","forks_url":"https://api.github.com/repos/sjakthol/redash/forks","keys_url":"https://api.github.com/repos/sjakthol/redash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sjakthol/redash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sjakthol/redash/teams","hooks_url":"https://api.github.com/repos/sjakthol/redash/hooks","issue_events_url":"https://api.github.com/repos/sjakthol/redash/issues/events{/number}","events_url":"https://api.github.com/repos/sjakthol/redash/events","assignees_url":"https://api.github.com/repos/sjakthol/redash/assignees{/user}","branches_url":"https://api.github.com/repos/sjakthol/redash/branches{/branch}","tags_url":"https://api.github.com/repos/sjakthol/redash/tags","blobs_url":"https://api.github.com/repos/sjakthol/redash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sjakthol/redash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sjakthol/redash/git/refs{/sha}","trees_url":"https://api.github.com/repos/sjakthol/redash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sjakthol/redash/statuses/{sha}","languages_url":"https://api.github.com/repos/sjakthol/redash/languages","stargazers_url":"https://api.github.com/repos/sjakthol/redash/stargazers","contributors_url":"https://api.github.com/repos/sjakthol/redash/contributors","subscribers_url":"https://api.github.com/repos/sjakthol/redash/subscribers","subscription_url":"https://api.github.com/repos/sjakthol/redash/subscription","commits_url":"https://api.github.com/repos/sjakthol/redash/commits{/sha}","git_commits_url":"https://api.github.com/repos/sjakthol/redash/git/commits{/sha}","comments_url":"https://api.github.com/repos/sjakthol/redash/comments{/number}","issue_comment_url":"https://api.github.com/repos/sjakthol/redash/issues/comments{/number}","contents_url":"https://api.github.com/repos/sjakthol/redash/contents/{+path}","compare_url":"https://api.github.com/repos/sjakthol/redash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sjakthol/redash/merges","archive_url":"https://api.github.com/repos/sjakthol/redash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sjakthol/redash/downloads","issues_url":"https://api.github.com/repos/sjakthol/redash/issues{/number}","pulls_url":"https://api.github.com/repos/sjakthol/redash/pulls{/number}","milestones_url":"https://api.github.com/repos/sjakthol/redash/milestones{/number}","notifications_url":"https://api.github.com/repos/sjakthol/redash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sjakthol/redash/labels{/name}","releases_url":"https://api.github.com/repos/sjakthol/redash/releases{/id}","deployments_url":"https://api.github.com/repos/sjakthol/redash/deployments","created_at":"2018-01-06T18:45:07Z","updated_at":"2018-09-27T15:21:52Z","pushed_at":"2018-10-27T08:56:38Z","git_url":"git://github.com/sjakthol/redash.git","ssh_url":"git@github.com:sjakthol/redash.git","clone_url":"https://github.com/sjakthol/redash.git","svn_url":"https://github.com/sjakthol/redash","homepage":"http://redash.io/","size":12074,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"getredash:master","ref":"master","sha":"ab6ed7da34dd2797914382c435981450b7bf9d7a","user":{"login":"getredash","id":10746780,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNzQ2Nzgw","avatar_url":"https://avatars2.githubusercontent.com/u/10746780?v=4","gravatar_id":"","url":"https://api.github.com/users/getredash","html_url":"https://github.com/getredash","followers_url":"https://api.github.com/users/getredash/followers","following_url":"https://api.github.com/users/getredash/following{/other_user}","gists_url":"https://api.github.com/users/getredash/gists{/gist_id}","starred_url":"https://api.github.com/users/getredash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getredash/subscriptions","organizations_url":"https://api.github.com/users/getredash/orgs","repos_url":"https://api.github.com/users/getredash/repos","events_url":"https://api.github.com/users/getredash/events{/privacy}","received_events_url":"https://api.github.com/users/getredash/received_events","type":"Organization","site_admin":false},"repo":{"id":13926404,"node_id":"MDEwOlJlcG9zaXRvcnkxMzkyNjQwNA==","name":"redash","full_name":"getredash/redash","private":false,"owner":{"login":"getredash","id":10746780,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEwNzQ2Nzgw","avatar_url":"https://avatars2.githubusercontent.com/u/10746780?v=4","gravatar_id":"","url":"https://api.github.com/users/getredash","html_url":"https://github.com/getredash","followers_url":"https://api.github.com/users/getredash/followers","following_url":"https://api.github.com/users/getredash/following{/other_user}","gists_url":"https://api.github.com/users/getredash/gists{/gist_id}","starred_url":"https://api.github.com/users/getredash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/getredash/subscriptions","organizations_url":"https://api.github.com/users/getredash/orgs","repos_url":"https://api.github.com/users/getredash/repos","events_url":"https://api.github.com/users/getredash/events{/privacy}","received_events_url":"https://api.github.com/users/getredash/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/getredash/redash","description":"Make Your Company Data Driven. Connect to any data source, easily visualize, dashboard and share your data.","fork":false,"url":"https://api.github.com/repos/getredash/redash","forks_url":"https://api.github.com/repos/getredash/redash/forks","keys_url":"https://api.github.com/repos/getredash/redash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/getredash/redash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/getredash/redash/teams","hooks_url":"https://api.github.com/repos/getredash/redash/hooks","issue_events_url":"https://api.github.com/repos/getredash/redash/issues/events{/number}","events_url":"https://api.github.com/repos/getredash/redash/events","assignees_url":"https://api.github.com/repos/getredash/redash/assignees{/user}","branches_url":"https://api.github.com/repos/getredash/redash/branches{/branch}","tags_url":"https://api.github.com/repos/getredash/redash/tags","blobs_url":"https://api.github.com/repos/getredash/redash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/getredash/redash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/getredash/redash/git/refs{/sha}","trees_url":"https://api.github.com/repos/getredash/redash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/getredash/redash/statuses/{sha}","languages_url":"https://api.github.com/repos/getredash/redash/languages","stargazers_url":"https://api.github.com/repos/getredash/redash/stargazers","contributors_url":"https://api.github.com/repos/getredash/redash/contributors","subscribers_url":"https://api.github.com/repos/getredash/redash/subscribers","subscription_url":"https://api.github.com/repos/getredash/redash/subscription","commits_url":"https://api.github.com/repos/getredash/redash/commits{/sha}","git_commits_url":"https://api.github.com/repos/getredash/redash/git/commits{/sha}","comments_url":"https://api.github.com/repos/getredash/redash/comments{/number}","issue_comment_url":"https://api.github.com/repos/getredash/redash/issues/comments{/number}","contents_url":"https://api.github.com/repos/getredash/redash/contents/{+path}","compare_url":"https://api.github.com/repos/getredash/redash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/getredash/redash/merges","archive_url":"https://api.github.com/repos/getredash/redash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/getredash/redash/downloads","issues_url":"https://api.github.com/repos/getredash/redash/issues{/number}","pulls_url":"https://api.github.com/repos/getredash/redash/pulls{/number}","milestones_url":"https://api.github.com/repos/getredash/redash/milestones{/number}","notifications_url":"https://api.github.com/repos/getredash/redash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/getredash/redash/labels{/name}","releases_url":"https://api.github.com/repos/getredash/redash/releases{/id}","deployments_url":"https://api.github.com/repos/getredash/redash/deployments","created_at":"2013-10-28T13:19:39Z","updated_at":"2018-11-08T06:24:25Z","pushed_at":"2018-11-08T08:53:05Z","git_url":"git://github.com/getredash/redash.git","ssh_url":"git@github.com:getredash/redash.git","clone_url":"https://github.com/getredash/redash.git","svn_url":"https://github.com/getredash/redash","homepage":"http://redash.io/","size":12231,"stargazers_count":10714,"watchers_count":10714,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":1695,"mirror_url":null,"archived":false,"open_issues_count":451,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":1695,"open_issues":451,"watchers":10714,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/getredash/redash/pulls/2866"},"html":{"href":"https://github.com/getredash/redash/pull/2866"},"issue":{"href":"https://api.github.com/repos/getredash/redash/issues/2866"},"comments":{"href":"https://api.github.com/repos/getredash/redash/issues/2866/comments"},"review_comments":{"href":"https://api.github.com/repos/getredash/redash/pulls/2866/comments"},"review_comment":{"href":"https://api.github.com/repos/getredash/redash/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/getredash/redash/pulls/2866/commits"},"statuses":{"href":"https://api.github.com/repos/getredash/redash/statuses/f212456074f8261ad1aad43f9f08bc5ec4c951e2"}},"author_association":"CONTRIBUTOR","merged":true,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":{"login":"arikfr","id":71468,"node_id":"MDQ6VXNlcjcxNDY4","avatar_url":"https://avatars2.githubusercontent.com/u/71468?v=4","gravatar_id":"","url":"https://api.github.com/users/arikfr","html_url":"https://github.com/arikfr","followers_url":"https://api.github.com/users/arikfr/followers","following_url":"https://api.github.com/users/arikfr/following{/other_user}","gists_url":"https://api.github.com/users/arikfr/gists{/gist_id}","starred_url":"https://api.github.com/users/arikfr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arikfr/subscriptions","organizations_url":"https://api.github.com/users/arikfr/orgs","repos_url":"https://api.github.com/users/arikfr/repos","events_url":"https://api.github.com/users/arikfr/events{/privacy}","received_events_url":"https://api.github.com/users/arikfr/received_events","type":"User","site_admin":false},"comments":2,"review_comments":2,"maintainer_can_modify":false,"commits":1,"additions":11,"deletions":0,"changed_files":1}}
{"actor":{"display_login":"arikfr"}}