from flask import ( Blueprint, flash, g, redirect, render_template, request, url_for ) from werkzeug.exceptions import abort from servecerts.auth import login_required from servecerts.db import get_db import hashlib import base64 #bp = Blueprint('pubkeys', __name__, url_prefix='/pubkeys') bp = Blueprint('pubkeys', __name__, url_prefix='/pubkeys') @bp.route('/') @login_required def index(): db = get_db() pubkeys = db.execute( 'SELECT' ' p.id, key_name, fullname, ssh_pubkey, p.created, user_id, revoked, deleted' ' FROM pubkeys p' ' JOIN user u ON p.user_id = u.id' ' ORDER BY deleted ASC, revoked ASC, p.created DESC' ).fetchall() users = db.execute( 'SELECT * FROM user WHERE id = ?', (g.user['id'],) ).fetchone() return render_template('pubkeys/index.html', pubkeys=pubkeys, users=users) def get_pubkey(id, check_user=True): pubkey = get_db().execute( 'SELECT p.id, ssh_pubkey, key_name, user_id, fingerprint, deleted' ' FROM pubkeys p JOIN user u ON p.user_id = u.id' ' WHERE p.id = ?', (id,) ).fetchone() if pubkey is None: abort(404, "Pubkey id {0} does not exist.".format(id)) if check_user and pubkey['user_id'] != g.user['id']: abort(403) return pubkey @bp.route('/create', methods=('GET', 'POST')) @login_required def create(): if request.method == 'POST': key_name = request.form['key_name'] ssh_pubkey = request.form['ssh_pubkey'] splitkey = ssh_pubkey.split(' ') enc = splitkey.pop(0) key = splitkey.pop(0) comment = ' '.join(splitkey) fingerprint = base64.b64encode(hashlib.sha256(base64.b64decode(key)).digest()).rstrip("=") print fingerprint db = get_db() ckfp = db.execute( 'SELECT id, fingerprint, deleted FROM pubkeys WHERE fingerprint = ?', (fingerprint, ) ).fetchone() if ckfp != None: if ckfp['fingerprint'] == fingerprint: if ckfp['deleted'] == 0: error = "Key exists already" else: error = "Key was deleted before -> reactivate it again!" flash(error) return redirect(url_for('pubkeys.update', id=ckfp['id'])) if not key_name: key_name = comment error = None if not ssh_pubkey: error = 'SSH-Pubkey is required.' if error is not None: flash(error) else: #db = get_db() db.execute( 'INSERT INTO pubkeys (ssh_pubkey, key_name, user_id, fingerprint)' ' VALUES (?, ?, ?, ?)', (ssh_pubkey, key_name, g.user['id'], fingerprint) ) db.commit() return redirect(url_for('pubkeys.index')) return render_template('pubkeys/create.html') @bp.route('//update', methods=('GET', 'POST')) @login_required def update(id): pubkey = get_pubkey(id) if request.method == 'POST': key_name = request.form['key_name'] deleted = request.form.get('deleted') error = None if not key_name: error = 'Key-ID is required.' deleted = 0 if not deleted else 1 # if not ssh_pubkey: # error = "SSH-Pubkey is requred." if error is not None: flash(error) else: db = get_db() db.execute( 'UPDATE pubkeys SET key_name = ?, deleted = ?' ' WHERE id = ?', (key_name, deleted, id) ) db.commit() return redirect(url_for('pubkeys.index')) return render_template('pubkeys/update.html', pubkey=pubkey) @bp.route('//delete', methods=('GET',)) @login_required def delete(id): get_pubkey(id) db = get_db() #db.execute('DELETE FROM pubkeys WHERE id = ?', (id,)) db.execute('UPDATE pubkeys SET deleted = 1 WHERE id = ?', (id,)) db.execute('UPDATE certificates SET deleted = 1 WHERE pubkey_id = ?', (id,)) db.commit() return redirect(url_for('pubkeys.index')) @bp.route('//deletefinal', methods=('GET',)) @login_required def deletefinal(id): get_pubkey(id) db = get_db() db.execute('DELETE FROM pubkeys WHERE id = ?', (id,)) #db.execute('UPDATE certificates SET deleted = 1 WHERE pubkey_id = ?', (id,)) db.commit() return redirect(url_for('pubkeys.index')) @bp.route('//revoke', methods=('POST', 'GET')) @login_required def revoke(id): get_pubkey(id) db = get_db() db.execute( 'UPDATE pubkeys SET revoked = 1' ' WHERE id = ?', (id,) ) db.commit() return redirect(url_for('pubkeys.index'))