Example #1
0
def login():
    title = 'Login'

    if current_user.is_authenticated:
        return redirect(url_for('main.index'))

    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data.lower()).first()
        if user and bcrypt.check_password_hash(user.password.encode(), form.password.data):
            if user.activated != 0:
                session['email'] = user.email
                session['master_key'] = decrypt(get_key(form.password.data), user.master_key)
                if user.otp_secret is None:
                    login_user(user, remember=form.remember.data)
                    session['encryption_key'] = get_key(session['master_key'])
                    next_page = request.args.get('next')
                    return redirect(next_page) if next_page else redirect(url_for('main.index'))
                else:
                    return redirect(url_for('account.login_2fa'))
            else:
                flash(Markup(f'Your  email address is not confirmed. Check your email for the verification link or '
                      f'<a href="{url_for("account.resend_activation_link", email=user.email)}">'
                             f'send again.</a>'), 'warning')
        else:
            flash('Invalid email or password!', 'danger')

    return render_template('account/login.html', title=title, form=form)
Example #2
0
def account_settings():
    title = 'Account Settings'

    # Check if 2fa is enabled for current user
    if current_user.otp_secret is None:
        tfa = False
    else:
        tfa = True

    form = UpdateAccountForm()
    if form.validate_on_submit():
        if bcrypt.check_password_hash(current_user.password.encode(), form.current_password.data):
            if form.email.data != current_user.email:
                current_user.email = form.email.data
                current_user.activated = False
                send_activation_email(current_user)
                flash('Email address has been changed. Please check your email for the verification link.', 'success')
            if form.new_password.data:
                current_user.password = bcrypt.generate_password_hash(form.new_password.data)
                current_user.master_key = encrypt(get_key(form.new_password.data), session['master_key'])
                flash('Password has been updated.', 'success')
            db.session.commit()
            return redirect(url_for('account.account_settings'))
    elif request.method == 'GET':
        form.email.data = current_user.email

    return render_template('account/account_settings.html', title=title, form=form, tfa=tfa)
Example #3
0
def register():
    title = 'Create an account'

    if current_user.is_authenticated:
        return redirect(url_for('main.index'))

    form = RegistrationForm()
    if form.validate_on_submit():
        email = form.email.data.lower()
        hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
        master_key = generate_pswrd(length=32, special=False)
        encrypted_master_key = encrypt(get_key(form.password.data), master_key)
        user = User(email=email, password=hashed_password, master_key=encrypted_master_key)

        try:
            send_activation_email(user)
            flash('Account created! Verification link has been sent to your email.', 'success')
        except SMTPRecipientsRefused:
            flash('Entered email address is invalid!', 'danger')
            return redirect(url_for('account.register'))
        except:
            user.activated = True
            flash('Account created! You can now log in.', 'success')

        db.session.add(user)
        db.session.commit()

        return redirect(url_for('account.login'))

    return render_template('account/register.html', title=title, form=form)
Example #4
0
def import_encrypted_user_data(data, master_key):
    data = json.loads(data)
    encryption_key = get_key(master_key)

    passwords = []
    for entry_id in data['passwords']:
        entry = data['passwords'][entry_id]
        entry['name'] = entry['name']
        entry['site'] = entry['site']
        entry['username'] = entry['username']
        entry['password'] = entry['password']
        passwords.append(
            Password(name=entry['name'],
                     site=entry['site'],
                     username=entry['username'],
                     password=entry['password']))

    secure_notes = []
    for entry_id in data['secure_notes']:
        entry = data['secure_notes'][entry_id]
        entry['name'] = entry['name']
        entry['content'] = entry['content']
        secure_notes.append(
            SecureNote(name=entry['name'], content=entry['content']))

    credit_cards = []
    for entry_id in data['credit_cards']:
        entry = data['credit_cards'][entry_id]
        entry['name'] = entry['name']
        entry['number'] = entry['number']
        entry['expiration_date'] = entry['expiration_date']
        entry['cvv'] = entry['cvv']
        entry['cardholder_name'] = entry['cardholder_name']
        credit_cards.append(
            CreditCard(name=entry['name'],
                       number=entry['number'],
                       expiration_date=entry['expiration_date'],
                       cvv=entry['cvv'],
                       cardholder_name=entry['cardholder_name']))

    decrypted_passwords = []
    for entry in passwords:
        entry = decrypt_password(encryption_key, entry)
        decrypted_passwords.append(entry)

    decrypted_secure_notes = []
    for entry in secure_notes:
        entry = decrypt_secure_note(encryption_key, entry)
        decrypted_secure_notes.append(entry)

    decrypted_credit_cards = []
    for entry in credit_cards:
        entry = decrypt_credit_card(encryption_key, entry)
        decrypted_credit_cards.append(entry)

    return decrypted_passwords, decrypted_secure_notes, decrypted_credit_cards
Example #5
0
def reset_token(token):
    title = 'Reset Password'

    if current_user.is_authenticated:
        return redirect(url_for('main.index'))

    user = User.verify_reset_token(token)
    if not user:
        flash('Invalid or expired token.', 'danger')
        return redirect(url_for('account.reset_request'))

    form = ResetPasswordForm()
    if form.validate_on_submit():

        if bcrypt.check_password_hash(user.password.encode(), form.password.data):
            flash('The password you entered is already set.', 'danger')
            return redirect(url_for('account.reset_token', token=token))

        file_contents = ''
        if form.master_key_file.data:
            file_contents = form.master_key_file.data.stream.readline().decode('utf-8')

        if not form.master_key.data and not file_contents and form.lost_master_key.data:
            wipe_user_data(user)
            master_key = generate_pswrd(length=32, special=False)
            user.master_key = encrypt(get_key(form.password.data), master_key)
            flash('User data has been permanently erased! Master key has been reset.', 'warning')
        elif not check_master_key(form.master_key.data, user) and not check_master_key(file_contents, user):
            flash('Master key invalid or not provided!', 'danger')
            return redirect(url_for('account.reset_token', token=token))
        else:
            user.master_key = encrypt(get_key(form.password.data), form.master_key.data)

        user.password = bcrypt.generate_password_hash(form.password.data)
        db.session.commit()
        flash('Password has been updated.', 'success')
        return redirect(url_for('account.login'))

    return render_template('account/password_reset_token.html', title=title, form=form)
Example #6
0
def change_master_key():
    title = 'Get a New Master Key'

    form = ChangeMasterKeyForm()
    if form.validate_on_submit():
        if bcrypt.check_password_hash(current_user.password.encode(), form.password.data):
            current_user.master_key = encrypt(get_key(form.password.data), form.master_key.data)

            old_encryption_key = session['encryption_key']
            new_encryption_key = get_key(form.master_key.data)
            reencrypt_user_data(current_user, old_encryption_key, new_encryption_key)
            db.session.commit()

            session['master_key'] = form.master_key.data
            session['encryption_key'] = new_encryption_key
            flash('Master key has been changed. Don\'t forget to save it in a secure place!', 'success')
            return redirect(url_for('account.account_settings'))
        else:
            flash('The password you entered is incorrect.', 'danger')
            return redirect(url_for('account.change_master_key'))
    elif request.method == 'GET':
        form.master_key.data = generate_pswrd(length=32, special=False)

    return render_template('account/change_master_key.html', title=title, form=form)
Example #7
0
def login_2fa():
    title = 'Login'

    user = User.query.filter_by(email=session['email']).first()
    form = TFAForm()
    if form.validate_on_submit():
        if user.verify_totp(form.security_code.data):
            login_user(user, remember=form.remember.data)
            session['encryption_key'] = get_key(session['master_key'])
            return redirect(url_for('main.index'))
        else:
            session['email'] = None
            session['master_key'] = None
            flash('Invalid security code!', 'danger')
            return redirect(url_for('account.login'))

    return render_template('account/login_2fa.html', title=title, form=form)
Example #8
0
def check_master_key(master_key, user):
    """Checks if provided master key is valid by trying to decrypt user data with it."""
    encryption_key = get_key(master_key)

    try:
        get_user_passwords(user, encryption_key)
    except:
        return False

    try:
        get_user_secure_notes(user, encryption_key)
    except:
        return False

    try:
        get_user_credit_cards(user, encryption_key)
    except:
        return False

    return True