diff --git a/CTFd/auth.py b/CTFd/auth.py index 97017aaa..e3a1e8c9 100644 --- a/CTFd/auth.py +++ b/CTFd/auth.py @@ -20,7 +20,7 @@ def confirm_user(data=None): # If the CTF doesn't care about confirming email addresses then redierct to challenges return redirect(url_for('challenges.challenges_view')) - logger = logging.getLogger('logins') + logger = logging.getLogger('regs') # User is confirming email account if data and request.method == "GET": try: @@ -30,18 +30,16 @@ def confirm_user(data=None): return render_template('confirm.html', errors=['Your confirmation link has expired']) except BadSignature: return render_template('confirm.html', errors=['Your confirmation link seems wrong']) - except: - return render_template('confirm.html', errors=['Your link appears broken, please try again.']) team = Teams.query.filter_by(email=email).first_or_404() team.verified = True db.session.commit() - db.session.close() logger.warn("[{date}] {ip} - {username} confirmed their account".format( date=time.strftime("%m/%d/%Y %X"), ip=utils.get_ip(), username=team.name.encode('utf-8'), email=team.email.encode('utf-8') )) + db.session.close() if utils.authed(): return redirect(url_for('challenges.challenges_view')) return redirect(url_for('auth.login')) @@ -91,12 +89,12 @@ def reset_password(data=None): team = Teams.query.filter_by(name=name).first_or_404() team.password = bcrypt_sha256.encrypt(request.form['password'].strip()) db.session.commit() - db.session.close() logger.warn("[{date}] {ip} - successful password reset for {username}".format( date=time.strftime("%m/%d/%Y %X"), ip=utils.get_ip(), username=team.name.encode('utf-8') )) + db.session.close() return redirect(url_for('auth.login')) if request.method == 'POST': @@ -165,7 +163,6 @@ def register(): session['nonce'] = utils.sha512(os.urandom(10)) if utils.can_send_mail() and utils.get_config('verify_emails'): # Confirming users is enabled and we can send email. - db.session.close() logger = logging.getLogger('regs') logger.warn("[{date}] {ip} - {username} registered (UNCONFIRMED) with {email}".format( date=time.strftime("%m/%d/%Y %X"), @@ -173,22 +170,20 @@ def register(): username=request.form['name'].encode('utf-8'), email=request.form['email'].encode('utf-8') )) - utils.verify_email(team.email) - + db.session.close() return redirect(url_for('auth.confirm_user')) else: # Don't care about confirming users if utils.can_send_mail(): # We want to notify the user that they have registered. utils.sendmail(request.form['email'], "You've successfully registered for {}".format(utils.get_config('ctf_name'))) - db.session.close() - logger.warn("[{date}] {ip} - {username} registered with {email}".format( date=time.strftime("%m/%d/%Y %X"), ip=utils.get_ip(), username=request.form['name'].encode('utf-8'), email=request.form['email'].encode('utf-8') )) + db.session.close() return redirect(url_for('challenges.challenges_view')) else: return render_template('register.html') diff --git a/CTFd/themes/original/templates/confirm.html b/CTFd/themes/original/templates/confirm.html index 5fe95eed..6dc42c2a 100644 --- a/CTFd/themes/original/templates/confirm.html +++ b/CTFd/themes/original/templates/confirm.html @@ -35,6 +35,7 @@ aria-hidden="true">× {% endfor %} + {% if team %}

We've sent a confirmation email to {{ team.email }}

@@ -44,8 +45,9 @@

Please click the link in that email to confirm your account.

+ {% endif %} - + {% if username %}

Need to resend the confirmation email? @@ -55,6 +57,7 @@ + {% endif %} diff --git a/CTFd/utils.py b/CTFd/utils.py index 29e4b18e..34744c2d 100644 --- a/CTFd/utils.py +++ b/CTFd/utils.py @@ -529,6 +529,10 @@ def sha512(string): def base64encode(s, urlencode=False): if six.PY3 and isinstance(s, six.string_types): s = s.encode('utf-8') + else: + # Python 2 support because the base64 module doesnt like unicode + s = str(s) + encoded = base64.urlsafe_b64encode(s) if six.PY3: encoded = encoded.decode('utf-8') @@ -540,8 +544,13 @@ def base64encode(s, urlencode=False): def base64decode(s, urldecode=False): if urldecode: s = unquote(s) + if six.PY3 and isinstance(s, six.string_types): s = s.encode('utf-8') + else: + # Python 2 support because the base64 module doesnt like unicode + s = str(s) + decoded = base64.urlsafe_b64decode(s) if six.PY3: decoded = decoded.decode('utf-8') diff --git a/tests/test_utils.py b/tests/test_utils.py index 16bbac12..78800bb2 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -7,6 +7,7 @@ from CTFd.utils import get_config, set_config, override_template, sendmail, veri from CTFd.utils import base64encode, base64decode from mock import patch import json +import six def test_get_config_and_set_config(): @@ -44,16 +45,34 @@ def test_long2ip_ipv6(): def test_base64encode(): """The base64encode wrapper works properly""" - assert base64encode('abc123') == 'YWJjMTIz' - assert base64encode('😆') == '8J-Yhg==' - assert base64encode('😆', urlencode=True) == '8J-Yhg%3D%3D' + if six.PY2: + assert base64encode('abc123') == 'YWJjMTIz' + assert base64encode(unicode('abc123')) == 'YWJjMTIz' + assert base64encode(unicode('"test@mailinator.com".DGxeoA.lCssU3M2QuBfohO-FtdgDQLKbU4'), urlencode=True) == 'InRlc3RAbWFpbGluYXRvci5jb20iLkRHeGVvQS5sQ3NzVTNNMlF1QmZvaE8tRnRkZ0RRTEtiVTQ%3D' + assert base64encode('😆') == '8J-Yhg==' + assert base64encode('😆', urlencode=True) == '8J-Yhg%3D%3D' + else: + assert base64encode('abc123') == 'YWJjMTIz' + assert base64encode('abc123') == 'YWJjMTIz' + assert base64encode('"test@mailinator.com".DGxeoA.lCssU3M2QuBfohO-FtdgDQLKbU4', urlencode=True) == 'InRlc3RAbWFpbGluYXRvci5jb20iLkRHeGVvQS5sQ3NzVTNNMlF1QmZvaE8tRnRkZ0RRTEtiVTQ%3D' + assert base64encode('😆') == '8J-Yhg==' + assert base64encode('😆', urlencode=True) == '8J-Yhg%3D%3D' def test_base64decode(): """The base64decode wrapper works properly""" - assert base64decode('YWJjMTIz') == 'abc123' - assert base64decode('8J-Yhg==') == '😆' - assert base64decode('8J-Yhg%3D%3D', urldecode=True) == '😆' + if six.PY2: + assert base64decode('YWJjMTIz') == 'abc123' + assert base64decode(unicode('YWJjMTIz')) == 'abc123' + assert base64decode(unicode('InRlc3RAbWFpbGluYXRvci5jb20iLkRHeGVvQS5sQ3NzVTNNMlF1QmZvaE8tRnRkZ0RRTEtiVTQ%3D'), urldecode=True) == '"test@mailinator.com".DGxeoA.lCssU3M2QuBfohO-FtdgDQLKbU4' + assert base64decode('8J-Yhg==') == '😆' + assert base64decode('8J-Yhg%3D%3D', urldecode=True) == '😆' + else: + assert base64decode('YWJjMTIz') == 'abc123' + assert base64decode('YWJjMTIz') == 'abc123' + assert base64decode('InRlc3RAbWFpbGluYXRvci5jb20iLkRHeGVvQS5sQ3NzVTNNMlF1QmZvaE8tRnRkZ0RRTEtiVTQ%3D', urldecode=True) == '"test@mailinator.com".DGxeoA.lCssU3M2QuBfohO-FtdgDQLKbU4' + assert base64decode('8J-Yhg==') == '😆' + assert base64decode('8J-Yhg%3D%3D', urldecode=True) == '😆' def test_override_template():