mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 22:12:24 +01:00
parent
727db52c19
commit
3c944cbd72
@ -13,7 +13,7 @@ from . import bp
|
|||||||
|
|
||||||
|
|
||||||
def get_setting_tabs(user):
|
def get_setting_tabs(user):
|
||||||
return [
|
ret = [
|
||||||
{
|
{
|
||||||
"id": "edit_profile",
|
"id": "edit_profile",
|
||||||
"title": gettext("Edit Profile"),
|
"title": gettext("Edit Profile"),
|
||||||
@ -36,6 +36,15 @@ def get_setting_tabs(user):
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if current_user.rank.atLeast(UserRank.MODERATOR):
|
||||||
|
ret.append({
|
||||||
|
"id": "modtools",
|
||||||
|
"title": gettext("Moderator Tools"),
|
||||||
|
"url": url_for("users.modtools", username=user.username)
|
||||||
|
})
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class UserProfileForm(FlaskForm):
|
class UserProfileForm(FlaskForm):
|
||||||
display_name = StringField(lazy_gettext("Display Name"), [Optional(), Length(1, 20)], filters=[lambda x: nonEmptyOrNone(x)])
|
display_name = StringField(lazy_gettext("Display Name"), [Optional(), Length(1, 20)], filters=[lambda x: nonEmptyOrNone(x)])
|
||||||
@ -194,65 +203,14 @@ def email_notifications(username=None):
|
|||||||
tabs=get_setting_tabs(user), current_tab="notifications")
|
tabs=get_setting_tabs(user), current_tab="notifications")
|
||||||
|
|
||||||
|
|
||||||
class UserAccountForm(FlaskForm):
|
@bp.route("/users/<username>/settings/account/")
|
||||||
username = StringField(lazy_gettext("Username"), [Optional(), Length(1, 50)])
|
|
||||||
display_name = StringField(lazy_gettext("Display name"), [Optional(), Length(2, 100)])
|
|
||||||
forums_username = StringField(lazy_gettext("Forums Username"), [Optional(), Length(2, 50)])
|
|
||||||
github_username = StringField(lazy_gettext("GitHub Username"), [Optional(), Length(2, 50)])
|
|
||||||
rank = SelectField(lazy_gettext("Rank"), [Optional()], choices=UserRank.choices(), coerce=UserRank.coerce,
|
|
||||||
default=UserRank.NEW_MEMBER)
|
|
||||||
submit = SubmitField(lazy_gettext("Save"))
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/users/<username>/settings/account/", methods=["GET", "POST"])
|
|
||||||
@login_required
|
@login_required
|
||||||
def account(username):
|
def account(username):
|
||||||
user : User = User.query.filter_by(username=username).first()
|
user : User = User.query.filter_by(username=username).first()
|
||||||
if not user:
|
if not user:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.can_see_edit_profile(current_user):
|
return render_template("users/account.html", user=user, tabs=get_setting_tabs(user), current_tab="account")
|
||||||
flash(gettext("Permission denied"), "danger")
|
|
||||||
return redirect(url_for("users.profile", username=username))
|
|
||||||
|
|
||||||
can_edit_account_settings = user.checkPerm(current_user, Permission.CHANGE_USERNAMES) or \
|
|
||||||
user.checkPerm(current_user, Permission.CHANGE_RANK)
|
|
||||||
form = UserAccountForm(obj=user) if can_edit_account_settings else None
|
|
||||||
if form and 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))
|
|
||||||
|
|
||||||
# Copy form fields to user_profile fields
|
|
||||||
if user.checkPerm(current_user, Permission.CHANGE_USERNAMES):
|
|
||||||
if user.username != form.username.data:
|
|
||||||
for package in user.packages:
|
|
||||||
alias = PackageAlias(user.username, package.name)
|
|
||||||
package.aliases.append(alias)
|
|
||||||
db.session.add(alias)
|
|
||||||
|
|
||||||
user.username = form.username.data
|
|
||||||
|
|
||||||
user.display_name = form.display_name.data
|
|
||||||
user.forums_username = nonEmptyOrNone(form.forums_username.data)
|
|
||||||
user.github_username = nonEmptyOrNone(form.github_username.data)
|
|
||||||
|
|
||||||
if user.checkPerm(current_user, Permission.CHANGE_RANK):
|
|
||||||
newRank = form["rank"].data
|
|
||||||
if current_user.rank.atLeast(newRank):
|
|
||||||
if newRank != user.rank:
|
|
||||||
user.rank = form["rank"].data
|
|
||||||
msg = "Set rank of {} to {}".format(user.display_name, user.rank.getTitle())
|
|
||||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg,
|
|
||||||
url_for("users.profile", username=username))
|
|
||||||
else:
|
|
||||||
flash(gettext("Can't promote a user to a rank higher than yourself!"), "danger")
|
|
||||||
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return redirect(url_for("users.account", username=username))
|
|
||||||
|
|
||||||
return render_template("users/account.html", user=user, form=form, tabs=get_setting_tabs(user), current_tab="account")
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/users/<username>/delete/", methods=["GET", "POST"])
|
@bp.route("/users/<username>/delete/", methods=["GET", "POST"])
|
||||||
@ -299,3 +257,112 @@ def delete(username):
|
|||||||
logout_user()
|
logout_user()
|
||||||
|
|
||||||
return redirect(url_for("homepage.home"))
|
return redirect(url_for("homepage.home"))
|
||||||
|
|
||||||
|
|
||||||
|
class ModToolsForm(FlaskForm):
|
||||||
|
username = StringField(lazy_gettext("Username"), [Optional(), Length(1, 50)])
|
||||||
|
display_name = StringField(lazy_gettext("Display name"), [Optional(), Length(2, 100)])
|
||||||
|
forums_username = StringField(lazy_gettext("Forums Username"), [Optional(), Length(2, 50)])
|
||||||
|
github_username = StringField(lazy_gettext("GitHub Username"), [Optional(), Length(2, 50)])
|
||||||
|
rank = SelectField(lazy_gettext("Rank"), [Optional()], choices=UserRank.choices(), coerce=UserRank.coerce,
|
||||||
|
default=UserRank.NEW_MEMBER)
|
||||||
|
submit = SubmitField(lazy_gettext("Save"))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/users/<username>/modtools/", methods=["GET", "POST"])
|
||||||
|
@rank_required(UserRank.MODERATOR)
|
||||||
|
def modtools(username):
|
||||||
|
user: User = User.query.filter_by(username=username).first()
|
||||||
|
if not user:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
form = ModToolsForm(obj=user)
|
||||||
|
if form.validate_on_submit():
|
||||||
|
severity = AuditSeverity.NORMAL if current_user == user else AuditSeverity.MODERATION
|
||||||
|
addAuditLog(severity, current_user, "Edited {}'s account".format(user.display_name),
|
||||||
|
url_for("users.profile", username=username))
|
||||||
|
|
||||||
|
# Copy form fields to user_profile fields
|
||||||
|
if user.checkPerm(current_user, Permission.CHANGE_USERNAMES):
|
||||||
|
if user.username != form.username.data:
|
||||||
|
for package in user.packages:
|
||||||
|
alias = PackageAlias(user.username, package.name)
|
||||||
|
package.aliases.append(alias)
|
||||||
|
db.session.add(alias)
|
||||||
|
|
||||||
|
user.username = form.username.data
|
||||||
|
|
||||||
|
user.display_name = form.display_name.data
|
||||||
|
user.forums_username = nonEmptyOrNone(form.forums_username.data)
|
||||||
|
user.github_username = nonEmptyOrNone(form.github_username.data)
|
||||||
|
|
||||||
|
if user.checkPerm(current_user, Permission.CHANGE_RANK):
|
||||||
|
newRank = form["rank"].data
|
||||||
|
if current_user.rank.atLeast(newRank):
|
||||||
|
if newRank != user.rank:
|
||||||
|
user.rank = form["rank"].data
|
||||||
|
msg = "Set rank of {} to {}".format(user.display_name, user.rank.getTitle())
|
||||||
|
addAuditLog(AuditSeverity.MODERATION, current_user, msg,
|
||||||
|
url_for("users.profile", username=username))
|
||||||
|
else:
|
||||||
|
flash(gettext("Can't promote a user to a rank higher than yourself!"), "danger")
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("users.modtools", username=username))
|
||||||
|
|
||||||
|
return render_template("users/modtools.html", user=user, form=form, tabs=get_setting_tabs(user), current_tab="modtools")
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/users/<username>/modtools/set-email/", methods=["POST"])
|
||||||
|
@rank_required(UserRank.MODERATOR)
|
||||||
|
def modtools_set_email(username):
|
||||||
|
user: User = User.query.filter_by(username=username).first()
|
||||||
|
if not user:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
user.email = request.form["email"]
|
||||||
|
user.is_active = False
|
||||||
|
|
||||||
|
token = randomString(32)
|
||||||
|
addAuditLog(AuditSeverity.MODERATION, current_user, f"Set email and sent a password reset on {user.username}",
|
||||||
|
url_for("users.profile", username=user.username), None)
|
||||||
|
|
||||||
|
ver = UserEmailVerification()
|
||||||
|
ver.user = user
|
||||||
|
ver.token = token
|
||||||
|
ver.email = user.email
|
||||||
|
ver.is_password_reset = True
|
||||||
|
db.session.add(ver)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
send_verify_email.delay(user.email, token)
|
||||||
|
|
||||||
|
flash(f"Set email and sent a password reset on {user.username}", "success")
|
||||||
|
return redirect(url_for("users.modtools", username=username))
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/users/<username>/modtools/ban/", methods=["POST"])
|
||||||
|
@rank_required(UserRank.MODERATOR)
|
||||||
|
def modtools_ban(username):
|
||||||
|
user: User = User.query.filter_by(username=username).first()
|
||||||
|
if not user:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
if not user.checkPerm(current_user, Permission.CHANGE_RANK):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
user.rank = UserRank.BANNED
|
||||||
|
|
||||||
|
addAuditLog(AuditSeverity.MODERATION, current_user, f"Banned {user.username}",
|
||||||
|
url_for("users.profile", username=user.username), None)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
flash(f"Banned {user.username}", "success")
|
||||||
|
return redirect(url_for("users.modtools", username=username))
|
@ -216,10 +216,12 @@ class User(db.Model, UserMixin):
|
|||||||
# Members can edit their own packages, and editors can edit any packages
|
# Members can edit their own packages, and editors can edit any packages
|
||||||
if perm == Permission.CHANGE_AUTHOR:
|
if perm == Permission.CHANGE_AUTHOR:
|
||||||
return user.rank.atLeast(UserRank.EDITOR)
|
return user.rank.atLeast(UserRank.EDITOR)
|
||||||
elif perm == Permission.CHANGE_RANK or perm == Permission.CHANGE_USERNAMES:
|
elif perm == Permission.CHANGE_USERNAMES:
|
||||||
return user.rank.atLeast(UserRank.MODERATOR)
|
return user.rank.atLeast(UserRank.MODERATOR)
|
||||||
|
elif perm == Permission.CHANGE_RANK:
|
||||||
|
return user.rank.atLeast(UserRank.MODERATOR) and not self.rank.atLeast(user.rank)
|
||||||
elif perm == Permission.CHANGE_EMAIL or perm == Permission.CHANGE_PROFILE_URLS:
|
elif perm == Permission.CHANGE_EMAIL or perm == Permission.CHANGE_PROFILE_URLS:
|
||||||
return user == self or user.rank.atLeast(UserRank.ADMIN)
|
return user == self or (user.rank.atLeast(UserRank.MODERATOR) and not self.rank.atLeast(user.rank))
|
||||||
elif perm == Permission.CHANGE_DISPLAY_NAME:
|
elif perm == Permission.CHANGE_DISPLAY_NAME:
|
||||||
return user.rank.atLeast(UserRank.MEMBER if user == self else UserRank.MODERATOR)
|
return user.rank.atLeast(UserRank.MEMBER if user == self else UserRank.MODERATOR)
|
||||||
elif perm == Permission.CREATE_TOKEN:
|
elif perm == Permission.CREATE_TOKEN:
|
||||||
|
@ -11,33 +11,6 @@
|
|||||||
{% block pane %}
|
{% block pane %}
|
||||||
<h2 class="mt-0">{{ _("Account and Security") }}</h2>
|
<h2 class="mt-0">{{ _("Account and Security") }}</h2>
|
||||||
|
|
||||||
{% if form %}
|
|
||||||
<h3>
|
|
||||||
{{ _("Edit Account") }}
|
|
||||||
<small class="fas fa-user-shield ml-2 text-muted"></small>
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
{% from "macros/forms.html" import render_field, render_field_prefix, render_submit_field %}
|
|
||||||
<form action="" method="POST" class="form" role="form">
|
|
||||||
{{ form.hidden_tag() }}
|
|
||||||
|
|
||||||
{% if user.checkPerm(current_user, "CHANGE_USERNAMES") %}
|
|
||||||
{{ render_field(form.username, tabindex=230) }}
|
|
||||||
{{ render_field(form.display_name, tabindex=230) }}
|
|
||||||
{{ render_field(form.forums_username, tabindex=230) }}
|
|
||||||
{{ render_field_prefix(form.github_username, tabindex=230) }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if user.checkPerm(current_user, "CHANGE_RANK") %}
|
|
||||||
{{ render_field(form.rank, tabindex=250) }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<p>
|
|
||||||
{{ render_submit_field(form.submit, tabindex=280) }}
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h3>{{ _("Password") }}</h3>
|
<h3>{{ _("Password") }}</h3>
|
||||||
{% if user == current_user %}
|
{% if user == current_user %}
|
||||||
{% if user.password %}
|
{% if user.password %}
|
||||||
|
66
app/templates/users/modtools.html
Normal file
66
app/templates/users/modtools.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
{% extends "users/settings_base.html" %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{{ _("Moderator Tools") }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block pane %}
|
||||||
|
<h2 class="mt-0">{{ _("Moderator Tools") }}</h2>
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
{{ _("Edit Account") }}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
{% from "macros/forms.html" import render_field, render_field_prefix, render_submit_field %}
|
||||||
|
<form action="" method="POST" class="form" role="form">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
|
{% if user.checkPerm(current_user, "CHANGE_USERNAMES") %}
|
||||||
|
{{ render_field(form.username, tabindex=230) }}
|
||||||
|
{{ render_field(form.display_name, tabindex=230) }}
|
||||||
|
{{ render_field(form.forums_username, tabindex=230) }}
|
||||||
|
{{ render_field_prefix(form.github_username, tabindex=230) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if user.checkPerm(current_user, "CHANGE_RANK") %}
|
||||||
|
{{ render_field(form.rank, tabindex=250) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ render_submit_field(form.submit, tabindex=280) }}
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>{{ _("Password") }}</h3>
|
||||||
|
{% if user.password %}
|
||||||
|
<p>{{ _("Has password") }}</p>
|
||||||
|
{% else %}
|
||||||
|
<p class="text-danger">{{ _("Doesn't have password") }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not user.rank.atLeast(current_user.rank) %}
|
||||||
|
<h3>{{ _("Ban") }}</h3>
|
||||||
|
{% if user.rank.name == "BANNED" %}
|
||||||
|
<p>
|
||||||
|
Banned.
|
||||||
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<form method="POST" action="{{ url_for('users.modtools_ban', username=user.username) }}">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
|
<input type="submit" value="{{ _('Ban') }}" class="btn btn-danger" />
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h3>{{ _("Change Email and Send Password Reset") }}</h3>
|
||||||
|
<form method="POST" action="{{ url_for('users.modtools_set_email', username=user.username) }}">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">{{ _("Email Address") }}</label>
|
||||||
|
<input type="email" class="form-control" name="email" id="email" value="{{ user.email or '' }}" />
|
||||||
|
</div>
|
||||||
|
<input type="submit" value="{{ _('Save') }}" class="btn btn-primary" />
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -28,12 +28,20 @@
|
|||||||
{{ _("Report") }}
|
{{ _("Report") }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.MODERATOR) and user.email %}
|
{% if current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.MODERATOR) %}
|
||||||
|
{% if not user.rank.atLeast(current_user.rank) %}
|
||||||
|
<a class="btn btn-secondary float-right mr-3" href="{{ url_for('users.modtools', username=user.username) }}">
|
||||||
|
<i class="fas fa-user-shield mr-1"></i>
|
||||||
|
{{ _("Moderator Tools") }}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if user.email %}
|
||||||
<a class="btn btn-secondary float-right mr-3" href="{{ url_for('admin.send_single_email', username=user.username) }}">
|
<a class="btn btn-secondary float-right mr-3" href="{{ url_for('admin.send_single_email', username=user.username) }}">
|
||||||
<i class="fas fa-envelope mr-1"></i>
|
<i class="fas fa-envelope mr-1"></i>
|
||||||
{{ _("Send Email") }}
|
{{ _("Send Email") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<h1 class="ml-3 my-0 {{ user.rank.name }}">
|
<h1 class="ml-3 my-0 {{ user.rank.name }}">
|
||||||
{{ user.display_name }}
|
{{ user.display_name }}
|
||||||
|
Loading…
Reference in New Issue
Block a user