def create_user_with_role(self, user, email, password, role, github_token=None): """ Create a user with specified user details and role. """ from flask import g user = User(self.user.name, email=self.user.email, password=User.generate_hash(self.user.password), role=role, github_token=github_token) g.db.add(user) g.db.commit()
def complete_reset(uid, expires, mac): """ Complete process of account reset. :param uid: user id :type uid: int :param expires: integer representing time after which the link expires :type expires: int :param mac: message authentication code :type mac: str """ from run import app # Check if time expired now = int(time.time()) if now <= expires: user = User.query.filter_by(id=uid).first() if user is not None: # Validate HMAC content_to_hash = "{id}|{expiry}|{passwd}".format( id=uid, expiry=expires, passwd=user.password) real_hash = generate_hmac_hash(app.config.get('HMAC_KEY', ''), content_to_hash) try: authentic = hmac.compare_digest(real_hash, mac) except AttributeError: g.log.warning(f'falling back to direct comparison of hash...') # Older python version? Fallback which is less safe authentic = real_hash == mac if authentic: form = CompleteResetForm(request.form) if form.validate_on_submit(): user.password = User.generate_hash(form.password.data) g.db.commit() template = app.jinja_env.get_or_select_template( 'email/password_reset.txt') message = template.render(name=user.name) g.mailer.send_simple_message({ "to": user.email, "subject": "CCExtractor CI platform password reset", "text": message }) session['user_id'] = user.id return redirect("/") return { 'form': form, 'uid': uid, 'mac': mac, 'expires': expires } flash( 'The request to reset your password was invalid. Please enter your email again to start over.', 'error-message') return redirect(url_for('.reset'))
def complete_signup(email: str, expires: int, mac: str) -> Union[Response, Dict[str, Union[CompleteSignupForm, str, int]]]: """ Complete user signup. :param email: email address of the user :type email: str :param expires: integer representing time after which the link expires :type expires: int :param mac: message authentication code :type mac: str """ from run import app if int(time.time()) <= expires: content_to_hash = f"{email}|{expires}" real_hash = generate_hmac_hash(app.config.get('HMAC_KEY', ''), content_to_hash) try: authentic = hmac.compare_digest(real_hash, mac) except AttributeError: g.log.warning(f'falling back to direct comparison of hash...') # Older python version? Fallback which is less safe authentic = real_hash == mac if authentic: # Check if email already exists (sign up twice with same email) user_that_exists = User.query.filter_by(email=email).first() if user_that_exists is not None: flash('There is already a user with this email address registered.', 'error-message') return redirect(url_for('.signup')) form = CompleteSignupForm() if form.validate_on_submit(): user_to_register = User(form.name.data, email=email, password=User.generate_hash(form.password.data)) g.db.add(user_to_register) g.db.commit() session['user_id'] = user_to_register.id template = app.jinja_env.get_or_select_template('email/registration_ok.txt') message = template.render(name=user_to_register.name) g.mailer.send_simple_message({ "to": user_to_register.email, "subject": "Welcome to the CCExtractor CI platform", "text": message }) return redirect('/') return { 'form': form, 'email': email, 'expires': expires, 'mac': mac } flash('The request to complete the registration was invalid. Please enter your email again to start over.', 'error-message') return redirect(url_for('.signup'))
def complete_signup(email, expires, mac): from run import app # Check if time expired now = int(time.time()) if now <= expires: # Validate HMAC content_to_hash = "{email}|{expiry}".format(email=email, expiry=expires) real_hash = generate_hmac_hash(app.config.get('HMAC_KEY', ''), content_to_hash) try: authentic = hmac.compare_digest(real_hash, mac) except AttributeError: # Older python version? Fallback which is less safe authentic = real_hash == mac if authentic: # Check if email already exists (sign up twice with same email) user = User.query.filter_by(email=email).first() if user is not None: flash( 'There is already a user with this email address registered.', 'error-message') return redirect(url_for('.signup')) form = CompleteSignupForm() if form.validate_on_submit(): user = User(form.name.data, email=email, password=User.generate_hash(form.password.data)) g.db.add(user) g.db.commit() session['user_id'] = user.id # Send email template = app.jinja_env.get_or_select_template( 'email/registration_ok.txt') message = template.render(name=user.name) g.mailer.send_simple_message({ "to": user.email, "subject": "Welcome to the CCExtractor CI platform", "text": message }) return redirect('/') return { 'form': form, 'email': email, 'expires': expires, 'mac': mac } flash( 'The request to complete the registration was invalid. Please enter your email again to start over.', 'error-message') return redirect(url_for('.signup'))
def run(): from database import create_session from mod_auth.models import User, Role db = create_session(sys.argv[1]) # Check if there's at least one admin user admin = User.query.filter(User.role == Role.admin).first() if admin is not None: print(f"Admin already exists: {admin.name}") return user = User(sys.argv[2], Role.admin, sys.argv[3], User.generate_hash(sys.argv[4])) db.add(user) db.commit() print(f"Admin user created with name: {user.name}")
def run(): from database import create_session from mod_auth.models import User, Role from mod_auth.models import Page db = create_session(sys.argv[1]) # Create pages if not existing pages = Page.query.all() if len(pages) == 0: page_entries = { 'report.dashboard': 'Dashboard', 'config.notifications': 'Notification services', 'config.data_processing': 'Data processing', 'config.services': 'Honeypot services', 'auth.users': 'User manager', 'auth.access': 'Access manager', 'honeypot.profiles': 'Profile management', 'honeypot.manage': 'Honeypot management' } for name, pretty_name in page_entries.iteritems(): page = Page(name, pretty_name) db.add(page) db.commit() # Add support pages db.add(Page('support.about', 'About', True)) db.add(Page('support.support', 'Support', True)) db.commit() # Create admin role, or check if it already exists existing = Role.query.filter(Role.is_admin).first() if existing is None: role = Role("Admin") db.add(role) db.commit() existing = role else: # Check if there's at least one admin user admin = User.query.filter(User.role_id == existing.id).first() if admin is not None: print("Admin already exists: %s" % admin.name) return user = User(existing.id, sys.argv[2], sys.argv[3], User.generate_hash(sys.argv[4])) db.add(user) db.commit() print("Admin user created with name: %s" % user.name)
def manage(): """Allow editing or accessing account details.""" from run import app form = AccountForm(request.form, g.user) if form.validate_on_submit(): user_to_update = User.query.filter(User.id == g.user.id).first() old_email = None password = False if user_to_update.email != form.email.data: old_email = user_to_update.email user_to_update.email = form.email.data if len(form.new_password.data) >= 10: password = True user_to_update.password = User.generate_hash( form.new_password.data) if user_to_update.name != form.name.data: user_to_update.name = form.name.data g.user = user_to_update g.db.commit() if old_email is not None: template = app.jinja_env.get_or_select_template( 'email/email_changed.txt') message = template.render(name=user_to_update.name, email=user_to_update.email) g.mailer.send_simple_message({ "to": [old_email, user_to_update.email], "subject": "CCExtractor CI platform email changed", "text": message }) if password: template = app.jinja_env.get_or_select_template( 'email/password_changed.txt') message = template.render(name=user_to_update.name) to = user_to_update.email if old_email is None else [ old_email, user_to_update.email ] g.mailer.send_simple_message({ "to": to, "subject": "CCExtractor CI platform password changed", "text": message }) flash('Settings saved') github_url = github_redirect() return {'form': form, 'url': github_url}
def complete_signup(email, expires, mac): from run import app # Check if time expired now = int(time.time()) if now <= expires: # Validate HMAC content_to_hash = "{email}|{expiry}".format(email=email, expiry=expires) real_hash = generate_hmac_hash(app.config.get('HMAC_KEY', ''), content_to_hash) try: authentic = hmac.compare_digest(real_hash, mac) except AttributeError: # Older python version? Fallback which is less safe authentic = real_hash == mac if authentic: # Check if email already exists (sign up twice with same email) user = User.query.filter_by(email=email).first() if user is not None: flash('There is already a user with this email address registered.', 'error-message') return redirect(url_for('.signup')) form = CompleteSignupForm() if form.validate_on_submit(): user = User(form.name.data, email=email, password=User.generate_hash(form.password.data)) g.db.add(user) g.db.commit() session['user_id'] = user.id # Send email template = app.jinja_env.get_or_select_template('email/registration_ok.txt') message = template.render(name=user.name) g.mailer.send_simple_message({ "to": user.email, "subject": "Welcome to the CCExtractor CI platform", "text": message }) return redirect('/') return { 'form': form, 'email': email, 'expires': expires, 'mac': mac } flash('The request to complete the registration was invalid. Please enter your email again to start over.', 'error-message') return redirect(url_for('.signup'))
def complete_reset(uid, expires, mac): from run import app # Check if time expired now = int(time.time()) if now <= int(expires): user = User.query.filter_by(id=uid).first() if user is not None: # Validate HMAC real_hash = hmac.new( app.config.get('HMAC_KEY', ''), "%s|%s|%s" % (uid, expires, user.password) ).hexdigest() try: authentic = hmac.compare_digest(real_hash, mac.encode('utf-8')) except AttributeError: # Older python version? Fallback which is less safe authentic = real_hash == mac if authentic: form = CompleteResetForm(request.form) if form.validate_on_submit(): user.password = User.generate_hash(form.password.data) g.db.commit() template = app.jinja_env.get_or_select_template( 'email/password_reset.txt') message = template.render(name=user.name) g.mailer.send_simple_message({ "to": user.email, "subject": "CCExtractor CI platform password reset", "text": message }) session['user_id'] = user.id return redirect("/") return { 'form': form, 'uid': uid, 'mac': mac, 'expires': expires } flash('The request to reset your password was invalid. Please enter your ' 'email again to start over.', 'error-message') return redirect(url_for('.reset'))
def manage(): """ Function to edit or access account details """ from run import app form = AccountForm(request.form, g.user) if form.validate_on_submit(): user = User.query.filter(User.id == g.user.id).first() old_email = None password = False if user.email != form.email.data: old_email = user.email user.email = form.email.data if len(form.new_password.data) >= 10: password = True user.password = User.generate_hash(form.new_password.data) if user.name != form.name.data: user.name = form.name.data g.user = user g.db.commit() if old_email is not None: template = app.jinja_env.get_or_select_template('email/email_changed.txt') message = template.render(name=user.name, email=user.email) g.mailer.send_simple_message({ "to": [old_email, user.email], "subject": "CCExtractor CI platform email changed", "text": message }) if password: template = app.jinja_env.get_or_select_template('email/password_changed.txt') message = template.render(name=user.name) to = user.email if old_email is None else [old_email, user.email] g.mailer.send_simple_message({ "to": to, "subject": "CCExtractor CI platform password changed", "text": message }) flash('Settings saved') github_url = github_redirect() return { 'form': form, 'url': github_url }
def manage(): form = AccountForm(request.form, g.user) if not g.user.is_admin(): form.email.validators = [] if request.method == 'POST': result = {'status': 'error', 'errors': []} if form.validate_on_submit(): user = User.query.filter(User.id == g.user.id).first() if user.is_admin(): user.email = form.email.data if len(form.new_password.data) >= 10: user.password = User.generate_hash(form.new_password.data) g.user = user g.db.commit() result['status'] = 'success' result['errors'] = form.errors return jsonify(result) return {'form': form}
def complete_reset(uid, expires, mac): from run import app # Check if time expired now = int(time.time()) if now <= expires: user = User.query.filter_by(id=uid).first() if user is not None: # Validate HMAC content_to_hash = "{id}|{expiry}|{passwd}".format(id=uid, expiry=expires, passwd=user.password) real_hash = generate_hmac_hash(app.config.get('HMAC_KEY', ''), content_to_hash) try: authentic = hmac.compare_digest(real_hash, mac) except AttributeError: # Older python version? Fallback which is less safe authentic = real_hash == mac if authentic: form = CompleteResetForm(request.form) if form.validate_on_submit(): user.password = User.generate_hash(form.password.data) g.db.commit() template = app.jinja_env.get_or_select_template('email/password_reset.txt') message = template.render(name=user.name) g.mailer.send_simple_message({ "to": user.email, "subject": "CCExtractor CI platform password reset", "text": message }) session['user_id'] = user.id return redirect("/") return { 'form': form, 'uid': uid, 'mac': mac, 'expires': expires } flash('The request to reset your password was invalid. Please enter your email again to start over.', 'error-message') return redirect(url_for('.reset'))
def manage(): form = AccountForm(request.form, g.user) if not g.user.is_admin(): form.email.validators = [] if request.method == 'POST': result = { 'status': 'error', 'errors': [] } if form.validate_on_submit(): user = User.query.filter(User.id == g.user.id).first() if user.is_admin(): user.email = form.email.data if len(form.new_password.data) >= 10: user.password = User.generate_hash(form.new_password.data) g.user = user g.db.commit() result['status'] = 'success' result['errors'] = form.errors return jsonify(result) return { 'form': form }
def users_ajax(action): result = { 'status': 'error', 'errors': [] } if action == 'create': form = CreateUserForm(request.form) form.role.choices = [(r.id, r.name) for r in Role.query.order_by('name')] if form.validate_on_submit(): # Generate random password password = User.create_random_password() email = None if len(form.email.data) == 0 else form.email.data # No errors, so role is valid, email is valid & username # doesn't exist yet. Create user user = User(form.role.data, form.username.data, email, User.generate_hash(password)) g.db.add(user) g.db.commit() result['status'] = 'success' result['user'] = { 'id': user.id, 'name': user.name, 'role_id': user.role_id, 'role_name': user.role.name, 'email': user.email, 'password': password } result['errors'] = form.errors if action == 'delete': form = UserModifyForm('delete', g.user, request.form) if form.validate_on_submit(): # Delete user user = User.query.filter(User.id == form.id.data).first() g.db.delete(user) g.db.commit() result['status'] = 'success' result['errors'] = form.errors if action == 'change': form = UserModifyForm('change', g.user, request.form) if form.validate_on_submit(): # Change role user = User.query.filter(User.id == form.id.data).first() role = Role.query.filter(Role.id == form.role.data).first() user.role = role g.db.commit() result['status'] = 'success' result['role'] = { 'id': role.id, 'name': role.name } result['errors'] = form.errors if action == 'reset': form = UserModifyForm('reset', g.user, request.form) if form.validate_on_submit(): # Reset password user = User.query.filter(User.id == form.id.data).first() password = User.create_random_password() user.update_password(password) g.db.commit() result['status'] = 'success' result['message'] = 'The password for %s (#%s) was reset to: ' \ '<code>%s</code><br />Please copy ' \ 'this carefully and give it to the user in ' \ 'question.' % (user.name, user.id, password) result['errors'] = form.errors return jsonify(result)
def users_ajax(action): result = {'status': 'error', 'errors': []} if action == 'create': form = CreateUserForm(request.form) form.role.choices = [(r.id, r.name) for r in Role.query.order_by('name')] if form.validate_on_submit(): # Generate random password password = User.create_random_password() email = None if len(form.email.data) == 0 else form.email.data # No errors, so role is valid, email is valid & username # doesn't exist yet. Create user user = User(form.role.data, form.username.data, email, User.generate_hash(password)) g.db.add(user) g.db.commit() result['status'] = 'success' result['user'] = { 'id': user.id, 'name': user.name, 'role_id': user.role_id, 'role_name': user.role.name, 'email': user.email, 'password': password } result['errors'] = form.errors if action == 'delete': form = UserModifyForm('delete', g.user, request.form) if form.validate_on_submit(): # Delete user user = User.query.filter(User.id == form.id.data).first() g.db.delete(user) g.db.commit() result['status'] = 'success' result['errors'] = form.errors if action == 'change': form = UserModifyForm('change', g.user, request.form) if form.validate_on_submit(): # Change role user = User.query.filter(User.id == form.id.data).first() role = Role.query.filter(Role.id == form.role.data).first() user.role = role g.db.commit() result['status'] = 'success' result['role'] = {'id': role.id, 'name': role.name} result['errors'] = form.errors if action == 'reset': form = UserModifyForm('reset', g.user, request.form) if form.validate_on_submit(): # Reset password user = User.query.filter(User.id == form.id.data).first() password = User.create_random_password() user.update_password(password) g.db.commit() result['status'] = 'success' result['message'] = 'The password for %s (#%s) was reset to: ' \ '<code>%s</code><br />Please copy ' \ 'this carefully and give it to the user in ' \ 'question.' % (user.name, user.id, password) result['errors'] = form.errors return jsonify(result)