Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] No bearer header causes crash in async authenticate() HttpBearer #1386

Open
mmkhitaryan opened this issue Jan 9, 2025 · 1 comment

Comments

@mmkhitaryan
Copy link

mmkhitaryan commented Jan 9, 2025

Describe the bug
I expect that if I write the same authenticate handlers in async and sync, they behave the same. But in reality, I get proper 401 with SyncBearerAuth and crash for AsyncBearerAuth with the same handling logic.

Traceback (most recent call last):
  File "C:\Users\Marat\Desktop\csmbackend\.venv\Lib\site-packages\ninja\operation.py", line 190, in _run_authentication
    result = async_to_sync(callback)(request)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marat\Desktop\csmbackend\.venv\Lib\site-packages\asgiref\sync.py", line 254, in __call__
    return call_result.result()
           ^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marat\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\_base.py", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marat\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\_base.py", line 401, in __get_result
    raise self._exception
  File "C:\Users\Marat\Desktop\csmbackend\.venv\Lib\site-packages\asgiref\sync.py", line 331, in main_wrap
    result = await self.awaitable(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: object NoneType can't be used in 'await' expression

Versions (please complete the following information):

  • Python version: 3.12.8
  • Django version: 5.1.4
  • Django-Ninja version: 1.3.0
  • Pydantic version: 2.10.5

Note you can quickly get this by runninng in ./manage.py shell this line:

import pytest

from ninja.security import (
    HttpBearer,
)
from ninja import NinjaAPI
from ninja.testing import TestClient, TestAsyncClient

class SyncBearerAuth(HttpBearer):
    def authenticate(self, request, token: str):
        return

class AsyncBearerAuth(HttpBearer):
    async def authenticate(self, request, token: str):
        return

api = NinjaAPI()

@api.get("/sync/", auth=SyncBearerAuth())
def sync_auth(request):
    return

@api.get("/async/", auth=AsyncBearerAuth())
def async_auth(request):
    return

client = TestClient(api)
async_client = TestAsyncClient(api)

def test_async_bearer_invalid_bearer():
    response = client.get("/async/", headers={"Authorization": "Bearer 123"})
    assert response.status_code == 401

def test_async_bearer_no_bearer():
    # TypeError: object NoneType can't be used in 'await' expression
    response = client.get("/async/")
    assert response.status_code == 401

def test_sync_bearer_no_berer():
    response = client.get("/sync/")
    assert response.status_code == 401

As you can see, the authenticate implementations are the same but no bearer header causes different behavior:

FAILED tests/test_weird_case.py::test_bearer_auth - TypeError: object NoneType can't be used in 'await' expression
@mmkhitaryan mmkhitaryan changed the title [BUG] Async authenticate() in HttpBearer causes crash [BUG] No bearer header causes crash in async authenticate() HttpBearer Jan 9, 2025
mmkhitaryan added a commit to mmkhitaryan/django-ninja that referenced this issue Jan 9, 2025
@mmkhitaryan
Copy link
Author

Made a PR: #1387

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant