Skip to content

Commit

Permalink
Better target info display
Browse files Browse the repository at this point in the history
  • Loading branch information
np5 committed Sep 4, 2024
1 parent 5ddd461 commit dddb9a7
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 72 deletions.
253 changes: 184 additions & 69 deletions zentral/contrib/santa/templates/santa/target_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<li class="breadcrumb-item active">{{ target_type_display }}</li>
</ol>


<div class="object-details">
<div class="d-flex align-items-center mb-1">
<h2 class="m-0">{{ title }}</h2>
Expand All @@ -29,87 +30,201 @@ <h2 class="m-0">{{ title }}</h2>
<td><code>{{ identifier }}</code></td>
</tr>
<tr>
<td>Related targets</td>
<td>Info</td>
<td>
{% for target_type, target_type_display, target_infos in related_targets %}
<p>{{ target_type_display }}</p>
<ul>
{% for target_info in target_infos %}
<li>
<a href="{{ target_info.url }}"><code>{{ target_info.identifier }}</code></a>
{% for obj_str in target_info.obj_strings %}
<br>{{ obj_str }}
{% if prepared_objects %}
<table class="table table-sm">
<thead>
<tr>
{% for col in prepared_objects.cols %}
<th width="{{ prepared_objects.width }}%">{{ col }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in prepared_objects.rows %}
<tr>
{% for val in row %}
<td>{{ val|default:"-" }}</td>
{% endfor %}
</tr>
{% endfor %}
</li>
{% endfor %}
</ul>
{% endfor %}
</tbody>
</table>
{% else %}
-
{% endif %}
</td>
</tr>
</tbody>
<tr>
<tbody>
</table>
</div>

{% if show_ballots %}
<div class="d-flex align-items-center mb-3">
<h3 class="m-0">Ballot{{ ballot_count|pluralize }} ({{ ballot_count }})</h3>
<div class="ms-auto">
<ul class="nav nav-tabs" id="target-tabs" role="tablist">
{% if show_ballots %}
<li class="nav-item" role="presentation">
<button class="nav-link{% if show_ballots %} active{% endif %}"
id="ballots-tab"
data-bs-toggle="tab" data-bs-target="#ballots-tab-pane"
type="button" role="tab"
aria-controls="ballots-tab-pane"
aria-selected="true">
Ballot{{ ballot_count|pluralize }} ({{ ballot_count }})
</button>
</li>
{% endif %}
<li class="nav-item" role="presentation">
<button class="nav-link{% if not show_ballots %} active{% endif %}"
id="related-targets-tab"
data-bs-toggle="tab" data-bs-target="#related-targets-tab-pane"
type="button" role="tab"
aria-controls="related-targets-tab-pane"
aria-selected="{% if not show_ballots %}true{% else %}false{% endif %}">
Related target{{ total_related_targets|pluralize }} ({{ total_related_targets }})
</button>
</li>
{% if show_rules %}
<li class="nav-item" role="presentation">
<button class="nav-link"
id="rules-tab"
data-bs-toggle="tab" data-bs-target="#rules-tab-pane"
type="button" role="tab"
aria-controls="rules-tab-pane"
aria-selected="false">
Rule{{ rule_count|pluralize }} ({{ rule_count }})
</button>
</li>
{% endif %}
</ul>

<div class="tab-content">

{% if show_ballots %}
<div class="tab-pane fade show active"
id="ballots-tab-pane" role="tabpanel"
aria-labelledby="ballots-tab" tabindex="0">

<p class="mt-2 mb-2">
{% if cast_ballot_url %}
<a class="btn btn-link" href="{{ cast_ballot_url }}">
<i class="bi bi-plus-circle"></i>
<a class="btn btn-outline-secondary" href="{{ cast_ballot_url }}">
Cast a ballot
</a>
{% else %}
You cannot vote on this target
{% endif %}
</div>
</div>
{% include "santa/_ballot_list.html" %}
{% endif %}
</p>

{% if show_rules %}
<div class="d-flex align-items-center mb-3">
<h3 class="m-0">Rule{{ rule_count|pluralize }} ({{ rule_count }})</h3>
<div class="ms-auto">
{% if perms.santa.add_rule and add_rule_links %}
<button class="btn btn-link dropdown-toggle" type="button"
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" id="createRule">
<i class="bi bi-plus-circle"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="createRule">
{% for text, url in add_rule_links %}
<li><a class="dropdown-item" href="{{ url }}">{{ text }}</a></li>
{% include "santa/_ballot_list.html" %}
</div>
{% endif %}

<div class="tab-pane fade{% if not show_ballots %} show active{% endif %}"
id="related-targets-tab-pane" role="tabpanel"
aria-labelledby="related-targets-tab" tabindex="1">

<table class="table table-striped align-top">
<thead>
<tr>
<th>Type</th>
<th>Identifier</th>
<th style="width:60%">Info</th>
</tr>
</thead>
<tbody>
{% for target_type, target_type_display, target_infos in related_targets %}
{% for target_info in target_infos %}
<tr>
<td>{{ target_type_display }}</td>
<td>
<a href="{{ target_info.url }}"><code>{{ target_info.identifier }}</code></a>
</td>
<td>
{% if target_info.prepared_objects %}
<table class="table table-sm">
<thead>
<tr>
{% for col in target_info.prepared_objects.cols %}
<th width="{{ target_info.prepared_objects.width }}%">{{ col }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in target_info.prepared_objects.rows %}
<tr>
{% for val in row %}
<td style="overflow:hidden;white-space:nowrap;text-overflow:ellipsis;max-width:0">{{ val|default:"-" }}</td>
{% endfor %}
</tr>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</tbody>
</table>
{% else %}
-
{% endif %}
</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>

{% if show_rules %}
<div class="tab-pane fade"
id="rules-tab-pane" role="tabpanel"
aria-labelledby="rules-tab" tabindex="2">

{% if rule_count %}
<table class="table table-striped align-middle">
<thead>
<th>Configuration</th>
<th>Ruleset</th>
<th>Policy</th>
</thead>
<tbody>
{% for rule in rules %}
<tr>
<td>
{% if perms.santa.view_rule %}
<a href="{{ rule.get_absolute_url }}">{{ rule.configuration }}</a>
{% else %}
{{ rule.configuration }}
{% endif %}
</td>
<td>{{ rule.ruleset|default:"-" }}</td>
<td>
<span class="label label-{% if rule.is_blocking_rule %}danger{% else %}success{% endif %}">
{{ rule.get_policy_display }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endif %}
{% if perms.santa.add_rule and add_rule_links %}
<p class="mt-2">
<div class="dropdown">
<button class="btn btn-outline-secondary dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"
id="createRule">
Create a rule
</button>
<ul class="dropdown-menu" aria-labelledby="createRule">
{% for text, url in add_rule_links %}
<li><a class="dropdown-item" href="{{ url }}">{{ text }}</a></li>
{% endfor %}
</ul>
</div>
</p>
{% endif %}

{% if rule_count %}
<table class="table table-striped align-middle">
<thead>
<th>Configuration</th>
<th>Ruleset</th>
<th>Policy</th>
</thead>
<tbody>
{% for rule in rules %}
<tr>
<td>
{% if perms.santa.view_rule %}
<a href="{{ rule.get_absolute_url }}">{{ rule.configuration }}</a>
{% else %}
{{ rule.configuration }}
{% endif %}
</td>
<td>{{ rule.ruleset|default:"-" }}</td>
<td>
<span class="label label-{% if rule.is_blocking_rule %}danger{% else %}success{% endif %}">
{{ rule.get_policy_display }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
{% endif %}

</div>

{% endblock %}
25 changes: 22 additions & 3 deletions zentral/contrib/santa/views/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def get_add_rule_links(self):
return links
for configuration in (Configuration.objects.exclude(rule__target__type=self.target_type,
rule__target__identifier=self.identifier)
.exclude(voting_realm__isnull=False)
.order_by("name")):
links.append((configuration.name,
reverse("santa:create_configuration_rule", args=(configuration.pk,)) + f"?{query_dict}"))
Expand All @@ -133,8 +134,23 @@ def get_context_data(self, **kwargs):
ballot_box = BallotBox.for_realm_user(target, realm_user, lock_target=False, all_configurations=True)
ctx["ballot_box"] = ballot_box

def prepare_objects(objects):
keys = set()
for obj in objects:
keys.update((k, k.replace("_", " ")) for k in obj.keys())
keys = sorted(keys)
return {"width": 100 / len(keys),
"cols": [l for _, l in keys],
"rows": [[obj.get(k) for k, l in keys] for obj in objects]}

try:
ctx["prepared_objects"] = prepare_objects(ballot_box.target_info()["objects"])
except (TypeError, KeyError):
pass

# related targets
ctx["related_targets"] = []
total_related_targets = 0
for target_type in Target.Type:
related_targets = ballot_box.related_targets.get(target_type.value, {})
if not related_targets:
Expand All @@ -144,12 +160,15 @@ def get_context_data(self, **kwargs):
for identifier in sorted(related_targets.keys())
if not related_targets[identifier]["self"]
]
total_related_targets += len(target_infos)
for target_info in target_infos:
for obj in target_info["objects"]:
obj_str = ", ".join(f"{k}: {obj[k]}" for k in sorted(obj.keys()))
target_info.setdefault("obj_strings", []).append(obj_str)
try:
target_info["prepared_objects"] = prepare_objects(target_info["objects"])
except KeyError:
pass
if target_infos:
ctx["related_targets"].append((target_type.value, target_type.label, target_infos))
ctx["total_related_targets"] = total_related_targets

# objects
self.objects = self.get_objects()
Expand Down

0 comments on commit dddb9a7

Please sign in to comment.