mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 22:14:25 +01:00
Send confirmation emails on register and add button to resend email (#298)
* Fixes #293 * Adding get_config/set_config test
This commit is contained in:
39
CTFd/auth.py
39
CTFd/auth.py
@@ -18,8 +18,11 @@ auth = Blueprint('auth', __name__)
|
|||||||
@auth.route('/confirm/<data>', methods=['GET'])
|
@auth.route('/confirm/<data>', methods=['GET'])
|
||||||
def confirm_user(data=None):
|
def confirm_user(data=None):
|
||||||
if not utils.get_config('verify_emails'):
|
if not utils.get_config('verify_emails'):
|
||||||
|
# If the CTF doesn't care about confirming email addresses then redierct to challenges
|
||||||
return redirect(url_for('challenges.challenges_view'))
|
return redirect(url_for('challenges.challenges_view'))
|
||||||
if data and request.method == "GET": # User is confirming email account
|
|
||||||
|
# User is confirming email account
|
||||||
|
if data and request.method == "GET":
|
||||||
try:
|
try:
|
||||||
s = Signer(app.config['SECRET_KEY'])
|
s = Signer(app.config['SECRET_KEY'])
|
||||||
email = s.unsign(urllib.unquote_plus(data.decode('base64')))
|
email = s.unsign(urllib.unquote_plus(data.decode('base64')))
|
||||||
@@ -36,15 +39,28 @@ def confirm_user(data=None):
|
|||||||
if utils.authed():
|
if utils.authed():
|
||||||
return redirect(url_for('challenges.challenges_view'))
|
return redirect(url_for('challenges.challenges_view'))
|
||||||
return redirect(url_for('auth.login'))
|
return redirect(url_for('auth.login'))
|
||||||
if not data and request.method == "GET": # User has been directed to the confirm page because his account is not verified
|
|
||||||
if not utils.authed():
|
# User is trying to start or restart the confirmation flow
|
||||||
return redirect(url_for('auth.login'))
|
if not utils.authed():
|
||||||
team = Teams.query.filter_by(id=session['id']).first_or_404()
|
return redirect(url_for('auth.login'))
|
||||||
if team.verified:
|
|
||||||
return redirect(url_for('views.profile'))
|
team = Teams.query.filter_by(id=session['id']).first_or_404()
|
||||||
else:
|
|
||||||
utils.verify_email(team.email)
|
if data is None:
|
||||||
return render_template('confirm.html', team=team)
|
if request.method == "POST":
|
||||||
|
# User wants to resend their confirmation email
|
||||||
|
if team.verified:
|
||||||
|
return redirect(url_for('views.profile'))
|
||||||
|
else:
|
||||||
|
utils.verify_email(team.email)
|
||||||
|
return render_template('confirm.html', team=team, infos=['Your confirmation email has been resent!'])
|
||||||
|
elif request.method == "GET":
|
||||||
|
# User has been directed to the confirm page
|
||||||
|
team = Teams.query.filter_by(id=session['id']).first_or_404()
|
||||||
|
if team.verified:
|
||||||
|
# If user is already verified, redirect to their profile
|
||||||
|
return redirect(url_for('views.profile'))
|
||||||
|
return render_template('confirm.html', team=team)
|
||||||
|
|
||||||
|
|
||||||
@auth.route('/reset_password', methods=['POST', 'GET'])
|
@auth.route('/reset_password', methods=['POST', 'GET'])
|
||||||
@@ -136,6 +152,9 @@ def register():
|
|||||||
logger.warn("[{0}] {1} registered (UNCONFIRMED) with {2}".format(time.strftime("%m/%d/%Y %X"),
|
logger.warn("[{0}] {1} registered (UNCONFIRMED) with {2}".format(time.strftime("%m/%d/%Y %X"),
|
||||||
request.form['name'].encode('utf-8'),
|
request.form['name'].encode('utf-8'),
|
||||||
request.form['email'].encode('utf-8')))
|
request.form['email'].encode('utf-8')))
|
||||||
|
|
||||||
|
utils.verify_email(team.email)
|
||||||
|
|
||||||
return redirect(url_for('auth.confirm_user'))
|
return redirect(url_for('auth.confirm_user'))
|
||||||
else: # Don't care about confirming users
|
else: # Don't care about confirming users
|
||||||
if utils.can_send_mail(): # We want to notify the user that they have registered.
|
if utils.can_send_mail(): # We want to notify the user that they have registered.
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
{% block stylesheets %}
|
{% block stylesheets %}
|
||||||
<style>
|
<style>
|
||||||
#login-container {
|
|
||||||
padding-left: 60px;
|
|
||||||
padding-right: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.done-row {
|
.done-row {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
@@ -22,7 +18,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="container main-container">
|
<div class="container main-container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="login-container" class="col-md-6 col-md-offset-3">
|
<div id="confirm-container" class="col-md-6 col-md-offset-3">
|
||||||
|
{% for info in infos %}
|
||||||
|
<div class="alert alert-info alert-dismissable" role="alert">
|
||||||
|
<span class="sr-only"></span>
|
||||||
|
{{ info }}
|
||||||
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
{% for error in errors %}
|
{% for error in errors %}
|
||||||
<div class="alert alert-danger alert-dismissable" role="alert">
|
<div class="alert alert-danger alert-dismissable" role="alert">
|
||||||
<span class="sr-only">Error:</span>
|
<span class="sr-only">Error:</span>
|
||||||
@@ -35,9 +39,22 @@
|
|||||||
We've sent a confirmation email to {{ team.email }}
|
We've sent a confirmation email to {{ team.email }}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<h3 class="text-center">
|
<br>
|
||||||
Please click the link in that email to confirm your account and access the rest of the CTF.
|
|
||||||
</h3>
|
<h4 class="text-center">
|
||||||
|
Please click the link in that email to confirm your account.
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<h4 class="text-center">
|
||||||
|
Need to resend the confirmation email?
|
||||||
|
</h4>
|
||||||
|
<div class="col-md-12 text-center">
|
||||||
|
<button type="submit" id="submit" tabindex="5" class="btn btn-md btn-theme btn-outlined">Resend</button>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="nonce" value="{{ nonce }}">
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,10 +3,20 @@
|
|||||||
|
|
||||||
from tests.helpers import *
|
from tests.helpers import *
|
||||||
from CTFd.models import ip2long, long2ip
|
from CTFd.models import ip2long, long2ip
|
||||||
from CTFd.utils import override_template
|
from CTFd.utils import get_config, set_config, override_template
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_config_and_set_config():
|
||||||
|
"""Does get_config and set_config work properly"""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
assert get_config('setup') == True
|
||||||
|
config = set_config('TEST_CONFIG_ENTRY', 'test_config_entry')
|
||||||
|
assert config.value == 'test_config_entry'
|
||||||
|
assert get_config('TEST_CONFIG_ENTRY') == 'test_config_entry'
|
||||||
|
|
||||||
|
|
||||||
def test_ip2long_ipv4():
|
def test_ip2long_ipv4():
|
||||||
"""Does ip2long work properly for ipv4 addresses"""
|
"""Does ip2long work properly for ipv4 addresses"""
|
||||||
assert ip2long('127.0.0.1') == 2130706433
|
assert ip2long('127.0.0.1') == 2130706433
|
||||||
|
|||||||
Reference in New Issue
Block a user