"""Test endpoint rules checker.""" from unittest.mock import MagicMock import pytest from grass.logic import endpoint_rules, user TEST_RULES = 'tests/unit/logic/rules.yaml' @pytest.mark.parametrize( 'route, result_regex', [ ('/holds/', '^/holds/\\d+$'), ('/holds/active', '^/holds/active$'), ('/holds/<*>', '^/holds/.*$'), ('///average', '^/[\\w_\\-]+/\\d+/average$'), ], ) def test_route_to_regex(route, result_regex): """Test converting an endpoint route to regex.""" assert endpoint_rules.route_to_regex(route) == result_regex @pytest.mark.parametrize( 'path, method, group, role, has_access', [ ('/holds/234', 'PUT', 'alw', [1], True), ('/holds/234', 'PUT', 'oa', [1, 4], True), ('/holds/234', 'PUT', 'alw', [2], False), ('/holds/234', 'GET', 'alw', [2, 4], True), ('/holds/active', 'GET', 'alw', [2], True), ('/holds/active', 'GET', 'oa', [2], False), ('/holds/active', 'GET', 'oa', [1], True), ('/holds/active', 'POST', 'alw', [2], False), ('/holds/vendor/123', 'GET', 'alw', [3], True), ('/holds/vendor/123', 'POST', 'alw', [3], False), ('/holds/vendor/active', 'PATCH', 'alw', [1], True), ('/holds/vendor/active', 'PATCH', 'alw', [3], False), ('/holds/blah', 'GET', 'alw', [1], True), ('/holds/blah', 'GET', 'alw', [3], False), ('/test/3/average', 'GET', 'alw', [1], True), ('/test/what/average', 'GET', 'alw', [1], False), ('/holdsregex/vendor/123', 'GET', 'alw', [1], True), ('/holdsregex/7777/123', 'GET', 'alw', [1], False), ('/report', 'GET', 'alw', [4, 5, 6], True), ('/report', 'GET', 'alw', [6], False), ('/report', 'GET', 'oa', [1], False), ('/upload-token?rand=a234fdsdf', 'GET', 'alw', [1], True), ('/test_slash/', 'GET', 'alw', [1], True), ('/test_slash', 'GET', 'alw', [1], True), ('/test_slash/23', 'GET', 'alw', [1], True), ('/test_slash/23/', 'GET', 'alw', [1], True), ('/reporting/report/product-view-UK', 'GET', 'alw', [3], True), ('/reporting/report/product_view_UK', 'GET', 'alw', [3], True), ], ) def test_rules(path, method, group, role, has_access): """Test rules validator.""" validator = endpoint_rules.EndpointRulesValidator(TEST_RULES) assert validator.has_access(path, method, group, role) == has_access @pytest.mark.parametrize( 'path, method, group, role, has_access', [ ('/assets/v2/assets/upload', 'POST', 'alw', [1], True), ('/assets/v2/assets/upload', 'POST', 'alw', [4], True), ('/assets/v2/assets/upload', 'POST', 'alw', [3], False), ('/assets/v2/assets/upload', 'POST', 'oa', [1], True), ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f?part_numbers=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10', 'GET', 'alw', [1], True, ), # noqa: E501 ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f?part_numbers=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10', 'GET', 'alw', [4], True, ), # noqa: E501 ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f?part_numbers=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10', 'GET', 'alw', [3], False, ), # noqa: E501 ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f?part_numbers=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10', 'GET', 'oa', [1], True, ), # noqa: E501 ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f', 'PATCH', 'alw', [1], True, ), # noqa: E501 ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f', 'PATCH', 'alw', [4], True, ), # noqa: E501 ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f', 'PATCH', 'alw', [3], False, ), # noqa: E501 ( '/assets/v2/assets/upload/edcf2f82_725e_4c85_ba2d_a0809d8b127f', 'PATCH', 'oa', [1], True, ), # noqa: E501 ], ) def test_assets_rules(path, method, group, role, has_access): """Test rules validator on assets.""" validator = endpoint_rules.EndpointRulesValidator('grass/rules/ows-assets.yml') assert validator.has_access(path, method, group, role) == has_access @pytest.mark.parametrize( 'path, method, group, user_id, has_access', [ ('/pricing/admin/pricing-family', 'POST', 'oa', 'oa:562', True), ('/pricing/admin/store-pricing-scheme/46', 'PUT', 'oa', 'oa:562', True), ('/pricing/admin/orchard-pricing-tier', 'POST', 'oa', 'oa:562', True), ('/pricing/admin/store_pricing_tier_code/1', 'DELETE', 'oa', 'oa:562', True), ('/pricing/admin/orchard-pricing-tier', 'GET', 'oa', 'oa:562', False), ('/pricing/admin/store-pricing-scheme/46', 'PUT', 'oa', 'oa:1849', False), ('/pricing/admin/orchard-pricing-tier', 'POST', 'oa', 'oa:1849', False), ('/pricing/admin/store_pricing_tier_code/1', 'DELETE', 'oa', 'oa:1849', False), ('/holds/active', 'GET', 'oa', 'oa:562', False), ('/reporting/report/product-view-UK', 'GET', 'oa', 'oa:562', False), ('/pricing/admin/orchard-pricing-tier', 'POST', 'oa', 'alw:43807', False), ], ) def test_rules_has_resource_access( path, method, group, user_id, has_access, monkeypatch ): """Test rules validator.""" monkeypatch.setattr( user, 'is_allowed_for_any_resources', MagicMock(return_value=has_access) ) validator = endpoint_rules.EndpointRulesValidator(TEST_RULES) assert validator.has_resource_access(path, method, group, user_id) == has_access def test_rules_has_resource_access_wildcard_resource(monkeypatch): """Test rules validator grants access for a rule with groups=['*'].""" mock_is_allowed_for_any_resources = MagicMock() monkeypatch.setattr( user, 'is_allowed_for_any_resources', mock_is_allowed_for_any_resources ) validator = endpoint_rules.EndpointRulesValidator(TEST_RULES) assert ( validator.has_resource_access('/holds/vendor/234', 'GET', 'alw', 'alw:562') is True ) mock_is_allowed_for_any_resources.assert_not_called() @pytest.mark.parametrize( 'path, method, group, role, has_access', [ ('/video/output_video_outer_resolutions', 'GET', 'alw', [1], True), ('/video/output_video_outer_resolutions', 'GET', 'alw', [4], True), ('/video/output_video_outer_resolutions', 'GET', 'alw', [3], False), ('/video/output_video_outer_resolutions', 'GET', 'oa', [1], True), ], ) def test_video_rules(path, method, group, role, has_access): """Test rules validator on video.""" validator = endpoint_rules.EndpointRulesValidator('grass/rules/ows-video.yml') assert validator.has_access(path, method, group, role) == has_access