introducing auth blueprints, refactoring app init, setting up forms and sqlalchemy, starting user registration process
parent
f245272796
commit
218500c20c
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
source .venv/bin/activate
|
||||
export FLASK_APP=wowstash/run.py
|
||||
export FLASK_APP=wowstash/app.py
|
||||
export FLASK_SECRETS=config.py
|
||||
export FLASK_DEBUG=1
|
||||
flask run
|
||||
|
@ -0,0 +1,6 @@
|
||||
from wowstash.factory import create_app
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = create_app()
|
||||
app.run()
|
@ -1,2 +1,3 @@
|
||||
from .account import account_bp
|
||||
from .authentication import authentication_bp
|
||||
from .meta import meta_bp
|
||||
|
@ -0,0 +1,5 @@
|
||||
from flask import Blueprint
|
||||
|
||||
meta_bp = Blueprint("meta", __name__)
|
||||
|
||||
from . import routes
|
@ -0,0 +1,23 @@
|
||||
from flask import request, render_template, session, redirect, url_for, make_response, jsonify
|
||||
from wowstash.blueprints.meta import meta_bp
|
||||
from wowstash.library.jsonrpc import daemon
|
||||
from wowstash.library.info import info
|
||||
from wowstash.library.db import Database
|
||||
|
||||
|
||||
@meta_bp.route('/')
|
||||
def index():
|
||||
return render_template('index.html', node=daemon.info(), info=info.get_info())
|
||||
|
||||
@meta_bp.route('/health')
|
||||
def health():
|
||||
return make_response(jsonify({
|
||||
'cache': info.redis.ping(),
|
||||
'db': Database().connected
|
||||
}), 200)
|
||||
|
||||
# @app.errorhandler(404)
|
||||
# def not_found(error):
|
||||
# return make_response(jsonify({
|
||||
# 'error': 'Page not found'
|
||||
# }), 404)
|
@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def not_found(error):
|
||||
return make_response(jsonify({
|
||||
'error': 'Page not found'
|
||||
}), 404)
|
||||
|
||||
@app.cli.command('initdb')
|
||||
def initdb():
|
||||
from wowstash.models import *
|
||||
db.create_all()
|
@ -0,0 +1,61 @@
|
||||
import wowstash.models
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_session import Session
|
||||
from flask_bcrypt import Bcrypt
|
||||
from redis import Redis
|
||||
from wowstash.blueprints.authentication import authentication_bp
|
||||
from wowstash.blueprints.account import account_bp
|
||||
from wowstash.blueprints.meta import meta_bp
|
||||
from wowstash import config
|
||||
|
||||
|
||||
app = None
|
||||
db = None
|
||||
bcrypt = None
|
||||
|
||||
def _setup_db(app: Flask):
|
||||
global db
|
||||
uri = 'postgresql+psycopg2://{user}:{pw}@{url}/{db}'.format(
|
||||
user=config.DB_USER,
|
||||
pw=config.DB_PASS,
|
||||
url=config.DB_HOST,
|
||||
db=config.DB_NAME
|
||||
)
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = uri
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
db = SQLAlchemy(app)
|
||||
db.create_all()
|
||||
|
||||
def _setup_session(app: Flask):
|
||||
app.config['SESSION_TYPE'] = 'redis'
|
||||
app.config['SESSION_COOKIE_NAME'] = app.config.get('SESSION_COOKIE_NAME', 'wowstash')
|
||||
app.config['SESSION_REDIS'] = Redis(
|
||||
host=app.config['REDIS_HOST'],
|
||||
port=app.config['REDIS_PORT']
|
||||
)
|
||||
Session(app)
|
||||
|
||||
def _setup_bcrypt(app: Flask):
|
||||
bcrypt = Bcrypt(app)
|
||||
|
||||
def create_app():
|
||||
global app
|
||||
global db
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_envvar('FLASK_SECRETS')
|
||||
app.secret_key = app.config['SECRET_KEY']
|
||||
|
||||
# Setup backends
|
||||
_setup_db(app)
|
||||
_setup_session(app)
|
||||
_setup_bcrypt(app)
|
||||
|
||||
# Routes
|
||||
app.register_blueprint(meta_bp)
|
||||
app.register_blueprint(authentication_bp)
|
||||
app.register_blueprint(account_bp)
|
||||
|
||||
app.app_context().push()
|
||||
return app
|
@ -0,0 +1,8 @@
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
|
||||
class Register(FlaskForm):
|
||||
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"})
|
@ -0,0 +1,23 @@
|
||||
from sqlalchemy import Column, Integer, DateTime, String
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.sql import func
|
||||
from flask_bcrypt import generate_password_hash, check_password_hash
|
||||
from wowstash.factory import db
|
||||
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class User(db.Model):
|
||||
__tablename__ = 'users'
|
||||
|
||||
id = db.Column('user_id', db.Integer, primary_key=True)
|
||||
password = db.Column(db.String(120))
|
||||
email = db.Column(db.String(50), unique=True, index=True)
|
||||
subaddress_index = db.Column(db.Integer)
|
||||
registered_on = db.Column(db.DateTime, server_default=func.now())
|
||||
|
||||
def hash_password(self):
|
||||
self.password = generate_password_hash(self.password).decode('utf8')
|
||||
|
||||
def check_password(self, password):
|
||||
return check_password_hash(self.password, password)
|
@ -1,51 +0,0 @@
|
||||
from flask import Flask, jsonify, request, make_response, render_template, session, redirect, url_for, escape
|
||||
from flask_session import Session
|
||||
from datetime import timedelta, datetime
|
||||
from redis import Redis
|
||||
from wowstash.library.jsonrpc import daemon
|
||||
from wowstash.library.info import info
|
||||
from wowstash.library.db import Database
|
||||
from wowstash import config
|
||||
# from wowstash.blueprints.account import account_bp
|
||||
# from wowstash.blueprints.authentication import authentication_bp
|
||||
|
||||
# Setup app
|
||||
app = Flask(__name__)
|
||||
app.config.from_envvar('FLASK_SECRETS')
|
||||
app.secret_key = app.config['SECRET_KEY']
|
||||
|
||||
# Setup sessions
|
||||
app.config['SESSION_REDIS'] = Redis(
|
||||
host=app.config['REDIS_HOST'],
|
||||
port=app.config['REDIS_PORT']
|
||||
)
|
||||
sess = Session()
|
||||
sess.init_app(app)
|
||||
|
||||
# app.register_blueprint(account_bp)
|
||||
# app.register_blueprint(authentication_bp)
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('home.html', node=daemon.info(), info=info.get_info())
|
||||
|
||||
@app.route('/health')
|
||||
def health():
|
||||
return make_response(jsonify({
|
||||
'cache': info.redis.ping(),
|
||||
'db': Database().connected
|
||||
}), 200)
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def not_found(error):
|
||||
return make_response(jsonify({
|
||||
'error': 'Page not found'
|
||||
}), 404)
|
||||
|
||||
@app.cli.command('eviscerate')
|
||||
def eviscerate():
|
||||
print('Eviscerate the proletariat')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
{% include 'head.html' %}
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
{% include 'navbar.html' %}
|
||||
|
||||
<header class="masthead">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100">
|
||||
<div class="col-lg-12 my-auto">
|
||||
<div class="header-content mx-auto">
|
||||
<form method="POST" action="{{ url_for('authentication.register') }}">
|
||||
{{ form.csrf_token }}
|
||||
<div class="form-group">
|
||||
{{ form.email.label }}
|
||||
{{ form.email }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.password.label }}
|
||||
{{ form.password }}
|
||||
</div>
|
||||
<ul>
|
||||
{% for field, errors in form.errors.items() %}
|
||||
<li>{{ form[field].label }}: {{ ', '.join(errors) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<input type="submit" value="Register" class="btn btn-link btn-outline btn-xl">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
|
||||
{% include 'scripts.html' %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue