[Python-modules-team] Bug#952172: django-oauth-toolkit: FTBFS: dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.8 3.7" --system=custom "--test-args=PYTHONPATH={build_dir} {interpreter} -m pytest" returned exit code 13
Lucas Nussbaum
lucas at debian.org
Sun Feb 23 13:06:46 GMT 2020
Source: django-oauth-toolkit
Version: 1.2.0-2
Severity: serious
Justification: FTBFS on amd64
Tags: bullseye sid ftbfs
Usertags: ftbfs-20200222 ftbfs-bullseye
Hi,
During a rebuild of all packages in sid, your package failed to build
on amd64.
Relevant part (hopefully):
> make[1]: Entering directory '/<<PKGBUILDDIR>>'
> dh_auto_test -- --system=custom --test-args="PYTHONPATH={build_dir} {interpreter} -m pytest"
> I: pybuild base:217: PYTHONPATH=/<<PKGBUILDDIR>>/.pybuild/cpython3_3.8_django-oauth-toolkit/build python3.8 -m pytest
> ============================= test session starts ==============================
> platform linux -- Python 3.8.2rc2, pytest-4.6.9, py-1.8.1, pluggy-0.13.0
> Django settings: tests.settings (from ini file)
> rootdir: /<<PKGBUILDDIR>>, inifile: tox.ini
> plugins: django-3.5.1
> collected 221 items
>
> tests/test_application_views.py ..... [ 2%]
> tests/test_auth_backends.py ........ [ 5%]
> tests/test_authorization_code.py .......................F..F......FFF..F [ 23%]
> ...... [ 26%]
> tests/test_client_credential.py ..... [ 28%]
> tests/test_decorators.py ... [ 29%]
> tests/test_generator.py ... [ 31%]
> tests/test_implicit.py ........... [ 36%]
> tests/test_introspection_auth.py ..... [ 38%]
> tests/test_introspection_view.py ......... [ 42%]
> tests/test_mixins.py ........ [ 46%]
> tests/test_models.py ....................... [ 56%]
> tests/test_oauth2_backends.py ...... [ 59%]
> tests/test_oauth2_validators.py ......................... [ 70%]
> tests/test_password.py F.. [ 71%]
> tests/test_rest_framework.py ............................. [ 85%]
> tests/test_scopes.py ............ [ 90%]
> tests/test_scopes_backend.py .. [ 91%]
> tests/test_token_revocation.py FFFFFF [ 94%]
> tests/test_token_view.py .......... [ 98%]
> tests/test_validators.py ... [100%]
>
> =================================== FAILURES ===================================
> _________ TestAuthorizationCodeTokenView.test_basic_auth_bad_authcode __________
>
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_basic_auth_bad_authcode>
>
> def test_basic_auth_bad_authcode(self):
> """
> Request an access token using a bad authorization code
> """
> self.client.login(username="test_user", password="123456")
>
> token_request_data = {
> "grant_type": "authorization_code",
> "code": "BLAH",
> "redirect_uri": "http://example.org"
> }
> auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> > self.assertEqual(response.status_code, 401)
> E AssertionError: 400 != 401
>
> tests/test_authorization_code.py:854: AssertionError
> _________ TestAuthorizationCodeTokenView.test_basic_auth_grant_expired _________
>
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_basic_auth_grant_expired>
>
> def test_basic_auth_grant_expired(self):
> """
> Request an access token using an expired grant token
> """
> self.client.login(username="test_user", password="123456")
> g = Grant(
> application=self.application, user=self.test_user, code="BLAH",
> expires=timezone.now(), redirect_uri="", scope="")
> g.save()
>
> token_request_data = {
> "grant_type": "authorization_code",
> "code": "BLAH",
> "redirect_uri": "http://example.org"
> }
> auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> > self.assertEqual(response.status_code, 401)
> E AssertionError: 400 != 401
>
> tests/test_authorization_code.py:890: AssertionError
> _________________ TestAuthorizationCodeTokenView.test_refresh __________________
>
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh>
>
> def test_refresh(self):
> """
> Request an access token using a refresh token
> """
> self.client.login(username="test_user", password="123456")
> authorization_code = self.get_auth()
>
> token_request_data = {
> "grant_type": "authorization_code",
> "code": authorization_code,
> "redirect_uri": "http://example.org"
> }
> auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> content = json.loads(response.content.decode("utf-8"))
> self.assertTrue("refresh_token" in content)
>
> # make a second token request to be sure the previous refresh token remains valid, see #65
> authorization_code = self.get_auth()
> token_request_data = {
> "grant_type": "authorization_code",
> "code": authorization_code,
> "redirect_uri": "http://example.org"
> }
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
>
> token_request_data = {
> "grant_type": "refresh_token",
> "refresh_token": content["refresh_token"],
> "scope": content["scope"],
> }
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> self.assertEqual(response.status_code, 200)
>
> content = json.loads(response.content.decode("utf-8"))
> self.assertTrue("access_token" in content)
>
> # check refresh token cannot be used twice
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> > self.assertEqual(response.status_code, 401)
> E AssertionError: 400 != 401
>
> tests/test_authorization_code.py:602: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG oauth2_provider:base.py:123 Success url for the request: http://example.org?code=l2AmHuE4wbSp2reQQN45z16cP3J0PO&state=random_state_string
> DEBUG oauth2_provider:base.py:123 Success url for the request: http://example.org?code=cRHhTdtbcuflkVoOTyPZyz6PbBekAL&state=random_state_string
> ____________ TestAuthorizationCodeTokenView.test_refresh_bad_scopes ____________
>
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh_bad_scopes>
>
> def test_refresh_bad_scopes(self):
> """
> Request an access token using a refresh token and wrong scopes
> """
> self.client.login(username="test_user", password="123456")
> authorization_code = self.get_auth()
>
> token_request_data = {
> "grant_type": "authorization_code",
> "code": authorization_code,
> "redirect_uri": "http://example.org"
> }
> auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> content = json.loads(response.content.decode("utf-8"))
> self.assertTrue("refresh_token" in content)
>
> token_request_data = {
> "grant_type": "refresh_token",
> "refresh_token": content["refresh_token"],
> "scope": "read write nuke",
> }
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> > self.assertEqual(response.status_code, 401)
> E AssertionError: 400 != 401
>
> tests/test_authorization_code.py:738: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG oauth2_provider:base.py:123 Success url for the request: http://example.org?code=iJ1ZqhQpW7nGz72LgOCtZtAMc1AMkT&state=random_state_string
> _____ TestAuthorizationCodeTokenView.test_refresh_fail_repeating_requests ______
>
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh_fail_repeating_requests>
>
> def test_refresh_fail_repeating_requests(self):
> """
> Try refreshing an access token with the same refresh token more than once
> """
> self.client.login(username="test_user", password="123456")
> authorization_code = self.get_auth()
>
> token_request_data = {
> "grant_type": "authorization_code",
> "code": authorization_code,
> "redirect_uri": "http://example.org"
> }
> auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> content = json.loads(response.content.decode("utf-8"))
> self.assertTrue("refresh_token" in content)
>
> token_request_data = {
> "grant_type": "refresh_token",
> "refresh_token": content["refresh_token"],
> "scope": content["scope"],
> }
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> self.assertEqual(response.status_code, 200)
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> > self.assertEqual(response.status_code, 401)
> E AssertionError: 400 != 401
>
> tests/test_authorization_code.py:766: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG oauth2_provider:base.py:123 Success url for the request: http://example.org?code=6b3Ykx9JcNqfZZP34hXp4LQKEMbfkf&state=random_state_string
> ________ TestAuthorizationCodeTokenView.test_refresh_repeating_requests ________
>
> self = <tests.test_authorization_code.TestAuthorizationCodeTokenView testMethod=test_refresh_repeating_requests>
>
> def test_refresh_repeating_requests(self):
> """
> Trying to refresh an access token with the same refresh token more than
> once succeeds in the grace period and fails outside
> """
> oauth2_settings.REFRESH_TOKEN_GRACE_PERIOD_SECONDS = 120
> self.client.login(username="test_user", password="123456")
> authorization_code = self.get_auth()
>
> token_request_data = {
> "grant_type": "authorization_code",
> "code": authorization_code,
> "redirect_uri": "http://example.org"
> }
> auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> content = json.loads(response.content.decode("utf-8"))
> self.assertTrue("refresh_token" in content)
>
> token_request_data = {
> "grant_type": "refresh_token",
> "refresh_token": content["refresh_token"],
> "scope": content["scope"],
> }
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> self.assertEqual(response.status_code, 200)
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> self.assertEqual(response.status_code, 200)
>
> # try refreshing outside the refresh window, see #497
> rt = RefreshToken.objects.get(token=content["refresh_token"])
> self.assertIsNotNone(rt.revoked)
> rt.revoked = timezone.now() - datetime.timedelta(minutes=10) # instead of mocking out datetime
> rt.save()
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> > self.assertEqual(response.status_code, 401)
> E AssertionError: 400 != 401
>
> tests/test_authorization_code.py:805: AssertionError
> ------------------------------ Captured log call -------------------------------
> DEBUG oauth2_provider:base.py:123 Success url for the request: http://example.org?code=6Op5KhS2YPELG4NWKYkhIL2OJb8Y3G&state=random_state_string
> __________________ TestPasswordTokenView.test_bad_credentials __________________
>
> self = <tests.test_password.TestPasswordTokenView testMethod=test_bad_credentials>
>
> def test_bad_credentials(self):
> """
> Request an access token using Resource Owner Password Flow
> """
> token_request_data = {
> "grant_type": "password",
> "username": "test_user",
> "password": "NOT_MY_PASS",
> }
> auth_headers = get_basic_auth_header(self.application.client_id, self.application.client_secret)
>
> response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
> > self.assertEqual(response.status_code, 401)
> E AssertionError: 400 != 401
>
> tests/test_password.py:79: AssertionError
> _________________ TestRevocationView.test_revoke_access_token __________________
>
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token>
>
> def test_revoke_access_token(self):
> """
>
> """
> tok = AccessToken.objects.create(
> user=self.test_user, token="1234567890",
> application=self.application,
> expires=timezone.now() + datetime.timedelta(days=1),
> scope="read write"
> )
> query_string = urlencode({
> "client_id": self.application.client_id,
> "client_secret": self.application.client_secret,
> "token": tok.token,
> })
> url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
> response = self.client.post(url)
> > self.assertEqual(response.status_code, 200)
> E AssertionError: 400 != 200
>
> tests/test_token_revocation.py:62: AssertionError
> ______________ TestRevocationView.test_revoke_access_token_public ______________
>
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token_public>
>
> def test_revoke_access_token_public(self):
> public_app = Application(
> name="Test Application",
> redirect_uris="http://localhost http://example.com http://example.org",
> user=self.dev_user,
> client_type=Application.CLIENT_PUBLIC,
> authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
> )
> public_app.save()
>
> tok = AccessToken.objects.create(
> user=self.test_user, token="1234567890", application=public_app,
> expires=timezone.now() + datetime.timedelta(days=1),
> scope="read write"
> )
>
> query_string = urlencode({
> "client_id": public_app.client_id,
> "token": tok.token,
> })
>
> url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
> response = self.client.post(url)
> > self.assertEqual(response.status_code, 200)
> E AssertionError: 400 != 200
>
> tests/test_token_revocation.py:89: AssertionError
> ____________ TestRevocationView.test_revoke_access_token_with_hint _____________
>
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token_with_hint>
>
> def test_revoke_access_token_with_hint(self):
> """
>
> """
> tok = AccessToken.objects.create(
> user=self.test_user, token="1234567890",
> application=self.application,
> expires=timezone.now() + datetime.timedelta(days=1),
> scope="read write"
> )
> query_string = urlencode({
> "client_id": self.application.client_id,
> "client_secret": self.application.client_secret,
> "token": tok.token,
> "token_type_hint": "access_token"
> })
> url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
> response = self.client.post(url)
> > self.assertEqual(response.status_code, 200)
> E AssertionError: 400 != 200
>
> tests/test_token_revocation.py:109: AssertionError
> ________ TestRevocationView.test_revoke_access_token_with_invalid_hint _________
>
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_access_token_with_invalid_hint>
>
> def test_revoke_access_token_with_invalid_hint(self):
> tok = AccessToken.objects.create(
> user=self.test_user, token="1234567890",
> application=self.application,
> expires=timezone.now() + datetime.timedelta(days=1),
> scope="read write"
> )
> # invalid hint should have no effect
> query_string = urlencode({
> "client_id": self.application.client_id,
> "client_secret": self.application.client_secret,
> "token": tok.token,
> "token_type_hint": "bad_hint"
> })
> url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
> response = self.client.post(url)
> > self.assertEqual(response.status_code, 200)
> E AssertionError: 400 != 200
>
> tests/test_token_revocation.py:128: AssertionError
> _________________ TestRevocationView.test_revoke_refresh_token _________________
>
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_refresh_token>
>
> def test_revoke_refresh_token(self):
> tok = AccessToken.objects.create(
> user=self.test_user, token="1234567890",
> application=self.application,
> expires=timezone.now() + datetime.timedelta(days=1),
> scope="read write"
> )
> rtok = RefreshToken.objects.create(
> user=self.test_user, token="999999999",
> application=self.application, access_token=tok
> )
> query_string = urlencode({
> "client_id": self.application.client_id,
> "client_secret": self.application.client_secret,
> "token": rtok.token,
> })
> url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
> response = self.client.post(url)
> > self.assertEqual(response.status_code, 200)
> E AssertionError: 400 != 200
>
> tests/test_token_revocation.py:149: AssertionError
> _____________ TestRevocationView.test_revoke_token_with_wrong_hint _____________
>
> self = <tests.test_token_revocation.TestRevocationView testMethod=test_revoke_token_with_wrong_hint>
>
> def test_revoke_token_with_wrong_hint(self):
> """
> From the revocation rfc, `Section 4.1.2`_ :
>
> If the server is unable to locate the token using the given hint,
> it MUST extend its search across all of its supported token types
> .. _`Section 4.1.2`: http://tools.ietf.org/html/draft-ietf-oauth-revocation-11#section-4.1.2
> """
> tok = AccessToken.objects.create(
> user=self.test_user, token="1234567890",
> application=self.application,
> expires=timezone.now() + datetime.timedelta(days=1),
> scope="read write"
> )
>
> query_string = urlencode({
> "client_id": self.application.client_id,
> "client_secret": self.application.client_secret,
> "token": tok.token,
> "token_type_hint": "refresh_token"
> })
> url = "{url}?{qs}".format(url=reverse("oauth2_provider:revoke-token"), qs=query_string)
> response = self.client.post(url)
> > self.assertEqual(response.status_code, 200)
> E AssertionError: 400 != 200
>
> tests/test_token_revocation.py:177: AssertionError
> =============================== warnings summary ===============================
> tests/test_application_views.py::TestApplicationViews::test_application_detail_owner
> tests/test_application_views.py::TestApplicationViews::test_application_list
> tests/test_authorization_code.py::TestRegressionIssue315::test_request_is_not_overwritten
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_code_post_auth_fails_when_redirect_uri_path_is_invalid
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_code_post_auth_forbidden_redirect_uri
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_code_post_auth_malicious_redirect_uri
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_approval_prompt
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_approval_prompt_default
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_default_redirect
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_forbibben_redirect
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_invalid_client
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_valid_client
> tests/test_authorization_code.py::TestAuthorizationCodeView::test_pre_auth_valid_client_custom_redirect_uri_scheme
> tests/test_authorization_code.py::TestDefaultScopes::test_pre_auth_default_scopes
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_implicit_fails_when_redirect_uri_path_is_invalid
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_default_redirect
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_forbibben_redirect
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_invalid_client
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_valid_client
> tests/test_implicit.py::TestImplicitAuthorizationCodeView::test_pre_auth_valid_client_default_scopes
> tests/test_token_view.py::TestAuthorizedTokenListView::test_empty_list_view
> tests/test_token_view.py::TestAuthorizedTokenListView::test_list_view_one_token
> tests/test_token_view.py::TestAuthorizedTokenListView::test_list_view_shows_correct_user_token
> tests/test_token_view.py::TestAuthorizedTokenListView::test_list_view_two_tokens
> tests/test_token_view.py::TestAuthorizedTokenDeleteView::test_delete_view_post_actually_deletes
> tests/test_token_view.py::TestAuthorizedTokenDeleteView::test_delete_view_works
> /usr/lib/python3/dist-packages/django/contrib/staticfiles/templatetags/staticfiles.py:24: RemovedInDjango30Warning: {% load staticfiles %} is deprecated in favor of {% load static %}.
> warnings.warn(
>
> -- Docs: https://docs.pytest.org/en/latest/warnings.html
> ============= 13 failed, 208 passed, 26 warnings in 40.01 seconds ==============
> E: pybuild pybuild:341: test: plugin custom failed with: exit code=1: PYTHONPATH=/<<PKGBUILDDIR>>/.pybuild/cpython3_3.8_django-oauth-toolkit/build python3.8 -m pytest
> dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.8 3.7" --system=custom "--test-args=PYTHONPATH={build_dir} {interpreter} -m pytest" returned exit code 13
The full build log is available from:
http://qa-logs.debian.net/2020/02/22/django-oauth-toolkit_1.2.0-2_unstable.log
A list of current common problems and possible solutions is available at
http://wiki.debian.org/qa.debian.org/FTBFS . You're welcome to contribute!
About the archive rebuild: The rebuild was done on EC2 VM instances from
Amazon Web Services, using a clean, minimal and up-to-date chroot. Every
failed build was retried once to eliminate random failures.
More information about the Python-modules-team
mailing list