Exemplo n.º 1
0
def _do_login(auths: Authorizations,
              ip: str,
              tracking_cookie: str,
              user: User = None) -> Tuple[Session, str]:
    with legacy.transaction():
        c_session = legacy.create(auths, ip, ip, tracking_cookie, user=user)
        c_cookie = legacy.generate_cookie(c_session)
        logger.debug('Created classic session: %s', c_session.session_id)
        return c_session, c_cookie
Exemplo n.º 2
0
def logout(session_cookie: Optional[str],
           classic_session_cookie: Optional[str],
           next_page: str) -> ResponseData:
    """
    Log the user out, and redirect to arXiv.org.

    Parameters
    ----------
    session_id : str or None
        If not None, invalidates the session.
    classic_session_id : str or None
        If not None, invalidates the session.
    next_page : str
        Page to which the user should be redirected upon logout.

    Returns
    -------
    dict
        Additional data to add to the response.
    int
        Status code. This should be 303 (See Other).
    dict
        Headers to add to the response.

    """
    logger.debug('Request to log out')
    sessions = SessionStore.current_session()
    if session_cookie:
        try:
            sessions.delete(session_cookie)
        except sessions.exceptions.SessionDeletionFailed as e:
            logger.debug('Logout failed: %s', e)

    if classic_session_cookie:
        try:
            with legacy.transaction():
                _do_logout(classic_session_cookie)
        except legacy.exceptions.SessionDeletionFailed as e:
            logger.debug('Logout failed: %s', e)
        except legacy.exceptions.UnknownSession as e:
            logger.debug('Unknown session: %s', e)

    data = {
        'cookies': {
            'auth_session_cookie': ('', 0),
            'classic_cookie': ('', 0)
        }
    }
    return data, status.HTTP_303_SEE_OTHER, {'Location': next_page}
Exemplo n.º 3
0
    def test_post_login(self):
        """POST request to /login with valid form data returns redirect."""
        client = self.app.test_client()
        client.environ_base = self.environ_base
        form_data = {'username': '******', 'password': '******'}
        next_page = '/foo'
        response = client.post(f'/login?next_page={next_page}', data=form_data)
        self.assertEqual(response.status_code, status.HTTP_303_SEE_OTHER)
        self.assertTrue(response.headers['Location'].endswith(next_page),
                        "Redirect should point at value of `next_page` param")
        cookies = _parse_cookies(response.headers.getlist('Set-Cookie'))

        cookie_name = self.app.config['AUTH_SESSION_COOKIE_NAME']
        self.assertIn(cookie_name, cookies, "Sets cookie for authn session.")

        classic_cookie_name = self.app.config['CLASSIC_COOKIE_NAME']
        self.assertIn(classic_cookie_name, cookies, "Sets classic cookie")

        cookie = cookies[cookie_name]
        classic_cookie = cookies[classic_cookie_name]

        # Verify that the domain is correct.
        self.assertEqual(cookie['Domain'], '.arxiv.org', 'Domain is set')
        self.assertEqual(classic_cookie['Domain'], '.arxiv.org',
                         'Domain is set')

        # Verify that the correct expiry is set.
        self.assertEqual(int(cookie['Max-Age']), self.expiry - 1)
        self.assertEqual(int(classic_cookie['Max-Age']), self.expiry - 1)

        expires_in = (parse(cookie['Expires']) - datetime.now(UTC)).seconds
        classic_expires_in = (parse(classic_cookie['Expires']) -
                              datetime.now(UTC)).seconds
        self.assertLess(expires_in - self.expiry, 2)
        self.assertLess(classic_expires_in - self.expiry, 2)

        # Verify that the expiry is not set in the database. This is kind of
        # a weird "feature" of the classic auth system.
        with self.app.app_context():
            with legacy.transaction() as session:
                db_session = session.query(legacy.models.DBSession) \
                    .filter(legacy.models.DBSession.user_id == 1) \
                    .order_by(legacy.models.DBSession.session_id.desc()) \
                    .first()
                self.assertEqual(db_session.end_time, 0)
Exemplo n.º 4
0
def _do_logout(classic_session_cookie: str) -> None:
    with legacy.transaction():
        legacy.invalidate(classic_session_cookie)
Exemplo n.º 5
0
def _do_authn(username: str, password: str) -> Tuple[User, Authorizations]:
    with legacy.transaction():
        return users.authenticate(username_or_email=username,
                                  password=password)
Exemplo n.º 6
0
    def test_login_logout(self):
        """User logs in and then logs out."""
        client = self.app.test_client()
        form_data = {'username': '******', 'password': '******'}

        # Werkzeug should keep the cookies around for the next request.
        response = client.post('/login', data=form_data)
        cookies = _parse_cookies(response.headers.getlist('Set-Cookie'))

        cookie_name = self.app.config['AUTH_SESSION_COOKIE_NAME']
        self.assertIn(cookie_name, cookies, "Sets cookie for authn session.")

        classic_cookie_name = self.app.config['CLASSIC_COOKIE_NAME']
        self.assertIn(classic_cookie_name, cookies, "Sets classic cookie")

        cookie = cookies[cookie_name]
        classic_cookie = cookies[classic_cookie_name]

        # Verify that the domain is correct.
        self.assertEqual(cookie['Domain'], '.arxiv.org', 'Domain is set')
        self.assertEqual(classic_cookie['Domain'], '.arxiv.org',
                         'Domain is set')

        # Verify that the correct expiry is set.
        self.assertEqual(int(cookie['Max-Age']), self.expiry - 1)
        self.assertEqual(int(classic_cookie['Max-Age']), self.expiry - 1)

        expires_in = (parse(cookie['Expires']) - datetime.now(UTC)).seconds
        classic_expires_in = (parse(classic_cookie['Expires']) -
                              datetime.now(UTC)).seconds
        self.assertLess(expires_in - self.expiry, 2)
        self.assertLess(classic_expires_in - self.expiry, 2)

        # Verify that the expiry is not set in the database. This is kind of
        # a weird "feature" of the classic auth system.
        with self.app.app_context():
            with legacy.transaction() as session:
                db_session = session.query(legacy.models.DBSession) \
                    .filter(legacy.models.DBSession.user_id == 1) \
                    .order_by(legacy.models.DBSession.session_id.desc()) \
                    .first()
                self.assertEqual(db_session.end_time, 0)

        response = client.get('/logout')
        logout_cookies = _parse_cookies(response.headers.getlist('Set-Cookie'))

        cookie = logout_cookies[cookie_name]
        classic_cookie = logout_cookies[classic_cookie_name]

        self.assertEqual(cookie['value'], '', 'Session cookie is unset')
        self.assertEqual(cookie['Max-Age'], '0', 'Session cookie is expired')
        self.assertLessEqual(parse(cookie['Expires']), datetime.now(UTC),
                             "Session cookie is expired")
        self.assertEqual(cookie['Domain'], '.arxiv.org', 'Domain is set')

        self.assertEqual(classic_cookie['value'], '',
                         'Classic cookie is unset')
        self.assertEqual(classic_cookie['Max-Age'], '0',
                         'Classic session cookie is expired')
        self.assertLessEqual(parse(classic_cookie['Expires']),
                             datetime.now(UTC),
                             'Classic session cookie is expired')
        self.assertEqual(classic_cookie['Domain'], '.arxiv.org',
                         'Domain is set')

        # Verify that the expiry is set in the database.
        with self.app.app_context():
            with legacy.transaction() as session:
                db_session = session.query(legacy.models.DBSession) \
                    .filter(legacy.models.DBSession.user_id == 1) \
                    .order_by(legacy.models.DBSession.session_id.desc()) \
                    .first()
                self.assertLessEqual(
                    datetime.fromtimestamp(db_session.end_time, tz=UTC),
                    datetime.now(UTC))