diff --git a/corehq/apps/cleanup/migrations/0016_delete_oauth_integrations_models.py b/corehq/apps/cleanup/migrations/0016_delete_oauth_integrations_models.py new file mode 100644 index 000000000000..566a90931e03 --- /dev/null +++ b/corehq/apps/cleanup/migrations/0016_delete_oauth_integrations_models.py @@ -0,0 +1,55 @@ +# Generated by Django 3.2.24 on 2024-02-09 14:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cleanup', '0015_deletedcouchdoc_unique_id_and_type'), + ] + + operations = [ + migrations.RunSQL(""" + DROP TABLE IF EXISTS "oauth_integrations_googleapitoken" CASCADE; + DROP TABLE IF EXISTS "oauth_integrations_livegooglesheetrefreshstatus" CASCADE; + DROP TABLE IF EXISTS "oauth_integrations_livegooglesheetschedule" CASCADE; + """), + ] + + +""" +Dropped entities can be checked with the following query: + + select pg_describe_object(classid, objid, objsubid) + from pg_depend + where refobjid in ( + 'oauth_integrations_googleapitoken'::regclass, + 'oauth_integrations_livegooglesheetrefreshstatus'::regclass, + 'oauth_integrations_livegooglesheetschedule'::regclass + ); + +Example output (from staging, the same as a local dev setup): + + type oauth_integrations_livegooglesheetschedule + type oauth_integrations_livegooglesheetrefreshstatus + type oauth_integrations_googleapitoken + toast table pg_toast.pg_toast_2980995 + toast table pg_toast.pg_toast_2980982 + toast table pg_toast.pg_toast_2892669 + sequence oauth_integrations_livegooglesheetschedule_id_seq + sequence oauth_integrations_livegooglesheetrefreshstatus_id_seq + sequence oauth_integrations_googleapitoken_id_seq + index oauth_integrations_livegoo_schedule_id_064aa4f4 + index oauth_integrations_livegoo_export_config_id_200127ab + index oauth_integrations_liveg_export_config_id_200127ab_like + index oauth_integrations_googleapitoken_user_id_9d01255f + default value for column id of table oauth_integrations_livegooglesheetschedule + default value for column id of table oauth_integrations_livegooglesheetrefreshstatus + default value for column id of table oauth_integrations_googleapitoken + constraint oauth_integrations_livegooglesheetschedule_pkey on table oauth_integrations_livegooglesheetschedule + constraint oauth_integrations_livegooglesheetrefreshstatus_pkey on table oauth_integrations_livegooglesheetrefreshstatus + constraint oauth_integrations_l_schedule_id_064aa4f4_fk_oauth_int on table oauth_integrations_livegooglesheetrefreshstatus + constraint oauth_integrations_googleapitoken_pkey on table oauth_integrations_googleapitoken + constraint oauth_integrations_g_user_id_9d01255f_fk_auth_user on table oauth_integrations_googleapitoken +""" diff --git a/corehq/apps/domain/tests/test_deletion_models.py b/corehq/apps/domain/tests/test_deletion_models.py index 2ae0aac447af..1a5f536605ec 100644 --- a/corehq/apps/domain/tests/test_deletion_models.py +++ b/corehq/apps/domain/tests/test_deletion_models.py @@ -38,7 +38,6 @@ 'telerivet', 'toggle_ui', 'sso', - 'oauth_integrations', } IGNORE_MODELS = { diff --git a/corehq/apps/dump_reload/tests/test_dump_models.py b/corehq/apps/dump_reload/tests/test_dump_models.py index 4adaf1b383ba..9326cfb49c34 100644 --- a/corehq/apps/dump_reload/tests/test_dump_models.py +++ b/corehq/apps/dump_reload/tests/test_dump_models.py @@ -132,9 +132,6 @@ "oauth2_provider.Grant", "oauth2_provider.IDToken", "oauth2_provider.RefreshToken", - "oauth_integrations.GoogleApiToken", - "oauth_integrations.LiveGoogleSheetRefreshStatus", - "oauth_integrations.LiveGoogleSheetSchedule", "registration.AsyncSignupRequest", "registration.RegistrationRequest", "reminders.EmailUsage", diff --git a/corehq/apps/oauth_integrations/__init__.py b/corehq/apps/oauth_integrations/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/corehq/apps/oauth_integrations/migrations/0001_initial.py b/corehq/apps/oauth_integrations/migrations/0001_initial.py deleted file mode 100644 index 2b638c4095a4..000000000000 --- a/corehq/apps/oauth_integrations/migrations/0001_initial.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by Django 2.2.24 on 2022-01-10 13:57 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='GoogleApiToken', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('token', models.CharField(max_length=700)), - ('date_created', models.DateField(auto_now_add=True)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='google_api_tokens', to=settings.AUTH_USER_MODEL)), - ], - ), - ] diff --git a/corehq/apps/oauth_integrations/migrations/0002_livegooglesheetschedule.py b/corehq/apps/oauth_integrations/migrations/0002_livegooglesheetschedule.py deleted file mode 100644 index 078f1b071a12..000000000000 --- a/corehq/apps/oauth_integrations/migrations/0002_livegooglesheetschedule.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.2.27 on 2022-02-28 10:54 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('oauth_integrations', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='LiveGoogleSheetSchedule', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('export_config_id', models.CharField(db_index=True, max_length=250)), - ('is_active', models.BooleanField(default=True)), - ('start_time', models.IntegerField(default=200)), - ('google_sheet_id', models.CharField(max_length=250)), - ], - ), - ] diff --git a/corehq/apps/oauth_integrations/migrations/0003_livegooglesheetrefreshstatus.py b/corehq/apps/oauth_integrations/migrations/0003_livegooglesheetrefreshstatus.py deleted file mode 100644 index df4e94bb6d33..000000000000 --- a/corehq/apps/oauth_integrations/migrations/0003_livegooglesheetrefreshstatus.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 2.2.27 on 2022-02-28 11:57 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('oauth_integrations', '0002_livegooglesheetschedule'), - ] - - operations = [ - migrations.CreateModel( - name='LiveGoogleSheetRefreshStatus', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('date_start', models.DateTimeField(auto_now_add=True)), - ('date_end', models.DateTimeField(blank=True, null=True)), - ('refresh_error_reason', models.CharField(choices=[(None, 'No Error'), ('token', 'Invalid Token'), ('timeout', 'Data Timeout'), ('other', 'Other...')], default=None, max_length=7, null=True)), - ('refresh_error_note', models.TextField(blank=True, null=True)), - ('schedule', models.ForeignKey(on_delete=models.CASCADE, to='oauth_integrations.LiveGoogleSheetSchedule')), - ], - ), - ] diff --git a/corehq/apps/oauth_integrations/migrations/0004_auto_20220304_1139.py b/corehq/apps/oauth_integrations/migrations/0004_auto_20220304_1139.py deleted file mode 100644 index 19d83b2b61bc..000000000000 --- a/corehq/apps/oauth_integrations/migrations/0004_auto_20220304_1139.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 2.2.27 on 2022-03-04 11:39 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('oauth_integrations', '0003_livegooglesheetrefreshstatus'), - ] - - operations = [ - migrations.AlterField( - model_name='livegooglesheetrefreshstatus', - name='refresh_error_reason', - field=models.CharField(choices=[(None, 'No Error'), ('token', 'Invalid Token'), ('timeout', 'Data Timeout'), ('other', 'Other...')], default=None, max_length=16, null=True), - ), - migrations.AlterField( - model_name='livegooglesheetrefreshstatus', - name='schedule', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='oauth_integrations.LiveGoogleSheetSchedule'), - ), - ] diff --git a/corehq/apps/oauth_integrations/migrations/__init__.py b/corehq/apps/oauth_integrations/migrations/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/corehq/apps/oauth_integrations/models.py b/corehq/apps/oauth_integrations/models.py deleted file mode 100644 index 2262ab9c86cb..000000000000 --- a/corehq/apps/oauth_integrations/models.py +++ /dev/null @@ -1,43 +0,0 @@ -from django.db import models - -from django.contrib.auth.models import User - - -class GoogleApiToken(models.Model): - user = models.ForeignKey(User, related_name='google_api_tokens', on_delete=models.CASCADE) - token = models.CharField(max_length=700) - date_created = models.DateField(auto_now_add=True) - - -class LiveGoogleSheetSchedule(models.Model): - export_config_id = models.CharField(max_length=250, db_index=True) - is_active = models.BooleanField(default=True) - start_time = models.IntegerField(default=200) - google_sheet_id = models.CharField(max_length=250) - - -class LiveGoogleSheetErrorReason(): - NO_ERROR = None - INVALID_TOKEN = 'token' - TIMEOUT = 'timeout' - OTHER = 'other' - - CHOICES = ( - (NO_ERROR, "No Error"), - (INVALID_TOKEN, "Invalid Token"), - (TIMEOUT, "Data Timeout"), - (OTHER, "Other..."), - ) - - -class LiveGoogleSheetRefreshStatus(models.Model): - schedule = models.ForeignKey(LiveGoogleSheetSchedule, on_delete=models.CASCADE) - date_start = models.DateTimeField(auto_now_add=True) - date_end = models.DateTimeField(null=True, blank=True) - refresh_error_reason = models.CharField( - max_length=16, - choices=LiveGoogleSheetErrorReason.CHOICES, - null=True, - default=LiveGoogleSheetErrorReason.NO_ERROR, - ) - refresh_error_note = models.TextField(null=True, blank=True) diff --git a/corehq/apps/oauth_integrations/tests/__init__.py b/corehq/apps/oauth_integrations/tests/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/corehq/apps/oauth_integrations/tests/test_util.py b/corehq/apps/oauth_integrations/tests/test_util.py deleted file mode 100644 index f3126aa3af75..000000000000 --- a/corehq/apps/oauth_integrations/tests/test_util.py +++ /dev/null @@ -1,89 +0,0 @@ -from datetime import datetime - -from django.test import SimpleTestCase, TestCase -from django.contrib.auth.models import User - -from google.oauth2.credentials import Credentials - -from corehq.apps.oauth_integrations.models import GoogleApiToken -from corehq.apps.oauth_integrations.utils import get_token, load_credentials, stringify_credentials - - -class TestUtils(TestCase): - - def setUp(self): - super().setUp() - self.user = User() - self.user.username = 'test@user.com' - self.user.save() - self.credentials = Credentials( - token="token", - refresh_token="refresh_token", - id_token="id_token", - token_uri="token_uri", - client_id="client_id", - client_secret="client_secret", - scopes="scopes", - expiry=datetime(2020, 1, 1) - ) - - def tearDown(self): - self.credentials = None - self.user.delete() - return super().tearDown() - - def test_get_token_with_created_token(self): - GoogleApiToken.objects.create( - user=self.user, - token=stringify_credentials(self.credentials) - ) - - token = get_token(self.user) - - self.assertIsNotNone(token) - self.tearDowntoken() - - def test_get_token_without_token(self): - token = get_token(self.user) - - self.assertIsNone(token) - - def tearDowntoken(self): - objects = GoogleApiToken.objects.get(user=self.user) - objects.delete() - - -class TestCredentialsUtils(SimpleTestCase): - def setUp(self): - super().setUp() - self.credentials = Credentials( - token="token", - refresh_token="refresh_token", - id_token="id_token", - token_uri="token_uri", - client_id="client_id", - client_secret="client_secret", - scopes="scopes", - expiry=datetime(2020, 1, 1) - ) - - def tearDown(self): - self.credentials = None - return super().tearDown() - - def test_stringify_credentials(self): - desired_credentials = ('{"token": "token", "refresh_token": "refresh_token", "id_token": "id_token", ' - '"token_uri": "token_uri", "client_id": "client_id", "client_secret": "client_secret", ' - '"scopes": "scopes", "expiry": "2020-01-01 00:00:00"}') - - stringified_credentials = stringify_credentials(self.credentials) - - self.assertEqual(desired_credentials, stringified_credentials) - - def test_load_credentials(self): - desired_credentials = self.credentials - - stringified_credentials = stringify_credentials(self.credentials) - loaded_credentials = load_credentials(stringified_credentials) - - self.assertEqual(loaded_credentials.token, desired_credentials.token) diff --git a/corehq/apps/oauth_integrations/tests/test_views.py b/corehq/apps/oauth_integrations/tests/test_views.py deleted file mode 100644 index 25f5121c25b7..000000000000 --- a/corehq/apps/oauth_integrations/tests/test_views.py +++ /dev/null @@ -1,146 +0,0 @@ -from datetime import datetime - -from unittest.mock import patch - -from django.test import TestCase, RequestFactory, override_settings -from django.contrib.auth.models import User - -from google.oauth2.credentials import Credentials -from corehq.apps.oauth_integrations.utils import get_token, load_credentials, stringify_credentials - -from corehq.apps.oauth_integrations.views.google import redirect_oauth_view, call_back_view -from corehq.apps.domain.shortcuts import create_domain -from corehq.apps.oauth_integrations.models import GoogleApiToken - - -class TestViews(TestCase): - - def test_redirect_oauth_view_without_credentials(self): - self.mocked_get_url.return_value = "googleredirecturl.com" - request = self.factory.get('') - request.user = self.user - - response = redirect_oauth_view(request, self.domain) - - self.assertEqual(response.url, 'googleredirecturl.com') - - def test_redirect_oauth_view_with_credentials(self): - self.setUp_credentials() - self.mocked_refresh_credentials.return_value = self.create_new_credentials(token="new_token") - self.mocked_get_url.return_value = "googleredirecturl.com" - request = self.factory.get('') - request.user = self.user - - response = redirect_oauth_view(request, self.domain) - stringified_creds = get_token(self.user) - creds = load_credentials(stringified_creds.token) - - self.assertEqual(response.url, "placeholder.com") - self.assertEqual(creds.token, 'new_token') - - @override_settings(GOOGLE_OATH_CONFIG={ - "web": { - "client_id": "test_id", - "project_id": "test_project_id", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_secret": "test_client_secret"} - }) - def test_call_back_view_with_token_updates_credentials(self): - self.setUp_credentials() - self.mocked_get_token.return_value = stringify_credentials(self.create_new_credentials("new_token")) - request = self.factory.get('', {'state': 101}) - request.user = self.user - - call_back_view(request, self.domain) - - stringified_creds = get_token(self.user) - creds = load_credentials(stringified_creds.token) - - self.assertEqual(creds.token, "new_token") - - @override_settings(GOOGLE_OATH_CONFIG={ - "web": { - "client_id": "test_id", - "project_id": "test_project_id", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_secret": "test_client_secret"} - }) - def test_call_back_view_without_token_creates_credentials(self): - self.mocked_get_token.return_value = stringify_credentials(self.create_new_credentials("new_token")) - request = self.factory.get('', {'state': 101}) - request.user = self.user - - call_back_view(request, self.domain) - - creds = get_token(self.user) - - self.assertIsNotNone(creds) - - def setUp(self): - self.setUp_mocks() - self.factory = RequestFactory() - self.user = User() - self.user.username = 'test@user.com' - self.user.save() - - self.domain = create_domain("test_domain") - - self.credentials = Credentials( - token="token", - refresh_token="refresh_token", - id_token="id_token", - token_uri="token_uri", - client_id="client_id", - client_secret="client_secret", - scopes="scopes", - expiry=datetime(2020, 1, 1) - ) - self.stringified_token = stringify_credentials(self.credentials) - - return super().setUp() - - def tearDown(self): - token = get_token(self.user) - if token: - token.delete() - self.user.delete() - self.domain.delete() - - return super().tearDown() - - def setUp_mocks(self): - get_url_from_google_patcher = patch('corehq.apps.oauth_integrations.views.google.get_url_from_google') - refresh_credentials_patcher = patch('corehq.apps.oauth_integrations.views.google.refresh_credentials') - get_token_patcher = patch('corehq.apps.oauth_integrations.views.google.get_token_from_google') - - self.mocked_get_url = get_url_from_google_patcher.start() - self.mocked_refresh_credentials = refresh_credentials_patcher.start() - self.mocked_get_token = get_token_patcher.start() - - self.addCleanup(get_url_from_google_patcher.stop) - self.addCleanup(refresh_credentials_patcher.stop) - self.addCleanup(get_token_patcher.stop) - - def setUp_credentials(self): - return GoogleApiToken.objects.create( - user=self.user, - token=self.stringified_token - ) - - def create_new_credentials(self, token="new_token"): - credentials = Credentials( - token=token, - refresh_token="refresh_token", - id_token="id_token", - token_uri="token_uri", - client_id="client_id", - client_secret="client_secret", - scopes="scopes", - expiry=datetime(2020, 1, 1) - ) - - return credentials diff --git a/corehq/apps/oauth_integrations/urls.py b/corehq/apps/oauth_integrations/urls.py deleted file mode 100644 index ebb7622c7cbc..000000000000 --- a/corehq/apps/oauth_integrations/urls.py +++ /dev/null @@ -1,16 +0,0 @@ -from django.conf.urls import re_path as url - -from corehq.apps.oauth_integrations.views.google import ( - redirect_oauth_view, - call_back_view -) - -urlpatterns = [ - # OAuth redirect views - url(r"^google_sheets_oauth/redirect/$", - redirect_oauth_view, - name="google_sheet_oauth_redirect"), - url(r"^google_sheets_oauth/callback/$", - call_back_view, - name="google_sheet_oauth_callback") -] diff --git a/corehq/apps/oauth_integrations/utils.py b/corehq/apps/oauth_integrations/utils.py deleted file mode 100644 index a0d9c7de4c9f..000000000000 --- a/corehq/apps/oauth_integrations/utils.py +++ /dev/null @@ -1,92 +0,0 @@ -import json - -from django.conf import settings - -from datetime import datetime - -from google.oauth2.credentials import Credentials - -from corehq.util.couch import get_document_or_404 - -from corehq.apps.export.esaccessors import get_case_export_base_query -from corehq.apps.oauth_integrations.models import GoogleApiToken - -from googleapiclient.discovery import build - - -def stringify_credentials(credentials): - credentials_dict = { - 'token': credentials.token, - 'refresh_token': credentials.refresh_token, - 'id_token': credentials.id_token, - 'token_uri': credentials.token_uri, - 'client_id': credentials.client_id, - 'client_secret': credentials.client_secret, - 'scopes': credentials.scopes, - 'expiry': datetime.strftime(credentials.expiry, '%Y-%m-%d %H:%M:%S') - } - return json.dumps(credentials_dict) - - -def load_credentials(stringified_credentials): - credentials_dict = json.loads(stringified_credentials) - credentials = Credentials( - credentials_dict['token'], - refresh_token=credentials_dict['refresh_token'], - id_token=credentials_dict['id_token'], - token_uri=credentials_dict['token_uri'], - client_id=credentials_dict['client_id'], - client_secret=credentials_dict['client_secret'], - scopes=credentials_dict['scopes'], - ) - return credentials - - -def get_token(user): - try: - return GoogleApiToken.objects.get(user=user) - except GoogleApiToken.DoesNotExist: - return None - - -def get_query_results(export_instance, domain, id): - export = get_document_or_404(export_instance, domain, id) - query = get_case_export_base_query(domain, export.case_type) - results = query.run() - return results - - -def create_spreadsheet(spreadsheet_data, user): - token = GoogleApiToken.objects.get(user=user) - credentials = load_credentials(token.token) - - service = build(settings.GOOGLE_SHEETS_API_NAME, settings.GOOGLE_SHEETS_API_VERSION, credentials=credentials) - sheets_file = service.spreadsheets().create().execute() - spreadsheet_id = sheets_file['spreadsheetId'] - - for chunk in spreadsheet_data: - value_range_body = { - 'majorDimension': 'ROWS', - 'values': chunk - } - service.spreadsheets().values().append( - spreadsheetId=spreadsheet_id, - valueInputOption='USER_ENTERED', - body=value_range_body, - range='A1' - ).execute() - - return sheets_file - - -def listify_data(query_results): - data = [] - for row_number, document in enumerate(query_results): - row_values = document.get("case_json") - - if(row_number == 0): - headers = list(row_values.keys()) - data.append(headers) - data.append(list(row_values.values())) - - return data diff --git a/corehq/apps/oauth_integrations/views/__init__.py b/corehq/apps/oauth_integrations/views/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/corehq/apps/oauth_integrations/views/google.py b/corehq/apps/oauth_integrations/views/google.py deleted file mode 100644 index e4f53434f701..000000000000 --- a/corehq/apps/oauth_integrations/views/google.py +++ /dev/null @@ -1,100 +0,0 @@ -from django.conf import settings -from django.contrib import messages -from django.http import HttpResponseRedirect -from django.urls import reverse -from django.utils.translation import gettext as _ - -from corehq.apps.oauth_integrations.models import GoogleApiToken -from corehq.apps.oauth_integrations.utils import ( - stringify_credentials, - load_credentials, - get_token, -) -from corehq.apps.export.exceptions import InvalidLoginException - -from google.auth.transport.requests import Request -from google_auth_oauthlib.flow import Flow -from google.auth.exceptions import RefreshError - - -def redirect_oauth_view(request, domain): - redirect_uri = request.build_absolute_uri(reverse("google_sheet_oauth_callback")) - token = get_token(request.user) - - if token is None: - return HttpResponseRedirect(get_url_from_google(redirect_uri)) - else: - credentials = load_credentials(token.token) - try: - token.token = stringify_credentials(refresh_credentials(credentials)) - token.save() - # When we lose access to a user's refresh token, we get this refresh error. - # This will simply have them log into google sheets again to give us another refresh token - except RefreshError: - return HttpResponseRedirect(get_url_from_google(redirect_uri)) - #replace with google sheet view - return HttpResponseRedirect("placeholder.com") - - -def refresh_credentials(credentials, user): - return credentials.refresh(Request()) - - -def get_url_from_google(redirect_uri): - INDEX_URL = 0 - flow = Flow.from_client_config( - settings.GOOGLE_OATH_CONFIG, - settings.GOOGLE_OAUTH_SCOPES, - redirect_uri=redirect_uri - ) - # Returns a tuple containing (url, state) and we only want the url - auth_tuple = flow.authorization_url(prompt='consent') - return auth_tuple[INDEX_URL] - - -def call_back_view(request, domain): - redirect_uri = request.build_absolute_uri(reverse("google_sheet_oauth_callback")) - - try: - check_state(request) - - flow = Flow.from_client_config( - settings.GOOGLE_OATH_CONFIG, - settings.GOOGLE_OAUTH_SCOPES, - redirect_uri=redirect_uri - ) - flow.redirect_uri = redirect_uri - - # Fetch the token and stringify it - stringified_token = get_token_from_google(request, flow) - - token = get_token(request.user) - - if not token: - GoogleApiToken.objects.create( - user=request.user, - token=stringified_token - ) - else: - token.token = stringified_token - token.save() - - except InvalidLoginException: - messages.error(request, _("Something went wrong when trying to sign you in to Google. Please try again.")) - - #replace with google sheet view - return HttpResponseRedirect("placeholder.com") - - -def check_state(request): - state = request.GET.get('state', None) - - if not state: - raise InvalidLoginException - - -def get_token_from_google(request, flow): - authorization_response = request.build_absolute_uri() - flow.fetch_token(authorization_response) - credentials = flow.credentials - return stringify_credentials(credentials) diff --git a/migrations.lock b/migrations.lock index 81baa165aa31..276160a29746 100644 --- a/migrations.lock +++ b/migrations.lock @@ -238,6 +238,7 @@ cleanup 0013_migrate_kafka_checkpoint_format 0014_deletedcouchdoc 0015_deletedcouchdoc_unique_id_and_type + 0016_delete_oauth_integrations_models cloudcare 0001_initial 0002_sqlapplicationaccess @@ -694,11 +695,6 @@ oauth2_provider 0005_auto_20211222_2352 0006_alter_application_client_secret 0007_application_post_logout_redirect_uris -oauth_integrations - 0001_initial - 0002_livegooglesheetschedule - 0003_livegooglesheetrefreshstatus - 0004_auto_20220304_1139 ota 0001_initial 0002_alter_db_index diff --git a/requirements/base-requirements.in b/requirements/base-requirements.in index 7b0b180b0714..7bec9505147d 100644 --- a/requirements/base-requirements.in +++ b/requirements/base-requirements.in @@ -49,9 +49,6 @@ ethiopian-date-converter eulxml firebase-admin # India Division - used for FCM Push Notifications gevent -google-api-python-client==2.32.0 -google-auth-httplib2==0.1.0 -google-auth-oauthlib==0.4.6 greenlet gunicorn haversine # SolTech - Used in Geospatial features diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index c004f9d728bb..5a100c846772 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -277,28 +277,22 @@ gnureadline==8.1.2 google-api-core[grpc]==2.11.0 # via # firebase-admin + # google-api-core # google-api-python-client # google-cloud-core # google-cloud-firestore # google-cloud-storage google-api-python-client==2.32.0 - # via - # -r base-requirements.in - # firebase-admin + # via firebase-admin google-auth==2.18.1 # via # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage google-auth-httplib2==0.1.0 - # via - # -r base-requirements.in - # google-api-python-client -google-auth-oauthlib==0.4.6 - # via -r base-requirements.in + # via google-api-python-client google-cloud-core==2.3.2 # via # google-cloud-firestore @@ -633,9 +627,7 @@ requests==2.28.2 requests-mock==1.9.3 # via -r test-requirements.in requests-oauthlib==1.3.1 - # via - # -r base-requirements.in - # google-auth-oauthlib + # via -r base-requirements.in requests-toolbelt==1.0.0 # via -r base-requirements.in rjsmin==1.2.0 diff --git a/requirements/docs-requirements.txt b/requirements/docs-requirements.txt index 45678c0cc364..5e7a45172f86 100644 --- a/requirements/docs-requirements.txt +++ b/requirements/docs-requirements.txt @@ -234,28 +234,22 @@ gevent==23.9.1 google-api-core[grpc]==2.11.0 # via # firebase-admin + # google-api-core # google-api-python-client # google-cloud-core # google-cloud-firestore # google-cloud-storage google-api-python-client==2.32.0 - # via - # -r base-requirements.in - # firebase-admin + # via firebase-admin google-auth==2.18.1 # via # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage google-auth-httplib2==0.1.0 - # via - # -r base-requirements.in - # google-api-python-client -google-auth-oauthlib==0.4.6 - # via -r base-requirements.in + # via google-api-python-client google-cloud-core==2.3.2 # via # google-cloud-firestore @@ -523,9 +517,7 @@ requests==2.28.2 # stripe # twilio requests-oauthlib==1.3.1 - # via - # -r base-requirements.in - # google-auth-oauthlib + # via -r base-requirements.in requests-toolbelt==1.0.0 # via -r base-requirements.in rjsmin==1.2.0 diff --git a/requirements/prod-requirements.txt b/requirements/prod-requirements.txt index 60226f98bb1a..f544402a73ee 100644 --- a/requirements/prod-requirements.txt +++ b/requirements/prod-requirements.txt @@ -234,28 +234,22 @@ gevent==23.9.1 google-api-core[grpc]==2.11.0 # via # firebase-admin + # google-api-core # google-api-python-client # google-cloud-core # google-cloud-firestore # google-cloud-storage google-api-python-client==2.32.0 - # via - # -r base-requirements.in - # firebase-admin + # via firebase-admin google-auth==2.18.1 # via # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage google-auth-httplib2==0.1.0 - # via - # -r base-requirements.in - # google-api-python-client -google-auth-oauthlib==0.4.6 - # via -r base-requirements.in + # via google-api-python-client google-cloud-core==2.3.2 # via # google-cloud-firestore @@ -538,9 +532,7 @@ requests==2.28.2 # stripe # twilio requests-oauthlib==1.3.1 - # via - # -r base-requirements.in - # google-auth-oauthlib + # via -r base-requirements.in requests-toolbelt==1.0.0 # via -r base-requirements.in rjsmin==1.2.0 diff --git a/requirements/requirements.txt b/requirements/requirements.txt index f30b2543bc5f..e7018bb6d74a 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -222,28 +222,22 @@ gevent==23.9.1 google-api-core[grpc]==2.11.0 # via # firebase-admin + # google-api-core # google-api-python-client # google-cloud-core # google-cloud-firestore # google-cloud-storage google-api-python-client==2.32.0 - # via - # -r base-requirements.in - # firebase-admin + # via firebase-admin google-auth==2.18.1 # via # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage google-auth-httplib2==0.1.0 - # via - # -r base-requirements.in - # google-api-python-client -google-auth-oauthlib==0.4.6 - # via -r base-requirements.in + # via google-api-python-client google-cloud-core==2.3.2 # via # google-cloud-firestore @@ -492,9 +486,7 @@ requests==2.28.2 # stripe # twilio requests-oauthlib==1.3.1 - # via - # -r base-requirements.in - # google-auth-oauthlib + # via -r base-requirements.in requests-toolbelt==1.0.0 # via -r base-requirements.in rjsmin==1.2.0 diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index 706ee9ed9dba..90217ad65db3 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -239,28 +239,22 @@ gevent==23.9.1 google-api-core[grpc]==2.11.0 # via # firebase-admin + # google-api-core # google-api-python-client # google-cloud-core # google-cloud-firestore # google-cloud-storage google-api-python-client==2.32.0 - # via - # -r base-requirements.in - # firebase-admin + # via firebase-admin google-auth==2.18.1 # via # google-api-core # google-api-python-client # google-auth-httplib2 - # google-auth-oauthlib # google-cloud-core # google-cloud-storage google-auth-httplib2==0.1.0 - # via - # -r base-requirements.in - # google-api-python-client -google-auth-oauthlib==0.4.6 - # via -r base-requirements.in + # via google-api-python-client google-cloud-core==2.3.2 # via # google-cloud-firestore @@ -532,9 +526,7 @@ requests==2.28.2 requests-mock==1.9.3 # via -r test-requirements.in requests-oauthlib==1.3.1 - # via - # -r base-requirements.in - # google-auth-oauthlib + # via -r base-requirements.in requests-toolbelt==1.0.0 # via -r base-requirements.in rjsmin==1.2.0 diff --git a/settings.py b/settings.py index f5ed5f97d9d5..61361f3b995e 100755 --- a/settings.py +++ b/settings.py @@ -318,7 +318,6 @@ 'corehq.apps.smsforms', 'corehq.apps.sso', 'corehq.apps.ivr', - 'corehq.apps.oauth_integrations', 'corehq.messaging.MessagingAppConfig', 'corehq.messaging.scheduling', 'corehq.messaging.scheduling.scheduling_partitioned', diff --git a/urls.py b/urls.py index 3234d5dfb512..ca4e5fc6c389 100644 --- a/urls.py +++ b/urls.py @@ -160,7 +160,6 @@ r'(?P[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})/(?P[\w-]+)/', ReportNotificationUnsubscribeView.as_view(), name=ReportNotificationUnsubscribeView.urlname), url(r'^phone/list_apps', list_apps, name="list_accessible_apps"), - url(r'^oauth/', include('corehq.apps.oauth_integrations.urls')), ] + LOCAL_APP_URLS if settings.ENABLE_PRELOGIN_SITE: