redash/tests/test_permissions.py

74 lines
2.7 KiB
Python
Raw Normal View History

Allow Parameters on Public Dashboards (#3659) * change has_access and require_access signatures to work with the objects that require access, instead of their groups * use the textless endpoint (/api/queries/:id/results) for pristine queriest * Revert "use the textless endpoint (/api/queries/:id/results) for pristine" This reverts commit cd2cee77385ecf79efd2f1aa21fab0dd43943264. * go to textless /api/queries/:id/results by default * change `run_query`'s signature to accept a ParameterizedQuery instead of constructing it inside * raise HTTP 400 when receiving invalid parameter values. Fixes #3394 * enqueue jobs for ApiUsers * rename `id` to `user_id` * support executing queries using Query api_keys by instantiating an ApiUser that would be able to execute the specific query * show deprecation messages for ALLOW_PARAMETERS_IN_EMBEDS. Also, move other message (email not verified) to use the same mechanism * add link to forum message regarding embed deprecation * change API to /api/queries/:id/dropdowns/:dropdown_id * split to 2 different dropdown endpoints and implement the second * add test cases for /api/queries/:id/dropdowns/:id * use new /dropdowns endpoint in frontend * first e2e test for sharing embeds * Pleasing the CodeClimate overlords * All glory to CodeClimate * remove residues from bad rebase * add query id and data source id to serialized public dashboards * add global parameters directive to public dashboards page * allow access to a query by the api_key of the dashboard which includes it * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * support global parameters for public dashboards * change has_access and require_access signatures to work with the objects that require access, instead of their groups * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * no need to log `is_api_key` * send parameters to public dashboard page * allow access to a query by the api_key of the dashboard which includes it * disable sharing if dashboard is associated with unsafe queries * remove cypress test added in the wrong place due to a faulty rebase * add support for clicking buttons in cy.clickThrough * Cypress test which verifies that dashboards with safe queries can be shared * Cypress test which verifies that dashboards with unsafe queries can't be shared * remove duplicate tests * use this.enabled and negate when needed * remove stale comment * add another Cypress test to verify that unauthenticated users have access to public dashboards with parameters * obviously, I commit 'only' the first time I use it * search for query access by query id and not api_key * no need to fetch latest query data as it is loaded by frontend from the textless endpoint * test that queries associated with dashboards are accessible when supplying the dashboard api_key * propagate `isDirty` down to `QueryBasedParameterInput` * go to /api/:id/dropdown while editing a query, since dropdown queries might still not be associated with the parent. see #3711 * show helpful error message if dropdown values cannot be fetched * use backticks instead of line concatenation * remove requirement to have direct access to dropdown query in order validate it. parent query association checks are sufficient * remove isDirty-based implementation and allow dropdown queries through nested ACL even if they aren't associated yet (given that the user has _direct_ access to the dropdown query) * fix tests to cover all cases for /api/queries/:id/dropdowns/:id * fix indentation * require access to the query, not the data source * resolve dashboard user by query id * apply new copy to Cypress tests * if only something would have prevented me from commiting an 'only' call 🤔 * very important handling of whitespace * respond to parameter's Apply button * text widgets are safe for sharing * remove redundant event * add a safety check that object has dashboard_api_keys before calling it * supply a parameter value for text parameters to have it show up * add parameter values for date and datetime * use the current year and month to avoid pagination * use Cypress.moment() instead of preinstalled moment() * explicitly create parameters * refresh query data if a querystring parameter is provided * avoid sending a data_source_id - it's only relevant to unsaved queries, since a saved query's data_source is available in the backend * remove empty query text workaround * provide default value to parameter * add a few more dashboard sharing specs * lint * wait for DynamicTable to appear to reveal that actual results are displaying * override error message for unsafely shared widgets
2019-07-15 12:09:30 +00:00
from tests import BaseTestCase
from collections import namedtuple
from unittest import TestCase
from redash.permissions import has_access
Allow Parameters on Public Dashboards (#3659) * change has_access and require_access signatures to work with the objects that require access, instead of their groups * use the textless endpoint (/api/queries/:id/results) for pristine queriest * Revert "use the textless endpoint (/api/queries/:id/results) for pristine" This reverts commit cd2cee77385ecf79efd2f1aa21fab0dd43943264. * go to textless /api/queries/:id/results by default * change `run_query`'s signature to accept a ParameterizedQuery instead of constructing it inside * raise HTTP 400 when receiving invalid parameter values. Fixes #3394 * enqueue jobs for ApiUsers * rename `id` to `user_id` * support executing queries using Query api_keys by instantiating an ApiUser that would be able to execute the specific query * show deprecation messages for ALLOW_PARAMETERS_IN_EMBEDS. Also, move other message (email not verified) to use the same mechanism * add link to forum message regarding embed deprecation * change API to /api/queries/:id/dropdowns/:dropdown_id * split to 2 different dropdown endpoints and implement the second * add test cases for /api/queries/:id/dropdowns/:id * use new /dropdowns endpoint in frontend * first e2e test for sharing embeds * Pleasing the CodeClimate overlords * All glory to CodeClimate * remove residues from bad rebase * add query id and data source id to serialized public dashboards * add global parameters directive to public dashboards page * allow access to a query by the api_key of the dashboard which includes it * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * support global parameters for public dashboards * change has_access and require_access signatures to work with the objects that require access, instead of their groups * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * no need to log `is_api_key` * send parameters to public dashboard page * allow access to a query by the api_key of the dashboard which includes it * disable sharing if dashboard is associated with unsafe queries * remove cypress test added in the wrong place due to a faulty rebase * add support for clicking buttons in cy.clickThrough * Cypress test which verifies that dashboards with safe queries can be shared * Cypress test which verifies that dashboards with unsafe queries can't be shared * remove duplicate tests * use this.enabled and negate when needed * remove stale comment * add another Cypress test to verify that unauthenticated users have access to public dashboards with parameters * obviously, I commit 'only' the first time I use it * search for query access by query id and not api_key * no need to fetch latest query data as it is loaded by frontend from the textless endpoint * test that queries associated with dashboards are accessible when supplying the dashboard api_key * propagate `isDirty` down to `QueryBasedParameterInput` * go to /api/:id/dropdown while editing a query, since dropdown queries might still not be associated with the parent. see #3711 * show helpful error message if dropdown values cannot be fetched * use backticks instead of line concatenation * remove requirement to have direct access to dropdown query in order validate it. parent query association checks are sufficient * remove isDirty-based implementation and allow dropdown queries through nested ACL even if they aren't associated yet (given that the user has _direct_ access to the dropdown query) * fix tests to cover all cases for /api/queries/:id/dropdowns/:id * fix indentation * require access to the query, not the data source * resolve dashboard user by query id * apply new copy to Cypress tests * if only something would have prevented me from commiting an 'only' call 🤔 * very important handling of whitespace * respond to parameter's Apply button * text widgets are safe for sharing * remove redundant event * add a safety check that object has dashboard_api_keys before calling it * supply a parameter value for text parameters to have it show up * add parameter values for date and datetime * use the current year and month to avoid pagination * use Cypress.moment() instead of preinstalled moment() * explicitly create parameters * refresh query data if a querystring parameter is provided * avoid sending a data_source_id - it's only relevant to unsaved queries, since a saved query's data_source is available in the backend * remove empty query text workaround * provide default value to parameter * add a few more dashboard sharing specs * lint * wait for DynamicTable to appear to reveal that actual results are displaying * override error message for unsafely shared widgets
2019-07-15 12:09:30 +00:00
from redash import models
MockUser = namedtuple("MockUser", ["permissions", "group_ids"])
view_only = True
Allow Parameters on Public Dashboards (#3659) * change has_access and require_access signatures to work with the objects that require access, instead of their groups * use the textless endpoint (/api/queries/:id/results) for pristine queriest * Revert "use the textless endpoint (/api/queries/:id/results) for pristine" This reverts commit cd2cee77385ecf79efd2f1aa21fab0dd43943264. * go to textless /api/queries/:id/results by default * change `run_query`'s signature to accept a ParameterizedQuery instead of constructing it inside * raise HTTP 400 when receiving invalid parameter values. Fixes #3394 * enqueue jobs for ApiUsers * rename `id` to `user_id` * support executing queries using Query api_keys by instantiating an ApiUser that would be able to execute the specific query * show deprecation messages for ALLOW_PARAMETERS_IN_EMBEDS. Also, move other message (email not verified) to use the same mechanism * add link to forum message regarding embed deprecation * change API to /api/queries/:id/dropdowns/:dropdown_id * split to 2 different dropdown endpoints and implement the second * add test cases for /api/queries/:id/dropdowns/:id * use new /dropdowns endpoint in frontend * first e2e test for sharing embeds * Pleasing the CodeClimate overlords * All glory to CodeClimate * remove residues from bad rebase * add query id and data source id to serialized public dashboards * add global parameters directive to public dashboards page * allow access to a query by the api_key of the dashboard which includes it * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * support global parameters for public dashboards * change has_access and require_access signatures to work with the objects that require access, instead of their groups * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * no need to log `is_api_key` * send parameters to public dashboard page * allow access to a query by the api_key of the dashboard which includes it * disable sharing if dashboard is associated with unsafe queries * remove cypress test added in the wrong place due to a faulty rebase * add support for clicking buttons in cy.clickThrough * Cypress test which verifies that dashboards with safe queries can be shared * Cypress test which verifies that dashboards with unsafe queries can't be shared * remove duplicate tests * use this.enabled and negate when needed * remove stale comment * add another Cypress test to verify that unauthenticated users have access to public dashboards with parameters * obviously, I commit 'only' the first time I use it * search for query access by query id and not api_key * no need to fetch latest query data as it is loaded by frontend from the textless endpoint * test that queries associated with dashboards are accessible when supplying the dashboard api_key * propagate `isDirty` down to `QueryBasedParameterInput` * go to /api/:id/dropdown while editing a query, since dropdown queries might still not be associated with the parent. see #3711 * show helpful error message if dropdown values cannot be fetched * use backticks instead of line concatenation * remove requirement to have direct access to dropdown query in order validate it. parent query association checks are sufficient * remove isDirty-based implementation and allow dropdown queries through nested ACL even if they aren't associated yet (given that the user has _direct_ access to the dropdown query) * fix tests to cover all cases for /api/queries/:id/dropdowns/:id * fix indentation * require access to the query, not the data source * resolve dashboard user by query id * apply new copy to Cypress tests * if only something would have prevented me from commiting an 'only' call 🤔 * very important handling of whitespace * respond to parameter's Apply button * text widgets are safe for sharing * remove redundant event * add a safety check that object has dashboard_api_keys before calling it * supply a parameter value for text parameters to have it show up * add parameter values for date and datetime * use the current year and month to avoid pagination * use Cypress.moment() instead of preinstalled moment() * explicitly create parameters * refresh query data if a querystring parameter is provided * avoid sending a data_source_id - it's only relevant to unsaved queries, since a saved query's data_source is available in the backend * remove empty query text workaround * provide default value to parameter * add a few more dashboard sharing specs * lint * wait for DynamicTable to appear to reveal that actual results are displaying * override error message for unsafely shared widgets
2019-07-15 12:09:30 +00:00
class TestHasAccess(BaseTestCase):
def test_allows_admin_regardless_of_groups(self):
user = MockUser(["admin"], [])
self.assertTrue(has_access({}, user, view_only))
self.assertTrue(has_access({}, user, not view_only))
def test_allows_if_user_member_in_group_with_view_access(self):
user = MockUser([], [1])
self.assertTrue(has_access({1: view_only}, user, view_only))
def test_allows_if_user_member_in_group_with_full_access(self):
user = MockUser([], [1])
self.assertTrue(has_access({1: not view_only}, user, not view_only))
def test_allows_if_user_member_in_multiple_groups(self):
user = MockUser([], [1, 2, 3])
self.assertTrue(
has_access({1: not view_only, 2: view_only}, user, not view_only)
)
self.assertFalse(has_access({1: view_only, 2: view_only}, user, not view_only))
self.assertTrue(has_access({1: view_only, 2: view_only}, user, view_only))
self.assertTrue(
has_access({1: not view_only, 2: not view_only}, user, view_only)
)
def test_not_allows_if_not_enough_permission(self):
user = MockUser([], [1])
self.assertFalse(has_access({1: view_only}, user, not view_only))
self.assertFalse(has_access({2: view_only}, user, not view_only))
self.assertFalse(has_access({2: view_only}, user, view_only))
self.assertFalse(
has_access({2: not view_only, 1: view_only}, user, not view_only)
)
Allow Parameters on Public Dashboards (#3659) * change has_access and require_access signatures to work with the objects that require access, instead of their groups * use the textless endpoint (/api/queries/:id/results) for pristine queriest * Revert "use the textless endpoint (/api/queries/:id/results) for pristine" This reverts commit cd2cee77385ecf79efd2f1aa21fab0dd43943264. * go to textless /api/queries/:id/results by default * change `run_query`'s signature to accept a ParameterizedQuery instead of constructing it inside * raise HTTP 400 when receiving invalid parameter values. Fixes #3394 * enqueue jobs for ApiUsers * rename `id` to `user_id` * support executing queries using Query api_keys by instantiating an ApiUser that would be able to execute the specific query * show deprecation messages for ALLOW_PARAMETERS_IN_EMBEDS. Also, move other message (email not verified) to use the same mechanism * add link to forum message regarding embed deprecation * change API to /api/queries/:id/dropdowns/:dropdown_id * split to 2 different dropdown endpoints and implement the second * add test cases for /api/queries/:id/dropdowns/:id * use new /dropdowns endpoint in frontend * first e2e test for sharing embeds * Pleasing the CodeClimate overlords * All glory to CodeClimate * remove residues from bad rebase * add query id and data source id to serialized public dashboards * add global parameters directive to public dashboards page * allow access to a query by the api_key of the dashboard which includes it * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * support global parameters for public dashboards * change has_access and require_access signatures to work with the objects that require access, instead of their groups * rename `object` to `obj` * simplify permission tests once `has_access` accepts groups * no need to log `is_api_key` * send parameters to public dashboard page * allow access to a query by the api_key of the dashboard which includes it * disable sharing if dashboard is associated with unsafe queries * remove cypress test added in the wrong place due to a faulty rebase * add support for clicking buttons in cy.clickThrough * Cypress test which verifies that dashboards with safe queries can be shared * Cypress test which verifies that dashboards with unsafe queries can't be shared * remove duplicate tests * use this.enabled and negate when needed * remove stale comment * add another Cypress test to verify that unauthenticated users have access to public dashboards with parameters * obviously, I commit 'only' the first time I use it * search for query access by query id and not api_key * no need to fetch latest query data as it is loaded by frontend from the textless endpoint * test that queries associated with dashboards are accessible when supplying the dashboard api_key * propagate `isDirty` down to `QueryBasedParameterInput` * go to /api/:id/dropdown while editing a query, since dropdown queries might still not be associated with the parent. see #3711 * show helpful error message if dropdown values cannot be fetched * use backticks instead of line concatenation * remove requirement to have direct access to dropdown query in order validate it. parent query association checks are sufficient * remove isDirty-based implementation and allow dropdown queries through nested ACL even if they aren't associated yet (given that the user has _direct_ access to the dropdown query) * fix tests to cover all cases for /api/queries/:id/dropdowns/:id * fix indentation * require access to the query, not the data source * resolve dashboard user by query id * apply new copy to Cypress tests * if only something would have prevented me from commiting an 'only' call 🤔 * very important handling of whitespace * respond to parameter's Apply button * text widgets are safe for sharing * remove redundant event * add a safety check that object has dashboard_api_keys before calling it * supply a parameter value for text parameters to have it show up * add parameter values for date and datetime * use the current year and month to avoid pagination * use Cypress.moment() instead of preinstalled moment() * explicitly create parameters * refresh query data if a querystring parameter is provided * avoid sending a data_source_id - it's only relevant to unsaved queries, since a saved query's data_source is available in the backend * remove empty query text workaround * provide default value to parameter * add a few more dashboard sharing specs * lint * wait for DynamicTable to appear to reveal that actual results are displaying * override error message for unsafely shared widgets
2019-07-15 12:09:30 +00:00
def test_allows_access_to_query_by_query_api_key(self):
query = self.factory.create_query()
user = models.ApiUser(query.api_key, None, [])
self.assertTrue(has_access(query, user, view_only))
def test_doesnt_allow_access_to_query_by_different_api_key(self):
query = self.factory.create_query()
other_query = self.factory.create_query()
user = models.ApiUser(other_query.api_key, None, [])
self.assertFalse(has_access(query, user, view_only))
def test_allows_access_to_query_by_dashboard_api_key(self):
dashboard = self.factory.create_dashboard()
visualization = self.factory.create_visualization()
self.factory.create_widget(dashboard=dashboard, visualization=visualization)
query = self.factory.create_query(visualizations=[visualization])
api_key = self.factory.create_api_key(object=dashboard).api_key
user = models.ApiUser(api_key, None, [])
self.assertTrue(has_access(query, user, view_only))