diff --git a/.gitignore b/.gitignore index 6ffac1c..7c6c6ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.pyc *.egg-info .coverage +env/ diff --git a/Makefile b/Makefile index ff94f01..bd698c9 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ .DEFAULT_GOAL := test test: clean lint - @py.test --cov app.py -s test/ + @py.test test/ --cov app.py -s lint: @flake8 . diff --git a/README.md b/README.md index 0749bec..dc09eb6 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,9 @@ How To Use This --------------- 1. Navigate over to https://developer.uber.com/, and sign up for an Uber developer account. -2. Register a new Uber application and make your Redirect URI http://localhost:7000/submit - ensure that both the `profile` and `history` OAuth scopes are checked. +2. Register a new Uber application and make your Redirect URI `http://localhost:7000/submit` - ensure that both the `profile` and `history` OAuth scopes are checked. 3. Fill in the relevant information in the `config.json` file in the root folder and add your client id and secret as the environment variables `UBER_CLIENT_ID` and `UBER_CLIENT_SECRET`. -4. Run `export UBER_CLIENT_ID="YOUR_CLIENT_ID"&&export UBER_CLIENT_SECRET="YOUR_CLIENT_SECRET"` +4. Run `export UBER_CLIENT_ID="`*{your client id}*`"&&export UBER_CLIENT_SECRET="`*{your client secret}*`"` 5. Run `pip install -r requirements.txt` to install dependencies 6. Run `python app.py` 7. Navigate to http://localhost:7000 in your browser @@ -47,7 +47,8 @@ Click the button below to set up this sample app on Heroku: [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) -After creating your app on Heroku, you have to configure the redirect URL for your Uber OAuth app. Use a `https://{my-app-name}.herokuapp.com/submit` URL. +After creating your app on Heroku, you have to configure the redirect URL for your Uber OAuth app. Use a `https://`*{your-app-name}*`.herokuapp.com/submit` URL. +You will also want to configure the heroku environment variable FLASK_DEBUG=False in order to properly serve SSL traffic. Making Requests --------------- diff --git a/app.py b/app.py index 76f916c..94b2471 100644 --- a/app.py +++ b/app.py @@ -54,7 +54,7 @@ def signup(): params = { 'response_type': 'code', 'redirect_uri': get_redirect_uri(request), - 'scope': ','.join(config.get('scopes')), + 'scopes': ','.join(config.get('scopes')), } url = generate_oauth_service().get_authorize_url(**params) return redirect(url) @@ -72,7 +72,6 @@ def submit(): 'code': request.args.get('code'), 'grant_type': 'authorization_code' } - response = app.requests_session.post( config.get('access_token_url'), auth=( @@ -82,6 +81,7 @@ def submit(): data=params, ) session['access_token'] = response.json().get('access_token') + return render_template( 'success.html', token=response.json().get('access_token') @@ -180,7 +180,7 @@ def price(): @app.route('/history', methods=['GET']) def history(): """Return the last 5 trips made by the logged in user.""" - url = config.get('base_uber_url') + 'history' + url = config.get('base_uber_url_v1_1') + 'history' params = { 'offset': 0, 'limit': 5, @@ -229,4 +229,5 @@ def get_redirect_uri(request): return 'https://{hostname}/submit'.format(hostname=parsed_url.hostname) if __name__ == '__main__': + app.debug = os.environ.get('FLASK_DEBUG', True) app.run(port=7000) diff --git a/config.json b/config.json index e3b8629..46e7fe6 100644 --- a/config.json +++ b/config.json @@ -2,9 +2,10 @@ "access_token_url": "https://login.uber.com/oauth/token", "authorize_url": "https://login.uber.com/oauth/authorize", "base_url": "https://login.uber.com/", - "scopes": ["profile"], + "scopes": ["profile", "history_lite"], "name": "Sample app", "base_uber_url": "https://api.uber.com/v1/", + "base_uber_url_v1_1" : "https://api.uber.com/v1.1/", "start_latitude": "37.781955", "start_longitude": "-122.402367", "end_latitude": "37.744352", diff --git a/requirements-test.txt b/requirements-test.txt index a22d87f..78e2876 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,16 +1,12 @@ # Test harness pytest==2.5.2 - # Coverage pytest-cov==1.6 - # HTTP Fixtures betamax==0.4.0 - # LINT OR DIE flake8==2.1.0 pep8==1.5.6 pyflakes==0.8.1 - # Coveralls coveralls==0.4.2 diff --git a/setup.cfg b/setup.cfg index 7da1f96..7598993 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,3 @@ [flake8] max-line-length = 100 +exclude = env diff --git a/templates/results.html b/templates/results.html index 7a37a7b..9d4de3b 100644 --- a/templates/results.html +++ b/templates/results.html @@ -9,6 +9,6 @@

Welcome to the {{ endpoint }} endpoint!

Here is the result of a call to the {{ endpoint }}:

-

{{ data }} +

{{ data }}

diff --git a/test/fixtures/history_failure.json b/test/fixtures/history_failure.json index c89c553..df181de 100644 --- a/test/fixtures/history_failure.json +++ b/test/fixtures/history_failure.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept": ["*/*"], "Content-Type": ["application/json"], "Accept-Encoding": ["gzip, deflate"], "Authorization": ["bearer NOT_A_CODE"], "User-Agent": ["python-requests/2.3.0 CPython/2.7.5 Darwin/13.2.0"]}, "method": "GET", "uri": "https://api.uber.com/v1/history?limit=5&offset=0"}, "response": {"body": {"string": "{\"message\":\"Invalid OAuth 2.0 credentials provided.\",\"code\":\"unauthorized\"}", "encoding": null}, "headers": {"content-length": ["75"], "server": ["nginx"], "connection": ["keep-alive"], "date": ["Fri, 01 Aug 2014 20:22:08 GMT"], "x-uber-app": ["uberex-nonsandbox"], "content-type": ["application/json"]}, "status": {"message": "Unauthorized", "code": 401}, "url": "https://api.uber.com/v1/history?limit=5&offset=0"}, "recorded_at": "2014-08-01T20:22:08"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept": ["*/*"], "Content-Type": ["application/json"], "Accept-Encoding": ["gzip, deflate"], "Authorization": ["bearer NOT_A_CODE"], "User-Agent": ["python-requests/2.3.0 CPython/2.7.5 Darwin/13.4.0"]}, "method": "GET", "uri": "https://api.uber.com/v1.1/history?limit=5&offset=0"}, "response": {"body": {"string": "{\"message\":\"Invalid OAuth 2.0 credentials provided.\",\"code\":\"unauthorized\"}", "encoding": null}, "headers": {"content-length": ["75"], "server": ["nginx"], "connection": ["keep-alive"], "date": ["Mon, 06 Oct 2014 16:58:57 GMT"], "x-uber-app": ["uberex-nonsandbox"], "content-type": ["application/json"]}, "status": {"message": "Unauthorized", "code": 401}, "url": "https://api.uber.com/v1.1/history?limit=5&offset=0"}, "recorded_at": "2014-10-06T16:58:57"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file diff --git a/test/fixtures/history_success.json b/test/fixtures/history_success.json index 11cf2a0..f0dd74b 100644 --- a/test/fixtures/history_success.json +++ b/test/fixtures/history_success.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept": ["*/*"], "Content-Type": ["application/json"], "Accept-Encoding": ["gzip, deflate"], "Authorization": ["bearer 42Kq726Vv6lzJ0TMhXWsgUulVjRsxh"], "User-Agent": ["python-requests/2.3.0 CPython/2.7.5 Darwin/13.2.0"]}, "method": "GET", "uri": "https://api.uber.com/v1/history?limit=5&offset=0"}, "response": {"body": {"base64_string": "H4sIAAAAAAAAA62VUWvcMAzHv0rIc1xsybaseyuDbU9jUNjLGMWJnTZwd+lyydgo/e7TraXd7dJe1u3NEEey9Pv/pduy6aftWK58VfZtu8ty1FW57jadnFxVXne7sR9+lKvPt+VujOO0K1fyz+ZmncecyqpMciFum1yu4MwGBq+Nx6qcpi7JTTKhBY+tYjakLDk5Oc9KAxsOZOrWWQkiIYbxcuw2EsZY7Vmz51CVN0Ofpma8/BVrqvPwXS7nbfr9qtEIcvU+xLpv4tj123J1W67lNE5JQiKdkSXPTIal0HW/vXr4ogzIs7UP6ANJuTGlIe/2NQZbfMxDXI+xOP+Wt1Ouiou4Ld4OUmy3a/qqeHNe3t2/5vms5MARW4SZrCZYZgA+yKpAF8aM18XFOOQ8PpN0yF+nvPujY2jdXbWAEhptHEqLHylFTE1os1Ym1kLJglDyiRRlxoQYHaZ6hlIADEyLKAWwDuTqaUqktRedzPRLe2IQhR30C/4TJQb0diapQDKMVlTzmzReCykABOIFkIxokow1AcwjpBCw8dS0ygk8sZJuVPSxVgJKN7mus4E5K1Hw5JZBIjGkFu+egiQW1+iClrcdWcmQgWDtoah1KC76SUT9SRz0Qfz1L5ayJBIBu1fTUXbtvfVMh7T0Mokce0pa5ywswIVnyM44zfYJl28ptRGtqhtyyno0KmhtxGKoM1MMNsUZTxEGApnACyYfoVQqRjmFSyYf7cPON8xRcF4+PcmbjEzrZT3bj+KXhp9kRdwPmiNS4ivQJhyMXFJgXjX8pDpgXAjKaJEPSOKHFRUsNT6ZWjWNrZVt66xqTFE50OhdFs9yngEl2yT4haC0lpl7GhQxMnsAseBRvwAt2f2EeuLknVayJYt3/XR1Yl+8zMkGH9h6Pb8aCeAgrehcVOyAi/dxc7O77ob8t8tqv4kd3n25+wkeOPQwfwgAAA==", "encoding": null}, "headers": {"x-rate-limit-remaining": ["4990"], "content-language": ["en"], "content-encoding": ["gzip"], "transfer-encoding": ["chunked"], "strict-transport-security": ["max-age=2592000"], "server": ["nginx"], "connection": ["keep-alive"], "x-rate-limit-reset": ["1406926800"], "x-uber-app": ["uberex-nonsandbox"], "date": ["Fri, 01 Aug 2014 20:22:09 GMT"], "x-rate-limit-limit": ["5000"], "content-type": ["application/json"]}, "status": {"message": "OK", "code": 200}, "url": "https://api.uber.com/v1/history?limit=5&offset=0"}, "recorded_at": "2014-08-01T20:22:09"}], "recorded_with": "betamax/0.4.0"} +{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept": ["*/*"], "Content-Type": ["application/json"], "Accept-Encoding": ["gzip, deflate"], "Authorization": ["bearer MLth87eHvSAaCQ1vn7jTd0xA9Kapo5"], "User-Agent": ["python-requests/2.3.0 CPython/2.7.5 Darwin/13.4.0"]}, "method": "GET", "uri": "https://api.uber.com/v1.1/history?limit=5&offset=0"}, "response": {"body": {"base64_string": "H4sIAAAAAAAAA62TTW7bMBBG78K1aHB+yOH4KkURUBSJGojtxJYWReC7d5SFi9gGaqDRjuLokW++0Yerx+Uwu20UHNyx93OzRRjc626/W18P7tfuPB9Pv932x4c7z2Vezm5rX+3fXtvcJje4yQrKoTa3BdhIzFGFMw9uWXaTlbYWShtz9TFS8Jwq+kKZfW9x7KI1tKpGMcZpfpl3+5XDgFbNRIN7Ox2npc4vn6wC9lRjVcFPFvlsdR57nSahEDisN2qH6QuJE5ndqb0v7XxzBgFdhn+L4QZDRFXQv2LcU9fCwVcu3TPW4jV08hFUEiXRVPIjMYKwUr5BjDCG9FCMAos+IYYb0IyUrd3XwEJhqG0KPvVaPRcZvSaiNbreKcaecW3ybWDMwGiU//cyUmbr0H1gtkPIT3jxBpk0RYGrFkdoHdEGr49sMoheI3dfa5NWiGxm4YEWqVnJd2gZScFI91q2AyRPaOEmZEg5iOjVq/SeRonox1p0DSn4cQT10ssIQkUCyAMv1Bjo1mviMpbSxHeekmcwqoINgRifmh0dCxvr6/9lJEl2n3svtN5lvvy8/AHuOYdTZwQAAA==", "encoding": null}, "headers": {"x-rate-limit-remaining": ["999"], "content-language": ["en"], "content-encoding": ["gzip"], "transfer-encoding": ["chunked"], "strict-transport-security": ["max-age=2592000"], "server": ["nginx"], "connection": ["keep-alive"], "x-rate-limit-reset": ["1412618400"], "x-uber-app": ["uberex-nonsandbox"], "date": ["Mon, 06 Oct 2014 17:12:33 GMT"], "x-rate-limit-limit": ["1000"], "content-type": ["application/json"]}, "status": {"message": "OK", "code": 200}, "url": "https://api.uber.com/v1.1/history?limit=5&offset=0"}, "recorded_at": "2014-10-06T17:12:33"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file diff --git a/test/fixtures/submit_failure.json b/test/fixtures/submit_failure.json index 6ac459f..61484cf 100644 --- a/test/fixtures/submit_failure.json +++ b/test/fixtures/submit_failure.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "code=not_a_code&redirect_uri=https%3A%2F%2Flocalhost%3ANone%2Fsubmit&grant_type=authorization_code", "encoding": "utf-8"}, "headers": {"Content-Length": ["98"], "Accept-Encoding": ["gzip, deflate"], "Accept": ["*/*"], "User-Agent": ["python-requests/2.3.0 CPython/2.7.5 Darwin/13.2.0"], "Content-Type": ["application/x-www-form-urlencoded"], "Authorization": ["Basic X3Y1QmNlNGZ6U0xsTWlJcTgyT05YWGtnZFcwOFBYSlc6QzJkZW1iY3JJV3ljWlBYcVE0SzY1RW1pTFRzRWFOSnAwS045VkJLUQ=="]}, "method": "POST", "uri": "https://login.uber.com/oauth/token"}, "response": {"body": {"string": "{\"error\": \"invalid_grant\"}", "encoding": null}, "headers": {"content-length": ["26"], "server": ["nginx"], "connection": ["keep-alive"], "pragma": ["no-cache"], "cache-control": ["no-store"], "date": ["Fri, 22 Aug 2014 18:40:19 GMT"], "x-uber-app": ["login"], "content-type": ["application/json"]}, "status": {"message": "BAD REQUEST", "code": 400}, "url": "https://login.uber.com/oauth/token"}, "recorded_at": "2014-08-22T18:40:19"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"string": "code=not_a_code&redirect_uri=http%3A%2F%2Flocalhost%3ANone%2Fsubmit&grant_type=authorization_code", "encoding": "utf-8"}, "headers": {"Content-Length": ["97"], "Accept-Encoding": ["gzip, deflate"], "Accept": ["*/*"], "User-Agent": ["python-requests/2.3.0 CPython/2.7.5 Darwin/13.4.0"], "Content-Type": ["application/x-www-form-urlencoded"], "Authorization": ["Basic MW14R3hFR1JxcXU3Z1g5OTE2Rnc0azkwVmlHcTdLVzA6SV8wNW9tRFNIbjM5MHFISDJreE5zd04wb004bUZlc3pBQnREckQ0RQ=="]}, "method": "POST", "uri": "https://login.uber.com/oauth/token"}, "response": {"body": {"string": "{\"error\": \"invalid_grant\"}", "encoding": null}, "headers": {"content-length": ["26"], "server": ["nginx"], "connection": ["keep-alive"], "pragma": ["no-cache"], "cache-control": ["no-store"], "date": ["Mon, 06 Oct 2014 17:11:05 GMT"], "x-uber-app": ["login"], "content-type": ["application/json"]}, "status": {"message": "BAD REQUEST", "code": 400}, "url": "https://login.uber.com/oauth/token"}, "recorded_at": "2014-10-06T17:11:05"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file diff --git a/test/fixtures/submit_success.json b/test/fixtures/submit_success.json deleted file mode 100644 index 685c15b..0000000 --- a/test/fixtures/submit_success.json +++ /dev/null @@ -1 +0,0 @@ -{"http_interactions": [{"request": {"body": {"string": "code=eIzpzFBUv1X57AFmoKPSMBZrAnb4nK&redirect_uri=https%3A%2F%2Flocalhost%3ANone%2Fsubmit&grant_type=authorization_code", "encoding": "utf-8"}, "headers": {"Content-Length": ["118"], "Accept-Encoding": ["gzip, deflate"], "Accept": ["*/*"], "User-Agent": ["python-requests/2.3.0 CPython/2.7.5 Darwin/13.2.0"], "Content-Type": ["application/x-www-form-urlencoded"], "Authorization": ["Basic X3Y1QmNlNGZ6U0xsTWlJcTgyT05YWGtnZFcwOFBYSlc6QzJkZW1iY3JJV3ljWlBYcVE0SzY1RW1pTFRzRWFOSnAwS045VkJLUQ=="]}, "method": "POST", "uri": "https://login.uber.com/oauth/token"}, "response": {"body": {"string": "{\"error\": \"access_denied\"}", "encoding": null}, "headers": {"content-length": ["26"], "server": ["nginx"], "connection": ["keep-alive"], "pragma": ["no-cache"], "cache-control": ["no-store"], "date": ["Fri, 22 Aug 2014 18:39:07 GMT"], "x-uber-app": ["login"], "content-type": ["application/json"]}, "status": {"message": "BAD REQUEST", "code": 400}, "url": "https://login.uber.com/oauth/token"}, "recorded_at": "2014-08-22T18:39:07"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file diff --git a/test/test_endpoints.py b/test/test_endpoints.py index 703d30f..746b849 100644 --- a/test/test_endpoints.py +++ b/test/test_endpoints.py @@ -6,8 +6,7 @@ with Betamax.configure() as config: config.cassette_library_dir = 'test/fixtures' -test_auth_token = '42Kq726Vv6lzJ0TMhXWsgUulVjRsxh' -test_auth_code = 'eIzpzFBUv1X57AFmoKPSMBZrAnb4nK' +test_auth_token = 'MLth87eHvSAaCQ1vn7jTd0xA9Kapo5' class TestCases(unittest.TestCase): @@ -27,15 +26,6 @@ def test_root_endpoint(self): response = app.test_client().get('/') self.assertIn('login.uber.com', response.data) - def test_submit_endpoint_success(self): - """Assert that the / endpoint correctly redirects to login.uber.com.""" - with app.test_client() as client: - with client.session_transaction() as session: - session['access_token'] = test_auth_token - with Betamax(app.requests_session).use_cassette('submit_success'): - response = client.get('/submit?code=%s' % test_auth_code) - self.assertEquals(response.status_code, 200) - def test_submit_endpoint_failure(self): """Assert that the submit endpoint returns no code in the response.""" with app.test_client() as client: