From 397135b857a9928bbbddfc161047fac5ced09bc6 Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Tue, 21 Nov 2023 11:52:46 +0100 Subject: [PATCH] Allow avoiding inclusion of other permissions Permission mapping items can have optional field "testcases_ignore" with list of patterns to avoid matching specific test case names that are otherwise matched by "testcases". JIRA: RHELWF-10228 --- tests/test_api_v10.py | 29 ++++++++++++++++++++++++++++- waiverdb/api_v1.py | 15 ++++++++++++++- waiverdb/authorization.py | 12 ++++++++---- waiverdb/templates/layout.html | 4 ++++ waiverdb/templates/permissions.html | 22 +++++++++++++--------- 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/tests/test_api_v10.py b/tests/test_api_v10.py index f08db8b9..99c0008b 100644 --- a/tests/test_api_v10.py +++ b/tests/test_api_v10.py @@ -886,7 +886,7 @@ def test_permissions_endpoint(client): "maintainers": ["alice@example.com"], "_testcase_regex_pattern": "^kernel-qe", "groups": ["devel", "qa"], - "users": ["alice@example.com"], + "users": ["alice"], }, { "name": "Greenwave Tests", @@ -928,6 +928,33 @@ def test_permissions_endpoint(client): assert f"{config['PERMISSIONS'][1]['name']}" in r.text +def test_permissions_endpoint_include_following(client): + config = { + 'PERMISSIONS': [ + { + "name": "Security", + "testcases": ["security.*"], + "groups": ["security"], + }, + { + "name": "Development", + "testcases": ["*"], + "groups": ["devel"], + "testcases_ignore": ["security.*"], + } + ] + } + + with patch.dict(client.application.config, config): + r = client.get('/api/v1.0/permissions?testcase=security.test1') + assert r.status_code == 200, r.text + assert r.json == config['PERMISSIONS'][0:1] + + r = client.get('/api/v1.0/permissions?testcase=security-not.test1') + assert r.status_code == 200, r.text + assert r.json == config['PERMISSIONS'][1:] + + def test_config_endpoint_superusers(client): config = { 'SUPERUSERS': ['alice', 'bob'] diff --git a/waiverdb/api_v1.py b/waiverdb/api_v1.py index e4880984..f1b2ef5f 100644 --- a/waiverdb/api_v1.py +++ b/waiverdb/api_v1.py @@ -681,6 +681,18 @@ def get(self): """ Returns the waiver permissions. + Each entry has "testcases" (list of glob patterns for matching test + case name) and "users" or "groups". + + Optional "testcases_ignore" (similar to "testcases") allows to ignore a + permission entry on a matching test case name. + + The full list of users and groups permitted to waive given test case is + constructed by iterating the permissions in order and adding "users" + and "groups" from each permission entry which has at least one pattern + in "testcases" matching the test case name and no matching pattern in + "testcases_ignore". + **Sample response**: .. sourcecode:: none @@ -696,8 +708,9 @@ def get(self): "name": "kernel-qe", "maintainers": ["alice@example.com"], "testcases": ["kernel-qe.*"], + "testcases_ignore": ["kernel-qe.unwaivable.*"], "groups": ["devel", "qa"], - "users": ["alice@example.com"] + "users": ["alice@example.com"], }, { "name": "Greenwave Tests", diff --git a/waiverdb/authorization.py b/waiverdb/authorization.py index 3b58595b..061c9b09 100644 --- a/waiverdb/authorization.py +++ b/waiverdb/authorization.py @@ -32,13 +32,17 @@ def get_group_membership(ldap, user, con, ldap_search): raise Unauthorized('Some error occurred initializing the LDAP connection.') +def match_testcase(testcase: str, patterns: dict[str, Any]): + return any(fnmatch(testcase, pattern) for pattern in patterns) + + def match_testcase_permissions(testcase: str, permissions: list[dict[str, Any]]): for permission in permissions: + if match_testcase(testcase, permission.get("testcases_ignore", [])): + continue + if "testcases" in permission: - testcase_match = any( - fnmatch(testcase, testcase_pattern) - for testcase_pattern in permission["testcases"] - ) + testcase_match = match_testcase(testcase, permission["testcases"]) elif "_testcase_regex_pattern" in permission: testcase_match = re.search( permission["_testcase_regex_pattern"], testcase) diff --git a/waiverdb/templates/layout.html b/waiverdb/templates/layout.html index f7f3485b..8a5f7039 100644 --- a/waiverdb/templates/layout.html +++ b/waiverdb/templates/layout.html @@ -19,6 +19,10 @@ {% block scripts %} {% endblock %} + + diff --git a/waiverdb/templates/permissions.html b/waiverdb/templates/permissions.html index 07e99607..62ddcab1 100644 --- a/waiverdb/templates/permissions.html +++ b/waiverdb/templates/permissions.html @@ -21,19 +21,23 @@ {% for p in permissions -%} {{ p["name"] }} - {{ p["maintainers"] | map("urlize") | join(" ") | safe }} - {{ p["testcases"] | join("
") | replace('-', '‑') | safe }} + + {% if p["groups"] | length > 0 -%} - Groups:
- {{ p["groups"] | join("
") | replace('-', '‑') | safe }} - {% if p["users"] | length > 0 -%} -
- {%- endif %} + Groups: + {%- endif %} + {% if p["users"] | length > 0 -%} - Users:
- {{ p["users"] | join("
") | replace('-', '‑') | safe }} + Users: + {%- endif %}