Allow users to change their display name

Fixes #269
This commit is contained in:
rubenwardy 2021-02-25 23:25:33 +00:00
parent 96b5b4ea5b
commit dea5a52c86
11 changed files with 53 additions and 22 deletions

View File

@ -1,6 +1,7 @@
from flask import *
from flask_login import current_user, login_required, logout_user
from flask_wtf import FlaskForm
from sqlalchemy import or_
from wtforms import *
from wtforms.validators import *
@ -36,11 +37,39 @@ def get_setting_tabs(user):
class UserProfileForm(FlaskForm):
display_name = StringField("Display Name", [Optional(), Length(1, 20)], filters=[lambda x: nonEmptyOrNone(x)])
website_url = StringField("Website URL", [Optional(), URL()], filters = [lambda x: x or None])
donate_url = StringField("Donation URL", [Optional(), URL()], filters = [lambda x: x or None])
submit = SubmitField("Save")
def handle_profile_edit(form, user, username):
severity = AuditSeverity.NORMAL if current_user == user else AuditSeverity.MODERATION
addAuditLog(severity, current_user, "Edited {}'s profile".format(user.display_name),
url_for("users.profile", username=username))
if user.checkPerm(current_user, Permission.CHANGE_DISPLAY_NAME) and \
user.display_name != form.display_name.data:
if User.query.filter(id != user.id,
or_(User.username == form.display_name.data,
User.display_name.ilike(form.display_name.data))).count() > 0:
flash("A user already has that name", "danger")
return None
user.display_name = form.display_name.data
addAuditLog(severity, current_user, "Changed display name of {} to {}"
.format(user.username, user.display_name),
url_for("users.profile", username=username))
if user.checkPerm(current_user, Permission.CHANGE_PROFILE_URLS):
user.website_url = form["website_url"].data
user.donate_url = form["donate_url"].data
db.session.commit()
return redirect(url_for("users.profile", username=username))
@bp.route("/users/<username>/settings/profile/", methods=["GET", "POST"])
@login_required
def profile_edit(username):
@ -54,17 +83,9 @@ def profile_edit(username):
form = UserProfileForm(obj=user)
if form.validate_on_submit():
severity = AuditSeverity.NORMAL if current_user == user else AuditSeverity.MODERATION
addAuditLog(severity, current_user, "Edited {}'s profile".format(user.display_name),
url_for("users.profile", username=username))
if user.checkPerm(current_user, Permission.CHANGE_PROFILE_URLS):
user.website_url = form["website_url"].data
user.donate_url = form["donate_url"].data
db.session.commit()
return redirect(url_for("users.profile", username=username))
ret = handle_profile_edit(form, user, username)
if ret:
return ret
# Process GET or invalid POST
return render_template("users/profile_edit.html", user=user, form=form, tabs=get_setting_tabs(user), current_tab="edit_profile")

View File

@ -88,6 +88,7 @@ class Permission(enum.Enum):
CREATE_TOKEN = "CREATE_TOKEN"
EDIT_MAINTAINERS = "EDIT_MAINTAINERS"
CHANGE_PROFILE_URLS = "CHANGE_PROFILE_URLS"
CHANGE_DISPLAY_NAME = "CHANGE_DISPLAY_NAME"
# Only return true if the permission is valid for *all* contexts
# See Package.checkPerm for package-specific contexts
@ -216,6 +217,8 @@ class User(db.Model, UserMixin):
return user.rank.atLeast(UserRank.MODERATOR)
elif perm == Permission.CHANGE_EMAIL or perm == Permission.CHANGE_PROFILE_URLS:
return user == self or user.rank.atLeast(UserRank.ADMIN)
elif perm == Permission.CHANGE_DISPLAY_NAME:
return user.rank.atLeast(UserRank.MEMBER if user == self else UserRank.MODERATOR)
elif perm == Permission.CREATE_TOKEN:
if user == self:
return user.rank.atLeast(UserRank.MEMBER)

View File

@ -13,11 +13,11 @@
{% if entry.causer %}
<p class="text-muted mb-4">
{{ _("Caused by %(author)s.", author=entry.causer.display_name) }}
{{ _("Caused by %(author)s.", author=entry.causer.username) }}
</p>
{% else %}
<p class="text-muted mb-4">
{{ _("Caused by a deleted user.", author=entry.causer.display_name) }}
{{ _("Caused by a deleted user.") }}
</p>
{% endif %}

View File

@ -5,14 +5,12 @@
{{ notification.title }}
</h2>
<p>
{% if notification.package %}
{{ _("From %(username)s and on package %(package)s.",
username=notification.causer.display_name, package=notification.package.title) }}
username=notification.causer.username, package=notification.package.title) }}
{% else %}
{{ _("From %(username)s.", username=notification.causer.display_name) }}
{{ _("From %(username)s.", username=notification.causer.username) }}
{% endif %}
</p>

View File

@ -11,7 +11,7 @@
{% for notification in group %}
<li>
<a href="{{ notification.url | abs_url }}">{{ notification.title }}</a> -
{{ _("from %(username)s.", username=notification.causer.display_name) }}
{{ _("from %(username)s.", username=notification.causer.username) }}
</li>
{% endfor %}
</ul>

View File

@ -27,7 +27,7 @@
style="max-height: 22px;"
src="{{ entry.causer.getProfilePicURL() }}" />
<span class="pl-2">{{ entry.causer.display_name }}</span>
<span class="pl-2">{{ entry.causer.username }}</span>
{% else %}
<i>Deleted User</i>
{% endif %}

View File

@ -8,7 +8,7 @@
<form method="POST" action="" class="card box_grey">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<h3 class="card-header">Delete reply by {{ reply.author.display_name }}</h3>
<h3 class="card-header">Delete reply by {{ reply.author.username }}</h3>
<div class="card-body markdown">
{{ reply.comment | markdown }}
</div>

View File

@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block title %}
{{ _('Delete "%(title)s" by %(author)s', title=thread.title, author=thread.author.display_name) }}
{{ _('Delete "%(title)s" by %(author)s', title=thread.title, author=thread.author.username) }}
{% endblock %}
{% block content %}

View File

@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block title %}
Delete user {{ user.display_name }}
Delete user {{ user.username }}
{% endblock %}
{% block content %}

View File

@ -49,6 +49,11 @@
<span class="col-sm {{ user.rank }}">
{{ user.display_name }}
{% if user.username != user.display_name %}
<span class="text-muted small ml-2">
({{ user.username }})
</span>
{% endif %}
</span>
<div class="col-sm-1 text-center">

View File

@ -48,6 +48,10 @@
<form action="" method="POST" class="form" role="form">
{{ form.hidden_tag() }}
{% if user.checkPerm(current_user, "CHANGE_DISPLAY_NAME") %}
{{ render_field(form.display_name, tabindex=230, hint=_("Pretending to be another user is grounds for a permanent ban")) }}
{% endif %}
{% if user.checkPerm(current_user, "CHANGE_PROFILE_URLS") %}
{{ render_field(form.website_url, tabindex=232) }}
{{ render_field(form.donate_url, tabindex=233) }}