Skip to content

Commit

Permalink
Merge pull request #423 from BarraQDA/master
Browse files Browse the repository at this point in the history
Reworked @bryanlandia extension to allow application-only authentication
  • Loading branch information
jeremylow committed Mar 29, 2017
2 parents e02e9b8 + c71c197 commit fa548ce
Showing 1 changed file with 45 additions and 16 deletions.
61 changes: 45 additions & 16 deletions twitter/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import base64
import re
import requests
from requests_oauthlib import OAuth1
from requests_oauthlib import OAuth1, OAuth2
import io
import warnings
from uuid import uuid4
Expand Down Expand Up @@ -144,6 +144,7 @@ def __init__(self,
consumer_secret=None,
access_token_key=None,
access_token_secret=None,
application_only_auth=False,
input_encoding=None,
request_headers=None,
cache=DEFAULT_CACHE,
Expand All @@ -170,6 +171,9 @@ def __init__(self,
access_token_secret (str):
The oAuth access token's secret, also retrieved
from the get_access_token.py run.
application_only_auth:
Use Application-Only Auth instead of User Auth.
Defaults to False [Optional]
input_encoding (str, optional):
The encoding used to encode input strings.
request_header (dict, optional):
Expand Down Expand Up @@ -259,16 +263,12 @@ def __init__(self,
"strongly advised to increase it above 16384"
))

if consumer_key is not None and (access_token_key is None or
access_token_secret is None):
print('Twitter now requires an oAuth Access Token for API calls. '
'If you\'re using this library from a command line utility, '
'please run the included get_access_token.py tool to '
'generate one.', file=sys.stderr)
if (consumer_key and not
(application_only_auth or all([access_token_key, access_token_secret]))):
raise TwitterError({'message': "Missing oAuth Consumer Key or Access Token"})

raise TwitterError({'message': "Twitter requires oAuth Access Token for all API access"})

self.SetCredentials(consumer_key, consumer_secret, access_token_key, access_token_secret)
self.SetCredentials(consumer_key, consumer_secret, access_token_key, access_token_secret,
application_only_auth)

if debugHTTP:
import logging
Expand All @@ -282,11 +282,33 @@ def __init__(self,
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

def GetAppOnlyAuthToken(self, consumer_key, consumer_secret):
"""
Generate a Bearer Token from consumer_key and consumer_secret
"""
from urllib import quote_plus
import base64

key = quote_plus(consumer_key)
secret = quote_plus(consumer_secret)
bearer_token = base64.b64encode('{}:{}'.format(key, secret) )

post_headers = {
'Authorization': 'Basic '+bearer_token,
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
res = requests.post(url='https://api.twitter.com/oauth2/token',
data={'grant_type':'client_credentials'},
headers=post_headers)
bearer_creds = res.json()
return bearer_creds

def SetCredentials(self,
consumer_key,
consumer_secret,
access_token_key=None,
access_token_secret=None):
access_token_secret=None,
application_only_auth=False):
"""Set the consumer_key and consumer_secret for this instance
Args:
Expand All @@ -300,17 +322,23 @@ def SetCredentials(self,
access_token_secret:
The oAuth access token's secret, also retrieved
from the get_access_token.py run.
application_only_auth:
Whether to generate a bearer token and use Application-Only Auth
"""
self._consumer_key = consumer_key
self._consumer_secret = consumer_secret
self._access_token_key = access_token_key
self._access_token_secret = access_token_secret
auth_list = [consumer_key, consumer_secret,
access_token_key, access_token_secret]

if all(auth_list):
self.__auth = OAuth1(consumer_key, consumer_secret,
access_token_key, access_token_secret)
if application_only_auth:
self._bearer_token = self.GetAppOnlyAuthToken(consumer_key, consumer_secret)
self.__auth = OAuth2(token=self._bearer_token)
else:
auth_list = [consumer_key, consumer_secret,
access_token_key, access_token_secret]
if all(auth_list):
self.__auth = OAuth1(consumer_key, consumer_secret,
access_token_key, access_token_secret)

self._config = None

Expand Down Expand Up @@ -353,6 +381,7 @@ def ClearCredentials(self):
self._consumer_secret = None
self._access_token_key = None
self._access_token_secret = None
self._bearer_token = None
self.__auth = None # for request upgrade

def GetSearch(self,
Expand Down

0 comments on commit fa548ce

Please sign in to comment.