From 31d810b65d366d0078f2b408c4be017e08e1be43 Mon Sep 17 00:00:00 2001
From: Eli Ribble <eli@authentise.com>
Date: Thu, 9 Jun 2016 10:12:24 -0600
Subject: [PATCH] Clean up old sepiida-based work, create pattern for pages

I'm going to do server-side rendering. That means that I don't really
need sepiida in the way we think of it because I don't need a JSON-based
API to do my UI. And that's fine. This simplifies a bunch of stuff, so
I'll be happy with it

This commit breaks apart my growing list of endpoints into a new module,
vanth.pages, where I intend to keep the various pages. I've put auth in
a separate, non-pages module even though it has pages because auth is a
special beast that deals with sessions and DB stuff, so I like it in a
separate kind of module
---
 vanth/api/about.py               | 18 -------
 vanth/api/ofxsource.py           | 22 ---------
 vanth/api/session.py             | 55 ---------------------
 vanth/api/user.py                | 32 -------------
 vanth/auth.py                    | 82 +++++++++++++-------------------
 vanth/{api => pages}/__init__.py |  0
 vanth/pages/index.py             |  7 +++
 vanth/server.py                  | 63 +++---------------------
 8 files changed, 45 insertions(+), 234 deletions(-)
 delete mode 100644 vanth/api/about.py
 delete mode 100644 vanth/api/ofxsource.py
 delete mode 100644 vanth/api/session.py
 delete mode 100644 vanth/api/user.py
 rename vanth/{api => pages}/__init__.py (100%)
 create mode 100644 vanth/pages/index.py

diff --git a/vanth/api/about.py b/vanth/api/about.py
deleted file mode 100644
index 974343a..0000000
--- a/vanth/api/about.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import json
-
-import flask
-import sepiida.endpoints
-import sepiida.fields
-
-from vanth.version import VERSION
-
-
-class About(sepiida.endpoints.APIEndpoint):
-    ENDPOINT = "/about/"
-    SIGNATURE = sepiida.fields.JSONObject(s={
-        'version'   : sepiida.fields.String()
-    })
-    PUBLIC_METHODS = ['list']
-    @staticmethod
-    def list():
-        return flask.make_response(json.dumps({'version': VERSION}), 200)
diff --git a/vanth/api/ofxsource.py b/vanth/api/ofxsource.py
deleted file mode 100644
index 3ef2c4b..0000000
--- a/vanth/api/ofxsource.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import sepiida.endpoints
-import sepiida.fields
-
-import vanth.platform.ofxsource
-
-
-class OFXSource(sepiida.endpoints.APIEndpoint):
-    ENDPOINT = '/ofxsource/'
-    SIGNATURE = sepiida.fields.JSONObject(s={
-        'name'      : sepiida.fields.String(),
-        'fid'       : sepiida.fields.String(),
-        'bankid'    : sepiida.fields.String(),
-        'uri'       : sepiida.fields.URI('ofxsource'),
-    })
-    @staticmethod
-    def list():
-        return vanth.platform.ofxsource.by_filter({})
-
-
-    @staticmethod
-    def get(uuid):
-        return vanth.platform.ofxsource.by_filter({'uuid': [str(uuid)]})[0]
diff --git a/vanth/api/session.py b/vanth/api/session.py
deleted file mode 100644
index 94f3174..0000000
--- a/vanth/api/session.py
+++ /dev/null
@@ -1,55 +0,0 @@
-import json
-import logging
-
-import flask
-import sepiida.endpoints
-import sepiida.fields
-import sepiida.routing
-
-import vanth.auth
-import vanth.errors
-import vanth.platform.user
-import vanth.user
-
-LOGGER = logging.getLogger(__name__)
-
-class Session(sepiida.endpoints.APIEndpoint):
-    ENDPOINT = '/session/'
-    SIGNATURE = sepiida.fields.JSONObject(s={
-        'name'      : sepiida.fields.String(methods=['GET']),
-        'password'  : sepiida.fields.String(methods=['POST']),
-        'uri'       : sepiida.fields.URI('session', methods=['GET']),
-        'user'      : sepiida.fields.URI('user', methods=['GET']),
-        'username'  : sepiida.fields.String(),
-    })
-    @staticmethod
-    def post(payload):
-        user = vanth.platform.user.by_credentials(payload['username'], payload['password'])
-        if not user:
-            raise vanth.errors.InvalidCredentials()
-        LOGGER.debug("Logged in %s %s", user['username'], user['uri'])
-        vanth.auth.set_session(user)
-
-    @staticmethod
-    def get(uuid): # pylint: disable=unused-argument
-        user = vanth.auth.current_user()
-        if not user:
-            raise vanth.errors.ResourceDoesNotExist("You are not currently authenticated and therefore do not have a session")
-        return {
-            'name'      : user['name'],
-            'uri'       : sepiida.routing.uri('session', flask.session['uuid']),
-            'user'      : user['uri'],
-            'username'  : user['username'],
-        }
-
-    def list(self):
-        payload = self.get(None)
-        return flask.make_response(json.dumps(payload), 200, {'Content-Type': 'application/json'})
-
-    @staticmethod
-    def delete(uuid):
-        user = vanth.auth.current_user()
-        if not user:
-            raise vanth.errors.AuthenticationException("You cannot delete a session when you do not have a session")
-        LOGGER.debug("Deleteing session %s for %s", uuid, user['uri'])
-        flask.session.clear()
diff --git a/vanth/api/user.py b/vanth/api/user.py
deleted file mode 100644
index d881e72..0000000
--- a/vanth/api/user.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import sepiida.endpoints
-import sepiida.errors
-import sepiida.fields
-
-import vanth.platform.user
-
-
-class User(sepiida.endpoints.APIEndpoint):
-    ENDPOINT = '/user/'
-    SIGNATURE = sepiida.fields.JSONObject(s={
-        'name'      : sepiida.fields.String(),
-        'password'  : sepiida.fields.String(methods=['POST', 'PUT']),
-        'username'  : sepiida.fields.String(),
-    })
-
-    @staticmethod
-    def post(payload):
-        uri = vanth.platform.user.create(payload['name'], payload['username'], payload['password'])
-        vanth.auth.set_session({
-            'name'      : payload['name'],
-            'uri'       : uri,
-            'username'  : payload['username'],
-        })
-
-        return None, 204, {'Location': uri}
-
-    @staticmethod
-    def get(uuid):
-        users = vanth.platform.user.by_filter({'uuid': [str(uuid)]})
-        if not users:
-            raise sepiida.errors.ResourceNotFound()
-        return users[0]
diff --git a/vanth/auth.py b/vanth/auth.py
index 622dfc4..dd69cff 100644
--- a/vanth/auth.py
+++ b/vanth/auth.py
@@ -1,60 +1,42 @@
-import json
-import uuid
+import logging
 
 import flask
-import sepiida.routing
+import flask_login
 
 import vanth.platform.user
 
-PUBLIC_ENDPOINTS = [
-    'session.get',
-    'session.post',
-    'about.get',
-]
+LOGGER = logging.getLogger(__name__)
+blueprint = flask.Blueprint('auth', __name__)
 
-def register_auth_handlers(app):
-    app.before_request(require_user)
+def load_user(user_id):
+    LOGGER.debug("Loading user %s", user_id)
+    return vanth.platform.user.load(user_id)
 
-def endpoint():
-    if flask.request.endpoint and flask.request.method:
-        return "{}.{}".format(flask.request.endpoint.lower(), flask.request.method.lower())
+@blueprint.route('/login/', methods=['GET', 'POST', 'DELETE'])
+def login():
+    if flask.request.method == 'GET':
+        return flask.render_template('login.html')
+    elif flask.request.method == 'POST':
+        username = flask.request.form.get('username')
+        password = flask.request.form.get('password')
+        LOGGER.debug("Checking credentials for %s %s", username, password)
+        user = vanth.platform.user.by_credentials(username, password)
+        if not user:
+            return flask.make_response('error', 403)
+        flask_login.login_user(user)
+    elif flask.request.method == 'DELETE':
+        flask_login.logout_user()
+    return flask.redirect('/')
 
-def error(code, title, status_code=403):
-    content = {
-        'errors'    : [{
-            'code'  : code,
-            'title' : title,
-        }]
-    }
-    return flask.make_response(json.dumps(content), status_code)
+@blueprint.route('/logout/', methods=['POST'])
+def logout():
+    LOGGER.info("Logging out user %s", flask.session['user_id'])
+    flask_login.logout_user()
+    return flask.redirect('/login/')
 
-def require_user():
-    user = None
-    if flask.request.method == 'OPTIONS' and 'Access-Control-Request-Method' in flask.request.headers:
+def require_login():
+    LOGGER.debug("Current user %s for %s", flask.session, flask.request.path)
+    if flask.request.path == '/login/':
         return
-
-    if not endpoint():
-        return error('resource-not-found', 'The resource at URL {} could not be found'.format(flask.request.url), 404)
-
-    if 'user_uri' not in flask.session:
-        if endpoint() in PUBLIC_ENDPOINTS:
-            return
-        return error('unauthorized', 'You must provide a valid session cookie', 403)
-
-    _, params = sepiida.routing.extract_parameters(flask.current_app, 'GET', flask.session['user_uri'])
-    user = vanth.platform.user.by_filter({'uuid': [str(params['uuid'])]})
-    if not user and endpoint() not in PUBLIC_ENDPOINTS:
-        return error('invalid-user', 'The user tied to your session does not exist. Figure that out', 403)
-
-    flask.g.current_user = user[0]
-    flask.g.session = sepiida.routing.uri('session', flask.session['uuid'])
-
-def current_user():
-    return getattr(flask.g, 'current_user', None)
-
-def is_authenticated():
-    return current_user() is not None
-
-def set_session(user):
-    flask.session['user_uri'] = user['uri']
-    flask.session['uuid'] = str(uuid.uuid4())
+    if not flask.session.get('user_id'):
+        return flask.redirect('/login/')
diff --git a/vanth/api/__init__.py b/vanth/pages/__init__.py
similarity index 100%
rename from vanth/api/__init__.py
rename to vanth/pages/__init__.py
diff --git a/vanth/pages/index.py b/vanth/pages/index.py
new file mode 100644
index 0000000..0a8cafa
--- /dev/null
+++ b/vanth/pages/index.py
@@ -0,0 +1,7 @@
+import flask
+
+blueprint = flask.Blueprint('index', __name__)
+
+@blueprint.route('/', methods=['GET'])
+def index():
+    return flask.render_template('index.html', path='/')
diff --git a/vanth/server.py b/vanth/server.py
index 8dcd6d9..004bb9f 100644
--- a/vanth/server.py
+++ b/vanth/server.py
@@ -3,15 +3,9 @@ import logging
 import flask
 import flask_login
 import flask_uuid
-import sepiida.cors
-import sepiida.endpoints
 
-import vanth.api.about
-import vanth.api.ofxsource
-import vanth.api.session
-import vanth.api.user
 import vanth.auth
-import vanth.platform.user
+import vanth.pages.index
 
 LOGGER = logging.getLogger(__name__)
 
@@ -19,40 +13,6 @@ EXPOSE_HEADERS = [
     'Location',
 ]
 
-def index():
-    return flask.render_template('index.html', path='/')
-
-def load_user(user_id):
-    LOGGER.debug("Loading user %s", user_id)
-    return vanth.platform.user.load(user_id)
-
-def login():
-    if flask.request.method == 'GET':
-        return flask.render_template('login.html')
-    elif flask.request.method == 'POST':
-        username = flask.request.form.get('username')
-        password = flask.request.form.get('password')
-        LOGGER.debug("Checking credentials for %s %s", username, password)
-        user = vanth.platform.user.by_credentials(username, password)
-        if not user:
-            return flask.make_response('error', 403)
-        flask_login.login_user(user)
-    elif flask.request.method == 'DELETE':
-        flask_login.logout_user()
-    return flask.redirect('/')
-
-def logout():
-    LOGGER.info("Logging out user %s", flask.session['user_id'])
-    flask_login.logout_user()
-    return flask.redirect('/login/')
-
-def require_login():
-    LOGGER.debug("Current user %s for %s", flask.session, flask.request.path)
-    if flask.request.path == '/login/':
-        return
-    if not flask.session.get('user_id'):
-        return flask.redirect('/login/')
-
 def create_app(config):
     app = flask.Flask('vanth', template_folder='../templates')
 
@@ -60,7 +20,7 @@ def create_app(config):
     login_manager = flask_login.LoginManager()
     login_manager.init_app(app)
 
-    login_manager.user_loader(load_user)
+    login_manager.user_loader(vanth.auth.load_user)
 
     app.config.update(
         API_TOKEN                 = config.api_token,
@@ -68,23 +28,12 @@ def create_app(config):
         SECRET_KEY                = config.secret_key,
         SESSION_COOKIE_DOMAIN     = config.session_cookie_domain,
     )
-    sepiida.cors.register_cors_handlers(
-        app,
-        domains=['localhost:8080', 'www.vanth.com'],
-        supports_credentials=True,
-        expose_headers=EXPOSE_HEADERS,
-    )
-    #vanth.auth.register_auth_handlers(app)
 
-    app.route('/',          methods=['GET'])(index)
-    app.route('/login/',    methods=['GET', 'POST', 'DELETE'])(login)
-    app.route('/logout/',   methods=['POST'])(logout)
+    app.register_blueprint(vanth.pages.index.blueprint)
+    app.register_blueprint(vanth.auth.blueprint)
 
-    app.before_request(require_login)
+    app.before_request(vanth.auth.require_login)
 
-    sepiida.endpoints.add_resource(app, vanth.api.about.About,          endpoint='about')
-    sepiida.endpoints.add_resource(app, vanth.api.ofxsource.OFXSource,  endpoint='ofxsource')
-    sepiida.endpoints.add_resource(app, vanth.api.session.Session,      endpoint='session')
-    sepiida.endpoints.add_resource(app, vanth.api.user.User,            endpoint='user')
 
+    LOGGER.debug("app created")
     return app