bitvend/bitvend/admin.py

111 lines
2.5 KiB
Python

import time
from six import wraps
from flask import (
Blueprint,
render_template,
redirect,
request,
flash,
url_for,
session,
abort,
current_app,
)
from flask_login import current_user, fresh_login_required
from bitvend import dev, spaceauth
from bitvend.models import db, Transaction
from sqlalchemy import func
from bitvend.forms import ManualForm
from spaceauth import cap_required
def get_user_groups():
groups = session.get("groups", [])
groups_uid = session.get("groups_uid", "")
groups_ts = session.get("groups_ts", 0)
if not groups or groups_uid != current_user.uid or time.time() - groups_ts >= 60.0:
resp = spaceauth.remote.get("/api/1/userinfo")
groups = resp.data.get("groups")
session["groups"] = groups
session["groups_ts"] = time.time()
session["groups_uid"] = current_user.uid
return session["groups"]
# Checks if user is a member of vending-admin group
def admin_required(fn):
@wraps(fn)
def wrapped(*args, **kwargs):
groups = get_user_groups()
if not groups:
return current_app.login_manager.unauthorized()
if "vending-admin" not in groups:
abort(403)
return fn(*args, **kwargs)
return wrapped
bp = Blueprint("admin", __name__)
@bp.route("/")
@fresh_login_required
@admin_required
def admin_index():
return redirect(url_for("admin.manual"))
@bp.route("/manual/", methods=["GET", "POST"])
@fresh_login_required
@admin_required
def manual():
form = ManualForm()
if form.validate_on_submit():
current_user.transactions.append(Transaction(amount=form.amount.data))
db.session.commit()
flash("Operation successful.", "success")
return render_template(
"admin/manual.html",
form=form,
summary=db.session.query(func.sum(Transaction.amount))
.filter(Transaction.uid != "__bitcoin__")
.scalar(),
)
@bp.route("/transactions/", defaults={"page": 1})
@bp.route("/transactions/p/<int:page>")
@fresh_login_required
@admin_required
def transactions(page):
return render_template(
"admin/transactions.html", transactions=Transaction.query.paginate(page)
)
@bp.route("/begin")
@fresh_login_required
@admin_required
def begin():
dev.begin_session(500)
flash("Operation successful.", "success")
return redirect("/")
@bp.route("/cancel")
@fresh_login_required
@admin_required
def cancel():
dev.cancel_session()
flash("Operation successful.", "success")
return redirect("/")