Added JWT back into Project

deb
androiddrew 7 years ago
parent d0a9b556c6
commit 922f8c7d52

@ -1,11 +1,12 @@
import typing import typing
from apistar import Route, http, App from apistar import Route, http, App
from apistar_jwt import JWT from apistar_jwt import JWT, authentication_required, JWTUser
import logbook import logbook
from sqlalchemy import create_engine from sqlalchemy import create_engine
from cookie_api.auth import auth_routes
from cookie_api.logger import global_init from cookie_api.logger import global_init
from cookie_api.models import Cookie from cookie_api.models import Cookie
from cookie_api.schema import CookieSchema from cookie_api.schema import CookieSchema
@ -29,7 +30,8 @@ def get_cookie(session: Session, id) -> CookieSchema:
return ExtJSONResponse(CookieSchema(cookie), 200) return ExtJSONResponse(CookieSchema(cookie), 200)
def create_cookie(session: Session, cookie_data: CookieSchema, app: App): @authentication_required
def create_cookie(session: Session, cookie_data: CookieSchema, app: App, user: JWTUser):
cookie = Cookie(**cookie_data) cookie = Cookie(**cookie_data)
session.add(cookie) session.add(cookie)
session.commit() session.commit()
@ -37,11 +39,13 @@ def create_cookie(session: Session, cookie_data: CookieSchema, app: App):
return ExtJSONResponse(CookieSchema(cookie), 201, headers=headers) return ExtJSONResponse(CookieSchema(cookie), 201, headers=headers)
def delete_cookie(session: Session, id: int): @authentication_required
def delete_cookie(session: Session, id: int, user: JWTUser):
cookie = session.query(Cookie).filter_by(id=id).one_or_none() cookie = session.query(Cookie).filter_by(id=id).one_or_none()
if cookie is None: if cookie is None:
msg = {"error": "404 Not Found"} msg = {"error": "404 Not Found"}
return http.Response(msg, status=404) return http.Response(msg, status=404)
logger.debug("Deleting cookie {} {}".format(cookie.id, cookie.name)) logger.debug("Deleting cookie {} {}".format(cookie.id, cookie.name))
session.delete(cookie) session.delete(cookie)
session.commit() session.commit()
@ -62,13 +66,14 @@ app_settings = {
} }
} }
_routes = _routes # + auth_routes _routes = _routes + auth_routes
_hooks = [SQLAlchemyHook] _hooks = [SQLAlchemyHook]
_components = [ _components = [
SQLAlchemySession(engine=engine), SQLAlchemySession(engine=engine),
JWT({ JWT({
'JWT_USER_ID': 'sub',
'JWT_SECRET': 'thisisasecret', 'JWT_SECRET': 'thisisasecret',
}), }),
] ]

@ -1,18 +1,21 @@
"""
import datetime as dt import datetime as dt
from apistar import Component, http, Route, Include from apistar import http, Route, Include
from apistar_jwt.token import JWT from apistar_jwt.token import JWT, JWTUser
# from apistar_mail import Message, Mail # from apistar_mail import Message, Mail
from sqlalchemy.exc import IntegrityError, InvalidRequestError # from sqlalchemy.exc import IntegrityError, InvalidRequestError
from sqlalchemy.orm import Session
from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.exc import NoResultFound
from cookie_api.models import User from cookie_api.models import User
from cookie_api.schema import from cookie_api.util import ExtJSONResponse
def login(settings: Settings, json_data: http.RequestData, session: Session): # from cookie_api.schema import
def login(json_data: http.RequestData, session: Session, jwt: JWT):
user_id = json_data.get('email') user_id = json_data.get('email')
password = json_data.get('password') password = json_data.get('password')
@ -24,13 +27,11 @@ def login(settings: Settings, json_data: http.RequestData, session: Session):
'status': 'fail', 'status': 'fail',
'message': 'User does not exist' 'message': 'User does not exist'
} }
return http.Response(error, status=400, headers={'WWW-Authenticate': 'Bearer'}) return ExtJSONResponse(error, status=400, headers={'WWW-Authenticate': 'Bearer'})
if not user.check_password(password): if not user.check_password(password):
error = {'error': 'Password auth failed'}, error = {'error': 'Password auth failed'},
return http.Response(error, status=401, headers={'WWW-Authenticate': 'Bearer'}) return ExtJSONResponse(error, status=401, headers={'WWW-Authenticate': 'Bearer'})
secret = settings['JWT'].get('SECRET')
payload = { payload = {
'exp': dt.datetime.utcnow() + dt.timedelta(days=0, minutes=60), # Expiration date of the token 'exp': dt.datetime.utcnow() + dt.timedelta(days=0, minutes=60), # Expiration date of the token
@ -38,7 +39,7 @@ def login(settings: Settings, json_data: http.RequestData, session: Session):
'sub': user.id # the subject of the token 'sub': user.id # the subject of the token
} }
token = JWT.encode(payload, secret=secret) token = jwt.encode(payload)
data = { data = {
'status': 'success', 'status': 'success',
@ -46,7 +47,7 @@ def login(settings: Settings, json_data: http.RequestData, session: Session):
'auth_token': token 'auth_token': token
} }
return data return ExtJSONResponse(data, 200)
# TODO Add user logout # TODO Add user logout
@ -55,38 +56,42 @@ def logout():
# TODO Add user registration # TODO Add user registration
def register(user_rep: UserCreateSchema, session: Session, mail: Mail): # def register(user_rep: UserCreateSchema, session: Session, mail: Mail):
email_check = session.query(User).filter_by(email=user_rep['email']).one_or_none() def register():
# email_check = session.query(User).filter_by(email=user_rep['email']).one_or_none()
if email_check is not None: #
message = { # if email_check is not None:
'status': 'error', # message = {
'message': 'user email address is already in use' # 'status': 'error',
} # 'message': 'user email address is already in use'
return http.Response(message, status=400) # }
# return http.Response(message, status=400)
user = User(email=user_rep['email'], password=user_rep['password']) #
# user = User(email=user_rep['email'], password=user_rep['password'])
session.add(user) #
session.commit() # session.add(user)
# session.commit()
msg = Message("Thank you for registering please confirm your email", recipients=[user_rep['email']]) #
mail.send(msg) # msg = Message("Thank you for registering please confirm your email", recipients=[user_rep['email']])
# mail.send(msg)
#
# headers = {}
# message = {
# 'status': 'success',
# 'message': 'Please check your inbox and confirm your email'
# }
# return http.Response(message, status=201, headers=headers)
pass
headers = {}
message = {
'status': 'success',
'message': 'Please check your inbox and confirm your email'
}
return http.Response(message, status=201, headers=headers)
def user_profile(user: JWTUser, session: Session): # -> UserSchema
try:
user = session.query(User).filter_by(id=user.id).one()
except NoResultFound as e:
error = {'message': str(e)}
return ExtJSONResponse(error, 400)
return ExtJSONResponse(user.to_dict())
@annotate(authentication=[JWTAuthentication()])
def user_profile(auth: Auth, settings: Settings, session: Session) -> UserSchema:
token = JWT(token=auth.token, settings=settings)
user_id = token.payload.get('sub')
user = session.query(User).filter_by(id=user_id).one()
return UserSchema(user)
# TODO Add email confirmation # TODO Add email confirmation
def confirm(json_data: http.RequestData, session: Session): def confirm(json_data: http.RequestData, session: Session):
@ -100,9 +105,8 @@ def reset():
routes = [ routes = [
Route('/login', 'POST', login), Route('/login', 'POST', login),
Route('/register', 'POST', register), # Route('/register', 'POST', register),
Route('/status', 'GET', user_profile) Route('/status', 'GET', user_profile)
] ]
auth_routes = [Include('/auth', routes)] auth_routes = [Include('/auth', name='auth', routes=routes)]
"""

@ -65,6 +65,13 @@ class User(DBMixin, Base):
def check_password(self, password): def check_password(self, password):
return bcrypt.checkpw(password.encode('utf-8'), self.password.encode('utf-8')) return bcrypt.checkpw(password.encode('utf-8'), self.password.encode('utf-8'))
def to_dict(self):
d = self.__dict__.copy()
if '_sa_instance_state' in d:
d.pop('_sa_instance_state')
d.pop('password')
return d
class Order(DBMixin, Base): class Order(DBMixin, Base):
__tablename__ = 'orders' __tablename__ = 'orders'

Loading…
Cancel
Save