From 680789c59068696484a4973c3f2377a11341385f Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Thu, 30 May 2024 08:14:27 -0300 Subject: [PATCH] Switch to oauth2 authentication (#697) * Switch to oauth2 authentication * Update ChangesetCommentAPI to use oauth2 * FIx comment api tests * Update social-user's extra_data param in tests * Update tests to oauth2 fields * Fix client.post and token check --- config/settings/common.py | 14 ++-- osmchadjango/changeset/tasks.py | 21 +++--- .../changeset/tests/test_add_feature_views.py | 8 +-- .../changeset/tests/test_changeset_views.py | 52 +++++++-------- .../changeset/tests/test_comment_views.py | 64 +++++++++---------- .../tests/test_reasons_tags_views.py | 12 ++-- .../tests/test_review_features_views.py | 19 ++---- .../changeset/tests/test_stats_views.py | 4 +- .../changeset/tests/test_tag_changes_view.py | 4 +- osmchadjango/changeset/tests/test_tasks.py | 45 ++++++------- .../changeset/tests/test_whitelist_views.py | 8 +-- .../roulette_integration/tests/test_views.py | 8 +-- osmchadjango/supervise/tests/test_views.py | 34 +++++----- .../migrations/0012_auto_20240523_0227.py | 21 ++++++ osmchadjango/users/serializers.py | 8 +-- osmchadjango/users/tests/test_management.py | 6 +- osmchadjango/users/tests/test_utils.py | 6 +- osmchadjango/users/tests/test_views.py | 23 ++++--- osmchadjango/users/utils.py | 4 +- osmchadjango/users/views.py | 62 ++++++++---------- requirements/base.txt | 4 +- 21 files changed, 206 insertions(+), 221 deletions(-) create mode 100644 osmchadjango/users/migrations/0012_auto_20240523_0227.py diff --git a/config/settings/common.py b/config/settings/common.py index 2ea240f3..ee47327a 100644 --- a/config/settings/common.py +++ b/config/settings/common.py @@ -254,14 +254,16 @@ SOCIAL_AUTH_DEFAULT_USERNAME = lambda u: slugify(u) SOCIAL_AUTH_ASSOCIATE_BY_EMAIL = True -SOCIAL_AUTH_OPENSTREETMAP_KEY = env('OAUTH_OSM_KEY', default='') -SOCIAL_AUTH_OPENSTREETMAP_SECRET = env('OAUTH_OSM_SECRET', default='') +SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY = env("OAUTH2_OSM_KEY", default="") +SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET = env("OAUTH2_OSM_SECRET", default="") +SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SCOPE = ["read_prefs", "write_api"] +SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_USE_PKCE = False # AUTHENTICATION CONFIGURATION # ------------------------------------------------------------------------------ AUTHENTICATION_BACKENDS = ( - 'social_core.backends.openstreetmap.OpenStreetMapOAuth', - 'django.contrib.auth.backends.ModelBackend', + "social_core.backends.openstreetmap_oauth2.OpenStreetMapOAuth2", + "django.contrib.auth.backends.ModelBackend", ) SOCIAL_AUTH_PIPELINE = ( @@ -372,7 +374,7 @@ # in OSM website OAUTH_REDIRECT_URI = env( 'OAUTH_REDIRECT_URI', - default='http://localhost:8000/oauth-landing.html' + default='http://127.0.0.1:3000/oauth-landing.html' ) -OSMCHA_URL = env('OSMCHA_URL', default='https://osmcha.org') \ No newline at end of file +OSMCHA_URL = env('OSMCHA_URL', default='https://osmcha.org') diff --git a/osmchadjango/changeset/tasks.py b/osmchadjango/changeset/tasks.py index 8791ba60..9235da39 100644 --- a/osmchadjango/changeset/tasks.py +++ b/osmchadjango/changeset/tasks.py @@ -13,7 +13,7 @@ from django.db.utils import IntegrityError import requests -from requests_oauthlib import OAuth1Session +from requests_oauthlib import OAuth2Session from osmcha.changeset import Analyse, ChangesetList from .models import Changeset, SuspicionReasons, Import @@ -119,12 +119,11 @@ class ChangesetCommentAPI(object): def __init__(self, user, changeset_id): self.changeset_id = changeset_id - user_token = user.social_auth.all().first().access_token - self.client = OAuth1Session( - settings.SOCIAL_AUTH_OPENSTREETMAP_KEY, - client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_SECRET, - resource_owner_key=user_token["oauth_token"], - resource_owner_secret=user_token["oauth_token_secret"], + user_token = user.social_auth.all().first().extra_data + user_token['token_type'] = 'Bearer' + self.client = OAuth2Session( + settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, + token=user_token, ) self.url = "{}/api/0.6/changeset/{}/comment/".format( settings.OSM_SERVER_URL, changeset_id @@ -132,8 +131,12 @@ def __init__(self, user, changeset_id): def post_comment(self, message=None): """Post comment to changeset.""" - response = self.client.post( - self.url, data="text={}".format(quote(message)).encode("utf-8") + response = self.client.request( + 'POST', + self.url, + data="text={}".format(quote(message)).encode("utf-8"), + client_id=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, + client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET ) if response.status_code == 200: print( diff --git a/osmchadjango/changeset/tests/test_add_feature_views.py b/osmchadjango/changeset/tests/test_add_feature_views.py index cae17e27..839ec36a 100644 --- a/osmchadjango/changeset/tests/test_add_feature_views.py +++ b/osmchadjango/changeset/tests/test_add_feature_views.py @@ -29,7 +29,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123' ) @@ -41,7 +41,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='443324' ) @@ -327,7 +327,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.token = Token.objects.create(user=self.user) @@ -370,7 +370,7 @@ def test_is_not_staff_user_request(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='444444', ) token = Token.objects.create(user=user) diff --git a/osmchadjango/changeset/tests/test_changeset_views.py b/osmchadjango/changeset/tests/test_changeset_views.py index c73bcee4..85b253ee 100644 --- a/osmchadjango/changeset/tests/test_changeset_views.py +++ b/osmchadjango/changeset/tests/test_changeset_views.py @@ -30,7 +30,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.url = reverse('changeset:list') @@ -313,7 +313,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.client.login(username=self.user.username, password='password') @@ -369,7 +369,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.client.login(username=self.user.username, password='password') @@ -509,7 +509,7 @@ def test_authenticated_changeset_detail_response(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.client.login(username=self.user.username, password='password') @@ -535,7 +535,7 @@ def test_changeset_detail_response_with_staff_user(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.client.login(username=self.user.username, password='password') @@ -564,7 +564,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.admin_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.user = User.objects.create_user( @@ -574,7 +574,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='234312', ) self.reason_1 = SuspicionReasons.objects.create(name='possible import') @@ -724,14 +724,11 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', extra_data={ 'id': '123123', - 'access_token': { - 'oauth_token': 'aaaa', - 'oauth_token_secret': 'bbbb' - } + 'access_token': '1shjasgw' } ) self.tag_1 = TagFactory(name='Illegal import') @@ -980,14 +977,11 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', extra_data={ 'id': '123123', - 'access_token': { - 'oauth_token': 'aaaa', - 'oauth_token_secret': 'bbbb' - } + 'access_token': 'ajhsjhags' } ) self.suspect_changeset = SuspectChangesetFactory() @@ -1072,7 +1066,7 @@ def test_staff_user_uncheck_any_changeset(self): ) UserSocialAuth.objects.create( user=staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='87873', ) self.client.login(username=staff_user.username, password='password') @@ -1101,7 +1095,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='999', ) self.changeset_user = User.objects.create_user( @@ -1111,7 +1105,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.changeset_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.changeset = ChangesetFactory() @@ -1183,7 +1177,7 @@ def test_other_user_can_not_add_tag_to_checked_changeset(self): ) UserSocialAuth.objects.create( user=other_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='28763', ) self.client.login(username=other_user.username, password='password') @@ -1203,7 +1197,7 @@ def test_staff_user_add_tag_to_checked_changeset(self): ) UserSocialAuth.objects.create( user=staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='28763', ) self.client.login(username=staff_user.username, password='password') @@ -1224,7 +1218,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='999', ) self.changeset_user = User.objects.create_user( @@ -1234,7 +1228,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.changeset_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.changeset = ChangesetFactory() @@ -1298,7 +1292,7 @@ def test_other_user_can_not_remove_tag_to_checked_changeset(self): ) UserSocialAuth.objects.create( user=other_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='28763', ) self.client.login(username=other_user.username, password='password') @@ -1318,7 +1312,7 @@ def test_staff_user_remove_tag_to_checked_changeset(self): ) UserSocialAuth.objects.create( user=staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='28763', ) self.client.login(username=staff_user.username, password='password') @@ -1341,7 +1335,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) @@ -1390,7 +1384,7 @@ def test_set_good_by_staff_user(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='8987', ) self.client.login(username=user.username, password='password') @@ -1411,7 +1405,7 @@ def test_set_harmful_by_staff_user(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='8987', ) self.client.login(username=user.username, password='password') diff --git a/osmchadjango/changeset/tests/test_comment_views.py b/osmchadjango/changeset/tests/test_comment_views.py index a08f40f0..ade61443 100644 --- a/osmchadjango/changeset/tests/test_comment_views.py +++ b/osmchadjango/changeset/tests/test_comment_views.py @@ -8,7 +8,7 @@ from social_django.models import UserSocialAuth from rest_framework.test import APITestCase -from requests_oauthlib import OAuth1Session +from requests_oauthlib import OAuth2Session from unittest import mock from ...users.models import User @@ -27,14 +27,11 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', extra_data={ 'id': '123123', - 'access_token': { - 'oauth_token': 'aaaa', - 'oauth_token_secret': 'bbbb' - } + 'access_token': 'bbbb' } ) self.changeset = ChangesetFactory(id=31982802) @@ -52,7 +49,7 @@ def test_comment_changeset_unauthenticated(self): self.assertEqual(response.status_code, 401) @override_settings(ENABLE_POST_CHANGESET_COMMENTS=True) - @mock.patch.object(OAuth1Session, 'request') + @mock.patch.object(OAuth2Session, 'request') def test_comment_harmful_changeset(self, mock_oauth_client): # Simulate a response object class MockResponse(): @@ -67,22 +64,23 @@ class MockResponse(): Published using OSMCha: https://osmcha.org/changesets/31982803 """ response = self.client.post( - reverse('changeset:comment', args=[self.harmful_changeset.id]), - data=comment) + reverse("changeset:comment", args=[self.harmful_changeset.id]), + data=comment + ) self.assertEqual(response.status_code, 201) mock_oauth_client.assert_called_with( - 'POST', - '{}/api/0.6/changeset/{}/comment/'.format( - settings.OSM_SERVER_URL, - self.harmful_changeset.id + "POST", + "{}/api/0.6/changeset/{}/comment/".format( + settings.OSM_SERVER_URL, self.harmful_changeset.id ), - data='text={}'.format(quote(message)).encode('utf-8'), - json=None - ) + data="text={}".format(quote(message)).encode("utf-8"), + client_id=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, + client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET, + ) @override_settings(ENABLE_POST_CHANGESET_COMMENTS=True) - @mock.patch.object(OAuth1Session, 'request') + @mock.patch.object(OAuth2Session, 'request') def test_comment_good_changeset(self, mock_oauth_client): # Simulate a response object class MockResponse(): @@ -103,16 +101,17 @@ class MockResponse(): self.assertEqual(response.status_code, 201) mock_oauth_client.assert_called_with( - 'POST', - 'https://www.openstreetmap.org/api/0.6/changeset/{}/comment/'.format( - self.good_changeset.id - ), - data='text={}'.format(quote(message)).encode('utf-8'), - json=None - ) + "POST", + "https://www.openstreetmap.org/api/0.6/changeset/{}/comment/".format( + self.good_changeset.id + ), + data="text={}".format(quote(message)).encode("utf-8"), + client_id=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, + client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET, + ) @override_settings(ENABLE_POST_CHANGESET_COMMENTS=True) - @mock.patch.object(OAuth1Session, 'request') + @mock.patch.object(OAuth2Session, 'request') def test_comment_unreviewed_changeset(self, mock_oauth_client): """Unreviewed changeset should not receive the #OSMCHA_(GOOD or BAD) hashtag. @@ -134,13 +133,14 @@ class MockResponse(): self.assertEqual(response.status_code, 201) mock_oauth_client.assert_called_with( - 'POST', - 'https://www.openstreetmap.org/api/0.6/changeset/{}/comment/'.format( - self.changeset.id - ), - data='text={}'.format(quote(message)).encode('utf-8'), - json=None - ) + "POST", + "https://www.openstreetmap.org/api/0.6/changeset/{}/comment/".format( + self.changeset.id + ), + data="text={}".format(quote(message)).encode("utf-8"), + client_id=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, + client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET, + ) def test_comment_good_changeset_wrong_data(self): self.client.login(username=self.user.username, password='password') diff --git a/osmchadjango/changeset/tests/test_reasons_tags_views.py b/osmchadjango/changeset/tests/test_reasons_tags_views.py index bc496cbb..3d6232b5 100644 --- a/osmchadjango/changeset/tests/test_reasons_tags_views.py +++ b/osmchadjango/changeset/tests/test_reasons_tags_views.py @@ -26,7 +26,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) @@ -69,7 +69,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) @@ -107,7 +107,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.reason_1 = SuspicionReasons.objects.create(name='possible import') @@ -133,7 +133,7 @@ def test_normal_user_request(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='99989', ) self.client.login(username=user.username, password='password') @@ -173,7 +173,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.reason_1 = SuspicionReasons.objects.create(name='possible import') @@ -204,7 +204,7 @@ def test_normal_user_request(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='99989', ) self.client.login(username=user.username, password='password') diff --git a/osmchadjango/changeset/tests/test_review_features_views.py b/osmchadjango/changeset/tests/test_review_features_views.py index 533d5580..cc5d7678 100644 --- a/osmchadjango/changeset/tests/test_review_features_views.py +++ b/osmchadjango/changeset/tests/test_review_features_views.py @@ -1,17 +1,12 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from urllib.parse import quote from django.urls import reverse -from django.test import override_settings from social_django.models import UserSocialAuth from rest_framework.test import APITestCase -from requests_oauthlib import OAuth1Session -from unittest import mock from ...users.models import User -from ..models import Changeset from .modelfactories import ChangesetFactory @@ -24,16 +19,10 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', - uid='345', - extra_data={ - 'id': '345', - 'access_token': { - 'oauth_token': 'aaaa', - 'oauth_token_secret': 'bbbb' - } - } - ) + provider="openstreetmap-oauth2", + uid="345", + extra_data={"id": "345", "access_token": "bbbb"}, + ) self.changeset = ChangesetFactory(id=31982802) def test_review_feature_unauthenticated(self): diff --git a/osmchadjango/changeset/tests/test_stats_views.py b/osmchadjango/changeset/tests/test_stats_views.py index a0665bf1..9363cf04 100644 --- a/osmchadjango/changeset/tests/test_stats_views.py +++ b/osmchadjango/changeset/tests/test_stats_views.py @@ -21,7 +21,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.changeset = ChangesetFactory() @@ -171,7 +171,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) diff --git a/osmchadjango/changeset/tests/test_tag_changes_view.py b/osmchadjango/changeset/tests/test_tag_changes_view.py index df6c2d56..51815385 100644 --- a/osmchadjango/changeset/tests/test_tag_changes_view.py +++ b/osmchadjango/changeset/tests/test_tag_changes_view.py @@ -17,7 +17,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) @@ -48,7 +48,7 @@ def test_normal_user_request(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='99989', ) self.client.login(username=user.username, password='password') diff --git a/osmchadjango/changeset/tests/test_tasks.py b/osmchadjango/changeset/tests/test_tasks.py index 33c653c3..ab13afc5 100644 --- a/osmchadjango/changeset/tests/test_tasks.py +++ b/osmchadjango/changeset/tests/test_tasks.py @@ -3,9 +3,10 @@ from urllib.parse import quote from django.test import TestCase +from django.conf import settings from social_django.models import UserSocialAuth -from requests_oauthlib import OAuth1Session +from requests_oauthlib import OAuth2Session from ...users.models import User from ..models import Changeset, SuspicionReasons @@ -77,34 +78,21 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', - uid='123123', - extra_data={ - 'id': '123123', - 'access_token': { - 'oauth_token': 'aaaa', - 'oauth_token_secret': 'bbbb' - } - } - ) + provider="openstreetmap-oauth2", + uid="123123", + extra_data={"id": "123123", "access_token": "bbbb"}, + ) def test_changeset_comment_init(self): changeset_comment = ChangesetCommentAPI(self.user, 123456) self.assertEqual( changeset_comment.url, - 'https://www.openstreetmap.org/api/0.6/changeset/123456/comment/' - ) - self.assertIsInstance(changeset_comment.client, OAuth1Session) - self.assertEqual( - changeset_comment.client.auth.client.resource_owner_key, - 'aaaa' - ) - self.assertEqual( - changeset_comment.client.auth.client.resource_owner_secret, - 'bbbb' + "https://www.openstreetmap.org/api/0.6/changeset/123456/comment/" ) + self.assertIsInstance(changeset_comment.client, OAuth2Session) + self.assertEqual(changeset_comment.client.access_token, "bbbb") - @patch.object(OAuth1Session, 'request') + @patch.object(OAuth2Session, 'request') def test_post_comment(self, mock_oauth_client): class MockRequest(): status_code = 200 @@ -113,8 +101,11 @@ class MockRequest(): changeset_comment.post_comment('Reviewed in OSMCha and set as GOOD!') mock_oauth_client.assert_called_with( - 'POST', - 'https://www.openstreetmap.org/api/0.6/changeset/123456/comment/', - data='text={}'.format(quote('Reviewed in OSMCha and set as GOOD!')).encode('utf-8'), - json=None - ) + "POST", + "https://www.openstreetmap.org/api/0.6/changeset/123456/comment/", + data="text={}".format(quote("Reviewed in OSMCha and set as GOOD!")).encode( + "utf-8" + ), + client_id=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, + client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET, + ) diff --git a/osmchadjango/changeset/tests/test_whitelist_views.py b/osmchadjango/changeset/tests/test_whitelist_views.py index 0bee0b0b..379149c0 100644 --- a/osmchadjango/changeset/tests/test_whitelist_views.py +++ b/osmchadjango/changeset/tests/test_whitelist_views.py @@ -16,7 +16,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.user_2 = User.objects.create_user( @@ -26,7 +26,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='444444', ) self.url = reverse('changeset:whitelist-user') @@ -84,7 +84,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) UserWhitelist.objects.create(user=self.user, whitelist_user='good_user') @@ -96,7 +96,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='444444', ) UserWhitelist.objects.create(user=self.user_2, whitelist_user='the_user') diff --git a/osmchadjango/roulette_integration/tests/test_views.py b/osmchadjango/roulette_integration/tests/test_views.py index 2dfa5359..a4c0bed3 100644 --- a/osmchadjango/roulette_integration/tests/test_views.py +++ b/osmchadjango/roulette_integration/tests/test_views.py @@ -18,7 +18,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.user_2 = User.objects.create_user( @@ -28,7 +28,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='444444', ) self.reason_1 = SuspicionReasonsFactory(name="Grafitti") @@ -75,7 +75,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.user_2 = User.objects.create_user( @@ -85,7 +85,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='444444', ) self.reason_1 = SuspicionReasonsFactory(name="Grafitti") diff --git a/osmchadjango/supervise/tests/test_views.py b/osmchadjango/supervise/tests/test_views.py index 5fb1e769..36ff4c26 100644 --- a/osmchadjango/supervise/tests/test_views.py +++ b/osmchadjango/supervise/tests/test_views.py @@ -34,7 +34,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.user_2 = User.objects.create_user( @@ -44,7 +44,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='42344', ) self.area = AreaOfInterest.objects.create( @@ -127,7 +127,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.url = reverse('supervise:aoi-list-create') @@ -217,7 +217,7 @@ def test_auto_user_field(self): ) UserSocialAuth.objects.create( user=user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='4444', ) self.client.login(username=self.user.username, password='password') @@ -243,7 +243,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.aoi = AreaOfInterest.objects.create( @@ -556,7 +556,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.aoi = AreaOfInterest.objects.create( @@ -658,7 +658,7 @@ def test_aoi_with_hide_whitelist_filter(self): ) UserSocialAuth.objects.create( user=user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='42344', ) UserWhitelistFactory(user=self.user, whitelist_user='test') @@ -703,7 +703,7 @@ def test_aoi_with_false_hide_whitelist_filter(self): ) UserSocialAuth.objects.create( user=user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='42344', ) UserWhitelistFactory(user=self.user, whitelist_user='test') @@ -753,7 +753,7 @@ def test_aoi_with_blacklist_filter(self): ) UserSocialAuth.objects.create( user=user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='42344', ) BlacklistedUser.objects.create( @@ -809,7 +809,7 @@ def test_aoi_with_false_blacklist_filter(self): ) UserSocialAuth.objects.create( user=user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='42344', ) BlacklistedUser.objects.create( @@ -992,7 +992,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.aoi = AreaOfInterest.objects.create( @@ -1100,7 +1100,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.staff_user = User.objects.create_user( @@ -1111,7 +1111,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='999898', ) BlacklistedUser.objects.create( @@ -1157,7 +1157,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.staff_user = User.objects.create_user( @@ -1168,7 +1168,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='999898', ) self.url = reverse('supervise:blacklist-list-create') @@ -1201,7 +1201,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.staff_user = User.objects.create_user( @@ -1212,7 +1212,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='999898', ) diff --git a/osmchadjango/users/migrations/0012_auto_20240523_0227.py b/osmchadjango/users/migrations/0012_auto_20240523_0227.py new file mode 100644 index 00000000..91be56f2 --- /dev/null +++ b/osmchadjango/users/migrations/0012_auto_20240523_0227.py @@ -0,0 +1,21 @@ +# Generated by Django 2.2.28 on 2024-05-23 02:27 + +from django.db import migrations + + +def update_provider(apps, schema_editor): + # To keep the same users entries we have right now in the database, + # we need to update the UserSocialAuth entries' providers + UserSocialAuth = apps.get_model("social_django", "UserSocialAuth") + UserSocialAuth.objects.all().update(provider="openstreetmap-oauth2") + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0011_auto_20190206_1257'), + ] + + operations = [ + migrations.RunPython(update_provider), + ] diff --git a/osmchadjango/users/serializers.py b/osmchadjango/users/serializers.py index 1c19041b..1e63e4c9 100644 --- a/osmchadjango/users/serializers.py +++ b/osmchadjango/users/serializers.py @@ -21,14 +21,14 @@ class UserSerializer(ModelSerializer): def get_uid(self, obj): try: - return obj.social_auth.filter(provider='openstreetmap').last().uid + return obj.social_auth.filter(provider='openstreetmap-oauth2').last().uid except AttributeError: return None def get_avatar(self, obj): try: return obj.social_auth.filter( - provider='openstreetmap' + provider='openstreetmap-oauth2' ).last().extra_data.get('avatar') except AttributeError: return None @@ -50,9 +50,7 @@ class Meta: class SocialSignUpSerializer(Serializer): - oauth_token = CharField() - oauth_verifier = CharField() - oauth_token_secret = CharField() + code = CharField() class MappingTeamSerializer(ModelSerializer): diff --git a/osmchadjango/users/tests/test_management.py b/osmchadjango/users/tests/test_management.py index acee0858..ac6e4cb0 100644 --- a/osmchadjango/users/tests/test_management.py +++ b/osmchadjango/users/tests/test_management.py @@ -19,7 +19,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='5654409', ) self.user_2 = User.objects.create_user( @@ -29,7 +29,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='612405', ) @@ -50,7 +50,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='5654409', ) Token.objects.create(user=self.user) diff --git a/osmchadjango/users/tests/test_utils.py b/osmchadjango/users/tests/test_utils.py index 9071ae35..85e32b2f 100644 --- a/osmchadjango/users/tests/test_utils.py +++ b/osmchadjango/users/tests/test_utils.py @@ -18,7 +18,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='5654409', ) self.user_2 = User.objects.create_user( @@ -28,7 +28,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='612405', ) @@ -46,7 +46,7 @@ def test_user_with_wrong_uid(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='1989776798', ) update_user_name(user) diff --git a/osmchadjango/users/tests/test_views.py b/osmchadjango/users/tests/test_views.py index d8cb9dca..67c98c78 100644 --- a/osmchadjango/users/tests/test_views.py +++ b/osmchadjango/users/tests/test_views.py @@ -17,7 +17,7 @@ def setUp(self): ) self.social_auth = UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.social_auth.set_extra_data({'avatar': 'http://theurl.org/pic.jpg'}) @@ -100,9 +100,8 @@ def test_get_response(self): def test_receive_oauth_token(self): response = self.client.post(self.url) self.assertEqual(response.status_code, 200) - self.assertIn('oauth_token', response.data.keys()) - self.assertIn('oauth_token_secret', response.data.keys()) - + self.assertIn('auth_url', response.data.keys()) + self.assertIn('state', response.data.keys()) class TestMappingTeamListCreateAPIView(APITestCase): @@ -115,7 +114,7 @@ def setUp(self): ) self.social_auth = UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.payload = { @@ -202,7 +201,7 @@ def setUp(self): ) self.social_auth = UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.payload = { @@ -313,7 +312,7 @@ def setUp(self): ) self.social_auth = UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.payload = { @@ -412,7 +411,7 @@ def test_with_other_user(self): ) UserSocialAuth.objects.create( user=self.staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123456', ) @@ -429,7 +428,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123123', ) self.staff_user = User.objects.create_user( @@ -440,7 +439,7 @@ def setUp(self): ) UserSocialAuth.objects.create( user=self.staff_user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='123456', ) @@ -468,7 +467,7 @@ def test_view(self): ) UserSocialAuth.objects.create( user=user, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='1769', ) user_2 = User.objects.create_user( @@ -478,7 +477,7 @@ def test_view(self): ) UserSocialAuth.objects.create( user=user_2, - provider='openstreetmap', + provider='openstreetmap-oauth2', uid='1234', ) self.client.login(username=self.staff_user.username, password='password') diff --git a/osmchadjango/users/utils.py b/osmchadjango/users/utils.py index d1c0fd04..f5eadded 100644 --- a/osmchadjango/users/utils.py +++ b/osmchadjango/users/utils.py @@ -14,7 +14,7 @@ def save_real_username(backend, user, response, *args, **kwargs): It records the real username of the OSM user in the name field of the User model. """ - if backend.name == 'openstreetmap' and user.name != response.get('username'): + if backend.name == 'openstreetmap-oauth2' and user.name != response.get('username'): user.name = response.get('username') user.save(update_fields=['name']) @@ -24,7 +24,7 @@ def update_user_name(user): user in our local database. """ try: - uid = user.social_auth.get(provider='openstreetmap').uid + uid = user.social_auth.get(provider='openstreetmap-oauth2').uid url = '{}/api/0.6/user/{}/'.format(settings.OSM_SERVER_URL, uid) data = ET.fromstring(requests.get(url).content) display_name = data.find('user').get('display_name') diff --git a/osmchadjango/users/views.py b/osmchadjango/users/views.py index 3f8d0a9d..632c64fd 100644 --- a/osmchadjango/users/views.py +++ b/osmchadjango/users/views.py @@ -20,7 +20,7 @@ from rest_framework.parsers import JSONParser, MultiPartParser, FormParser from rest_framework.response import Response from social_django.utils import load_strategy, load_backend -from requests_oauthlib import OAuth1Session +from requests_oauthlib import OAuth2Session from django_filters import rest_framework as filters from django_filters.widgets import BooleanWidget @@ -74,54 +74,42 @@ class SocialAuthAPIView(GenericAPIView): queryset = User.objects.all() serializer_class = SocialSignUpSerializer - base_url = "{}/oauth".format(settings.OSM_SERVER_URL) - request_token_url = "{}/request_token?oauth_callback={}".format( - base_url, settings.OAUTH_REDIRECT_URI + base_oauth2_url = "{}/oauth2".format(settings.OSM_SERVER_URL) + token_url = "{}/token".format(base_oauth2_url) + auth_url = "{}/authorize".format(base_oauth2_url) + consumer = OAuth2Session( + client_id=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY, + scope=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SCOPE, + redirect_uri=settings.OAUTH_REDIRECT_URI, ) - access_token_url = "{}/access_token".format(base_url) - - def get_access_token(self, oauth_token, oauth_token_secret, oauth_verifier): - oauth = OAuth1Session( - settings.SOCIAL_AUTH_OPENSTREETMAP_KEY, - client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_SECRET, - resource_owner_key=oauth_token, - resource_owner_secret=oauth_token_secret, - verifier=oauth_verifier - ) - return oauth.fetch_access_token(self.access_token_url) - def get_user_token(self, request, access_token): + def get_access_token(self, code): + return self.consumer.fetch_token( + token_url=self.token_url, + code=code, + client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET, + ) + + def get_user_token(self, request, access_token, *args, **kwargs): backend = load_backend( strategy=load_strategy(request), - name='openstreetmap', - redirect_uri=None - ) - authed_user = request.user if not request.user.is_anonymous else None - user = backend.do_auth(access_token, user=authed_user) + name="openstreetmap-oauth2", + redirect_uri=settings.OAUTH_REDIRECT_URI, + ) + user = backend.do_auth(access_token, *args, **kwargs) token, created = Token.objects.get_or_create(user=user) return {'token': token.key} def post(self, request, *args, **kwargs): - if 'oauth_token' not in request.data.keys() or not request.data['oauth_token']: - consumer = OAuth1Session( - settings.SOCIAL_AUTH_OPENSTREETMAP_KEY, - client_secret=settings.SOCIAL_AUTH_OPENSTREETMAP_SECRET - ) - request_token = consumer.fetch_request_token( - self.request_token_url - ) - return Response({ - 'oauth_token': request_token['oauth_token'], - 'oauth_token_secret': request_token['oauth_token_secret'] - }) + if 'code' not in request.data.keys() or not request.data['code']: + login_url, state = self.consumer.authorization_url(self.auth_url) + return Response({"auth_url": login_url, "state": state}) else: serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) access_token = self.get_access_token( - request.data['oauth_token'], - request.data['oauth_token_secret'], - request.data['oauth_verifier'] - ) + request.data['code'], + ).get('access_token') return Response(self.get_user_token(request, access_token)) diff --git a/requirements/base.txt b/requirements/base.txt index b278dd96..b609396b 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,8 +12,8 @@ django-braces==1.14.0 django-model-utils==4.2.0 # For authentication with OSM -social-auth-app-django==4.0.0 -social-auth-core==3.3.3 +social-auth-app-django==5.1.0 +social-auth-core==4.5.3 # DRF and DRF-gis djangorestframework==3.11.2