Adding system tests to make sure token exchange works as expected.
- Updates CONTRIBUTING.md to explain how to set-up and run these tests. - Requires a version of httplib2 that has not been released on PyPI yet in order to work on Python 3. - Simply creates 3 different token types (JSON key for svc. acct., P12 key for svc. acct., JSON key for user acct.) and then authorizes an httplib2.Http object to hit the USERINFO API.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -15,3 +15,6 @@ docs/_build
|
||||
.coverage
|
||||
coverage.xml
|
||||
nosetests.xml
|
||||
|
||||
# Files with private / local data
|
||||
scripts/local_test_setup
|
||||
|
||||
@@ -90,6 +90,49 @@ Running Tests
|
||||
$ tox
|
||||
```
|
||||
|
||||
Running System Tests
|
||||
--------------------
|
||||
|
||||
- To run system tests you can execute:
|
||||
|
||||
```bash
|
||||
$ tox -e system-tests
|
||||
$ tox -e system-tests3
|
||||
```
|
||||
|
||||
This alone will not run the tests. You'll need to change some local
|
||||
auth settings and download some service account configuration files
|
||||
from your project to run all the tests.
|
||||
|
||||
- System tests will be run against an actual project and so you'll need to
|
||||
provide some environment variables to facilitate this.
|
||||
|
||||
- `OAUTH2CLIENT_TEST_JSON_KEY_PATH`: The path to a service account JSON
|
||||
key file; see `tests/data/gcloud/application_default_credentials.json`
|
||||
as an example. Such a file can be downloaded directly from the
|
||||
developer's console by clicking "Generate new JSON key". See private
|
||||
key [docs][3] for more details.
|
||||
- `OAUTH2CLIENT_TEST_P12_KEY_PATH`: The path to a service account
|
||||
P12/PKCS12 key file. You can download this in the same way as a JSON
|
||||
key, just select "P12 Key" as your "Key type" when downloading.
|
||||
- `OAUTH2CLIENT_TEST_P12_KEY_EMAIL`: The service account email
|
||||
corresponding to the P12/PKCS12 key file.
|
||||
- `OAUTH2CLIENT_TEST_USER_KEY_PATH`: The path to a JSON key file for a
|
||||
user. If this is not set, the file created by running
|
||||
`gcloud auth login` will be used. See
|
||||
`tests/data/gcloud/application_default_credentials_authorized_user.json`
|
||||
for an example.
|
||||
- `OAUTH2CLIENT_TEST_USER_KEY_EMAIL`: The user account email
|
||||
corresponding to the user JSON key file.
|
||||
|
||||
- Examples of these can be found in `scripts/local_test_setup.sample`. We
|
||||
recommend copying this to `scripts/local_test_setup`, editing the values
|
||||
and sourcing them into your environment:
|
||||
|
||||
```bash
|
||||
$ source scripts/local_test_setup
|
||||
```
|
||||
|
||||
Contributor License Agreements
|
||||
------------------------------
|
||||
|
||||
|
||||
5
scripts/local_test_setup.sample
Normal file
5
scripts/local_test_setup.sample
Normal file
@@ -0,0 +1,5 @@
|
||||
export OAUTH2CLIENT_TEST_JSON_KEY_PATH="tests/data/gcloud/application_default_credentials.json"
|
||||
export OAUTH2CLIENT_TEST_P12_KEY_PATH="tests/data/privatekey.p12"
|
||||
export OAUTH2CLIENT_TEST_P12_KEY_EMAIL="project-foo@developer.gserviceaccount.com"
|
||||
export OAUTH2CLIENT_TEST_USER_KEY_PATH="tests/data/gcloud/application_default_credentials_authorized_user.json"
|
||||
export OAUTH2CLIENT_TEST_USER_KEY_EMAIL="foo@gmail.com"
|
||||
107
scripts/run_system_tests.py
Normal file
107
scripts/run_system_tests.py
Normal file
@@ -0,0 +1,107 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
import httplib2
|
||||
from oauth2client import client
|
||||
from oauth2client import service_account
|
||||
|
||||
|
||||
JSON_KEY_PATH = os.getenv('OAUTH2CLIENT_TEST_JSON_KEY_PATH')
|
||||
P12_KEY_PATH = os.getenv('OAUTH2CLIENT_TEST_P12_KEY_PATH')
|
||||
P12_KEY_EMAIL = os.getenv('OAUTH2CLIENT_TEST_P12_KEY_EMAIL')
|
||||
USER_KEY_PATH = os.getenv('OAUTH2CLIENT_TEST_USER_KEY_PATH',
|
||||
client._get_well_known_file())
|
||||
USER_KEY_EMAIL = os.getenv('OAUTH2CLIENT_TEST_USER_KEY_EMAIL')
|
||||
|
||||
SCOPE = ('https://www.googleapis.com/auth/plus.login',
|
||||
'https://www.googleapis.com/auth/plus.me',
|
||||
'https://www.googleapis.com/auth/userinfo.email',
|
||||
'https://www.googleapis.com/auth/userinfo.profile')
|
||||
USER_INFO = 'https://www.googleapis.com/oauth2/v2/userinfo'
|
||||
|
||||
|
||||
def _require_environ():
|
||||
if (JSON_KEY_PATH is None or P12_KEY_PATH is None or
|
||||
P12_KEY_EMAIL is None or USER_KEY_PATH is None or
|
||||
USER_KEY_EMAIL is None):
|
||||
raise EnvironmentError('Expected environment variables to be set:',
|
||||
'OAUTH2CLIENT_TEST_JSON_KEY_PATH',
|
||||
'OAUTH2CLIENT_TEST_P12_KEY_PATH',
|
||||
'OAUTH2CLIENT_TEST_P12_KEY_EMAIL',
|
||||
'OAUTH2CLIENT_TEST_USER_KEY_PATH',
|
||||
'OAUTH2CLIENT_TEST_USER_KEY_EMAIL')
|
||||
|
||||
if not os.path.isfile(JSON_KEY_PATH):
|
||||
raise EnvironmentError(JSON_KEY_PATH, 'is not a file')
|
||||
if not os.path.isfile(P12_KEY_PATH):
|
||||
raise EnvironmentError(P12_KEY_PATH, 'is not a file')
|
||||
if not os.path.isfile(USER_KEY_PATH):
|
||||
raise EnvironmentError(USER_KEY_PATH, 'is not a file')
|
||||
|
||||
|
||||
def _check_user_info(credentials, expected_email):
|
||||
http = credentials.authorize(httplib2.Http())
|
||||
response, content = http.request(USER_INFO)
|
||||
if response.status != 200:
|
||||
raise ValueError('Expected 200 response.')
|
||||
|
||||
content = content.decode('utf-8')
|
||||
payload = json.loads(content)
|
||||
if payload['email'] != expected_email:
|
||||
raise ValueError('User info email does not match credentials.')
|
||||
|
||||
|
||||
def run_json():
|
||||
with open(JSON_KEY_PATH, 'r') as file_object:
|
||||
client_credentials = json.load(file_object)
|
||||
|
||||
credentials = service_account._ServiceAccountCredentials(
|
||||
service_account_id=client_credentials['client_id'],
|
||||
service_account_email=client_credentials['client_email'],
|
||||
private_key_id=client_credentials['private_key_id'],
|
||||
private_key_pkcs8_text=client_credentials['private_key'],
|
||||
scopes=SCOPE,
|
||||
)
|
||||
|
||||
_check_user_info(credentials, client_credentials['client_email'])
|
||||
|
||||
|
||||
def run_p12():
|
||||
with open(P12_KEY_PATH, 'rb') as file_object:
|
||||
private_key_contents = file_object.read()
|
||||
|
||||
credentials = client.SignedJwtAssertionCredentials(
|
||||
service_account_name=P12_KEY_EMAIL,
|
||||
private_key=private_key_contents,
|
||||
scope=SCOPE,
|
||||
)
|
||||
|
||||
_check_user_info(credentials, P12_KEY_EMAIL)
|
||||
|
||||
|
||||
def run_user_json():
|
||||
with open(USER_KEY_PATH, 'r') as file_object:
|
||||
client_credentials = json.load(file_object)
|
||||
|
||||
credentials = client.GoogleCredentials(
|
||||
access_token=None,
|
||||
client_id=client_credentials['client_id'],
|
||||
client_secret=client_credentials['client_secret'],
|
||||
refresh_token=client_credentials['refresh_token'],
|
||||
token_expiry=None,
|
||||
token_uri=client.GOOGLE_TOKEN_URI,
|
||||
user_agent='Python client library',
|
||||
)
|
||||
|
||||
_check_user_info(credentials, USER_KEY_EMAIL)
|
||||
|
||||
|
||||
def main():
|
||||
_require_environ()
|
||||
run_json()
|
||||
run_p12()
|
||||
run_user_json()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
34
scripts/run_system_tests.sh
Executable file
34
scripts/run_system_tests.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -ev
|
||||
|
||||
|
||||
# If we're on Travis, we need to set up the environment.
|
||||
if [[ "${TRAVIS}" == "true" ]]; then
|
||||
# If merging to master and not a pull request, run system test.
|
||||
if [[ "${TRAVIS_BRANCH}" == "master" ]] && \
|
||||
[[ "${TRAVIS_PULL_REQUEST}" == "false" ]]; then
|
||||
echo "Running in Travis during merge, not setup correctly yet."
|
||||
exit 1
|
||||
else
|
||||
echo "Running in Travis during non-merge to master, doing nothing."
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run the system tests for each tested package.
|
||||
python scripts/run_system_tests.py
|
||||
2
setup.py
2
setup.py
@@ -35,7 +35,7 @@ packages = [
|
||||
]
|
||||
|
||||
install_requires = [
|
||||
'httplib2>=0.8',
|
||||
'httplib2>=0.9.1',
|
||||
'pyasn1==0.1.7',
|
||||
'pyasn1_modules==0.0.5',
|
||||
'rsa==3.1.4',
|
||||
|
||||
18
tox.ini
18
tox.ini
@@ -72,3 +72,21 @@ basepython = python2.7
|
||||
deps = {[testenv]basedeps}
|
||||
django>=1.5,<1.6
|
||||
pyopenssl<0.14
|
||||
|
||||
[testenv:system-tests]
|
||||
basepython =
|
||||
python2.7
|
||||
commands =
|
||||
{toxinidir}/scripts/run_system_tests.sh
|
||||
deps =
|
||||
pycrypto==2.6
|
||||
pyopenssl==0.14
|
||||
|
||||
[testenv:system-tests3]
|
||||
basepython =
|
||||
python3.4
|
||||
commands =
|
||||
{toxinidir}/scripts/run_system_tests.sh
|
||||
deps =
|
||||
pycrypto==2.6
|
||||
pyopenssl==0.14
|
||||
|
||||
Reference in New Issue
Block a user