Skip to content

Commit

Permalink
Revert "Merge pull request #81 from ka05/ka05/oauth-2fa"
Browse files Browse the repository at this point in the history
This reverts commit b60891e.
  • Loading branch information
dahifi committed May 26, 2020
1 parent e8de229 commit 45124cb
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 237 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,3 @@ python_junit.xml
# IDE
.ctrlpignore

# PyCharm idea files
.idea/*
16 changes: 3 additions & 13 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,12 @@ Set the name and id to something reasonably unique, and the redirect to `http://


### Step 5
Run `tdameritrade.auth.authentication` from a python prompt, with `client_id=consumer_key` and `redirect_uri` from step 4.
run `tdameritrade.auth.authentication` from a python prompt, with `client_id=consumer_key` and `redirect_uri` from step 4.

### Step 6
Sign in and authorize your app.

You can enter credentials by hand.

Or store them in environment variables in `.env`:

- Copy `.env.default` to `.env` and fill out

If you setup all of the env variables in `.env`, including the Security QA vars,
the entire web form will be filled in and complete automatically returning the OAuth token.
( If you did this skip Step 7 and store your tokens. )

You can enter credentials by hand or store them in environment variables `TDAUSER` and `TDAPASS`. When stored, the first page will be filled in and advanced automaticly.

```eval_rst
.. image:: ./img/auth/2.png
Expand All @@ -53,8 +44,7 @@ the entire web form will be filled in and complete automatically returning the O
```

### Step 7
Return to the prompt, if you entered the info correctly you should see your tokens printed.
Write these down, i recommend keeping a `keys.sh` file setting `ACCESS_TOKEN` and `REFRESH_TOKEN` environment variables.
Return to the prompt, if you entered the info correctly you should see your tokens printed. Write these down, i recommend keeping a `keys.sh` file setting `ACCESS_TOKEN` and `REFRESH_TOKEN` environment variables.


```eval_rst
Expand Down
9 changes: 0 additions & 9 deletions requirements.txt

This file was deleted.

15 changes: 7 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def get_version(file, name='__version__'):
exec(f.read(), {}, version_ns)
return version_ns[name]


version = get_version(pjoin(here, name, '_version.py'))

with open(pjoin(here, 'README.md'), encoding='utf-8') as f:
Expand All @@ -32,13 +31,13 @@ def get_version(file, name='__version__'):
]

requires_dev = [
'flake8>=3.7.8',
'mock',
'pytest>=4.3.0',
'pytest-cov>=2.6.1',
'Sphinx>=1.8.4',
'sphinx-markdown-builder>=0.5.2',
] + requires
'flake8>=3.7.8',
'mock',
'pytest>=4.3.0',
'pytest-cov>=2.6.1',
'Sphinx>=1.8.4',
'sphinx-markdown-builder>=0.5.2',
] + requires

setup(
name=name,
Expand Down
101 changes: 74 additions & 27 deletions tdameritrade/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,82 @@
import os
import os.path
import sys
import time
import urllib.parse as up
from shutil import which

import requests

from tdameritrade.auth.auth_form_executioner import FormExecutioner
from tdameritrade.auth.tda_config_provider import TDAConfigProvider, TDAConfig
from tdameritrade.auth.web_driver_provider import WebDriverProvider

def authentication(client_id, redirect_uri, tdauser=None, tdapass=None):
from selenium import webdriver
client_id = client_id + '@AMER.OAUTHAP'
url = 'https://auth.tdameritrade.com/auth?response_type=code&redirect_uri=' + up.quote(redirect_uri) + '&client_id=' + up.quote(client_id)

options = webdriver.ChromeOptions()

if sys.platform == 'darwin':
# MacOS
if os.path.exists("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"):
options.binary_location = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
elif os.path.exists("/Applications/Chrome.app/Contents/MacOS/Google Chrome"):
options.binary_location = "/Applications/Chrome.app/Contents/MacOS/Google Chrome"
elif 'linux' in sys.platform:
# Linux
options.binary_location = which('google-chrome') or which('chrome') or which('chromium')

def authentication(
client_id=None,
redirect_uri=None,
tdauser=None,
tdapass=None):
# handles arguments or loading config from .env
if client_id is None:
tda_config = TDAConfigProvider.get_config()
else:
tda_config = TDAConfig(
client_id,
redirect_uri,
tdauser,
tdapass
)
# Windows
if os.path.exists('C:/Program Files (x86)/Google/Chrome/Application/chrome.exe'):
options.binary_location = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe'
elif os.path.exists('C:/Program Files/Google/Chrome/Application/chrome.exe'):
options.binary_location = 'C:/Program Files/Google/Chrome/Application/chrome.exe'

chrome_driver_binary = which('chromedriver') or "/usr/local/bin/chromedriver"
driver = webdriver.Chrome(chrome_driver_binary, chrome_options=options)

return FormExecutioner(
tda_config,
WebDriverProvider.get_web_driver()).get_token()
driver.get(url)

# Set tdauser and tdapass from environemnt if TDAUSER and TDAPASS environment variables were defined
tdauser = tdauser or os.environ.get('TDAUSER', '')
tdapass = tdapass or os.environ.get('TDAPASS', '')

# Fully automated oauth2 authentication (if tdauser and tdapass were intputed into the function, or found as
# environment variables)
if tdauser and tdapass:
ubox = driver.find_element_by_id('username')
pbox = driver.find_element_by_id('password')
ubox.send_keys(tdauser)
pbox.send_keys(tdapass)
driver.find_element_by_id('accept').click()

driver.find_element_by_id('accept').click()
while True:
try:
code = up.unquote(driver.current_url.split('code=')[1])
if code != '':
break
else:
time.sleep(2)
except (TypeError, IndexError):
pass
else:
input('after giving access, hit enter to continue')
code = up.unquote(driver.current_url.split('code=')[1])

driver.close()

resp = requests.post('https://api.tdameritrade.com/v1/oauth2/token',
headers={'Content-Type': 'application/x-www-form-urlencoded'},
data={'grant_type': 'authorization_code',
'refresh_token': '',
'access_type': 'offline',
'code': code,
'client_id': client_id,
'redirect_uri': redirect_uri})
if resp.status_code != 200:
raise Exception('Could not authenticate!')
return resp.json()


def access_token(refresh_token, client_id):
Expand All @@ -33,13 +86,7 @@ def access_token(refresh_token, client_id):
'refresh_token': refresh_token,
'client_id': client_id})
if resp.status_code != 200:

# Attempt to refresh token via web flow
token = authentication()
if token == "" or token is None:
raise Exception('Could not authenticate!')
else:
return token
raise Exception('Could not authenticate!')
return resp.json()


Expand Down
108 changes: 0 additions & 108 deletions tdameritrade/auth/auth_form_executioner.py

This file was deleted.

51 changes: 0 additions & 51 deletions tdameritrade/auth/tda_config_provider.py

This file was deleted.

19 changes: 0 additions & 19 deletions tdameritrade/auth/web_driver_provider.py

This file was deleted.

0 comments on commit 45124cb

Please sign in to comment.