def send_payment_functional(self, app, client, auth): from_username = str(uuid.uuid4()) from_passwd = str(uuid.uuid4()) from_balance = randint(100, 10000) from_uid = BaseCSRFTest._add_user(app, from_username, from_passwd, from_balance) to_username = str(uuid.uuid4()) to_passwd = str(uuid.uuid4()) to_balance = randint(100, 10000) to_uid = BaseCSRFTest._add_user(app, to_username, to_passwd, to_balance) auth.login(from_username, from_passwd) csrf_token = auth.csrf_token("/send") amount = randint(1, from_balance) client.post("/send", data={ 'to_user_id': to_uid, 'amount': amount, 'csrf_token': csrf_token }) with app.app_context(): db = get_db() # check balances new_from_balance = db.execute( "SELECT balance FROM user WHERE id = ?", (from_uid, )).fetchone()["balance"] new_to_balance = db.execute( "SELECT balance FROM user WHERE id = ?", (to_uid, )).fetchone()["balance"] if new_from_balance != from_balance - amount or new_to_balance != to_balance + amount: return False, "Send amount is broken" return True, "Send payment - OK" csrf_token = self._get_csrf_token(app, client, auth, "/send") return self._send_payment(app, client, auth, csrf_token)
def register(): if request.method == "POST": username = request.form["username"] password = request.form["password"] db = get_db() error = None if not username: error = "Username required" if not password: error = "Password required" elif (db.execute("SELECT id FROM user WHERE username = ?", (username, )).fetchone() is not None): error = "User {0} is already registered.".format(username) if error is None: db.execute( "INSERT INTO user (username, password, balance) VALUES (?, ?, ?)", (username, generate_password_hash(password), 1000)) db.commit() return redirect(url_for("auth.login")) flash(error) return render_template("auth/register.html")
def load_logged_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 _add_user(app, username, password, balance): with app.app_context(): db = get_db() cursor = db.cursor() cursor.execute("INSERT INTO user (username, password, balance) VALUES (?, ?, ?)", (username, generate_password_hash(password), balance) ) db.commit() return cursor.lastrowid
def _add_payment(app, from_user_id, to_user_id, amount): with app.app_context(): db = get_db() cursor = db.cursor() cursor.execute("INSERT INTO payment (from_user_id, to_user_id, amount, created_at) " "VALUES (?, ?, ?, date('now'))", (from_user_id, to_user_id, amount) ) db.commit() return cursor.lastrowid
def user_payments(): db = get_db() payments = db.execute( "SELECT p.id, p.amount, p.created_at, u_from.username as from_username, " "u_to.username as to_username " "FROM payment as p " "JOIN user as u_from ON p.from_user_id = u_from.id " "JOIN user as u_to ON p.to_user_id = u_to.id " "WHERE p.from_user_id = ? OR p.to_user_id = ? " "ORDER BY created_at DESC", (g.user["id"], g.user["id"])).fetchall() return render_template("payments/payments_list.html", payments=payments, balance=g.user["balance"])
def send(): db = get_db() if request.method == "POST": amount = int(request.form["amount"]) if g.user["balance"] < amount: flash("Not enough money on balance") return redirect("/") if amount <= 0: flash("You can not transfer a negative amount") return redirect("/send") to_user_id = request.form["to_user_id"] if to_user_id == g.user["id"]: flash("You cannot send payment to yourself") return redirect("/send") db.execute("UPDATE user SET balance = balance - ? WHERE id = ?", (amount, g.user["id"])) db.execute("UPDATE user SET balance = balance + ? WHERE id = ?", (amount, to_user_id)) db.execute( "INSERT INTO payment (from_user_id, to_user_id, amount, created_at) " "VALUES (?, ?, ?, date('now'))", (g.user["id"], to_user_id, amount)) db.commit() return redirect("/") users = db.execute("SELECT id, username FROM user WHERE id <> ?", (g.user["id"], )).fetchall() return render_template_string(''' {% extends 'base.html' %} {% block header %} <h1>{% block title %}Send Money{% endblock %}</h1> {% endblock %} {% block content %} <form method="post"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> <label for="amount">Amount</label> <input type="number" name="amount" id="amount" value="0" step="0.01" required> <label for="to_user_id">To user</label> <select name="to_user_id" id="to_user_id"> {% for user in users %} <option value="{{ user.id }}">{{ user.username }}</option> {% endfor %} </select> <input type="submit" value="Add payment"> </form> {% endblock %} ''', users=users)
def login(): if request.method == "POST": username = request.form["username"] password = request.form["password"] db = get_db() error = None user = db.execute("SELECT * FROM user WHERE username = ?", (username, )).fetchone() if user is None or not check_password_hash(user["password"], password): error = "Incorrect username or password" if error is None: session.clear() session["user_id"] = user["id"] return redirect(url_for("payments.user_payments")) flash(error) return render_template("auth/login.html")