diff --git a/bin/dev b/bin/dev
index ddcff3e..11a0476 100755
--- a/bin/dev
+++ b/bin/dev
@@ -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
diff --git a/requirements.txt b/requirements.txt
index 9772b45..bcce1c1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,6 @@ psycopg2-binary
redis
flask_session
requests
+Flask-WTF
+flask_sqlalchemy
+flask-bcrypt
diff --git a/wowstash/app.py b/wowstash/app.py
new file mode 100644
index 0000000..e6f5959
--- /dev/null
+++ b/wowstash/app.py
@@ -0,0 +1,6 @@
+from wowstash.factory import create_app
+
+
+if __name__ == '__main__':
+ app = create_app()
+ app.run()
diff --git a/wowstash/blueprints/__init__.py b/wowstash/blueprints/__init__.py
index 1bd2b40..ea7c7f6 100644
--- a/wowstash/blueprints/__init__.py
+++ b/wowstash/blueprints/__init__.py
@@ -1,2 +1,3 @@
from .account import account_bp
from .authentication import authentication_bp
+from .meta import meta_bp
diff --git a/wowstash/blueprints/account/routes.py b/wowstash/blueprints/account/routes.py
index 1ac1fbc..458f0cf 100644
--- a/wowstash/blueprints/account/routes.py
+++ b/wowstash/blueprints/account/routes.py
@@ -1,8 +1,7 @@
from flask import request, render_template, session
from flask import redirect, url_for, current_app
-from wallet.blueprints.account import account_bp
-from wallet.library.daemon import daemon
-from wallet.library.wallet import wallet
+from wowstash.blueprints.account import account_bp
+
@account_bp.route("/account")
def overview():
diff --git a/wowstash/blueprints/authentication/routes.py b/wowstash/blueprints/authentication/routes.py
index 43d06db..5614cd6 100644
--- a/wowstash/blueprints/authentication/routes.py
+++ b/wowstash/blueprints/authentication/routes.py
@@ -1,42 +1,25 @@
from flask import request, render_template, session, redirect, url_for
-from wallet.blueprints.authentication import authentication_bp
-from wallet.library.daemon import daemon
-from wallet.library.wallet import wallet
-from monero.seed import Seed
-from binascii import hexlify
-from datetime import datetime
-from os import urandom
+from wowstash.blueprints.authentication import authentication_bp
+from wowstash.forms import Register
+from wowstash.models import User
-@authentication_bp.route("/login", methods=["GET", "POST"])
-def login():
- error = None
- if request.method == "POST":
- if request.form.get('seed'):
- try:
- seed = Seed(str(request.form['seed']))
-
- session['seed'] = seed.phrase
- session['start_time'] = datetime.utcnow()
- session['public_address'] = seed.public_address()
- session['private_spend_key'] = seed.secret_spend_key()
- session['public_spend_key'] = seed.public_spend_key()
- session['private_view_key'] = seed.secret_view_key()
- session['public_view_key'] = seed.public_view_key()
- session['wallet_password'] = hexlify(urandom(64))
- if request.form.get('persistence'):
- session['wallet_persistence'] = "Enabled"
- else:
- session['wallet_persistence'] = "Disabled"
- return redirect(url_for('account.overview'))
- except AssertionError:
- error = "Invalid seed checksum"
- except Exception as e:
- error = "Invalid seed {0}".format(e)
- else:
- error = "Must provide a seed"
+@authentication_bp.route("/register", methods=["GET", "POST"])
+def register():
+ form = Register()
+ if form.validate_on_submit():
+ print(dir(User))
+ # user = User.query
+ user = User.objects.filter(email=form.email.data)
+ print(user)
+ return "ok"
+ else:
+ print(form)
+ return render_template("authentication/register.html", form=form)
- return render_template("login.html", error=error)
+@authentication_bp.route("/login", methods=["GET", "POST"])
+def login():
+ return render_template("authentication/login.html")
@authentication_bp.route("/logout")
def logout():
diff --git a/wowstash/blueprints/meta/__init__.py b/wowstash/blueprints/meta/__init__.py
new file mode 100644
index 0000000..cbe8f3f
--- /dev/null
+++ b/wowstash/blueprints/meta/__init__.py
@@ -0,0 +1,5 @@
+from flask import Blueprint
+
+meta_bp = Blueprint("meta", __name__)
+
+from . import routes
diff --git a/wowstash/blueprints/meta/routes.py b/wowstash/blueprints/meta/routes.py
new file mode 100644
index 0000000..db3dbdf
--- /dev/null
+++ b/wowstash/blueprints/meta/routes.py
@@ -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)
diff --git a/wowstash/cli.py b/wowstash/cli.py
new file mode 100644
index 0000000..4e3e8f2
--- /dev/null
+++ b/wowstash/cli.py
@@ -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()
diff --git a/wowstash/factory.py b/wowstash/factory.py
new file mode 100644
index 0000000..8f84995
--- /dev/null
+++ b/wowstash/factory.py
@@ -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
diff --git a/wowstash/forms.py b/wowstash/forms.py
new file mode 100644
index 0000000..f8e4a70
--- /dev/null
+++ b/wowstash/forms.py
@@ -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"})
diff --git a/wowstash/library/wownero.py b/wowstash/library/wownero.py
index 9169a00..6166bce 100644
--- a/wowstash/library/wownero.py
+++ b/wowstash/library/wownero.py
@@ -68,7 +68,7 @@ class Wallet(object):
_account = self.make_wallet_rpc('create_account', {'label': label})
return _account['account_index']
- def addresses(self, account, addr_indices=None):
+ def addresses(self, account=0, addr_indices=None):
qdata = {'account_index': account}
if addr_indices:
qdata['address_index'] = addr_indices
@@ -78,12 +78,12 @@ class Wallet(object):
addresses[_addr['address_index']] = _addr['address']
return addresses
- def new_address(self, account, label=None):
+ def new_address(self, account=0, label=None):
data = {'account_index': account, 'label': label}
_address = self.make_wallet_rpc('create_address', data)
return (_address['address_index'], _address['address'])
- def balances(self, account):
+ def balances(self, account=0):
data = {'account_index': account}
_balance = self.make_wallet_rpc('get_balance', data)
return (from_atomic(_balance['balance']), from_atomic(_balance['unlocked_balance']))
diff --git a/wowstash/models.py b/wowstash/models.py
new file mode 100644
index 0000000..04ea861
--- /dev/null
+++ b/wowstash/models.py
@@ -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)
diff --git a/wowstash/run.py b/wowstash/run.py
deleted file mode 100644
index 82299ca..0000000
--- a/wowstash/run.py
+++ /dev/null
@@ -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()
diff --git a/wowstash/static/css/new-age.css b/wowstash/static/css/new-age.css
index 4282f84..132e951 100644
--- a/wowstash/static/css/new-age.css
+++ b/wowstash/static/css/new-age.css
@@ -78,7 +78,6 @@ section h2 {
}
#mainNav .navbar-brand {
- color: white;
font-family: 'Catamaran', 'Helvetica', 'Arial', 'sans-serif';
font-weight: 200;
letter-spacing: 1px;
@@ -126,7 +125,7 @@ section h2 {
background-color: transparent;
}
#mainNav .navbar-brand {
- color: fade(white, 70%);
+ color: white;
}
#mainNav .navbar-brand:hover, #mainNav .navbar-brand:focus {
color: white;
diff --git a/wowstash/static/js/new-age.js b/wowstash/static/js/new-age.js
index 8749275..634a789 100644
--- a/wowstash/static/js/new-age.js
+++ b/wowstash/static/js/new-age.js
@@ -30,8 +30,10 @@
var navbarCollapse = function() {
if ($("#mainNav").offset().top > 100) {
$("#mainNav").addClass("navbar-shrink");
+ $("#navbar-brand").addClass("navbar-brand");
} else {
$("#mainNav").removeClass("navbar-shrink");
+ // $("#navbar-brand").removeClass("navbar-brand");
}
};
// Collapse now if page is not at top
diff --git a/wowstash/templates/login.html b/wowstash/templates/authentication/login.html
similarity index 87%
rename from wowstash/templates/login.html
rename to wowstash/templates/authentication/login.html
index 3b08188..7d621e8 100644
--- a/wowstash/templates/login.html
+++ b/wowstash/templates/authentication/login.html
@@ -27,10 +27,11 @@
- Create Account
-
+
Need an account? Register below:
+ Register diff --git a/wowstash/templates/authentication/register.html b/wowstash/templates/authentication/register.html new file mode 100644 index 0000000..55e9938 --- /dev/null +++ b/wowstash/templates/authentication/register.html @@ -0,0 +1,44 @@ + + + + {% include 'head.html' %} + + + + {% include 'navbar.html' %} + +