building out auth routes

main
lza_menace 3 years ago
parent e30185d85e
commit ddfb382e50

@ -1,5 +1,6 @@
Flask-WTF
flask-login
flask-bcrypt
hypercorn
Pillow
psycopg2-binary

@ -1,5 +1,7 @@
import quart.flask_patch
from quart import Quart
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from xmrbackers.cli import cli
from xmrbackers import config
@ -15,12 +17,27 @@ async def _setup_db(app: Quart):
def create_app():
app = Quart(__name__)
app.config.from_envvar('QUART_SECRETS')
app = cli(app)
@app.before_serving
async def startup():
from xmrbackers.routes import meta, api
from xmrbackers.routes import meta, api, auth
from xmrbackers import filters
await _setup_db(app)
app.register_blueprint(meta.bp)
app.register_blueprint(api.bp)
app.register_blueprint(auth.bp)
app.register_blueprint(filters.bp)
return cli(app)
login_manager = LoginManager(app)
# Login manager
login_manager.login_view = 'auth.login'
login_manager.logout_view = 'auth.logout'
@login_manager.user_loader
def load_user(user_id):
from xmrbackers.models import User
user = User.query.get(user_id)
return user.id
return app
bcrypt = Bcrypt(create_app())

@ -1,8 +1,15 @@
import quart.flask_patch
from flask_wtf import FlaskForm
from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired
class Login(FlaskForm):
username = StringField('Username:', validators=[DataRequired()], render_kw={"placeholder": "Username", "class": "form-control", "type": "text"})
email = StringField('Email Address:', validators=[DataRequired()], render_kw={"placeholder": "Email", "class": "form-control", "type": "email"})
password = StringField('Password:', validators=[DataRequired()], render_kw={"placeholder": "Password", "class": "form-control", "type": "password"})
class Register(FlaskForm):
username = StringField('Username:', validators=[DataRequired()], render_kw={"placeholder": "Username", "class": "form-control", "type": "text"})
email = StringField('Email Address:', validators=[DataRequired()], render_kw={"placeholder": "Email", "class": "form-control", "type": "email"})
password = StringField('Password:', validators=[DataRequired()], render_kw={"placeholder": "Password", "class": "form-control", "type": "password"})

@ -12,29 +12,52 @@ db = pw.PostgresqlDatabase(
host=config.DB_HOST,
)
class Creator(pw.Model):
class User(pw.Model):
id = pw.AutoField()
register_date = pw.DateTimeField(default=datetime.now)
last_login_date = pw.DateTimeField(default=datetime.now)
wallet_address = pw.CharField()
username = pw.CharField(unique=True)
email = pw.CharField(unique=True)
password = pw.CharField(unique=True)
@property
def is_authenticated(self):
return True
@property
def is_active(self):
return True
@property
def is_anonymous(self):
return False
@property
def is_admin(self):
return self.admin
def get_id(self):
return self.id
class Meta:
database = db
class CreatorProfile(pw.Model):
id = pw.AutoField()
user = pw.ForeignKeyField(User)
create_date = pw.DateTimeField(default=datetime.now)
last_login_date = pw.DateTimeField(default=datetime.now)
wallet_address = pw.CharField(null=True)
bio = pw.CharField()
class Meta:
database = db
class Backer(pw.Model):
class BackerProfile(pw.Model):
id = pw.AutoField()
register_date = pw.DateTimeField(default=datetime.now)
last_login_date = pw.DateTimeField(default=datetime.now)
wallet_address = pw.CharField()
username = pw.CharField(unique=True)
email = pw.CharField(unique=True)
password = pw.CharField(unique=True)
class Meta:
database = db
@ -43,7 +66,7 @@ class Backer(pw.Model):
class SubscriptionMeta(pw.Model):
id = pw.AutoField()
create_date = pw.DateTimeField(default=datetime.now)
creator = pw.ForeignKeyField(Creator)
creator = pw.ForeignKeyField(CreatorProfile)
atomic_xmr = pw.BigIntegerField()
number_hours = pw.IntegerField()
@ -59,8 +82,8 @@ class Subscription(pw.Model):
id = pw.AutoField()
subscribe_date = pw.DateTimeField(default=datetime.now)
active = pw.BooleanField(default=True)
creator = pw.ForeignKeyField(Creator)
backer = pw.ForeignKeyField(Backer)
creator = pw.ForeignKeyField(CreatorProfile)
backer = pw.ForeignKeyField(BackerProfile)
meta = pw.ForeignKeyField(SubscriptionMeta)
xmr_address = pw.CharField(unique=True)
xmr_acct_idx = pw.BigIntegerField(unique=True) # in case it gets many subscribers
@ -76,7 +99,7 @@ class TextPost(pw.Model):
content = pw.TextField()
title = pw.CharField()
last_edit_date = pw.DateTimeField(default=datetime.now)
creator = pw.ForeignKeyField(Creator)
creator = pw.ForeignKeyField(CreatorProfile)
class Meta:
database = db

@ -0,0 +1,120 @@
import quart.flask_patch
from quart import Blueprint, render_template
from quart import flash, redirect, url_for
from flask_login import login_user, logout_user, current_user
from xmrbackers.factory import bcrypt
from xmrbackers.forms import Register
from xmrbackers.models import User
bp = Blueprint('auth', 'auth')
@bp.route("/register", methods=["GET", "POST"])
async def register():
form = Register()
# if current_user.is_authenticated:
# flash('Already registered and authenticated.')
# return redirect(url_for('meta.index'))
# return 'gotem'
if form.validate_on_submit():
# Check if email already exists
user = User.query.filter_by(email=form.email.data).first()
if user:
flash('This email is already registered.')
# return redirect(url_for('auth.login'))
return 'gotem'
# Save new user
user = User(
email=form.email.data,
username=form.username.data,
password=bcrypt.generate_password_hash(form.password.data).decode('utf8'),
)
user.save()
login_user(user)
return redirect(url_for('meta.index'))
return await render_template("auth/register.html", form=form)
#
# @auth_bp.route("/login", methods=["GET", "POST"])
# def login():
# form = Login()
# if current_user.is_authenticated:
# flash('Already registered and authenticated.')
# return redirect(url_for('wallet.dashboard'))
#
# if form.validate_on_submit():
# # Check if user doesn't exist
# user = User.query.filter_by(email=form.email.data).first()
# if not user:
# flash('Invalid username or password.')
# return redirect(url_for('auth.login'))
#
# # Check if password is correct
# password_matches = bcrypt.check_password_hash(
# user.password,
# form.password.data
# )
# if not password_matches:
# flash('Invalid username or password.')
# return redirect(url_for('auth.login'))
#
# # Capture event, login user, and redirect to wallet page
# capture_event(user.id, 'login')
# login_user(user)
# return redirect(url_for('wallet.dashboard'))
#
# return render_template("auth/login.html", form=form)
#
# @auth_bp.route("/logout")
# def logout():
# if current_user.is_authenticated:
# docker.stop_container(current_user.wallet_container)
# capture_event(current_user.id, 'stop_container')
# current_user.clear_wallet_data()
# capture_event(current_user.id, 'logout')
# logout_user()
# return redirect(url_for('meta.index'))
#
# @auth_bp.route("/delete", methods=["GET", "POST"])
# @login_required
# def delete():
# form = Delete()
# if form.validate_on_submit():
# docker.stop_container(current_user.wallet_container)
# capture_event(current_user.id, 'stop_container')
# sleep(1)
# docker.delete_wallet_data(current_user.id)
# capture_event(current_user.id, 'delete_wallet')
# current_user.clear_wallet_data(reset_password=True, reset_wallet=True)
# flash('Successfully deleted wallet data')
# return redirect(url_for('wallet.setup'))
# else:
# flash('Please confirm deletion of the account')
# return redirect(url_for('wallet.dashboard'))
#
# @auth_bp.route("/reset/<string:hash>", methods=["GET", "POST"])
# def reset(hash):
# hash = PasswordReset.query.filter(PasswordReset.hash==hash).first()
# if not hash:
# flash('Invalid password reset hash')
# return redirect(url_for('auth.login'))
#
# if hash.hours_elapsed() > hash.expiration_hours or hash.expired:
# flash('Reset hash has expired')
# return redirect(url_for('auth.login'))
#
# form = ResetPassword()
# if form.validate_on_submit():
# try:
# user = User.query.get(hash.user)
# user.password = bcrypt.generate_password_hash(form.password.data).decode('utf8')
# hash.expired = True
# db.session.commit()
# flash('Password reset successfully')
# return redirect(url_for('auth.login'))
# except:
# flash('Error resetting password')
# return redirect(url_for('auth.login'))
#
# return render_template('auth/reset.html', form=form)

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
{% include 'includes/head.html' %}
<body class="is-preload landing">
<div id="page-wrapper">
<section id="banner">
<div class="content">
<header>
<h2>Register</h2>
<p>Authenticated: {{ current_user.is_authenticated }}</p>
<form>
{{ form.username }}
{{ form.password }}
{{ form.email }}
</form>
</header>
<span class="image"><img src="/static/images/monero-logo.png" width=150px></span>
</div>
<a href="#swap" class="goto-next scrolly">Next</a>
</section>
{% include 'includes/footer.html' %}
</div>
{% include 'includes/scripts.html' %}
</body>
</html>

@ -10,8 +10,7 @@
<h1 id="logo"><a href="/">MyThing sample app</a></h1>
<nav id="nav">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/#search" class="button primary">Search</a></li>
<li><a href="/register" class="button primary">Register</a></li>
</ul>
</nav>
</header>

Loading…
Cancel
Save