def copy_profile(pr_id): db = get_db() profile = db.execute(""" SELECT * FROM profile WHERE id = ? """, (pr_id,)).fetchone() if not profile: abort(404) if profile['user_id'] != g.user['id']: abort(403) db = get_db() db.execute(""" INSERT INTO profile (user_id, name, host, port, config) VALUES (?,?,?,?,?) """, ( profile['user_id'], 'Copy of ' + profile['name'], profile['host'], profile['port'], profile['config'])) db.commit() return redirect(url_for('user.profiles'))
def test_convert_local(client, auth, app): auth.login() with app.app_context(): db = get_db() count = db.execute(""" SELECT COUNT(id) FROM profile WHERE user_id = 1 """).fetchone()[0] assert count == 2 resp = client.post('/user/convert_local', data={'user_config': '{"somelocal": "userconfig"}'}) assert resp.status_code == 200 with app.app_context(): db = get_db() count = db.execute(""" SELECT COUNT(id) FROM profile WHERE user_id = 1 """).fetchone()[0] assert count == 3 new_prof = db.execute(""" SELECT * FROM profile WHERE user_id = 1 ORDER BY id DESC LIMIT 1 """).fetchone() assert new_prof['config'] == '{"somelocal": "userconfig"}' assert new_prof['host'] == 'CHANGEME' assert new_prof['port'] == 0 # Sending empty config (should not happen) resp = client.post('/user/convert_local', data={'user_config': ' '}) assert resp.status_code == 200 with app.app_context(): db = get_db() count = db.execute(""" SELECT COUNT(id) FROM profile WHERE user_id = 1 """).fetchone()[0] assert count == 4 new_prof = db.execute(""" SELECT * FROM profile WHERE user_id = 1 ORDER BY id DESC LIMIT 1 """).fetchone() assert new_prof['config'] == None assert new_prof['host'] == 'CHANGEME' assert new_prof['port'] == 0
def edit_profile(pr_id): db = get_db() profile = db.execute(""" SELECT * FROM profile WHERE id = ? """, (pr_id,)).fetchone() if not profile: abort(404) if profile['user_id'] != g.user['id']: abort(403) if request.method == 'POST': name = request.form['name'].strip() host = request.form['host'].strip() port = request.form['port'].strip() error = None if not name: error = 'Profile name is required' elif not host: error = 'Host is required' elif not port: error = 'Port is required' else: try: port = int(port) except ValueError: error = 'Port must be an integer' if error is not None: flash(error) else: db = get_db() db.execute(""" UPDATE profile SET name = ?, host = ?, port = ? WHERE id = ? """, (name, host, port, pr_id)) db.commit() return redirect(url_for('user.profiles')) return render_template('user/edit_profile.html', profile=profile)
def test_copy_profile(client, auth, app): auth.login() assert _profile_count(app, 1) == 2 resp = client.post('/user/876/copy_profile') assert resp.status_code == 404 resp = client.post('/user/3/copy_profile') assert resp.status_code == 403 resp = client.post('/user/2/copy_profile') assert _profile_count(app, 1) == 3 with app.app_context(): db = get_db() ref_prof = db.execute(""" SELECT * FROM profile WHERE id = 2 """).fetchone() prof = db.execute(""" SELECT * FROM profile WHERE user_id = 1 ORDER BY id DESC LIMIT 1 """).fetchone() assert prof['name'] == 'Copy of ' + ref_prof['name'] assert prof['host'] == ref_prof['host'] assert prof['port'] == ref_prof['port'] assert prof['config'] == ref_prof['config']
def login(): if g.user is not None: return redirect(url_for('user.profiles')) form = LoginForm() if form.validate_on_submit(): db = get_db() error = None user = db.execute("SELECT * FROM user WHERE lower(email) = lower(?)", (form.email.data, )).fetchone() if user is None: error = "Incorrect email." elif not check_password_hash(user["password"], form.password.data): error = "Incorrect password." if error is None: # store the user id in a new session and return to the index session.clear() session["user_id"] = user["id"] return redirect(url_for("user.profiles")) flash(error) return render_template("auth/login.html", form=form)
def create_profile(): if request.method == 'POST': name = request.form['name'].strip() host = request.form['host'].strip() port = request.form['port'].strip() error = None if not name: error = 'Profile name is required' elif not host: error = 'Host is required' elif not port: error = 'Port is required' else: try: port = int(port) except ValueError: error = 'Port must be an integer' if error is not None: flash(error) else: db = get_db() db.execute(""" INSERT INTO profile (user_id, name, host, port) VALUES (?,?,?,?) """, (g.user['id'], name, host, port)) db.commit() return redirect(url_for('user.profiles')) return render_template('user/create_profile.html')
def test_register_confirm(mocker, client, app): sig = auth.dump_sig(app, {'email': '*****@*****.**'}, auth.REGISTER_SALT) assert client.get(f"/auth/{sig}/register").status_code == 200 # test that successful registration redirects to the login page response = client.post(f"/auth/{sig}/register", data={"password": "******", "password2": "a"}) assert "http://localhost/auth/login" == response.headers["Location"] # test that the user was inserted into the database with app.app_context(): assert ( get_db().execute("select * from user where email = '*****@*****.**'").fetchone() is not None ) response = client.post(f"/auth/{sig}/register", data={"password": "******", "password2": "a"}, follow_redirects=True) assert b'already registered' in response.data mocker.patch.object(auth, 'load_sig') auth.load_sig.side_effect = itsdangerous.SignatureExpired('some message') response = client.post( f"/auth/{sig}/register", data={"password": "******", "password2": "a"}, follow_redirects=True) assert b'expired' in response.data
def register_confirm(sig): if g.user is not None: return redirect(url_for('user.profiles')) try: o = load_sig(current_app, sig, 3600, REGISTER_SALT) except SignatureExpired: flash('Registration link expired.') return redirect(url_for('auth.register')) email = o['email'] db = get_db() row = db.execute("SELECT 1 FROM user WHERE lower(email) = lower(?)", (email, )).fetchone() if row is not None: flash(f'{email} is already registered.') return redirect(url_for('auth.login')) form = SetPasswordForm() if form.validate_on_submit(): db.execute("INSERT INTO user (email, password) VALUES (?, ?)", (email, generate_password_hash(form.password.data))) db.commit() flash(f'{email} registration completed.') return redirect(url_for("auth.login")) return render_template('auth/set_password.html', email=email, form=form)
def app(): db_fd, db_path = tempfile.mkstemp() app = create_app({ 'TESTING': True, 'DATABASE': db_path, 'WTF_CSRF_ENABLED': False }) with app.app_context(): migrate_db() get_db().executescript(_data_sql) yield app os.close(db_fd) os.unlink(db_path)
def _profile_count(app, user_id): with app.app_context(): db = get_db() count = db.execute( """ SELECT COUNT(id) FROM profile WHERE user_id = ? """, (user_id, )).fetchone()[0] return count
def profiles(): db = get_db() profiles = db.execute(""" SELECT * FROM profile WHERE user_id = ? """, (g.user['id'],)) return render_template( 'user/profiles.html', profiles=profiles)
def load_logged_in_user(): """If a user id is stored in the session, load the user object from the database into ``g.user``.""" user_id = session.get("user_id") if user_id is None: g.user = None else: g.user = (get_db().execute("SELECT * FROM user WHERE id = ?", (user_id, )).fetchone())
def migrate(): if request.method == 'GET': migr_id = request.args.get('migr_id') db = get_db(); row = db.execute(""" SELECT config FROM client_migrate WHERE id = ? """, (migr_id,)).fetchone() return {'config': row['config']}, 200 elif request.method == 'POST': d = request.json if not d: return {'error': 'no json'}, 400 if 'complete' in d: migr_id = d['migr_id'] db = get_db() db.execute(""" UPDATE client_migrate SET complete = 1 WHERE id = ? """, (migr_id,)) db.commit() return {}, 200 else: if 'config' not in d: return {'error': 'missing config'}, 400 new_uuid = str(uuid.uuid4()) db = get_db() db.execute(""" INSERT INTO client_migrate (id, config) VALUES (?,?) """, ( new_uuid, d['config'])) db.commit() return {'migr_id': new_uuid}, 200
def delete_profile(pr_id): db = get_db() profile = db.execute(""" SELECT * FROM profile WHERE id = ? """, (pr_id,)).fetchone() if not profile: abort(404) if profile['user_id'] != g.user['id']: abort(403) db.execute("DELETE FROM profile WHERE id = ?", (pr_id,)) db.commit() return redirect(url_for('user.profiles'))
def admin_login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] db = get_db() error = None admin_user = db.execute('SELECT * FROM admin_user WHERE username = ?', (username, )).fetchone() if admin_user is None: error = 'Incorrect username.' elif not check_password_hash(admin_user['password'], password): error = 'Incorrect password.' if error is None: session.clear() session['admin_user_id'] = admin_user['id'] return redirect(url_for('admin.index')) flash(error) return render_template('auth/admin_login.html')
def get_profile(): if g.user is None: abort(403) if 'id' not in request.args: abort(400) pr_id = request.args['id'] db = get_db() profile = db.execute(""" SELECT * FROM profile WHERE id = ? """, (pr_id,)).fetchone() if not profile: abort(404) if profile['user_id'] != g.user['id']: abort(403) return dict(profile), 200
def reset_password(): if g.user is not None: return redirect(url_for('user.profiles')) form = ResetPasswordForm() if form.validate_on_submit(): db = get_db() user = db.execute("SELECT * FROM user WHERE lower(email) = lower(?)", (form.email.data, )).fetchone() email = user['email'] sig = dump_sig(current_app, {'email': email}, RESET_SALT) reset_url = url_for('auth.reset_password_confirm', sig=sig, _external=True) msg = Message('Mudslinger Password Reset', sender=('Mudslinger Client', '*****@*****.**'), recipients=[email]) msg.html = f""" <span><b>You have requested a password reset.</b></span> <br> <br> <span>Please follow the link below to set a new password.</span> <br> <span>Note: the link will expire after 60 minutes.</span> <br> <a href={reset_url}>{reset_url}</a>""" mail.send(msg) flash( f'An email with a password reset link has been sent to {form.email.data}. ' 'Please check your inbox.') form.email.data = '' return render_template('auth/reset_password.html', form=form)
def test_delete_profile(client, auth, app): auth.login() assert _profile_count(app, 1) == 2 resp = client.post('/user/876/delete_profile') assert resp.status_code == 404 resp = client.post('/user/3/delete_profile') assert resp.status_code == 403 resp = client.post('/user/2/delete_profile') assert _profile_count(app, 1) == 1 with app.app_context(): db = get_db() prof = db.execute(""" SELECT * FROM profile WHERE id = 2 """).fetchone() assert prof is None
def reset_password_confirm(sig): if g.user is not None: return redirect(url_for('user.profiles')) try: o = load_sig(current_app, sig, 3600, RESET_SALT) except SignatureExpired: flash('Reset link expired.') return redirect(url_for('auth.login')) email = o['email'] form = SetPasswordForm() if form.validate_on_submit(): db = get_db() db.execute("UPDATE user SET password = ? WHERE email = ?", (generate_password_hash(form.password.data), email)) db.commit() flash('Password was updated.') return redirect(url_for('auth.login')) return render_template('auth/set_password.html', email=email, form=form)
def save_profile_config(): if g.user is None: abort(403) d = request.json if not d: abort(400) if 'id' not in d: abort(400) if 'config' not in d: abort(400) pr_id = d['id'] config = d['config'] db = get_db() profile = db.execute(""" SELECT * FROM profile WHERE id = ? """, (pr_id,)).fetchone() if profile is None: abort(404) if profile['user_id'] != g.user['id']: abort(403) db.execute(""" UPDATE profile SET config = ? WHERE id = ? """, (config, pr_id)) db.commit() return {}, 200