mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-20 07:14:24 +01:00
Merging changes from various forks
Until v1 is released all changes are fair game. Caching support Fixes for decoding confirmation and reset_password email tokens Starting work on #154 specifying why challenges are not open Adding a required parameter to HTML to sort of fix #153 Adding a column to specify when a team registered Check static key by default in new key Decreasing capability of pages functionality to address security concerns Fixing confirmations restrictions by modifying can__view_challenges()
This commit is contained in:
69
CTFd/auth.py
69
CTFd/auth.py
@@ -10,6 +10,7 @@ import logging
|
||||
import time
|
||||
import re
|
||||
import os
|
||||
import urllib
|
||||
|
||||
auth = Blueprint('auth', __name__)
|
||||
|
||||
@@ -22,20 +23,28 @@ def confirm_user(data=None):
|
||||
if data and request.method == "GET": ## User is confirming email account
|
||||
try:
|
||||
s = Signer(app.config['SECRET_KEY'])
|
||||
email = s.unsign(data.decode('base64'))
|
||||
email = s.unsign(urllib.unquote(data.decode('base64')))
|
||||
except BadSignature:
|
||||
return render_template('confirm.html', errors=['Your confirmation link seems wrong'])
|
||||
except:
|
||||
return render_template('reset_password.html', errors=['Your link appears broken, please try again.'])
|
||||
team = Teams.query.filter_by(email=email).first()
|
||||
team.verified = True
|
||||
db.session.commit()
|
||||
db.session.close()
|
||||
logger = logging.getLogger('regs')
|
||||
logger.warn("[{0}] {1} confirmed {2}".format(time.strftime("%m/%d/%Y %X"), team.name.encode('utf-8'), team.email.encode('utf-8')))
|
||||
if authed():
|
||||
return redirect(url_for('challenges.challenges_view'))
|
||||
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 data and request.method == "GET": ## User has been directed to the confirm page because his account is not verified
|
||||
if not authed():
|
||||
return redirect(url_for('auth.login'))
|
||||
team = Teams.query.filter_by(id=session['id']).first()
|
||||
if team.verified:
|
||||
return redirect(url_for('views.profile'))
|
||||
else:
|
||||
verify_email(team.email)
|
||||
return render_template('confirm.html', team=team)
|
||||
|
||||
|
||||
@@ -48,7 +57,7 @@ def reset_password(data=None):
|
||||
if data is not None and request.method == "POST":
|
||||
try:
|
||||
s = TimedSerializer(app.config['SECRET_KEY'])
|
||||
name = s.loads(data.decode('base64'), max_age=1800)
|
||||
name = s.loads(urllib.unquote(data.decode('base64')), max_age=1800)
|
||||
except BadTimeSignature:
|
||||
return render_template('reset_password.html', errors=['Your link has expired'])
|
||||
team = Teams.query.filter_by(name=name).first()
|
||||
@@ -92,7 +101,7 @@ def register():
|
||||
emails = Teams.query.add_columns('email', 'id').filter_by(email=email).first()
|
||||
pass_short = len(password) == 0
|
||||
pass_long = len(password) > 128
|
||||
valid_email = re.match("[^@]+@[^@]+\.[^@]+", request.form['email'])
|
||||
valid_email = re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", request.form['email'])
|
||||
|
||||
if not valid_email:
|
||||
errors.append("That email doesn't look right")
|
||||
@@ -121,10 +130,15 @@ def register():
|
||||
session['admin'] = team.admin
|
||||
session['nonce'] = sha512(os.urandom(10))
|
||||
|
||||
if can_send_mail() and get_config('verify_emails'):
|
||||
verify_email(team.email)
|
||||
else:
|
||||
if can_send_mail():
|
||||
if can_send_mail() and get_config('verify_emails'): ## Confirming users is enabled and we can send email.
|
||||
db.session.close()
|
||||
logger = logging.getLogger('regs')
|
||||
logger.warn("[{0}] {1} registered (UNCONFIRMED) with {2}".format(time.strftime("%m/%d/%Y %X"),
|
||||
request.form['name'].encode('utf-8'),
|
||||
request.form['email'].encode('utf-8')))
|
||||
return redirect(url_for('auth.confirm_user'))
|
||||
else: ## Don't care about confirming users
|
||||
if can_send_mail(): ## We want to notify the user that they have registered.
|
||||
sendmail(request.form['email'], "You've successfully registered for {}".format(get_config('ctf_name')))
|
||||
|
||||
db.session.close()
|
||||
@@ -142,25 +156,30 @@ def login():
|
||||
errors = []
|
||||
name = request.form['name']
|
||||
team = Teams.query.filter_by(name=name).first()
|
||||
if team and bcrypt_sha256.verify(request.form['password'], team.password):
|
||||
try:
|
||||
session.regenerate() # NO SESSION FIXATION FOR YOU
|
||||
except:
|
||||
pass # TODO: Some session objects don't implement regenerate :(
|
||||
session['username'] = team.name
|
||||
session['id'] = team.id
|
||||
session['admin'] = team.admin
|
||||
session['nonce'] = sha512(os.urandom(10))
|
||||
db.session.close()
|
||||
if team:
|
||||
if team and bcrypt_sha256.verify(request.form['password'], team.password):
|
||||
try:
|
||||
session.regenerate() # NO SESSION FIXATION FOR YOU
|
||||
except:
|
||||
pass # TODO: Some session objects don't implement regenerate :(
|
||||
session['username'] = team.name
|
||||
session['id'] = team.id
|
||||
session['admin'] = team.admin
|
||||
session['nonce'] = sha512(os.urandom(10))
|
||||
db.session.close()
|
||||
|
||||
logger = logging.getLogger('logins')
|
||||
logger.warn("[{0}] {1} logged in".format(time.strftime("%m/%d/%Y %X"), session['username'].encode('utf-8')))
|
||||
logger = logging.getLogger('logins')
|
||||
logger.warn("[{0}] {1} logged in".format(time.strftime("%m/%d/%Y %X"), session['username'].encode('utf-8')))
|
||||
|
||||
if request.args.get('next') and is_safe_url(request.args.get('next')):
|
||||
return redirect(request.args.get('next'))
|
||||
return redirect(url_for('challenges.challenges_view'))
|
||||
else:
|
||||
errors.append("That account doesn't seem to exist")
|
||||
if request.args.get('next') and is_safe_url(request.args.get('next')):
|
||||
return redirect(request.args.get('next'))
|
||||
return redirect(url_for('challenges.challenges_view'))
|
||||
else: # This user exists but the password is wrong
|
||||
errors.append("That account doesn't seem to exist")
|
||||
db.session.close()
|
||||
return render_template('login.html', errors=errors)
|
||||
else: # This user just doesn't exist
|
||||
errors.append("Your username or password is incorrect")
|
||||
db.session.close()
|
||||
return render_template('login.html', errors=errors)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user