Exemplo n.º 1
0
    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"]
            })
Exemplo n.º 2
0
 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"]
     })
Exemplo n.º 3
0
    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"]
        })
Exemplo n.º 4
0
    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
            })
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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