Skip to content
This repository was archived by the owner on Oct 2, 2023. It is now read-only.

Language library refactor #37

Open
wants to merge 256 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
256 commits
Select commit Hold shift + click to select a range
236ea0b
Refactor get_auth_url
Jan 15, 2015
a2e09a6
Refactor get_oauth_signed_url
Jan 15, 2015
3c679a4
Check kwargs and set default values for get_auth_url
Jan 15, 2015
d6799d9
Check kwargs for ttl or set default value
Jan 15, 2015
f76a6e8
Rename _get_oauth_signed_url
Jan 15, 2015
1230438
Rename authenticate params
Jan 15, 2015
aa3cc13
Rename AuthenticationStatus to AuthenticationRequest
Jan 15, 2015
ad1da3e
Rename PairingStatus to Pairing
Jan 15, 2015
4ba88b0
remove get_pair_url test
Jan 15, 2015
0635cc3
Refactor authenticate_with_otp
Jan 15, 2015
5d7ae27
Add Pairing.refresh_from_server
Jan 15, 2015
276008b
Add AuthenticationRequest.refresh_from_server
Jan 15, 2015
de24260
Rename uri to url
Jan 15, 2015
2d27608
Add UserTerminal class and test
Jan 15, 2015
453c0ea
Add get_user_terminal_by_id
Jan 15, 2015
9da5024
Add UserTerminal.refresh_from_server
Jan 15, 2015
f32ec21
Remove comment since test is passing
Jan 15, 2015
205a1cb
"Refactor" AuthenticationRequest.refresh_from_server
Jan 15, 2015
eb80a8b
"Refactor" Pairing.refresh_from_server
Jan 15, 2015
0616c0b
Return UserTerminal instance from create_user_terminal
Jan 15, 2015
aad114e
Refactor enable_user and disable_user
Jan 15, 2015
a047dda
Add get_pairing_reset_link
Jan 15, 2015
ea710e8
Add email_pairing_reset_link_to_user
Jan 15, 2015
15aa251
Add post and get
Jan 15, 2015
be1639a
Add User and create_user
Jan 15, 2015
3ac3e53
Add get_user_by_id
Jan 15, 2015
e0e8167
Add User.refresh_from_server
Jan 15, 2015
62fc11a
Add User.enable and User.disable
Jan 15, 2015
a5bafd2
Rename user_name to username
Jan 15, 2015
2411879
Add reset_user and User.reset
Jan 15, 2015
05ff6d7
Update README.md
Jan 16, 2015
e4daab1
Remove commented out code
Jan 16, 2015
9cf10a4
Update README-Iframe.md
Jan 16, 2015
8cefa84
Update version to 2.0.0
Jan 16, 2015
3ab7e37
Update demo.py
Jan 16, 2015
ecaa370
Update demo_bells_and_whistles.py
Jan 16, 2015
5f850fb
nevermind the country code for demo_bells_and_whistles.py
Jan 16, 2015
bcfbfd8
Use fresh_from_server to update pairing and authorization request
Jan 16, 2015
0b45f77
Add pending field to Pairing class
Jan 16, 2015
8460a07
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 16, 2015
e6a03dc
Fix order of checking if pairing is pending or complete
Jan 16, 2015
31826c8
Rename auth_request_status to auth_request
Jan 16, 2015
c90ed54
Make sure there are two blank lines between classes
Jan 16, 2015
f44460d
Try to make text pretty for Seth
Jan 16, 2015
a0ec572
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 16, 2015
e29fb83
Make it even prettier
Jan 16, 2015
0dc53e3
Make printing prettier
Jan 16, 2015
b7eb00d
Create get_qr_code_image
Jan 16, 2015
934b363
Fix QR image tests
Jan 16, 2015
87bcc27
Add pair by QR code to demo_bells_and_whistles.py
Jan 16, 2015
a8d1bb7
Use refresh_from_server() instead of get_authentication_request_by_id()
Jan 19, 2015
dfd2433
Create API documentation
Jan 19, 2015
21e7f30
Move api-docs.md
Jan 19, 2015
f188926
Rename get_auth_url() to get_auth_iframe_url()
Jan 19, 2015
5166251
Rename get_user_management_url() to get_user_management_iframe_url()
Jan 19, 2015
df7beb4
Fix spacing for ToopherIframeTests
Jan 19, 2015
a57b3ee
Add setUp() and clean up ToopherTests
Jan 19, 2015
b9a84e6
Add setUp() and cleanup ZeroStorageTests
Jan 19, 2015
e39358c
Update ToopherTests.setUp()
Jan 19, 2015
416d7ad
Add setUp() and cleanup AuthenticationRequestTests
Jan 20, 2015
9b1e7e8
Make sure we save self._raw_data appropriately with instance methods
Jan 20, 2015
0822d14
have AuthenticationRequest.authenticate_with_otp update self instance…
Jan 20, 2015
f4afb3f
Add setUp() and cleanup PairingTests
Jan 20, 2015
3d7d2d2
Add setUp() and cleanup UserTerminalTests
Jan 20, 2015
cc662e9
Add setUp() and cleanup UserTests
Jan 20, 2015
837ef2a
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 20, 2015
b019990
Remove repetitive code and use ToopherApi.post and ToopherApi.get ins…
Jan 20, 2015
fbbef1a
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 20, 2015
751e261
Don't call _set_toopher_disabled_for_user within User.enable and User…
Jan 20, 2015
dd135eb
Make Pairing.user store a User instance
Jan 20, 2015
7816771
Add attributes and arguments to ToopherIframe documentation
Jan 20, 2015
8596125
Add UserTerminal.update
Jan 20, 2015
6a704f7
Have AuthenticationRequest.terminal be a UserTerminal instance and up…
Jan 20, 2015
f704f06
Fix table
Jan 20, 2015
882068b
Fix remaining tables
Jan 20, 2015
62cc4b7
Create User.update
Jan 20, 2015
2356092
Update get_auth_url and get_user_management_url names
Jan 20, 2015
9dee6f4
Add Pairing.update
Jan 20, 2015
022fc98
Add AuthenticationRequest.user => User
Jan 20, 2015
dd9559b
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 20, 2015
6de4799
Don't return anything on User.reset
Jan 20, 2015
c36a9a0
Have UserTerminal.user return a User instance
Jan 20, 2015
85d1f92
Move get_reset_link and email_reset_link under Pairing class
Jan 20, 2015
4e1f44b
Switch order of params in authenticate_with_otp
Jan 20, 2015
f2cc5f6
Clean up demo
Jan 20, 2015
1ff6176
Update api-docs
Jan 20, 2015
aa7acb7
Add AdvancedApiUsageFactory and ApiRawRequester with get and post met…
Jan 21, 2015
5a380eb
Remove old get_pairing_reset_link and email_pairing_reset_link_to_user
Jan 21, 2015
603ae22
Add PairingFinder and get_by_id
Jan 21, 2015
bd95088
Add AuthenticationRequestFinder and get_by_id
Jan 21, 2015
a7fe786
Update ToopherIFrame docs
Jan 21, 2015
e3fa38a
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 21, 2015
2014811
Add UserFinder and get_by_id
Jan 21, 2015
61872d0
Add UserFinder.get_by_name
Jan 21, 2015
8dd013c
Add UserTerminalFinder and get_by_id
Jan 21, 2015
4a9a4b5
Update args tables
Jan 21, 2015
79486f9
Update headers and defaults
Jan 21, 2015
42fc2aa
Remove deprecated methods from ToopherApi that are now instance metho…
Jan 21, 2015
701789c
Remove deprecated methods from ToopherApi that are now in ApiRawReque…
Jan 21, 2015
6a25488
Update api-docs
Jan 21, 2015
276db7e
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 21, 2015
24c312f
Update api-docs
Jan 21, 2015
0045490
Rename X_Finder to Xs plural namespace
Jan 21, 2015
55e7651
Move create_user and create_user_terminal to Users.create and UserTer…
Jan 21, 2015
dbe3ffc
Rename get_auth_iframe_url() to get_authentication_url()
Jan 21, 2015
14fe88b
Rename get_user_management_iframe_url() to get_user_management_url()
Jan 21, 2015
821f9c9
Cleanup test names
Jan 21, 2015
7fc0114
Update formatting in api-docs
Jan 22, 2015
ebfff60
Update formatting for list
Jan 22, 2015
b6ab3d2
Correct args for validate_postback
Jan 22, 2015
657acc6
Fix formatting for Users
Jan 22, 2015
bffe89d
Remove args from validate_postback
Jan 22, 2015
5ace2e3
Update args table for ToopherIframe
Jan 22, 2015
19d2a59
Dont make another API call in Users.get_by_name when it is unnecessary
Jan 22, 2015
896f28d
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 22, 2015
0213038
Rename tests to be more descriptive
Jan 26, 2015
288f1b6
Make self.assertTrue(False) self.fail() with explanatory message
Jan 27, 2015
ac17c32
Have SignatureValidationError inherit from ToopherApiError
Jan 27, 2015
7adf87b
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 27, 2015
f72d768
Merge ZeroStorageTests with ToopherTests
Jan 27, 2015
6634943
Make update() for User, UserTerminal, Pairing, and AuthenticationRequ…
Jan 27, 2015
3d308de
Add Action class and AuthenticationRequest.action
Jan 27, 2015
116c51b
Change DEFAULT_IFRAME_TTL to 300
Jan 27, 2015
1ac3815
Check for disable_toopher_auth
Jan 27, 2015
a4444ac
Rename authenticate_with_otp to grant_with_otp
Jan 27, 2015
34b7067
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 27, 2015
64348c4
Remove default values for allow_inline_pairing, automation_allowed an…
Jan 28, 2015
7573002
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 28, 2015
3b40521
Add reason_code to AuthenticationRequest class
Jan 28, 2015
b68af09
Rename terminal.name_extra to terminal.requester_specified_id
Jan 28, 2015
8ecfd29
Rename enable/disable to enable_toopher_authentication/disable_toophe…
Jan 28, 2015
b15845b
Rename user.disable_toopher_auth to user.toopher_authentication_enabled
Jan 28, 2015
972884d
Create ToopherBase class for __getattr__()
Jan 28, 2015
5e1702b
Add Pairing.api and Pairings.api
Jan 29, 2015
2ac7371
Add AuthenticationRequest.api and AuthenticationRequests.api
Jan 29, 2015
a121413
Add User.api, Users.api, UserTerminal.api and UserTerminals.api
Jan 29, 2015
077caab
Don't need to store self.raw in Pairings, Users, AuthenticationReques…
Jan 29, 2015
0b102f9
Refactor PairingTests.test_get_reset_link()
Jan 30, 2015
4a72283
Merge branch 'lang-library-refactor' of github.com:toopher/toopher-py…
Jan 30, 2015
aea5be6
Add ToopherBaseTests.test_pickling_and_unpickling()
Jan 30, 2015
52f23fa
Remove old comment
Feb 3, 2015
41145da
Remove unncessary return statement
Feb 3, 2015
5990fac
Rename _raw_data to raw_response
Feb 3, 2015
b489469
Update UserTerminal.__init__ to use api
Feb 3, 2015
5396b60
Remove unused variable from ToopherApiDemo
Feb 9, 2015
f950359
Update auth.refresh_from_server() in README
Feb 9, 2015
43c3c57
Refactor __init__ method of factory objects into base class
Feb 13, 2015
bdd540f
Cleanup test_get_qr_code_image to only check last_called_method and l…
Feb 13, 2015
239a5fc
Fix errors in tests
Feb 13, 2015
e7cab37
Also test 2.7
Feb 13, 2015
58670ec
Merge pull request #39 from toopher/feature/refactor-factory-base-class
dshafer Feb 13, 2015
c1ec60d
Add User.toopher_authentication_enabled and cleanup __init__
Feb 13, 2015
cde61e5
Add UserTerminal.requester_specified_id and cleanup __init__
Feb 13, 2015
fb12f42
Cleanup Action.__init__ and _update
Feb 13, 2015
cad48f7
Cleanup AuthenticationRequest.__init__ and _update
Feb 13, 2015
877a015
Cleanup Pairing.__init__ and _update
Feb 13, 2015
cf3114b
Rename terminal_name_extra to requester_specified_terminal_id
Feb 13, 2015
03ca33b
Use named parameters for ToopherApi.authenticate
Feb 19, 2015
40b90d9
Refactor ToopherApi.authenticate
Feb 19, 2015
85a1514
Use authenticate by username (zero requester storage) in demo
Feb 20, 2015
2454f84
Use pythonic syntax in variable assignment
Feb 23, 2015
4d5e7f8
Update demo and cleanup prints
Feb 27, 2015
4aa7d0c
Update ToopherIframe README with new validate postback options
Feb 27, 2015
2bf0609
Remove separate python API doc
Mar 2, 2015
330cc12
Urlencode Toopher form data for ToopherIframe
Mar 2, 2015
c3f6113
Use single quotes
Mar 2, 2015
b3209c5
Improve ToopherApiError messages
Mar 2, 2015
1c51cbf
Add info to ToopherApiError messages
Mar 2, 2015
8b437e9
Replace ToopherApi.validate_postback with #process_postback and #is_p…
Mar 2, 2015
d4a7210
Add default reset_email for ToopherIframe.get_authentication_url
Mar 2, 2015
3e4567f
Add tests for #update
Mar 2, 2015
b3e843c
Update ToopherIframe tests to match postback values from API
Mar 3, 2015
df99d15
Update CONTRIBUTING.md to use nosetests to run tests
Mar 3, 2015
d67885f
Log errors in ToopherIframe.is_authentication_granted instead of rais…
Mar 3, 2015
0886691
Rename ToopherIframe._urldecode_data to _urldecode_iframe_data
Mar 3, 2015
470c0c7
Split tests into separate files
Mar 3, 2015
9f5c7a4
Use 'api.toopher.test' URL for tests
Mar 3, 2015
b1c00cb
Split ToopherIframe into own file
Mar 3, 2015
471c0dc
Config log messages for ToopherIframe.is_authentication_granted
Mar 3, 2015
61349c5
Refactor ToopherIframe._validate_postback
Mar 3, 2015
c4353b8
Update travis.yml with new test script
Mar 4, 2015
e5ee6c6
Clean up ToopherIframe tests and improve coverage
Mar 4, 2015
497d0c9
Merge kwargs with params in ToopherIframe.get_user_management_url
Mar 4, 2015
88202a4
Rename ToopherIframe._signature to _calculate_signature
Mar 4, 2015
0a04334
Refactor error message for signature calculation error
Mar 4, 2015
b1b23b5
Update readme with new import
Mar 4, 2015
15086a9
Removed Werkzeug from requirements
Mar 4, 2015
026b115
Remove pillow from requirements
Mar 4, 2015
bb028aa
Update Iframe README with new process_postback
Mar 4, 2015
95bdcde
Refactor ToopherApi._request to return raw response or json
Mar 4, 2015
3f61a91
Test ToopherApiError in Action.__init__ and update
Mar 4, 2015
15f2917
Add tests for ToopherIframe.get_authentication_url
Mar 5, 2015
20a4c3c
Fix code snippets in Iframe readme
Mar 5, 2015
b5625e7
Fix Iframe README
Mar 5, 2015
99e13c5
Return True if UserDisabledError
Mar 5, 2015
dd8cb26
Simplify return for #is_authentication_granted
Mar 5, 2015
764e6cd
Simplify assignment for boolean values
Mar 5, 2015
64af51d
Reorder methods
Mar 5, 2015
9c19e33
Set default reset_email for #get_user_management_url and test
Mar 5, 2015
d8c1cb2
Log UserDisabledError as info not error
Mar 5, 2015
da9202e
Remove demo bells and whistles
Mar 6, 2015
6e9ad94
Update readme with named, optional args for #authenticate
Mar 6, 2015
b7ce02b
Add CONTRIBUTING.md info to README
Mar 6, 2015
0e5c5f5
Reorder sections in README
Mar 6, 2015
4188e6e
Combine README and README-Iframe
Mar 6, 2015
f4571b2
Refactor README
Mar 6, 2015
6502c86
Clean up IFRAME text
Mar 9, 2015
c410e78
Reformat text and subheaders
Mar 9, 2015
f2f75fc
Remove dupe test
Mar 9, 2015
f9dc71d
Use self.request_token instead of ToopherIframeTest.request_token
Mar 9, 2015
e39865d
Add tests for ToopherIframe.is_authentication_granted
Mar 9, 2015
501153b
Add test for process_postback with extras
Mar 9, 2015
862c0c6
Add test for ToopherIframe.process_postback without request token
Mar 9, 2015
cf664ed
Simplify README
Mar 10, 2015
a74935d
Use dict for postback_data tests
Mar 10, 2015
ddd526e
Rename get_authentication_url tests
Mar 10, 2015
f109152
Remove process_postback from README
Mar 10, 2015
0817299
Cleanup tests for is_authentication_granted and make sure to pass kwa…
Mar 11, 2015
71d2490
Fix error tests for is_authentication_granted
Mar 11, 2015
b0b0ede
Set default reset_email, request_token and requester_metadata to empt…
Mar 11, 2015
1ef2b9a
Add Iframe version to params in get_oauth_signed_url
Mar 11, 2015
fe94dc0
Cleanup Iframe tests
Mar 11, 2015
0371537
Expand test for get_user_management_url
Mar 20, 2015
abce789
Add test for is_authentication_granted with auth request is granted a…
Mar 20, 2015
48314a2
Improve test failure messages for is_authentication_granted
Mar 20, 2015
05a4f1b
Cleanup text in demo
Mar 23, 2015
b5ed48b
Include base_uri when creating new instance of ToopherApi
Mar 24, 2015
fbf85e0
Refactor Pairing.get_qr_code_image to use new get_raw method
Mar 25, 2015
45d7931
Add license section to README
Mar 26, 2015
4f77063
Add coverage to nosetests script
Mar 26, 2015
30c81d9
Improve tests for User
Mar 26, 2015
f20c6cb
Use cover-inclusive for nosetests
Mar 26, 2015
c32f47b
Improve tests for Pairing
Mar 26, 2015
eb71816
Move HttpClientMock to new testutils file
Mar 26, 2015
ff0eac9
Cleanup pickle test
Mar 26, 2015
23fc9aa
Cleanup ToopherApi test
Mar 26, 2015
d3d0534
Update coveragerc to exclude test files
Mar 27, 2015
6de42f0
Simplify test script for travis
Mar 27, 2015
6712470
Authenticate by username in README
Mar 27, 2015
9b7878f
Add more info about postback_data
Mar 27, 2015
29a1fad
Expect iframe postback data to be a string from POST parameter toophe…
Mar 27, 2015
ddf9271
Keep blank values when parsing postback data
Mar 30, 2015
8ca207b
Add process_postback test for keys with empty values
Mar 30, 2015
8f341c3
Cleanup text in the README
Mar 30, 2015
9a8cae2
fix parameter error for Users.get_by_name
dshafer Jun 11, 2015
8bf5770
fix another incorrect parameter
dshafer Jun 12, 2015
5539c41
fix tests too
dshafer Nov 19, 2015
2c1323e
python 3 updates
natemoser Jun 24, 2021
5083c36
update to reflect Python 3.6
natemoser Jun 24, 2021
6b1a43a
Merge pull request #40 from natemoser/lang-library-refactor
dshafer Jun 25, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
omit =
*/python?.?/*
*/site-packages/nose/*
tests.py
test/*
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ Icon

### Added by etg
setenv

### Added by ndm
venv
.idea
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
language: python
python:
- 2.6
- 2.7
install:
- pip install -r requirements.txt --use-mirrors
script:
nosetests tests.py --with-coverage --cover-package=toopher
nosetests --with-coverage test
after_success:
coveralls
18 changes: 0 additions & 18 deletions CONTRIBUTING.md

This file was deleted.

119 changes: 0 additions & 119 deletions README-Iframe.md

This file was deleted.

133 changes: 76 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,104 @@
#ToopherPython
#ToopherPython [![Build Status](https://travis-ci.org/toopher/toopher-python.png?branch=master)](https://travis-ci.org/toopher/toopher-python)

[![Build Status](https://travis-ci.org/toopher/toopher-python.png?branch=master)](https://travis-ci.org/toopher/toopher-python)
ToopherPython is a Toopher API library that simplifies the task of interfacing with the Toopher API from Python code.
This project wrangles all the dependency libraries and handles the required OAuth and JSON functionality so you can
focus on just using the API.

#### Introduction
ToopherPython is a Toopher API library that simplifies the task of interfacing with the Toopher API from Python code. This project wrangles all the required OAuth and JSON functionality so you can focus on just using the API.
### Python Version
* 3.6

#### Learn the Toopher API
### Documentation
Make sure you visit [https://dev.toopher.com](https://dev.toopher.com) to get acquainted with the Toopher API fundamentals. The documentation there will tell you the details about the operations this API wrapper library provides.

#### OAuth Authentication
First off, to access the Toopher API you'll need to sign up for an account at the [Toopher developers portal](https://dev.toopher.com) and create a "requester". When that process is complete, your requester is issued OAuth 1.0a credentials in the form of a consumer key and secret. Your key is used to identify your requester when Toopher interacts with your customers, and the secret is used to sign each request so that we know it is generated by you. This library properly formats each request with your credentials automatically.
## ToopherApi Workflow

#### The Toopher Two-Step
Interacting with the Toopher web service involves two steps: pairing, and authenticating.

##### Pair
Before you can enhance your website's actions with Toopher, your customers will need to pair their phone's Toopher app with your website. To do this, they generate a unique, nonsensical "pairing phrase" from within the app on their phone. You will need to prompt them for a pairing phrase as part of the Toopher enrollment process. Once you have a pairing phrase, just send it to the Toopher web service and we'll return a pairing ID that you can use whenever you want to authenticate an action for that user.

##### Authenticate
You have complete control over what actions you want to authenticate using Toopher (for example: logging in, changing account information, making a purchase, etc.). Just send us the user's pairing ID, a name for the terminal they're using, and a description of the action they're trying to perform and we'll make sure they actually want it to happen.

#### Librarified
This library makes it super simple to do the Toopher two-step. Check it out:
### Step 1: Pair
Before you can enhance your website's actions with Toopher, your customers will need to pair their mobile device's Toopher app with your website. To do this, they generate a unique pairing phrase from within the app on their mobile device. You will need to prompt them for a pairing phrase as part of the Toopher enrollment process. Once you have a pairing phrase, just send it to the Toopher web service along with your requester credentials and we'll return a pairing ID that you can use whenever you want to authenticate an action for that user.

```python
import toopher

# Create an API object using your credentials
api = toopher.ToopherApi("<your consumer key>", "<your consumer secret>")

# Step 1 - Pair with their phone's Toopher app
pairing_status = api.pair("pairing phrase", "username@yourservice.com")
# Step 1 - Pair with their mobile device's Toopher app
pairing = api.pair("username@yourservice.com", "pairing phrase")
```

### Step 2: Authenticate
You have complete control over what actions you want to authenticate using Toopher (logging in, changing account
information, making a purchase, etc.). Just send us the username or pairing ID and we'll make sure they actually want it to happen
. You can also choose to provide the following optional parameters: terminal name, requester specified ID and
action name (*default: "Log in"*).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to check that the user has responded affirmatively like we do after the authenticate call below--can you please add a similar check here? Note that pairings are enabled rather than granted.

```python
# Step 2 - Authenticate a log in
auth = api.authenticate(pairing_status.id, "my computer")
authentication_request = api.authenticate("username@yourservice.com", "terminal name")

# Once they've responded you can then check the status
auth_status = api.get_authentication_status(auth.id)
if (auth_status.pending == False and auth_status.granted == True):
authentication_request.refresh_from_server()
if not authentication_request.pending and authentication_request.granted:
# Success!
```

#### Handling Errors
If any request runs into an error a `ToopherApiError` will be thrown with more details on what went wrong.
## ToopherIframe Workflow

#### Zero-Storage usage option
Requesters can choose to integrate the Toopher API in a way does not require storing any per-user data such as Pairing ID and Terminal ID - all of the storage
is handled by the Toopher API Web Service, allowing your local database to remain unchanged. If the Toopher API needs more data, it will `raise()` a specific
error that allows your code to respond appropriately.
### Step 1: Embed a request in an IFRAME
1. Generate an authentication URL by providing a username.
2. Display a webpage to your user that embeds this URL within an `<iframe>` element.

```python
try:
# optimistically try to authenticate against Toopher API with username and a Terminal Identifier
# Terminal Identifer is typically a randomly generated secure browser cookie. It does not
# need to be human-readable
auth = api.authenticate_by_user_name(user_name, requester_terminal_id)

# if you got here, everything is good! poll the auth request status as described above
# there are four distinct errors ToopherAPI can return if it needs more data
except UserDisabledError:
# you have marked this user as disabled in the Toopher API.
except UserUnknownError:
# This user has not yet paired a mobile device with their account. Pair them
# using api.pair() as described above, then re-try authentication
except TerminalUnknownError:
# This user has not assigned a "Friendly Name" to this terminal identifier.
# Prompt them to enter a terminal name, then submit that "friendly name" to
# the Toopher API:
# api.create_user_terminal(user_name, terminal_name, requester_terminal_id)
# Afterwards, re-try authentication
except PairingDeactivatedError:
# this user does not have an active pairing,
# typically because they deleted the pairing. You can prompt
# the user to re-pair with a new mobile device.
import toopher

# Create an API object using your credentials
iframe_api = toopher.ToopherIframe("<your consumer key>", "<your consumer secret>")


auth_iframe_url = iframe_api.get_authentication_url("username@yourservice.com");

# Add an <iframe> element to your HTML:
# <iframe id="toopher_iframe" src=auth_iframe_url />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add some information about how to style the iframe - they should make it 300px tall. Width should be at least 400px, with 720px or wider being preferred

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plan was to have the original HTML markup info moved to the dev site. Do you think it needs to be included here as well?

```

#### Dependencies
This library uses the [Requests](http://docs.python-requests.org/en/latest/) library to handle OAuth signing and to make the web requests. If you install using pip (or easy_install) they'll be installed automatically for you.
### Step 2: Validate the postback data

The simplest way to validate the postback data is to call `is_authentication_granted` to check if the authentication request was granted.

#### Try it out
Check out `demo.py` for an example program that walks you through the whole process! Just download the contents of this repo, make sure you have the dependencies listed above installed, and then run it like-a-this:
```python
# Retrieve the postback data as a string from POST parameter 'iframe_postback_data'
postback_data = request.args['iframe_postback_data']

# Returns boolean indicating if authentication request was granted by user
authentication_request_granted = iframe_api.is_authentication_granted(postback_data)

if authentication_request_granted:
# Success!
```

### Handling Errors
If any request runs into an error a `ToopherApiError` will be thrown with more details on what went wrong.

### Demo
Check out `demo.py` for an example program that walks you through the whole process! Just download the contents of
this repo, make sure you have the dependencies installed, and run the command below:
```shell
$ python demo.py
```

## Contributing
### Dependencies
This library uses the [Requests](http://docs.python-requests.org/en/latest/) library and [OAuthLib](https://oauthlib.readthedocs.org/en/latest/index.html) to handle OAuth signing and make the web requests.

Toopher uses [pip](https://pypi.python.org/pypi/pip) to install Python packages. To ensure all dependencies are up-to-date run:
```shell
$ python ./demo.py
$ pip install -r requirements.txt
```

### Tests
To run the tests using [nose](http://nose.readthedocs.org/en/latest/) enter:
```shell
$ nosetests test
```

## License
ToopherPython is licensed under the MIT License. See LICENSE.txt for the full text.
43 changes: 43 additions & 0 deletions assets/js/toopher-web.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(function(window, $){
var postToUrl = function (path, params, method){
method = method || 'POST';
var form = $('<form />').attr('method', method).attr('action', path);
for (var key in params){
if (params.hasOwnProperty(key)){
var hiddenField = $('<input />').attr('type', 'hidden').attr('name', key).attr('value', params[key]);
form.append(hiddenField);
}
}
$('body').append(form);
form.submit();
}

var handleMessage = function(e){
var msgData = JSON.parse(e.data);
if (msgData.status === 'toopher-api-complete'){
var iframe = $('#toopher_iframe');
var frameworkPostArgsJSON = iframe.attr('framework_post_args');
var frameworkPostArgs = {};
if(frameworkPostArgsJSON){
frameworkPostArgs = $.parseJSON(frameworkPostArgsJSON);
}
var postData = $.extend({}, msgData.payload, frameworkPostArgs);
var toopherData = {'toopher_iframe_data': $.param(postData)};

if(iframe.attr('use_ajax_postback')){
$.post(iframe.attr('toopher_postback'), toopherData)
.done(function(data){
data = $.parseJSON(data);
});
} else {
postToUrl(iframe.attr('toopher_postback'), toopherData, 'POST');
}
}
}

if (window.addEventListener) {
window.addEventListener('message', handleMessage, false);
} else {
window.attachEvent('onmessage', handleMessage);
}
})(window, jQuery);
Loading