async def test_hubauth_service_token(request, app, mockservice_url, scopes, allowed):
    """Test HubAuthenticated service with service API tokens"""

    scopes = [scope.replace('$service', mockservice_url.name) for scope in scopes]

    token = hexlify(os.urandom(5)).decode('utf8')
    name = 'test-api-service'
    app.service_tokens[token] = name
    await app.init_api_tokens()

    orm_service = app.db.query(orm.Service).filter_by(name=name).one()
    role_name = "test-hubauth-service-token"

    roles.create_role(
        app.db,
        {
            "name": role_name,
            "description": "role for test",
            "scopes": scopes,
        },
    )
    request.addfinalizer(lambda: roles.delete_role(app.db, role_name))
    roles.grant_role(app.db, orm_service, role_name)

    # token in Authorization header
    r = await async_requests.get(
        public_url(app, mockservice_url) + 'whoami/',
        headers={'Authorization': f'token {token}'},
        allow_redirects=False,
    )
    service_model = {
        'kind': 'service',
        'name': name,
        'admin': False,
        'scopes': scopes,
    }
    if allowed:
        r.raise_for_status()
        assert r.status_code == 200
        reply = r.json()
        assert service_model.items() <= reply.items()
        assert not r.cookies
    else:
        assert r.status_code == 403

    # token in ?token parameter is not allowed by default
    r = await async_requests.get(
        public_url(app, mockservice_url) + f'whoami/?token={token}',
        allow_redirects=False,
    )
    assert r.status_code == 403
Test HubAuthenticated service with service API tokens
jupyterhub/tests/test_services_auth.py