async def test_refresh_with_session_data(client: TestClient):
    async with request_mock() as mock_request:
        start_st()
        mock_request.post(
            url='https://' + AUTH0_DOMAIN + '/oauth/token',
            name="t1"
        ).respond(
            status_code=200,
            json={
                'id_token': TEST_ID_TOKEN,
                'expires_in': get_timestamp_ms() + 30000,
                'access_token': 'test-access-token',
                'refresh_token': 'test-refresh-token'
            }
        )
        r1 = client.post("/login-without-callback", json={
            'action': 'login',
            'redirect_uri': 'http://localhost:3000',
            'code': 'randomString'
        })
        c1 = extract_all_cookies(r1)
        mock_request.pop('t1')
        mock_request.post(
            url='https://' + AUTH0_DOMAIN + '/oauth/token',
            name="t2"
        ).respond(
            status_code=200,
            json={
                'id_token': 'custom-token',
                'expires_in': get_timestamp_ms() + 30000,
                'access_token': 'test-access-token',
                'refresh_token': 'test-refresh-token'
            }
        )

        r2 = client.post(
            url="/refresh-auth0",
            cookies={
                'sAccessToken': c1['sAccessToken']['value'],
                'sIdRefreshToken': c1['sIdRefreshToken']['value']
            },
            headers={
                'anti-csrf': r1.headers.get('anti-csrf')
            },
            json={
                'action': 'refresh'
            }
        )
        assert r2.status_code == 200
        assert r2.json()['id_token'] == 'custom-token'
Ejemplo n.º 2
0
async def test_refresh_non_200_response(client: TestClient):
    async with request_mock() as mock:
        start_st()
        mock.post(url='https://' + AUTH0_DOMAIN + '/oauth/token',
                  status_code=200,
                  content={
                      'id_token': TEST_ID_TOKEN,
                      'expires_in': get_timestamp_ms() + 30000,
                      'access_token': 'test-access-token',
                      'refresh_token': 'test-refresh-token'
                  },
                  alias='t1')
        r1 = client.post("/login-without-callback",
                         json={
                             'action': 'login',
                             'redirect_uri': 'http://localhost:3000',
                             'code': 'randomString'
                         })
        c1 = extract_all_cookies(r1)
        mock.pop('t1')
        mock.post(url='https://' + AUTH0_DOMAIN + '/oauth/token',
                  status_code=403,
                  content={},
                  alias='t2')
        r2 = client.post(url="/refresh-auth0",
                         cookies={
                             'sAccessToken': c1['sAccessToken']['value'],
                             'sIdRefreshToken': c1['sIdRefreshToken']['value']
                         },
                         headers={'anti-csrf': r1.headers.get('anti-csrf')},
                         json={'action': 'refresh'})
        assert r2.status_code == 403
async def test_login_with_callback(client: TestClient):
    async with request_mock() as mock_request:
        start_st()
        mock_request.post(
            url='https://' + AUTH0_DOMAIN + '/oauth/token'
        ).respond(
            status_code=200,
            json={
                'id_token': TEST_ID_TOKEN,
                'expires_in': get_timestamp_ms() + 30000,
                'access_token': 'test-access-token',
                'refresh_token': 'test-refresh-token'
            }
        )
        r1 = client.post("/login-with-callback-save-rt", json={
            'action': 'login',
            'redirect_uri': 'http://localhost:3000',
            'code': 'randomString'
        })
        c1 = extract_all_cookies(r1)
        r2 = client.get(
            url="/get-session-data",
            cookies={
                'sAccessToken': c1['sAccessToken']['value'],
                'sIdRefreshToken': c1['sIdRefreshToken']['value']
            }
        )
        assert r2.json() == {
            'access_token': 'test-access-token',
            'refresh_token': 'test-refresh-token'
        }
Ejemplo n.º 4
0
async def set_cookie(response: Response, key, value, expires, path, domain,
                     secure, http_only, same_site):
    response.delete_cookie(key)  # Delete earlier cookies
    if CookieConfig.get_instance().cookie_domain is not None:
        domain = CookieConfig.get_instance().cookie_domain
    if CookieConfig.get_instance().cookie_secure is not None:
        secure = CookieConfig.get_instance().cookie_secure
    if CookieConfig.get_instance().cookie_same_site is not None:
        same_site = CookieConfig.get_instance().cookie_same_site
    handshake_info = await HandshakeInfo.get_instance()
    if path in {
            handshake_info.refresh_token_path, handshake_info.access_token_path
    }:
        if path == handshake_info.access_token_path and CookieConfig.get_instance(
        ).access_token_path is not None:
            path = CookieConfig.get_instance().access_token_path
        elif path == handshake_info.refresh_token_path and CookieConfig.get_instance(
        ).refresh_token_path is not None:
            path = CookieConfig.get_instance().refresh_token_path
    response.set_cookie(key=key,
                        value=quote(value, encoding='utf-8'),
                        expires=((expires - get_timestamp_ms()) // 1000),
                        path=path,
                        domain=domain,
                        secure=secure,
                        httponly=http_only,
                        samesite=same_site)
async def test_logout_without_depends(client: TestClient):
    async with request_mock() as mock_request:
        start_st()
        mock_request.post(
            url='https://' + AUTH0_DOMAIN + '/oauth/token'
        ).respond(
            status_code=200,
            json={
                'id_token': TEST_ID_TOKEN,
                'expires_in': get_timestamp_ms() + 30000,
                'access_token': 'test-access-token',
                'refresh_token': 'test-refresh-token'
            }
        )
        r1 = client.post("/login-without-callback", json={
            'action': 'login',
            'redirect_uri': 'http://localhost:3000',
            'code': 'randomString'
        })
        c1 = extract_all_cookies(r1)
        r2 = client.post(
            url="/logout-without-depends",
            cookies={
                'sAccessToken': c1['sAccessToken']['value'],
                'sIdRefreshToken': c1['sIdRefreshToken']['value']
            },
            headers={
                'anti-csrf': r1.headers.get('anti-csrf')
            },
            json={
                'action': 'logout'
            }
        )
        c2 = extract_all_cookies(r2)
        assert r2.headers.get('anti-csrf') is None
        assert c2['sAccessToken']['value'] == ''
        assert c2['sRefreshToken']['value'] == ''
        assert c2['sIdRefreshToken']['value'] == ''
        assert c2['sAccessToken']['path'] == '/'
        assert c2['sRefreshToken']['path'] == '/refresh'
        assert c2['sIdRefreshToken']['path'] == '/'
        assert c2['sAccessToken']['httponly']
        assert c2['sRefreshToken']['httponly']
        assert c2['sIdRefreshToken']['httponly']
        assert c2['sAccessToken']['secure'] is None
        assert c2['sRefreshToken']['secure'] is None
        assert c2['sIdRefreshToken']['secure'] is None
        assert verify_within_5_second_diff(
            get_unix_timestamp(c2['sAccessToken']['expires']), 0
        )
        assert verify_within_5_second_diff(
            get_unix_timestamp(c2['sRefreshToken']['expires']), 0
        )
        assert verify_within_5_second_diff(
            get_unix_timestamp(c2['sIdRefreshToken']['expires']), 0
        )
        assert r2.headers['Id-Refresh-Token'] == 'remove'
Ejemplo n.º 6
0
async def get_session(access_token: str, anti_csrf_token: Union[str, None], do_anti_csrf_check: bool):
    handshake_info = await HandshakeInfo.get_instance()

    try:
        if handshake_info.jwt_signing_public_key_expiry_time > get_timestamp_ms():
            access_token_info = get_info_from_access_token(access_token, handshake_info.jwt_signing_public_key,
                                                           handshake_info.enable_anti_csrf and do_anti_csrf_check)

            if handshake_info.enable_anti_csrf and do_anti_csrf_check and \
                    (anti_csrf_token is None or anti_csrf_token != access_token_info['antiCsrfToken']):
                if anti_csrf_token is None:
                    raise_try_refresh_token_exception('anti_csrf_token is undefined')
                raise_try_refresh_token_exception('anti-csrf check failed')

            if not handshake_info.access_token_blacklisting_enabled and \
                    access_token_info['parentRefreshTokenHash1'] is None:
                ProcessState.update_service_called(False)
                return {
                    'session': {
                        'handle': access_token_info['sessionHandle'],
                        'userId': access_token_info['userId'],
                        'userDataInJWT': access_token_info['userData']
                    }
                }
    except SuperTokensTryRefreshTokenError:
        pass

    ProcessState.update_service_called(True)

    data = {
        'accessToken': access_token,
        'doAntiCsrfCheck': do_anti_csrf_check
    }
    if anti_csrf_token is not None:
        data['antiCsrfToken'] = anti_csrf_token

    response = await Querier.get_instance().send_post_request(SESSION_VERIFY, data)
    if response['status'] == 'OK':
        handshake_info = await HandshakeInfo.get_instance()
        handshake_info.update_jwt_signing_public_key_info(response['jwtSigningPublicKey'],
                                                          response['jwtSigningPublicKeyExpiryTime'])
        response.pop('status', None)
        response.pop('jwtSigningPublicKey', None)
        response.pop('jwtSigningPublicKeyExpiryTime', None)
        return response
    elif response['status'] == 'UNAUTHORISED':
        raise_unauthorised_exception(response['message'])
    else:
        raise_try_refresh_token_exception(response['message'])
Ejemplo n.º 7
0
def test_set_cookie(client: TestClient):
    start_st()
    expiry = get_timestamp_ms()
    response = client.get('/?expiry=' + str(expiry))
    test_cookie = get_cookie_from_response(response, 'test')
    assert test_cookie is not None
    assert test_cookie['value'] == 'value'
    assert test_cookie['domain'] == 'localhost.org'
    assert test_cookie['path'] == '/'
    assert test_cookie['samesite'] == 'none' or test_cookie['samesite'] == 'lax'
    assert test_cookie['secure']
    assert test_cookie.get('httponly') is None
    assert verify_within_5_second_diff(
        get_unix_timestamp(test_cookie['expires']), floor(expiry / 1000)
    )
Ejemplo n.º 8
0
async def test_login_invalid_id_token(client: TestClient):
    async with request_mock() as mock:
        start_st()
        mock.post(url='https://' + AUTH0_DOMAIN + '/oauth/token',
                  status_code=200,
                  content={
                      'id_token': 'invalid token',
                      'expires_in': get_timestamp_ms() + 30000,
                      'access_token': 'test-access-token',
                      'refresh_token': 'test-refresh-token'
                  })
        r1 = client.post("/login-without-callback",
                         json={
                             'action': 'login',
                             'redirect_uri': 'http://localhost:3000',
                             'code': 'randomString'
                         })
        assert r1.status_code == 500
Ejemplo n.º 9
0
async def test_login_with_callback_error_thrown(client: TestClient):
    async with request_mock() as mock:
        start_st()
        mock.post(url='https://' + AUTH0_DOMAIN + '/oauth/token',
                  status_code=200,
                  content={
                      'id_token': TEST_ID_TOKEN,
                      'expires_in': get_timestamp_ms() + 30000,
                      'access_token': 'test-access-token',
                      'refresh_token': 'test-refresh-token'
                  })
        r1 = client.post("/login-with-error-callback",
                         json={
                             'action': 'login',
                             'redirect_uri': 'http://localhost:3000',
                             'code': 'randomString'
                         })
        assert r1.status_code == 500
        assert r1.json() == {'detail': 'access token not matching'}
async def test_login_without_callback(client: TestClient):
    async with request_mock() as mock_request:
        start_st()
        mock_request.post(
            url='https://' + AUTH0_DOMAIN + '/oauth/token'
        ).respond(
            status_code=200,
            json={
                'id_token': TEST_ID_TOKEN,
                'expires_in': get_timestamp_ms() + 30000,
                'access_token': 'test-access-token',
                'refresh_token': 'test-refresh-token'
            }
        )
        r = client.post("/login-without-callback", json={
            'action': 'login',
            'redirect_uri': 'http://localhost:3000',
            'code': 'randomString'
        })
        assert r.json()['id_token'] == TEST_ID_TOKEN
Ejemplo n.º 11
0
def get_info_from_access_token(token, jwt_signing_public_key,
                               do_anti_csrf_check):
    try:
        payload = get_payload(token, jwt_signing_public_key)
        session_handle = sanitize_string(payload.get('sessionHandle'))
        user_id = sanitize_string(payload.get('userId'))
        refresh_token_hash_1 = sanitize_string(
            payload.get('refreshTokenHash1'))
        parent_refresh_token_hash_1 = sanitize_string(
            payload.get('parentRefreshTokenHash1'))
        user_data = payload.get('userData')
        anti_csrf_token = sanitize_string(payload.get('antiCsrfToken'))
        expiry_time = sanitize_number(payload.get('expiryTime'))
        time_created = sanitize_number(payload.get('timeCreated'))

        if (session_handle is None) or \
                (user_data is None) or \
                (refresh_token_hash_1 is None) or \
                (user_data is None) or \
                (anti_csrf_token is None and do_anti_csrf_check) or \
                (expiry_time is None) or \
                (time_created is None):
            raise Exception(
                'Access token does not contain all the information. Maybe the structure has changed?'
            )

        if expiry_time < get_timestamp_ms():
            raise Exception('Access token expired')

        return {
            'sessionHandle': session_handle,
            'userId': user_id,
            'refreshTokenHash1': refresh_token_hash_1,
            'parentRefreshTokenHash1': parent_refresh_token_hash_1,
            'userData': user_data,
            'antiCsrfToken': anti_csrf_token,
            'expiryTime': expiry_time,
            'timeCreated': time_created
        }
    except Exception as e:
        raise_try_refresh_token_exception(e)