atr/templates/keys-add.html (122 lines of code) (raw):
{% extends "layouts/base.html" %}
{% block title %}
Add your GPG key ~ ATR
{% endblock title %}
{% block description %}
Add your public signing key to your ATR account.
{% endblock description %}
{% block content %}
<p>
<a href="{{ as_url(routes.keys.keys) }}" class="atr-back-link">← Back to Manage keys</a>
</p>
<div class="my-4">
<h1 class="mb-4">Add your GPG key</h1>
<p>Add your public key to use for signing release artifacts.</p>
{% if form.errors %}<div class="alert alert-danger">Please correct the errors below:</div>{% endif %}
<form method="post"
class="atr-canary py-4 px-5"
action="{{ as_url(routes.keys.add) }}"
novalidate>
{{ form.hidden_tag() if form.hidden_tag }}
<div class="mb-4">
<div class="row mb-3 pb-3 border-bottom">
<div class="col-md-2 text-md-end fw-medium pt-2">{{ form.public_key.label }}</div>
<div class="col-md-9">
{{ form.public_key(class_='form-control font-monospace', rows=10, placeholder='Paste your ASCII-armored public GPG key here...') }}
<small class="form-text text-muted">
Your public key should be in ASCII-armored format, starting with:
<br />
"-----BEGIN PGP PUBLIC KEY BLOCK-----"
</small>
{% if form.public_key.errors %}
<div class="invalid-feedback d-block">
{% for error in form.public_key.errors %}{{ error }}{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="row mb-3 pb-3 border-bottom">
<div class="col-md-2 text-md-end fw-medium pt-2">{{ form.selected_committees.label }}</div>
<div class="col-md-9">
<div class="row">
{% for subfield in form.selected_committees %}
<div class="col-sm-12 col-md-6 col-lg-4">
<div class="form-check mb-2">
{{ subfield(class_='form-check-input') }}
{{ subfield.label(class_='form-check-label') }}
</div>
</div>
{% endfor %}
</div>
<div class="mt-2 mb-2">
<button type="button"
id="toggleCommitteesBtn"
class="btn btn-sm btn-outline-secondary">Select all</button>
</div>
<small class="form-text text-muted">Select the committees with which to associate your key.</small>
{% if form.selected_committees.errors %}
<div class="invalid-feedback d-block">
{% for error in form.selected_committees.errors %}{{ error }}{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<div class="mt-4 col-md-9 offset-md-2">
{{ form.submit(class_='btn btn-primary') }}
<a href="{{ as_url(routes.keys.keys) }}"
class="btn btn-link text-secondary">Cancel</a>
</div>
</form>
{% if key_info and key_info.status == 'success' %}
<div class="mt-5">
<h2 class="mb-3 fs-5">Key details added:</h2>
<div class="p-3 bg-light border rounded">
<p>
<strong>Key ID:</strong> {{ key_info.key_id }}
<br />
<strong>Fingerprint:</strong> <code>{{ key_info.fingerprint }}</code>
<br />
<strong>User ID:</strong> {{ key_info.user_id }}
<br />
<strong>Created:</strong> {{ key_info.creation_date.strftime("%Y-%m-%d") }}
<br />
<strong>Expires:</strong> {{ key_info.expiration_date.strftime("%Y-%m-%d") if key_info.expiration_date else 'Never' }}
</p>
</div>
</div>
{% endif %}
</div>
{% endblock content %}
{% block javascripts %}
{{ super() }}
<script>
document.addEventListener("DOMContentLoaded", () => {
const btn = document.getElementById("toggleCommitteesBtn");
const checkboxes = document.querySelectorAll("input[name='selected_committees']");
if (!btn || checkboxes.length === 0) return;
function updateButtonText() {
let allChecked = true;
checkboxes.forEach(cb => {
if (!cb.checked) allChecked = false;
});
btn.textContent = allChecked ? "Select none" : "Select all";
}
btn.addEventListener("click", () => {
let allChecked = true;
checkboxes.forEach(cb => {
if (!cb.checked) allChecked = false;
});
const shouldCheck = !allChecked;
checkboxes.forEach(cb => {
cb.checked = shouldCheck;
});
updateButtonText();
});
checkboxes.forEach(cb => {
cb.addEventListener("change", updateButtonText);
});
updateButtonText();
});
</script>
{% endblock javascripts %}