async def test_oauth_access_scopes(
    app,
    mockservice_url,
    create_user_with_scopes,
    access_scopes,
    expect_success,
):
    """Check that oauth/authorize validates access scopes"""
    service = mockservice_url
    access_scopes = [s.replace("$service", service.name) for s in access_scopes]
    url = url_path_join(public_url(app, mockservice_url) + 'owhoami/?arg=x')
    # first request is only going to login and get us to the oauth form page
    s = AsyncSession()
    user = create_user_with_scopes(*access_scopes)
    name = user.name
    s.cookies = await app.login_user(name)

    r = await s.get(url)
    if not expect_success:
        assert r.status_code == 403
        return
    r.raise_for_status()
    # we should be looking at the oauth confirmation page
    assert urlparse(r.url).path == app.base_url + 'hub/api/oauth2/authorize'
    # verify oauth state cookie was set at some point
    assert set(r.history[0].cookies.keys()) == {f'service-{service.name}-oauth-state'}

    # submit the oauth form to complete authorization
    r = await s.post(r.url, data={"_xsrf": s.cookies["_xsrf"]})
    r.raise_for_status()
    assert r.url == url
    # verify oauth cookie is set
    assert f'service-{service.name}' in set(s.cookies.keys())
    # verify oauth state cookie has been consumed
    assert f'service-{service.name}-oauth-state' not in set(s.cookies.keys())

    # second request should be authenticated, which means no redirects
    r = await s.get(url, allow_redirects=False)
    r.raise_for_status()
    assert r.status_code == 200
    reply = r.json()
    sub_reply = {key: reply.get(key, 'missing') for key in ('kind', 'name')}
    assert sub_reply == {'name': name, 'kind': 'user'}

    # revoke user access, should result in 403
    user.roles = []
    app.db.commit()

    # reset session id to avoid cached response
    s.cookies.pop('jupyterhub-session-id')

    r = await s.get(url, allow_redirects=False)
    assert r.status_code == 403
Check that oauth/authorize validates access scopes
jupyterhub/tests/test_services_auth.py