Add session creation and handling
This commit adds setting the content of the current user from the session cookie the user sends back and forth. That means we can actually pull out the session data for use when handling requests. We can also create new sessions and set up the session cookie
This commit is contained in:
parent
db066e18d7
commit
d83312234b
|
@ -0,0 +1,36 @@
|
|||
import json
|
||||
|
||||
import flask
|
||||
import sepiida.endpoints
|
||||
import sepiida.fields
|
||||
|
||||
import vanth.auth
|
||||
import vanth.errors
|
||||
import vanth.platform.user
|
||||
import vanth.user
|
||||
|
||||
|
||||
class Session(sepiida.endpoints.APIEndpoint):
|
||||
ENDPOINT = '/session/'
|
||||
SIGNATURE = sepiida.fields.JSONObject(s={
|
||||
'username' : sepiida.fields.String(),
|
||||
'password' : sepiida.fields.String(methods=['POST']),
|
||||
})
|
||||
@staticmethod
|
||||
def post(payload):
|
||||
user = vanth.platform.user.by_credentials(payload['username'], payload['password'])
|
||||
if not user:
|
||||
raise vanth.errors.InvalidCredentials()
|
||||
vanth.auth.set_session(user)
|
||||
|
||||
@staticmethod
|
||||
def get(uuid): # pylint: disable=unused-argument
|
||||
user = vanth.auth.current_user()
|
||||
del user['password']
|
||||
if not user:
|
||||
raise vanth.errors.ResourceDoesNotExist("You are not currently authenticated and therefore do not have a session")
|
||||
return user
|
||||
|
||||
def list(self):
|
||||
payload = self.get(None)
|
||||
return flask.make_response(json.dumps(payload), 200, {'Content-Type': 'application/json'})
|
|
@ -0,0 +1,57 @@
|
|||
import uuid
|
||||
|
||||
import flask
|
||||
import sepiida.routing
|
||||
|
||||
import vanth.platform.user
|
||||
|
||||
PUBLIC_ENDPOINTS = [
|
||||
'session.post',
|
||||
'about.get',
|
||||
]
|
||||
|
||||
def register_auth_handlers(app):
|
||||
app.before_request(require_user)
|
||||
|
||||
def endpoint():
|
||||
if flask.request.endpoint and flask.request.method:
|
||||
return "{}.{}".format(flask.request.endpoint.lower(), flask.request.method.lower())
|
||||
|
||||
def require_user():
|
||||
user = None
|
||||
if flask.request.method == 'OPTIONS' and 'Access-Control-Request-Method' in flask.request.headers:
|
||||
return
|
||||
|
||||
if not endpoint():
|
||||
return flask.make_response('Resource not found', 404)
|
||||
|
||||
if endpoint() in PUBLIC_ENDPOINTS:
|
||||
return
|
||||
|
||||
if 'user_uri' not in flask.session:
|
||||
raise vanth.errors.AuthenticationException(
|
||||
status_code = 403,
|
||||
error_code = 'unauthorized',
|
||||
title = 'You must provide a valid session cookie',
|
||||
)
|
||||
|
||||
_, 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:
|
||||
raise vanth.errors.AuthenticationException(
|
||||
status_code = 403,
|
||||
error_code = 'invalid-user',
|
||||
title = 'The user tied to your session does not exist. Figure that out',
|
||||
)
|
||||
|
||||
flask.g.current_user = user[0]
|
||||
|
||||
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())
|
|
@ -0,0 +1,5 @@
|
|||
import sepiida.errors
|
||||
|
||||
AuthenticationException = sepiida.errors.api_error(status_code=403, error_code='authentication-exception')
|
||||
InvalidCredentials = sepiida.errors.api_error(status_code=401, error_code='invalid-credentials')
|
||||
ResourceDoesNotExist = sepiida.errors.api_error(status_code=404, error_code='resource-does-not-exist')
|
|
@ -8,17 +8,32 @@ import sepiida.routing
|
|||
import vanth.tables
|
||||
|
||||
|
||||
def _to_dict(result):
|
||||
return {
|
||||
'username' : result[vanth.tables.User.c.username],
|
||||
'password' : result[vanth.tables.User.c.password],
|
||||
'name' : result[vanth.tables.User.c.name],
|
||||
'uri' : sepiida.routing.uri('user', result[vanth.tables.User.c.uuid]),
|
||||
}
|
||||
|
||||
def by_filter(filters):
|
||||
engine = chryso.connection.get()
|
||||
|
||||
query = vanth.tables.User.select()
|
||||
query = chryso.queryadapter.map_and_filter(vanth.tables.User, filters, query)
|
||||
results = engine.execute(query).fetchall()
|
||||
return [{
|
||||
'username' : result[vanth.tables.User.c.username],
|
||||
'password' : result[vanth.tables.User.c.password],
|
||||
'name' : result[vanth.tables.User.c.name],
|
||||
} for result in results]
|
||||
return [_to_dict(result) for result in results]
|
||||
|
||||
def by_credentials(username, password):
|
||||
engine = chryso.connection.get()
|
||||
|
||||
query = vanth.tables.User.select().where(vanth.tables.User.c.username == username)
|
||||
result = engine.execute(query).first()
|
||||
|
||||
if not (result and passlib.apps.custom_app_context.verify(password, result[vanth.tables.User.c.password])):
|
||||
return None
|
||||
|
||||
return _to_dict(result)
|
||||
|
||||
def create(name, username, password):
|
||||
engine = chryso.connection.get()
|
||||
|
|
|
@ -9,6 +9,7 @@ import sepiida.endpoints
|
|||
import vanth.api.about
|
||||
import vanth.api.session
|
||||
import vanth.api.user
|
||||
import vanth.auth
|
||||
import vanth.user
|
||||
|
||||
EXPOSE_HEADERS = [
|
||||
|
@ -56,6 +57,7 @@ def create_app(config):
|
|||
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)
|
||||
|
@ -63,5 +65,6 @@ def create_app(config):
|
|||
|
||||
sepiida.endpoints.add_resource(app, vanth.api.about.About, endpoint='about')
|
||||
sepiida.endpoints.add_resource(app, vanth.api.user.User, endpoint='user')
|
||||
sepiida.endpoints.add_resource(app, vanth.api.session.Session, endpoint='session')
|
||||
|
||||
return app
|
||||
|
|
Loading…
Reference in New Issue