Пример #1
0
def test_auth_not_authorized(session, app, client):
    user = User(username="******")
    session.add(user)
    session.commit()

    @app.get("/me",
             dependencies=[
                 Depends(auth.validate_authenticated),
                 Security(auth.validate_all_scopes, scopes=["me"])
             ])
    async def _get():
        return {}

    app.add_middleware(AuthenticationMiddleware,
                       backend=auth.PayloadAuthBackend(user_cls=User))
    app.add_middleware(middleware.UpstreamPayloadMiddleware)
    app.add_middleware(middleware.SessionMiddleware, bind=session.bind)

    payload_prefix = middleware.UpstreamPayloadMiddleware.PAYLOAD_HEADER_PREFIX

    res = client.get(
        "/me",
        headers={
            f"{payload_prefix}username": user.username,
            f"{payload_prefix}permissions": "read,write"  # no "me" scope
        })
    assert res.status_code == 403
Пример #2
0
def test_payload_auth_backend_missing_session_error(mocker, loop):
    backend = auth.PayloadAuthBackend(user_cls=User)

    mock_conn = mocker.Mock(state=State({"payload": {"username": "******"}}))
    with pytest.raises(RuntimeError) as exc_info:
        loop.run_until_complete(backend.authenticate(mock_conn))

    error_msg = "Missing 'request.state.session': " \
                "try adding 'middleware.SessionMiddleware'"
    assert str(exc_info.value) == error_msg
Пример #3
0
def test_payload_auth_backend_missing_payload_error(mocker, loop):
    backend = auth.PayloadAuthBackend()

    mock_conn = mocker.Mock(state=State())
    with pytest.raises(RuntimeError) as exc_info:
        loop.run_until_complete(backend.authenticate(mock_conn))

    error_msg = "Missing 'request.state.payload': " \
                "try adding 'middleware.UpstreamPayloadMiddleware'"
    assert str(exc_info.value) == error_msg
Пример #4
0
def test_payload_auth_backend_no_user_cls(mocker, loop):
    expected_username = "******"

    backend = auth.PayloadAuthBackend()

    mock_conn = mocker.Mock(
        state=State({"payload": {
            "username": expected_username
        }}))
    result = loop.run_until_complete(backend.authenticate(mock_conn))
    assert result is not None
    assert len(result) == 2
    assert isinstance(result[1], SimpleUser)
    assert result[1].username == expected_username
Пример #5
0
def test_auth(session, app, client):
    user = User(username="******")
    session.add(user)
    session.commit()

    @app.get("/ping")
    def _ping():
        return "pong"

    @app.get("/me", dependencies=[
        Depends(auth.validate_authenticated),
    ])
    async def _get(request: Request):
        return {"user": request.user.as_dict(), "scopes": request.auth.scopes}

    @app.post("/me/scopes",
              dependencies=[
                  Depends(auth.validate_authenticated),
                  Security(auth.validate_all_scopes,
                           scopes=["test-scope", "write"])
              ])
    def _post(request: Request, ):
        return {"user": request.user.as_dict(), "scopes": request.auth.scopes}

    app.add_middleware(AuthenticationMiddleware,
                       backend=auth.PayloadAuthBackend(user_cls=User))
    app.add_middleware(middleware.UpstreamPayloadMiddleware)
    app.add_middleware(middleware.SessionMiddleware, bind=session.bind)

    # Test /ping - no auth & authz required
    res = client.get("/ping")
    assert res.status_code == 200, res.text
    assert res.text == '"pong"'

    # Test /me - auth required, no authz
    res = client.get("/me", headers={"X-Payload-username": user.username})
    assert res.status_code == 200, res.text
    assert res.json() == {"user": user.as_dict(), "scopes": []}

    # Test /me/scopes - auth & authz required
    res = client.post("/me/scopes",
                      headers={
                          "X-Payload-username": user.username,
                          "X-Payload-permissions": "test-scope,write"
                      })
    assert res.status_code == 200, res.text
    assert res.json() == {
        "user": user.as_dict(),
        "scopes": ["test-scope", "write"]
    }
Пример #6
0
def test_payload_auth_backend_scopes(loop):
    backend = auth.PayloadAuthBackend(admin_scope="admin")

    result = loop.run_until_complete(backend.scopes({"scopes": "read, write"}))
    assert result == ["read", "write"]

    result = loop.run_until_complete(
        backend.scopes({"permissions": "read, write"}))
    assert result == ["read", "write"]

    result = loop.run_until_complete(backend.scopes({}))
    assert result == []

    result = loop.run_until_complete(backend.scopes({"permissions": "admin"}))
    assert result == ["admin"]
Пример #7
0
def test_auth_not_authenticated(session, app, client):
    @app.get("/me", dependencies=[Depends(auth.validate_authenticated)])
    async def _get():
        return {}

    app.add_middleware(AuthenticationMiddleware,
                       backend=auth.PayloadAuthBackend(user_cls=User))
    app.add_middleware(middleware.UpstreamPayloadMiddleware)
    app.add_middleware(middleware.SessionMiddleware, bind=session.bind)

    payload_prefix = middleware.UpstreamPayloadMiddleware.PAYLOAD_HEADER_PREFIX

    res = client.get("/me",
                     headers={f"{payload_prefix}username": "******"})
    assert res.status_code == 401
Пример #8
0
def test_auth_any_scope(session, app, client):
    user = User(username="******")
    session.add(user)
    session.commit()

    @app.get("/me",
             dependencies=[
                 Depends(auth.validate_authenticated),
                 Security(auth.validate_any_scope, scopes=["admin", "read"])
             ])
    async def _get():
        return {}

    app.add_middleware(AuthenticationMiddleware,
                       backend=auth.PayloadAuthBackend(user_cls=User))
    app.add_middleware(middleware.UpstreamPayloadMiddleware)
    app.add_middleware(middleware.SessionMiddleware, bind=session.bind)

    payload_prefix = middleware.UpstreamPayloadMiddleware.PAYLOAD_HEADER_PREFIX

    # Test request with only "admin" scope
    res = client.get("/me",
                     headers={
                         f"{payload_prefix}username": user.username,
                         f"{payload_prefix}permissions": "admin"
                     })
    assert res.status_code == 200

    # Test request with only "read" scope
    res = client.get("/me",
                     headers={
                         f"{payload_prefix}username": user.username,
                         f"{payload_prefix}permissions": "read"
                     })
    assert res.status_code == 200

    # Test request without any scope
    res = client.get("/me",
                     headers={
                         f"{payload_prefix}username": user.username,
                         f"{payload_prefix}permissions": ""
                     })
    assert res.status_code == 403
Пример #9
0
def test_payload_auth_backend():
    backend = auth.PayloadAuthBackend(user_cls=User, admin_scope="admin")
    assert backend.user_cls is User
    assert backend.admin_scope == "admin"
Пример #10
0
def test_auth(session, app, client):
    user = User(username="******")
    session.add(user)
    session.commit()

    admin_scope = "admin"

    @app.get("/ping")
    def _ping():
        return "pong"

    @app.get("/me", dependencies=[
        Depends(auth.validate_authenticated),
    ])
    def _get(request: Request):
        return {
            "username": request.user.username,
            "scopes": request.auth.scopes
        }

    @app.get("/scopes/all",
             dependencies=[
                 Depends(
                     auth.AllScopesValidator(scopes=["read", "write", "me"],
                                             admin_scope=admin_scope))
             ])
    def _scopes_all(request: Request):
        return {
            "username": request.user.username,
            "scopes": request.auth.scopes
        }

    @app.get("/scopes/any",
             dependencies=[
                 Depends(
                     auth.AnyScopeValidator(scopes=["read", "write"],
                                            admin_scope=admin_scope))
             ])
    def _scopes_any(request: Request):
        return {
            "username": request.user.username,
            "scopes": request.auth.scopes
        }

    @app.get(
        "/admin",
        dependencies=[Depends(auth.AdminValidator(admin_scope=admin_scope))])
    def _admin(request: Request):
        return {
            "username": request.user.username,
            "scopes": request.auth.scopes
        }

    app.add_middleware(AuthenticationMiddleware,
                       backend=auth.PayloadAuthBackend(
                           user_cls=User, admin_scope=admin_scope))
    app.add_middleware(middleware.UpstreamPayloadMiddleware)
    app.add_middleware(middleware.SessionMiddleware, bind=session.bind)

    payload_prefix = middleware.UpstreamPayloadMiddleware.PAYLOAD_HEADER_PREFIX

    # Test /ping - no auth & authz required
    res = client.get("/ping")
    assert res.status_code == 200, res.text
    assert res.text == '"pong"'

    # Test /me - not authenticated
    res = client.get("/me",
                     headers={f"{payload_prefix}username": "******"})
    assert res.status_code == 401

    # Test /me - success
    res = client.get("/me",
                     headers={f"{payload_prefix}username": user.username})
    assert res.status_code == 200, res.text
    assert res.json() == {"username": user.username, "scopes": []}

    # Test /scopes/all - not authenticated
    res = client.get("/scopes/all",
                     headers={
                         f"{payload_prefix}username": "******",
                         f"{payload_prefix}permissions": "read,write"
                     })
    assert res.status_code == 401

    # Test /scopes/all - missing required scope
    res = client.get(
        "/scopes/all",
        headers={
            f"{payload_prefix}username": user.username,
            f"{payload_prefix}permissions": "read,write"  # no "me" scope
        })
    assert res.status_code == 403

    # Test /scopes/all - success
    res = client.get("/scopes/all",
                     headers={
                         f"{payload_prefix}username": user.username,
                         f"{payload_prefix}permissions": "read,write,me"
                     })
    assert res.status_code == 200, res.text
    assert res.json() == {
        "username": user.username,
        "scopes": ["read", "write", "me"]
    }

    # Test /scopes/all - admin scope - success
    res = client.get(
        "/scopes/all",
        headers={
            f"{payload_prefix}username": user.username,
            f"{payload_prefix}permissions":
            admin_scope  # not specified in endpoint
        })
    assert res.status_code == 200, res.text
    assert res.json() == {"username": user.username, "scopes": [admin_scope]}

    # Test /scopes/any - not authenticated
    res = client.get("/scopes/any",
                     headers={f"{payload_prefix}username": "******"})
    assert res.status_code == 401

    # Test /scopes/any - request without any scope
    res = client.get("/scopes/any",
                     headers={f"{payload_prefix}username": user.username})
    assert res.status_code == 403

    # Test /scopes/any - request with only "read" scope
    res = client.get("/scopes/any",
                     headers={
                         f"{payload_prefix}username": user.username,
                         f"{payload_prefix}permissions": "read"
                     })
    assert res.status_code == 200
    assert res.json() == {"username": user.username, "scopes": ["read"]}

    # Test /scopes/any - admin scope - success
    res = client.get(
        "/scopes/any",
        headers={
            f"{payload_prefix}username": user.username,
            f"{payload_prefix}permissions":
            admin_scope  # not specified in endpoint
        })
    assert res.status_code == 200
    assert res.json() == {"username": user.username, "scopes": [admin_scope]}

    # Test /admin - failed - no admin scope
    res = client.get("/admin",
                     headers={
                         "X-Payload-username": user.username,
                         "X-Payload-permissions": "non-admin-scope"
                     })
    assert res.status_code == 403

    # Test /admin - admin scope required
    res = client.get("/admin",
                     headers={
                         "X-Payload-username": user.username,
                         "X-Payload-permissions": f"{admin_scope},read"
                     })
    assert res.status_code == 200, res.text
    assert res.json() == {"username": user.username, "scopes": [admin_scope]}