1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 10:37:23 +00:00

Fix: admin functions were accessible for regular users

This commit is contained in:
Jan Broer 2015-10-13 18:07:17 +02:00
parent 0f7c129495
commit 6b4ddbe946
3 changed files with 80 additions and 29 deletions

View File

@ -3,17 +3,17 @@
<div class="well col-sm-6 col-sm-offset-2"> <div class="well col-sm-6 col-sm-offset-2">
<h2 style="margin-top: 0">Register a new account</h2> <h2 style="margin-top: 0">Register a new account</h2>
<form method="POST" role="form"> <form method="POST" role="form">
<div class="form-group"> <div class="form-group required">
<label for="nickname">Username</label> <label for="nickname">Username</label>
<input type="text" class="form-control" id="nickname" name="nickname" placeholder="Choose a username"> <input type="text" class="form-control" id="nickname" name="nickname" placeholder="Choose a username" required>
</div> </div>
<div class="form-group"> <div class="form-group required">
<label for="password">Password</label> <label for="password">Password</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Choose a password"> <input type="password" class="form-control" id="password" name="password" placeholder="Choose a password" required>
</div> </div>
<div class="form-group"> <div class="form-group required">
<label for="email">Email address</label> <label for="email">Email address</label>
<input type="email" class="form-control" id="email" name="email" placeholder="Your email address"> <input type="email" class="form-control" id="email" name="email" placeholder="Your email address" required>
</div> </div>
<button type="submit" class="btn btn-primary">Register</button> <button type="submit" class="btn btn-primary">Register</button>
</form> </form>

View File

@ -3,27 +3,31 @@
<div class="discover"> <div class="discover">
<h1>{{title}}</h1> <h1>{{title}}</h1>
<form role="form" method="POST"> <form role="form" method="POST">
{% if g.user and g.user.role and new_user %}
<div class="form-group required">
<label for="nickname">Username</label>
<input type="text" class="form-control" name="nickname" id="nickname" value="{{ content.nickname if content.nickname != None }}">
</div>
{% endif %}
<div class="form-group"> <div class="form-group">
<label for="email">e-mail</label> <label for="email">Email address</label>
<input type="email" class="form-control" name="email" id="email" value="{{ content.email if content.email != None }}"> <input type="email" class="form-control" name="email" id="email" value="{{ content.email if content.email != None }}" required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">password</label> <label for="password">Password</label>
<input type="password" class="form-control" name="password" id="password" value=""> <input type="password" class="form-control" name="password" id="password" value="">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="kindle_mail">Kindle E-Mail</label> <label for="kindle_mail">Kindle E-Mail</label>
<input type="text" class="form-control" name="kindle_mail" id="kindle_mail" value="{{ content.kindle_mail if content.kindle_mail != None }}"> <input type="text" class="form-control" name="kindle_mail" id="kindle_mail" value="{{ content.kindle_mail if content.kindle_mail != None }}">
</div> </div>
{% if g.user and g.user.role %} {% if g.user and g.user.role and not profile %}
<div class="form-group"> <div class="form-group">
<label for="user_role">Admin user? 0 or 1</label> <label for="user_role">Admin user</label>
<input type="text" class="form-control" name="user_role" id="user_role" value="{{ content.role if content.role != None }}"> <input type="checkbox" name="admin_user" id="admin_user" {% if content.role %}checked{% endif %}>
</div>
<div class="form-group">
<label for="nickname">nickname</label>
<input type="text" class="form-control" name="nickname" id="nickname" value="{{ content.nickname if content.nickname != None }}">
</div> </div>
{% endif %}
{% if g.user and g.user.role and not profile and not new_user %}
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input type="checkbox" name="delete"> Delete this user <input type="checkbox" name="delete"> Delete this user

View File

@ -7,11 +7,13 @@ from flask import Flask, render_template, session, request, redirect, url_for, s
from cps import db, config, ub, helper from cps import db, config, ub, helper
import os import os
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from sqlalchemy.exc import IntegrityError
from math import ceil from math import ceil
from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user
from flask.ext.principal import Principal, Identity, AnonymousIdentity, identity_changed from flask.ext.principal import Principal, Identity, AnonymousIdentity, identity_changed
import requests, zipfile import requests, zipfile
from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.security import generate_password_hash, check_password_hash
from functools import wraps
app = (Flask(__name__)) app = (Flask(__name__))
@ -82,6 +84,17 @@ def url_for_other_page(page):
app.jinja_env.globals['url_for_other_page'] = url_for_other_page app.jinja_env.globals['url_for_other_page'] = url_for_other_page
def admin_required(f):
"""
Checks if current_user.role == 1
"""
@wraps(f)
def inner(*args, **kwargs):
if int(current_user.role) == 1:
return f(*args, **kwargs)
abort(403)
return inner
@app.before_request @app.before_request
def before_request(): def before_request():
g.user = current_user g.user = current_user
@ -236,7 +249,8 @@ def series(name):
@app.route("/admin/") @app.route("/admin/")
def admin(): def admin():
return "Admin ONLY!" #return "Admin ONLY!"
abort(403)
@app.route("/search", methods=["GET"]) @app.route("/search", methods=["GET"])
@ -462,13 +476,20 @@ def profile():
content.password = generate_password_hash(to_save["password"]) content.password = generate_password_hash(to_save["password"])
if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail: if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail:
content.kindle_mail = to_save["kindle_mail"] content.kindle_mail = to_save["kindle_mail"]
if to_save["user_role"]: if to_save["email"] and to_save["email"] != content.email:
content.role = int(to_save["user_role"]) content.email = to_save["email"]
try:
ub.session.commit() ub.session.commit()
except IntegrityError:
ub.session.rollback()
flash("Found an existing account for this email address.", category="error")
return render_template("user_edit.html", content=content, downloads=downloads, title="%s's profile" % current_user.nickname) return render_template("user_edit.html", content=content, downloads=downloads, title="%s's profile" % current_user.nickname)
flash("Profile updated", category="success")
return render_template("user_edit.html", profile=1, content=content, downloads=downloads, title="%s's profile" % current_user.nickname)
@app.route("/admin/user") @app.route("/admin/user")
@login_required @login_required
@admin_required
def user_list(): def user_list():
content = ub.session.query(ub.User).all() content = ub.session.query(ub.User).all()
settings = ub.session.query(ub.Settings).first() settings = ub.session.query(ub.Settings).first()
@ -476,24 +497,34 @@ def user_list():
@app.route("/admin/user/new", methods = ["GET", "POST"]) @app.route("/admin/user/new", methods = ["GET", "POST"])
@login_required @login_required
@admin_required
def new_user(): def new_user():
content = ub.User() content = ub.User()
if request.method == "POST": if request.method == "POST":
to_save = request.form.to_dict() to_save = request.form.to_dict()
if not to_save["nickname"] or not to_save["email"] or not to_save["password"]:
flash("Please fill out all fields!", category="error")
return render_template("user_edit.html", new_user=1, content=content, title="Add new user")
content.password = generate_password_hash(to_save["password"]) content.password = generate_password_hash(to_save["password"])
content.nickname = to_save["nickname"] content.nickname = to_save["nickname"]
content.email = to_save["email"] content.email = to_save["email"]
content.role = int(to_save["user_role"]) if "admin_user" in to_save:
content.role = 1
else:
content.role = 0
try: try:
ub.session.add(content) ub.session.add(content)
ub.session.commit() ub.session.commit()
flash("User created", category="success") flash("User '%s' created" % content.nickname, category="success")
except (e): return redirect(url_for('user_list'))
flash(e, category="error") except IntegrityError:
return render_template("user_edit.html", content=content, title="User list") ub.session.rollback()
flash("Found an existing account for this email address or nickname.", category="error")
return render_template("user_edit.html", new_user=1, content=content, title="Add new user")
@app.route("/admin/user/mailsettings", methods = ["GET", "POST"]) @app.route("/admin/user/mailsettings", methods = ["GET", "POST"])
@login_required @login_required
@admin_required
def edit_mailsettings(): def edit_mailsettings():
content = ub.session.query(ub.Settings).first() content = ub.session.query(ub.Settings).first()
if request.method == "POST": if request.method == "POST":
@ -512,6 +543,7 @@ def edit_mailsettings():
@app.route("/admin/user/<int:user_id>", methods = ["GET", "POST"]) @app.route("/admin/user/<int:user_id>", methods = ["GET", "POST"])
@login_required @login_required
@admin_required
def edit_user(user_id): def edit_user(user_id):
content = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() content = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first()
downloads = list() downloads = list()
@ -521,15 +553,30 @@ def edit_user(user_id):
to_save = request.form.to_dict() to_save = request.form.to_dict()
if "delete" in to_save: if "delete" in to_save:
ub.session.delete(content) ub.session.delete(content)
flash("User '%s' deleted" % content.nickname, category="success")
return redirect(url_for('user_list')) return redirect(url_for('user_list'))
else: else:
if "password" in to_save: if to_save["password"]:
content.password == generate_password_hash(to_save["password"]) content.password == generate_password_hash(to_save["password"])
if "admin_user" in to_save and content.role != 1:
content.role = 1
elif not "admin_user" in to_save and content.role == 1:
content.role = 0
if to_save["email"] and to_save["email"] != content.email:
content.email = to_save["email"]
if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail:
content.kindle_mail = to_save["kindle_mail"]
try:
ub.session.commit() ub.session.commit()
return render_template("user_edit.html", content=content, downloads=downloads, title="Edit User %s" % current_user.nickname) flash("User '%s' updated" % content.nickname, category="success")
except IntegrityError:
ub.session.rollback()
flash("An unknown error occured.", category="error")
return render_template("user_edit.html", new_user=0, content=content, downloads=downloads, title="Edit User %s" % content.nickname)
@app.route("/admin/book/<int:book_id>", methods=['GET', 'POST']) @app.route("/admin/book/<int:book_id>", methods=['GET', 'POST'])
@login_required @login_required
@admin_required
def edit_book(book_id): def edit_book(book_id):
## create the function for sorting... ## create the function for sorting...
db.session.connection().connection.connection.create_function("title_sort",1,db.title_sort) db.session.connection().connection.connection.create_function("title_sort",1,db.title_sort)