diff --git a/google/colab/auth.py b/google/colab/auth.py index 4e307ded..b8b17d27 100644 --- a/google/colab/auth.py +++ b/google/colab/auth.py @@ -29,7 +29,11 @@ from google.colab import files as _files from google.colab import output as _output -__all__ = ['authenticate_service_account', 'authenticate_user'] +__all__ = [ + 'authenticate_service_account', + 'authenticate_user', + 'authenticate_desktop_application', +] _LOGGER = _logging.getLogger(__name__) @@ -353,3 +357,24 @@ def authenticate_service_account(clear_output=True): print('Successfully saved credentials for', creds.service_account_email) return raise _errors.AuthorizationError('Failed to fetch user credentials') + + +def authenticate_desktop_application(client_secrets_path, scopes): + """Authenticates the user for a desktop application. + + This method uses the OAuth 2.0 flow for installed applications to obtain user + credentials. It will use the console strategy to handle the authorization + flow. + + Args: + client_secrets_path: The path to the client secrets JSON file. + scopes: A list of scopes to request during the authorization flow. + + Returns: + The user's credentials. + """ + from google_auth_oauthlib.flow import InstalledAppFlow # pylint: disable=g-import-not-at-top + + flow = InstalledAppFlow.from_client_secrets_file(client_secrets_path, scopes) + creds = flow.run_console() + return creds diff --git a/setup.py b/setup.py index f2236a73..b81a10c8 100644 --- a/setup.py +++ b/setup.py @@ -28,6 +28,8 @@ 'portpicker==1.5.2', 'requests==2.32.4', 'tornado==6.4.2', + 'google-auth-oauthlib==1.2.2', + 'google-api-python-client==2.179.0', ) setup( diff --git a/tests/client_secrets.json b/tests/client_secrets.json new file mode 100644 index 00000000..a9b6f9c0 --- /dev/null +++ b/tests/client_secrets.json @@ -0,0 +1,13 @@ +{ + "installed": { + "client_id": "dummy_client_id", + "project_id": "dummy_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": "dummy_client_secret", + "redirect_uris": [ + "http://localhost" + ] + } +} diff --git a/tests/temp_auth_test.py b/tests/temp_auth_test.py new file mode 100644 index 00000000..b483cebb --- /dev/null +++ b/tests/temp_auth_test.py @@ -0,0 +1,23 @@ +import unittest +from unittest import mock + +from google.colab import auth + + +class AuthTest(unittest.TestCase): + + @mock.patch('google_auth_oauthlib.flow.InstalledAppFlow') + def test_authenticate_desktop_application(self, mock_flow): + """Test that authenticate_desktop_application calls run_console.""" + mock_flow.from_client_secrets_file.return_value = mock_flow + auth.authenticate_desktop_application( + 'tests/client_secrets.json', ['scope1', 'scope2'] + ) + mock_flow.from_client_secrets_file.assert_called_once_with( + 'tests/client_secrets.json', ['scope1', 'scope2'] + ) + mock_flow.run_console.assert_called_once() + + +if __name__ == '__main__': + unittest.main()