def verify_email(username, code): """ Verifies to the system that an email address exists, and assigns it to a user. Expected to be used only by users clicking links in email-verfication emails. Not part of the documented API. """ change_request = PendingEmail(username) if not change_request.in_db: return "No such change request", 404, PLAINTEXT_HEADER email_change_days = config.config.getint('nemesis', 'email_change_days') max_age = timedelta(days=email_change_days) if change_request.age > max_age: return "Request not valid", 410, PLAINTEXT_HEADER if change_request.verify_code != code: return "Invalid verification code", 403, PLAINTEXT_HEADER log_action('changing email', user=username, new_email=change_request.new_email) u = User(change_request.username) u.set_email(change_request.new_email) u.save() return "Email address successfully changed", 200, PLAINTEXT_HEADER
def verify_email(username, code): """ Verifies to the system that an email address exists, and assigns it to a user. Expected to be used only by users clicking links in email-verfication emails. Not part of the documented API. """ change_request = PendingEmail(username) if not change_request.in_db: return "No such change request", 404 if change_request.age > timedelta(days = 2): return "Request not valid", 410 if change_request.verify_code != code: return "Invalid verification code", 403 log_action('changing email', user = username, new_email = change_request.new_email) u = User(change_request.username) u.set_email(change_request.new_email) u.save() return "Email address successfully changed", 200
def verify_email(username, code): """ Verifies to the system that an email address exists, and assigns it to a user. Expected to be used only by users clicking links in email-verfication emails. Not part of the documented API. """ change_request = PendingEmail(username) if not change_request.in_db: return "No such change request", 404 if change_request.age > timedelta(days=2): return "Request not valid", 410 if change_request.verify_code != code: return "Invalid verification code", 403 log_action('changing email', user=username, new_email=change_request.new_email) u = User(change_request.username) u.set_email(change_request.new_email) u.save() return "Email address successfully changed", 200
def verify_email(username, code): """ Verifies to the system that an email address exists, and assigns it to a user. Expected to be used only by users clicking links in email-verfication emails. Not part of the documented API. """ change_request = PendingEmail(username) if not change_request.in_db: return "No such change request", 404, PLAINTEXT_HEADER email_change_days = config.config.getint('nemesis', 'email_change_days') max_age = timedelta(days = email_change_days) if change_request.age > max_age: return "Request not valid", 410, PLAINTEXT_HEADER if change_request.verify_code != code: return "Invalid verification code", 403, PLAINTEXT_HEADER log_action('changing email', user = username, new_email = change_request.new_email) u = User(change_request.username) u.set_email(change_request.new_email) u.save() return "Email address successfully changed", 200, PLAINTEXT_HEADER
def send_password_reset(requesting_user, userid): user_to_update = User.create_user(userid) if not requesting_user.can_administrate(user_to_update): return AUTHORIZATION_DENIED verify_code = helpers.create_verify_code(user_to_update.username, requesting_user.username) ppr = PendingPasswordReset(user_to_update.username) ppr.requestor_username = requesting_user.username ppr.verify_code = verify_code ppr.save() log_action('sending password reset', ppr) url = url_for('reset_password', username=user_to_update.username, code=verify_code, _external=True) ppr.send_reset_email( user_to_update.email, user_to_update.first_name, url, "{0} {1}".format(requesting_user.first_name, requesting_user.last_name), ) return "{}", 202
def activate_account(username, code): """ Verifies to the system that an email address exists, and that the related account should be made into a full account. Expected to be used only by users clicking links in account-activation emails. Not part of the documented API. """ pu = PendingUser(username) if not pu.in_db: return "No such user account", 404 if pu.age > timedelta(days=2): return "Request not valid", 410 if pu.verify_code != code: return "Invalid verification code", 403 log_action('activating user', pu) from libnemesis import srusers new_pass = srusers.users.GenPasswd() u = User(username) u.set_email(pu.email) u.set_team(pu.team) u.set_college(pu.college) u.set_password(new_pass) u.make_student() u.save() # let the team-leader know rq_user = User.create_user(pu.teacher_username) email_vars = { 'name': rq_user.first_name, 'au_username': username, 'au_first_name': u.first_name, 'au_last_name': u.last_name } mailer.email_template(rq_user.email, 'user_activated_team_leader', email_vars) pu.delete() html = open(PATH + "/templates/activate.html").read() replacements = { 'first_name': u.first_name, 'last_name': u.last_name, 'password': new_pass, 'email': u.email, 'username': username, 'root': url_for('.index') } html = html.format(**replacements) return html, 200
def test_log_action_objects(self): class Foo(object): def __repr__(self): return 'Foo(bacon)' helpers.log_action('action-my', Foo()) logged = self._stream.getvalue() expected = "action-my: Foo(bacon)" assert expected in logged
def test_log_action(self): helpers.log_action('my-action', 'foo', bar='jam', spam='ham') logged = self._stream.getvalue() expected = ( # Cope with variable dictionary ordering "my-action: foo, bar: jam, spam: ham\n", "my-action: foo, spam: ham, bar: jam\n", ) assert logged in expected
def register_user(requesting_user): if not requesting_user.can_register_users: return json.dumps({"error":"YOU_CANT_REGISTER_USERS"}), 403 teacher_username = requesting_user.username college_group = request.form["college"].strip() first_name = request.form["first_name"].strip() last_name = request.form["last_name"].strip() email = request.form["email"].strip() team = request.form["team"].strip() if College(college_group) not in requesting_user.colleges: return json.dumps({"error":"BAD_COLLEGE"}), 403 if team not in [t.name for t in College(college_group).teams]: return json.dumps({"error":"BAD_TEAM"}), 403 if not helpers.is_email_valid(email): return json.dumps({"error":"BAD_EMAIL"}), 403 if not helpers.is_name_valid(first_name): return json.dumps({"error":"BAD_FIRST_NAME"}), 403 if not helpers.is_name_valid(last_name): return json.dumps({"error":"BAD_LAST_NAME"}), 403 if User.name_used(first_name, last_name) or helpers.email_used(email): return json.dumps({"error":"DETAILS_ALREADY_USED"}), 403 u = User.create_new_user(requesting_user, college_group, first_name, last_name) verify_code = helpers.create_verify_code(u.username, email) pu = PendingUser(u.username) pu.teacher_username = teacher_username pu.college = college_group pu.email = email pu.team = team pu.verify_code = verify_code pu.save() log_action('registering user', pu) url = url_for('activate_account', username=u.username, code=verify_code, _external=True) pu.send_welcome_email(first_name, url) rqu_email_vars = { 'name': requesting_user.first_name, 'activation_days': ACTIVATION_DAYS, 'pu_first_name': first_name, 'pu_last_name': last_name, 'pu_username': pu.username, 'pu_college': College(pu.college).name, 'pu_email': pu.email, 'pu_team': pu.team } mailer.email_template(requesting_user.email, 'user_requested', rqu_email_vars) return "{}", 202
def activate_account(username, code): """ Verifies to the system that an email address exists, and that the related account should be made into a full account. Expected to be used only by users clicking links in account-activation emails. Not part of the documented API. """ pu = PendingUser(username) if not pu.in_db: return "No such user account", 404 if pu.age > timedelta(days = 2): return "Request not valid", 410 if pu.verify_code != code: return "Invalid verification code", 403 log_action('activating user', pu) from libnemesis import srusers new_pass = srusers.users.GenPasswd() u = User(username) u.set_email(pu.email) u.set_team(pu.team) u.set_college(pu.college) u.set_password(new_pass) u.make_student() u.save() # let the team-leader know rq_user = User.create_user(pu.teacher_username) email_vars = { 'name': rq_user.first_name, 'au_username': username, 'au_first_name': u.first_name, 'au_last_name': u.last_name } mailer.email_template(rq_user.email, 'user_activated_team_leader', email_vars) pu.delete() html = open(PATH + "/templates/activate.html").read() replacements = { 'first_name': u.first_name , 'last_name': u.last_name , 'password': new_pass , 'email': u.email , 'username': username , 'root': url_for('.index') } html = html.format(**replacements) return html, 200
def reset_password(username, code): """ Resets a user's password after they've clicked a link in an email we sent them, then serves up a page for them to change their password. Not part of the documented API. """ ppr = PendingPasswordReset(username) if not ppr.in_db: return "No such user account", 404, PLAINTEXT_HEADER if ppr.age > timedelta(days=PASSWORD_RESET_DAYS): return "Request not valid", 410, PLAINTEXT_HEADER if ppr.verify_code != code: return "Invalid verification code", 403, PLAINTEXT_HEADER log_action('resetting user password', ppr) from libnemesis import srusers new_pass = srusers.users.GenPasswd() u = User(username) u.set_password(new_pass) # No need to save since set_password happens immediately ppr.delete() html = open(PATH + "/templates/password_reset.html").read() replacements = { 'first_name': u.first_name, 'last_name': u.last_name, 'password': new_pass, 'username': username, 'root': url_for('.index') } html = html.format(**replacements) return html, 200, CSP_HEADER
def ajax_verify(): if not 'password' in request.form or not 'type' in request.form: return "password or type field missing", 200 uid = request.form.get('uid') password = request.form.get('password') opentype = request.form.get('type') if helpers.verify_password(uid, password): helpers.log_action(opentype, uid) if opentype == 'Open': door_operator.open_door() elif opentype == 'Close': door_operator.close_door() return jsonify(response=True) return jsonify(response=False)
def reset_password(username, code): """ Resets a user's password after they've clicked a link in an email we sent them, then serves up a page for them to change their password. Not part of the documented API. """ ppr = PendingPasswordReset(username) if not ppr.in_db: return "No such user account", 404, PLAINTEXT_HEADER if ppr.age > timedelta(days = PASSWORD_RESET_DAYS): return "Request not valid", 410, PLAINTEXT_HEADER if ppr.verify_code != code: return "Invalid verification code", 403, PLAINTEXT_HEADER log_action('resetting user password', ppr) from libnemesis import srusers new_pass = srusers.users.GenPasswd() u = User(username) u.set_password(new_pass) # No need to save since set_password happens immediately ppr.delete() html = open(PATH + "/templates/password_reset.html").read() replacements = { 'first_name': u.first_name , 'last_name': u.last_name , 'password': new_pass , 'username': username , 'root': url_for('.index') } html = html.format(**replacements) return html, 200, CSP_HEADER
def test_log_action(self): helpers.log_action('my-action', 'foo', bar = 'jam', spam = 'ham') logged = self._stream.getvalue() expected = "my-action: foo, bar: jam, spam: ham" assert expected in logged
def test_log_action(self): helpers.log_action('my-action', 'foo', bar='jam', spam='ham') logged = self._stream.getvalue() expected = "my-action: foo, bar: jam, spam: ham" assert expected in logged
def register_user(): ah = AuthHelper(request) if not ah.auth_will_succeed: return ah.auth_error_json, 403 requesting_user = ah.user if not requesting_user.can_register_users: return json.dumps({"error": "YOU_CANT_REGISTER_USERS"}), 403 teacher_username = requesting_user.username college_group = request.form["college"].strip() first_name = request.form["first_name"].strip() last_name = request.form["last_name"].strip() email = request.form["email"].strip() team = request.form["team"].strip() if College(college_group) not in requesting_user.colleges: return json.dumps({"error": "BAD_COLLEGE"}), 403 if team not in [t.name for t in College(college_group).teams]: return json.dumps({"error": "BAD_TEAM"}), 403 if not helpers.is_email_valid(email): return json.dumps({"error": "BAD_EMAIL"}), 403 if not helpers.is_name_valid(first_name): return json.dumps({"error": "BAD_FIRST_NAME"}), 403 if not helpers.is_name_valid(last_name): return json.dumps({"error": "BAD_LAST_NAME"}), 403 if User.name_used(first_name, last_name) or helpers.email_used(email): return json.dumps({"error": "DETAILS_ALREADY_USED"}), 403 u = User.create_new_user(requesting_user, college_group, first_name, last_name) verify_code = helpers.create_verify_code(u.username, email) pu = PendingUser(u.username) pu.teacher_username = teacher_username pu.college = college_group pu.email = email pu.team = team pu.verify_code = verify_code pu.save() log_action('registering user', pu) url = url_for('activate_account', username=u.username, code=verify_code, _external=True) pu.send_welcome_email(first_name, url) rqu_email_vars = { 'name': requesting_user.first_name, 'pu_first_name': first_name, 'pu_last_name': last_name, 'pu_username': pu.username, 'pu_college': College(pu.college).name, 'pu_email': pu.email, 'pu_team': pu.team } mailer.email_template(requesting_user.email, 'user_requested', rqu_email_vars) return "{}", 202