1# Copyright 2016 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import datetime
16import os
17import sys
18
19import mock
20import oauth2client.client
21import oauth2client.contrib.gce
22import oauth2client.service_account
23import pytest
24from six.moves import reload_module
25
26from google.auth import _oauth2client
27
28
29DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
30SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")
31
32
33def test__convert_oauth2_credentials():
34    old_credentials = oauth2client.client.OAuth2Credentials(
35        "access_token",
36        "client_id",
37        "client_secret",
38        "refresh_token",
39        datetime.datetime.min,
40        "token_uri",
41        "user_agent",
42        scopes="one two",
43    )
44
45    new_credentials = _oauth2client._convert_oauth2_credentials(old_credentials)
46
47    assert new_credentials.token == old_credentials.access_token
48    assert new_credentials._refresh_token == old_credentials.refresh_token
49    assert new_credentials._client_id == old_credentials.client_id
50    assert new_credentials._client_secret == old_credentials.client_secret
51    assert new_credentials._token_uri == old_credentials.token_uri
52    assert new_credentials.scopes == old_credentials.scopes
53
54
55def test__convert_service_account_credentials():
56    old_class = oauth2client.service_account.ServiceAccountCredentials
57    old_credentials = old_class.from_json_keyfile_name(SERVICE_ACCOUNT_JSON_FILE)
58
59    new_credentials = _oauth2client._convert_service_account_credentials(
60        old_credentials
61    )
62
63    assert (
64        new_credentials.service_account_email == old_credentials.service_account_email
65    )
66    assert new_credentials._signer.key_id == old_credentials._private_key_id
67    assert new_credentials._token_uri == old_credentials.token_uri
68
69
70def test__convert_service_account_credentials_with_jwt():
71    old_class = oauth2client.service_account._JWTAccessCredentials
72    old_credentials = old_class.from_json_keyfile_name(SERVICE_ACCOUNT_JSON_FILE)
73
74    new_credentials = _oauth2client._convert_service_account_credentials(
75        old_credentials
76    )
77
78    assert (
79        new_credentials.service_account_email == old_credentials.service_account_email
80    )
81    assert new_credentials._signer.key_id == old_credentials._private_key_id
82    assert new_credentials._token_uri == old_credentials.token_uri
83
84
85def test__convert_gce_app_assertion_credentials():
86    old_credentials = oauth2client.contrib.gce.AppAssertionCredentials(
87        email="some_email"
88    )
89
90    new_credentials = _oauth2client._convert_gce_app_assertion_credentials(
91        old_credentials
92    )
93
94    assert (
95        new_credentials.service_account_email == old_credentials.service_account_email
96    )
97
98
99@pytest.fixture
100def mock_oauth2client_gae_imports(mock_non_existent_module):
101    mock_non_existent_module("google.appengine.api.app_identity")
102    mock_non_existent_module("google.appengine.ext.ndb")
103    mock_non_existent_module("google.appengine.ext.webapp.util")
104    mock_non_existent_module("webapp2")
105
106
107@mock.patch("google.auth.app_engine.app_identity")
108def test__convert_appengine_app_assertion_credentials(
109    app_identity, mock_oauth2client_gae_imports
110):
111
112    import oauth2client.contrib.appengine
113
114    service_account_id = "service_account_id"
115    old_credentials = oauth2client.contrib.appengine.AppAssertionCredentials(
116        scope="one two", service_account_id=service_account_id
117    )
118
119    new_credentials = _oauth2client._convert_appengine_app_assertion_credentials(
120        old_credentials
121    )
122
123    assert new_credentials.scopes == ["one", "two"]
124    assert new_credentials._service_account_id == old_credentials.service_account_id
125
126
127class FakeCredentials(object):
128    pass
129
130
131def test_convert_success():
132    convert_function = mock.Mock(spec=["__call__"])
133    conversion_map_patch = mock.patch.object(
134        _oauth2client, "_CLASS_CONVERSION_MAP", {FakeCredentials: convert_function}
135    )
136    credentials = FakeCredentials()
137
138    with conversion_map_patch:
139        result = _oauth2client.convert(credentials)
140
141    convert_function.assert_called_once_with(credentials)
142    assert result == convert_function.return_value
143
144
145def test_convert_not_found():
146    with pytest.raises(ValueError) as excinfo:
147        _oauth2client.convert("a string is not a real credentials class")
148
149    assert excinfo.match("Unable to convert")
150
151
152@pytest.fixture
153def reset__oauth2client_module():
154    """Reloads the _oauth2client module after a test."""
155    reload_module(_oauth2client)
156
157
158def test_import_has_app_engine(
159    mock_oauth2client_gae_imports, reset__oauth2client_module
160):
161    reload_module(_oauth2client)
162    assert _oauth2client._HAS_APPENGINE
163
164
165def test_import_without_oauth2client(monkeypatch, reset__oauth2client_module):
166    monkeypatch.setitem(sys.modules, "oauth2client", None)
167    with pytest.raises(ImportError) as excinfo:
168        reload_module(_oauth2client)
169
170    assert excinfo.match("oauth2client")
171