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
This commit is contained in:
parent
f566ca8914
commit
31d810b65d
|
@ -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)
|
|
@ -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]
|
|
@ -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()
|
|
@ -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]
|
|
@ -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/')
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import flask
|
||||
|
||||
blueprint = flask.Blueprint('index', __name__)
|
||||
|
||||
@blueprint.route('/', methods=['GET'])
|
||||
def index():
|
||||
return flask.render_template('index.html', path='/')
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue