From 74b89b1b7e519720498d6deba3e6ed5b470c70f6 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 8 Aug 2020 13:41:18 +0000 Subject: [PATCH] Add API Key to the UI --- powerdnsadmin/routes/admin.py | 123 +++++++++++++ powerdnsadmin/templates/admin_edit_key.html | 168 ++++++++++++++++++ .../templates/admin_manage_keys.html | 131 ++++++++++++++ powerdnsadmin/templates/base.html | 3 + 4 files changed, 425 insertions(+) create mode 100644 powerdnsadmin/templates/admin_edit_key.html create mode 100644 powerdnsadmin/templates/admin_manage_keys.html diff --git a/powerdnsadmin/routes/admin.py b/powerdnsadmin/routes/admin.py index e56778e..ba3968d 100644 --- a/powerdnsadmin/routes/admin.py +++ b/powerdnsadmin/routes/admin.py @@ -1,6 +1,7 @@ import json import datetime import traceback +from base64 import b64encode from ast import literal_eval from flask import Blueprint, render_template, make_response, url_for, current_app, request, redirect, jsonify, abort, flash, session from flask_login import login_required, current_user @@ -17,6 +18,11 @@ from ..models.domain import Domain from ..models.record import Record from ..models.domain_template import DomainTemplate from ..models.domain_template_record import DomainTemplateRecord +from ..models.api_key import ApiKey + +from ..lib.schema import ApiPlainKeySchema + +apikey_plain_schema = ApiPlainKeySchema(many=True) admin_bp = Blueprint('admin', __name__, @@ -127,6 +133,123 @@ def edit_user(user_username=None): create=create, error=result['msg']) +@admin_bp.route('/key/edit/', methods=['GET', 'POST']) +@admin_bp.route('/key/edit', methods=['GET', 'POST']) +@login_required +@operator_role_required +def edit_key(key_id=None): + domains = Domain.query.all() + roles = Role.query.all() + apikey = None + create = True + plain_key = None + + if key_id: + apikey = ApiKey.query.filter(ApiKey.id == key_id).first() + create = False + + if not apikey: + return render_template('errors/404.html'), 404 + + if request.method == 'GET': + return render_template('admin_edit_key.html', + key=apikey, + domains=domains, + roles=roles, + create=create) + + if request.method == 'POST': + fdata = request.form + description = fdata['description'] + role = fdata.getlist('key_role')[0] + doamin_list = fdata.getlist('key_multi_domain') + + # Create new apikey + if create: + domain_obj_list = Domain.query.filter(Domain.name.in_(doamin_list)).all() + apikey = ApiKey(desc=description, + role_name=role, + domains=domain_obj_list) + try: + apikey.create() + except Exception as e: + current_app.logger.error('Error: {0}'.format(e)) + raise ApiKeyCreateFail(message='Api key create failed') + + plain_key = apikey_plain_schema.dump([apikey])[0]["plain_key"] + plain_key = b64encode(plain_key.encode('utf-8')).decode('utf-8') + history_message = "Created API key {0}".format(apikey.id) + + # Update existing apikey + else: + try: + apikey.update(role,description,doamin_list) + history_message = "Updated API key {0}".format(apikey.id) + except Exception as e: + current_app.logger.error('Error: {0}'.format(e)) + + history = History(msg=history_message, + detail=str({ + 'key': apikey.id, + 'role': apikey.role.name, + 'description': apikey.description, + 'domain_acl': [domain.name for domain in apikey.domains] + }), + created_by=current_user.username) + history.add() + + return render_template('admin_edit_key.html', + key=apikey, + domains=domains, + roles=roles, + create=create, + plain_key=plain_key) + +@admin_bp.route('/manage-keys', methods=['GET', 'POST']) +@login_required +@operator_role_required +def manage_keys(): + if request.method == 'GET': + try: + apikeys = ApiKey.query.all() + except Exception as e: + current_app.logger.error('Error: {0}'.format(e)) + abort(500) + + return render_template('admin_manage_keys.html', + keys=apikeys) + + elif request.method == 'POST': + jdata = request.json + if jdata['action'] == 'delete_key': + + apikey = ApiKey.query.get(jdata['data']) + try: + history_apikey_id = apikey.id + history_apikey_role = apikey.role.name + history_apikey_description = apikey.description + history_apikey_domains = [ domain.name for domain in apikey.domains] + + apikey.delete() + except Exception as e: + current_app.logger.error('Error: {0}'.format(e)) + + current_app.logger.info('Delete API key {0}'.format(apikey.id)) + history = History(msg='Delete API key {0}'.format(apikey.id), + detail=str({ + 'key': history_apikey_id, + 'role': history_apikey_role, + 'description': history_apikey_description, + 'domains': history_apikey_domains + }), + created_by=current_user.username) + history.add() + + return make_response( + jsonify({ + 'status': 'ok', + 'msg': 'Key has been removed.' + }), 200) @admin_bp.route('/manage-user', methods=['GET', 'POST']) @login_required diff --git a/powerdnsadmin/templates/admin_edit_key.html b/powerdnsadmin/templates/admin_edit_key.html new file mode 100644 index 0000000..f1a33a0 --- /dev/null +++ b/powerdnsadmin/templates/admin_edit_key.html @@ -0,0 +1,168 @@ +{% extends "base.html" %} +{% set active_page = "admin_keys" %} +{% block title %} +Edit Key - {{ SITE_NAME }} +{% endblock %} +{% block dashboard_stat %} + +
+

+ Key + {% if create %}New key{% else %}{{ key.id }}{% endif %} +

+ +
+{% endblock %} + +{% block content %} +
+
+
+
+
+

{% if create %}Add{% else %}Edit{% endif %} key

+
+ + +
+ + +
+
+ + +
+
+ + +
+
+
+

Access Control

+
+
+

This key will have acess to the domains on the right.

+

Click on domains to move between the columns.

+
+ +
+
+ +
+
+
+
+
+
+

Help with {% if create %}creating a new{% else%}updating a{% endif %} key +

+
+
+

Fill in all the fields in the form to the left.

+

Role The role of the key.

+

Description The key description.

+

Access Control The domains which the key has access to.

+
+
+
+
+
+{% endblock %} +{% block extrascripts %} + +{% endblock %} +{% block modals %} + +{% endblock %} \ No newline at end of file diff --git a/powerdnsadmin/templates/admin_manage_keys.html b/powerdnsadmin/templates/admin_manage_keys.html new file mode 100644 index 0000000..215c3d8 --- /dev/null +++ b/powerdnsadmin/templates/admin_manage_keys.html @@ -0,0 +1,131 @@ +{% extends "base.html" %} +{% set active_page = "admin_keys" %} +{% block title %} +Key Management - {{ SITE_NAME }} +{% endblock %} {% block dashboard_stat %} +
+

+ Key Manage API keys +

+ +
+{% endblock %} {% block content %} +
+
+
+
+
+

Key Management

+
+ +
+ + + + + + + + + + + + {% for key in keys %} + + + + + + + + {% endfor %} + +
IdRoleDescriptionDomainsAction
{{ key.id }}{{ key.role.name }}{{ key.description }}{% for domain in key.domains %}{{ domain.name }}{% if not loop.last %}, {% endif %}{% endfor %} + + +
+
+ +
+ +
+ +
+ +
+{% endblock %} +{% block extrascripts %} + +{% endblock %} +{% block modals %} + +{% endblock %} diff --git a/powerdnsadmin/templates/base.html b/powerdnsadmin/templates/base.html index ca1839e..21b542d 100644 --- a/powerdnsadmin/templates/base.html +++ b/powerdnsadmin/templates/base.html @@ -132,6 +132,9 @@
  • Users
  • +
  • + API Keys +
  • Settings