Skip to content

Commit aad727f

Browse files
F30rudis
andcommitted
Web: Allow to resend email confirmation mail from admin interface
Closes: #93 Co-authored-by: Simon Ruderich <simon@ruderich.org>
1 parent 08ec1c7 commit aad727f

4 files changed

Lines changed: 44 additions & 33 deletions

File tree

src/ctf_gameserver/web/admin.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from .registration.models import Team
88
from .registration.admin_inline import InlineTeamAdmin
9+
from .registration.util import send_confirmation_mail
910
from .scoring.models import GameControl
1011
from .util import format_lazy
1112

@@ -32,6 +33,13 @@ def site_title(cls): # pylint: disable=no-self-argument
3233
admin_site = CTFAdminSite() # pylint: disable=invalid-name
3334

3435

36+
@admin.action(description=_('Resend email confirmation mail'))
37+
def resend_confirmation_mail(_model_admin, request, queryset):
38+
39+
for user in queryset:
40+
send_confirmation_mail(user, request)
41+
42+
3543
@admin.register(User, site=admin_site)
3644
class CTFUserAdmin(UserAdmin):
3745
"""
@@ -79,6 +87,7 @@ def team_net_number(self, user):
7987
list_filter = ('is_active', 'is_staff', 'is_superuser', TeamListFilter, 'date_joined')
8088
search_fields = ('username', 'email', 'team__net_number', 'team__informal_email', 'team__affiliation',
8189
'team__country')
90+
actions = [resend_confirmation_mail]
8291

8392
fieldsets = (
8493
(None, {'fields': ('username', 'password', 'email')}),

src/ctf_gameserver/web/registration/forms.py

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
from django import forms
2-
from django.core.mail import send_mail
3-
from django.template import loader
4-
from django.conf import settings
52
from django.utils.safestring import mark_safe
63
from django.utils.translation import gettext_lazy as _
74
from django.contrib.auth.models import User
8-
from django.contrib.sites.shortcuts import get_current_site
95

106
import ctf_gameserver.web.scoring.models as scoring_models
117

128
from .models import Team
139
from .fields import ClearableThumbnailImageInput
14-
from .util import email_token_generator, get_country_names
10+
from .util import get_country_names
1511

1612
FIVE_MB = 5 * 1024**2
1713

@@ -85,28 +81,6 @@ def save(self, commit=True):
8581

8682
return user
8783

88-
def send_confirmation_mail(self, request):
89-
"""
90-
Sends an email containing the address confirmation link to the user associated with this form. As it
91-
requires a User instance, it should only be called after the object has initially been saved.
92-
93-
Args:
94-
request: The HttpRequest from which this function is being called
95-
"""
96-
competition_name = scoring_models.GameControl.get_instance().competition_name
97-
98-
context = {
99-
'competition_name': competition_name,
100-
'protocol': 'https' if request.is_secure() else 'http',
101-
'domain': get_current_site(request),
102-
'user': self.instance.pk,
103-
'token': email_token_generator.make_token(self.instance)
104-
}
105-
message = loader.render_to_string('confirmation_mail.txt', context)
106-
107-
send_mail(competition_name+' email confirmation', message, settings.DEFAULT_FROM_EMAIL,
108-
[self.instance.email])
109-
11084

11185
class TeamForm(forms.ModelForm):
11286
"""

src/ctf_gameserver/web/registration/util.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,37 @@
22
import locale
33
import csv
44

5+
from django.conf import settings
6+
from django.core.mail import send_mail
57
from django.contrib.auth.tokens import PasswordResetTokenGenerator
8+
from django.contrib.sites.shortcuts import get_current_site
9+
from django.template import loader
10+
11+
import ctf_gameserver.web.scoring.models as scoring_models
12+
13+
14+
def send_confirmation_mail(user, request):
15+
"""
16+
Sends an email containing the email address confirmation link to the given user. As it requires a User
17+
instance, it should only be called after the User object has initially been saved.
18+
19+
Args:
20+
request: An HttpRequest from which this function is being called
21+
"""
22+
23+
email_token_generator = EmailConfirmationTokenGenerator()
24+
competition_name = scoring_models.GameControl.get_instance().competition_name
25+
26+
context = {
27+
'competition_name': competition_name,
28+
'protocol': 'https' if request.is_secure() else 'http',
29+
'domain': get_current_site(request),
30+
'user': user.pk,
31+
'token': email_token_generator.make_token(user)
32+
}
33+
message = loader.render_to_string('confirmation_mail.txt', context)
34+
35+
send_mail(competition_name+' email confirmation', message, settings.DEFAULT_FROM_EMAIL, [user.email])
636

737

838
class EmailConfirmationTokenGenerator(PasswordResetTokenGenerator):
@@ -23,9 +53,6 @@ def _make_hash_value(self, user, timestamp):
2353
return str(user.pk) + user.email + str(login_timestamp) + str(timestamp)
2454

2555

26-
email_token_generator = EmailConfirmationTokenGenerator() # pylint: disable=invalid-name
27-
28-
2956
def get_country_names():
3057
"""
3158
Returns a list of (English) country names from the OKFN/Core Datasets "List of all countries with their

src/ctf_gameserver/web/registration/views.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import ctf_gameserver.web.scoring.models as scoring_models
1818
from . import forms
1919
from .models import Team, TeamDownload
20-
from .util import email_token_generator
20+
from .util import EmailConfirmationTokenGenerator, send_confirmation_mail
2121

2222
User = get_user_model() # pylint: disable=invalid-name
2323

@@ -40,7 +40,7 @@ def register(request):
4040
if user_form.is_valid() and team_form.is_valid():
4141
user = user_form.save()
4242
team_form.save(user)
43-
user_form.send_confirmation_mail(request)
43+
send_confirmation_mail(user, request)
4444

4545
messages.success(request,
4646
mark_safe(_('Successful registration! A confirmation mail has been sent to '
@@ -75,7 +75,7 @@ def edit_team(request):
7575
team_form.save(user)
7676

7777
if 'email' in user_form.changed_data:
78-
user_form.send_confirmation_mail(request)
78+
send_confirmation_mail(user, request)
7979
logout(request)
8080

8181
messages.warning(request, _('A confirmation mail has been sent to your new formal email '
@@ -164,6 +164,7 @@ def confirm_email(request):
164164
messages.error(request, error_message)
165165
return render(request, '400.html', status=400)
166166

167+
email_token_generator = EmailConfirmationTokenGenerator()
167168
if not email_token_generator.check_token(user, token):
168169
messages.error(request, error_message)
169170
return render(request, '400.html', status=400)

0 commit comments

Comments
 (0)