Add switch user admin tool

This commit is contained in:
rubenwardy 2018-05-13 15:28:27 +01:00
parent 9f33f5fb1b
commit e372bb810d
No known key found for this signature in database
GPG Key ID: A1E29D52FF81513C
6 changed files with 130 additions and 56 deletions

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% block title %}
Admin Tools
{% endblock %}
{% block content %}
<ul>
<a href="{{ url_for('switch_user_page') }}">Sign in as another user</a>
</ul>
{% endblock %}

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block title %}
Switch User
{% endblock %}
{% block content %}
{% from "macros/forms.html" import render_field, render_submit_field %}
<form method="POST" action="">
{{ form.hidden_tag() }}
{{ render_field(form.username) }}
{{ render_submit_field(form.submit) }}
</form>
{% endblock %}

@ -30,4 +30,4 @@ def home_page():
packages = Package.query.filter_by(approved=True).all() packages = Package.query.filter_by(approved=True).all()
return render_template("index.html", packages=packages) return render_template("index.html", packages=packages)
from . import users, githublogin, packages, sass, tasks from . import users, githublogin, packages, sass, tasks, admin

37
app/views/admin.py Normal file

@ -0,0 +1,37 @@
from flask import *
from flask_user import *
from flask.ext import menu
from app import app
from app.models import *
from flask_wtf import FlaskForm
from wtforms import *
from .utils import loginUser, rank_required
@menu.register_menu(app, ".admin", "Admin", order=30,
visible_when=lambda: current_user.rank.atLeast(UserRank.ADMIN))
@app.route("/admin/")
@rank_required(UserRank.ADMIN)
def admin_page():
return render_template("admin/list.html")
class SwitchUserForm(FlaskForm):
username = StringField("Username")
submit = SubmitField("Switch")
@app.route("/admin/switchuser/", methods=["GET", "POST"])
@rank_required(UserRank.ADMIN)
def switch_user_page():
form = SwitchUserForm(formdata=request.form)
if request.method == "POST" and form.validate():
user = User.query.filter_by(username=form["username"].data).first()
if user is None:
flash("Unable to find user", "error")
elif loginUser(user):
return redirect(url_for("user_profile_page", username=current_user.username))
else:
flash("Unable to login as user", "error")
# Process GET or invalid POST
return render_template("admin/switch_user_page.html", form=form)

@ -5,63 +5,12 @@ import flask_menu as menu
from flask_github import GitHub from flask_github import GitHub
from app import app, github from app import app, github
from app.models import * from app.models import *
from .utils import loginUser
@app.route("/user/github/start/") @app.route("/user/github/start/")
def github_signin_page(): def github_signin_page():
return github.authorize("") return github.authorize("")
def _do_login_user(user, remember_me=False):
def _call_or_get(v):
if callable(v):
return v()
else:
return v
# User must have been authenticated
if not user:
return False
user.active = True
if not user.rank.atLeast(UserRank.NEW_MEMBER):
user.rank = UserRank.NEW_MEMBER
db.session.commit()
# Check if user account has been disabled
if not _call_or_get(user.is_active):
flash("Your account has not been enabled.", "error")
return False
# Check if user has a confirmed email address
user_manager = current_app.user_manager
if user_manager.enable_email and user_manager.enable_confirm_email \
and not current_app.user_manager.enable_login_without_confirm_email \
and not user.has_confirmed_email():
url = url_for("user.resend_confirm_email")
flash("Your email address has not yet been confirmed", "error")
return False
# Use Flask-Login to sign in user
login_user(user, remember=remember_me)
signals.user_logged_in.send(current_app._get_current_object(), user=user)
flash("You have signed in successfully.", "success")
return True
def _login_user(user):
user_mixin = None
if user_manager.enable_username:
user_mixin = user_manager.find_user_by_username(user.username)
return _do_login_user(user_mixin, False)
@app.route("/user/github/callback/") @app.route("/user/github/callback/")
@github.authorized_handler @github.authorized_handler
def github_authorized(oauth_token): def github_authorized(oauth_token):
@ -99,12 +48,12 @@ def github_authorized(oauth_token):
db.session.add(newUser) db.session.add(newUser)
db.session.commit() db.session.commit()
if not _login_user(newUser): if not loginUser(newUser):
raise Exception("Unable to login as user we just created") raise Exception("Unable to login as user we just created")
flash("Created an account", "success") flash("Created an account", "success")
return redirect(url_for("user_profile_page", username=username)) return redirect(url_for("user_profile_page", username=username))
elif _login_user(userByGithub): elif loginUser(userByGithub):
return redirect(next_url or url_for("home_page")) return redirect(next_url or url_for("home_page"))
else: else:
flash("Authorization failed [err=gh-login-failed]", "danger") flash("Authorization failed [err=gh-login-failed]", "danger")

@ -1,4 +1,7 @@
from flask import request, flash from flask import request, flash, abort
from flask_user import *
from flask_login import login_user, logout_user
from app.models import *
from app import app from app import app
import random, string, os import random, string, os
@ -29,3 +32,62 @@ def doFileUpload(file, allowedExtensions, fileTypeName):
filename = randomString(10) + "." + ext filename = randomString(10) + "." + ext
file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename)) file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename))
return "/uploads/" + filename return "/uploads/" + filename
def _do_login_user(user, remember_me=False):
def _call_or_get(v):
if callable(v):
return v()
else:
return v
# User must have been authenticated
if not user:
return False
user.active = True
if not user.rank.atLeast(UserRank.NEW_MEMBER):
user.rank = UserRank.NEW_MEMBER
db.session.commit()
# Check if user account has been disabled
if not _call_or_get(user.is_active):
flash("Your account has not been enabled.", "error")
return False
# Check if user has a confirmed email address
user_manager = current_app.user_manager
if user_manager.enable_email and user_manager.enable_confirm_email \
and not current_app.user_manager.enable_login_without_confirm_email \
and not user.has_confirmed_email():
url = url_for("user.resend_confirm_email")
flash("Your email address has not yet been confirmed", "error")
return False
# Use Flask-Login to sign in user
login_user(user, remember=remember_me)
signals.user_logged_in.send(current_app._get_current_object(), user=user)
flash("You have signed in successfully.", "success")
return True
def loginUser(user):
user_mixin = None
if user_manager.enable_username:
user_mixin = user_manager.find_user_by_username(user.username)
return _do_login_user(user_mixin, False)
def rank_required(rank):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.rank.atLeast(rank):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator