Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow avoiding inclusion of other permissions #141

Merged
merged 1 commit into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion tests/test_api_v10.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ def test_permissions_endpoint(client):
"maintainers": ["[email protected]"],
"_testcase_regex_pattern": "^kernel-qe",
"groups": ["devel", "qa"],
"users": ["alice@example.com"],
"users": ["alice"],
},
{
"name": "Greenwave Tests",
Expand Down Expand Up @@ -928,6 +928,33 @@ def test_permissions_endpoint(client):
assert f"<td>{config['PERMISSIONS'][1]['name']}</td>" 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']
Expand Down
15 changes: 14 additions & 1 deletion waiverdb/api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -696,8 +708,9 @@ def get(self):
"name": "kernel-qe",
"maintainers": ["[email protected]"],
"testcases": ["kernel-qe.*"],
"testcases_ignore": ["kernel-qe.unwaivable.*"],
"groups": ["devel", "qa"],
"users": ["[email protected]"]
"users": ["[email protected]"],
},
{
"name": "Greenwave Tests",
Expand Down
12 changes: 8 additions & 4 deletions waiverdb/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions waiverdb/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
{% block scripts %}
{% endblock %}

<style>
tr ul { padding-left: 1rem; }
</style>
</head>

<body>
Expand Down
22 changes: 13 additions & 9 deletions waiverdb/templates/permissions.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,23 @@
{% for p in permissions -%}
<tr>
<td>{{ p["name"] }}</td>
<td>{{ p["maintainers"] | map("urlize") | join(" ") | safe }}</td>
<td>{{ p["testcases"] | join("<br />") | replace('-', '&#8209;') | safe }}</td>
<td><ul>
{%- for maintainer in p["maintainers"] %}<li>{{ maintainer | urlize }}</li>{% endfor -%}
</ul></td>
<td><ul>
{%- if p["_testcase_regex_pattern"] -%}<li><code>/{{ p["_testcase_regex_pattern"] }}/</code></li>{%- endif -%}
{%- for testcase in p["testcases_ignore"] %}<li><b>NOT</b> <code>{{ testcase }}</code></li>{% endfor -%}
{%- for testcase in p["testcases"] %}<li><code>{{ testcase }}</code></li>{% endfor -%}
</ul></td>
<td>
{% if p["groups"] | length > 0 -%}
<span class="font-weight-bold">Groups:</span><br />
{{ p["groups"] | join("<br />") | replace('-', '&#8209;') | safe }}
{% if p["users"] | length > 0 -%}
<br />
{%- endif %}
<b>Groups:</b>
<ul>{%- for group in p["groups"] %}<li>{{ group }}</li>{% endfor -%}</ul>
{%- endif %}

{% if p["users"] | length > 0 -%}
<span class="font-weight-bold">Users:</span><br />
{{ p["users"] | join("<br />") | replace('-', '&#8209;') | safe }}
<b>Users:</b>
<ul>{%- for user in p["users"] %}<li>{{ user }}</li>{% endfor -%}</ul>
{%- endif %}
</td>
</tr>
Expand Down
Loading