Exemple #1
0
def test_middleware_token_validation_raises_error_on_token_exp(app_settings):
    def test_handler(jwt_identity: JWTIdentity):
        if jwt_identity is None:
            return "No user token present"
        return jwt_identity.id

    jwt = JWT(key="keepthissafe", alg="HS256")
    iat = dt.datetime.now() + dt.timedelta(seconds=-10)
    exp = iat + dt.timedelta(seconds=5)
    payload = {"sub": "1234567890", "name": "John Doe", "iat": iat, "exp": exp}
    token = jwt.encode(payload)

    routes = [Route("/auth-required", method="GET", handler=test_handler)]

    components = [
        SettingsComponent(app_settings),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    middleware = [ResponseRendererMiddleware(), JWTAuthMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    response = client.get("/auth-required",
                          headers={"Authorization": f"Bearer {token}"})
    assert 401 == response.status_code
    content = response.json()
    assert "error_message" in content
    assert content.get("status") == 401
Exemple #2
0
def test_middleware_white_listing(app_settings, testing_token):
    def test_handler(jwt_identity: JWTIdentity):
        if jwt_identity is None:
            return "No user token present"
        return jwt_identity.id

    routes = [Route("/whitelisted", method="GET", handler=test_handler)]

    components = [
        SettingsComponent({
            **app_settings, "JWT_AUTH_WHITELIST": ["test_handler"]
        }),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    middleware = [ResponseRendererMiddleware(), JWTAuthMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    response = client.get("/whitelisted",
                          headers={"Authorization": f"Bearer {testing_token}"})

    unauthenticated = client.get("/whitelisted")
    assert 200 == response.status_code
    assert "1234567890" in response.data
    assert 200 == unauthenticated.status_code
    assert "No user token present" in unauthenticated.data
Exemple #3
0
def test_test_client_raises_an_error_if_given_both_data_and_json():
    # Given that I have a test client
    client = testing.TestClient(app)

    # When I try to pass it both data and json params
    # Then a RuntimeError should be raised
    with pytest.raises(RuntimeError):
        client.get("/", data={}, json={})
Exemple #4
0
def test_complex_apps_can_render_the_swagger_ui():
    # Given that I have a complex app
    # When I visit its docs uri
    response = testing.TestClient(app).get("/docs")

    # Then I should get back a successful response
    assert response.status_code == 200
    assert response.headers["content-type"] == "text/html"
    assert app.reverse_uri("schema") in response.data
Exemple #5
0
def test_complex_apps_can_return_openapi_document():
    # Given that I have a complex app
    # When I visit its schema uri
    response = testing.TestClient(app).get("/schema.json")

    # Then I should get back a successful response
    assert response.status_code == 200
    with open("tests/openapi/fixtures/complex.json") as f:
        assert response.json() == json.load(f)
Exemple #6
0
def test_empty_app_can_return_openapi_document():
    # Given that I have an empty app
    app = App(routes=[
        Route("/schema.json",
              OpenAPIHandler(
                  Metadata(
                      title="empty application",
                      description="an application that doesn't do anything",
                      version="0.1.0",
                      contact=Contact(name="Jim Gordon", ),
                  )),
              name="schema"),
    ])

    # When I visit its schema uri
    response = testing.TestClient(app).get("/schema.json")

    # Then I should get back a successful response
    assert response.status_code == 200
    assert response.json() == {
        "openapi": "3.0.1",
        "info": {
            "title": "empty application",
            "description": "an application that doesn't do anything",
            "version": "0.1.0",
            "contact": {
                "name": "Jim Gordon",
            },
        },
        "paths": {
            "/schema.json": {
                "get": {
                    "tags": [],
                    "operationId": "schema",
                    "summary": "Generates an OpenAPI v3 document.",
                    "description": "",
                    "deprecated": False,
                    "parameters": [],
                    "responses": {
                        "200": {
                            "description": "A successful response.",
                            "content": {},
                        },
                    },
                }
            }
        },
        "components": {
            "schemas": {},
            "securitySchemes": {},
        },
    }
Exemple #7
0
def test_apps_session_cookies_expire():
    # Given that I have an app with a cookie store that immediately expires session cookies
    cookie_store = CookieStore(b"secret", cookie_ttl=0)

    def set_username(username: str, session: Session) -> None:
        session["username"] = username

    def get_username(session: Session) -> Optional[str]:
        return session.get("username")

    app = App(
        components=[
            SessionComponent(cookie_store),
        ],

        middleware=[
            SessionMiddleware(cookie_store),
            ResponseRendererMiddleware(),
        ],

        routes=[
            Route("/set-username/{username}", set_username),
            Route("/get-username", get_username),
        ],
    )

    # And a client for that app
    client = testing.TestClient(app)

    # When I make a request to a handler that stores session data
    response = client.get(app.reverse_uri("set_username", username="******"))

    # Then I should get back a successful response
    assert response.status_code == 200

    # And the response should contain my session cookie
    cookie = cookies.SimpleCookie()
    for data in response.headers.get_all("set-cookie"):
        cookie.load(data.replace("SameSite=Strict", ""))

    assert "__sess__" in cookie

    # When I make another request with that same cookie
    session_cookie = cookie.output(attrs=[], header="")
    response = client.get(app.reverse_uri("get_username"), headers={
        "cookie": session_cookie,
    })

    # Then I should get back nothing
    assert response.json() is None
Exemple #8
0
def test_claims_required_attaches_values(app_settings):
    @claims_required({"admin": True})
    def test_handler():
        return "Handler called"

    routes = [Route("/claims", method="GET", handler=test_handler)]

    components = [SettingsComponent(app_settings)]

    middleware = [ResponseRendererMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    response = client.get("/claims")
    assert 200 == response.status_code
    assert "admin" in test_handler.claims
    assert test_handler.claims.get("admin") is True
    assert "Handler called" in response.data
Exemple #9
0
def test_middleware_raises_401_error(app_settings):
    def test_handler():
        return "Handler called"

    routes = [Route("/auth-required", method="GET", handler=test_handler)]

    components = [
        SettingsComponent(app_settings),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    middleware = [ResponseRendererMiddleware(), JWTAuthMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    response = client.get("/auth-required")
    assert 401 == response.status_code
Exemple #10
0
def test_test_client_auth():
    # Given that I have a test client
    client = testing.TestClient(app)

    # When I make a request without auth
    response = client.get("/")

    # Then I should get a 403 back
    assert response.status_code == 403
    assert response.data == '{"error": "Forbidden"}'

    # When I make a request with auth
    def auth(request):
        request.headers["authorization"] = "Bearer authorized"
        return request

    response = client.get("/", auth=auth)

    # Then I should get back a 200
    assert response.status_code == 200
Exemple #11
0
def test_JWT_claims_options_raises_error(app_settings, testing_token):
    def test_handler(jwt_identity: JWTIdentity):
        if jwt_identity is None:
            return "No user token present"
        return jwt_identity.id

    jwt = JWT(key=app_settings.get("JWT_SECRET_KEY"), alg="HS256")
    mod_token = jwt.encode({
        **jwt.decode(testing_token),
        **{
            "iss": "https://molten.com"
        }
    })

    routes = [Route("/claim_options", method="GET", handler=test_handler)]

    components = [
        SettingsComponent({
            **app_settings,
            "JWT_CLAIMS_OPTIONS": {
                "iss": {
                    "essential": True,
                    "values": ["https://example.com", "https://example.org"],
                }
            },
        }),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    middleware = [ResponseRendererMiddleware(), JWTAuthMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    missing_claim_response = client.get(
        "/claim_options", headers={"Authorization": f"Bearer {testing_token}"})
    wrong_claim_value_response = client.get(
        "/claim_options", headers={"Authorization": f"Bearer {mod_token}"})
    assert 401 == missing_claim_response.status_code
    assert 401 == wrong_claim_value_response.status_code
Exemple #12
0
def test_claims_required_raises_error(app_settings, testing_token):
    @claims_required({"admin": True})
    def test_handler():
        return "Handler called"

    routes = [Route("/claims", method="GET", handler=test_handler)]

    components = [
        SettingsComponent(app_settings),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    middleware = [ResponseRendererMiddleware(), JWTAuthMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    response = client.get("/claims",
                          headers={"Authorization": f"Bearer {testing_token}"})
    assert 403 == response.status_code
Exemple #13
0
def test_middleware_anonymous_user_support(app_settings):
    @allow_anonymous
    def test_handler():
        return "Handler called"

    routes = [Route("/auth-maybe", method="GET", handler=test_handler)]

    components = [
        SettingsComponent(app_settings),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    middleware = [ResponseRendererMiddleware(), JWTAuthMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    response = client.get("/auth-maybe")
    assert 200 == response.status_code
    assert "Handler called" in response.data
Exemple #14
0
def test_identity_extract_jwt_from_cookie(app_settings):
    def test_auth(jwt: JWT):
        cookie_name = "molten_auth_cookie"
        cookie_value = jwt.encode({"sub": 123456, "name": "spiderman"})
        auth_response = Response(HTTP_200)
        auth_response.set_cookie(Cookie(cookie_name, cookie_value))
        return auth_response

    def test_cookie(jwt_identity: JWTIdentity):
        if jwt_identity is None:
            return "Didn't work"
        return f"Hello {jwt_identity.name} your sub id is {jwt_identity.sub}"

    routes = [
        Route("/auth", method="POST", handler=test_auth),
        Route("/cookie", method="GET", handler=test_cookie),
    ]

    components = [
        SettingsComponent({
            **app_settings,
            **{
                "JWT_AUTH_COOKIE": "molten_auth_cookie"
            }
        }),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    app = App(routes=routes, components=components)
    client = testing.TestClient(app)

    auth_response = client.post("/auth")
    cookie_value = auth_response.headers.get_all("set-cookie")[0]
    assert "molten_auth_cookie" in cookie_value
    cookie_response = client.get("/cookie", headers={"cookie": cookie_value})
    assert "123456" in cookie_response.data
    assert "spiderman" in cookie_response.data
Exemple #15
0
def test_middleware_token_validation_passes(app_settings, testing_token):
    def test_handler(jwt_identity: JWTIdentity):
        if jwt_identity is None:
            return "No user token present"
        return jwt_identity.id

    routes = [Route("/auth-required", method="GET", handler=test_handler)]

    components = [
        SettingsComponent(app_settings),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    middleware = [ResponseRendererMiddleware(), JWTAuthMiddleware()]

    app = App(routes=routes, components=components, middleware=middleware)
    client = testing.TestClient(app)

    response = client.get("/auth-required",
                          headers={"Authorization": f"Bearer {testing_token}"})
    assert 200 == response.status_code
    assert "1234567890" in response.data
def test_app_can_render_mail_templates():
    mail = Mail(
        user="******",
        password="******",
        port=587,
        use_tls=True,
        suppress_send=True,
    )
    mail.send = MagicMock(return_value=None)

    def template_handler(mail_templates: MailTemplates) -> Response:
        mail.send_message(
            subject="Test email",
            html=mail_templates.render("test_template.html", name="Molten"),
            recipients=["*****@*****.**"],
        )
        return Response(HTTP_204, content="")

    app = App(
        components=[MailTemplatesComponent("./tests/mail_templates")],
        routes=[Route("/", template_handler, name="index")],
    )

    client = testing.TestClient(app)

    # Given that a handler will use templating
    # When constructing and email
    response = client.get(app.reverse_uri("index"))

    # Then I should get back a successfull response
    assert response.status_code == 204

    # and the handler should have called the Mail object
    # with the string value of the rendered template
    mail_msg = mail.send.call_args[0][0]
    assert "<th>Hey there Molten</th>" in mail_msg.html
Exemple #17
0
def test_missing_auth_cookie(app_settings):
    def test_cookie(jwt_identity: JWTIdentity):
        if jwt_identity is None:
            return "Didn't work"
        return f"Hello {jwt_identity.name} your sub id is {jwt_identity.sub}"

    routes = [Route("/cookie", method="GET", handler=test_cookie)]

    components = [
        SettingsComponent({
            **app_settings,
            **{
                "JWT_AUTH_COOKIE": "molten_auth_cookie"
            }
        }),
        JWTComponent(),
        JWTIdentityComponent(),
    ]

    app = App(routes=routes, components=components)
    client = testing.TestClient(app)

    cookie_response = client.get("/cookie")
    assert "Didn't work" in cookie_response.data
Exemple #18
0
app = App(components=[
    TOMLSettingsComponent("tests/contrib/fixtures/sqlalchemy_settings.toml"),
    SQLAlchemyEngineComponent(),
    SQLAlchemySessionComponent(),
],
          middleware=[
              ResponseRendererMiddleware([JSONRenderer()]),
              SQLAlchemyMiddleware(),
          ],
          routes=[
              Route("/todos", create_todo, method="POST"),
              Route("/todos/{todo_id}", get_todo),
              Route("/no-db", no_db),
          ])

client = testing.TestClient(app)


def initdb(engine_data: EngineData):
    Base.metadata.create_all(engine_data.engine)


resolver = app.injector.get_resolver()
resolver.resolve(initdb)()


def test_can_create_and_retrieve_todos():
    # When I make a request to create a todo
    response = client.post(
        app.reverse_uri("create_todo"),
        json={"description": "test"},
Exemple #19
0
def client(app):
    """Creates a testing client"""
    return testing.TestClient(app)
Exemple #20
0
def client():
    return testing.TestClient(app)
Exemple #21
0
def client(test_app):
    return testing.TestClient(test_app)