def delete_user(): requirePasswordedUser() requireCSRFToken() # Get data email = request.values.get('email', None) if email is None: return json_status(400, "No email specified") if "@" not in email: email += "@illinois.edu" elif "@illinois.edu" not in email: return json_status(400, "Invalid email") # Validate ID pw_query = PasswordUser.select().where(PasswordUser.email==email) ac_query = AuthcodeUser.select().where(AuthcodeUser.email==email) if not pw_query.exists() and not ac_query.exists(): return json_status(410, "No matching user") # Do deletion if pw_query.exists(): pw_query.get().delete_instance() else: ac_query.get().delete_instance() # Done! return json_status(200, None)
def change_section(): requirePasswordedUser() requireCSRFToken() # Get data weekday = request.values.get('weekday', None) time = request.values.get('time', None) id = request.values.get('id', None) if id == '': id = None # Validate data if weekday is None or time is None: return json_status(400, "Missing weekday and/or time field.") weekday = weekday.title() if weekday not in calendar.day_name: return json_status(400, "Invalid weekday name.") # Create/fetch section if id is None: section = Section(weekday=weekday, time=time) else: query = Section.select().where(Section.id==id) if not query.exists(): json_status(410, "Invalid section id.") section = query.get() section.weekday = weekday section.time = time # Update section section.save() # Done! return json_status(200, section.id)
def reset_password(): error_message = None # Handle GET (user clicked on email link) if request.method == 'GET': # Get token token = request.args.get('token', '') pw_query = PasswordUser.select().where(PasswordUser.password_reset_token == token) # Check for user if not pw_query.exists(): return json_status(410, "Invalid token.") # Require long-enough reset token if len(token) != DEFAULT_TOKEN_LENGTH: return json_status(410, "Invalid token.") # Get user + construct password reset page user = pw_query.get() session['csrf_token'] = secure_token() # To prevent CSRF session['reset_id'] = user.id # Invalidate user's existing password reset token user.password_reset_token = secure_token() user.save() # Show finished page return render_template('reset-newpassword.html', session=session) # Handle POST (user requested new password) else: requireCSRFToken() # Get user user_query = PasswordUser.select().where(PasswordUser.id == session['reset_id']) if not user_query.exists(): return json_status(500, "No matching user.") user = user_query.get() # Validate requested password password = request.form.get('password', '') if len(password) < 12 or len(set(password)) < 8: return render_template('reset-newpassword.html', session=session, error_message='Passwords must be 12+ characters long and contain 8+ different characters.') # Update user's password new_salt = secure_token() user.salt = new_salt user.salted_hash = hash_password(password, new_salt) user.save() # Redirect user to complete page return render_template('reset-complete.html')
def delete_section(): requirePasswordedUser() requireCSRFToken() # Get data id = request.values.get('id', None) if id is None: return json_status(400, "Missing section id.") # Validate ID query = Section.select().where(Section.id==id) if not query.exists(): return json_status(410, "Invalid section id.") # Do deletion query.get().delete_instance() # Done! return json_status(200, None)
def add_user(): requirePasswordedUser() requireCSRFToken() # Get data email = request.values.get('email', None) is_passworded = request.values.get('is_passworded', None) # Validate data if email is None or is_passworded is None: return json_status(400, "One or more of (email, is_passworded) is missing.") if len(email) < 2 or len(email) > 256: return json_status(400, "Email must be between 2 and 256 (inclusive) characters long.") if '@' not in email: email += '@illinois.edu' elif '@illinois.edu' not in email: return json_status(400, "Emails must be either netids or @illinois.edu emails") is_passworded = is_passworded.lower() if is_passworded not in ["true", "false"]: return json_status(400, "Invalid is_passworded value") is_passworded = (is_passworded == "true") # Prevent duplication if PasswordUser.select().where(PasswordUser.email==email).exists() or AuthcodeUser.select().where(AuthcodeUser.email==email).exists(): return json_status(400, "User already exists") # Create user password = None user = None if is_passworded: password = secure_token(12) salt = secure_token() salted_hash = hash_password(password, salt) user = PasswordUser(email=email, salt=salt, salted_hash=salted_hash) else: user = AuthcodeUser(email=email, authcode=secure_token()) user.save() # Trigger event hooks (to notify the user) if is_passworded: on_create_password_user(user, password) else: on_create_authcode_user(user) # Done! return json_status(200, user.id)