async def post(self): """ POST request of /login query param: `email` query param: `nickname` query param: `password` """ # TODO check for self.current_user, if already set, user is authenticated and can be redirected to MainHandler # TODO check if those arguments were set, if not, return 400 bad request email = self.get_argument("email", "") nickname = self.get_argument("nickname", "") password = self.get_argument("password") try: user = await queryone( "SELECT * FROM users WHERE email = %s OR name = %s", email, nickname) except NoResultError: # user does not exist self.set_status(409) self.write({ "status": 409, "reason": "user_not_found", "redirect_suggestions": ["/login", "/register"] }) self.flush() # check passwords match password_validated = await tornado.ioloop.IOLoop.current( ).run_in_executor(None, bcrypt.checkpw, tornado.escape.utf8(password), tornado.escape.utf8(user['hashed_password'])) if password_validated: # generate token, store and return it access_token = b64encode(os.urandom( CONSTANTS.TOKEN_SIZE)).decode("utf-8") token_cache().insert(access_token, user['id']) self.set_secure_cookie("access_token", access_token) self.set_status(200) self.write({ "status": 200, "success": True, "access_token": access_token }) else: self.status(401) self.write({ "status": 401, "success": False, "reason": "password_validation_failed", "redirect_suggestions": ["/login", "/register"] })
def post(self): # simply remove token from the cache --> user needs to login again to proceed token = tornado.escape.url_escape(self.get_argument( "access_token", "")) token_cache().remove(token) self.set_status(200) self.write({ "status": 200, "success": True, "redirect_suggestions": ["/login"] })
def post(self): # simply remove token from the cache and clear the cookie --> user needs to login again to proceed token_cache().remove(self._access_token) self.clear_cookie("access_token") self.set_status(200) self.write({ "status": 200, "success": True, "redirect_suggestions": ["/login"] })
async def post(self): """ POST request of /register query param: `email` query param: `nickname` query param: `password` """ # TODO check if those arguments were set, if not, return 400 bad request email = self.get_argument("email") nickname = self.get_argument("nickname") unhashed_password = self.get_argument("password") hashed_password = await tornado.ioloop.IOLoop.current( ).run_in_executor( None, bcrypt.hashpw, tornado.escape.utf8(unhashed_password), bcrypt.gensalt(), ) if (await user_exists(nickname)): self.set_status(409) self.write({ "status": 409, "reason": "username_already_exists", "redirect_suggestions": ["/login"] }) self.flush() else: # save user, generate token, store and return it result = await queryone( "INSERT INTO users (email, name, hashed_password, role) \ VALUES (%s, %s, %s, %s) RETURNING id", email, nickname, tornado.escape.to_unicode(hashed_password), "user") user_id = result['id'] access_token = b64encode(os.urandom( CONSTANTS.TOKEN_SIZE)).decode("utf-8") token_cache().insert(access_token, user_id) self.set_secure_cookie("access_token", access_token) self.set_status(200) self.write({ "status": 200, "success": True, "access_token": access_token })
def prepare(self): """ Checks for the presence of the access token. First the "access_token" cookie is checked. If it is not present there, the Authorization Header is checked. If it is present anywhere in those two places and can be associated with a user account, self.current_user will be overridden to the user id, meaning the user is authenticated. If not present or not associated with a user, self.current_user will be set to None, meaning no authentication is granted. If the server was started with the --dev flag (for dev-mode), self.current_user will be automatically set (-1 as indicator for dev). This means no authentication is needed in dev mode. """ if dev_mode is False: token = self.get_secure_cookie("access_token") if token is not None: token = token.decode( "utf-8" ) # need to to decoding separate because of possible None value else: # cookie not set, try to auth with authorization header if "Authorization" in self.request.headers: token = self.request.headers["Authorization"] self._access_token = token cached_user = token_cache().get(token) if cached_user is not None: self.current_user = cached_user["user_id"] else: self.current_user = None else: self.current_user = -1
def prepare(self): """ Checks for the access token in the Authorization header. If it is present and can be associated with a user account, self.current_user will be overridden to the user id, meaning the user is authenticated. If not present or not associated with a user, self.current_user will be set to None, meaning no authentication is granted. If the server was started with the --dev flag (for dev-mode), self.current_user will be automatically set (-1 as indicator for dev). This means no authentication is needed in dev mode. """ if dev_mode is False: token = tornado.escape.url_escape( self.get_argument("access_token", "") ) # need to url_escape because e.g. + would become space --> validation would fail cached_user = token_cache().get(token) if cached_user is not None: self.current_user = cached_user["user_id"] else: self.current_user = None else: self.current_user = -1