mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
The REST API took only the login session, so a script could not use it without a browser. A user now makes API tokens on the profile page (API Tokens tab): a name, and an expiry of 30, 90 or 365 days or none. The token is shown once, on a page that is not cached, and then kept only as a SHA-512 digest; the list shows its name, first characters, creation and expiry, and a token is deleted there. Tools send it as "Authorization: Token wvc_...", and act as its user, with that user's permissions. Making and deleting a token is logged, without the token. A password alone (HTTP Basic) still does not reach the API, as it would skip the OTP second factor: a token is made in a session that passed the login and its OTP. The token class comes first, so a refused request gets 401 with its challenge instead of 403. django-rest-knox 5.1.0 provides the tokens (accounts.ApiToken adds the name); settings.py takes "knox", KNOX_TOKEN_MODEL and REST_KNOX from the template.
16 lines
936 B
HTML
16 lines
936 B
HTML
{% extends "base.html" %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% trans "API token created" %}{% endblock %}
|
|
{% block page_heading %}{% trans "API token created" %}: {{ name }}{% endblock page_heading %}
|
|
|
|
{% block content %}
|
|
<div class="alert alert-warning" role="alert">
|
|
{% trans "Copy the token now: it is not shown again. Anyone who has it can use the REST API as you." %}
|
|
</div>
|
|
<label class="form-label" for="api-token">{% trans "Token" %}</label>
|
|
<input type="text" class="form-control font-monospace mb-3" id="api-token" value="{{ key }}" readonly>
|
|
<p>{% trans "Use it like this:" %}</p>
|
|
<pre class="bg-body-tertiary p-2 text-break" style="white-space: pre-wrap"><code>curl -H "Authorization: Token {{ key }}" {{ request.scheme }}://{{ request.get_host }}{% url 'instance-list' %}</code></pre>
|
|
<a class="btn btn-primary" href="{% url 'accounts:profile' %}#apitokens">{% trans "Back to the profile" %}</a>
|
|
{% endblock content %}
|