Add user rank changing

Fixes #14
This commit is contained in:
rubenwardy 2018-03-24 19:37:33 +00:00
parent f51224a8d5
commit 69efdd7fde
4 changed files with 52 additions and 12 deletions

@ -24,6 +24,20 @@ class UserRank(enum.Enum):
def getTitle(self): def getTitle(self):
return self.name.replace("_", " ").title() return self.name.replace("_", " ").title()
def toName(self):
return self.name.lower()
def __str__(self):
return self.name
@classmethod
def choices(cls):
return [(choice, choice.getTitle()) for choice in cls]
@classmethod
def coerce(cls, item):
return item if type(item) == UserRank else UserRank[item]
class Permission(enum.Enum): class Permission(enum.Enum):
EDIT_PACKAGE = "EDIT_PACKAGE" EDIT_PACKAGE = "EDIT_PACKAGE"
@ -34,6 +48,7 @@ class Permission(enum.Enum):
APPROVE_RELEASE = "APPROVE_RELEASE" APPROVE_RELEASE = "APPROVE_RELEASE"
APPROVE_NEW = "APPROVE_NEW" APPROVE_NEW = "APPROVE_NEW"
CHANGE_RELEASE_URL = "CHANGE_RELEASE_URL" CHANGE_RELEASE_URL = "CHANGE_RELEASE_URL"
CHANGE_RANK = "CHANGE_RANK"
# Only return true if the permission is valid for *all* contexts # Only return true if the permission is valid for *all* contexts
# See Package.checkPerm for package-specific contexts # See Package.checkPerm for package-specific contexts
@ -86,6 +101,21 @@ class User(db.Model, UserMixin):
def isClaimed(self): def isClaimed(self):
return self.password is not None and self.password != "" return self.password is not None and self.password != ""
def checkPerm(self, user, perm):
if not user.is_authenticated:
return False
if type(perm) == str:
perm = Permission[perm]
elif type(perm) != Permission:
raise Exception("Unknown permission given to User.checkPerm()")
# Members can edit their own packages, and editors can edit any packages
if perm == Permission.CHANGE_RANK:
return user.rank.atLeast(UserRank.MODERATOR)
else:
raise Exception("Permission {} is not related to users".format(perm.name))
class PackageType(enum.Enum): class PackageType(enum.Enum):
MOD = "Mod" MOD = "Mod"
GAME = "Game" GAME = "Game"

@ -87,6 +87,10 @@
{{ render_field(form.display_name, tabindex=240) }} {{ render_field(form.display_name, tabindex=240) }}
{% if user.checkPerm(current_user, "CHANGE_RANK") %}
{{ render_field(form.rank, tabindex=240) }}
{% endif %}
{{ render_submit_field(form.submit, tabindex=280) }} {{ render_submit_field(form.submit, tabindex=280) }}
</div> </div>
</div> </div>

@ -4,20 +4,18 @@ from flask_login import login_user, logout_user
from flask.ext import menu from flask.ext import menu
from app import app from app import app
from app.models import * from app.models import *
# Define the User registration form
# It augments the Flask-User RegisterForm with additional fields
from flask_user.forms import RegisterForm
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, validators from flask_user.forms import RegisterForm
from wtforms import *
from wtforms.validators import *
class MyRegisterForm(RegisterForm): class MyRegisterForm(RegisterForm):
display_name = StringField("Display name") display_name = StringField("Display name")
# Define the User profile form # Define the User profile form
class UserProfileForm(FlaskForm): class UserProfileForm(FlaskForm):
display_name = StringField("Display name") display_name = StringField("Display name")
rank = SelectField("Rank", [InputRequired()], choices=UserRank.choices(), coerce=UserRank.coerce, default=UserRank.NEW_MEMBER)
submit = SubmitField("Save") submit = SubmitField("Save")
@app.route("/users/", methods=["GET"]) @app.route("/users/", methods=["GET"])
@ -33,20 +31,28 @@ def user_profile_page(username):
abort(404) abort(404)
form = None form = None
if user == current_user: if user == current_user or user.checkPerm(current_user, Permission.CHANGE_RANK):
# Initialize form # Initialize form
form = UserProfileForm(formdata=request.form, obj=current_user) form = UserProfileForm(formdata=request.form, obj=user)
# Process valid POST # Process valid POST
if request.method=="POST" and form.validate(): if request.method=="POST" and form.validate():
# Copy form fields to user_profile fields # Copy form fields to user_profile fields
form.populate_obj(current_user) if user == current_user:
user.display_name = form["display_name"].data
if user.checkPerm(current_user, Permission.CHANGE_RANK):
newRank = form["rank"].data
if current_user.rank.atLeast(newRank):
user.rank = form["rank"].data
else:
flash("Can't promote a user to a rank higher than yourself!", "error")
# Save user_profile # Save user_profile
db.session.commit() db.session.commit()
# Redirect to home page # Redirect to home page
return redirect(url_for("home_page")) return redirect(url_for("user_profile_page", username=username))
# Process GET or invalid POST # Process GET or invalid POST
return render_template("users/user_profile_page.html", return render_template("users/user_profile_page.html",

@ -17,7 +17,7 @@ if not os.path.isfile("db.sqlite"):
ruben = User("rubenwardy") ruben = User("rubenwardy")
ruben.github_username = "rubenwardy" ruben.github_username = "rubenwardy"
ruben.rank = UserRank.EDITOR ruben.rank = UserRank.ADMIN
db.session.add(ruben) db.session.add(ruben)
ez = User("Shara") ez = User("Shara")