Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import logging
- import hashlib
- import tornado.web
- import json
- import datetime
- import time
- import base64
- import random
- import string
- import settings
- from tornado.web import authenticated
- from db.base import AsyncDB, SyncDB
- from core.utils import DummyObject
- async_db, async_fs = AsyncDB()()
- sync_db, sync_fs = SyncDB()()
- logger = logging.getLogger(__name__)
- # TODO: should be placed in utils module
- def get_token(context):
- # check for token as param
- token = context.get_argument('access_token', None)
- if not token:
- # or as Authorization bearer header
- auth_header = context.request.headers.get('Authorization', None)
- if not auth_header:
- raise Exception('This resource need a authorization token')
- token = auth_header[7:]
- return token
- # TODO: should be placed in utils module
- async def create_token(data, user):
- access_raw = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15))
- access_token = base64.b64encode( access_raw.encode("utf-8") ).decode("utf-8")
- refresh_raw = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15))
- refresh_token = base64.b64encode( refresh_raw.encode("utf-8") ).decode("utf-8")
- expires_in = int(datetime.datetime.now(datetime.timezone.utc).timestamp() + settings.TOKEN_TTL)
- refresh_expires_in = int(datetime.datetime.now(datetime.timezone.utc).timestamp() + settings.REFRESH_TOKEN_TTL)
- result = await async_db.access_tokens.insert({
- "grant_type": data.get('grant_type'),
- "access_token": access_token,
- "data": data,
- "expires_in": expires_in,
- "refresh_token": refresh_token,
- "refresh_expires_in": refresh_expires_in,
- "user_id": user.get('_id')
- })
- return access_token, refresh_token
- class Base(tornado.web.RequestHandler):
- def get_current_user(self):
- try:
- token = get_token(self)
- access = sync_db.access_tokens.find_one({'access_token':token})
- if not access:
- raise Exception('Invalid token')
- if int(access.get('expires_in')) <= int(time.time()):
- raise Exception('Expired token')
- _user = sync_db.admin_users.find_one({'_id':access.get('user_id')})
- if not _user is None:
- user = DummyObject()
- user.__dict__ = _user
- return user
- except Exception as e:
- self.set_header('Content-Type', 'application/json')
- self.set_status(401)
- raise tornado.web.Finish()
- class Logout(Base):
- async def get(self):
- try:
- token = get_token(self)
- access = await async_db.access_tokens.remove({'access_token':token})
- except Exception as e:
- self.set_header('Content-Type', 'application/json')
- self.set_status(401)
- self.write({ 'error': str(e)})
- class Login(Base):
- async def post(self):
- try:
- data = json.loads(self.request.body.decode('utf-8'))
- except Exception as e:
- self.set_status(400)
- self.write({ 'error':'Bad request'})
- return
- # check grant_type
- if data.get('grant_type') == 'password':
- hashpassword = hashlib.md5(str.encode(settings.SALT + data.get('password'))).hexdigest()
- user = await async_db.admin_users.find_one({
- "email":data.get('username'),
- "password":hashpassword
- })
- if user is None:
- self.set_status(401)
- self.write({ 'error':'Wrong username or password'})
- return
- try:
- access_token, refresh_token = await create_token(data=data, user=user)
- except Exception as e:
- logger.debug('login error: %r' % e)
- self.set_status(400)
- self.write({ 'error':'Could not log in. Please try again later'})
- return
- self.write({
- 'access_token':access_token,
- 'token_type':settings.TOKEN_TYPE,
- 'user_id': str(user.get('_id')),
- 'refresh_token':refresh_token,
- 'expires_in':settings.TOKEN_TTL
- })
- return
- if data.get('grant_type') == 'refresh_token':
- try:
- access = await async_db.access_tokens.find_one({'refresh_token':data.get('refresh_token')})
- if access is None:
- raise Exception('Invalid refresh token')
- if int(access.get('refresh_expires_in')) <= int(time.time()):
- raise Exception('expired token')
- user = await async_db.admin_users.find_one({'_id':access.get('user_id')})
- if user is None:
- raise Exception('Invalid refresh token')
- except Exception as e:
- self.set_header('Content-Type', 'application/json')
- self.set_status(401)
- self.write({ 'error': str(e)})
- return
- try:
- access_token, refresh_token = await create_token(data=data, user=user)
- except Exception as e:
- logger.debug('login error: %r' % e)
- self.set_status(400)
- self.write({ 'error':'Could not log in. Please try again later'})
- return
- _ = await async_db.access_tokens.remove({'refresh_token':data.get('refresh_token')})
- self.write({
- 'access_token':access_token,
- 'user_id': str(user.get('_id')),
- 'refresh_token':refresh_token,
- 'expires_in':settings.TOKEN_TTL
- })
- return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement