Replace plaintext token storage with SHA-256 hashes so leaked database contents cannot be used to authenticate. Plaintext is generated, shown once at creation time, and never persisted. - Add `hash_token()` helper and `MCPTokenManager.create_token()` that returns `(instance, plaintext)`. - Replace `token` field with indexed `token_hash`; look up bearers by hashing the incoming value. - Update dashboard, management command, and admin to surface plaintext only at creation. Disable admin "add" since it cannot reveal plaintext. - Migration drops the old `token` column and adds `token_hash`; pre-existing tokens are invalidated and must be reissued.
61 lines
2.3 KiB
HTML
61 lines
2.3 KiB
HTML
{% extends "themis/base.html" %}
|
|
|
|
{% block title %}Edit {{ token.name }} — {{ themis_app_name }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="max-w-2xl mx-auto">
|
|
<h1 class="text-2xl font-bold mb-6">Edit Token: {{ token.name }}</h1>
|
|
|
|
<div class="alert alert-info mb-6">
|
|
<span>You can edit metadata below. The token value itself cannot be changed — generate a new token if needed.</span>
|
|
</div>
|
|
|
|
<form method="post" action="{% url 'mcp_server:mcp-token-edit' pk=token.pk %}">
|
|
{% csrf_token %}
|
|
|
|
<div class="card bg-base-200 mb-6">
|
|
<div class="card-body">
|
|
<div class="form-control">
|
|
<label class="label" for="id_name">
|
|
<span class="label-text">Name</span>
|
|
</label>
|
|
{{ form.name }}
|
|
</div>
|
|
<div class="form-control mt-4">
|
|
<label class="label cursor-pointer justify-start gap-3">
|
|
{{ form.is_active }}
|
|
<span class="label-text">Active</span>
|
|
</label>
|
|
</div>
|
|
<div class="form-control mt-4">
|
|
<label class="label" for="id_expires_at">
|
|
<span class="label-text">Expires at (optional)</span>
|
|
</label>
|
|
{{ form.expires_at }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card bg-base-200 mb-6">
|
|
<div class="card-body">
|
|
<h2 class="card-title text-lg">Allowed Tools</h2>
|
|
<p class="text-sm opacity-60 mb-2">{{ form.allowed_tools.help_text }}</p>
|
|
<div class="space-y-1">
|
|
{% for choice in form.allowed_tools %}
|
|
<label class="label cursor-pointer justify-start gap-3">
|
|
{{ choice.tag }}
|
|
<span class="label-text font-mono">{{ choice.choice_label }}</span>
|
|
</label>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-between">
|
|
<a href="{% url 'mcp_server:mcp-token-detail' pk=token.pk %}" class="btn btn-ghost">Cancel</a>
|
|
<button type="submit" class="btn btn-primary">Save Changes</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
{% endblock %}
|