Пример #1
0
def verify_token(token=None):
    """
        Verifies the token for the user (if provided). If in production environment and token is not provided,
        gets user from the SSO headers and returns their token.

        Args:
            token: Optional[str]

        Returns:
            token: str

        Raises:
            ApiError.  If not on production and token is not valid, returns an 'invalid_token' 403 error.
            If on production and user is not authenticated, returns a 'no_user' 403 error.
   """

    failure_error = ApiError(
        "invalid_token",
        "Unable to decode the token you provided.  Please re-authenticate",
        status_code=403)

    if not _is_production() and (token is None or 'user' not in g):
        g.user = UserModel.query.first()
        token = g.user.encode_auth_token()

    if token:
        try:
            token_info = UserModel.decode_auth_token(token)
            g.user = UserModel.query.filter_by(uid=token_info['sub']).first()
        except:
            raise failure_error
        if g.user is not None:
            return token_info
        else:
            raise failure_error

    # If there's no token and we're in production, get the user from the SSO headers and return their token
    if not token and _is_production():
        uid = _get_request_uid(request)

        if uid is not None:
            db_user = UserModel.query.filter_by(uid=uid).first()

            if db_user is not None:
                g.user = db_user
                token = g.user.encode_auth_token().decode()
                token_info = UserModel.decode_auth_token(token)
                return token_info

            else:
                raise ApiError(
                    "no_user",
                    "User not found. Please login via the frontend app before accessing this feature.",
                    status_code=403)
Пример #2
0
    def test_auth_token(self):
        # Save the orginal timeout setting
        orig_ttl = float(app.config['TOKEN_AUTH_TTL_HOURS'])

        self.load_example_data()

        # Set the timeout to something else
        new_ttl = 4.0
        app.config['TOKEN_AUTH_TTL_HOURS'] = new_ttl
        user_1 = UserModel(uid="dhf8r")
        expected_exp_1 = timegm(
            (datetime.utcnow() + timedelta(hours=new_ttl)).utctimetuple())
        auth_token_1 = user_1.encode_auth_token()
        self.assertTrue(isinstance(auth_token_1, bytes))
        self.assertEqual("dhf8r",
                         user_1.decode_auth_token(auth_token_1).get("sub"))
        actual_exp_1 = user_1.decode_auth_token(auth_token_1).get("exp")
        self.assertTrue(
            expected_exp_1 - 1000 <= actual_exp_1 <= expected_exp_1 + 1000)

        # Set the timeout to something else
        neg_ttl = -0.01
        app.config['TOKEN_AUTH_TTL_HOURS'] = neg_ttl
        user_2 = UserModel(uid="dhf8r")
        expected_exp_2 = timegm(
            (datetime.utcnow() + timedelta(hours=neg_ttl)).utctimetuple())
        auth_token_2 = user_2.encode_auth_token()
        self.assertTrue(isinstance(auth_token_2, bytes))
        with self.assertRaises(ApiError) as api_error:
            with self.assertRaises(jwt.exceptions.ExpiredSignatureError):
                user_2.decode_auth_token(auth_token_2)
        self.assertEqual(api_error.exception.status_code, 400,
                         'Should raise an API Error if token is expired')

        # Set the timeout back to where it was
        app.config['TOKEN_AUTH_TTL_HOURS'] = orig_ttl
        user_3 = UserModel(uid="dhf8r")
        expected_exp_3 = timegm(
            (datetime.utcnow() + timedelta(hours=new_ttl)).utctimetuple())
        auth_token_3 = user_3.encode_auth_token()
        self.assertTrue(isinstance(auth_token_3, bytes))
        actual_exp_3 = user_3.decode_auth_token(auth_token_1).get("exp")
        self.assertTrue(
            expected_exp_3 - 1000 <= actual_exp_3 <= expected_exp_3 + 1000)
Пример #3
0
def verify_token_admin(token=None):
    """
        Verifies the token for the user (if provided) in non-production environment.
        If in production environment, checks that the user is in the list of authorized admins

        Args:
            token: Optional[str]

        Returns:
            token: str
   """
    verify_token(token)
    if "user" in g and g.user.is_admin():
        token = g.user.encode_auth_token()
        token_info = UserModel.decode_auth_token(token)
        return token_info
Пример #4
0
    def test_auth_token(self):
        # Save the orginal timeout setting
        orig_ttl = float(app.config['TOKEN_AUTH_TTL_HOURS'])

        self.load_example_data()

        # Set the timeout to something else
        new_ttl = 4.0
        app.config['TOKEN_AUTH_TTL_HOURS'] = new_ttl
        user_1 = UserModel(uid="dhf8r")
        expected_exp_1 = timegm(
            (datetime.utcnow() + timedelta(hours=new_ttl)).utctimetuple())
        auth_token_1 = user_1.encode_auth_token()
        self.assertTrue(isinstance(auth_token_1, str))
        self.assertEqual("dhf8r",
                         user_1.decode_auth_token(auth_token_1).get("sub"))
Пример #5
0
def verify_token(token=None):
    """
        Verifies the token for the user (if provided). If in production environment and token is not provided,
        gets user from the SSO headers and returns their token.

        Args:
            token: Optional[str]

        Returns:
            token: str

        Raises:
            ApiError.  If not on production and token is not valid, returns an 'invalid_token' 403 error.
            If on production and user is not authenticated, returns a 'no_user' 403 error.
   """

    failure_error = ApiError("invalid_token", "Unable to decode the token you provided.  Please re-authenticate",
                             status_code=403)

    if token:
        try:
            token_info = UserModel.decode_auth_token(token)
            g.user = UserModel.query.filter_by(uid=token_info['sub']).first()

            # If the user is valid, store the token for this session
            if g.user:
                g.token = token
        except:
            raise failure_error
        if g.user is not None:
            return token_info
        else:
            raise failure_error

    # If there's no token and we're in production, get the user from the SSO headers and return their token
    elif _is_production():
        uid = _get_request_uid(request)

        if uid is not None:
            db_user = UserModel.query.filter_by(uid=uid).first()

            # If the user is valid, store the user and token for this session
            if db_user is not None:
                g.user = db_user
                token = g.user.encode_auth_token().decode()
                g.token = token
                token_info = UserModel.decode_auth_token(token)
                return token_info

            else:
                raise ApiError("no_user",
                               "User not found. Please login via the frontend app before accessing this feature.",
                               status_code=403)

    else:
        # Fall back to a default user if this is not production.
        g.user = UserModel.query.first()
        if not g.user:
            raise ApiError("no_user", "You are in development mode, but there are no users in the database.  Add one, and it will use it.")
        token = g.user.encode_auth_token()
        token_info = UserModel.decode_auth_token(token)
        return token_info