Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow admins to change names/email addresses on accounts #1356

Merged
merged 4 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 71 additions & 1 deletion apps/admin/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

from . import admin
from main import db
from sqlalchemy_continuum.utils import version_class

from models.user import User, generate_signup_code
from models.permission import Permission
from ..common.email import from_email
Expand Down Expand Up @@ -70,6 +72,9 @@ class UserForm(Form):
note = StringField("Check-in note (will be shown to check-in operator)")
add_note = SubmitField("Save Note")
change_permissions = SubmitField("Change")
new_name = StringField("New name")
new_email = StringField("New email (will notify old and new emails if changed)")
update_details = SubmitField("Update")

for permission in permissions:
setattr(
Expand Down Expand Up @@ -107,12 +112,77 @@ class UserForm(Form):
user.checkin_note = form.note.data
db.session.commit()

elif form.update_details.data:
made_changes = []

if form.new_name.data and form.new_name.data != user.name:
app.logger.info(
"user %s name changed from %s to %s",
user.id,
user.name,
form.new_name.data,
)
user.name = form.new_name.data
made_changes.append("name")

if form.new_email.data and form.new_email.data != user.email:
# NB: any login tokens that were previously generated and emailed will still be valid until expiry.
# Maybe we should expire them and their sessions, just in case?
old_email = user.email
user.email = form.new_email.data
app.logger.info(
"user %s (%s) email changed from %s to %s",
user.name,
user.id,
old_email,
form.new_email.data,
)
_send_email_changed_from(user, old_email)
_send_email_changed_to(user, form.new_email.data)
made_changes.append("email")

if made_changes:
flash(f'Updated user {" & ".join(made_changes)}')
db.session.commit()

return redirect(url_for(".user", user_id=user.id))

form.note.data = user.checkin_note
form.new_name.data = user.name
form.new_email.data = user.email

versions = user.versions.order_by(None).order_by(
version_class(User).transaction_id.desc()
)

return render_template(
"admin/users/user.html", user=user, form=form, permissions=permissions
"admin/users/user.html",
user=user,
form=form,
permissions=permissions,
versions=versions,
)


def _send_email_changed_from(user: User, old_email: str) -> None:
msg = EmailMessage(
"Your email address has been changed",
from_email=from_email("CONTACT_EMAIL"),
to=[old_email],
)
msg.body = render_template("emails/user-email-changed-from.txt", user=user)
msg.send()


def _send_email_changed_to(user: User, new_email: str) -> None:
code = user.login_code(app.config["SECRET_KEY"])
msg = EmailMessage(
"Your email address has been changed",
from_email=from_email("CONTACT_EMAIL"),
to=[new_email],
)
msg.body = render_template("emails/user-email-changed.txt", user=user, code=code)
msg.send()


class SignupForm(Form):
Expand Down
1 change: 1 addition & 0 deletions config/development-example.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DEBUG = True
SQLALCHEMY_RECORD_QUERIES = True
FIX_URL_SCHEME = False
DEBUG_TB_INTERCEPT_REDIRECTS = False
BYPASS_LOGIN = False
Expand Down
46 changes: 44 additions & 2 deletions templates/admin/users/user.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,20 @@ <h2>User Details</h2>
</table>


<h3>Permissions</h3>
<p>Note that the admin permission implies all other permissions.</p>
<form method="post">
{{ form.hidden_tag() }}
{{ form.keys }}

<h3>Update Details</h3>
{{ render_field(form.new_name) }}
{{ render_field(form.new_email) }}
{{ form.update_details(class_="btn btn-success pull-right") }}

<div class="row">&nbsp;</div>

<h3>Permissions</h3>
<p>Note that the admin permission implies all other permissions.</p>

<table class="table table-condensed">
<tr>{% for permission in permissions %}
<th>{{permission.name|capitalize}}</th>
Expand Down Expand Up @@ -122,4 +130,38 @@ <h3>Proposals</h3>
{% endfor %}
</table>

<h3>Changes</h3>
<table class="table table-condensed">
<thead>
<tr>
<th>When</th>
<th>By</th>
<th>Fieldname</th>
<th>Was</th>
<th>Changed to</th>
</tr>
</thead>
<tbody>
{% for version in versions %}
{% for (field, (old, new)) in version.changeset.items() %}
<tr class="{{- loop.cycle('odd', 'even') -}}">
{% if loop.first %}
<td rowspan="{{ loop.length }}">{{ version.transaction.issued_at.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3] }}</td>
<td rowspan="{{ loop.length }}">
{% if version.transaction.user %}
<a href="{{ url_for('admin.user', user_id=version.transaction.user.id) }}">{{ version.transaction.user.name }} ({{ version.transaction.user.email }})</a>
{% else %}
[unknown]
{% endif %}
</td>
{% endif %}
<td>{{field}}</td>
<td>{{old}}</td>
<td>{{new}}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>

{% endblock %}
12 changes: 12 additions & 0 deletions templates/emails/user-email-changed-from.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends "emails/base.txt" %}
{% block body %}
Hi {{ user.name }},

The email address on your account on our website for Electromagnetic Field {{ event_year }} has been changed from this email address to a different one.

If you think this change was made in error, please let us know by replying to this email.

Love,

All the EMF team
{% endblock %}
16 changes: 16 additions & 0 deletions templates/emails/user-email-changed.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends "emails/base.txt" %}
{% block body %}
Hi {{ user.name }},

The email address on your account on our website for Electromagnetic Field {{ event_year }} has been changed to this one.

You can log into this account by visiting:

{{ external_url('users.login', code=code, next=url_for('users.account')) }}

If you think this change was made in error, please let us know by replying to this email.

Love,

All the EMF team
{% endblock %}
Loading