requests-oauthlib-0.8.0/0000755000076500000240000000000013050617554015304 5ustar corystaff00000000000000requests-oauthlib-0.8.0/AUTHORS.rst0000644000076500000240000000127512417777126017200 0ustar corystaff00000000000000Requests-oauthlib is written and maintained by Kenneth Reitz and various contributors: Development Lead ---------------- - Kenneth Reitz Patches and Suggestions ----------------------- - Cory Benfield - Ib Lundgren - Devin Sevilla - Imad Mouhtassem - Johan Euphrosine - Johannes Spielmann - Martin Trigaux - Matt McClure - Mikhail Sobolev - Paul Bonser - Vinay Raikar - kracekumar - David Baumgold requests-oauthlib-0.8.0/docs/0000755000076500000240000000000013050617553016233 5ustar corystaff00000000000000requests-oauthlib-0.8.0/docs/api.rst0000644000076500000240000000062612201441447017534 0ustar corystaff00000000000000.. _api: Developer Interface =================== .. module:: requests_oauthlib OAuth 1.0 --------- .. autoclass:: OAuth1 :members: OAuth 1.0 Session ----------------- .. autoclass:: OAuth1Session :members: OAuth 2.0 --------- .. autoclass:: OAuth2 :members: .. autoclass:: TokenUpdated :members: OAuth 2.0 Session ----------------- .. autoclass:: OAuth2Session :members: requests-oauthlib-0.8.0/docs/conf.py0000644000076500000240000002045112417777126017545 0ustar corystaff00000000000000# -*- coding: utf-8 -*- # # Requests-OAuthlib documentation build configuration file, created by # sphinx-quickstart on Fri May 10 11:49:01 2013. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('..')) from requests_oauthlib import __version__ # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Requests-OAuthlib' copyright = u'2014, Kenneth Reitz' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = __version__ # The full version, including alpha/beta/rc tags. release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Requests-OAuthlibdoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'Requests-OAuthlib.tex', u'Requests-OAuthlib Documentation', u'Requests-OAuthlib Contributors', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'requests-oauthlib', u'Requests-OAuthlib Documentation', [u'Requests-OAuthlib Contributors'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'Requests-OAuthlib', u'Requests-OAuthlib Documentation', u'Requests-OAuthlib Contributors', 'Requests-OAuthlib', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('http://python.readthedocs.org/en/latest/', None), 'requests': ('http://requests.readthedocs.org/en/latest/', None), 'oauthlib': ('http://oauthlib.readthedocs.org/en/latest/', None), } requests-oauthlib-0.8.0/docs/examples/0000755000076500000240000000000013050617553020051 5ustar corystaff00000000000000requests-oauthlib-0.8.0/docs/examples/bitbucket.rst0000644000076500000240000000342312315510554022555 0ustar corystaff00000000000000Bitbucket OAuth 1 Tutorial ========================== Start with setting up a new consumer by following the instructions on `Bitbucket`_. When you have obtained a ``key`` and a ``secret`` you can try out the command line interactive example below. .. _`Bitbucket`: https://confluence.atlassian.com/display/BITBUCKET/OAuth+on+Bitbucket .. code-block:: pycon # Credentials you get from adding a new consumer in bitbucket -> manage account # -> integrated applications. >>> key = '' >>> secret = '' >>> # OAuth endpoints given in the Bitbucket API documentation >>> request_token_url = 'https://bitbucket.org/!api/1.0/oauth/request_token' >>> authorization_base_url = 'https://bitbucket.org/!api/1.0/oauth/authenticate' >>> access_token_url = 'https://bitbucket.org/!api/1.0/oauth/access_token' >>> # 2. Fetch a request token >>> from requests_oauthlib import OAuth1Session >>> bitbucket = OAuth1Session(key, client_secret=secret, >>> callback_uri='http://127.0.0.1/cb') >>> bitbucket.fetch_request_token(request_token_url) >>> # 3. Redirect user to Bitbucket for authorization >>> authorization_url = bitbucket.authorization_url(authorization_base_url) >>> print 'Please go here and authorize,', authorization_url >>> # 4. Get the authorization verifier code from the callback url >>> redirect_response = raw_input('Paste the full redirect URL here:') >>> bitbucket.parse_authorization_response(redirect_response) >>> # 5. Fetch the access token >>> bitbucket.fetch_access_token(access_token_url) >>> # 6. Fetch a protected resource, i.e. user profile >>> r = bitbucket.get('https://bitbucket.org/api/1.0/user') >>> print r.content requests-oauthlib-0.8.0/docs/examples/examples.rst0000644000076500000240000000027113000127600022401 0ustar corystaff00000000000000Examples ========= .. toctree:: :maxdepth: 2 bitbucket github google facebook linkedin outlook tumblr real_world_example real_world_example_with_refresh requests-oauthlib-0.8.0/docs/examples/facebook.rst0000644000076500000240000000331512315510554022352 0ustar corystaff00000000000000Facebook OAuth 2 Tutorial ========================= Setup a new web application client in the `Facebook APP console`_ When you have obtained a ``client_id``, ``client_secret`` and registered a callback URL then you can try out the command line interactive example below. .. _`Facebook APP console`: https://developers.facebook.com/apps .. code-block:: pycon >>> # Credentials you get from registering a new application >>> client_id = '' >>> client_secret = '' >>> # OAuth endpoints given in the Facebook API documentation >>> authorization_base_url = 'https://www.facebook.com/dialog/oauth' >>> token_url = 'https://graph.facebook.com/oauth/access_token' >>> redirect_uri = 'https://localhost/' # Should match Site URL >>> from requests_oauthlib import OAuth2Session >>> from requests_oauthlib.compliance_fixes import facebook_compliance_fix >>> facebook = OAuth2Session(client_id, redirect_uri=redirect_uri) >>> facebook = facebook_compliance_fix(facebook) >>> # Redirect user to Facebook for authorization >>> authorization_url, state = facebook.authorization_url(authorization_base_url) >>> print 'Please go here and authorize,', authorization_url >>> # Get the authorization verifier code from the callback url >>> redirect_response = raw_input('Paste the full redirect URL here:') >>> # Fetch the access token >>> facebook.fetch_token(token_url, client_secret=client_secret, ..> authorization_response=redirect_response) >>> # Fetch a protected resource, i.e. user profile >>> r = facebook.get('https://graph.facebook.com/me?') >>> print r.content requests-oauthlib-0.8.0/docs/examples/github.rst0000644000076500000240000000263412315510554022066 0ustar corystaff00000000000000GitHub OAuth 2 Tutorial ========================== Setup credentials following the instructions on `GitHub`_. When you have obtained a ``client_id`` and a ``client_secret`` you can try out the command line interactive example below. .. _`GitHub`: https://github.com/settings/applications/new .. code-block:: pycon >>> # Credentials you get from registering a new application >>> client_id = '' >>> client_secret = '' >>> # OAuth endpoints given in the GitHub API documentation >>> authorization_base_url = 'https://github.com/login/oauth/authorize' >>> token_url = 'https://github.com/login/oauth/access_token' >>> from requests_oauthlib import OAuth2Session >>> github = OAuth2Session(client_id) >>> # Redirect user to GitHub for authorization >>> authorization_url, state = github.authorization_url(authorization_base_url) >>> print 'Please go here and authorize,', authorization_url >>> # Get the authorization verifier code from the callback url >>> redirect_response = raw_input('Paste the full redirect URL here:') >>> # Fetch the access token >>> github.fetch_token(token_url, client_secret=client_secret, >>> authorization_response=redirect_response) >>> # Fetch a protected resource, i.e. user profile >>> r = github.get('https://api.github.com/user') >>> print r.content requests-oauthlib-0.8.0/docs/examples/google.rst0000644000076500000240000000360612767453154022075 0ustar corystaff00000000000000Google OAuth 2 Tutorial ========================== Setup a new web project in the `Google Cloud Console`_ When you have obtained a ``client_id``, ``client_secret`` and registered a callback URL then you can try out the command line interactive example below. .. _`Google Cloud Console`: https://cloud.google.com/console/project .. code-block:: pycon >>> # Credentials you get from registering a new application >>> client_id = '.apps.googleusercontent.com' >>> client_secret = '' >>> redirect_uri = 'https://your.registered/callback' >>> # OAuth endpoints given in the Google API documentation >>> authorization_base_url = "https://accounts.google.com/o/oauth2/v2/auth" >>> token_url = "https://www.googleapis.com/oauth2/v4/token" >>> scope = [ ... "https://www.googleapis.com/auth/userinfo.email", ... "https://www.googleapis.com/auth/userinfo.profile" ... ] >>> from requests_oauthlib import OAuth2Session >>> google = OAuth2Session(client_id, scope=scope, redirect_uri=redirect_uri) >>> # Redirect user to Google for authorization >>> authorization_url, state = google.authorization_url(authorization_base_url, ... # offline for refresh token ... # force to always make user click authorize ... access_type="offline", approval_prompt="force") >>> print 'Please go here and authorize,', authorization_url >>> # Get the authorization verifier code from the callback url >>> redirect_response = raw_input('Paste the full redirect URL here:') >>> # Fetch the access token >>> google.fetch_token(token_url, client_secret=client_secret, ... authorization_response=redirect_response) >>> # Fetch a protected resource, i.e. user profile >>> r = google.get('https://www.googleapis.com/oauth2/v1/userinfo') >>> print r.content requests-oauthlib-0.8.0/docs/examples/linkedin.rst0000644000076500000240000000316712315510554022403 0ustar corystaff00000000000000LinkedIn OAuth 2 Tutorial ========================= Setup credentials following the instructions on `LinkedIn`_. When you have obtained a ``client_id`` and a ``client_secret`` you can try out the command line interactive example below. .. _`LinkedIn`: https://www.linkedin.com/secure/developer .. code-block:: pycon >>> # Credentials you get from registering a new application >>> client_id = '' >>> client_secret = '' >>> # OAuth endpoints given in the LinkedIn API documentation >>> authorization_base_url = 'https://www.linkedin.com/uas/oauth2/authorization' >>> token_url = 'https://www.linkedin.com/uas/oauth2/accessToken' >>> from requests_oauthlib import OAuth2Session >>> from requests_oauthlib.compliance_fixes import linkedin_compliance_fix >>> linkedin = OAuth2Session(client_id, redirect_uri='http://127.0.0.1') >>> linkedin = linkedin_compliance_fix(linkedin) >>> # Redirect user to LinkedIn for authorization >>> authorization_url, state = linkedin.authorization_url(authorization_base_url) >>> print 'Please go here and authorize,', authorization_url >>> # Get the authorization verifier code from the callback url >>> redirect_response = raw_input('Paste the full redirect URL here:') >>> # Fetch the access token >>> linkedin.fetch_token(token_url, client_secret=client_secret, ... authorization_response=redirect_response) >>> # Fetch a protected resource, i.e. user profile >>> r = linkedin.get('https://api.linkedin.com/v1/people/~') >>> print r.content requests-oauthlib-0.8.0/docs/examples/mediawiki.rst0000644000076500000240000001435512344337640022557 0ustar corystaff00000000000000MediaWiki OAuth 1 Tutorial ========================== Start with setting up a new consumer by following the instructions on `MediaWiki`_. When you have obtained a ``key`` and a ``secret`` you can try out the command line interactive example below. You'll also have to set a callback url while registering. See also this library implementing all the flow below, plus the `/identify` custom call: `mwoauth`_. .. _`MediaWiki`: https://www.mediawiki.org/wiki/Extension:OAuth#Using_OAuth .. _`mwoauth`: https://github.com/halfak/MediaWiki-OAuth Using OAuth1Session ------------------- .. code-block:: python from requests_oauthlib import OAuth1Session # Get the anonymous oauth_token and secret request_token_url = 'https://www.mediawiki.org/w/index.php?title=Special%3aOAuth%2finitiate' # Note the custom callback_uri arg! oauth = OAuth1Session(CLIENT_KEY, client_secret=CLIENT_SECRET, callback_uri='oob') fetch_response = oauth.fetch_request_token(request_token_url) # fetch_response: {u'oauth_token_secret': u'3768a660fcdc5ba958268decc11bf590', u'oauth_token': u'5d684692fe129665c9f967f54bbc525d', u'oauth_callback_confirmed': u'true'} resource_owner_key = fetch_response.get('oauth_token') resource_owner_secret = fetch_response.get('oauth_token_secret') # Redirect the user to /authorize and get the callback base_authorization_url = 'https://www.mediawiki.org/wiki/Special:OAuth/authorize' # Note the extra oauth_consumer_key argument! authorization_url = oauth.authorization_url(base_authorization_url, oauth_consumer_key=CLIENT_KEY) print 'Please go here and authorize,', authorization_url # OUT: Please go here and authorize, https://www.mediawiki.org/wiki/Special:OAuth/authorize?oauth_consumer_key=85c9f176fcb96952f1b3b967cbb4ef9e&oauth_token=5d684692fe129665c9f967f54bbc525d redirect_response = raw_input('Paste the full redirect URL here: ') # OUT: Paste the full redirect URL here: https://snuggle.wmflabs.org/oauth/callback?oauth_verifier=7f98e940b58745e14602e0522c7e5e90&oauth_token=5d684692fe129665c9f967f54bbc525d oauth_response = oauth.parse_authorization_response(redirect_response) # oauth_response: {u'oauth_token': u'5d684692fe129665c9f967f54bbc525d', u'oauth_verifier': u'7f98e940b58745e14602e0522c7e5e90'} verifier = oauth_response.get('oauth_verifier') # Get the final oauth_token and secret access_token_url = 'https://www.mediawiki.org/w/index.php?title=Special%3aOAuth%2ftoken' oauth = OAuth1Session(CLIENT_KEY, client_secret=CLIENT_SECRET, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret, verifier=verifier) oauth_tokens = oauth.fetch_access_token(access_token_url) # oauth_tokens: {u'oauth_token_secret': u'10e284c0ce48c2c2c6ce4f58fca358d6ff495a55', u'oauth_token': u'2f227cce369edad1ff3880bb4dab84f2', u'oauth_callback_confirmed': u'true'} resource_owner_key = oauth_tokens.get('oauth_token') resource_owner_secret = oauth_tokens.get('oauth_token_secret') # Make authenticated calls to the API data = {'action': 'query', 'meta': 'userinfo', 'format': 'json'} from urllib import urlencode url = 'https://www.mediawiki.org/w/api.php?' + urlencode(data) oauth = OAuth1Session(CLIENT_KEY, client_secret=CLIENT_SECRET, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret) r = oauth.get(url) r.json() # OUT: {u'query': {u'userinfo': {u'id': 32663, u'name': u'FiloSottile'}}} Using OAuth1 auth helper (stateless) ------------------------------------ .. code-block:: python import requests from requests_oauthlib import OAuth1 # Get the anonymous oauth_token and secret request_token_url = 'https://www.mediawiki.org/w/index.php?title=Special%3aOAuth%2finitiate' oauth = OAuth1(CLIENT_KEY, client_secret=CLIENT_SECRET, callback_uri='oob') r = requests.post(url=request_token_url, auth=oauth) r.content # OUT: 'oauth_token=d44ce3a59d2d8cbcc0ebbae4d0157f4a&oauth_token_secret=a10676b7e6c4ae44db1411d1dece9267&oauth_callback_confirmed=true' from urlparse import parse_qs credentials = parse_qs(r.content) resource_owner_key = credentials.get('oauth_token')[0] resource_owner_secret = credentials.get('oauth_token_secret')[0] # Redirect the user to /authorize and get the callback base_authorization_url = 'https://www.mediawiki.org/wiki/Special:OAuth/authorize' authorize_url = base_authorization_url + '?oauth_token=' + resource_owner_key + '&oauth_consumer_key=' + CLIENT_KEY print 'Please go here and authorize,', authorize_url # OUT: Please go here and authorize, https://www.mediawiki.org/wiki/Special:OAuth/authorize?oauth_token=d44ce3a59d2d8cbcc0ebbae4d0157f4a&oauth_consumer_key=85c9f176fcb96952f1b3b967cbb4ef9e callback_qs = raw_input('Please input the callback query string: ') # OUT: Please input the callback query string: oauth_verifier=5eb313f9b4006e922c3e4a7d2493df98&oauth_token=d44ce3a59d2d8cbcc0ebbae4d0157f4a callback_data = parse_qs(callback_qs) verifier = callback_data.get('oauth_verifier')[0] assert callback_data.get('oauth_token')[0] == resource_owner_key # Get the final oauth_token and secret access_token_url = 'https://www.mediawiki.org/w/index.php?title=Special%3aOAuth%2ftoken' oauth = OAuth1(CLIENT_KEY, client_secret=CLIENT_SECRET, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret, verifier=verifier) r = requests.post(url=access_token_url, auth=oauth) r.content # OUT: 'oauth_token=2f227cce369edad1ff3880bb4dab84f2&oauth_token_secret=10e284c0ce48c2c2c6ce4f58fca358d6ff495a55&oauth_callback_confirmed=true' credentials = parse_qs(r.content) resource_owner_key = credentials.get('oauth_token')[0] resource_owner_secret = credentials.get('oauth_token_secret')[0] # Make authenticated calls to the API data = {'action': 'query', 'meta': 'userinfo', 'format': 'json'} from urllib import urlencode url = 'https://www.mediawiki.org/w/api.php?' + urlencode(data) oauth = OAuth1(CLIENT_KEY, client_secret=CLIENT_SECRET, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret) r = requests.get(url=url, auth=oauth) r.json() # OUT: {u'query': {u'userinfo': {u'id': 32663, u'name': u'FiloSottile'}}} requests-oauthlib-0.8.0/docs/examples/outlook.rst0000644000076500000240000000344213000127600022262 0ustar corystaff00000000000000Outlook Calender OAuth 2 Tutorial ========================== Create a new web application client in the `Microsoft Application Registration Portal`_ When you have obtained a ``client_id``, ``client_secret`` and registered a callback URL then you can try out the command line interactive example below. .. _`Outlook App console`: https://apps.dev.microsoft.com .. code-block:: pycon >>> # This information is obtained upon registration of a new Outlook Application >>> client_id = '' >>> client_secret = '' >>> # OAuth endpoints given in Outlook API documentation >>> authorization_base_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' >>> token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token' >>> scope = ['https://outlook.office.com/calendars.readwrite'] >>> redirect_uri = 'https://localhost/' # Should match Site URL >>> from requests_oauthlib import OAuth2Session >>> outlook = OAuth2Session(client_id,scope=scope,redirect_uri=redirect_uri) >>> # Redirect the user owner to the OAuth provider (i.e. Outlook) using an URL with a few key OAuth parameters. >>> authorization_url, state = outlook.authorization_url(authorization_base_url) >>> print 'Please go here and authorize,', authorization_url >>> # Get the authorization verifier code from the callback url >>> redirect_response = raw_input('Paste the full redirect URL here:') >>> # Fetch the access token >>> token = outlook.fetch_token(token_url,client_secret=client_secret,authorization_response=redirect_response) >>> # Fetch a protected resource, i.e. calender information >>> o = outlook.get('https://outlook.office.com/api/v1.0/me/calendars') >>> print o.content requests-oauthlib-0.8.0/docs/examples/real_world_example.rst0000644000076500000240000000755412633522042024455 0ustar corystaff00000000000000.. _real_example: Web App Example of OAuth 2 web application flow =============================================== OAuth is commonly used by web applications. The example below shows what such a web application might look like using the `Flask web framework `_ and GitHub as a provider. It should be easily transferrable to any web framework. .. note:: While the flow remains the same across most providers, Github is special in that the ``redirect_uri`` parameter is optional. This means that it may be necessary to explicitly pass a redirect_uri to the ``OAuth2Session`` object (e.g. when creating a custom OAuthProvider with ``flask-oauthlib``). .. code-block:: python from requests_oauthlib import OAuth2Session from flask import Flask, request, redirect, session, url_for from flask.json import jsonify import os app = Flask(__name__) # This information is obtained upon registration of a new GitHub OAuth # application here: https://github.com/settings/applications/new client_id = "" client_secret = "" authorization_base_url = 'https://github.com/login/oauth/authorize' token_url = 'https://github.com/login/oauth/access_token' @app.route("/") def demo(): """Step 1: User Authorization. Redirect the user/resource owner to the OAuth provider (i.e. Github) using an URL with a few key OAuth parameters. """ github = OAuth2Session(client_id) authorization_url, state = github.authorization_url(authorization_base_url) # State is used to prevent CSRF, keep this for later. session['oauth_state'] = state return redirect(authorization_url) # Step 2: User authorization, this happens on the provider. @app.route("/callback", methods=["GET"]) def callback(): """ Step 3: Retrieving an access token. The user has been redirected back from the provider to your registered callback URL. With this redirection comes an authorization code included in the redirect URL. We will use that to obtain an access token. """ github = OAuth2Session(client_id, state=session['oauth_state']) token = github.fetch_token(token_url, client_secret=client_secret, authorization_response=request.url) # At this point you can fetch protected resources but lets save # the token and show how this is done from a persisted token # in /profile. session['oauth_token'] = token return redirect(url_for('.profile')) @app.route("/profile", methods=["GET"]) def profile(): """Fetching a protected resource using an OAuth 2 token. """ github = OAuth2Session(client_id, token=session['oauth_token']) return jsonify(github.get('https://api.github.com/user').json()) if __name__ == "__main__": # This allows us to use a plain HTTP callback os.environ['DEBUG'] = "1" app.secret_key = os.urandom(24) app.run(debug=True) This example is lovingly borrowed from `this gist `_. **N.B:** You should note that Oauth2 works through SSL layer. If your server is not parametrized to allow HTTPS, the *fetch_token* method will raise an **oauthlib.oauth2.rfc6749.errors.InsecureTransportError**. Most people don't set SSL on their server while testing and that is fine. You can disable this check in two ways: 1. By setting an environment variable. .. code-block:: bash export OAUTHLIB_INSECURE_TRANSPORT=1 2. Equivalent to above you can set this in Python (if you have problems setting environment variables) .. code-block:: python # Somewhere in webapp_example.py, before the app.run for example import os os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' requests-oauthlib-0.8.0/docs/examples/real_world_example_with_refresh.rst0000644000076500000240000001460512344337640027230 0ustar corystaff00000000000000.. _token_refresh: Refreshing tokens in OAuth 2 ============================ OAuth 2 providers may allow you to refresh access tokens using refresh tokens. Commonly, only clients that authenticate may refresh tokens, e.g. web applications but not javascript clients. The provider will mention whether they allow token refresh in their API documentation and if you see a "refresh_token" in your token response you are good to go. This example shows how a simple web application (using the `Flask web framework `_) can refresh Google OAuth 2 tokens. It should be trivial to transfer to any other web framework and provider. .. code-block:: python from pprint import pformat from time import time from flask import Flask, request, redirect, session, url_for from flask.json import jsonify import requests from requests_oauthlib import OAuth2Session app = Flask(__name__) # This information is obtained upon registration of a new Google OAuth # application at https://code.google.com/apis/console client_id = "" client_secret = "" redirect_uri = 'https://your.registered/callback' # Uncomment for detailed oauthlib logs #import logging #import sys #log = logging.getLogger('oauthlib') #log.addHandler(logging.StreamHandler(sys.stdout)) #log.setLevel(logging.DEBUG) # OAuth endpoints given in the Google API documentation authorization_base_url = "https://accounts.google.com/o/oauth2/auth" token_url = "https://accounts.google.com/o/oauth2/token" refresh_url = token_url # True for Google but not all providers. scope = [ "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", ] @app.route("/") def demo(): """Step 1: User Authorization. Redirect the user/resource owner to the OAuth provider (i.e. Google) using an URL with a few key OAuth parameters. """ google = OAuth2Session(client_id, scope=scope, redirect_uri=redirect_uri) authorization_url, state = google.authorization_url(authorization_base_url, # offline for refresh token # force to always make user click authorize access_type="offline", approval_prompt="force") # State is used to prevent CSRF, keep this for later. session['oauth_state'] = state return redirect(authorization_url) # Step 2: User authorization, this happens on the provider. @app.route("/callback", methods=["GET"]) def callback(): """ Step 3: Retrieving an access token. The user has been redirected back from the provider to your registered callback URL. With this redirection comes an authorization code included in the redirect URL. We will use that to obtain an access token. """ google = OAuth2Session(client_id, redirect_uri=redirect_uri, state=session['oauth_state']) token = google.fetch_token(token_url, client_secret=client_secret, authorization_response=request.url) # We use the session as a simple DB for this example. session['oauth_token'] = token return redirect(url_for('.menu')) @app.route("/menu", methods=["GET"]) def menu(): """""" return """

Congratulations, you have obtained an OAuth 2 token!

What would you like to do next?

        %s
        
""" % pformat(session['oauth_token'], indent=4) @app.route("/profile", methods=["GET"]) def profile(): """Fetching a protected resource using an OAuth 2 token. """ google = OAuth2Session(client_id, token=session['oauth_token']) return jsonify(google.get('https://www.googleapis.com/oauth2/v1/userinfo').json()) @app.route("/automatic_refresh", methods=["GET"]) def automatic_refresh(): """Refreshing an OAuth 2 token using a refresh token. """ token = session['oauth_token'] # We force an expiration by setting expired at in the past. # This will trigger an automatic refresh next time we interact with # Googles API. token['expires_at'] = time() - 10 extra = { 'client_id': client_id, 'client_secret': client_secret, } def token_updater(token): session['oauth_token'] = token google = OAuth2Session(client_id, token=token, auto_refresh_kwargs=extra, auto_refresh_url=refresh_url, token_updater=token_updater) # Trigger the automatic refresh jsonify(google.get('https://www.googleapis.com/oauth2/v1/userinfo').json()) return jsonify(session['oauth_token']) @app.route("/manual_refresh", methods=["GET"]) def manual_refresh(): """Refreshing an OAuth 2 token using a refresh token. """ token = session['oauth_token'] extra = { 'client_id': client_id, 'client_secret': client_secret, } google = OAuth2Session(client_id, token=token) session['oauth_token'] = google.refresh_token(refresh_url, **extra) return jsonify(session['oauth_token']) @app.route("/validate", methods=["GET"]) def validate(): """Validate a token with the OAuth provider Google. """ token = session['oauth_token'] # Defined at https://developers.google.com/accounts/docs/OAuth2LoginV1#validatingtoken validate_url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?' 'access_token=%s' % token['access_token']) # No OAuth2Session is needed, just a plain GET request return jsonify(requests.get(validate_url).json()) if __name__ == "__main__": # This allows us to use a plain HTTP callback import os os.environ['DEBUG'] = "1" app.secret_key = os.urandom(24) app.run(debug=True) requests-oauthlib-0.8.0/docs/examples/tumblr.rst0000644000076500000240000000274712344337640022123 0ustar corystaff00000000000000Tumblr OAuth1 Tutorial ====================== Register a new application on the `tumblr application page`_. Enter a call back url (can just be http://www.tumblr.com/dashboard) and get the ``OAuth Consumer Key`` and ``Secret Key``. .. _`tumblr application page`: http://www.tumblr.com/oauth/apps .. code-block:: pycon >>> # Credentials from the application page >>> key = '' >>> secret = '' >>> # OAuth URLs given on the application page >>> request_token_url = 'http://www.tumblr.com/oauth/request_token' >>> authorization_base_url = 'http://www.tumblr.com/oauth/authorize' >>> access_token_url = 'http://www.tumblr.com/oauth/access_token' >>> # Fetch a request token >>> from requests_oauthlib import OAuth1Session >>> tumblr = OAuth1Session(key, client_secret=secret, callback_uri='http://www.tumblr.com/dashboard') >>> tumblr.fetch_request_token(request_token_url) >>> # Link user to authorization page >>> authorization_url = tumblr.authorization_url(authorization_base_url) >>> print 'Please go here and authorize,', authorization_url >>> # Get the verifier code from the URL >>> redirect_response = raw_input('Paste the full redirect URL here: ') >>> tumblr.parse_authorization_response(redirect_response) >>> # Fetch the access token >>> tumblr.fetch_access_token(access_token_url) >>> # Fetch a protected resource >>> print tumblr.get('http://api.tumblr.com/v2/user/dashboard') requests-oauthlib-0.8.0/docs/index.rst0000644000076500000240000000427312661635562020111 0ustar corystaff00000000000000.. Requests-OAuthlib documentation master file, created by sphinx-quickstart on Fri May 10 11:49:01 2013. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Requests-OAuthlib: OAuth for Humans =================================== Requests-OAuthlib uses the Python `Requests `_ and `OAuthlib `_ libraries to provide an easy-to-use Python interface for building OAuth1 and OAuth2 clients. Overview -------- A simple Flask application which connects to the Github OAuth2 API looks approximately like this: .. code-block:: python from requests_oauthlib import OAuth2Session from flask import Flask, request, redirect, session, url_for from flask.json import jsonify # This information is obtained upon registration of a new GitHub client_id = "" client_secret = "" authorization_base_url = 'https://github.com/login/oauth/authorize' token_url = 'https://github.com/login/oauth/access_token' @app.route("/login") def login(): github = OAuth2Session(client_id) authorization_url, state = github.authorization_url(authorization_base_url) # State is used to prevent CSRF, keep this for later. session['oauth_state'] = state return redirect(authorization_url) @app.route("/callback") def callback(): github = OAuth2Session(client_id, state=session['oauth_state']) token = github.fetch_token(token_url, client_secret=client_secret, authorization_response=request.url) return jsonify(github.get('https://api.github.com/user').json()) The above is a truncated example. A full working example is available here: :ref:`real_example` Installation ============ Requests-OAuthlib can be installed with `pip `_: :: $ pip install requests_oauthlib Getting Started: ================ .. toctree:: :maxdepth: 2 oauth1_workflow oauth2_workflow examples/examples api Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` requests-oauthlib-0.8.0/docs/make.bat0000644000076500000240000001510312201441447017632 0ustar corystaff00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Requests-OAuthlib.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Requests-OAuthlib.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end requests-oauthlib-0.8.0/docs/Makefile0000644000076500000240000001522612201441447017673 0ustar corystaff00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Requests-OAuthlib.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Requests-OAuthlib.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Requests-OAuthlib" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Requests-OAuthlib" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." requests-oauthlib-0.8.0/docs/oauth1_workflow.rst0000644000076500000240000002115112222010711022077 0ustar corystaff00000000000000OAuth 1 Workflow ================ You will be forced to go through a few steps when you are using OAuth. Below is an example of the most common OAuth workflow using HMAC-SHA1 signed requests where the signature is supplied in the Authorization header. The example assumes an interactive prompt which is good for demonstration but in practice you will likely be using a web application (which makes authorizing much less awkward since you can simply redirect). The guide will show two ways of carrying out the OAuth1 workflow. One using the authentication helper OAuth1 and the alternative using OAuth1Session. The latter is usually more convenient and requires less code. Workflow example showing use of both OAuth1 and OAuth1Session ------------------------------------------------------------- 0. Manual client signup with the OAuth provider (i.e. Google, Twitter) to get a set of client credentials. Usually a client key and secret. Client might sometimes be referred to as consumer. For example: .. code-block:: pycon >>> # Using OAuth1Session >>> from requests_oauthlib import OAuth1Session >>> # Using OAuth1 auth helper >>> import requests >>> from requests_oauthlib import OAuth1 >>> client_key = '...' >>> client_secret = '...' 1. Obtain a request token which will identify you (the client) in the next step. At this stage you will only need your client key and secret. .. code-block:: pycon >>> request_token_url = 'https://api.twitter.com/oauth/request_token' >>> # Using OAuth1Session >>> oauth = OAuth1Session(client_key, client_secret=client_secret) >>> fetch_response = oauth.fetch_request_token(request_token_url) { "oauth_token": "Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik", "oauth_token_secret": "Kd75W4OQfb2oJTV0vzGzeXftVAwgMnEK9MumzYcM" } >>> resource_owner_key = fetch_response.get('oauth_token') >>> resource_owner_secret = fetch_response.get('oauth_token_secret') >>> # Using OAuth1 auth helper >>> oauth = OAuth1(client_key, client_secret=client_secret) >>> r = requests.post(url=request_token_url, auth=oauth) >>> r.content "oauth_token=Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik&oauth_token_secret=Kd75W4OQfb2oJTV0vzGzeXftVAwgMnEK9MumzYcM" >>> from urlparse import parse_qs >>> credentials = parse_qs(r.content) >>> resource_owner_key = credentials.get('oauth_token')[0] >>> resource_owner_secret = credentials.get('oauth_token_secret')[0] 2. Obtain authorization from the user (resource owner) to access their protected resources (images, tweets, etc.). This is commonly done by redirecting the user to a specific url to which you add the request token as a query parameter. Note that not all services will give you a verifier even if they should. Also the oauth_token given here will be the same as the one in the previous step. .. code-block:: pycon >>> base_authorization_url = 'https://api.twitter.com/oauth/authorize' >>> # Using OAuth1Session >>> authorization_url = oauth.authorization_url(base_authorization_url) >>> print 'Please go here and authorize,', authorization_url >>> redirect_response = raw_input('Paste the full redirect URL here: ') >>> oauth_response = oauth.parse_authorization_response(redirect_response) { "oauth_token": "Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik", "oauth_verifier": "sdflk3450FASDLJasd2349dfs" } >>> verifier = oauth_response.get('oauth_verifier') >>> # Using OAuth1 auth helper >>> authorize_url = base_authorization_url + '?oauth_token=' >>> authorize_url = authorize_url + resource_owner_key >>> print 'Please go here and authorize,', authorize_url >>> verifier = raw_input('Please input the verifier') 3. Obtain an access token from the OAuth provider. Save this token as it can be re-used later. In this step we will re-use most of the credentials obtained uptil this point. .. code-block:: pycon >>> access_token_url = 'https://api.twitter.com/oauth/access_token' >>> # Using OAuth1Session >>> oauth = OAuth1Session(client_key, client_secret=client_secret, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret, verifier=verifier) >>> oauth_tokens = oauth.fetch_access_token(access_token_url) { "oauth_token": "6253282-eWudHldSbIaelX7swmsiHImEL4KinwaGloHANdrY", "oauth_token_secret": "2EEfA6BG3ly3sR3RjE0IBSnlQu4ZrUzPiYKmrkVU" } >>> resource_owner_key = oauth_tokens.get('oauth_token') >>> resource_owner_secret = oauth_tokens.get('oauth_token_secret') >>> # Using OAuth1 auth helper >>> oauth = OAuth1(client_key, client_secret=client_secret, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret, verifier=verifier) >>> r = requests.post(url=access_token_url, auth=oauth) >>> r.content "oauth_token=6253282-eWudHldSbIaelX7swmsiHImEL4KinwaGloHANdrY&oauth_token_secret=2EEfA6BG3ly3sR3RjE0IBSnlQu4ZrUzPiYKmrkVU" >>> credentials = parse_qs(r.content) >>> resource_owner_key = credentials.get('oauth_token')[0] >>> resource_owner_secret = credentials.get('oauth_token_secret')[0] 4. Access protected resources. OAuth1 access tokens typically do not expire and may be re-used until revoked by the user or yourself. .. code-block:: pycon >>> protected_url = 'https://api.twitter.com/1/account/settings.json' >>> # Using OAuth1Session >>> oauth = OAuth1Session(client_key, client_secret=client_secret, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret) >>> r = oauth.get(protected_url) >>> # Using OAuth1 auth helper >>> oauth = OAuth1(client_key, client_secret=client_secret, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret) >>> r = requests.get(url=protected_url, auth=oauth) Signature placement - header, query or body? -------------------------------------------- OAuth takes many forms, so let's take a look at a few different forms: .. code-block:: python import requests from requests_oauthlib import OAuth1 url = u'https://api.twitter.com/1/account/settings.json' client_key = u'...' client_secret = u'...' resource_owner_key = u'...' resource_owner_secret = u'...' Header signing (recommended): .. code-block:: python headeroauth = OAuth1(client_key, client_secret, resource_owner_key, resource_owner_secret, signature_type='auth_header') r = requests.get(url, auth=headeroauth) Query signing: .. code-block:: python queryoauth = OAuth1(client_key, client_secret, resource_owner_key, resource_owner_secret, signature_type='query') r = requests.get(url, auth=queryoauth) Body signing: .. code-block:: python bodyoauth = OAuth1(client_key, client_secret, resource_owner_key, resource_owner_secret, signature_type='body') r = requests.post(url, auth=bodyoauth) Signature types - HMAC (most common), RSA, Plaintext ---------------------------------------------------- OAuth1 defaults to using HMAC and examples can be found in the previous sections. Plaintext work on the same credentials as HMAC and the only change you will need to make when using it is to add signature_type='PLAINTEXT' to the OAuth1 constructor: .. code-block:: python headeroauth = OAuth1(client_key, client_secret, resource_owner_key, resource_owner_secret, signature_method='PLAINTEXT') RSA is different in that it does not use client_secret nor resource_owner_secret. Instead it uses public and private keys. The public key is provided to the OAuth provider during client registration. The private key is used to sign requests. The previous section can be summarized as: .. code-block:: python key = open("your_rsa_key.pem").read() queryoauth = OAuth1(client_key, signature_method=SIGNATURE_RSA, rsa_key=key, signature_type='query') headeroauth = OAuth1(client_key, signature_method=SIGNATURE_RSA, rsa_key=key, signature_type='auth_header') bodyoauth = OAuth1(client_key, signature_method=SIGNATURE_RSA, rsa_key=key, signature_type='body') requests-oauthlib-0.8.0/docs/oauth2_workflow.rst0000644000076500000240000002225612620061233022116 0ustar corystaff00000000000000OAuth 2 Workflow ================ .. contents:: :depth: 3 :local: Introduction ------------ The following sections provide some example code that demonstrates some of the possible OAuth2 flows you can use with requests-oauthlib. We provide four examples: one for each of the grant types defined by the OAuth2 RFC. These grant types (or workflows) are the Authorization Code Grant (or Web Application Flow), the Implicit Grant (or Mobile Application Flow), the Resource Owner Password Credentials Grant (or, more succinctly, the Legacy Application Flow), and the Client Credentials Grant (or Backend Application Flow). Available Workflows ~~~~~~~~~~~~~~~~~~~ There are four core work flows: 1. :ref:`Authorization Code Grant ` (Web Application Flow). 2. :ref:`Implicit Grant ` (Mobile Application flow). 3. :ref:`Resource Owner Password Credentials Grant ` (Legacy Application flow). 4. :ref:`Client Credentials Grant ` (Backend Application flow). .. _web-application-flow: Web Application Flow -------------------- The steps below outline how to use the default Authorization Grant Type flow to obtain an access token and fetch a protected resource. In this example the provider is Google and the protected resource is the user's profile. 0. Obtain credentials from your OAuth provider manually. At minimum you will need a ``client_id`` but likely also a ``client_secret``. During this process you might also be required to register a default redirect URI to be used by your application. Save these things in your Python script: .. code-block:: pycon >>> client_id = r'your_client_id' >>> client_secret = r'your_client_secret' >>> redirect_uri = 'https://your.callback/uri' 1. User authorization through redirection. First we will create an authorization url from the base URL given by the provider and the credentials previously obtained. In addition most providers will request that you ask for access to a certain scope. In this example we will ask Google for access to the email address of the user and the users profile. .. code-block:: pycon # Note that these are Google specific scopes >>> scope = ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile'] >>> oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope) >>> authorization_url, state = oauth.authorization_url( 'https://accounts.google.com/o/oauth2/auth', # access_type and approval_prompt are Google specific extra # parameters. access_type="offline", approval_prompt="force") >>> print 'Please go to %s and authorize access.' % authorization_url >>> authorization_response = raw_input('Enter the full callback URL') 2. Fetch an access token from the provider using the authorization code obtained during user authorization. .. code-block:: pycon >>> token = oauth.fetch_token( 'https://accounts.google.com/o/oauth2/token', authorization_response=authorization_response, # Google specific extra parameter used for client # authentication client_secret=client_secret) 3. Access protected resources using the access token you just obtained. For example, get the users profile info. .. code-block:: pycon >>> r = oauth.get('https://www.googleapis.com/oauth2/v1/userinfo') >>> # Enjoy =) .. _mobile-application-flow: Mobile Application Flow ----------------------- Documentation coming soon. Want to help? Why not `write this section`_? .. _legacy-application-flow: Legacy Application Flow ----------------------- The steps below outline how to use the Resource Owner Password Credentials Grant Type flow to obtain an access token. 0. You will need the following settings. ``client_secret`` is optional depending on the provider. .. code-block:: pycon >>> client_id = 'your_client_id' >>> client_secret = 'your_client_secret' >>> username = 'your_username' >>> password = 'your_password' 1. Fetch an access token from the provider. .. code-block:: pycon >>> from oauthlib.oauth2 import LegacyApplicationClient >>> from requests_oauthlib import OAuth2Session >>> oauth = OAuth2Session(client=LegacyApplicationClient(client_id=client_id)) >>> token = oauth.fetch_token(token_url='https://somesite.com/oauth2/token', username=username, password=password, client_id=client_id, client_secret=client_secret) .. _backend-application-flow: Backend Application Flow ------------------------ The steps below outline how to use the Resource Owner Client Credentials Grant Type flow to obtain an access token. 0. Obtain credentials from your OAuth provider. At minimum you will need a ``client_id`` and ``client_secret``. .. code-block:: pycon >>> client_id = 'your_client_id' >>> client_secret = 'your_client_secret' 1. Fetch an access token from the provider. .. code-block:: pycon >>> from oauthlib.oauth2 import BackendApplicationClient >>> client = BackendApplicationClient(client_id=client_id) >>> oauth = OAuth2Session(client=client) >>> token = oauth.fetch_token(token_url='https://provider.com/oauth2/token', client_id=client_id, client_secret=client_secret) Refreshing tokens ----------------- Certain providers will give you a ``refresh_token`` along with the ``access_token``. These can be used to directly fetch new access tokens without going through the normal OAuth workflow. ``requests-oauthlib`` provides three methods of obtaining refresh tokens. All of these are dependant on you specifying an accurate ``expires_in`` in the token. ``expires_in`` is a credential given with the access and refresh token indiciating in how many seconds from now the access token expires. Commonly, access tokens expire after an hour an the ``expires_in`` would be ``3600``. Without this it is impossible for ``requests-oauthlib`` to know when a token is expired as the status code of a request failing due to token expiration is not defined. If you are not interested in token refreshing, always pass in a positive value for ``expires_in`` or omit it entirely. (ALL) Define the token, token saver and needed credentials ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: pycon >>> token = { ... 'access_token': 'eswfld123kjhn1v5423', ... 'refresh_token': 'asdfkljh23490sdf', ... 'token_type': 'Bearer', ... 'expires_in': '-30', # initially 3600, need to be updated by you ... } >>> client_id = r'foo' >>> refresh_url = 'https://provider.com/token' >>> protected_url = 'https://provider.com/secret' >>> # most providers will ask you for extra credentials to be passed along >>> # when refreshing tokens, usually for authentication purposes. >>> extra = { ... 'client_id': client_id, ... 'client_secret': r'potato', ... } >>> # After updating the token you will most likely want to save it. >>> def token_saver(token): ... # save token in database / session (First) Define Try-Catch TokenExpiredError on each request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is the most basic version in which an error is raised when refresh is necessary but refreshing is done manually. .. code-block:: pycon >>> from requests_oauthlib import OAuth2Session >>> from oauthlib.oauth2 import TokenExpiredError >>> try: ... client = OAuth2Session(client_id, token=token) ... r = client.get(protected_url) >>> except TokenExpiredError as e: ... token = client.refresh_token(refresh_url, **extra) ... token_saver(token) >>> client = OAuth2Session(client_id, token=token) >>> r = client.get(protected_url) (Second) Define automatic token refresh automatic but update manually ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is the, arguably awkward, middle between the basic and convenient refresh methods in which a token is automatically refreshed, but saving the new token is done manually. .. code-block:: pycon >>> from requests_oauthlib import OAuth2Session, TokenUpdated >>> try: ... client = OAuth2Session(client_id, token=token, ... auto_refresh_kwargs=extra, auto_refresh_url=refresh_url) ... r = client.get(protected_url) >>> except TokenUpdated as e: ... token_saver(e.token) (Third, Recommended) Define automatic token refresh and update ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The third and recommended method will automatically fetch refresh tokens and save them. It requires no exception catching and results in clean code. Remember however that you still need to update ``expires_in`` to trigger the refresh. .. code-block:: pycon >>> from requests_oauthlib import OAuth2Session >>> client = OAuth2Session(client_id, token=token, auto_refresh_url=refresh_url, ... auto_refresh_kwargs=extra, token_updater=token_saver) >>> r = client.get(protected_url) .. _write this section: https://github.com/requests/requests-oauthlib/issues/48 requests-oauthlib-0.8.0/HISTORY.rst0000644000076500000240000001016713050617371017201 0ustar corystaff00000000000000History ------- v0.8.0 (14 February 2017) +++++++++++++++++++++++++ - Added Fitbit compliance fix. - Fixed an issue where newlines in the response body for the access token request would cause errors when trying to extract the token. - Fixed an issue introduced in v0.7.0 where users passing ``auth`` to several methods would encounter conflicts with the ``client_id`` and ``client_secret``-derived auth. The user-supplied ``auth`` argument is now used in preference to those options. v0.7.0 (22 September 2016) ++++++++++++++++++++++++++ - Allowed ``OAuth2Session.request`` to take the ``client_id`` and ``client_secret`` parameters for the purposes of automatic token refresh, which may need them. v0.6.2 (12 July 2016) +++++++++++++++++++++ - Use ``client_id`` and ``client_secret`` for the Authorization header if provided. - Allow explicit bypass of the Authorization header by setting ``auth=False``. - Pass through the ``proxies`` kwarg when refreshing tokens. - Miscellaneous cleanups. v0.6.1 (19 February 2016) +++++++++++++++++++++++++ - Fixed a bug when sending authorization in headers with no username and password present. - Make sure we clear the session token before obtaining a new one. - Some improvements to the Slack compliance fix. - Avoid timing problems around token refresh. - Allow passing arbitrary arguments to requests when calling ``fetch_request_token`` and ``fetch_access_token``. v0.6.0 (14 December 2015) +++++++++++++++++++++++++ - Add compliance fix for Slack. - Add compliance fix for Mailchimp. - ``TokenRequestDenied`` exceptions now carry the entire response, not just the status code. - Pass through keyword arguments when refreshing tokens automatically. - Send authorization in headers, not just body, to maximize compatibility. - More getters/setters available for OAuth2 session client values. - Allow sending custom headers when refreshing tokens, and set some defaults. v0.5.0 (4 May 2015) +++++++++++++++++++ - Fix ``TypeError`` being raised instead of ``TokenMissing`` error. - Raise requests exceptions on 4XX and 5XX responses in the OAuth2 flow. - Avoid ``AttributeError`` when initializing the ``OAuth2Session`` class without complete client information. v0.4.2 (16 October 2014) ++++++++++++++++++++++++ - New ``authorized`` property on OAuth1Session and OAuth2Session, which allows you to easily determine if the session is already authorized with OAuth tokens or not. - New ``TokenMissing`` and ``VerifierMissing`` exception classes for OAuth1Session: this will make it easier to catch and identify these exceptions. v0.4.1 (6 June 2014) ++++++++++++++++++++ - New install target ``[rsa]`` for people using OAuth1 RSA-SHA1 signature method. - Fixed bug in OAuth2 where supplied state param was not used in auth url. - OAuth2 HTTPS checking can be disabled by setting environment variable ``OAUTHLIB_INSECURE_TRANSPORT``. - OAuth1 now re-authorize upon redirects. - OAuth1 token fetching now raise a detailed error message when the response body is incorrectly encoded or the request was denied. - Added support for custom OAuth1 clients. - OAuth2 compliance fix for Sina Weibo. - Multiple fixes to facebook compliance fix. - Compliance fixes now re-encode body properly as bytes in Python 3. - Logging now properly done under ``requests_oauthlib`` namespace instead of piggybacking on oauthlib namespace. - Logging introduced for OAuth1 auth and session. v0.4.0 (29 September 2013) ++++++++++++++++++++++++++ - OAuth1Session methods only return unicode strings. #55. - Renamed requests_oauthlib.core to requests_oauthlib.oauth1_auth for consistency. #79. - Added Facebook compliance fix and access_token_response hook to OAuth2Session. #63. - Added LinkedIn compliance fix. - Added refresh_token_response compliance hook, invoked before parsing the refresh token. - Correctly limit compliance hooks to running only once! - Content type guessing should only be done when no content type is given - OAuth1 now updates r.headers instead of replacing it with non case insensitive dict - Remove last use of Response.content (in OAuth1Session). #44. - State param can now be supplied in OAuth2Session.authorize_url requests-oauthlib-0.8.0/LICENSE0000644000076500000240000000135112741215636016312 0ustar corystaff00000000000000ISC License Copyright (c) 2014 Kenneth Reitz. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. requests-oauthlib-0.8.0/MANIFEST.in0000644000076500000240000000014712620061233017031 0ustar corystaff00000000000000include README.rst LICENSE HISTORY.rst requirements.txt AUTHORS.rst graft tests graft docs prune *.pyc requests-oauthlib-0.8.0/PKG-INFO0000644000076500000240000002112113050617554016376 0ustar corystaff00000000000000Metadata-Version: 1.1 Name: requests-oauthlib Version: 0.8.0 Summary: OAuthlib authentication support for Requests. Home-page: https://github.com/requests/requests-oauthlib Author: Kenneth Reitz Author-email: me@kennethreitz.com License: ISC Description: Requests-OAuthlib |build-status| |coverage-status| |docs| ========================================================= This project provides first-class OAuth library support for `Requests `_. The OAuth 1 workflow -------------------- OAuth 1 can seem overly complicated and it sure has its quirks. Luckily, requests_oauthlib hides most of these and let you focus at the task at hand. Accessing protected resources using requests_oauthlib is as simple as: .. code-block:: pycon >>> from requests_oauthlib import OAuth1Session >>> twitter = OAuth1Session('client_key', client_secret='client_secret', resource_owner_key='resource_owner_key', resource_owner_secret='resource_owner_secret') >>> url = 'https://api.twitter.com/1/account/settings.json' >>> r = twitter.get(url) Before accessing resources you will need to obtain a few credentials from your provider (i.e. Twitter) and authorization from the user for whom you wish to retrieve resources for. You can read all about this in the full `OAuth 1 workflow guide on RTD `_. The OAuth 2 workflow -------------------- OAuth 2 is generally simpler than OAuth 1 but comes in more flavours. The most common being the Authorization Code Grant, also known as the WebApplication flow. Fetching a protected resource after obtaining an access token can be extremely simple. However, before accessing resources you will need to obtain a few credentials from your provider (i.e. Google) and authorization from the user for whom you wish to retrieve resources for. You can read all about this in the full `OAuth 2 workflow guide on RTD `_. Installation ------------- To install requests and requests_oauthlib you can use pip: .. code-block:: bash $ pip install requests requests_oauthlib .. |build-status| image:: https://travis-ci.org/requests/requests-oauthlib.svg?branch=master :target: https://travis-ci.org/requests/requests-oauthlib .. |coverage-status| image:: https://img.shields.io/coveralls/requests/requests-oauthlib.svg :target: https://coveralls.io/r/requests/requests-oauthlib .. |docs| image:: https://readthedocs.org/projects/requests-oauthlib/badge/?version=latest :alt: Documentation Status :scale: 100% :target: https://readthedocs.org/projects/requests-oauthlib/ History ------- v0.8.0 (14 February 2017) +++++++++++++++++++++++++ - Added Fitbit compliance fix. - Fixed an issue where newlines in the response body for the access token request would cause errors when trying to extract the token. - Fixed an issue introduced in v0.7.0 where users passing ``auth`` to several methods would encounter conflicts with the ``client_id`` and ``client_secret``-derived auth. The user-supplied ``auth`` argument is now used in preference to those options. v0.7.0 (22 September 2016) ++++++++++++++++++++++++++ - Allowed ``OAuth2Session.request`` to take the ``client_id`` and ``client_secret`` parameters for the purposes of automatic token refresh, which may need them. v0.6.2 (12 July 2016) +++++++++++++++++++++ - Use ``client_id`` and ``client_secret`` for the Authorization header if provided. - Allow explicit bypass of the Authorization header by setting ``auth=False``. - Pass through the ``proxies`` kwarg when refreshing tokens. - Miscellaneous cleanups. v0.6.1 (19 February 2016) +++++++++++++++++++++++++ - Fixed a bug when sending authorization in headers with no username and password present. - Make sure we clear the session token before obtaining a new one. - Some improvements to the Slack compliance fix. - Avoid timing problems around token refresh. - Allow passing arbitrary arguments to requests when calling ``fetch_request_token`` and ``fetch_access_token``. v0.6.0 (14 December 2015) +++++++++++++++++++++++++ - Add compliance fix for Slack. - Add compliance fix for Mailchimp. - ``TokenRequestDenied`` exceptions now carry the entire response, not just the status code. - Pass through keyword arguments when refreshing tokens automatically. - Send authorization in headers, not just body, to maximize compatibility. - More getters/setters available for OAuth2 session client values. - Allow sending custom headers when refreshing tokens, and set some defaults. v0.5.0 (4 May 2015) +++++++++++++++++++ - Fix ``TypeError`` being raised instead of ``TokenMissing`` error. - Raise requests exceptions on 4XX and 5XX responses in the OAuth2 flow. - Avoid ``AttributeError`` when initializing the ``OAuth2Session`` class without complete client information. v0.4.2 (16 October 2014) ++++++++++++++++++++++++ - New ``authorized`` property on OAuth1Session and OAuth2Session, which allows you to easily determine if the session is already authorized with OAuth tokens or not. - New ``TokenMissing`` and ``VerifierMissing`` exception classes for OAuth1Session: this will make it easier to catch and identify these exceptions. v0.4.1 (6 June 2014) ++++++++++++++++++++ - New install target ``[rsa]`` for people using OAuth1 RSA-SHA1 signature method. - Fixed bug in OAuth2 where supplied state param was not used in auth url. - OAuth2 HTTPS checking can be disabled by setting environment variable ``OAUTHLIB_INSECURE_TRANSPORT``. - OAuth1 now re-authorize upon redirects. - OAuth1 token fetching now raise a detailed error message when the response body is incorrectly encoded or the request was denied. - Added support for custom OAuth1 clients. - OAuth2 compliance fix for Sina Weibo. - Multiple fixes to facebook compliance fix. - Compliance fixes now re-encode body properly as bytes in Python 3. - Logging now properly done under ``requests_oauthlib`` namespace instead of piggybacking on oauthlib namespace. - Logging introduced for OAuth1 auth and session. v0.4.0 (29 September 2013) ++++++++++++++++++++++++++ - OAuth1Session methods only return unicode strings. #55. - Renamed requests_oauthlib.core to requests_oauthlib.oauth1_auth for consistency. #79. - Added Facebook compliance fix and access_token_response hook to OAuth2Session. #63. - Added LinkedIn compliance fix. - Added refresh_token_response compliance hook, invoked before parsing the refresh token. - Correctly limit compliance hooks to running only once! - Content type guessing should only be done when no content type is given - OAuth1 now updates r.headers instead of replacing it with non case insensitive dict - Remove last use of Response.content (in OAuth1Session). #44. - State param can now be supplied in OAuth2Session.authorize_url Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Natural Language :: English Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 requests-oauthlib-0.8.0/README.rst0000644000076500000240000000475412623133510016773 0ustar corystaff00000000000000Requests-OAuthlib |build-status| |coverage-status| |docs| ========================================================= This project provides first-class OAuth library support for `Requests `_. The OAuth 1 workflow -------------------- OAuth 1 can seem overly complicated and it sure has its quirks. Luckily, requests_oauthlib hides most of these and let you focus at the task at hand. Accessing protected resources using requests_oauthlib is as simple as: .. code-block:: pycon >>> from requests_oauthlib import OAuth1Session >>> twitter = OAuth1Session('client_key', client_secret='client_secret', resource_owner_key='resource_owner_key', resource_owner_secret='resource_owner_secret') >>> url = 'https://api.twitter.com/1/account/settings.json' >>> r = twitter.get(url) Before accessing resources you will need to obtain a few credentials from your provider (i.e. Twitter) and authorization from the user for whom you wish to retrieve resources for. You can read all about this in the full `OAuth 1 workflow guide on RTD `_. The OAuth 2 workflow -------------------- OAuth 2 is generally simpler than OAuth 1 but comes in more flavours. The most common being the Authorization Code Grant, also known as the WebApplication flow. Fetching a protected resource after obtaining an access token can be extremely simple. However, before accessing resources you will need to obtain a few credentials from your provider (i.e. Google) and authorization from the user for whom you wish to retrieve resources for. You can read all about this in the full `OAuth 2 workflow guide on RTD `_. Installation ------------- To install requests and requests_oauthlib you can use pip: .. code-block:: bash $ pip install requests requests_oauthlib .. |build-status| image:: https://travis-ci.org/requests/requests-oauthlib.svg?branch=master :target: https://travis-ci.org/requests/requests-oauthlib .. |coverage-status| image:: https://img.shields.io/coveralls/requests/requests-oauthlib.svg :target: https://coveralls.io/r/requests/requests-oauthlib .. |docs| image:: https://readthedocs.org/projects/requests-oauthlib/badge/?version=latest :alt: Documentation Status :scale: 100% :target: https://readthedocs.org/projects/requests-oauthlib/ requests-oauthlib-0.8.0/requests_oauthlib/0000755000076500000240000000000013050617553021045 5ustar corystaff00000000000000requests-oauthlib-0.8.0/requests_oauthlib/__init__.py0000644000076500000240000000123713050617427023161 0ustar corystaff00000000000000from .oauth1_auth import OAuth1 from .oauth1_session import OAuth1Session from .oauth2_auth import OAuth2 from .oauth2_session import OAuth2Session, TokenUpdated __version__ = '0.8.0' import requests if requests.__version__ < '2.0.0': msg = ('You are using requests version %s, which is older than ' 'requests-oauthlib expects, please upgrade to 2.0.0 or later.') raise Warning(msg % requests.__version__) import logging try: # Python 2.7+ from logging import NullHandler except ImportError: class NullHandler(logging.Handler): def emit(self, record): pass logging.getLogger('requests_oauthlib').addHandler(NullHandler()) requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/0000755000076500000240000000000013050617554024356 5ustar corystaff00000000000000requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/__init__.py0000644000076500000240000000045613050616611026465 0ustar corystaff00000000000000from __future__ import absolute_import from .facebook import facebook_compliance_fix from .fitbit import fitbit_compliance_fix from .linkedin import linkedin_compliance_fix from .slack import slack_compliance_fix from .mailchimp import mailchimp_compliance_fix from .weibo import weibo_compliance_fix requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/douban.py0000644000076500000240000000073112417777126026211 0ustar corystaff00000000000000import json from oauthlib.common import to_unicode def douban_compliance_fix(session): def fix_token_type(r): token = json.loads(r.text) token.setdefault('token_type', 'Bearer') fixed_token = json.dumps(token) r._content = to_unicode(fixed_token).encode('utf-8') return r session._client_default_token_placement = 'query' session.register_compliance_hook('access_token_response', fix_token_type) return session requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/facebook.py0000644000076500000240000000213712344337640026504 0ustar corystaff00000000000000from json import dumps try: from urlparse import parse_qsl except ImportError: from urllib.parse import parse_qsl from oauthlib.common import to_unicode def facebook_compliance_fix(session): def _compliance_fix(r): # if Facebook claims to be sending us json, let's trust them. if 'application/json' in r.headers.get('content-type', {}): return r # Facebook returns a content-type of text/plain when sending their # x-www-form-urlencoded responses, along with a 200. If not, let's # assume we're getting JSON and bail on the fix. if 'text/plain' in r.headers.get('content-type', {}) and r.status_code == 200: token = dict(parse_qsl(r.text, keep_blank_values=True)) else: return r expires = token.get('expires') if expires is not None: token['expires_in'] = expires token['token_type'] = 'Bearer' r._content = to_unicode(dumps(token)).encode('UTF-8') return r session.register_compliance_hook('access_token_response', _compliance_fix) return session requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/fitbit.py0000644000076500000240000000161213050616611026202 0ustar corystaff00000000000000""" The Fitbit API breaks from the OAuth2 RFC standard by returning an "errors" object list, rather than a single "error" string. This puts hooks in place so that oauthlib can process an error in the results from access token and refresh token responses. This is necessary to prevent getting the generic red herring MissingTokenError. """ from json import loads, dumps from oauthlib.common import to_unicode def fitbit_compliance_fix(session): def _missing_error(r): token = loads(r.text) if 'errors' in token: # Set the error to the first one we have token['error'] = token['errors'][0]['errorType'] r._content = to_unicode(dumps(token)).encode('UTF-8') return r session.register_compliance_hook('access_token_response', _missing_error) session.register_compliance_hook('refresh_token_response', _missing_error) return session requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/linkedin.py0000644000076500000240000000147012661635562026535 0ustar corystaff00000000000000from json import loads, dumps from oauthlib.common import add_params_to_uri, to_unicode def linkedin_compliance_fix(session): def _missing_token_type(r): token = loads(r.text) token['token_type'] = 'Bearer' r._content = to_unicode(dumps(token)).encode('UTF-8') return r def _non_compliant_param_name(url, headers, data): token = [('oauth2_access_token', session.access_token)] url = add_params_to_uri(url, token) return url, headers, data session._client.default_token_placement = 'query' session.register_compliance_hook('access_token_response', _missing_token_type) session.register_compliance_hook('protected_request', _non_compliant_param_name) return session requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/mailchimp.py0000644000076500000240000000136412633524331026673 0ustar corystaff00000000000000import json from oauthlib.common import to_unicode def mailchimp_compliance_fix(session): def _null_scope(r): token = json.loads(r.text) if 'scope' in token and token['scope'] is None: token.pop('scope') r._content = to_unicode(json.dumps(token)).encode('utf-8') return r def _non_zero_expiration(r): token = json.loads(r.text) if 'expires_in' in token and token['expires_in'] == 0: token['expires_in'] = 3600 r._content = to_unicode(json.dumps(token)).encode('utf-8') return r session.register_compliance_hook('access_token_response', _null_scope) session.register_compliance_hook('access_token_response', _non_zero_expiration) return session requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/slack.py0000644000076500000240000000265512661635562026043 0ustar corystaff00000000000000try: from urlparse import urlparse, parse_qs except ImportError: from urllib.parse import urlparse, parse_qs from oauthlib.common import add_params_to_uri def slack_compliance_fix(session): def _non_compliant_param_name(url, headers, data): # If the user has already specified the token, either in the URL # or in a data dictionary, then there's nothing to do. # If the specified token is different from ``session.access_token``, # we assume the user intends to override the access token. url_query = dict(parse_qs(urlparse(url).query)) token = url_query.get("token") if not token and isinstance(data, dict): token = data.get("token") if token: # Nothing to do, just return. return url, headers, data if not data: data = {"token": session.access_token} elif isinstance(data, dict): data["token"] = session.access_token else: # ``data`` is something other than a dict: maybe a stream, # maybe a file object, maybe something else. We can't easily # modify it, so we'll set the token by modifying the URL instead. token = [('token', session.access_token)] url = add_params_to_uri(url, token) return url, headers, data session.register_compliance_hook('protected_request', _non_compliant_param_name) return session requests-oauthlib-0.8.0/requests_oauthlib/compliance_fixes/weibo.py0000644000076500000240000000074212344337640026040 0ustar corystaff00000000000000from json import loads, dumps from oauthlib.common import to_unicode def weibo_compliance_fix(session): def _missing_token_type(r): token = loads(r.text) token['token_type'] = 'Bearer' r._content = to_unicode(dumps(token)).encode('UTF-8') return r session._client.default_token_placement = 'query' session.register_compliance_hook('access_token_response', _missing_token_type) return session requests-oauthlib-0.8.0/requests_oauthlib/oauth1_auth.py0000644000076500000240000000673512633522042023646 0ustar corystaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import logging from oauthlib.common import extract_params from oauthlib.oauth1 import Client, SIGNATURE_HMAC, SIGNATURE_TYPE_AUTH_HEADER from oauthlib.oauth1 import SIGNATURE_TYPE_BODY from requests.compat import is_py3 from requests.utils import to_native_string from requests.auth import AuthBase CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' CONTENT_TYPE_MULTI_PART = 'multipart/form-data' if is_py3: unicode = str log = logging.getLogger(__name__) # OBS!: Correct signing of requests are conditional on invoking OAuth1 # as the last step of preparing a request, or at least having the # content-type set properly. class OAuth1(AuthBase): """Signs the request using OAuth 1 (RFC5849)""" client_class = Client def __init__(self, client_key, client_secret=None, resource_owner_key=None, resource_owner_secret=None, callback_uri=None, signature_method=SIGNATURE_HMAC, signature_type=SIGNATURE_TYPE_AUTH_HEADER, rsa_key=None, verifier=None, decoding='utf-8', client_class=None, force_include_body=False, **kwargs): try: signature_type = signature_type.upper() except AttributeError: pass client_class = client_class or self.client_class self.force_include_body = force_include_body self.client = client_class(client_key, client_secret, resource_owner_key, resource_owner_secret, callback_uri, signature_method, signature_type, rsa_key, verifier, decoding=decoding, **kwargs) def __call__(self, r): """Add OAuth parameters to the request. Parameters may be included from the body if the content-type is urlencoded, if no content type is set a guess is made. """ # Overwriting url is safe here as request will not modify it past # this point. log.debug('Signing request %s using client %s', r, self.client) content_type = r.headers.get('Content-Type', '') if (not content_type and extract_params(r.body) or self.client.signature_type == SIGNATURE_TYPE_BODY): content_type = CONTENT_TYPE_FORM_URLENCODED if not isinstance(content_type, unicode): content_type = content_type.decode('utf-8') is_form_encoded = (CONTENT_TYPE_FORM_URLENCODED in content_type) log.debug('Including body in call to sign: %s', is_form_encoded or self.force_include_body) if is_form_encoded: r.headers['Content-Type'] = CONTENT_TYPE_FORM_URLENCODED r.url, headers, r.body = self.client.sign( unicode(r.url), unicode(r.method), r.body or '', r.headers) elif self.force_include_body: # To allow custom clients to work on non form encoded bodies. r.url, headers, r.body = self.client.sign( unicode(r.url), unicode(r.method), r.body or '', r.headers) else: # Omit body data in the signing of non form-encoded requests r.url, headers, _ = self.client.sign( unicode(r.url), unicode(r.method), None, r.headers) r.prepare_headers(headers) r.url = to_native_string(r.url) log.debug('Updated url: %s', r.url) log.debug('Updated headers: %s', headers) log.debug('Updated body: %r', r.body) return r requests-oauthlib-0.8.0/requests_oauthlib/oauth1_session.py0000644000076500000240000004013213000127600024343 0ustar corystaff00000000000000from __future__ import unicode_literals try: from urlparse import urlparse except ImportError: from urllib.parse import urlparse import logging from oauthlib.common import add_params_to_uri from oauthlib.common import urldecode as _urldecode from oauthlib.oauth1 import ( SIGNATURE_HMAC, SIGNATURE_RSA, SIGNATURE_TYPE_AUTH_HEADER ) import requests from . import OAuth1 import sys if sys.version > "3": unicode = str log = logging.getLogger(__name__) def urldecode(body): """Parse query or json to python dictionary""" try: return _urldecode(body) except: import json return json.loads(body) class TokenRequestDenied(ValueError): def __init__(self, message, response): super(TokenRequestDenied, self).__init__(message) self.response = response @property def status_code(self): """For backwards-compatibility purposes""" return self.response.status_code class TokenMissing(ValueError): def __init__(self, message, response): super(TokenMissing, self).__init__(message) self.response = response class VerifierMissing(ValueError): pass class OAuth1Session(requests.Session): """Request signing and convenience methods for the oauth dance. What is the difference between OAuth1Session and OAuth1? OAuth1Session actually uses OAuth1 internally and its purpose is to assist in the OAuth workflow through convenience methods to prepare authorization URLs and parse the various token and redirection responses. It also provide rudimentary validation of responses. An example of the OAuth workflow using a basic CLI app and Twitter. >>> # Credentials obtained during the registration. >>> client_key = 'client key' >>> client_secret = 'secret' >>> callback_uri = 'https://127.0.0.1/callback' >>> >>> # Endpoints found in the OAuth provider API documentation >>> request_token_url = 'https://api.twitter.com/oauth/request_token' >>> authorization_url = 'https://api.twitter.com/oauth/authorize' >>> access_token_url = 'https://api.twitter.com/oauth/access_token' >>> >>> oauth_session = OAuth1Session(client_key,client_secret=client_secret, callback_uri=callback_uri) >>> >>> # First step, fetch the request token. >>> oauth_session.fetch_request_token(request_token_url) { 'oauth_token': 'kjerht2309u', 'oauth_token_secret': 'lsdajfh923874', } >>> >>> # Second step. Follow this link and authorize >>> oauth_session.authorization_url(authorization_url) 'https://api.twitter.com/oauth/authorize?oauth_token=sdf0o9823sjdfsdf&oauth_callback=https%3A%2F%2F127.0.0.1%2Fcallback' >>> >>> # Third step. Fetch the access token >>> redirect_response = raw_input('Paste the full redirect URL here.') >>> oauth_session.parse_authorization_response(redirect_response) { 'oauth_token: 'kjerht2309u', 'oauth_token_secret: 'lsdajfh923874', 'oauth_verifier: 'w34o8967345', } >>> oauth_session.fetch_access_token(access_token_url) { 'oauth_token': 'sdf0o9823sjdfsdf', 'oauth_token_secret': '2kjshdfp92i34asdasd', } >>> # Done. You can now make OAuth requests. >>> status_url = 'http://api.twitter.com/1/statuses/update.json' >>> new_status = {'status': 'hello world!'} >>> oauth_session.post(status_url, data=new_status) """ def __init__(self, client_key, client_secret=None, resource_owner_key=None, resource_owner_secret=None, callback_uri=None, signature_method=SIGNATURE_HMAC, signature_type=SIGNATURE_TYPE_AUTH_HEADER, rsa_key=None, verifier=None, client_class=None, force_include_body=False, **kwargs): """Construct the OAuth 1 session. :param client_key: A client specific identifier. :param client_secret: A client specific secret used to create HMAC and plaintext signatures. :param resource_owner_key: A resource owner key, also referred to as request token or access token depending on when in the workflow it is used. :param resource_owner_secret: A resource owner secret obtained with either a request or access token. Often referred to as token secret. :param callback_uri: The URL the user is redirect back to after authorization. :param signature_method: Signature methods determine how the OAuth signature is created. The three options are oauthlib.oauth1.SIGNATURE_HMAC (default), oauthlib.oauth1.SIGNATURE_RSA and oauthlib.oauth1.SIGNATURE_PLAIN. :param signature_type: Signature type decides where the OAuth parameters are added. Either in the Authorization header (default) or to the URL query parameters or the request body. Defined as oauthlib.oauth1.SIGNATURE_TYPE_AUTH_HEADER, oauthlib.oauth1.SIGNATURE_TYPE_QUERY and oauthlib.oauth1.SIGNATURE_TYPE_BODY respectively. :param rsa_key: The private RSA key as a string. Can only be used with signature_method=oauthlib.oauth1.SIGNATURE_RSA. :param verifier: A verifier string to prove authorization was granted. :param client_class: A subclass of `oauthlib.oauth1.Client` to use with `requests_oauthlib.OAuth1` instead of the default :param force_include_body: Always include the request body in the signature creation. :param **kwargs: Additional keyword arguments passed to `OAuth1` """ super(OAuth1Session, self).__init__() self._client = OAuth1(client_key, client_secret=client_secret, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret, callback_uri=callback_uri, signature_method=signature_method, signature_type=signature_type, rsa_key=rsa_key, verifier=verifier, client_class=client_class, force_include_body=force_include_body, **kwargs) self.auth = self._client @property def authorized(self): """Boolean that indicates whether this session has an OAuth token or not. If `self.authorized` is True, you can reasonably expect OAuth-protected requests to the resource to succeed. If `self.authorized` is False, you need the user to go through the OAuth authentication dance before OAuth-protected requests to the resource will succeed. """ if self._client.client.signature_method == SIGNATURE_RSA: # RSA only uses resource_owner_key return bool(self._client.client.resource_owner_key) else: # other methods of authentication use all three pieces return ( bool(self._client.client.client_secret) and bool(self._client.client.resource_owner_key) and bool(self._client.client.resource_owner_secret) ) def authorization_url(self, url, request_token=None, **kwargs): """Create an authorization URL by appending request_token and optional kwargs to url. This is the second step in the OAuth 1 workflow. The user should be redirected to this authorization URL, grant access to you, and then be redirected back to you. The redirection back can either be specified during client registration or by supplying a callback URI per request. :param url: The authorization endpoint URL. :param request_token: The previously obtained request token. :param kwargs: Optional parameters to append to the URL. :returns: The authorization URL with new parameters embedded. An example using a registered default callback URI. >>> request_token_url = 'https://api.twitter.com/oauth/request_token' >>> authorization_url = 'https://api.twitter.com/oauth/authorize' >>> oauth_session = OAuth1Session('client-key', client_secret='secret') >>> oauth_session.fetch_request_token(request_token_url) { 'oauth_token': 'sdf0o9823sjdfsdf', 'oauth_token_secret': '2kjshdfp92i34asdasd', } >>> oauth_session.authorization_url(authorization_url) 'https://api.twitter.com/oauth/authorize?oauth_token=sdf0o9823sjdfsdf' >>> oauth_session.authorization_url(authorization_url, foo='bar') 'https://api.twitter.com/oauth/authorize?oauth_token=sdf0o9823sjdfsdf&foo=bar' An example using an explicit callback URI. >>> request_token_url = 'https://api.twitter.com/oauth/request_token' >>> authorization_url = 'https://api.twitter.com/oauth/authorize' >>> oauth_session = OAuth1Session('client-key', client_secret='secret', callback_uri='https://127.0.0.1/callback') >>> oauth_session.fetch_request_token(request_token_url) { 'oauth_token': 'sdf0o9823sjdfsdf', 'oauth_token_secret': '2kjshdfp92i34asdasd', } >>> oauth_session.authorization_url(authorization_url) 'https://api.twitter.com/oauth/authorize?oauth_token=sdf0o9823sjdfsdf&oauth_callback=https%3A%2F%2F127.0.0.1%2Fcallback' """ kwargs['oauth_token'] = request_token or self._client.client.resource_owner_key log.debug('Adding parameters %s to url %s', kwargs, url) return add_params_to_uri(url, kwargs.items()) def fetch_request_token(self, url, realm=None, **request_kwargs): """Fetch a request token. This is the first step in the OAuth 1 workflow. A request token is obtained by making a signed post request to url. The token is then parsed from the application/x-www-form-urlencoded response and ready to be used to construct an authorization url. :param url: The request token endpoint URL. :param realm: A list of realms to request access to. :param \*\*request_kwargs: Optional arguments passed to ''post'' function in ''requests.Session'' :returns: The response in dict format. Note that a previously set callback_uri will be reset for your convenience, or else signature creation will be incorrect on consecutive requests. >>> request_token_url = 'https://api.twitter.com/oauth/request_token' >>> oauth_session = OAuth1Session('client-key', client_secret='secret') >>> oauth_session.fetch_request_token(request_token_url) { 'oauth_token': 'sdf0o9823sjdfsdf', 'oauth_token_secret': '2kjshdfp92i34asdasd', } """ self._client.client.realm = ' '.join(realm) if realm else None token = self._fetch_token(url, **request_kwargs) log.debug('Resetting callback_uri and realm (not needed in next phase).') self._client.client.callback_uri = None self._client.client.realm = None return token def fetch_access_token(self, url, verifier=None, **request_kwargs): """Fetch an access token. This is the final step in the OAuth 1 workflow. An access token is obtained using all previously obtained credentials, including the verifier from the authorization step. Note that a previously set verifier will be reset for your convenience, or else signature creation will be incorrect on consecutive requests. >>> access_token_url = 'https://api.twitter.com/oauth/access_token' >>> redirect_response = 'https://127.0.0.1/callback?oauth_token=kjerht2309uf&oauth_token_secret=lsdajfh923874&oauth_verifier=w34o8967345' >>> oauth_session = OAuth1Session('client-key', client_secret='secret') >>> oauth_session.parse_authorization_response(redirect_response) { 'oauth_token: 'kjerht2309u', 'oauth_token_secret: 'lsdajfh923874', 'oauth_verifier: 'w34o8967345', } >>> oauth_session.fetch_access_token(access_token_url) { 'oauth_token': 'sdf0o9823sjdfsdf', 'oauth_token_secret': '2kjshdfp92i34asdasd', } """ if verifier: self._client.client.verifier = verifier if not getattr(self._client.client, 'verifier', None): raise VerifierMissing('No client verifier has been set.') token = self._fetch_token(url, **request_kwargs) log.debug('Resetting verifier attribute, should not be used anymore.') self._client.client.verifier = None return token def parse_authorization_response(self, url): """Extract parameters from the post authorization redirect response URL. :param url: The full URL that resulted from the user being redirected back from the OAuth provider to you, the client. :returns: A dict of parameters extracted from the URL. >>> redirect_response = 'https://127.0.0.1/callback?oauth_token=kjerht2309uf&oauth_token_secret=lsdajfh923874&oauth_verifier=w34o8967345' >>> oauth_session = OAuth1Session('client-key', client_secret='secret') >>> oauth_session.parse_authorization_response(redirect_response) { 'oauth_token: 'kjerht2309u', 'oauth_token_secret: 'lsdajfh923874', 'oauth_verifier: 'w34o8967345', } """ log.debug('Parsing token from query part of url %s', url) token = dict(urldecode(urlparse(url).query)) log.debug('Updating internal client token attribute.') self._populate_attributes(token) return token def _populate_attributes(self, token): if 'oauth_token' in token: self._client.client.resource_owner_key = token['oauth_token'] else: raise TokenMissing( 'Response does not contain a token: {resp}'.format(resp=token), token, ) if 'oauth_token_secret' in token: self._client.client.resource_owner_secret = ( token['oauth_token_secret']) if 'oauth_verifier' in token: self._client.client.verifier = token['oauth_verifier'] def _fetch_token(self, url, **request_kwargs): log.debug('Fetching token from %s using client %s', url, self._client.client) r = self.post(url, **request_kwargs) if r.status_code >= 400: error = "Token request failed with code %s, response was '%s'." raise TokenRequestDenied(error % (r.status_code, r.text), r) log.debug('Decoding token from response "%s"', r.text) try: token = dict(urldecode(r.text.strip())) except ValueError as e: error = ("Unable to decode token from token response. " "This is commonly caused by an unsuccessful request where" " a non urlencoded error message is returned. " "The decoding error was %s""" % e) raise ValueError(error) log.debug('Obtained token %s', token) log.debug('Updating internal client attributes from token data.') self._populate_attributes(token) return token def rebuild_auth(self, prepared_request, response): """ When being redirected we should always strip Authorization header, since nonce may not be reused as per OAuth spec. """ if 'Authorization' in prepared_request.headers: # If we get redirected to a new host, we should strip out # any authentication headers. prepared_request.headers.pop('Authorization', True) prepared_request.prepare_auth(self.auth) return requests-oauthlib-0.8.0/requests_oauthlib/oauth2_auth.py0000644000076500000240000000300612633522042023633 0ustar corystaff00000000000000from __future__ import unicode_literals from oauthlib.oauth2 import WebApplicationClient, InsecureTransportError from oauthlib.oauth2 import is_secure_transport from requests.auth import AuthBase class OAuth2(AuthBase): """Adds proof of authorization (OAuth2 token) to the request.""" def __init__(self, client_id=None, client=None, token=None): """Construct a new OAuth 2 authorization object. :param client_id: Client id obtained during registration :param client: :class:`oauthlib.oauth2.Client` to be used. Default is WebApplicationClient which is useful for any hosted application but not mobile or desktop. :param token: Token dictionary, must include access_token and token_type. """ self._client = client or WebApplicationClient(client_id, token=token) if token: for k, v in token.items(): setattr(self._client, k, v) def __call__(self, r): """Append an OAuth 2 token to the request. Note that currently HTTPS is required for all requests. There may be a token type that allows for plain HTTP in the future and then this should be updated to allow plain HTTP on a white list basis. """ if not is_secure_transport(r.url): raise InsecureTransportError() r.url, r.headers, r.body = self._client.add_token(r.url, http_method=r.method, body=r.body, headers=r.headers) return r requests-oauthlib-0.8.0/requests_oauthlib/oauth2_session.py0000644000076500000240000004147713050616611024373 0ustar corystaff00000000000000from __future__ import unicode_literals import logging from oauthlib.common import generate_token, urldecode from oauthlib.oauth2 import WebApplicationClient, InsecureTransportError from oauthlib.oauth2 import TokenExpiredError, is_secure_transport import requests log = logging.getLogger(__name__) class TokenUpdated(Warning): def __init__(self, token): super(TokenUpdated, self).__init__() self.token = token class OAuth2Session(requests.Session): """Versatile OAuth 2 extension to :class:`requests.Session`. Supports any grant type adhering to :class:`oauthlib.oauth2.Client` spec including the four core OAuth 2 grants. Can be used to create authorization urls, fetch tokens and access protected resources using the :class:`requests.Session` interface you are used to. - :class:`oauthlib.oauth2.WebApplicationClient` (default): Authorization Code Grant - :class:`oauthlib.oauth2.MobileApplicationClient`: Implicit Grant - :class:`oauthlib.oauth2.LegacyApplicationClient`: Password Credentials Grant - :class:`oauthlib.oauth2.BackendApplicationClient`: Client Credentials Grant Note that the only time you will be using Implicit Grant from python is if you are driving a user agent able to obtain URL fragments. """ def __init__(self, client_id=None, client=None, auto_refresh_url=None, auto_refresh_kwargs=None, scope=None, redirect_uri=None, token=None, state=None, token_updater=None, **kwargs): """Construct a new OAuth 2 client session. :param client_id: Client id obtained during registration :param client: :class:`oauthlib.oauth2.Client` to be used. Default is WebApplicationClient which is useful for any hosted application but not mobile or desktop. :param scope: List of scopes you wish to request access to :param redirect_uri: Redirect URI you registered as callback :param token: Token dictionary, must include access_token and token_type. :param state: State string used to prevent CSRF. This will be given when creating the authorization url and must be supplied when parsing the authorization response. Can be either a string or a no argument callable. :auto_refresh_url: Refresh token endpoint URL, must be HTTPS. Supply this if you wish the client to automatically refresh your access tokens. :auto_refresh_kwargs: Extra arguments to pass to the refresh token endpoint. :token_updater: Method with one argument, token, to be used to update your token databse on automatic token refresh. If not set a TokenUpdated warning will be raised when a token has been refreshed. This warning will carry the token in its token argument. :param kwargs: Arguments to pass to the Session constructor. """ super(OAuth2Session, self).__init__(**kwargs) self._client = client or WebApplicationClient(client_id, token=token) self.token = token or {} self.scope = scope self.redirect_uri = redirect_uri self.state = state or generate_token self._state = state self.auto_refresh_url = auto_refresh_url self.auto_refresh_kwargs = auto_refresh_kwargs or {} self.token_updater = token_updater # Allow customizations for non compliant providers through various # hooks to adjust requests and responses. self.compliance_hook = { 'access_token_response': set([]), 'refresh_token_response': set([]), 'protected_request': set([]), } def new_state(self): """Generates a state string to be used in authorizations.""" try: self._state = self.state() log.debug('Generated new state %s.', self._state) except TypeError: self._state = self.state log.debug('Re-using previously supplied state %s.', self._state) return self._state @property def client_id(self): return getattr(self._client, "client_id", None) @client_id.setter def client_id(self, value): self._client.client_id = value @client_id.deleter def client_id(self): del self._client.client_id @property def token(self): return getattr(self._client, "token", None) @token.setter def token(self, value): self._client.token = value self._client._populate_attributes(value) @property def access_token(self): return getattr(self._client, "access_token", None) @access_token.setter def access_token(self, value): self._client.access_token = value @access_token.deleter def access_token(self): del self._client.access_token @property def authorized(self): """Boolean that indicates whether this session has an OAuth token or not. If `self.authorized` is True, you can reasonably expect OAuth-protected requests to the resource to succeed. If `self.authorized` is False, you need the user to go through the OAuth authentication dance before OAuth-protected requests to the resource will succeed. """ return bool(self.access_token) def authorization_url(self, url, state=None, **kwargs): """Form an authorization URL. :param url: Authorization endpoint url, must be HTTPS. :param state: An optional state string for CSRF protection. If not given it will be generated for you. :param kwargs: Extra parameters to include. :return: authorization_url, state """ state = state or self.new_state() return self._client.prepare_request_uri(url, redirect_uri=self.redirect_uri, scope=self.scope, state=state, **kwargs), state def fetch_token(self, token_url, code=None, authorization_response=None, body='', auth=None, username=None, password=None, method='POST', timeout=None, headers=None, verify=True, proxies=None, **kwargs): """Generic method for fetching an access token from the token endpoint. If you are using the MobileApplicationClient you will want to use token_from_fragment instead of fetch_token. :param token_url: Token endpoint URL, must use HTTPS. :param code: Authorization code (used by WebApplicationClients). :param authorization_response: Authorization response URL, the callback URL of the request back to you. Used by WebApplicationClients instead of code. :param body: Optional application/x-www-form-urlencoded body to add the include in the token request. Prefer kwargs over body. :param auth: An auth tuple or method as accepted by requests. :param username: Username used by LegacyApplicationClients. :param password: Password used by LegacyApplicationClients. :param method: The HTTP method used to make the request. Defaults to POST, but may also be GET. Other methods should be added as needed. :param headers: Dict to default request headers with. :param timeout: Timeout of the request in seconds. :param verify: Verify SSL certificate. :param kwargs: Extra parameters to include in the token request. :return: A token dict """ if not is_secure_transport(token_url): raise InsecureTransportError() if not code and authorization_response: self._client.parse_request_uri_response(authorization_response, state=self._state) code = self._client.code elif not code and isinstance(self._client, WebApplicationClient): code = self._client.code if not code: raise ValueError('Please supply either code or ' 'authorization_response parameters.') body = self._client.prepare_request_body(code=code, body=body, redirect_uri=self.redirect_uri, username=username, password=password, **kwargs) client_id = kwargs.get('client_id', '') if auth is None: if client_id: log.debug('Encoding client_id "%s" with client_secret as Basic auth credentials.', client_id) client_secret = kwargs.get('client_secret', '') client_secret = client_secret if client_secret is not None else '' auth = requests.auth.HTTPBasicAuth(client_id, client_secret) elif username: if password is None: raise ValueError('Username was supplied, but not password.') log.debug('Encoding username, password as Basic auth credentials.') auth = requests.auth.HTTPBasicAuth(username, password) headers = headers or { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', } self.token = {} if method.upper() == 'POST': r = self.post(token_url, data=dict(urldecode(body)), timeout=timeout, headers=headers, auth=auth, verify=verify, proxies=proxies) log.debug('Prepared fetch token request body %s', body) elif method.upper() == 'GET': # if method is not 'POST', switch body to querystring and GET r = self.get(token_url, params=dict(urldecode(body)), timeout=timeout, headers=headers, auth=auth, verify=verify, proxies=proxies) log.debug('Prepared fetch token request querystring %s', body) else: raise ValueError('The method kwarg must be POST or GET.') log.debug('Request to fetch token completed with status %s.', r.status_code) log.debug('Request headers were %s', r.request.headers) log.debug('Request body was %s', r.request.body) log.debug('Response headers were %s and content %s.', r.headers, r.text) log.debug('Invoking %d token response hooks.', len(self.compliance_hook['access_token_response'])) for hook in self.compliance_hook['access_token_response']: log.debug('Invoking hook %s.', hook) r = hook(r) self._client.parse_request_body_response(r.text, scope=self.scope) self.token = self._client.token log.debug('Obtained token %s.', self.token) return self.token def token_from_fragment(self, authorization_response): """Parse token from the URI fragment, used by MobileApplicationClients. :param authorization_response: The full URL of the redirect back to you :return: A token dict """ self._client.parse_request_uri_response(authorization_response, state=self._state) self.token = self._client.token return self.token def refresh_token(self, token_url, refresh_token=None, body='', auth=None, timeout=None, headers=None, verify=True, proxies=None, **kwargs): """Fetch a new access token using a refresh token. :param token_url: The token endpoint, must be HTTPS. :param refresh_token: The refresh_token to use. :param body: Optional application/x-www-form-urlencoded body to add the include in the token request. Prefer kwargs over body. :param auth: An auth tuple or method as accepted by requests. :param timeout: Timeout of the request in seconds. :param verify: Verify SSL certificate. :param kwargs: Extra parameters to include in the token request. :return: A token dict """ if not token_url: raise ValueError('No token endpoint set for auto_refresh.') if not is_secure_transport(token_url): raise InsecureTransportError() refresh_token = refresh_token or self.token.get('refresh_token') log.debug('Adding auto refresh key word arguments %s.', self.auto_refresh_kwargs) kwargs.update(self.auto_refresh_kwargs) body = self._client.prepare_refresh_body(body=body, refresh_token=refresh_token, scope=self.scope, **kwargs) log.debug('Prepared refresh token request body %s', body) if headers is None: headers = { 'Accept': 'application/json', 'Content-Type': ( 'application/x-www-form-urlencoded;charset=UTF-8' ), } r = self.post(token_url, data=dict(urldecode(body)), auth=auth, timeout=timeout, headers=headers, verify=verify, withhold_token=True, proxies=proxies) log.debug('Request to refresh token completed with status %s.', r.status_code) log.debug('Response headers were %s and content %s.', r.headers, r.text) log.debug('Invoking %d token response hooks.', len(self.compliance_hook['refresh_token_response'])) for hook in self.compliance_hook['refresh_token_response']: log.debug('Invoking hook %s.', hook) r = hook(r) self.token = self._client.parse_request_body_response(r.text, scope=self.scope) if not 'refresh_token' in self.token: log.debug('No new refresh token given. Re-using old.') self.token['refresh_token'] = refresh_token return self.token def request(self, method, url, data=None, headers=None, withhold_token=False, client_id=None, client_secret=None, **kwargs): """Intercept all requests and add the OAuth 2 token if present.""" if not is_secure_transport(url): raise InsecureTransportError() if self.token and not withhold_token: log.debug('Invoking %d protected resource request hooks.', len(self.compliance_hook['protected_request'])) for hook in self.compliance_hook['protected_request']: log.debug('Invoking hook %s.', hook) url, headers, data = hook(url, headers, data) log.debug('Adding token %s to request.', self.token) try: url, headers, data = self._client.add_token(url, http_method=method, body=data, headers=headers) # Attempt to retrieve and save new access token if expired except TokenExpiredError: if self.auto_refresh_url: log.debug('Auto refresh is set, attempting to refresh at %s.', self.auto_refresh_url) # We mustn't pass auth twice. auth = kwargs.pop('auth', None) if client_id and client_secret and (auth is None): log.debug('Encoding client_id "%s" with client_secret as Basic auth credentials.', client_id) auth = requests.auth.HTTPBasicAuth(client_id, client_secret) token = self.refresh_token( self.auto_refresh_url, auth=auth, **kwargs ) if self.token_updater: log.debug('Updating token to %s using %s.', token, self.token_updater) self.token_updater(token) url, headers, data = self._client.add_token(url, http_method=method, body=data, headers=headers) else: raise TokenUpdated(token) else: raise log.debug('Requesting url %s using method %s.', url, method) log.debug('Supplying headers %s and data %s', headers, data) log.debug('Passing through key word arguments %s.', kwargs) return super(OAuth2Session, self).request(method, url, headers=headers, data=data, **kwargs) def register_compliance_hook(self, hook_type, hook): """Register a hook for request/response tweaking. Available hooks are: access_token_response invoked before token parsing. refresh_token_response invoked before refresh token parsing. protected_request invoked before making a request. If you find a new hook is needed please send a GitHub PR request or open an issue. """ if hook_type not in self.compliance_hook: raise ValueError('Hook type %s is not in %s.', hook_type, self.compliance_hook) self.compliance_hook[hook_type].add(hook) requests-oauthlib-0.8.0/requests_oauthlib.egg-info/0000755000076500000240000000000013050617554022540 5ustar corystaff00000000000000requests-oauthlib-0.8.0/requests_oauthlib.egg-info/dependency_links.txt0000644000076500000240000000000113050617553026605 0ustar corystaff00000000000000 requests-oauthlib-0.8.0/requests_oauthlib.egg-info/not-zip-safe0000644000076500000240000000000112201450504024751 0ustar corystaff00000000000000 requests-oauthlib-0.8.0/requests_oauthlib.egg-info/PKG-INFO0000644000076500000240000002112113050617553023631 0ustar corystaff00000000000000Metadata-Version: 1.1 Name: requests-oauthlib Version: 0.8.0 Summary: OAuthlib authentication support for Requests. Home-page: https://github.com/requests/requests-oauthlib Author: Kenneth Reitz Author-email: me@kennethreitz.com License: ISC Description: Requests-OAuthlib |build-status| |coverage-status| |docs| ========================================================= This project provides first-class OAuth library support for `Requests `_. The OAuth 1 workflow -------------------- OAuth 1 can seem overly complicated and it sure has its quirks. Luckily, requests_oauthlib hides most of these and let you focus at the task at hand. Accessing protected resources using requests_oauthlib is as simple as: .. code-block:: pycon >>> from requests_oauthlib import OAuth1Session >>> twitter = OAuth1Session('client_key', client_secret='client_secret', resource_owner_key='resource_owner_key', resource_owner_secret='resource_owner_secret') >>> url = 'https://api.twitter.com/1/account/settings.json' >>> r = twitter.get(url) Before accessing resources you will need to obtain a few credentials from your provider (i.e. Twitter) and authorization from the user for whom you wish to retrieve resources for. You can read all about this in the full `OAuth 1 workflow guide on RTD `_. The OAuth 2 workflow -------------------- OAuth 2 is generally simpler than OAuth 1 but comes in more flavours. The most common being the Authorization Code Grant, also known as the WebApplication flow. Fetching a protected resource after obtaining an access token can be extremely simple. However, before accessing resources you will need to obtain a few credentials from your provider (i.e. Google) and authorization from the user for whom you wish to retrieve resources for. You can read all about this in the full `OAuth 2 workflow guide on RTD `_. Installation ------------- To install requests and requests_oauthlib you can use pip: .. code-block:: bash $ pip install requests requests_oauthlib .. |build-status| image:: https://travis-ci.org/requests/requests-oauthlib.svg?branch=master :target: https://travis-ci.org/requests/requests-oauthlib .. |coverage-status| image:: https://img.shields.io/coveralls/requests/requests-oauthlib.svg :target: https://coveralls.io/r/requests/requests-oauthlib .. |docs| image:: https://readthedocs.org/projects/requests-oauthlib/badge/?version=latest :alt: Documentation Status :scale: 100% :target: https://readthedocs.org/projects/requests-oauthlib/ History ------- v0.8.0 (14 February 2017) +++++++++++++++++++++++++ - Added Fitbit compliance fix. - Fixed an issue where newlines in the response body for the access token request would cause errors when trying to extract the token. - Fixed an issue introduced in v0.7.0 where users passing ``auth`` to several methods would encounter conflicts with the ``client_id`` and ``client_secret``-derived auth. The user-supplied ``auth`` argument is now used in preference to those options. v0.7.0 (22 September 2016) ++++++++++++++++++++++++++ - Allowed ``OAuth2Session.request`` to take the ``client_id`` and ``client_secret`` parameters for the purposes of automatic token refresh, which may need them. v0.6.2 (12 July 2016) +++++++++++++++++++++ - Use ``client_id`` and ``client_secret`` for the Authorization header if provided. - Allow explicit bypass of the Authorization header by setting ``auth=False``. - Pass through the ``proxies`` kwarg when refreshing tokens. - Miscellaneous cleanups. v0.6.1 (19 February 2016) +++++++++++++++++++++++++ - Fixed a bug when sending authorization in headers with no username and password present. - Make sure we clear the session token before obtaining a new one. - Some improvements to the Slack compliance fix. - Avoid timing problems around token refresh. - Allow passing arbitrary arguments to requests when calling ``fetch_request_token`` and ``fetch_access_token``. v0.6.0 (14 December 2015) +++++++++++++++++++++++++ - Add compliance fix for Slack. - Add compliance fix for Mailchimp. - ``TokenRequestDenied`` exceptions now carry the entire response, not just the status code. - Pass through keyword arguments when refreshing tokens automatically. - Send authorization in headers, not just body, to maximize compatibility. - More getters/setters available for OAuth2 session client values. - Allow sending custom headers when refreshing tokens, and set some defaults. v0.5.0 (4 May 2015) +++++++++++++++++++ - Fix ``TypeError`` being raised instead of ``TokenMissing`` error. - Raise requests exceptions on 4XX and 5XX responses in the OAuth2 flow. - Avoid ``AttributeError`` when initializing the ``OAuth2Session`` class without complete client information. v0.4.2 (16 October 2014) ++++++++++++++++++++++++ - New ``authorized`` property on OAuth1Session and OAuth2Session, which allows you to easily determine if the session is already authorized with OAuth tokens or not. - New ``TokenMissing`` and ``VerifierMissing`` exception classes for OAuth1Session: this will make it easier to catch and identify these exceptions. v0.4.1 (6 June 2014) ++++++++++++++++++++ - New install target ``[rsa]`` for people using OAuth1 RSA-SHA1 signature method. - Fixed bug in OAuth2 where supplied state param was not used in auth url. - OAuth2 HTTPS checking can be disabled by setting environment variable ``OAUTHLIB_INSECURE_TRANSPORT``. - OAuth1 now re-authorize upon redirects. - OAuth1 token fetching now raise a detailed error message when the response body is incorrectly encoded or the request was denied. - Added support for custom OAuth1 clients. - OAuth2 compliance fix for Sina Weibo. - Multiple fixes to facebook compliance fix. - Compliance fixes now re-encode body properly as bytes in Python 3. - Logging now properly done under ``requests_oauthlib`` namespace instead of piggybacking on oauthlib namespace. - Logging introduced for OAuth1 auth and session. v0.4.0 (29 September 2013) ++++++++++++++++++++++++++ - OAuth1Session methods only return unicode strings. #55. - Renamed requests_oauthlib.core to requests_oauthlib.oauth1_auth for consistency. #79. - Added Facebook compliance fix and access_token_response hook to OAuth2Session. #63. - Added LinkedIn compliance fix. - Added refresh_token_response compliance hook, invoked before parsing the refresh token. - Correctly limit compliance hooks to running only once! - Content type guessing should only be done when no content type is given - OAuth1 now updates r.headers instead of replacing it with non case insensitive dict - Remove last use of Response.content (in OAuth1Session). #44. - State param can now be supplied in OAuth2Session.authorize_url Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Natural Language :: English Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 requests-oauthlib-0.8.0/requests_oauthlib.egg-info/requires.txt0000644000076500000240000000011413050617553025133 0ustar corystaff00000000000000oauthlib>=0.6.2 requests>=2.0.0 [rsa] oauthlib[rsa]>=0.6.2 requests>=2.0.0 requests-oauthlib-0.8.0/requests_oauthlib.egg-info/SOURCES.txt0000644000076500000240000000530113050617553024422 0ustar corystaff00000000000000AUTHORS.rst HISTORY.rst LICENSE MANIFEST.in README.rst requirements.txt setup.cfg setup.py docs/Makefile docs/api.rst docs/conf.py docs/index.rst docs/make.bat docs/oauth1_workflow.rst docs/oauth2_workflow.rst docs/examples/bitbucket.rst docs/examples/examples.rst docs/examples/facebook.rst docs/examples/github.rst docs/examples/google.rst docs/examples/linkedin.rst docs/examples/mediawiki.rst docs/examples/outlook.rst docs/examples/real_world_example.rst docs/examples/real_world_example_with_refresh.rst docs/examples/tumblr.rst requests_oauthlib/__init__.py requests_oauthlib/oauth1_auth.py requests_oauthlib/oauth1_session.py requests_oauthlib/oauth2_auth.py requests_oauthlib/oauth2_session.py requests_oauthlib.egg-info/PKG-INFO requests_oauthlib.egg-info/SOURCES.txt requests_oauthlib.egg-info/dependency_links.txt requests_oauthlib.egg-info/not-zip-safe requests_oauthlib.egg-info/requires.txt requests_oauthlib.egg-info/top_level.txt requests_oauthlib/compliance_fixes/__init__.py requests_oauthlib/compliance_fixes/douban.py requests_oauthlib/compliance_fixes/facebook.py requests_oauthlib/compliance_fixes/fitbit.py requests_oauthlib/compliance_fixes/linkedin.py requests_oauthlib/compliance_fixes/mailchimp.py requests_oauthlib/compliance_fixes/slack.py requests_oauthlib/compliance_fixes/weibo.py tests/__init__.py tests/__init__.pyc tests/test.bin tests/test_compliance_fixes.py tests/test_compliance_fixes.pyc tests/test_core.py tests/test_core.pyc tests/test_oauth1_session.py tests/test_oauth1_session.pyc tests/test_oauth2_auth.py tests/test_oauth2_auth.pyc tests/test_oauth2_session.py tests/test_oauth2_session.pyc tests/__pycache__/__init__.cpython-33.pyc tests/__pycache__/__init__.cpython-34.pyc tests/__pycache__/__init__.cpython-35.pyc tests/__pycache__/test_compliance_fixes.cpython-33.pyc tests/__pycache__/test_compliance_fixes.cpython-34.pyc tests/__pycache__/test_compliance_fixes.cpython-35.pyc tests/__pycache__/test_core.cpython-27-PYTEST.pyc tests/__pycache__/test_core.cpython-33.pyc tests/__pycache__/test_core.cpython-34.pyc tests/__pycache__/test_core.cpython-35.pyc tests/__pycache__/test_oauth1_session.cpython-27-PYTEST.pyc tests/__pycache__/test_oauth1_session.cpython-33.pyc tests/__pycache__/test_oauth1_session.cpython-34.pyc tests/__pycache__/test_oauth1_session.cpython-35.pyc tests/__pycache__/test_oauth2_auth.cpython-27-PYTEST.pyc tests/__pycache__/test_oauth2_auth.cpython-33.pyc tests/__pycache__/test_oauth2_auth.cpython-34.pyc tests/__pycache__/test_oauth2_auth.cpython-35.pyc tests/__pycache__/test_oauth2_session.cpython-27-PYTEST.pyc tests/__pycache__/test_oauth2_session.cpython-33.pyc tests/__pycache__/test_oauth2_session.cpython-34.pyc tests/__pycache__/test_oauth2_session.cpython-35.pycrequests-oauthlib-0.8.0/requests_oauthlib.egg-info/top_level.txt0000644000076500000240000000002213050617553025263 0ustar corystaff00000000000000requests_oauthlib requests-oauthlib-0.8.0/requirements.txt0000644000076500000240000000005512620061233020555 0ustar corystaff00000000000000requests>=2.0.0 oauthlib[signedtoken]>=0.6.2 requests-oauthlib-0.8.0/setup.cfg0000644000076500000240000000010313050617554017117 0ustar corystaff00000000000000[bdist_wheel] universal = 1 [egg_info] tag_build = tag_date = 0 requests-oauthlib-0.8.0/setup.py0000644000076500000240000000363512661635562017033 0ustar corystaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import os import sys import re try: from setuptools import setup except ImportError: from distutils.core import setup # Get the version version_regex = r'__version__ = ["\']([^"\']*)["\']' with open('requests_oauthlib/__init__.py', 'r') as f: text = f.read() match = re.search(version_regex, text) if match: VERSION = match.group(1) else: raise RuntimeError("No version number found!") APP_NAME = 'requests-oauthlib' settings = dict() # Publish Helper. if sys.argv[-1] == 'publish': os.system('python setup.py sdist upload') sys.exit() tests_require = ['mock', 'requests-mock'] if sys.version_info < (2, 7): # Python 2.6 or lower tests_require.append('unittest2') settings.update( name=APP_NAME, version=VERSION, description='OAuthlib authentication support for Requests.', long_description=open('README.rst').read() + '\n\n' + open('HISTORY.rst').read(), author='Kenneth Reitz', author_email='me@kennethreitz.com', url='https://github.com/requests/requests-oauthlib', packages=['requests_oauthlib', 'requests_oauthlib.compliance_fixes'], install_requires=['oauthlib>=0.6.2', 'requests>=2.0.0'], extras_require={'rsa': ['oauthlib[rsa]>=0.6.2', 'requests>=2.0.0']}, license='ISC', classifiers=( 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Natural Language :: English', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', ), zip_safe=False, tests_require=tests_require, test_suite='tests' ) setup(**settings) requests-oauthlib-0.8.0/tests/0000755000076500000240000000000013050617554016446 5ustar corystaff00000000000000requests-oauthlib-0.8.0/tests/__init__.py0000644000076500000240000000000012201441447020536 0ustar corystaff00000000000000requests-oauthlib-0.8.0/tests/__init__.pyc0000644000076500000240000000024412770743363020730 0ustar corystaff00000000000000 'CRcsdS(N((((tM/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/__init__.pytsrequests-oauthlib-0.8.0/tests/__pycache__/0000755000076500000240000000000013050617554020656 5ustar corystaff00000000000000requests-oauthlib-0.8.0/tests/__pycache__/__init__.cpython-33.pyc0000644000076500000240000000025412633523103025031 0ustar corystaff00000000000000 'CRc@sdS(N((((uM/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/__init__.pyusrequests-oauthlib-0.8.0/tests/__pycache__/__init__.cpython-34.pyc0000644000076500000240000000024012617164042025032 0ustar corystaff00000000000000 'CR@sdS)NrrrM/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/__init__.pysrequests-oauthlib-0.8.0/tests/__pycache__/__init__.cpython-35.pyc0000644000076500000240000000024012633523122025027 0ustar corystaff00000000000000 'CR@sdS)NrrrM/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/__init__.pysrequests-oauthlib-0.8.0/tests/__pycache__/test_compliance_fixes.cpython-33.pyc0000644000076500000240000003167012770742377027671 0ustar corystaff00000000000000 r;Vc@sddlmZyddlmZWn"ek rHddlmZYnXddlZddlZddlZyddl m Z m Z Wn(ek rddl m Z m Z YnXddl m Z ddlmZddlmZddlmZdd lmZdd lmZGd d d eZGd ddeZGdddeZGdddeZGdddeZdS(i(uunicode_literals(uTestCaseN(uurlparseuparse_qs(u OAuth2Session(ufacebook_compliance_fix(ulinkedin_compliance_fix(umailchimp_compliance_fix(uweibo_compliance_fix(uslack_compliance_fixcBs,|EeZdZddZddZdS(uFacebookComplianceFixTestcCsktj}|jddddidd6|j|j|jtddd }t||_dS( Nu-https://graph.facebook.com/oauth/access_tokenutextuaccess_token=urlencodeduheadersu text/plainu Content-Typeufoou redirect_uriu https://i.b( u requests_mockuMockerupostustartu addCleanupustopu OAuth2Sessionufacebook_compliance_fixusession(uselfumockerufacebook((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyusetUps  uFacebookComplianceFixTest.setUpcCs@|jjddddd}|j|idd6dd 6dS( Nu-https://graph.facebook.com/oauth/access_tokenu client_secretubaruauthorization_responseuhttps://i.b/?code=hellou urlencodedu access_tokenuBeareru token_type(usessionu fetch_tokenu assertEqual(uselfutoken((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyutest_fetch_access_token&s   u1FacebookComplianceFixTest.test_fetch_access_tokenN(u__name__u __module__u __qualname__usetUputest_fetch_access_token(u __locals__((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyuFacebookComplianceFixTests uFacebookComplianceFixTestcBs8|EeZdZddZddZddZdS(uLinkedInComplianceFixTestcCstj}|jddidd6|jddddidd 6d d 6|j|j|jtd d d}t||_dS(Nu/https://www.linkedin.com/uas/oauth2/accessTokenujsonulinkedinu access_tokenu+https://api.linkedin.com/v1/people/~/sharesu status_codeiuUPDATE-3346389-595113200u updateKeyu6https://www.linkedin.com/updates?discuss=abc&scope=xyzu updateUrlufoou redirect_uriu https://i.b( u requests_mockuMockerupostustartu addCleanupustopu OAuth2Sessionulinkedin_compliance_fixusession(uselfumockerulinkedin((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyusetUp1s   uLinkedInComplianceFixTest.setUpcCs@|jjddddd}|j|idd6dd 6dS( Nu/https://www.linkedin.com/uas/oauth2/accessTokenu client_secretubaruauthorization_responseuhttps://i.b/?code=helloulinkedinu access_tokenuBeareru token_type(usessionu fetch_tokenu assertEqual(uselfutoken((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyutest_fetch_access_tokenEs   u1LinkedInComplianceFixTest.test_fetch_access_tokencCsaidd6|j_|jjd}|jj}tt|j}|j|ddgdS(Nudummy-access-tokenu access_tokenu+https://api.linkedin.com/v1/people/~/sharesuoauth2_access_token( usessionutokenuposturequestuurluparse_qsuurlparseuqueryu assertEqual(uselfuresponseuurluquery((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyutest_protected_requestMs    u0LinkedInComplianceFixTest.test_protected_requestN(u__name__u __module__u __qualname__usetUputest_fetch_access_tokenutest_protected_request(u __locals__((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyuLinkedInComplianceFixTest/s  uLinkedInComplianceFixTestcBs,|EeZdZddZddZdS(uMailChimpComplianceFixTestcCsstj}|jddidd6dd6dd6|j|j|jtdd d }t||_ dS( Nu(https://login.mailchimp.com/oauth2/tokenujsonu mailchimpu access_tokeniu expires_inuscopeufoou redirect_uriu https://i.b( u requests_mockuMockerupostuNoneustartu addCleanupustopu OAuth2Sessionumailchimp_compliance_fixusession(uselfumockeru mailchimp((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyusetUpYs  u MailChimpComplianceFixTest.setUpcCs|jjddddd}tjd}|jd}|j||dd |j|id d 6dd 6|jd |dS(Nu(https://login.mailchimp.com/oauth2/tokenu client_secretubaruauthorization_responseuhttps://i.b/?code=helloiu expires_atuplacesiu mailchimpu access_tokenu expires_inuscope(usessionu fetch_tokenutimeupopuassertAlmostEqualu assertEqualu assertNotIn(uselfutokenuapprox_expires_atuactual_expires_at((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyutest_fetch_access_tokenes  u2MailChimpComplianceFixTest.test_fetch_access_tokenN(u__name__u __module__u __qualname__usetUputest_fetch_access_token(u __locals__((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyuMailChimpComplianceFixTestWs uMailChimpComplianceFixTestcBs,|EeZdZddZddZdS(uWeiboComplianceFixTestcCsetj}|jddidd6|j|j|jtddd}t||_dS(Nu)https://api.weibo.com/oauth2/access_tokenujsonuweibou access_tokenufoou redirect_uriu https://i.b( u requests_mockuMockerupostustartu addCleanupustopu OAuth2Sessionuweibo_compliance_fixusession(uselfumockeruweibo((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyusetUpys  uWeiboComplianceFixTest.setUpcCs@|jjddddd}|j|idd6dd 6dS( Nu)https://api.weibo.com/oauth2/access_tokenu client_secretubaruauthorization_responseuhttps://i.b/?code=hellouweibou access_tokenuBeareru token_type(usessionu fetch_tokenu assertEqual(uselfutoken((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyutest_fetch_access_tokens   u.WeiboComplianceFixTest.test_fetch_access_tokenN(u__name__u __module__u __qualname__usetUputest_fetch_access_token(u __locals__((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyuWeiboComplianceFixTestws uWeiboComplianceFixTestcBsP|EeZdZddZddZddZddZd d Zd S( uSlackComplianceFixTestc Cstj}|jddidd6dd6xTdD]L}|jd |d d didd 6d d 6dd6dd6dd6dd6q4W|j|j|jtddd}t ||_ dS(Nu"https://slack.com/api/oauth.accessujsonuxoxt-23984754863-2348975623103u access_tokenureaduscopeuGETuPOSTumethoduurluhttps://slack.com/api/auth.testuokuhttps://myteam.slack.com/uMy TeamuteamucaluuseruT12345uteam_iduU12345uuser_idufoou redirect_uriu https://i.b(uGETuPOSTT( u requests_mockuMockeruposturequestuTrueustartu addCleanupustopu OAuth2Sessionuslack_compliance_fixusession(uselfumockerumethoduslack((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyusetUps*     uSlackComplianceFixTest.setUpcCsidd6|j_|jjd}|jj}tt|j}|jd||jj }t|}|j |ddgdS(Nudummy-access-tokenu access_tokenuhttps://slack.com/api/auth.testutoken( usessionutokenugeturequestuurluparse_qsuurlparseuqueryu assertNotInubodyu assertEqual(uselfuresponseuurluqueryubodyudata((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyutest_protected_requests     u-SlackComplianceFixTest.test_protected_requestcCsidd6|j_|jjddidd6}|jj}tt|j}|jd||jj }t|}|j |ddgdS(Nudummy-access-tokenu access_tokenuhttps://slack.com/api/auth.testudataudifferent-tokenutoken( usessionutokenugeturequestuurluparse_qsuurlparseuqueryu assertNotInubodyu assertEqual(uselfuresponseuurluqueryubodyudata((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyu)test_protected_request_override_token_gets    u@SlackComplianceFixTest.test_protected_request_override_token_getcCsidd6|j_|jjddidd6}|jj}tt|j}|jd||jj }t|}|j |ddgdS(Nudummy-access-tokenu access_tokenuhttps://slack.com/api/auth.testudataudifferent-tokenutoken( usessionutokenuposturequestuurluparse_qsuurlparseuqueryu assertNotInubodyu assertEqual(uselfuresponseuurluqueryubodyudata((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyu*test_protected_request_override_token_posts    uASlackComplianceFixTest.test_protected_request_override_token_postcCstidd6|j_|jjd}|jj}tt|j}|j|ddg|j |jj dS(Nudummy-access-tokenu access_tokenu5https://slack.com/api/auth.test?token=different-tokenutokenudifferent-token( usessionutokenugeturequestuurluparse_qsuurlparseuqueryu assertEqualu assertIsNoneubody(uselfuresponseuurluquery((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyu)test_protected_request_override_token_urls   u@SlackComplianceFixTest.test_protected_request_override_token_urlN(u__name__u __module__u __qualname__usetUputest_protected_requestu)test_protected_request_override_token_getu*test_protected_request_override_token_postu)test_protected_request_override_token_url(u __locals__((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyuSlackComplianceFixTests   uSlackComplianceFixTest(u __future__uunicode_literalsu unittest2uTestCaseu ImportErroruunittesturequestsu requests_mockutimeuurlparseuparse_qsu urllib.parseurequests_oauthlibu OAuth2Sessionu"requests_oauthlib.compliance_fixesufacebook_compliance_fixulinkedin_compliance_fixumailchimp_compliance_fixuweibo_compliance_fixuslack_compliance_fixuFacebookComplianceFixTestuLinkedInComplianceFixTestuMailChimpComplianceFixTestuWeiboComplianceFixTestuSlackComplianceFixTest(((uZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pyus,     ( requests-oauthlib-0.8.0/tests/__pycache__/test_compliance_fixes.cpython-34.pyc0000644000076500000240000002012012770742404027645 0ustar corystaff00000000000000 r;V@sddlmZyddlmZWn"ek rHddlmZYnXddlZddlZddlZyddl m Z m Z Wn(ek rddl m Z m Z YnXddl m Z ddlmZddlmZddlmZdd lmZdd lmZGd d d eZGd ddeZGdddeZGdddeZGdddeZdS))unicode_literals)TestCaseN)urlparseparse_qs) OAuth2Session)facebook_compliance_fix)linkedin_compliance_fix)mailchimp_compliance_fix)weibo_compliance_fix)slack_compliance_fixc@s(eZdZddZddZdS)FacebookComplianceFixTestcCsktj}|jddddidd6|j|j|jtddd }t||_dS) Nz-https://graph.facebook.com/oauth/access_tokentextzaccess_token=urlencodedheadersz text/plainz Content-Typefoo redirect_uriz https://i.b) requests_mockMockerpoststart addCleanupstoprrsession)selfmockerfacebookrZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pysetUps  zFacebookComplianceFixTest.setUpcCs@|jjddddd}|j|idd6dd 6dS) Nz-https://graph.facebook.com/oauth/access_token client_secretbarauthorization_responsezhttps://i.b/?code=hello urlencoded access_tokenBearer token_type)r fetch_token assertEqual)rtokenrrrtest_fetch_access_token&s   z1FacebookComplianceFixTest.test_fetch_access_tokenN)__name__ __module__ __qualname__rr(rrrrr s  r c@s4eZdZddZddZddZdS)LinkedInComplianceFixTestcCstj}|jddidd6|jddddidd 6d d 6|j|j|jtd d d}t||_dS)Nz/https://www.linkedin.com/uas/oauth2/accessTokenjsonlinkedinr"z+https://api.linkedin.com/v1/people/~/shares status_codezUPDATE-3346389-595113200Z updateKeyz6https://www.linkedin.com/updates?discuss=abc&scope=xyzZ updateUrlrrz https://i.b) rrrrrrrrr)rrr.rrrr1s   zLinkedInComplianceFixTest.setUpcCs@|jjddddd}|j|idd6dd 6dS) Nz/https://www.linkedin.com/uas/oauth2/accessTokenrrr zhttps://i.b/?code=hellor.r"r#r$)rr%r&)rr'rrrr(Es   z1LinkedInComplianceFixTest.test_fetch_access_tokencCsaidd6|j_|jjd}|jj}tt|j}|j|ddgdS)Nzdummy-access-tokenr"z+https://api.linkedin.com/v1/people/~/sharesoauth2_access_token) rr'rrequesturlrrqueryr&)rresponser3r4rrrtest_protected_requestMs    z0LinkedInComplianceFixTest.test_protected_requestN)r)r*r+rr(r6rrrrr,/s   r,c@s(eZdZddZddZdS)MailChimpComplianceFixTestcCsstj}|jddidd6dd6dd6|j|j|jtdd d }t||_dS) Nz(https://login.mailchimp.com/oauth2/tokenr- mailchimpr"r expires_inscoperrz https://i.b) rrrrrrrr r)rrr8rrrrYs  z MailChimpComplianceFixTest.setUpcCs|jjddddd}tjd}|jd}|j||dd |j|id d 6dd 6|jd |dS)Nz(https://login.mailchimp.com/oauth2/tokenrrr zhttps://i.b/?code=helloi expires_atplacesr8r"r9r:)rr%timepopassertAlmostEqualr& assertNotIn)rr'Zapprox_expires_atZactual_expires_atrrrr(es  z2MailChimpComplianceFixTest.test_fetch_access_tokenN)r)r*r+rr(rrrrr7Ws  r7c@s(eZdZddZddZdS)WeiboComplianceFixTestcCsetj}|jddidd6|j|j|jtddd}t||_dS)Nz)https://api.weibo.com/oauth2/access_tokenr-weibor"rrz https://i.b) rrrrrrrr r)rrrCrrrrys  zWeiboComplianceFixTest.setUpcCs@|jjddddd}|j|idd6dd 6dS) Nz)https://api.weibo.com/oauth2/access_tokenrrr zhttps://i.b/?code=hellorCr"r#r$)rr%r&)rr'rrrr(s   z.WeiboComplianceFixTest.test_fetch_access_tokenN)r)r*r+rr(rrrrrBws  rBc@sLeZdZddZddZddZddZd d Zd S) SlackComplianceFixTestc Cstj}|jddidd6dd6xTdD]L}|jd |d d did d 6dd 6dd6dd6dd6dd6q4W|j|j|jtddd}t||_ dS)Nz"https://slack.com/api/oauth.accessr-zxoxt-23984754863-2348975623103r"readr:GETPOSTmethodr3zhttps://slack.com/api/auth.testTokzhttps://myteam.slack.com/zMy TeamZteamcaluserZT12345Zteam_idZU12345Zuser_idrrz https://i.b)zGETzPOST) rrrr2rrrrr r)rrrHslackrrrrs*     zSlackComplianceFixTest.setUpcCsidd6|j_|jjd}|jj}tt|j}|jd||jj }t|}|j |ddgdS)Nzdummy-access-tokenr"zhttps://slack.com/api/auth.testr') rr'getr2r3rrr4rAbodyr&)rr5r3r4rNdatarrrr6s     z-SlackComplianceFixTest.test_protected_requestcCsidd6|j_|jjddidd6}|jj}tt|j}|jd||jj }t|}|j |ddgdS)Nzdummy-access-tokenr"zhttps://slack.com/api/auth.testrOzdifferent-tokenr') rr'rMr2r3rrr4rArNr&)rr5r3r4rNrOrrr)test_protected_request_override_token_gets    z@SlackComplianceFixTest.test_protected_request_override_token_getcCsidd6|j_|jjddidd6}|jj}tt|j}|jd||jj }t|}|j |ddgdS)Nzdummy-access-tokenr"zhttps://slack.com/api/auth.testrOzdifferent-tokenr') rr'rr2r3rrr4rArNr&)rr5r3r4rNrOrrr*test_protected_request_override_token_posts    zASlackComplianceFixTest.test_protected_request_override_token_postcCstidd6|j_|jjd}|jj}tt|j}|j|ddg|j |jj dS)Nzdummy-access-tokenr"z5https://slack.com/api/auth.test?token=different-tokenr'zdifferent-token) rr'rMr2r3rrr4r& assertIsNonerN)rr5r3r4rrr)test_protected_request_override_token_urls   z@SlackComplianceFixTest.test_protected_request_override_token_urlN)r)r*r+rr6rPrQrSrrrrrDs   rD) __future__rZ unittest2r ImportErrorunittestrequestsrr>rr urllib.parserequests_oauthlibrZ"requests_oauthlib.compliance_fixesrrr r r r r,r7rBrDrrrrs,     ( requests-oauthlib-0.8.0/tests/__pycache__/test_compliance_fixes.cpython-35.pyc0000644000076500000240000002005312770742411027651 0ustar corystaff00000000000000 r;V@sddlmZyddlmZWn"ek rHddlmZYnXddlZddlZddlZyddl m Z m Z Wn(ek rddl m Z m Z YnXddl m Z ddlmZddlmZddlmZdd lmZdd lmZGd d d eZGd ddeZGdddeZGdddeZGdddeZdS))unicode_literals)TestCaseN)urlparseparse_qs) OAuth2Session)facebook_compliance_fix)linkedin_compliance_fix)mailchimp_compliance_fix)weibo_compliance_fix)slack_compliance_fixc@s(eZdZddZddZdS)FacebookComplianceFixTestcCsjtj}|jddddddi|j|j|jtddd }t||_dS) Nz-https://graph.facebook.com/oauth/access_tokentextzaccess_token=urlencodedheadersz Content-Typez text/plainfoo redirect_uriz https://i.b) requests_mockMockerpoststart addCleanupstoprrsession)selfmockerfacebookrZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pysetUps   zFacebookComplianceFixTest.setUpcCs>|jjddddd}|j|dddd idS) Nz-https://graph.facebook.com/oauth/access_token client_secretbarauthorization_responsezhttps://i.b/?code=hello access_token urlencoded token_typeBearer)r fetch_token assertEqual)rtokenrrrtest_fetch_access_token&s   z1FacebookComplianceFixTest.test_fetch_access_tokenN)__name__ __module__ __qualname__rr(rrrrr s  r c@s4eZdZddZddZddZdS)LinkedInComplianceFixTestc Cstj}|jddddi|jdddddd d d i|j|j|jtd d d}t||_dS)Nz/https://www.linkedin.com/uas/oauth2/accessTokenjsonr!linkedinz+https://api.linkedin.com/v1/people/~/shares status_codeZ updateKeyzUPDATE-3346389-595113200Z updateUrlz6https://www.linkedin.com/updates?discuss=abc&scope=xyzrrz https://i.b) rrrrrrrrr)rrr.rrrr1s    zLinkedInComplianceFixTest.setUpcCs>|jjddddd}|j|dddd idS) Nz/https://www.linkedin.com/uas/oauth2/accessTokenrrr zhttps://i.b/?code=hellor!r.r#r$)rr%r&)rr'rrrr(Es   z1LinkedInComplianceFixTest.test_fetch_access_tokencCs`ddi|j_|jjd}|jj}tt|j}|j|ddgdS)Nr!zdummy-access-tokenz+https://api.linkedin.com/v1/people/~/sharesoauth2_access_token) rr'rrequesturlrrqueryr&)rresponser3r4rrrtest_protected_requestMs    z0LinkedInComplianceFixTest.test_protected_requestN)r)r*r+rr(r6rrrrr,/s   r,c@s(eZdZddZddZdS)MailChimpComplianceFixTestc Csptj}|jddddddddi|j|j|jtdd d }t||_dS) Nz(https://login.mailchimp.com/oauth2/tokenr-r! mailchimp expires_inrscoperrz https://i.b) rrrrrrrr r)rrr8rrrrYs  z MailChimpComplianceFixTest.setUpcCs|jjddddd}tjd}|jd}|j||dd |j|d d d di|jd |dS)Nz(https://login.mailchimp.com/oauth2/tokenrrr zhttps://i.b/?code=helloi expires_atplacesr!r8r9r:)rr%timepopassertAlmostEqualr& assertNotIn)rr'Zapprox_expires_atZactual_expires_atrrrr(es  z2MailChimpComplianceFixTest.test_fetch_access_tokenN)r)r*r+rr(rrrrr7Ws  r7c@s(eZdZddZddZdS)WeiboComplianceFixTestcCsdtj}|jddddi|j|j|jtddd}t||_dS)Nz)https://api.weibo.com/oauth2/access_tokenr-r!weiborrz https://i.b) rrrrrrrr r)rrrCrrrrys   zWeiboComplianceFixTest.setUpcCs>|jjddddd}|j|dddd idS) Nz)https://api.weibo.com/oauth2/access_tokenrrr zhttps://i.b/?code=hellor!rCr#r$)rr%r&)rr'rrrr(s   z.WeiboComplianceFixTest.test_fetch_access_tokenN)r)r*r+rr(rrrrrBws  rBc@sLeZdZddZddZddZddZd d Zd S) SlackComplianceFixTestcCstj}|jddddddixNdD]F}|jd |d d dd d d dddddddddiq2W|j|j|jtddd}t||_ dS)Nz"https://slack.com/api/oauth.accessr-r!zxoxt-23984754863-2348975623103r:readGETPOSTmethodr3zhttps://slack.com/api/auth.testokTzhttps://myteam.slack.com/ZteamzMy TeamusercalZteam_idZT12345Zuser_idZU12345rrz https://i.b)zGETzPOST) rrrr2rrrrr r)rrrHslackrrrrs&     zSlackComplianceFixTest.setUpcCsddi|j_|jjd}|jj}tt|j}|jd||jj }t|}|j |ddgdS)Nr!zdummy-access-tokenzhttps://slack.com/api/auth.testr') rr'getr2r3rrr4rAbodyr&)rr5r3r4rNdatarrrr6s     z-SlackComplianceFixTest.test_protected_requestcCsddi|j_|jjddddi}|jj}tt|j}|jd||jj }t|}|j |ddgdS)Nr!zdummy-access-tokenzhttps://slack.com/api/auth.testrOr'zdifferent-token) rr'rMr2r3rrr4rArNr&)rr5r3r4rNrOrrr)test_protected_request_override_token_gets    z@SlackComplianceFixTest.test_protected_request_override_token_getcCsddi|j_|jjddddi}|jj}tt|j}|jd||jj }t|}|j |ddgdS)Nr!zdummy-access-tokenzhttps://slack.com/api/auth.testrOr'zdifferent-token) rr'rr2r3rrr4rArNr&)rr5r3r4rNrOrrr*test_protected_request_override_token_posts    zASlackComplianceFixTest.test_protected_request_override_token_postcCssddi|j_|jjd}|jj}tt|j}|j|ddg|j |jj dS)Nr!zdummy-access-tokenz5https://slack.com/api/auth.test?token=different-tokenr'zdifferent-token) rr'rMr2r3rrr4r& assertIsNonerN)rr5r3r4rrr)test_protected_request_override_token_urls   z@SlackComplianceFixTest.test_protected_request_override_token_urlN)r)r*r+rr6rPrQrSrrrrrDs   rD) __future__rZ unittest2r ImportErrorunittestrequestsrr>rr urllib.parserequests_oauthlibrZ"requests_oauthlib.compliance_fixesrrr r r r r,r7rBrDrrrrs,     ( requests-oauthlib-0.8.0/tests/__pycache__/test_core.cpython-27-PYTEST.pyc0000644000076500000240000001261512222010772026313 0ustar corystaff00000000000000 HRc@s ddlmZddlZddljjZddlZddl Z ddl Z ddl Z ddl Z yddlmZWn!ek rddlmZnXddlZe jddkreZneZejdejddejfd YZdS( i(tunicode_literalsN(tStringIOiu3u*oauthlib.oauth1.rfc5849.generate_timestampu&oauthlib.oauth1.rfc5849.generate_noncet OAuth1TestcBs>eZdZdZdZdZdZdZRS(csfd}|_dS(NcsVt|tr!|jd}nt|trB|jd}nj||dS(Nuutf-8(t isinstancet bytes_typetdecodet assertEquals(tatb(tself(sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pytconverting_equalss (t assertEqual(R R ((R sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pytsetUpsc CsDd|_d|_tjd}idd6}tjdddd d |d d d |}|j}|j|jd |j|jd |j|j j ddtjdddd d |d d }|j}|j|jd |j|jd |j|j j dd|j|j j d|j j ddS(u=OAuth1 assumes form encoded if content type is not specified.uabcu1u client_keyu!application/x-www-form-urlencodedu Content-typetmethoduPOSTturluhttp://a.b/path?query=retaintauthtdatauthis=really&is=&+form=encodedtheadersu Content-Typeu AuthorizationN( t return_valuetrequests_oauthlibtOAuth1trequeststRequesttprepareR RtbodyRtget(R tgenerate_noncetgenerate_timestamptoauthRtrRR((sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyttestFormEncoded"s$     c Cs d|_d|_tjd}tjddddd|d d }|j}tjddddd|}|j}|j|jjd |jjd tjddddd|d it d d6}|j}|j|jjd |jjd dS(u:OAuth signature only depend on body if it is form encoded.uabcu1u client_keyR uPOSTRuhttp://a.b/path?query=retainRRuthis really is not form encodedu AuthorizationtfilesuhelloutestN( RRRRRRR RRR(R RRRRRRtc((sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyttestNonFormEncoded;s       c Csd|_d|_tjd}tjjt}tjj|d}t|d^}t j ddidd 6d itjj |j |fd 6d |}|j |jd WdQXdS(ur Test we can post binary data. Should prevent regression of the UnicodeDecodeError issue. uabcu1u client_keyutest.binurbuhttp://httpbin.org/postRuthereuhiRumediaRiN(RRRtostpathtdirnamet__file__tjointopenRtposttbasenametnameR t status_code(R RRRR$tfnametfR((sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyttestCanPostBinaryDataSs  " cCsVd|_d|_tjd}tjdd|}|jt|jjt dS(u> Test that the URL is always a native string. uabcu1u client_keyuhttp://httpbin.org/getRN( RRRRRt assertTrueRtrequestRtstr(R RRRR((sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyttest_url_is_native_strds   c Csd|_d|_tjd}d}tjdd|d|}|j|jjjdd tjdd|d|d id d 6}|j|jjjdd d S(uG Content type should only be guessed if none is given. uabcu1u client_keyuauhttp://httpbin.org/getRRu Content-Typeu!application/x-www-form-urlencodedRuapplication/jsonu Content-typeN( RRRRR(R R0RR(R RRRRR((sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyttest_content_type_overrideos  (t__name__t __module__R RR!R.R2R3(((sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyRs     (t __future__Rt __builtin__t @py_builtinst_pytest.assertion.rewritet assertiontrewritet @pytest_artmocktsysRRtos.pathR"tioRt ImportErrortunittesttversiontbytesRR1tpatchtTestCaseR(((sN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyts$          requests-oauthlib-0.8.0/tests/__pycache__/test_core.cpython-33.pyc0000644000076500000240000001731012633523103025262 0ustar corystaff00000000000000 Slc@sddlmZddlZddlZddlZddlZddlZddlZyddl m Z Wn"e k rddl m Z YnXddl Z ej ddkreZneZejdejdGddde jZdS( i(uunicode_literalsN(uStringIOu3u*oauthlib.oauth1.rfc5849.generate_timestampu&oauthlib.oauth1.rfc5849.generate_noncecBsh|EeZdZddZddZddZddZd d Zd d Zd dZ dS(u OAuth1Testcsfdd}|_dS(NcsVt|tr!|jd}nt|trB|jd}nj||dS(Nuutf-8(u isinstanceu bytes_typeudecodeu assertEquals(uaub(uself(uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyuconverting_equalss u+OAuth1Test.setUp..converting_equals(u assertEqual(uselfuconverting_equals((uselfuN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyusetUpsuOAuth1Test.setUpc CsDd|_d|_tjd}idd6}tjdddd d |d d d |}|j}|j|jd |j|jd |j|j j ddtjdddd d |d d }|j}|j|jd |j|jd |j|j j dd|j|j j d|j j ddS(u=OAuth1 assumes form encoded if content type is not specified.uabcu1u client_keyu!application/x-www-form-urlencodedu Content-typeumethoduPOSTuurluhttp://a.b/path?query=retainuauthudatauthis=really&is=&+form=encodeduheadersu Content-Typeu AuthorizationN( u return_valueurequests_oauthlibuOAuth1urequestsuRequestuprepareu assertEqualuurlubodyuheadersuget(uselfugenerate_nonceugenerate_timestampuoauthuheadersuruaub((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyutestFormEncoded#s$     uOAuth1Test.testFormEncodedc Cs d|_d|_tjd}tjddddd|d d }|j}tjddddd|}|j}|j|jjd |jjd tjddddd|d it d d6}|j}|j|jjd |jjd dS(u:OAuth signature only depend on body if it is form encoded.uabcu1u client_keyumethoduPOSTuurluhttp://a.b/path?query=retainuauthudatauthis really is not form encodedu AuthorizationufilesuhelloutestN( u return_valueurequests_oauthlibuOAuth1urequestsuRequestuprepareu assertEqualuheadersugetuStringIO(uselfugenerate_nonceugenerate_timestampuoauthuruaubuc((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyutestNonFormEncoded<s       uOAuth1Test.testNonFormEncodedcCsd|_d|_tjd}tjjt}tjj|d}t|dk}t j ddidd 6d itjj |j |fd 6d id d6d|}|j |jdWdQXdS(ur Test we can post binary data. Should prevent regression of the UnicodeDecodeError issue. uabcu1u client_keyutest.binurbuhttp://httpbin.org/postudatauthereuhiufilesumediauheadersuapplication/octet-streamu content-typeuauthiN(u return_valueurequests_oauthlibuOAuth1uosupathudirnameu__file__ujoinuopenurequestsupostubasenameunameu assertEqualu status_code(uselfugenerate_nonceugenerate_timestampuoauthudirnameufnameufur((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyutestCanPostBinaryDataTs  "  u OAuth1Test.testCanPostBinaryDatacCsVd|_d|_tjd}tjdd|}|jt|jjt dS(u> Test that the URL is always a native string. uabcu1u client_keyuhttp://httpbin.org/getuauthN( u return_valueurequests_oauthlibuOAuth1urequestsugetu assertTrueu isinstanceurequestuurlustr(uselfugenerate_nonceugenerate_timestampuoauthur((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyutest_url_is_native_strfs   u!OAuth1Test.test_url_is_native_strc Csd|_d|_tjd}d}tjdd|d|}|j|jjjdd tjdd|d|d id d 6}|j|jjjdd d S(uG Content type should only be guessed if none is given. uabcu1u client_keyuauhttp://httpbin.org/getudatauauthu Content-Typeu!application/x-www-form-urlencodeduheadersuapplication/jsonu Content-typeN( u return_valueurequests_oauthlibuOAuth1urequestsupostu assertEqualurequestuheadersuget(uselfugenerate_nonceugenerate_timestampuoauthudataur((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyutest_content_type_overrideqs  u%OAuth1Test.test_content_type_overridecCsXGdddtjj}|jttjd|jtjjtjjtjd}|jt |j tjj|j t |j ||tj_|jtjj|tjd}|jt |j tjj|jt |j |tjddtjj}|jt |j tjj|j t |j |dS(NcBs|EeZdZdS(u=OAuth1Test.test_register_client_class..ClientSubclassN(u__name__u __module__u __qualname__(u __locals__((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyuClientSubclasssuClientSubclassu client_classu client_key( uoauthlibuoauth1uClientu assertTrueuhasattrurequests_oauthlibuOAuth1u assertEqualu client_classu isinstanceuclientu assertFalse(uselfugenerate_timestampugenerate_nonceuClientSubclassunormalucustomu overridden((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyutest_register_client_classs"    u%OAuth1Test.test_register_client_classN( u__name__u __module__u __qualname__usetUputestFormEncodedutestNonFormEncodedutestCanPostBinaryDatautest_url_is_native_strutest_content_type_overrideutest_register_client_class(u __locals__((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyu OAuth1Tests    u OAuth1Test(u __future__uunicode_literalsumockusysurequestsurequests_oauthlibuoauthlibuos.pathuosuiouStringIOu ImportErroruunittestuversionubytesu bytes_typeustrupatchuTestCaseu OAuth1Test(((uN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyus"          requests-oauthlib-0.8.0/tests/__pycache__/test_core.cpython-34.pyc0000644000076500000240000001263212617164042025272 0ustar corystaff00000000000000 Sl@sddlmZddlZddlZddlZddlZddlZddlZyddl m Z Wn"e k rddl m Z YnXddl Z ej ddkreZneZejdejdGddde jZdS) )unicode_literalsN)StringIO3z*oauthlib.oauth1.rfc5849.generate_timestampz&oauthlib.oauth1.rfc5849.generate_noncec@sdeZdZddZddZddZddZd d Zd d Zd dZ dS) OAuth1Testcsfdd}|_dS)NcsVt|tr!|jd}nt|trB|jd}nj||dS)Nzutf-8) isinstance bytes_typedecode assertEquals)ab)selfN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyconverting_equalss z+OAuth1Test.setUp..converting_equals) assertEqual)r rr )r rsetUpszOAuth1Test.setUpc CsDd|_d|_tjd}idd6}tjdddd d |d d d |}|j}|j|jd |j|jd |j|j j ddtjdddd d |d d }|j}|j|jd |j|jd |j|j j dd|j|j j d|j j ddS)z=OAuth1 assumes form encoded if content type is not specified.abc1 client_keyz!application/x-www-form-urlencodedz Content-typemethodPOSTurlzhttp://a.b/path?query=retainauthdatazthis=really&is=&+form=encodedheadersz Content-Type AuthorizationN) return_valuerequests_oauthlibOAuth1requestsRequestpreparerrbodyrget)r generate_noncegenerate_timestampoauthrrr r r r rtestFormEncoded#s$     zOAuth1Test.testFormEncodedc Cs d|_d|_tjd}tjddddd|d d }|j}tjddddd|}|j}|j|jjd |jjd tjddddd|d it d d6}|j}|j|jjd |jjd dS)z:OAuth signature only depend on body if it is form encoded.rrrrrrzhttp://a.b/path?query=retainrrzthis really is not form encodedrfilesZhellotestN) rrrrr r!rrr#r)r r$r%r&r'r r cr r rtestNonFormEncoded<s       zOAuth1Test.testNonFormEncodedcCsd|_d|_tjd}tjjt}tjj|d}t|dk}t j ddidd 6d itjj |j |fd 6d id d6d|}|j |jdWdQXdS)zr Test we can post binary data. Should prevent regression of the UnicodeDecodeError issue. rrrztest.binrbzhttp://httpbin.org/postrZtherehir)Zmediarzapplication/octet-streamz content-typerN)rrrospathdirname__file__joinopenrpostbasenamenamer status_code)r r$r%r&r2fnamefr'r r rtestCanPostBinaryDataTs  "  z OAuth1Test.testCanPostBinaryDatacCsVd|_d|_tjd}tjdd|}|jt|jjt dS)z> Test that the URL is always a native string. rrrzhttp://httpbin.org/getrN) rrrrr# assertTruerrequestrstr)r r$r%r&r'r r rtest_url_is_native_strfs   z!OAuth1Test.test_url_is_native_strc Csd|_d|_tjd}d}tjdd|d|}|j|jjjdd tjdd|d|d id d 6}|j|jjjdd d S)zG Content type should only be guessed if none is given. rrrr zhttp://httpbin.org/getrrz Content-Typez!application/x-www-form-urlencodedrzapplication/jsonz Content-typeN) rrrrr6rr>rr#)r r$r%r&rr'r r rtest_content_type_overrideqs  z%OAuth1Test.test_content_type_overridecCsXGdddtjj}|jttjd|jtjjtjjtjd}|jt |j tjj|j t |j ||tj_|jtjj|tjd}|jt |j tjj|jt |j |tjddtjj}|jt |j tjj|j t |j |dS)Nc@seZdZdS)z=OAuth1Test.test_register_client_class..ClientSubclassN)__name__ __module__ __qualname__r r r rClientSubclasss rE client_classr) oauthliboauth1Clientr=hasattrrrrrFrclient assertFalse)r r%r$rEZnormalZcustomZ overriddenr r rtest_register_client_classs"    z%OAuth1Test.test_register_client_classN) rBrCrDrr(r,r<r@rArMr r r rrs     r) __future__rmocksysrrrGos.pathr0ior ImportErrorunittestversionbytesrr?patchTestCaserr r r rs"          requests-oauthlib-0.8.0/tests/__pycache__/test_core.cpython-35.pyc0000644000076500000240000001261712633523122025272 0ustar corystaff00000000000000 Sl@sddlmZddlZddlZddlZddlZddlZddlZyddl m Z Wn"e k rddl m Z YnXddl Z ej ddkreZneZejdejdGddde jZdS) )unicode_literalsN)StringIO3z*oauthlib.oauth1.rfc5849.generate_timestampz&oauthlib.oauth1.rfc5849.generate_noncec@sdeZdZddZddZddZddZd d Zd d Zd dZ dS) OAuth1Testcsfdd}|_dS)NcsPt|tr|jd}t|tr<|jd}j||dS)Nzutf-8) isinstance bytes_typedecode assertEquals)ab)selfN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pyconverting_equalss z+OAuth1Test.setUp..converting_equals) assertEqual)r rr )r rsetUpszOAuth1Test.setUpc CsCd|_d|_tjd}ddi}tjdddd d |d d d |}|j}|j|jd |j|jd |j|j j ddtjdddd d |d d }|j}|j|jd |j|jd |j|j j dd|j|j j d|j j ddS)z=OAuth1 assumes form encoded if content type is not specified.abc1 client_keyz Content-typez!application/x-www-form-urlencodedmethodPOSTurlzhttp://a.b/path?query=retainauthdatazthis=really&is=&+form=encodedheadersz Content-Type AuthorizationN) return_valuerequests_oauthlibOAuth1requestsRequestpreparerrbodyrget)r generate_noncegenerate_timestampoauthrrr r r r rtestFormEncoded#s$     zOAuth1Test.testFormEncodedc Cs d|_d|_tjd}tjddddd|d d }|j}tjddddd|}|j}|j|jjd |jjd tjddddd|d d t di}|j}|j|jjd |jjd dS)z:OAuth signature only depend on body if it is form encoded.rrrrrrzhttp://a.b/path?query=retainrrzthis really is not form encodedrfilestestZhelloN) rrrrr r!rrr#r)r r$r%r&r'r r cr r rtestNonFormEncoded<s       zOAuth1Test.testNonFormEncodedcCsd|_d|_tjd}tjjt}tjj|d}t|dh}t j dddd id d tjj |j |fid d did|}|j |jdWdQRXdS)zr Test we can post binary data. Should prevent regression of the UnicodeDecodeError issue. rrrztest.binrbzhttp://httpbin.org/postrhiZtherer)Zmediarz content-typezapplication/octet-streamrN)rrrospathdirname__file__joinopenrpostbasenamenamer status_code)r r$r%r&r2fnamefr'r r rtestCanPostBinaryDataTs  !  z OAuth1Test.testCanPostBinaryDatacCsVd|_d|_tjd}tjdd|}|jt|jjt dS)z> Test that the URL is always a native string. rrrzhttp://httpbin.org/getrN) rrrrr# assertTruerrequestrstr)r r$r%r&r'r r rtest_url_is_native_strfs   z!OAuth1Test.test_url_is_native_strc Csd|_d|_tjd}d}tjdd|d|}|j|jjjdd tjdd|d|d d d i}|j|jjjdd d S)zG Content type should only be guessed if none is given. rrrr zhttp://httpbin.org/getrrz Content-Typez!application/x-www-form-urlencodedrz Content-typezapplication/jsonN) rrrrr6rr>rr#)r r$r%r&rr'r r rtest_content_type_overrideqs  z%OAuth1Test.test_content_type_overridecCsXGdddtjj}|jttjd|jtjjtjjtjd}|jt |j tjj|j t |j ||tj_|jtjj|tjd}|jt |j tjj|jt |j |tjddtjj}|jt |j tjj|j t |j |dS)Nc@seZdZdS)z=OAuth1Test.test_register_client_class..ClientSubclassN)__name__ __module__ __qualname__r r r rClientSubclasss rE client_classr) oauthliboauth1Clientr=hasattrrrrrFrclient assertFalse)r r%r$rEZnormalZcustomZ overriddenr r rtest_register_client_classs"    z%OAuth1Test.test_register_client_classN) rBrCrDrr(r,r<r@rArMr r r rrs     r) __future__rmocksysrrrGos.pathr0ior ImportErrorunittestversionbytesrr?patchTestCaserr r r rs"          requests-oauthlib-0.8.0/tests/__pycache__/test_oauth1_session.cpython-27-PYTEST.pyc0000644000076500000240000002571712222010772030336 0ustar corystaff00000000000000 HRc@sddlmZddlZddljjZddlZddl Z ddl Z ddl m Z m Z ddl mZmZddlmZyddlmZWn!ek rddlmZnXe jddkreZeZn eZeZd e jfd YZdS( i(tunicode_literalsN(tSIGNATURE_TYPE_QUERYtSIGNATURE_TYPE_BODY(t SIGNATURE_RSAtSIGNATURE_PLAINTEXT(t OAuth1Session(tStringIOiu3tOAuth1SessionTestcBseZdZdZejdejddZejdejddZejdejddZdZ dZ d Z d Z d Z d ZRS( cs(tds$fd_ndS(NuassertIncsj||kS(N(t assertTrue(tatb(tself(sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyts(thasattrtassertIn(R ((R sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pytsetUpscsfd}td}|d|_|jdtddt}|d|_|jdtddt}idd6}|d |_|jdd |d d dS( Ncsfd}|S(NcsV|}t|tr-|jd}njd|tj}g|_|S(Nuutf-8uoauth_signature(t isinstancet bytes_typetdecodeRtmockt MagicMocktcookes(trtkwargst signaturetresp(tgetterR (sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyt fake_send s   ((RR(R (RsX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pytverify_signaturesufoocSs |jdS(Nu Authorization(theaders(R((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyR +su https://i.btsignature_typecSs|jS(N(turl(R((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyR /su!application/x-www-form-urlencodedu Content-TypecSs|jS(N(tbody(R((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyR 4sRtdatau(RtsendtpostRR(R RtheadertqueryR R((R sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyttest_signature_typess    u*oauthlib.oauth1.rfc5849.generate_timestampu&oauthlib.oauth1.rfc5849.generate_noncecCsd|_d|_d}td}|j||_|jdd}tddt}|j||_|jdd}d }tddtd |}|j||_|jddS( Nuabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"ufoou https://i.buOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="foo", oauth_signature="%26"tsignature_methodu-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEApF1JaMSN8TEsh4N4O/5SpEAVLivJyLH+Cgl3OQBPGgJkt8cg 49oasl+5iJS+VdrILxWM9/JCJyURpUuslX4Eb4eUBtQ0x5BaPa8+S2NLdGTaL7nB OO8o8n0C5FEUU+qlEip79KE8aqOj+OC44VsIquSmOvWIQD26n3fCVlgwoRBD1gzz sDOeaSyzpKrZR851Kh6rEmF2qjJ8jt6EkxMsRNACmBomzgA4M1TTsisSUO87444p e35Z4/n5c735o2fZMrGgMwiJNh7rT8SYxtIkxngioiGnwkxGQxQ4NzPAHg+XSY0J 04pNm7KqTkgtxyrqOANJLIjXlR+U9SQ90NjHVQIDAQABAoIBABuBPOKaWcJt3yzC NGGduoif7KtwSnEaUA+v69KPGa2Zju8uFHPssKD+4dZYRc2qMeunKJLpaGaSjnRh yHyvvOBJCN1nr3lhz6gY5kzJTfwpUFXCOPJlGy4Q+2Xnp4YvcvYqQ9n5DVovDiZ8 vJOBn16xqpudMPLHIa7D5LJ8SY76HBjE+imTXw1EShdh5TOV9bmPFQqH6JFzowRH hyH2DPHuyHJj6cl8FyqJw5lVWzG3n6Prvk7bYHsjmGjurN35UsumNAp6VouNyUP1 RAEcUJega49aIs6/FJ0ENJzQjlsAzVbTleHkpez2aIok+wsWJGJ4SVxAjADOWAaZ uEJPc3UCgYEA1g4ZGrXOuo75p9/MRIepXGpBWxip4V7B9XmO9WzPCv8nMorJntWB msYV1I01aITxadHatO4Gl2xLniNkDyrEQzJ7w38RQgsVK+CqbnC0K9N77QPbHeC1 YQd9RCNyUohOimKvb7jyv798FBU1GO5QI2eNgfnnfteSVXhD2iOoTOsCgYEAxJJ+ 8toxJdnLa0uUsAbql6zeNXGbUBMzu3FomKlyuWuq841jS2kIalaO/TRj5hbnE45j mCjeLgTVO6Ach3Wfk4zrqajqfFJ0zUg/Wexp49lC3RWiV4icBb85Q6bzeJD9Dn9v hjpfWVkczf/NeA1fGH/pcgfkT6Dm706GFFttLL8CgYBl/HeXk1H47xAiHO4dJKnb v0B+X8To/RXamF01r+8BpUoOubOQetdyX7ic+d6deuHu8i6LD/GSCeYJZYFR/KVg AtiW757QYalnq3ZogkhFrVCZP8IRfTPOFBxp752TlyAcrSI7T9pQ47IBe4094KXM CJWSfPgAJkOxd0iU0XJpmwKBgGfQxuMTgSlwYRKFlD1zKap5TdID8fbUbVnth0Q5 GbH7vwlp/qrxCdS/aj0n0irOpbOaW9ccnlrHiqY25VpVMLYIkt3DrDOEiNNx+KNR TItdTwbcSiTYrS4L0/56ydM/H6bsfsXxRjI18hSJqMZiqXqS84OZz2aOn+h7HCzc LEiZAoGASk20wFvilpRKHq79xxFWiDUPHi0x0pp82dYIEntGQkKUWkbSlhgf3MAi 5NEQTDmXdnB+rVeWIvEi+BXfdnNgdn8eC4zSdtF4sIAhYr5VWZo0WVWDhT7u2ccv ZBFymiz8lo3gN57wGUCi9pbZqzV1+ZppX6YTNDdDCE0q+KO3Cec= -----END RSA PRIVATE KEY-----uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="j8WF8PGjojT82aUDd2EL%2Bz7HCoHInFzWUpiEKMCy%2BJ2cYHWcBS7mXlmFDLgAKV0P%2FyX4TrpXODYnJ6dRWdfghqwDpi%2FlQmB2jxCiGMdJoYxh3c5zDf26gEbGdP6D7OSsp5HUnzH6sNkmVjuE%2FxoJcHJdc23H6GhOs7VJ2LWNdbhKWP%2FMMlTrcoQDn8lz%2Fb24WsJ6ae1txkUzpFOOlLM8aTdNtGL4OtsubOlRhNqnAFq93FyhXg0KjzUyIZzmMX9Vx90jTks5QeBGYcLE0Op2iHb2u%2FO%2BEgdwFchgEwE5LgMUyHUI4F3Wglp28yHOAMjPkI%2FkWMvpxtMrU3Z3KN31WQ%3D%3D"trsa_key(t return_valueRRR"R#RR(R tgenerate_noncetgenerate_timestampRtauthR(((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyttest_signature_methods7s       cCsud|_d|_td}idd6}d}td}|j||_|jdd |d d |fgdS( Nuabcu123u hello worlduapplication/xmlu Content-TypeuOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"ufoou https://i.bRtfilesufake(R)RRRR"R#(R R*R+tfake_xmlRRR,((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyttest_binary_uploadhs     cCsGd|_d|_d}td}|j||_|jddS(Nuabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="W0haoue5IZAZoaJiYCtfqwMf8x8%3D"ufoou"https://i.b?cjk=%E5%95%A6%E5%95%A6(R)RRR"R#(R R*R+RR,((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyt test_nonasciits    cCsItd}d}d}|j|d|}|j||d|dS(Nufoouhttps://example.comm/authorizeu asluif023sft request_tokenu ?oauth_token=(Rtauthorization_urlt assertEqual(R R,Rttokentauth_url((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyttest_authorization_url~s  cCsd}td}|j|}|j|dd|j|ddxF|jD]8\}}|jt|t|jt|tqVWdS(Nu7https://i.b/callback?oauth_token=foo&oauth_verifier=barufoou oauth_tokenuoauth_verifierubar(Rtparse_authorization_responseR4titemsRRt unicode_type(R RR,Rtktv((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyttest_parse_response_urls cCstd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqNWdS(Nufoouoauth_token=foouhttps://example.com/tokenu oauth_token( Rt fake_bodyR"tfetch_request_tokenR4R9RRR:(R R,RR;R<((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyttest_fetch_request_tokens cCstddd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqTWdS(Nufootverifierubaruoauth_token=foouhttps://example.com/tokenu oauth_token( RR>R"tfetch_access_tokenR4R9RRR:(R R,RR;R<((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyttest_fetch_access_tokenscsfd}|S(NcsW|jd}t|tr.|jd}nj|tj}g|_|S(Nu Authorizationuutf-8(RRRRR4RRR(RRt auth_headerR(R R(sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyRs   ((R RR((R RsX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyRscsfd}|S(Ncs"tj}g|_|_|S(N(RRRttext(RRR(R (sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyRs   ((R R R((R sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyR>s(t__name__t __module__RR&RtpatchR-R0R1R7R=R@RCRR>(((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyRs   0    (t __future__Rt __builtin__t @py_builtinst_pytest.assertion.rewritet assertiontrewritet @pytest_arRtunittesttsystoauthlib.oauth1RRRRtrequests_oauthlibRRt ImportErrortiotversiontstrR:tbytesRtunicodetTestCaseR(((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyts$      requests-oauthlib-0.8.0/tests/__pycache__/test_oauth1_session.cpython-33.pyc0000644000076500000240000005235012770742400027306 0ustar corystaff00000000000000 ;V8c@sddlmZmZddlZddlZddlZddlZddlmZm Z ddlm Z m Z ddl m Z yddlmZWn"ek rddlmZYnXyddlZWnek rdZYnXejddkreZeZn eZeZeedsYee_ejjej_d d Zeej_nd Z d Z!Gd ddej"Z#dS(i(uunicode_literalsuprint_functionN(uSIGNATURE_TYPE_QUERYuSIGNATURE_TYPE_BODY(u SIGNATURE_RSAuSIGNATURE_PLAINTEXT(u OAuth1Session(uStringIOu3uSkipTestcCsK|dtkr7tt|ddddtjdS|j||dS(Niiuendu ufile(uRuntimeWarninguprintustrusysustderrureal_add_error(uselfutestuexc_info((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyupatched_addError!s#upatched_addErroru-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEApF1JaMSN8TEsh4N4O/5SpEAVLivJyLH+Cgl3OQBPGgJkt8cg 49oasl+5iJS+VdrILxWM9/JCJyURpUuslX4Eb4eUBtQ0x5BaPa8+S2NLdGTaL7nB OO8o8n0C5FEUU+qlEip79KE8aqOj+OC44VsIquSmOvWIQD26n3fCVlgwoRBD1gzz sDOeaSyzpKrZR851Kh6rEmF2qjJ8jt6EkxMsRNACmBomzgA4M1TTsisSUO87444p e35Z4/n5c735o2fZMrGgMwiJNh7rT8SYxtIkxngioiGnwkxGQxQ4NzPAHg+XSY0J 04pNm7KqTkgtxyrqOANJLIjXlR+U9SQ90NjHVQIDAQABAoIBABuBPOKaWcJt3yzC NGGduoif7KtwSnEaUA+v69KPGa2Zju8uFHPssKD+4dZYRc2qMeunKJLpaGaSjnRh yHyvvOBJCN1nr3lhz6gY5kzJTfwpUFXCOPJlGy4Q+2Xnp4YvcvYqQ9n5DVovDiZ8 vJOBn16xqpudMPLHIa7D5LJ8SY76HBjE+imTXw1EShdh5TOV9bmPFQqH6JFzowRH hyH2DPHuyHJj6cl8FyqJw5lVWzG3n6Prvk7bYHsjmGjurN35UsumNAp6VouNyUP1 RAEcUJega49aIs6/FJ0ENJzQjlsAzVbTleHkpez2aIok+wsWJGJ4SVxAjADOWAaZ uEJPc3UCgYEA1g4ZGrXOuo75p9/MRIepXGpBWxip4V7B9XmO9WzPCv8nMorJntWB msYV1I01aITxadHatO4Gl2xLniNkDyrEQzJ7w38RQgsVK+CqbnC0K9N77QPbHeC1 YQd9RCNyUohOimKvb7jyv798FBU1GO5QI2eNgfnnfteSVXhD2iOoTOsCgYEAxJJ+ 8toxJdnLa0uUsAbql6zeNXGbUBMzu3FomKlyuWuq841jS2kIalaO/TRj5hbnE45j mCjeLgTVO6Ach3Wfk4zrqajqfFJ0zUg/Wexp49lC3RWiV4icBb85Q6bzeJD9Dn9v hjpfWVkczf/NeA1fGH/pcgfkT6Dm706GFFttLL8CgYBl/HeXk1H47xAiHO4dJKnb v0B+X8To/RXamF01r+8BpUoOubOQetdyX7ic+d6deuHu8i6LD/GSCeYJZYFR/KVg AtiW757QYalnq3ZogkhFrVCZP8IRfTPOFBxp752TlyAcrSI7T9pQ47IBe4094KXM CJWSfPgAJkOxd0iU0XJpmwKBgGfQxuMTgSlwYRKFlD1zKap5TdID8fbUbVnth0Q5 GbH7vwlp/qrxCdS/aj0n0irOpbOaW9ccnlrHiqY25VpVMLYIkt3DrDOEiNNx+KNR TItdTwbcSiTYrS4L0/56ydM/H6bsfsXxRjI18hSJqMZiqXqS84OZz2aOn+h7HCzc LEiZAoGASk20wFvilpRKHq79xxFWiDUPHi0x0pp82dYIEntGQkKUWkbSlhgf3MAi 5NEQTDmXdnB+rVeWIvEi+BXfdnNgdn8eC4zSdtF4sIAhYr5VWZo0WVWDhT7u2ccv ZBFymiz8lo3gN57wGUCi9pbZqzV1+ZppX6YTNDdDCE0q+KO3Cec= -----END RSA PRIVATE KEY-----upj8WF8PGjojT82aUDd2EL%2Bz7HCoHInFzWUpiEKMCy%2BJ2cYHWcBS7mXlmFDLgAKV0P%2FyX4TrpXODYnJ6dRWdfghqwDpi%2FlQmB2jxCiGMdJoYxh3c5zDf26gEbGdP6D7OSsp5HUnzH6sNkmVjuE%2FxoJcHJdc23H6GhOs7VJ2LWNdbhKWP%2FMMlTrcoQDn8lz%2Fb24WsJ6ae1txkUzpFOOlLM8aTdNtGL4OtsubOlRhNqnAFq93FyhXg0KjzUyIZzmMX9Vx90jTks5QeBGYcLE0Op2iHb2u%2FO%2BEgdwFchgEwE5LgMUyHUI4F3Wglp28yHOAMjPkI%2FkWMvpxtMrU3Z3KN31WQ%3D%3DcBs|EeZdZddZddZejdejdddZejdejdd d Zejdejdd d Z d dZ ddZ ddZ ddZ ddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zejdejdd'd(Zd)d*Zd+d,d-Zd.S(/uOAuth1SessionTestcs+tds'fdd_ndS(NuassertIncsj||kS(N(u assertTrue(uaub(uself(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyuWsu)OAuth1SessionTest.setUp..(uhasattruassertIn(uself((uselfuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyusetUpTsuOAuth1SessionTest.setUpcsfdd}td}|dd|_|jdtddt}|dd|_|jdtddt}id d 6}|d d|_|jdd |d ddS(Ncsfdd}|S(Ncs_|}t|tr-|jd}njd|tjdtj}g|_|S(Nuutf-8uoauth_signatureuspec( u isinstanceu bytes_typeudecodeuassertInumocku MagicMockurequestsuResponseucookies(urukwargsu signatureuresp(ugetteruself(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu fake_send[s  uSOAuth1SessionTest.test_signature_types..verify_signature..fake_send((ugetteru fake_send(uself(ugetteruX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyuverify_signatureZsu@OAuth1SessionTest.test_signature_types..verify_signatureufoocSs |jdS(Nu Authorization(uheaders(ur((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyufsu8OAuth1SessionTest.test_signature_types..u https://i.busignature_typecSs|jS(N(uurl(ur((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyujsu!application/x-www-form-urlencodedu Content-TypecSs|jS(N(ubody(ur((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyuosuheadersudatau(u OAuth1SessionusendupostuSIGNATURE_TYPE_QUERYuSIGNATURE_TYPE_BODY(uselfuverify_signatureuheaderuqueryubodyuheaders((uselfuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_signature_typesYs    u&OAuth1SessionTest.test_signature_typesu*oauthlib.oauth1.rfc5849.generate_timestampu&oauthlib.oauth1.rfc5849.generate_noncecCststjdnd|_d|_d}td}|j||_|jdd}tddt}|j||_|jdd j d t }tddt d t }|j||_|jddS( Nucryptography module is requireduabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"ufoou https://i.buOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="foo", oauth_signature="%26"usignature_methoduOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"usigursa_key( u cryptographyuunittestuSkipTestu return_valueu OAuth1Sessionuverify_signatureusendupostuSIGNATURE_PLAINTEXTuformatuTEST_RSA_OAUTH_SIGNATUREu SIGNATURE_RSAu TEST_RSA_KEY(uselfugenerate_nonceugenerate_timestampu signatureuauth((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_signature_methodsrs$        u(OAuth1SessionTest.test_signature_methodscCsud|_d|_td}idd6}d}td}|j||_|jdd |d d |fgdS( Nuabcu123u hello worlduapplication/xmlu Content-TypeuOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"ufoou https://i.buheadersufilesufake(u return_valueuStringIOu OAuth1Sessionuverify_signatureusendupost(uselfugenerate_nonceugenerate_timestampufake_xmluheadersu signatureuauth((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_binary_uploads     u$OAuth1SessionTest.test_binary_uploadcCsGd|_d|_d}td}|j||_|jddS(Nuabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="W0haoue5IZAZoaJiYCtfqwMf8x8%3D"ufoou"https://i.b?cjk=%E5%95%A6%E5%95%A6(u return_valueu OAuth1Sessionuverify_signatureusendupost(uselfugenerate_nonceugenerate_timestampu signatureuauth((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu test_nonasciis    uOAuth1SessionTest.test_nonasciicCsItd}d}d}|j|d|}|j||d|dS(Nufoouhttps://example.comm/authorizeu asluif023sfu request_tokenu ?oauth_token=(u OAuth1Sessionuauthorization_urlu assertEqual(uselfuauthuurlutokenuauth_url((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_authorization_urls  u(OAuth1SessionTest.test_authorization_urlcCsd}td}|j|}|j|dd|j|ddxF|jD]8\}}|jt|t|jt|tqVWdS(Nu7https://i.b/callback?oauth_token=foo&oauth_verifier=barufoou oauth_tokenuoauth_verifierubar(u OAuth1Sessionuparse_authorization_responseu assertEqualuitemsu assertTrueu isinstanceu unicode_type(uselfuurluauthurespukuv((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_parse_response_urls u)OAuth1SessionTest.test_parse_response_urlcCstd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqNWdS(Nufoouoauth_token=foouhttps://example.com/tokenu oauth_token( u OAuth1Sessionu fake_bodyusendufetch_request_tokenu assertEqualuitemsu assertTrueu isinstanceu unicode_type(uselfuauthurespukuv((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_fetch_request_tokens u*OAuth1SessionTest.test_fetch_request_tokencCstd}|jd|_|jddddd}|j|ddxF|jD]8\}}|jt |t |jt |t qZWdS( Nufoouoauth_token=foouhttps://example.com/tokenuverifyustreamu oauth_tokenFT( u OAuth1Sessionu fake_bodyusendufetch_request_tokenuFalseuTrueu assertEqualuitemsu assertTrueu isinstanceu unicode_type(uselfuauthurespukuv((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu0test_fetch_request_token_with_optional_argumentss  uBOAuth1SessionTest.test_fetch_request_token_with_optional_argumentscCstddd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqTWdS(Nufoouverifierubaruoauth_token=foouhttps://example.com/tokenu oauth_token( u OAuth1Sessionu fake_bodyusendufetch_access_tokenu assertEqualuitemsu assertTrueu isinstanceu unicode_type(uselfuauthurespukuv((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_fetch_access_tokensu)OAuth1SessionTest.test_fetch_access_tokencCstddd}|jd|_|jddd dd }|j|ddxF|jD]8\}}|jt |t |jt |t q`WdS( Nufoouverifierubaruoauth_token=foouhttps://example.com/tokenuverifyustreamu oauth_tokenFT( u OAuth1Sessionu fake_bodyusendufetch_access_tokenuFalseuTrueu assertEqualuitemsu assertTrueu isinstanceu unicode_type(uselfuauthurespukuv((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu/test_fetch_access_token_with_optional_argumentss uAOAuth1SessionTest.test_fetch_access_token_with_optional_argumentscCse|jd|_y|jdWn;tk r`}z|jdt|WYdd}~XnXdS(ukAssert that an error is being raised whenever there's no verifier passed in to the client. uoauth_token=foouhttps://example.com/tokenu No client verifier has been set.N(u fake_bodyusendufetch_access_tokenu ValueErroru assertEqualustr(uselfuauthuexc((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu%_test_fetch_access_token_raises_errors u7OAuth1SessionTest._test_fetch_access_token_raises_errorcCstd}|jd|_|jt|jdxd D]}|jd||_y|jdWnTtk r}z4|j|j||jt |j t j WYdd}~Xq;X|j dq;WdS( Nufoounot valid urlencoded response!uhttps://example.com/tokeniiiuvalid=responseuValueError not raised(iii(u OAuth1Sessionu fake_bodyusendu assertRaisesu ValueErrorufetch_request_tokenu assertEqualu status_codeu assertTrueu isinstanceuresponseurequestsuResponseufail(uselfuauthucodeuerr((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu!test_fetch_token_invalid_responses  /u3OAuth1SessionTest.test_fetch_token_invalid_responsecCs|jtddS(Nufoo(u%_test_fetch_access_token_raises_erroru OAuth1Session(uself((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu(test_fetch_access_token_missing_verifiersu:OAuth1SessionTest.test_fetch_access_token_missing_verifiercCs)td}|jj`|j|dS(Nufoo(u OAuth1Sessionu_clientuclientuverifieru%_test_fetch_access_token_raises_error(uselfuauth((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu,test_fetch_access_token_has_verifier_is_nones  u>OAuth1SessionTest.test_fetch_access_token_has_verifier_is_nonecCs td}|j|jdS(Nufoo(u OAuth1Sessionu assertFalseu authorized(uselfusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_authorized_falses u'OAuth1SessionTest.test_authorized_falsecCsPdjdt}tddtdt}|j||_|j|jdS(NuOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"usigufoousignature_methodursa_key( uformatuTEST_RSA_OAUTH_SIGNATUREu OAuth1Sessionu SIGNATURE_RSAu TEST_RSA_KEYuverify_signatureusendu assertFalseu authorized(uselfu signatureusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_authorized_false_rsas    u+OAuth1SessionTest.test_authorized_false_rsacCsHtdddd}|jd|_|jd|j|jdS(Nukeyusecretuverifierubaru&oauth_token=foo&oauth_token_secret=baruhttps://example.com/token(u OAuth1Sessionu fake_bodyusendufetch_access_tokenu assertTrueu authorized(uselfusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_authorized_trues u&OAuth1SessionTest.test_authorized_truec Cststjdnd|_d|_djdt}tdddtd td d }|j d |_ |j d |j |j dS(Nucryptography module is requireduabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_verifier="bar", oauth_signature="{sig}"usigukeyusecretusignature_methodursa_keyuverifierubaru&oauth_token=foo&oauth_token_secret=baruhttps://example.com/token(u cryptographyuunittestuSkipTestu return_valueuformatuTEST_RSA_OAUTH_SIGNATUREu OAuth1Sessionu SIGNATURE_RSAu TEST_RSA_KEYu fake_bodyusendufetch_access_tokenu assertTrueu authorized(uselfugenerate_nonceugenerate_timestampu signatureusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyutest_authorized_true_rsas     u*OAuth1SessionTest.test_authorized_true_rsacsfdd}|S(Ncs`|jd}t|tr.|jd}nj|tjdtj}g|_ |S(Nu Authorizationuutf-8uspec( uheadersu isinstanceu bytes_typeudecodeu assertEqualumocku MagicMockurequestsuResponseucookies(urukwargsu auth_headeruresp(uselfu signature(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu fake_send-s  u5OAuth1SessionTest.verify_signature..fake_send((uselfu signatureu fake_send((uselfu signatureuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyuverify_signature,su"OAuth1SessionTest.verify_signatureicsfdd}|S(Ncs4tjdtj}g|_|_|_|S(Nuspec(umocku MagicMockurequestsuResponseucookiesutextu status_code(urukwargsuresp(ubodyu status_code(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu fake_send8s    u.OAuth1SessionTest.fake_body..fake_send((uselfubodyu status_codeu fake_send((ubodyu status_codeuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyu fake_body7suOAuth1SessionTest.fake_bodyN(u__name__u __module__u __qualname__usetUputest_signature_typesumockupatchutest_signature_methodsutest_binary_uploadu test_nonasciiutest_authorization_urlutest_parse_response_urlutest_fetch_request_tokenu0test_fetch_request_token_with_optional_argumentsutest_fetch_access_tokenu/test_fetch_access_token_with_optional_argumentsu%_test_fetch_access_token_raises_erroru!test_fetch_token_invalid_responseu(test_fetch_access_token_missing_verifieru,test_fetch_access_token_has_verifier_is_noneutest_authorized_falseutest_authorized_false_rsautest_authorized_trueutest_authorized_true_rsauverify_signatureu fake_body(u __locals__((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyuOAuth1SessionTestRs2              uOAuth1SessionTest($u __future__uunicode_literalsuprint_functionumockuunittestusysurequestsuoauthlib.oauth1uSIGNATURE_TYPE_QUERYuSIGNATURE_TYPE_BODYu SIGNATURE_RSAuSIGNATURE_PLAINTEXTurequests_oauthlibu OAuth1SessionuStringIOu ImportErroruiou cryptographyuNoneuversionustru unicode_typeubytesu bytes_typeuunicodeuhasattruRuntimeWarninguSkipTestu TestResultuaddErrorureal_add_errorupatched_addErroru TEST_RSA_KEYuTEST_RSA_OAUTH_SIGNATUREuTestCaseuOAuth1SessionTest(((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pyus8           requests-oauthlib-0.8.0/tests/__pycache__/test_oauth1_session.cpython-34.pyc0000644000076500000240000003504612770742404027316 0ustar corystaff00000000000000 ;V8@sddlmZmZddlZddlZddlZddlZddlmZm Z ddlm Z m Z ddl m Z yddlmZWn"ek rddlmZYnXyddlZWnek rdZYnXejddkreZeZn eZeZeedsYee_ejjej_d d Zeej_nd Zd Z Gd ddej!Z"dS))unicode_literalsprint_functionN)SIGNATURE_TYPE_QUERYSIGNATURE_TYPE_BODY) SIGNATURE_RSASIGNATURE_PLAINTEXT) OAuth1Session)StringIO3SkipTestcCsK|dtkr7tt|ddddtjdS|j||dS)Nrend file)RuntimeWarningprintstrsysstderrreal_add_error)selftestexc_inforX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pypatched_addError!s#ra-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEApF1JaMSN8TEsh4N4O/5SpEAVLivJyLH+Cgl3OQBPGgJkt8cg 49oasl+5iJS+VdrILxWM9/JCJyURpUuslX4Eb4eUBtQ0x5BaPa8+S2NLdGTaL7nB OO8o8n0C5FEUU+qlEip79KE8aqOj+OC44VsIquSmOvWIQD26n3fCVlgwoRBD1gzz sDOeaSyzpKrZR851Kh6rEmF2qjJ8jt6EkxMsRNACmBomzgA4M1TTsisSUO87444p e35Z4/n5c735o2fZMrGgMwiJNh7rT8SYxtIkxngioiGnwkxGQxQ4NzPAHg+XSY0J 04pNm7KqTkgtxyrqOANJLIjXlR+U9SQ90NjHVQIDAQABAoIBABuBPOKaWcJt3yzC NGGduoif7KtwSnEaUA+v69KPGa2Zju8uFHPssKD+4dZYRc2qMeunKJLpaGaSjnRh yHyvvOBJCN1nr3lhz6gY5kzJTfwpUFXCOPJlGy4Q+2Xnp4YvcvYqQ9n5DVovDiZ8 vJOBn16xqpudMPLHIa7D5LJ8SY76HBjE+imTXw1EShdh5TOV9bmPFQqH6JFzowRH hyH2DPHuyHJj6cl8FyqJw5lVWzG3n6Prvk7bYHsjmGjurN35UsumNAp6VouNyUP1 RAEcUJega49aIs6/FJ0ENJzQjlsAzVbTleHkpez2aIok+wsWJGJ4SVxAjADOWAaZ uEJPc3UCgYEA1g4ZGrXOuo75p9/MRIepXGpBWxip4V7B9XmO9WzPCv8nMorJntWB msYV1I01aITxadHatO4Gl2xLniNkDyrEQzJ7w38RQgsVK+CqbnC0K9N77QPbHeC1 YQd9RCNyUohOimKvb7jyv798FBU1GO5QI2eNgfnnfteSVXhD2iOoTOsCgYEAxJJ+ 8toxJdnLa0uUsAbql6zeNXGbUBMzu3FomKlyuWuq841jS2kIalaO/TRj5hbnE45j mCjeLgTVO6Ach3Wfk4zrqajqfFJ0zUg/Wexp49lC3RWiV4icBb85Q6bzeJD9Dn9v hjpfWVkczf/NeA1fGH/pcgfkT6Dm706GFFttLL8CgYBl/HeXk1H47xAiHO4dJKnb v0B+X8To/RXamF01r+8BpUoOubOQetdyX7ic+d6deuHu8i6LD/GSCeYJZYFR/KVg AtiW757QYalnq3ZogkhFrVCZP8IRfTPOFBxp752TlyAcrSI7T9pQ47IBe4094KXM CJWSfPgAJkOxd0iU0XJpmwKBgGfQxuMTgSlwYRKFlD1zKap5TdID8fbUbVnth0Q5 GbH7vwlp/qrxCdS/aj0n0irOpbOaW9ccnlrHiqY25VpVMLYIkt3DrDOEiNNx+KNR TItdTwbcSiTYrS4L0/56ydM/H6bsfsXxRjI18hSJqMZiqXqS84OZz2aOn+h7HCzc LEiZAoGASk20wFvilpRKHq79xxFWiDUPHi0x0pp82dYIEntGQkKUWkbSlhgf3MAi 5NEQTDmXdnB+rVeWIvEi+BXfdnNgdn8eC4zSdtF4sIAhYr5VWZo0WVWDhT7u2ccv ZBFymiz8lo3gN57wGUCi9pbZqzV1+ZppX6YTNDdDCE0q+KO3Cec= -----END RSA PRIVATE KEY-----apj8WF8PGjojT82aUDd2EL%2Bz7HCoHInFzWUpiEKMCy%2BJ2cYHWcBS7mXlmFDLgAKV0P%2FyX4TrpXODYnJ6dRWdfghqwDpi%2FlQmB2jxCiGMdJoYxh3c5zDf26gEbGdP6D7OSsp5HUnzH6sNkmVjuE%2FxoJcHJdc23H6GhOs7VJ2LWNdbhKWP%2FMMlTrcoQDn8lz%2Fb24WsJ6ae1txkUzpFOOlLM8aTdNtGL4OtsubOlRhNqnAFq93FyhXg0KjzUyIZzmMX9Vx90jTks5QeBGYcLE0Op2iHb2u%2FO%2BEgdwFchgEwE5LgMUyHUI4F3Wglp28yHOAMjPkI%2FkWMvpxtMrU3Z3KN31WQ%3D%3Dc@seZdZddZddZejdejdddZejdejdd d Zejdejdd d Z d dZ ddZ ddZ ddZ ddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zejdejdd'd(Zd)d*Zd+d,d-Zd.S)/OAuth1SessionTestcs+tds'fdd_ndS)NassertIncsj||kS)N) assertTrue)ab)rrrWsz)OAuth1SessionTest.setUp..)hasattrr)rr)rrsetUpTszOAuth1SessionTest.setUpcsfdd}td}|dd|_|jdtddt}|dd|_|jdtddt}id d 6}|d d|_|jdd |d ddS)Ncsfdd}|S)Ncs_|}t|tr-|jd}njd|tjdtj}g|_|S)Nzutf-8oauth_signaturespec) isinstance bytes_typedecodermock MagicMockrequestsResponsecookies)rkwargs signatureresp)getterrrr fake_send[s  zSOAuth1SessionTest.test_signature_types..verify_signature..fake_sendr)r2r3)r)r2rverify_signatureZsz@OAuth1SessionTest.test_signature_types..verify_signaturefoocSs |jdS)N Authorization)headers)r.rrrr!fsz8OAuth1SessionTest.test_signature_types..z https://i.bsignature_typecSs|jS)N)url)r.rrrr!jsz!application/x-www-form-urlencodedz Content-TypecSs|jS)N)body)r.rrrr!osr7data)rsendpostrr)rr4headerqueryr:r7r)rrtest_signature_typesYs    z&OAuth1SessionTest.test_signature_typesz*oauthlib.oauth1.rfc5849.generate_timestampz&oauthlib.oauth1.rfc5849.generate_noncecCststjdnd|_d|_d}td}|j||_|jdd}tddt}|j||_|jdd j d t }tddt d t }|j||_|jddS) Nzcryptography module is requiredabc123zOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"r5z https://i.bzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="foo", oauth_signature="%26"signature_methodzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"sigrsa_key) cryptographyunittestr return_valuerr4r=r>rformatTEST_RSA_OAUTH_SIGNATUREr TEST_RSA_KEY)rgenerate_noncegenerate_timestampr0authrrrtest_signature_methodsrs$        z(OAuth1SessionTest.test_signature_methodscCsud|_d|_td}idd6}d}td}|j||_|jdd |d d |fgdS) NrBrCz hello worldzapplication/xmlz Content-TypezOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"r5z https://i.br7filesZfake)rIr rr4r=r>)rrMrNZfake_xmlr7r0rOrrrtest_binary_uploads     z$OAuth1SessionTest.test_binary_uploadcCsGd|_d|_d}td}|j||_|jddS)NrBrCzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="W0haoue5IZAZoaJiYCtfqwMf8x8%3D"r5z"https://i.b?cjk=%E5%95%A6%E5%95%A6)rIrr4r=r>)rrMrNr0rOrrr test_nonasciis    zOAuth1SessionTest.test_nonasciicCsItd}d}d}|j|d|}|j||d|dS)Nr5zhttps://example.comm/authorizeZ asluif023sf request_tokenz ?oauth_token=)rauthorization_url assertEqual)rrOr9tokenauth_urlrrrtest_authorization_urls  z(OAuth1SessionTest.test_authorization_urlcCsd}td}|j|}|j|dd|j|ddxF|jD]8\}}|jt|t|jt|tqVWdS)Nz7https://i.b/callback?oauth_token=foo&oauth_verifier=barr5 oauth_tokenoauth_verifierbar)rparse_authorization_responserVitemsrr& unicode_type)rr9rOr1kvrrrtest_parse_response_urls z)OAuth1SessionTest.test_parse_response_urlcCstd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqNWdS)Nr5zoauth_token=foozhttps://example.com/tokenrZ) r fake_bodyr=fetch_request_tokenrVr^rr&r_)rrOr1r`rarrrtest_fetch_request_tokens z*OAuth1SessionTest.test_fetch_request_tokencCstd}|jd|_|jddddd}|j|ddxF|jD]8\}}|jt|t|jt|tqZWdS) Nr5zoauth_token=foozhttps://example.com/tokenverifyFstreamTrZ) rrcr=rdrVr^rr&r_)rrOr1r`rarrr0test_fetch_request_token_with_optional_argumentss  zBOAuth1SessionTest.test_fetch_request_token_with_optional_argumentscCstddd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqTWdS)Nr5verifierr\zoauth_token=foozhttps://example.com/tokenrZ) rrcr=fetch_access_tokenrVr^rr&r_)rrOr1r`rarrrtest_fetch_access_tokensz)OAuth1SessionTest.test_fetch_access_tokencCstddd}|jd|_|jddddd }|j|d dxF|jD]8\}}|jt|t|jt|tq`WdS) Nr5rir\zoauth_token=foozhttps://example.com/tokenrfFrgTrZ) rrcr=rjrVr^rr&r_)rrOr1r`rarrr/test_fetch_access_token_with_optional_argumentss zAOAuth1SessionTest.test_fetch_access_token_with_optional_argumentscCse|jd|_y|jdWn;tk r`}z|jdt|WYdd}~XnXdS)zkAssert that an error is being raised whenever there's no verifier passed in to the client. zoauth_token=foozhttps://example.com/tokenz No client verifier has been set.N)rcr=rj ValueErrorrVr)rrOexcrrr%_test_fetch_access_token_raises_errors z7OAuth1SessionTest._test_fetch_access_token_raises_errorcCstd}|jd|_|jt|jdxd D]}|jd||_y|jdWnTtk r}z4|j|j||jt |j t j WYdd}~Xq;X|j dq;WdS) Nr5znot valid urlencoded response!zhttps://example.com/tokenzvalid=responsezValueError not raised)rprqrr)rrcr= assertRaisesrmrdrV status_coderr&responser+r,fail)rrOcodeerrrrr!test_fetch_token_invalid_responses  /z3OAuth1SessionTest.test_fetch_token_invalid_responsecCs|jtddS)Nr5)ror)rrrr(test_fetch_access_token_missing_verifiersz:OAuth1SessionTest.test_fetch_access_token_missing_verifiercCs)td}|jj`|j|dS)Nr5)r_clientclientriro)rrOrrr,test_fetch_access_token_has_verifier_is_nones  z>OAuth1SessionTest.test_fetch_access_token_has_verifier_is_nonecCs td}|j|jdS)Nr5)r assertFalse authorized)rsessrrrtest_authorized_falses z'OAuth1SessionTest.test_authorized_falsecCsPdjdt}tddtdt}|j||_|j|jdS)NzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"rEr5rDrF) rJrKrrrLr4r=r~r)rr0rrrrtest_authorized_false_rsas    z+OAuth1SessionTest.test_authorized_false_rsacCsHtdddd}|jd|_|jd|j|jdS)Nkeysecretrir\z&oauth_token=foo&oauth_token_secret=barzhttps://example.com/token)rrcr=rjrr)rrrrrtest_authorized_trues z&OAuth1SessionTest.test_authorized_truec Cststjdnd|_d|_djdt}tdddtd td d }|j d |_ |j d |j |j dS)Nzcryptography module is requiredrBrCzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_verifier="bar", oauth_signature="{sig}"rErrrDrFrir\z&oauth_token=foo&oauth_token_secret=barzhttps://example.com/token)rGrHr rIrJrKrrrLrcr=rjrr)rrMrNr0rrrrtest_authorized_true_rsas     z*OAuth1SessionTest.test_authorized_true_rsacsfdd}|S)Ncs`|jd}t|tr.|jd}nj|tjdtj}g|_ |S)Nr6zutf-8r%) r7r&r'r(rVr)r*r+r,r-)r.r/ auth_headerr1)rr0rrr3-s  z5OAuth1SessionTest.verify_signature..fake_sendr)rr0r3r)rr0rr4,sz"OAuth1SessionTest.verify_signaturecsfdd}|S)Ncs4tjdtj}g|_|_|_|S)Nr%)r)r*r+r,r-textrt)r.r/r1)r:rtrrr38s    z.OAuth1SessionTest.fake_body..fake_sendr)rr:rtr3r)r:rtrrc7szOAuth1SessionTest.fake_bodyN)__name__ __module__ __qualname__r#rAr)patchrPrRrSrYrbrerhrkrlroryrzr}rrrrr4rcrrrrrRs2               r)# __future__rrr)rHrr+oauthlib.oauth1rrrrrequests_oauthlibrr ImportErroriorGversionrr_bytesr'unicoder"rr TestResultaddErrorrrrLrKTestCaserrrrrs8           requests-oauthlib-0.8.0/tests/__pycache__/test_oauth1_session.cpython-35.pyc0000644000076500000240000003502212770742411027307 0ustar corystaff00000000000000 ;V8@sddlmZmZddlZddlZddlZddlZddlmZm Z ddlm Z m Z ddl m Z yddlmZWn"ek rddlmZYnXyddlZWnek rdZYnXejddkreZeZn eZeZeedsVee_ejjej_d d Zeej_d Zd Z Gd ddej!Z"dS))unicode_literalsprint_functionN)SIGNATURE_TYPE_QUERYSIGNATURE_TYPE_BODY) SIGNATURE_RSASIGNATURE_PLAINTEXT) OAuth1Session)StringIO3SkipTestcCsK|dtkr7tt|ddddtjdS|j||dS)Nrend file)RuntimeWarningprintstrsysstderrreal_add_error)selftestexc_inforX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pypatched_addError!s#ra-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEApF1JaMSN8TEsh4N4O/5SpEAVLivJyLH+Cgl3OQBPGgJkt8cg 49oasl+5iJS+VdrILxWM9/JCJyURpUuslX4Eb4eUBtQ0x5BaPa8+S2NLdGTaL7nB OO8o8n0C5FEUU+qlEip79KE8aqOj+OC44VsIquSmOvWIQD26n3fCVlgwoRBD1gzz sDOeaSyzpKrZR851Kh6rEmF2qjJ8jt6EkxMsRNACmBomzgA4M1TTsisSUO87444p e35Z4/n5c735o2fZMrGgMwiJNh7rT8SYxtIkxngioiGnwkxGQxQ4NzPAHg+XSY0J 04pNm7KqTkgtxyrqOANJLIjXlR+U9SQ90NjHVQIDAQABAoIBABuBPOKaWcJt3yzC NGGduoif7KtwSnEaUA+v69KPGa2Zju8uFHPssKD+4dZYRc2qMeunKJLpaGaSjnRh yHyvvOBJCN1nr3lhz6gY5kzJTfwpUFXCOPJlGy4Q+2Xnp4YvcvYqQ9n5DVovDiZ8 vJOBn16xqpudMPLHIa7D5LJ8SY76HBjE+imTXw1EShdh5TOV9bmPFQqH6JFzowRH hyH2DPHuyHJj6cl8FyqJw5lVWzG3n6Prvk7bYHsjmGjurN35UsumNAp6VouNyUP1 RAEcUJega49aIs6/FJ0ENJzQjlsAzVbTleHkpez2aIok+wsWJGJ4SVxAjADOWAaZ uEJPc3UCgYEA1g4ZGrXOuo75p9/MRIepXGpBWxip4V7B9XmO9WzPCv8nMorJntWB msYV1I01aITxadHatO4Gl2xLniNkDyrEQzJ7w38RQgsVK+CqbnC0K9N77QPbHeC1 YQd9RCNyUohOimKvb7jyv798FBU1GO5QI2eNgfnnfteSVXhD2iOoTOsCgYEAxJJ+ 8toxJdnLa0uUsAbql6zeNXGbUBMzu3FomKlyuWuq841jS2kIalaO/TRj5hbnE45j mCjeLgTVO6Ach3Wfk4zrqajqfFJ0zUg/Wexp49lC3RWiV4icBb85Q6bzeJD9Dn9v hjpfWVkczf/NeA1fGH/pcgfkT6Dm706GFFttLL8CgYBl/HeXk1H47xAiHO4dJKnb v0B+X8To/RXamF01r+8BpUoOubOQetdyX7ic+d6deuHu8i6LD/GSCeYJZYFR/KVg AtiW757QYalnq3ZogkhFrVCZP8IRfTPOFBxp752TlyAcrSI7T9pQ47IBe4094KXM CJWSfPgAJkOxd0iU0XJpmwKBgGfQxuMTgSlwYRKFlD1zKap5TdID8fbUbVnth0Q5 GbH7vwlp/qrxCdS/aj0n0irOpbOaW9ccnlrHiqY25VpVMLYIkt3DrDOEiNNx+KNR TItdTwbcSiTYrS4L0/56ydM/H6bsfsXxRjI18hSJqMZiqXqS84OZz2aOn+h7HCzc LEiZAoGASk20wFvilpRKHq79xxFWiDUPHi0x0pp82dYIEntGQkKUWkbSlhgf3MAi 5NEQTDmXdnB+rVeWIvEi+BXfdnNgdn8eC4zSdtF4sIAhYr5VWZo0WVWDhT7u2ccv ZBFymiz8lo3gN57wGUCi9pbZqzV1+ZppX6YTNDdDCE0q+KO3Cec= -----END RSA PRIVATE KEY-----apj8WF8PGjojT82aUDd2EL%2Bz7HCoHInFzWUpiEKMCy%2BJ2cYHWcBS7mXlmFDLgAKV0P%2FyX4TrpXODYnJ6dRWdfghqwDpi%2FlQmB2jxCiGMdJoYxh3c5zDf26gEbGdP6D7OSsp5HUnzH6sNkmVjuE%2FxoJcHJdc23H6GhOs7VJ2LWNdbhKWP%2FMMlTrcoQDn8lz%2Fb24WsJ6ae1txkUzpFOOlLM8aTdNtGL4OtsubOlRhNqnAFq93FyhXg0KjzUyIZzmMX9Vx90jTks5QeBGYcLE0Op2iHb2u%2FO%2BEgdwFchgEwE5LgMUyHUI4F3Wglp28yHOAMjPkI%2FkWMvpxtMrU3Z3KN31WQ%3D%3Dc@seZdZddZddZejdejdddZejdejdd d Zejdejdd d Z d dZ ddZ ddZ ddZ ddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zejdejdd'd(Zd)d*Zd+d,d-Zd.S)/OAuth1SessionTestcs(tds$fdd_dS)NassertIncsj||kS)N) assertTrue)ab)rrrWsz)OAuth1SessionTest.setUp..)hasattrr)rr)rrsetUpTszOAuth1SessionTest.setUpcsfdd}td}|dd|_|jdtddt}|dd|_|jdtddt}d d i}|d d|_|jdd |d ddS)Ncsfdd}|S)Ncs\|}t|tr*|jd}jd|tjdtj}g|_|S)Nzutf-8oauth_signaturespec) isinstance bytes_typedecodermock MagicMockrequestsResponsecookies)rkwargs signatureresp)getterrrr fake_send[s  zSOAuth1SessionTest.test_signature_types..verify_signature..fake_sendr)r2r3)r)r2rverify_signatureZsz@OAuth1SessionTest.test_signature_types..verify_signaturefoocSs |jdS)N Authorization)headers)r.rrrr!fsz8OAuth1SessionTest.test_signature_types..z https://i.bsignature_typecSs|jS)N)url)r.rrrr!jsz Content-Typez!application/x-www-form-urlencodedcSs|jS)N)body)r.rrrr!osr7data)rsendpostrr)rr4headerqueryr:r7r)rrtest_signature_typesYs    z&OAuth1SessionTest.test_signature_typesz*oauthlib.oauth1.rfc5849.generate_timestampz&oauthlib.oauth1.rfc5849.generate_noncecCststjdd|_d|_d}td}|j||_|jdd}tddt}|j||_|jdd j d t }tddt d t }|j||_|jddS) Nzcryptography module is requiredabc123zOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"r5z https://i.bzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="foo", oauth_signature="%26"signature_methodzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"sigrsa_key) cryptographyunittestr return_valuerr4r=r>rformatTEST_RSA_OAUTH_SIGNATUREr TEST_RSA_KEY)rgenerate_noncegenerate_timestampr0authrrrtest_signature_methodsrs$        z(OAuth1SessionTest.test_signature_methodscCstd|_d|_td}ddi}d}td}|j||_|jdd |d d |fgdS) NrBrCz hello worldz Content-Typezapplication/xmlzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"r5z https://i.br7filesZfake)rIr rr4r=r>)rrMrNZfake_xmlr7r0rOrrrtest_binary_uploads     z$OAuth1SessionTest.test_binary_uploadcCsGd|_d|_d}td}|j||_|jddS)NrBrCzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="W0haoue5IZAZoaJiYCtfqwMf8x8%3D"r5z"https://i.b?cjk=%E5%95%A6%E5%95%A6)rIrr4r=r>)rrMrNr0rOrrr test_nonasciis    zOAuth1SessionTest.test_nonasciicCsItd}d}d}|j|d|}|j||d|dS)Nr5zhttps://example.comm/authorizeZ asluif023sf request_tokenz ?oauth_token=)rauthorization_url assertEqual)rrOr9tokenauth_urlrrrtest_authorization_urls  z(OAuth1SessionTest.test_authorization_urlcCsd}td}|j|}|j|dd|j|ddxF|jD]8\}}|jt|t|jt|tqVWdS)Nz7https://i.b/callback?oauth_token=foo&oauth_verifier=barr5 oauth_tokenoauth_verifierbar)rparse_authorization_responserVitemsrr& unicode_type)rr9rOr1kvrrrtest_parse_response_urls z)OAuth1SessionTest.test_parse_response_urlcCstd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqNWdS)Nr5zoauth_token=foozhttps://example.com/tokenrZ) r fake_bodyr=fetch_request_tokenrVr^rr&r_)rrOr1r`rarrrtest_fetch_request_tokens z*OAuth1SessionTest.test_fetch_request_tokencCstd}|jd|_|jddddd}|j|ddxF|jD]8\}}|jt|t|jt|tqZWdS) Nr5zoauth_token=foozhttps://example.com/tokenverifyFstreamTrZ) rrcr=rdrVr^rr&r_)rrOr1r`rarrr0test_fetch_request_token_with_optional_argumentss  zBOAuth1SessionTest.test_fetch_request_token_with_optional_argumentscCstddd}|jd|_|jd}|j|ddxF|jD]8\}}|jt|t|jt|tqTWdS)Nr5verifierr\zoauth_token=foozhttps://example.com/tokenrZ) rrcr=fetch_access_tokenrVr^rr&r_)rrOr1r`rarrrtest_fetch_access_tokensz)OAuth1SessionTest.test_fetch_access_tokencCstddd}|jd|_|jddddd }|j|d dxF|jD]8\}}|jt|t|jt|tq`WdS) Nr5rir\zoauth_token=foozhttps://example.com/tokenrfFrgTrZ) rrcr=rjrVr^rr&r_)rrOr1r`rarrr/test_fetch_access_token_with_optional_argumentss zAOAuth1SessionTest.test_fetch_access_token_with_optional_argumentscCse|jd|_y|jdWn;tk r`}z|jdt|WYdd}~XnXdS)zkAssert that an error is being raised whenever there's no verifier passed in to the client. zoauth_token=foozhttps://example.com/tokenz No client verifier has been set.N)rcr=rj ValueErrorrVr)rrOexcrrr%_test_fetch_access_token_raises_errors z7OAuth1SessionTest._test_fetch_access_token_raises_errorcCstd}|jd|_|jt|jdxd D]}|jd||_y|jdWnTtk r}z4|j|j||jt |j t j WYdd}~Xq;X|j dq;WdS) Nr5znot valid urlencoded response!zhttps://example.com/tokenzvalid=responsezValueError not raised)rprqrr)rrcr= assertRaisesrmrdrV status_coderr&responser+r,fail)rrOcodeerrrrr!test_fetch_token_invalid_responses  /z3OAuth1SessionTest.test_fetch_token_invalid_responsecCs|jtddS)Nr5)ror)rrrr(test_fetch_access_token_missing_verifiersz:OAuth1SessionTest.test_fetch_access_token_missing_verifiercCs)td}|jj`|j|dS)Nr5)r_clientclientriro)rrOrrr,test_fetch_access_token_has_verifier_is_nones  z>OAuth1SessionTest.test_fetch_access_token_has_verifier_is_nonecCs td}|j|jdS)Nr5)r assertFalse authorized)rsessrrrtest_authorized_falses z'OAuth1SessionTest.test_authorized_falsecCsPdjdt}tddtdt}|j||_|j|jdS)NzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"rEr5rDrF) rJrKrrrLr4r=r~r)rr0rrrrtest_authorized_false_rsas    z+OAuth1SessionTest.test_authorized_false_rsacCsHtdddd}|jd|_|jd|j|jdS)Nkeysecretrir\z&oauth_token=foo&oauth_token_secret=barzhttps://example.com/token)rrcr=rjrr)rrrrrtest_authorized_trues z&OAuth1SessionTest.test_authorized_truec Cststjdd|_d|_djdt}tdddtd td d }|j d |_ |j d |j |j dS)Nzcryptography module is requiredrBrCzOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_verifier="bar", oauth_signature="{sig}"rErrrDrFrir\z&oauth_token=foo&oauth_token_secret=barzhttps://example.com/token)rGrHr rIrJrKrrrLrcr=rjrr)rrMrNr0rrrrtest_authorized_true_rsas     z*OAuth1SessionTest.test_authorized_true_rsacsfdd}|S)Ncs]|jd}t|tr+|jd}j|tjdtj}g|_ |S)Nr6zutf-8r%) r7r&r'r(rVr)r*r+r,r-)r.r/ auth_headerr1)rr0rrr3-s  z5OAuth1SessionTest.verify_signature..fake_sendr)rr0r3r)rr0rr4,sz"OAuth1SessionTest.verify_signaturecsfdd}|S)Ncs4tjdtj}g|_|_|_|S)Nr%)r)r*r+r,r-textrt)r.r/r1)r:rtrrr38s    z.OAuth1SessionTest.fake_body..fake_sendr)rr:rtr3r)r:rtrrc7szOAuth1SessionTest.fake_bodyN)__name__ __module__ __qualname__r#rAr)patchrPrRrSrYrbrerhrkrlroryrzr}rrrrr4rcrrrrrRs2               r)# __future__rrr)rHrr+oauthlib.oauth1rrrrrequests_oauthlibrr ImportErroriorGversionrr_bytesr'unicoder"rr TestResultaddErrorrrrLrKTestCaserrrrrs8            requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_auth.cpython-27-PYTEST.pyc0000644000076500000240000000650512222010772027607 0ustar corystaff00000000000000 'CRc@sddlmZddlZddljjZddlZddl m Z m Z ddl m Z m Z ddlmZddlmZdejfdYZdS( i(tunicode_literalsN(tWebApplicationClienttMobileApplicationClient(tLegacyApplicationClienttBackendApplicationClient(tRequest(tOAuth2tOAuth2AuthTestcBs5eZdZdZdZdZdZRS(cCsdidd6dd6dd6|_d|_t|jt|jt|jt|jg|_dS(NuBeareru token_typeuasdfoiw37850234lkjsdfsdfu access_tokenu3600u expires_inufoo(ttokent client_idRRRRtclients(tself((sU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pytsetUp s     cCsd}|d|jd}x`|jD]U}d|_td|d|j}td|d|j}|j|j|q%WdS( Nu$https://example.com/resource?foo=baru&access_token=u access_tokenuquerytclientRuGETtauth(RR tdefault_token_placementRRtpreparet assertEqualturl(R Rtnew_urlR Rtr((sU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyttest_add_token_to_urls cCssd|jd}x[|jD]P}td|d|j}tddd|j}|j|jd|qWdS( NuBearer u access_tokenR RuGETu https://i.bRu Authorization(RR RRRRtheaders(R RR RR((sU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyttest_add_token_to_headers#s cCsd}|d|jd}xf|jD][}d|_td|d|j}tddd |d |j}|j|j|q%WdS( Nufoo=baru&access_token=u access_tokenubodyR RuGETu https://i.btdataR(RR RRRRRtbody(R Rtnew_bodyR RR((sU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyttest_add_token_to_body*s !cCsOxH|jD]=}td|}tddd|}|jt|jq WdS(NR uGETu https://i.bR(R RRt assertRaisest ValueErrorR(R R RR((sU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyttest_add_nonexisting_token3s(t__name__t __module__R RRRR(((sU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyR s    (t __future__Rt __builtin__t @py_builtinst_pytest.assertion.rewritet assertiontrewritet @pytest_artunittesttoauthlib.oauth2RRRRtrequestsRtrequests_oauthlibRtTestCaseR(((sU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyts  requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_auth.cpython-33.pyc0000644000076500000240000001012612633523103026553 0ustar corystaff00000000000000 'CRbc@sddlmZddlZddlmZmZddlmZmZddlm Z ddl m Z Gdddej Z dS( i(uunicode_literalsN(uWebApplicationClientuMobileApplicationClient(uLegacyApplicationClientuBackendApplicationClient(uRequest(uOAuth2cBsP|EeZdZddZddZddZddZd d Zd S( uOAuth2AuthTestcCsdidd6dd6dd6|_d|_t|jt|jt|jt|jg|_dS(NuBeareru token_typeuasdfoiw37850234lkjsdfsdfu access_tokenu3600u expires_inufoo(utokenu client_iduWebApplicationClientuMobileApplicationClientuLegacyApplicationClientuBackendApplicationClientuclients(uself((uU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyusetUp s     uOAuth2AuthTest.setUpcCsd}|d|jd}x`|jD]U}d|_td|d|j}td|d|j}|j|j|q%WdS( Nu$https://example.com/resource?foo=baru&access_token=u access_tokenuqueryuclientutokenuGETuauth(utokenuclientsudefault_token_placementuOAuth2uRequestuprepareu assertEqualuurl(uselfuurlunew_urluclientuauthur((uU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyutest_add_token_to_urls u$OAuth2AuthTest.test_add_token_to_urlcCssd|jd}x[|jD]P}td|d|j}tddd|j}|j|jd|qWdS( NuBearer u access_tokenuclientutokenuGETu https://i.buauthu Authorization(utokenuclientsuOAuth2uRequestuprepareu assertEqualuheaders(uselfutokenuclientuauthur((uU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyutest_add_token_to_headers#s u(OAuth2AuthTest.test_add_token_to_headerscCsd}|d|jd}xf|jD][}d|_td|d|j}tddd |d |j}|j|j|q%WdS( Nufoo=baru&access_token=u access_tokenubodyuclientutokenuGETu https://i.budatauauth(utokenuclientsudefault_token_placementuOAuth2uRequestuprepareu assertEqualubody(uselfubodyunew_bodyuclientuauthur((uU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyutest_add_token_to_body*s !u%OAuth2AuthTest.test_add_token_to_bodycCsOxH|jD]=}td|}tddd|}|jt|jq WdS(NuclientuGETu https://i.buauth(uclientsuOAuth2uRequestu assertRaisesu ValueErroruprepare(uselfuclientuauthur((uU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyutest_add_nonexisting_token3su)OAuth2AuthTest.test_add_nonexisting_tokenN(u__name__u __module__u __qualname__usetUputest_add_token_to_urlutest_add_token_to_headersutest_add_token_to_bodyutest_add_nonexisting_token(u __locals__((uU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyuOAuth2AuthTest s    uOAuth2AuthTest(u __future__uunicode_literalsuunittestuoauthlib.oauth2uWebApplicationClientuMobileApplicationClientuLegacyApplicationClientuBackendApplicationClienturequestsuRequesturequests_oauthlibuOAuth2uTestCaseuOAuth2AuthTest(((uU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pyus  requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_auth.cpython-34.pyc0000644000076500000240000000522312617164042026563 0ustar corystaff00000000000000 'CRb@sddlmZddlZddlmZmZddlmZmZddlm Z ddl m Z Gdddej Z dS) )unicode_literalsN)WebApplicationClientMobileApplicationClient)LegacyApplicationClientBackendApplicationClient)Request)OAuth2c@sLeZdZddZddZddZddZd d Zd S) OAuth2AuthTestcCsdidd6dd6dd6|_d|_t|jt|jt|jt|jg|_dS)NBearer token_typeZasdfoiw37850234lkjsdfsdf access_tokenZ3600 expires_infoo)token client_idrrrrclients)selfrU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pysetUp s     zOAuth2AuthTest.setUpcCsd}|d|jd}x`|jD]U}d|_td|d|j}td|d|j}|j|j|q%WdS) Nz$https://example.com/resource?foo=barz&access_token=r queryclientrGETauth)rrdefault_token_placementrrprepare assertEqualurl)rrnew_urlrrrrrrtest_add_token_to_urls z$OAuth2AuthTest.test_add_token_to_urlcCssd|jd}x[|jD]P}td|d|j}tddd|j}|j|jd|qWdS) NzBearer r rrrz https://i.br Authorization)rrrrrrheaders)rrrrrrrrtest_add_token_to_headers#s z(OAuth2AuthTest.test_add_token_to_headerscCsd}|d|jd}xf|jD][}d|_td|d|j}tddd |d |j}|j|j|q%WdS) Nzfoo=barz&access_token=r bodyrrrz https://i.bdatar)rrrrrrrr$)rr$Znew_bodyrrrrrrtest_add_token_to_body*s !z%OAuth2AuthTest.test_add_token_to_bodycCsOxH|jD]=}td|}tddd|}|jt|jq WdS)Nrrz https://i.br)rrr assertRaises ValueErrorr)rrrrrrrtest_add_nonexisting_token3sz)OAuth2AuthTest.test_add_nonexisting_tokenN)__name__ __module__ __qualname__rr r#r&r)rrrrr s    r ) __future__runittestoauthlib.oauth2rrrrrequestsrrequests_oauthlibrTestCaser rrrrs  requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_auth.cpython-35.pyc0000644000076500000240000000521612633523123026563 0ustar corystaff00000000000000 'CRb@sddlmZddlZddlmZmZddlmZmZddlm Z ddl m Z Gdddej Z dS) )unicode_literalsN)WebApplicationClientMobileApplicationClient)LegacyApplicationClientBackendApplicationClient)Request)OAuth2c@sLeZdZddZddZddZddZd d Zd S) OAuth2AuthTestcCsaddddddi|_d|_t|jt|jt|jt|jg|_dS)N token_typeBearer access_tokenZasdfoiw37850234lkjsdfsdf expires_inZ3600foo)token client_idrrrrclients)selfrU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pysetUp s    zOAuth2AuthTest.setUpcCsd}|d|jd}x`|jD]U}d|_td|d|j}td|d|j}|j|j|q%WdS) Nz$https://example.com/resource?foo=barz&access_token=r queryclientrGETauth)rrdefault_token_placementrrprepare assertEqualurl)rrnew_urlrrrrrrtest_add_token_to_urls z$OAuth2AuthTest.test_add_token_to_urlcCssd|jd}x[|jD]P}td|d|j}tddd|j}|j|jd|qWdS) NzBearer r rrrz https://i.br Authorization)rrrrrrheaders)rrrrrrrrtest_add_token_to_headers#s z(OAuth2AuthTest.test_add_token_to_headerscCsd}|d|jd}xf|jD][}d|_td|d|j}tddd |d |j}|j|j|q%WdS) Nzfoo=barz&access_token=r bodyrrrz https://i.bdatar)rrrrrrrr$)rr$Znew_bodyrrrrrrtest_add_token_to_body*s !z%OAuth2AuthTest.test_add_token_to_bodycCsOxH|jD]=}td|}tddd|}|jt|jq WdS)Nrrz https://i.br)rrr assertRaises ValueErrorr)rrrrrrrtest_add_nonexisting_token3sz)OAuth2AuthTest.test_add_nonexisting_tokenN)__name__ __module__ __qualname__rr r#r&r)rrrrr s    r ) __future__runittestoauthlib.oauth2rrrrrequestsrrequests_oauthlibrTestCaser rrrrs  requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_session.cpython-27-PYTEST.pyc0000644000076500000240000001407012222010772030325 0ustar corystaff00000000000000 'CRc@sddlmZddlZddljjZddlZddl Z ddl Z ddl m Z ddl mZmZddl mZmZddl mZmZddlmZmZde jfd YZdS( i(tunicode_literalsN(t urlencode(tTokenExpiredErrortInvalidRequestError(tWebApplicationClienttMobileApplicationClient(tLegacyApplicationClienttBackendApplicationClient(t OAuth2Sessiont TokenUpdatedtOAuth2SessionTestcBs>eZdZdZdZdZdZdZRS(cstds$fd_nidd6dd6dd6d d 6_d _tjd d tjtjg_jtjg_ dS(NuassertIncsj||kS(N(t assertTrue(tatb(tself(sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pytsuBeareru token_typeuasdfoiw37850234lkjsdfsdfu access_tokenusldvafkjw34509s8dfsdfu refresh_tokenu3600u expires_inufootcodeu asdf345xdf( thasattrtassertInttokent client_idRRRtclientsRt all_clients(R((RsX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pytsetUps   csidjdfd}x?jD]4}td|dj}||_|jdq-WdS(NuBearer u access_tokencso|jjdd}djd|jkrF|jdjd}nj|tj}g|_|S(Nu Authorizationuutf-8(theaderstgettNonetencodet assertEqualtmockt MagicMocktcookes(trtkwargst auth_headertresp(RR(sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pytverifier%s  tclientRu https://i.b(RRRtsendR(RR$R%tauth((RRsX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyttest_add_token"s   cCsd}t|j}td|}|j|\}}|j|||j|j||jd|t|j}td|}|j|\}}|j|||j|j||jd|dS(Nu%https://example.com/authorize?foo=barR%uresponse_type=codeuresponse_type=token(RRRtauthorization_urlRR(Rturltwebtstauth_urltstatetmobile((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyttest_authorization_url3sc s"tj_djd<fd}x?jD]4}td|dj}jt|jdq8WxNjD]C}td|djdd}||_jt |jdqzWfd }xKjD]@}td|djddd |}||_|jdqWdS( Nu-1u expires_incs%tj}tjj|_|S(N(RRtjsontdumpsRttext(R R!R#(R(sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyt fake_refreshHs R%Ru https://i.btauto_refresh_urluhttps://i.b/refreshcsj|jdS(N(RR(R(R(sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyt token_updaterZsR6( tdictRt expired_tokenRRt assertRaisesRRR&R (RR4R%R'R6((RsX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyttest_refresh_token_requestDs$     cCsWt|j}dt|jj}td|}|j|j||jdS(Nuhttps://i.b/callback#R%(RRRRtitemsRRttoken_from_fragment(RR/t response_urlR'((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyttest_token_from_fragmentdscCsd}d}xW|jD]L}td|d|j}||j|_|j|j||jqWidd6}xN|jD]C}td|d|j}|||_|jt|j|qWdS(Ncsfd}|S(Ncs"tj}tj|_|S(N(RRR1R2R3(R R!R#(R(sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyt fake_sendls ((RR?((RsX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyt fake_tokenksuhttps://example.com/tokenR%Ruinvalid_requestuerror(RRRR&Rt fetch_tokenR9R(RR@R*R%R'terror((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyttest_fetch_tokenjs   (t__name__t __module__RR(R0R:R>RC(((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyR s     (t __future__Rt __builtin__t @py_builtinst_pytest.assertion.rewritet assertiontrewritet @pytest_arR1Rtunittesttoauthlib.commonRtoauthlib.oauth2RRRRRRtrequests_oauthlibRR tTestCaseR (((sX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyts    requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_session.cpython-33.pyc0000644000076500000240000003623112770742400027307 0ustar corystaff00000000000000 WJ%c @s7ddlmZddlZddlZddlZddlmZddlmZyddl m Z Wn"e k rddl m Z YnXddl mZddlmZmZddlmZdd lmZmZdd lmZmZdd lmZmZejZd d ZGddde ZdS(i(uunicode_literalsN(u b64encode(udeepcopy(uTestCase(u urlencode(uTokenExpiredErroru OAuth2Error(uMismatchingStateError(uWebApplicationClientuMobileApplicationClient(uLegacyApplicationClientuBackendApplicationClient(u OAuth2Sessionu TokenUpdatedcsfdd}|S(Ncs"tj}tj|_|S(N(umocku MagicMockujsonudumpsutext(urukwargsuresp(utoken(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu fake_sends ufake_token..fake_send((utokenu fake_send((utokenuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu fake_tokensu fake_tokencBs|EeZdZddZddZddZejddd d d d Zejddd d ddZ ejdddd ddZ ddZ ddZ ddZ ddZddZddZejdddd d d!Zd"S(#uOAuth2SessionTestcstds'fdd_nidd6dd6dd 6d d 6td d 6_d_tjddtjtjg_jt jg_ dS(NuassertIncsj||kS(N(u assertTrue(uaub(uself(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu%su)OAuth2SessionTest.setUp..uBeareru token_typeuasdfoiw37850234lkjsdfsdfu access_tokenusldvafkjw34509s8dfsdfu refresh_tokenu3600u expires_iniu expires_atufooucodeu asdf345xdf( uhasattruassertInu fake_timeutokenu client_iduWebApplicationClientuLegacyApplicationClientuBackendApplicationClientuclientsuMobileApplicationClientu all_clients(uself((uselfuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyusetUp"s  uOAuth2SessionTest.setUpcsldjdfdd}x?jD]4}td|dj}||_|jdq0WdS(NuBearer u access_tokencso|jjdd}djd|jkrF|jdjd}nj|tj}g|_|S(Nu Authorizationuutf-8(uheadersugetuNoneuencodeu assertEqualumocku MagicMockucookes(urukwargsu auth_headeruresp(uselfutoken(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyuverifier9s  u2OAuth2SessionTest.test_add_token..verifieruclientutokenu https://i.b(utokenu all_clientsu OAuth2Sessionusenduget(uselfuverifieruclientuauth((uselfutokenuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_add_token6s   u OAuth2SessionTest.test_add_tokencCsd}t|j}td|}|j|\}}|j|||j|j||jd|t|j}td|}|j|\}}|j|||j|j||jd|dS(Nu%https://example.com/authorize?foo=baruclienturesponse_type=codeuresponse_type=token(uWebApplicationClientu client_idu OAuth2Sessionuauthorization_urluassertInuMobileApplicationClient(uselfuurluwebusuauth_urlustateumobile((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_authorization_urlGsu(OAuth2SessionTest.test_authorization_urlu time.timeunewcCstS(N(u fake_time(((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyuXsuOAuth2SessionTest.c stj_djd<jd=fdd}x?jD]4}td|dj}jt|jdqEWxNjD]C}td|djd d }||_jt |jdqWfd d }xKjD]@}td|djd d d |}||_|jdqWfdd}xWjD]L}td|djd d d |}||_|jdddddqJWdS(Nu-1u expires_inu expires_atcsJd|jkr%jd|jntj}tjj|_|S(Nu/refreshu Authorization( uurlu assertNotInuheadersumocku MagicMockujsonudumpsutokenutext(urukwargsuresp(uself(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu fake_refresh^s  uBOAuth2SessionTest.test_refresh_token_request..fake_refreshuclientutokenu https://i.buauto_refresh_urluhttps://i.b/refreshcsj|jdS(N(u assertEqualutoken(utoken(uself(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu token_updaterrsuCOAuth2SessionTest.test_refresh_token_request..token_updateru token_updatercsd|jkr[jd|jtd}d|jd}j|jd|ntj}tj j |_ |S(Nu/refreshu Authorizationsfoo:barsBasic ulatin1( uurluassertInuheadersu b64encodeudecodeu assertEqualumocku MagicMockujsonudumpsutokenutext(urukwargsuencodeducontenturesp(uself(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyufake_refresh_with_auth|s  uLOAuth2SessionTest.test_refresh_token_request..fake_refresh_with_authu client_idufoou client_secretubar( udictutokenu expired_tokenuclientsu OAuth2Sessionu assertRaisesuTokenExpiredErrorugetusendu TokenUpdated(uselfu fake_refreshuclientuauthu token_updaterufake_refresh_with_auth((uselfuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_refresh_token_requestXs4         u,OAuth2SessionTest.test_refresh_token_requestcCstS(N(u fake_time(((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyuscCsWt|j}dt|jj}td|}|j|j||jdS(Nuhttps://i.b/callback#uclient(uMobileApplicationClientu client_idu urlencodeutokenuitemsu OAuth2Sessionu assertEqualutoken_from_fragment(uselfumobileu response_urluauth((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_token_from_fragmentsu*OAuth2SessionTest.test_token_from_fragmentcCstS(N(u fake_time(((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyuscCsd}xW|jD]L}td|d|j}t|j|_|j|j||jqWidd6}xN|jD]C}td|d|j}t||_|jt|j|qwWdS(Nuhttps://example.com/tokenuclientutokenuinvalid_requestuerror( uclientsu OAuth2Sessionutokenu fake_tokenusendu assertEqualu fetch_tokenu assertRaisesu OAuth2Error(uselfuurluclientuauthuerror((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_fetch_tokens  u"OAuth2SessionTest.test_fetch_tokenc st|j}tjd}tj||jd<d|dsuVOAuth2SessionTest.test_cleans_previous_token_before_fetching_new_one..uclientutokenN( udeepcopyutokenutimeumockupatchuclientsu OAuth2Sessionu fake_tokenusendu assertEqualu fetch_token(uselfu new_tokenupastuurluclientuauth((unowuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu2test_cleans_previous_token_before_fetching_new_ones  uDOAuth2SessionTest.test_cleans_previous_token_before_fetching_new_onecCs2tddd}|jt|jddddS(Nufooustateu somestateuhttps://i.b/tokenuauthorization_responseuhttps://i.b/no-state?code=abc(u OAuth2Sessionu assertRaisesuMismatchingStateErroru fetch_token(uselfuclient((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_web_app_fetch_tokensu*OAuth2SessionTest.test_web_app_fetch_tokencCsttd}|j|jdd|_|j|jdd|j_|j|jd|`|j|jdS(Nutest-idu different-idusomething-else(u OAuth2Sessionu assertEqualu client_idu_clientu assertIsNone(uselfusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_client_id_proxys   u&OAuth2SessionTest.test_client_id_proxycCsqtd}|j|jd|_|j|jdd|j_|j|jd|`|j|jdS(Nutest-idu test-tokenudifferent-token(u OAuth2Sessionu assertIsNoneu access_tokenu assertEqualu_client(uselfusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_access_token_proxys   u)OAuth2SessionTest.test_access_token_proxycCsidd6}tdd|}|j|jd|j|j|d|d<||_|j|jd|j|j|d|j_d|d<|j|jd|j|j||jt |`WdQXdS(Nu test-accessu access_tokenutest-idutokenusomething-elseudifferent-token(u OAuth2Sessionu assertEqualu access_tokenutokenu_clientu assertRaisesuAttributeError(uselfutokenusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_token_proxys     u"OAuth2SessionTest.test_token_proxycCs td}|j|jdS(Nufoo(u OAuth2Sessionu assertFalseu authorized(uselfusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_authorized_falses u'OAuth2SessionTest.test_authorized_falsecCstS(N(u fake_time(((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyuscCsxdd}d}x_|jD]T}td|}||j|_|j|j|j||j|jqWdS(Ncsfdd}|S(Ncs"tj}tj|_|S(N(umocku MagicMockujsonudumpsutext(urukwargsuresp(utoken(uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu fake_sends uMOAuth2SessionTest.test_authorized_true..fake_token..fake_send((utokenu fake_send((utokenuX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyu fake_tokensu:OAuth2SessionTest.test_authorized_true..fake_tokenuhttps://example.com/tokenuclient(uclientsu OAuth2Sessionutokenusendu assertFalseu authorizedu fetch_tokenu assertTrue(uselfu fake_tokenuurluclientusess((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyutest_authorized_trues  u&OAuth2SessionTest.test_authorized_trueN(u__name__u __module__u __qualname__usetUputest_add_tokenutest_authorization_urlumockupatchutest_refresh_token_requestutest_token_from_fragmentutest_fetch_tokenu2test_cleans_previous_token_before_fetching_new_oneutest_web_app_fetch_tokenutest_client_id_proxyutest_access_token_proxyutest_token_proxyutest_authorized_falseutest_authorized_true(u __locals__((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyuOAuth2SessionTest s   '5''    uOAuth2SessionTest(u __future__uunicode_literalsujsonumockutimeubase64u b64encodeucopyudeepcopyu unittest2uTestCaseu ImportErroruunittestuoauthlib.commonu urlencodeuoauthlib.oauth2uTokenExpiredErroru OAuth2ErroruMismatchingStateErroruWebApplicationClientuMobileApplicationClientuLegacyApplicationClientuBackendApplicationClienturequests_oauthlibu OAuth2Sessionu TokenUpdatedu fake_timeu fake_tokenuOAuth2SessionTest(((uX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyus$      requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_session.cpython-34.pyc0000644000076500000240000002345112770742404027314 0ustar corystaff00000000000000 WJ% @s7ddlmZddlZddlZddlZddlmZddlmZyddl m Z Wn"e k rddl m Z YnXddl mZddlmZmZddlmZdd lmZmZdd lmZmZdd lmZmZejZd d ZGddde ZdS))unicode_literalsN) b64encode)deepcopy)TestCase) urlencode)TokenExpiredError OAuth2Error)MismatchingStateError)WebApplicationClientMobileApplicationClient)LegacyApplicationClientBackendApplicationClient) OAuth2Session TokenUpdatedcsfdd}|S)Ncs"tj}tj|_|S)N)mock MagicMockjsondumpstext)rkwargsresp)tokenX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.py fake_sends zfake_token..fake_sendr)rrr)rr fake_tokensrc@seZdZddZddZddZejddd d d d Zejddd d ddZ ejdddd ddZ ddZ ddZ ddZ ddZddZddZejdddd d d!Zd"S)#OAuth2SessionTestcstds'fdd_nidd6dd6dd 6d d 6td d 6_d_tjddtjtjg_jt jg_ dS)NassertIncsj||kS)N) assertTrue)ab)selfrr%sz)OAuth2SessionTest.setUp..Bearer token_typeasdfoiw37850234lkjsdfsdf access_tokenZsldvafkjw34509s8dfsdf refresh_token3600 expires_ini expires_atfoocodeZ asdf345xdf) hasattrr fake_timer client_idr r r clientsr all_clients)r"r)r"rsetUp"s  zOAuth2SessionTest.setUpcsldjdfdd}x?jD]4}td|dj}||_|jdq0WdS)NzBearer r'cso|jjdd}djd|jkrF|jdjd}nj|tj}g|_|S)N Authorizationzutf-8)headersgetencode assertEqualrrZcookes)rr auth_headerr)r"rrrverifier9s  z2OAuth2SessionTest.test_add_token..verifierclientrz https://i.b)rr2rsendr6)r"r:r;authr)r"rrtest_add_token6s   z OAuth2SessionTest.test_add_tokencCsd}t|j}td|}|j|\}}|j|||j|j||jd|t|j}td|}|j|\}}|j|||j|j||jd|dS)Nz%https://example.com/authorize?foo=barr;zresponse_type=codezresponse_type=token)r r0rauthorization_urlrr )r"urlZwebsauth_urlstatemobilerrrtest_authorization_urlGsz(OAuth2SessionTest.test_authorization_urlz time.timenewcCstS)N)r/rrrrr#XszOAuth2SessionTest.c stj_djd<jd=fdd}x?jD]4}td|dj}jt|jdqEWxNjD]C}td|djd d }||_jt |jdqWfd d }xKjD]@}td|djd d d |}||_|jdqWfdd}xWjD]L}td|djd d d |}||_|jdddddqJWdS)Nz-1r*r+csJd|jkr%jd|jntj}tjj|_|S)Nz/refreshr4) r@ assertNotInr5rrrrrr)rrr)r"rr fake_refresh^s  zBOAuth2SessionTest.test_refresh_token_request..fake_refreshr;rz https://i.bauto_refresh_urlzhttps://i.b/refreshcsj|jdS)N)r8r)r)r"rr token_updaterrszCOAuth2SessionTest.test_refresh_token_request..token_updaterrJcsd|jkr[jd|jtd}d|jd}j|jd|ntj}tj j |_ |S)Nz/refreshr4sfoo:barsBasic latin1) r@rr5rdecoder8rrrrrr)rrencodedcontentr)r"rrfake_refresh_with_auth|s  zLOAuth2SessionTest.test_refresh_token_request..fake_refresh_with_authr0r, client_secretbar) dictrZ expired_tokenr1r assertRaisesrr6r<r)r"rHr;r=rJrOr)r"rtest_refresh_token_requestXs4         z,OAuth2SessionTest.test_refresh_token_requestcCstS)N)r/rrrrr#scCsWt|j}dt|jj}td|}|j|j||jdS)Nzhttps://i.b/callback#r;)r r0rritemsrr8token_from_fragment)r"rDZ response_urlr=rrrtest_token_from_fragmentsz*OAuth2SessionTest.test_token_from_fragmentcCstS)N)r/rrrrr#scCsd}xW|jD]L}td|d|j}t|j|_|j|j||jqWidd6}xN|jD]C}td|d|j}t||_|jt|j|qwWdS)Nzhttps://example.com/tokenr;rinvalid_requesterror) r1rrrr<r8 fetch_tokenrSr)r"r@r;r=rYrrrtest_fetch_tokens  z"OAuth2SessionTest.test_fetch_tokenc st|j}tjd}tj||jd<d|d.r;rN) rrtimerpatchr1rrr<r8rZ)r"Z new_tokenZpastr@r;r=r)r\r2test_cleans_previous_token_before_fetching_new_ones  zDOAuth2SessionTest.test_cleans_previous_token_before_fetching_new_onecCs2tddd}|jt|jddddS)Nr,rCZ somestatezhttps://i.b/tokenauthorization_responsezhttps://i.b/no-state?code=abc)rrSr rZ)r"r;rrrtest_web_app_fetch_tokensz*OAuth2SessionTest.test_web_app_fetch_tokencCsttd}|j|jdd|_|j|jdd|j_|j|jd|`|j|jdS)Nztest-idz different-idzsomething-else)rr8r0_client assertIsNone)r"sessrrrtest_client_id_proxys   z&OAuth2SessionTest.test_client_id_proxycCsqtd}|j|jd|_|j|jdd|j_|j|jd|`|j|jdS)Nztest-idz test-tokenzdifferent-token)rrcr'r8rb)r"rdrrrtest_access_token_proxys   z)OAuth2SessionTest.test_access_token_proxycCsidd6}tdd|}|j|jd|j|j|d|d<||_|j|jd|j|j|d|j_d|d<|j|jd|j|j||jt |`WdQXdS)Nz test-accessr'ztest-idrzsomething-elsezdifferent-token)rr8r'rrbrSAttributeError)r"rrdrrrtest_token_proxys     z"OAuth2SessionTest.test_token_proxycCs td}|j|jdS)Nr,)r assertFalse authorized)r"rdrrrtest_authorized_falses z'OAuth2SessionTest.test_authorized_falsecCstS)N)r/rrrrr#scCsxdd}d}x_|jD]T}td|}||j|_|j|j|j||j|jqWdS)Ncsfdd}|S)Ncs"tj}tj|_|S)N)rrrrr)rrr)rrrrs zMOAuth2SessionTest.test_authorized_true..fake_token..fake_sendr)rrr)rrrsz:OAuth2SessionTest.test_authorized_true..fake_tokenzhttps://example.com/tokenr;)r1rrr<rirjrZr)r"rr@r;rdrrrtest_authorized_trues  z&OAuth2SessionTest.test_authorized_trueN)__name__ __module__ __qualname__r3r>rErr^rTrWr[r_rarerfrhrkrlrrrrr s    '5''    r) __future__rrrr]base64rcopyr unittest2r ImportErrorunittestoauthlib.commonroauthlib.oauth2rrr r r r r requests_oauthlibrrr/rrrrrrs$      requests-oauthlib-0.8.0/tests/__pycache__/test_oauth2_session.cpython-35.pyc0000644000076500000240000002342412770742411027313 0ustar corystaff00000000000000 WJ% @s7ddlmZddlZddlZddlZddlmZddlmZyddl m Z Wn"e k rddl m Z YnXddl mZddlmZmZddlmZdd lmZmZdd lmZmZdd lmZmZejZd d ZGddde ZdS))unicode_literalsN) b64encode)deepcopy)TestCase) urlencode)TokenExpiredError OAuth2Error)MismatchingStateError)WebApplicationClientMobileApplicationClient)LegacyApplicationClientBackendApplicationClient) OAuth2Session TokenUpdatedcsfdd}|S)Ncs"tj}tj|_|S)N)mock MagicMockjsondumpstext)rkwargsresp)tokenX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.py fake_sends zfake_token..fake_sendr)rrr)rr fake_tokensrc@seZdZddZddZddZejddd d d d Zejddd d ddZ ejdddd ddZ ddZ ddZ ddZ ddZddZddZejdddd d d!Zd"S)#OAuth2SessionTestc stds$fdd_dddddd d d d td i_d_tjddtjtjg_jt jg_ dS)NassertIncsj||kS)N) assertTrue)ab)selfrr%sz)OAuth2SessionTest.setUp.. token_typeBearer access_tokenasdfoiw37850234lkjsdfsdf refresh_tokenZsldvafkjw34509s8dfsdf expires_in3600 expires_atifoocodeZ asdf345xdf) hasattrr fake_timer client_idr r r clientsr all_clients)r"r)r"rsetUp"s  zOAuth2SessionTest.setUpcsldjdfdd}x?jD]4}td|dj}||_|jdq0WdS)NzBearer r&csl|jjdd}djd|jkrC|jdjd}j|tj}g|_|S)N Authorizationzutf-8)headersgetencode assertEqualrrZcookes)rr auth_headerr)r"rrrverifier9s  z2OAuth2SessionTest.test_add_token..verifierclientrz https://i.b)rr2rsendr6)r"r:r;authr)r"rrtest_add_token6s   z OAuth2SessionTest.test_add_tokencCsd}t|j}td|}|j|\}}|j|||j|j||jd|t|j}td|}|j|\}}|j|||j|j||jd|dS)Nz%https://example.com/authorize?foo=barr;zresponse_type=codezresponse_type=token)r r0rauthorization_urlrr )r"urlZwebsauth_urlstatemobilerrrtest_authorization_urlGsz(OAuth2SessionTest.test_authorization_urlz time.timenewcCstS)N)r/rrrrr#XszOAuth2SessionTest.c stj_djd<jd=fdd}x?jD]4}td|dj}jt|jdqEWxNjD]C}td|djd d }||_jt |jdqWfd d }xKjD]@}td|djd d d |}||_|jdqWfdd}xWjD]L}td|djd d d |}||_|jdddddqJWdS)Nz-1r)r+csGd|jkr"jd|jtj}tjj|_|S)Nz/refreshr4) r@ assertNotInr5rrrrrr)rrr)r"rr fake_refresh^s  zBOAuth2SessionTest.test_refresh_token_request..fake_refreshr;rz https://i.bauto_refresh_urlzhttps://i.b/refreshcsj|jdS)N)r8r)r)r"rr token_updaterrszCOAuth2SessionTest.test_refresh_token_request..token_updaterrJcs}d|jkrXjd|jtd}d|jd}j|jd|tj}tj j |_ |S)Nz/refreshr4sfoo:barsBasic latin1) r@rr5rdecoder8rrrrrr)rrencodedcontentr)r"rrfake_refresh_with_auth|s  zLOAuth2SessionTest.test_refresh_token_request..fake_refresh_with_authr0r, client_secretbar) dictrZ expired_tokenr1r assertRaisesrr6r<r)r"rHr;r=rJrOr)r"rtest_refresh_token_requestXs4         z,OAuth2SessionTest.test_refresh_token_requestcCstS)N)r/rrrrr#scCsWt|j}dt|jj}td|}|j|j||jdS)Nzhttps://i.b/callback#r;)r r0rritemsrr8token_from_fragment)r"rDZ response_urlr=rrrtest_token_from_fragmentsz*OAuth2SessionTest.test_token_from_fragmentcCstS)N)r/rrrrr#scCsd}xW|jD]L}td|d|j}t|j|_|j|j||jqWddi}xN|jD]C}td|d|j}t||_|jt|j|qvWdS)Nzhttps://example.com/tokenr;rerrorinvalid_request) r1rrrr<r8 fetch_tokenrSr)r"r@r;r=rXrrrtest_fetch_tokens  z"OAuth2SessionTest.test_fetch_tokenc st|j}tjd}tj||jd<d|d.r;rN) rrtimerpatchr1rrr<r8rZ)r"Z new_tokenZpastr@r;r=r)r\r2test_cleans_previous_token_before_fetching_new_ones  zDOAuth2SessionTest.test_cleans_previous_token_before_fetching_new_onecCs2tddd}|jt|jddddS)Nr,rCZ somestatezhttps://i.b/tokenauthorization_responsezhttps://i.b/no-state?code=abc)rrSr rZ)r"r;rrrtest_web_app_fetch_tokensz*OAuth2SessionTest.test_web_app_fetch_tokencCsttd}|j|jdd|_|j|jdd|j_|j|jd|`|j|jdS)Nztest-idz different-idzsomething-else)rr8r0_client assertIsNone)r"sessrrrtest_client_id_proxys   z&OAuth2SessionTest.test_client_id_proxycCsqtd}|j|jd|_|j|jdd|j_|j|jd|`|j|jdS)Nztest-idz test-tokenzdifferent-token)rrcr&r8rb)r"rdrrrtest_access_token_proxys   z)OAuth2SessionTest.test_access_token_proxyc Csddi}tdd|}|j|jd|j|j|d|d<||_|j|jd|j|j|d|j_d|d<|j|jd|j|j||jt |`WdQRXdS)Nr&z test-accessztest-idrzsomething-elsezdifferent-token)rr8r&rrbrSAttributeError)r"rrdrrrtest_token_proxys     z"OAuth2SessionTest.test_token_proxycCs td}|j|jdS)Nr,)r assertFalse authorized)r"rdrrrtest_authorized_falses z'OAuth2SessionTest.test_authorized_falsecCstS)N)r/rrrrr#scCsxdd}d}x_|jD]T}td|}||j|_|j|j|j||j|jqWdS)Ncsfdd}|S)Ncs"tj}tj|_|S)N)rrrrr)rrr)rrrrs zMOAuth2SessionTest.test_authorized_true..fake_token..fake_sendr)rrr)rrrsz:OAuth2SessionTest.test_authorized_true..fake_tokenzhttps://example.com/tokenr;)r1rrr<rirjrZr)r"rr@r;rdrrrtest_authorized_trues  z&OAuth2SessionTest.test_authorized_trueN)__name__ __module__ __qualname__r3r>rErr^rTrWr[r_rarerfrhrkrlrrrrr s    '5''    r) __future__rrrr]base64rcopyr unittest2r ImportErrorunittestoauthlib.commonroauthlib.oauth2rrr r r r r requests_oauthlibrrr/rrrrrrs$      requests-oauthlib-0.8.0/tests/test.bin0000644000076500000240000000000212201441447020100 0ustar corystaff00000000000000requests-oauthlib-0.8.0/tests/test_compliance_fixes.py0000644000076500000240000002252013050616611023361 0ustar corystaff00000000000000from __future__ import unicode_literals try: from unittest2 import TestCase except ImportError: from unittest import TestCase import requests import requests_mock import time try: from urlparse import urlparse, parse_qs except ImportError: from urllib.parse import urlparse, parse_qs from oauthlib.oauth2.rfc6749.errors import InvalidGrantError from requests_oauthlib import OAuth2Session from requests_oauthlib.compliance_fixes import facebook_compliance_fix from requests_oauthlib.compliance_fixes import fitbit_compliance_fix from requests_oauthlib.compliance_fixes import linkedin_compliance_fix from requests_oauthlib.compliance_fixes import mailchimp_compliance_fix from requests_oauthlib.compliance_fixes import weibo_compliance_fix from requests_oauthlib.compliance_fixes import slack_compliance_fix class FacebookComplianceFixTest(TestCase): def setUp(self): mocker = requests_mock.Mocker() mocker.post( "https://graph.facebook.com/oauth/access_token", text="access_token=urlencoded", headers={"Content-Type": "text/plain"}, ) mocker.start() self.addCleanup(mocker.stop) facebook = OAuth2Session('foo', redirect_uri='https://i.b') self.session = facebook_compliance_fix(facebook) def test_fetch_access_token(self): token = self.session.fetch_token( 'https://graph.facebook.com/oauth/access_token', client_secret='bar', authorization_response='https://i.b/?code=hello', ) self.assertEqual(token, {'access_token': 'urlencoded', 'token_type': 'Bearer'}) class FitbitComplianceFixTest(TestCase): def setUp(self): self.mocker = requests_mock.Mocker() self.mocker.post( "https://api.fitbit.com/oauth2/token", json={"errors": [{"errorType": "invalid_grant"}]}, ) self.mocker.start() self.addCleanup(self.mocker.stop) fitbit = OAuth2Session('foo', redirect_uri='https://i.b') self.session = fitbit_compliance_fix(fitbit) def test_fetch_access_token(self): self.assertRaises( InvalidGrantError, self.session.fetch_token, 'https://api.fitbit.com/oauth2/token', client_secret='bar', authorization_response='https://i.b/?code=hello', ) self.mocker.post( "https://api.fitbit.com/oauth2/token", json={"access_token": "fitbit"}, ) token = self.session.fetch_token( 'https://api.fitbit.com/oauth2/token', client_secret='good' ) self.assertEqual(token, {'access_token': 'fitbit'}) def test_refresh_token(self): self.assertRaises( InvalidGrantError, self.session.refresh_token, 'https://api.fitbit.com/oauth2/token', auth=requests.auth.HTTPBasicAuth('foo', 'bar') ) self.mocker.post( "https://api.fitbit.com/oauth2/token", json={"access_token": "access", "refresh_token": "refresh"}, ) token = self.session.refresh_token( 'https://api.fitbit.com/oauth2/token', auth=requests.auth.HTTPBasicAuth('foo', 'bar') ) self.assertEqual(token['access_token'], 'access') self.assertEqual(token['refresh_token'], 'refresh') class LinkedInComplianceFixTest(TestCase): def setUp(self): mocker = requests_mock.Mocker() mocker.post( "https://www.linkedin.com/uas/oauth2/accessToken", json={"access_token": "linkedin"}, ) mocker.post( "https://api.linkedin.com/v1/people/~/shares", status_code=201, json={ "updateKey": "UPDATE-3346389-595113200", "updateUrl": "https://www.linkedin.com/updates?discuss=abc&scope=xyz" } ) mocker.start() self.addCleanup(mocker.stop) linkedin = OAuth2Session('foo', redirect_uri='https://i.b') self.session = linkedin_compliance_fix(linkedin) def test_fetch_access_token(self): token = self.session.fetch_token( 'https://www.linkedin.com/uas/oauth2/accessToken', client_secret='bar', authorization_response='https://i.b/?code=hello', ) self.assertEqual(token, {'access_token': 'linkedin', 'token_type': 'Bearer'}) def test_protected_request(self): self.session.token = {"access_token": 'dummy-access-token'} response = self.session.post( "https://api.linkedin.com/v1/people/~/shares" ) url = response.request.url query = parse_qs(urlparse(url).query) self.assertEqual(query["oauth2_access_token"], ["dummy-access-token"]) class MailChimpComplianceFixTest(TestCase): def setUp(self): mocker = requests_mock.Mocker() mocker.post( "https://login.mailchimp.com/oauth2/token", json={"access_token": "mailchimp", "expires_in": 0, "scope": None}, ) mocker.start() self.addCleanup(mocker.stop) mailchimp = OAuth2Session('foo', redirect_uri='https://i.b') self.session = mailchimp_compliance_fix(mailchimp) def test_fetch_access_token(self): token = self.session.fetch_token( "https://login.mailchimp.com/oauth2/token", client_secret='bar', authorization_response='https://i.b/?code=hello', ) # Times should be close approx_expires_at = time.time() + 3600 actual_expires_at = token.pop('expires_at') self.assertAlmostEqual(actual_expires_at, approx_expires_at, places=2) # Other token values exact self.assertEqual(token, {'access_token': 'mailchimp', 'expires_in': 3600}) # And no scope at all self.assertNotIn('scope', token) class WeiboComplianceFixTest(TestCase): def setUp(self): mocker = requests_mock.Mocker() mocker.post( "https://api.weibo.com/oauth2/access_token", json={"access_token": "weibo"}, ) mocker.start() self.addCleanup(mocker.stop) weibo = OAuth2Session('foo', redirect_uri='https://i.b') self.session = weibo_compliance_fix(weibo) def test_fetch_access_token(self): token = self.session.fetch_token( 'https://api.weibo.com/oauth2/access_token', client_secret='bar', authorization_response='https://i.b/?code=hello', ) self.assertEqual(token, {'access_token': 'weibo', 'token_type': 'Bearer'}) class SlackComplianceFixTest(TestCase): def setUp(self): mocker = requests_mock.Mocker() mocker.post( "https://slack.com/api/oauth.access", json={ "access_token": "xoxt-23984754863-2348975623103", "scope": "read", }, ) for method in ("GET", "POST"): mocker.request( method=method, url="https://slack.com/api/auth.test", json={ "ok": True, "url": "https://myteam.slack.com/", "team": "My Team", "user": "cal", "team_id": "T12345", "user_id": "U12345", } ) mocker.start() self.addCleanup(mocker.stop) slack = OAuth2Session('foo', redirect_uri='https://i.b') self.session = slack_compliance_fix(slack) def test_protected_request(self): self.session.token = {"access_token": 'dummy-access-token'} response = self.session.get( "https://slack.com/api/auth.test" ) url = response.request.url query = parse_qs(urlparse(url).query) self.assertNotIn("token", query) body = response.request.body data = parse_qs(body) self.assertEqual(data["token"], ["dummy-access-token"]) def test_protected_request_override_token_get(self): self.session.token = {"access_token": 'dummy-access-token'} response = self.session.get( "https://slack.com/api/auth.test", data={"token": "different-token"}, ) url = response.request.url query = parse_qs(urlparse(url).query) self.assertNotIn("token", query) body = response.request.body data = parse_qs(body) self.assertEqual(data["token"], ["different-token"]) def test_protected_request_override_token_post(self): self.session.token = {"access_token": 'dummy-access-token'} response = self.session.post( "https://slack.com/api/auth.test", data={"token": "different-token"}, ) url = response.request.url query = parse_qs(urlparse(url).query) self.assertNotIn("token", query) body = response.request.body data = parse_qs(body) self.assertEqual(data["token"], ["different-token"]) def test_protected_request_override_token_url(self): self.session.token = {"access_token": 'dummy-access-token'} response = self.session.get( "https://slack.com/api/auth.test?token=different-token", ) url = response.request.url query = parse_qs(urlparse(url).query) self.assertEqual(query["token"], ["different-token"]) self.assertIsNone(response.request.body) requests-oauthlib-0.8.0/tests/test_compliance_fixes.pyc0000644000076500000240000002012412770743363023537 0ustar corystaff00000000000000 r;VcsddlmZyddlmZWn!ek rGddlmZnXddlZddlZddlZyddl m Z m Z Wn'ek rddl m Z m Z nXddl m Z ddlmZddlmZddlmZdd lmZdd lmZd efd YZd efdYZdefdYZdefdYZdefdYZdS(i(tunicode_literals(tTestCaseN(turlparsetparse_qs(t OAuth2Session(tfacebook_compliance_fix(tlinkedin_compliance_fix(tmailchimp_compliance_fix(tweibo_compliance_fix(tslack_compliance_fixtFacebookComplianceFixTestcseZdZdZRS(c Cskt}|ddddidd6|||jtddd }t||_dS( Nu-https://graph.facebook.com/oauth/access_tokenttextuaccess_token=urlencodedtheadersu text/plainu Content-Typeufoot redirect_uriu https://i.b( t requests_mocktMockertposttstartt addCleanuptstopRRtsession(tselftmockertfacebook((tZ/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_compliance_fixes.pytsetUps  cCs@|jddddd}||idd6dd 6dS( Nu-https://graph.facebook.com/oauth/access_tokent client_secretubartauthorization_responseuhttps://i.b/?code=hellou urlencodedu access_tokenuBeareru token_type(Rt fetch_tokent assertEqual(Rttoken((Rttest_fetch_access_token&s   (t__name__t __module__RR(((RR s tLinkedInComplianceFixTestcs#eZdZdZdZRS(c Cst}|ddidd6|ddddidd 6d d 6|||jtd d d}t||_dS(Nu/https://www.linkedin.com/uas/oauth2/accessTokentjsonulinkedinu access_tokenu+https://api.linkedin.com/v1/people/~/sharest status_codeiuUPDATE-3346389-595113200u updateKeyu6https://www.linkedin.com/updates?discuss=abc&scope=xyzu updateUrlufooR u https://i.b( RRRRRRRRR(RRtlinkedin((RR1s   cCs@|jddddd}||idd6dd 6dS( Nu/https://www.linkedin.com/uas/oauth2/accessTokenRubarRuhttps://i.b/?code=helloulinkedinu access_tokenuBeareru token_type(RRR(RR((RREs   cCsaidd6|j_|jd}|jj}tt|j}||ddgdS(Nudummy-access-tokenu access_tokenu+https://api.linkedin.com/v1/people/~/sharesuoauth2_access_token( RRRtrequestturlRRtqueryR(RtresponseR'R(((Rttest_protected_requestMs    (R R!RRR*(((RR"/s  tMailChimpComplianceFixTestcseZdZdZRS(cCsst}|ddidd6dd6dd6|||jtdd d }t||_dS( Nu(https://login.mailchimp.com/oauth2/tokenR#u mailchimpu access_tokeniu expires_inuscopeufooR u https://i.b( RRRRRRRRR(RRt mailchimp((RRYs  cCs|jddddd}td}|d}|||dd ||id d 6dd 6|d |dS(Nu(https://login.mailchimp.com/oauth2/tokenRubarRuhttps://i.b/?code=helloiu expires_attplacesiu mailchimpu access_tokenu expires_inuscope(RRttimetpoptassertAlmostEqualRt assertNotIn(RRtapprox_expires_attactual_expires_at((RRes  (R R!RR(((RR+Ws tWeiboComplianceFixTestcseZdZdZRS(cCset}|ddidd6|||jtddd}t||_dS(Nu)https://api.weibo.com/oauth2/access_tokenR#uweibou access_tokenufooR u https://i.b( RRRRRRRRR(RRtweibo((RRys  cCs@|jddddd}||idd6dd 6dS( Nu)https://api.weibo.com/oauth2/access_tokenRubarRuhttps://i.b/?code=hellouweibou access_tokenuBeareru token_type(RRR(RR((RRs   (R R!RR(((RR4ws tSlackComplianceFixTestcs5eZdZdZdZdZdZRS(c Cst}|ddidd6dd6xTdD]L}|d|d d ditd 6d d 6dd6dd6dd6dd6q4W|||jtddd}t ||_ dS(Nu"https://slack.com/api/oauth.accessR#uxoxt-23984754863-2348975623103u access_tokenureaduscope(uGETuPOSTtmethodR'uhttps://slack.com/api/auth.testuokuhttps://myteam.slack.com/uurluMy TeamuteamucaluuseruT12345uteam_iduU12345uuser_idufooR u https://i.b( RRRR&tTrueRRRRR R(RRR7tslack((RRs,    cCsidd6|j_|jd}|jj}tt|j}|d||jj }t|}| |ddgdS(Nudummy-access-tokenu access_tokenuhttps://slack.com/api/auth.testutoken( RRtgetR&R'RRR(R1tbodyR(RR)R'R(R;tdata((RR*s     cCsidd6|j_|jddidd6}|jj}tt|j}|d||jj }t|}| |ddgdS(Nudummy-access-tokenu access_tokenuhttps://slack.com/api/auth.testR<udifferent-tokenutoken( RRR:R&R'RRR(R1R;R(RR)R'R(R;R<((Rt)test_protected_request_override_token_gets    cCsidd6|j_|jddidd6}|jj}tt|j}|d||jj }t|}| |ddgdS(Nudummy-access-tokenu access_tokenuhttps://slack.com/api/auth.testR<udifferent-tokenutoken( RRRR&R'RRR(R1R;R(RR)R'R(R;R<((Rt*test_protected_request_override_token_posts    cCstidd6|j_|jd}|jj}tt|j}||ddg| |jj dS(Nudummy-access-tokenu access_tokenu5https://slack.com/api/auth.test?token=different-tokenutokenudifferent-token( RRR:R&R'RRR(Rt assertIsNoneR;(RR)R'R(((Rt)test_protected_request_override_token_urls   (R R!RR*R=R>R@(((RR6s   (t __future__Rt unittest2Rt ImportErrortunittesttrequestsRR.RRt urllib.parsetrequests_oauthlibRt"requests_oauthlib.compliance_fixesRRRRR R R"R+R4R6(((Rts,     ( requests-oauthlib-0.8.0/tests/test_core.py0000644000076500000240000001415412344337640021014 0ustar corystaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import mock import sys import requests import requests_oauthlib import oauthlib import os.path try: from io import StringIO # python 3 except ImportError: from StringIO import StringIO # python 2 import unittest if sys.version[0] == '3': bytes_type = bytes else: bytes_type = str @mock.patch('oauthlib.oauth1.rfc5849.generate_timestamp') @mock.patch('oauthlib.oauth1.rfc5849.generate_nonce') class OAuth1Test(unittest.TestCase): def setUp(self): def converting_equals(a, b): if isinstance(a, bytes_type): a = a.decode('utf-8') if isinstance(b, bytes_type): b = b.decode('utf-8') self.assertEquals(a, b) self.assertEqual = converting_equals def testFormEncoded(self, generate_nonce, generate_timestamp): """OAuth1 assumes form encoded if content type is not specified.""" generate_nonce.return_value = 'abc' generate_timestamp.return_value = '1' oauth = requests_oauthlib.OAuth1('client_key') headers = {'Content-type': 'application/x-www-form-urlencoded'} r = requests.Request(method='POST', url='http://a.b/path?query=retain', auth=oauth, data='this=really&is=&+form=encoded', headers=headers) a = r.prepare() self.assertEqual(a.url, 'http://a.b/path?query=retain') self.assertEqual(a.body, 'this=really&is=&+form=encoded') self.assertEqual(a.headers.get('Content-Type'), 'application/x-www-form-urlencoded') # guess content-type r = requests.Request(method='POST', url='http://a.b/path?query=retain', auth=oauth, data='this=really&is=&+form=encoded') b = r.prepare() self.assertEqual(b.url, 'http://a.b/path?query=retain') self.assertEqual(b.body, 'this=really&is=&+form=encoded') self.assertEqual(b.headers.get('Content-Type'), 'application/x-www-form-urlencoded') self.assertEqual(a.headers.get('Authorization'), b.headers.get('Authorization')) def testNonFormEncoded(self, generate_nonce, generate_timestamp): """OAuth signature only depend on body if it is form encoded.""" generate_nonce.return_value = 'abc' generate_timestamp.return_value = '1' oauth = requests_oauthlib.OAuth1('client_key') r = requests.Request(method='POST', url='http://a.b/path?query=retain', auth=oauth, data='this really is not form encoded') a = r.prepare() r = requests.Request(method='POST', url='http://a.b/path?query=retain', auth=oauth) b = r.prepare() self.assertEqual(a.headers.get('Authorization'), b.headers.get('Authorization')) r = requests.Request(method='POST', url='http://a.b/path?query=retain', auth=oauth, files={'test': StringIO('hello')}) c = r.prepare() self.assertEqual(b.headers.get('Authorization'), c.headers.get('Authorization')) def testCanPostBinaryData(self, generate_nonce, generate_timestamp): """ Test we can post binary data. Should prevent regression of the UnicodeDecodeError issue. """ generate_nonce.return_value = 'abc' generate_timestamp.return_value = '1' oauth = requests_oauthlib.OAuth1('client_key') dirname = os.path.dirname(__file__) fname = os.path.join(dirname, 'test.bin') with open(fname, 'rb') as f: r = requests.post('http://httpbin.org/post', data={'hi': 'there'}, files={'media': (os.path.basename(f.name), f)}, headers={'content-type':'application/octet-stream'}, auth=oauth) self.assertEqual(r.status_code, 200) def test_url_is_native_str(self, generate_nonce, generate_timestamp): """ Test that the URL is always a native string. """ generate_nonce.return_value = 'abc' generate_timestamp.return_value = '1' oauth = requests_oauthlib.OAuth1('client_key') r = requests.get('http://httpbin.org/get', auth=oauth) self.assertTrue(isinstance(r.request.url, str)) def test_content_type_override(self, generate_nonce, generate_timestamp): """ Content type should only be guessed if none is given. """ generate_nonce.return_value = 'abc' generate_timestamp.return_value = '1' oauth = requests_oauthlib.OAuth1('client_key') data = 'a' r = requests.post('http://httpbin.org/get', data=data, auth=oauth) self.assertEqual(r.request.headers.get('Content-Type'), 'application/x-www-form-urlencoded') r = requests.post('http://httpbin.org/get', auth=oauth, data=data, headers={'Content-type': 'application/json'}) self.assertEqual(r.request.headers.get('Content-Type'), 'application/json') def test_register_client_class(self, generate_timestamp, generate_nonce): class ClientSubclass(oauthlib.oauth1.Client): pass self.assertTrue(hasattr(requests_oauthlib.OAuth1, 'client_class')) self.assertEqual( requests_oauthlib.OAuth1.client_class, oauthlib.oauth1.Client) normal = requests_oauthlib.OAuth1('client_key') self.assertTrue(isinstance(normal.client, oauthlib.oauth1.Client)) self.assertFalse(isinstance(normal.client, ClientSubclass)) requests_oauthlib.OAuth1.client_class = ClientSubclass self.assertEqual(requests_oauthlib.OAuth1.client_class, ClientSubclass) custom = requests_oauthlib.OAuth1('client_key') self.assertTrue(isinstance(custom.client, oauthlib.oauth1.Client)) self.assertTrue(isinstance(custom.client, ClientSubclass)) overridden = requests_oauthlib.OAuth1('client_key', client_class = oauthlib.oauth1.Client) self.assertTrue(isinstance(overridden.client, oauthlib.oauth1.Client)) self.assertFalse(isinstance(normal.client, ClientSubclass)) requests-oauthlib-0.8.0/tests/test_core.pyc0000644000076500000240000001301212770743363021155 0ustar corystaff00000000000000 ScsddlmZddlZddlZddlZddlZddlZddlZyddl m Z Wn!e k rddl m Z nXddl Z ej ddkreZneZededde jfd YZdS( i(tunicode_literalsN(tStringIOiu3u*oauthlib.oauth1.rfc5849.generate_timestampu&oauthlib.oauth1.rfc5849.generate_noncet OAuth1TestcsGeZdZdZdZdZdZdZdZRS(csfd}|_dS(NcsVt|tr!|d}nt|trB|d}n||dS(Nuutf-8(t isinstancet bytes_typetdecodet assertEquals(tatb(tself(tN/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_core.pytconverting_equalss (t assertEqual(R R ((R R tsetUpsc CsDd|_d|_td}idd6}tdddd d |d d d |}|}||jd ||jd ||j ddtdddd d |d d }|}||jd ||jd ||j dd||j d|j ddS(u=OAuth1 assumes form encoded if content type is not specified.uabcu1u client_keyu!application/x-www-form-urlencodedu Content-typetmethoduPOSTturluhttp://a.b/path?query=retaintauthtdatauthis=really&is=&+form=encodedtheadersu Content-Typeu AuthorizationN( t return_valuetrequests_oauthlibtOAuth1trequeststRequesttprepareR RtbodyRtget(R tgenerate_noncetgenerate_timestamptoauthRtrRR((R ttestFormEncoded#s$     c Cs d|_d|_td}tddddd|d d }|}tddddd|}|}||jd |jd tddddd|d it d d6}|}||jd |jd dS(u:OAuth signature only depend on body if it is form encoded.uabcu1u client_keyRuPOSTRuhttp://a.b/path?query=retainRRuthis really is not form encodedu AuthorizationtfilesuhelloutestN( RRRRRRR RRR(R RRRRRRtc((R ttestNonFormEncoded<s       c Csd|_d|_td}tjt}tj|d}t|dk}t ddidd 6d itj |j |fd 6d id d6d|}| |jdWdQXdS(ur Test we can post binary data. Should prevent regression of the UnicodeDecodeError issue. uabcu1u client_keyutest.binurbuhttp://httpbin.org/postRuthereuhiR umediaRuapplication/octet-streamu content-typeRiN(RRRtostpathtdirnamet__file__tjointopenRtposttbasenametnameR t status_code(R RRRR%tfnametfR((R ttestCanPostBinaryDataTs  "  cCsVd|_d|_td}tdd|}|t|jjt dS(u> Test that the URL is always a native string. uabcu1u client_keyuhttp://httpbin.org/getRN( RRRRRt assertTrueRtrequestRtstr(R RRRR((R ttest_url_is_native_strfs   c Csd|_d|_td}d}tdd|d|}||jjdd tdd|d|d id d 6}||jjdd d S(uG Content type should only be guessed if none is given. uabcu1u client_keyuauhttp://httpbin.org/getRRu Content-Typeu!application/x-www-form-urlencodedRuapplication/jsonu Content-typeN( RRRRR)R R1RR(R RRRRR((R ttest_content_type_overrideqs  cCsXdtjjfdY}|ttjd|tjjtjjtd}|t |j tjj| t |j ||tj_|tjj|td}|t |j tjj|t |j |tddtjj}|t |j tjj| t |j |dS(NtClientSubclasscseZRS((t__name__t __module__(((R R5su client_classu client_keyt client_class( toauthlibtoauth1tClientR0thasattrRRR R8Rtclientt assertFalse(R RRR5tnormaltcustomt overridden((R ttest_register_client_classs"    ( R6R7R RR"R/R3R4RB(((R Rs    (t __future__RtmocktsysRRR9tos.pathR#tioRt ImportErrortunittesttversiontbytesRR2tpatchtTestCaseR(((R ts"          requests-oauthlib-0.8.0/tests/test_oauth1_session.py0000644000076500000240000003432312661635765023043 0ustar corystaff00000000000000from __future__ import unicode_literals, print_function import mock import unittest import sys import requests from oauthlib.oauth1 import SIGNATURE_TYPE_QUERY, SIGNATURE_TYPE_BODY from oauthlib.oauth1 import SIGNATURE_RSA, SIGNATURE_PLAINTEXT from requests_oauthlib import OAuth1Session try: from StringIO import StringIO except ImportError: from io import StringIO try: import cryptography except ImportError: cryptography = None if sys.version[0] == '3': unicode_type = str bytes_type = bytes else: unicode_type = unicode bytes_type = str # Monkey patch Python 2.6 unittest if not hasattr(unittest, 'SkipTest'): unittest.SkipTest = RuntimeWarning unittest.TestResult.real_add_error = unittest.TestResult.addError def patched_addError(self, test, exc_info): if exc_info[0] is RuntimeWarning: print(str(exc_info[1]), end=' ', file=sys.stderr) return else: self.real_add_error(test, exc_info) unittest.TestResult.addError = patched_addError TEST_RSA_KEY = ( "-----BEGIN RSA PRIVATE KEY-----\n" "MIIEogIBAAKCAQEApF1JaMSN8TEsh4N4O/5SpEAVLivJyLH+Cgl3OQBPGgJkt8cg\n" "49oasl+5iJS+VdrILxWM9/JCJyURpUuslX4Eb4eUBtQ0x5BaPa8+S2NLdGTaL7nB\n" "OO8o8n0C5FEUU+qlEip79KE8aqOj+OC44VsIquSmOvWIQD26n3fCVlgwoRBD1gzz\n" "sDOeaSyzpKrZR851Kh6rEmF2qjJ8jt6EkxMsRNACmBomzgA4M1TTsisSUO87444p\n" "e35Z4/n5c735o2fZMrGgMwiJNh7rT8SYxtIkxngioiGnwkxGQxQ4NzPAHg+XSY0J\n" "04pNm7KqTkgtxyrqOANJLIjXlR+U9SQ90NjHVQIDAQABAoIBABuBPOKaWcJt3yzC\n" "NGGduoif7KtwSnEaUA+v69KPGa2Zju8uFHPssKD+4dZYRc2qMeunKJLpaGaSjnRh\n" "yHyvvOBJCN1nr3lhz6gY5kzJTfwpUFXCOPJlGy4Q+2Xnp4YvcvYqQ9n5DVovDiZ8\n" "vJOBn16xqpudMPLHIa7D5LJ8SY76HBjE+imTXw1EShdh5TOV9bmPFQqH6JFzowRH\n" "hyH2DPHuyHJj6cl8FyqJw5lVWzG3n6Prvk7bYHsjmGjurN35UsumNAp6VouNyUP1\n" "RAEcUJega49aIs6/FJ0ENJzQjlsAzVbTleHkpez2aIok+wsWJGJ4SVxAjADOWAaZ\n" "uEJPc3UCgYEA1g4ZGrXOuo75p9/MRIepXGpBWxip4V7B9XmO9WzPCv8nMorJntWB\n" "msYV1I01aITxadHatO4Gl2xLniNkDyrEQzJ7w38RQgsVK+CqbnC0K9N77QPbHeC1\n" "YQd9RCNyUohOimKvb7jyv798FBU1GO5QI2eNgfnnfteSVXhD2iOoTOsCgYEAxJJ+\n" "8toxJdnLa0uUsAbql6zeNXGbUBMzu3FomKlyuWuq841jS2kIalaO/TRj5hbnE45j\n" "mCjeLgTVO6Ach3Wfk4zrqajqfFJ0zUg/Wexp49lC3RWiV4icBb85Q6bzeJD9Dn9v\n" "hjpfWVkczf/NeA1fGH/pcgfkT6Dm706GFFttLL8CgYBl/HeXk1H47xAiHO4dJKnb\n" "v0B+X8To/RXamF01r+8BpUoOubOQetdyX7ic+d6deuHu8i6LD/GSCeYJZYFR/KVg\n" "AtiW757QYalnq3ZogkhFrVCZP8IRfTPOFBxp752TlyAcrSI7T9pQ47IBe4094KXM\n" "CJWSfPgAJkOxd0iU0XJpmwKBgGfQxuMTgSlwYRKFlD1zKap5TdID8fbUbVnth0Q5\n" "GbH7vwlp/qrxCdS/aj0n0irOpbOaW9ccnlrHiqY25VpVMLYIkt3DrDOEiNNx+KNR\n" "TItdTwbcSiTYrS4L0/56ydM/H6bsfsXxRjI18hSJqMZiqXqS84OZz2aOn+h7HCzc\n" "LEiZAoGASk20wFvilpRKHq79xxFWiDUPHi0x0pp82dYIEntGQkKUWkbSlhgf3MAi\n" "5NEQTDmXdnB+rVeWIvEi+BXfdnNgdn8eC4zSdtF4sIAhYr5VWZo0WVWDhT7u2ccv\n" "ZBFymiz8lo3gN57wGUCi9pbZqzV1+ZppX6YTNDdDCE0q+KO3Cec=\n" "-----END RSA PRIVATE KEY-----" ) TEST_RSA_OAUTH_SIGNATURE = ( "j8WF8PGjojT82aUDd2EL%2Bz7HCoHInFzWUpiEKMCy%2BJ2cYHWcBS7mXlmFDLgAKV0" "P%2FyX4TrpXODYnJ6dRWdfghqwDpi%2FlQmB2jxCiGMdJoYxh3c5zDf26gEbGdP6D7O" "Ssp5HUnzH6sNkmVjuE%2FxoJcHJdc23H6GhOs7VJ2LWNdbhKWP%2FMMlTrcoQDn8lz" "%2Fb24WsJ6ae1txkUzpFOOlLM8aTdNtGL4OtsubOlRhNqnAFq93FyhXg0KjzUyIZzmMX" "9Vx90jTks5QeBGYcLE0Op2iHb2u%2FO%2BEgdwFchgEwE5LgMUyHUI4F3Wglp28yHOAM" "jPkI%2FkWMvpxtMrU3Z3KN31WQ%3D%3D" ) class OAuth1SessionTest(unittest.TestCase): def setUp(self): # For python 2.6 if not hasattr(self, 'assertIn'): self.assertIn = lambda a, b: self.assertTrue(a in b) def test_signature_types(self): def verify_signature(getter): def fake_send(r, **kwargs): signature = getter(r) if isinstance(signature, bytes_type): signature = signature.decode('utf-8') self.assertIn('oauth_signature', signature) resp = mock.MagicMock(spec=requests.Response) resp.cookies = [] return resp return fake_send header = OAuth1Session('foo') header.send = verify_signature(lambda r: r.headers['Authorization']) header.post('https://i.b') query = OAuth1Session('foo', signature_type=SIGNATURE_TYPE_QUERY) query.send = verify_signature(lambda r: r.url) query.post('https://i.b') body = OAuth1Session('foo', signature_type=SIGNATURE_TYPE_BODY) headers = {'Content-Type': 'application/x-www-form-urlencoded'} body.send = verify_signature(lambda r: r.body) body.post('https://i.b', headers=headers, data='') @mock.patch('oauthlib.oauth1.rfc5849.generate_timestamp') @mock.patch('oauthlib.oauth1.rfc5849.generate_nonce') def test_signature_methods(self, generate_nonce, generate_timestamp): if not cryptography: raise unittest.SkipTest('cryptography module is required') generate_nonce.return_value = 'abc' generate_timestamp.return_value = '123' signature = 'OAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"' auth = OAuth1Session('foo') auth.send = self.verify_signature(signature) auth.post('https://i.b') signature = 'OAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="foo", oauth_signature="%26"' auth = OAuth1Session('foo', signature_method=SIGNATURE_PLAINTEXT) auth.send = self.verify_signature(signature) auth.post('https://i.b') signature = ('OAuth ' 'oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", ' 'oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", ' 'oauth_signature="{sig}"' ).format(sig=TEST_RSA_OAUTH_SIGNATURE) auth = OAuth1Session('foo', signature_method=SIGNATURE_RSA, rsa_key=TEST_RSA_KEY) auth.send = self.verify_signature(signature) auth.post('https://i.b') @mock.patch('oauthlib.oauth1.rfc5849.generate_timestamp') @mock.patch('oauthlib.oauth1.rfc5849.generate_nonce') def test_binary_upload(self, generate_nonce, generate_timestamp): generate_nonce.return_value = 'abc' generate_timestamp.return_value = '123' fake_xml = StringIO('hello world') headers = {'Content-Type': 'application/xml'} signature = 'OAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"' auth = OAuth1Session('foo') auth.send = self.verify_signature(signature) auth.post('https://i.b', headers=headers, files=[('fake', fake_xml)]) @mock.patch('oauthlib.oauth1.rfc5849.generate_timestamp') @mock.patch('oauthlib.oauth1.rfc5849.generate_nonce') def test_nonascii(self, generate_nonce, generate_timestamp): generate_nonce.return_value = 'abc' generate_timestamp.return_value = '123' signature = 'OAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="W0haoue5IZAZoaJiYCtfqwMf8x8%3D"' auth = OAuth1Session('foo') auth.send = self.verify_signature(signature) auth.post('https://i.b?cjk=%E5%95%A6%E5%95%A6') def test_authorization_url(self): auth = OAuth1Session('foo') url = 'https://example.comm/authorize' token = 'asluif023sf' auth_url = auth.authorization_url(url, request_token=token) self.assertEqual(auth_url, url + '?oauth_token=' + token) def test_parse_response_url(self): url = 'https://i.b/callback?oauth_token=foo&oauth_verifier=bar' auth = OAuth1Session('foo') resp = auth.parse_authorization_response(url) self.assertEqual(resp['oauth_token'], 'foo') self.assertEqual(resp['oauth_verifier'], 'bar') for k, v in resp.items(): self.assertTrue(isinstance(k, unicode_type)) self.assertTrue(isinstance(v, unicode_type)) def test_fetch_request_token(self): auth = OAuth1Session('foo') auth.send = self.fake_body('oauth_token=foo') resp = auth.fetch_request_token('https://example.com/token') self.assertEqual(resp['oauth_token'], 'foo') for k, v in resp.items(): self.assertTrue(isinstance(k, unicode_type)) self.assertTrue(isinstance(v, unicode_type)) def test_fetch_request_token_with_optional_arguments(self): auth = OAuth1Session('foo') auth.send = self.fake_body('oauth_token=foo') resp = auth.fetch_request_token('https://example.com/token', verify=False, stream=True) self.assertEqual(resp['oauth_token'], 'foo') for k, v in resp.items(): self.assertTrue(isinstance(k, unicode_type)) self.assertTrue(isinstance(v, unicode_type)) def test_fetch_access_token(self): auth = OAuth1Session('foo', verifier='bar') auth.send = self.fake_body('oauth_token=foo') resp = auth.fetch_access_token('https://example.com/token') self.assertEqual(resp['oauth_token'], 'foo') for k, v in resp.items(): self.assertTrue(isinstance(k, unicode_type)) self.assertTrue(isinstance(v, unicode_type)) def test_fetch_access_token_with_optional_arguments(self): auth = OAuth1Session('foo', verifier='bar') auth.send = self.fake_body('oauth_token=foo') resp = auth.fetch_access_token('https://example.com/token', verify=False, stream=True) self.assertEqual(resp['oauth_token'], 'foo') for k, v in resp.items(): self.assertTrue(isinstance(k, unicode_type)) self.assertTrue(isinstance(v, unicode_type)) def _test_fetch_access_token_raises_error(self, auth): """Assert that an error is being raised whenever there's no verifier passed in to the client. """ auth.send = self.fake_body('oauth_token=foo') # Use a try-except block so that we can assert on the exception message # being raised and also keep the Python2.6 compatibility where # assertRaises is not a context manager. try: auth.fetch_access_token('https://example.com/token') except ValueError as exc: self.assertEqual('No client verifier has been set.', str(exc)) def test_fetch_token_invalid_response(self): auth = OAuth1Session('foo') auth.send = self.fake_body('not valid urlencoded response!') self.assertRaises(ValueError, auth.fetch_request_token, 'https://example.com/token') for code in (400, 401, 403): auth.send = self.fake_body('valid=response', code) # use try/catch rather than self.assertRaises, so we can # assert on the properties of the exception try: auth.fetch_request_token('https://example.com/token') except ValueError as err: self.assertEqual(err.status_code, code) self.assertTrue(isinstance(err.response, requests.Response)) else: # no exception raised self.fail("ValueError not raised") def test_fetch_access_token_missing_verifier(self): self._test_fetch_access_token_raises_error(OAuth1Session('foo')) def test_fetch_access_token_has_verifier_is_none(self): auth = OAuth1Session('foo') del auth._client.client.verifier self._test_fetch_access_token_raises_error(auth) def test_authorized_false(self): sess = OAuth1Session('foo') self.assertFalse(sess.authorized) def test_authorized_false_rsa(self): signature = ('OAuth ' 'oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", ' 'oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", ' 'oauth_signature="{sig}"' ).format(sig=TEST_RSA_OAUTH_SIGNATURE) sess = OAuth1Session('foo', signature_method=SIGNATURE_RSA, rsa_key=TEST_RSA_KEY) sess.send = self.verify_signature(signature) self.assertFalse(sess.authorized) def test_authorized_true(self): sess = OAuth1Session('key', 'secret', verifier='bar') sess.send = self.fake_body('oauth_token=foo&oauth_token_secret=bar') sess.fetch_access_token('https://example.com/token') self.assertTrue(sess.authorized) @mock.patch('oauthlib.oauth1.rfc5849.generate_timestamp') @mock.patch('oauthlib.oauth1.rfc5849.generate_nonce') def test_authorized_true_rsa(self, generate_nonce, generate_timestamp): if not cryptography: raise unittest.SkipTest('cryptography module is required') generate_nonce.return_value = 'abc' generate_timestamp.return_value = '123' signature = ('OAuth ' 'oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", ' 'oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", ' 'oauth_verifier="bar", oauth_signature="{sig}"' ).format(sig=TEST_RSA_OAUTH_SIGNATURE) sess = OAuth1Session('key', 'secret', signature_method=SIGNATURE_RSA, rsa_key=TEST_RSA_KEY, verifier='bar') sess.send = self.fake_body('oauth_token=foo&oauth_token_secret=bar') sess.fetch_access_token('https://example.com/token') self.assertTrue(sess.authorized) def verify_signature(self, signature): def fake_send(r, **kwargs): auth_header = r.headers['Authorization'] if isinstance(auth_header, bytes_type): auth_header = auth_header.decode('utf-8') self.assertEqual(auth_header, signature) resp = mock.MagicMock(spec=requests.Response) resp.cookies = [] return resp return fake_send def fake_body(self, body, status_code=200): def fake_send(r, **kwargs): resp = mock.MagicMock(spec=requests.Response) resp.cookies = [] resp.text = body resp.status_code = status_code return resp return fake_send requests-oauthlib-0.8.0/tests/test_oauth1_session.pyc0000644000076500000240000003404012770743363023175 0ustar corystaff00000000000000 ;Vcs}ddlmZmZddlZddlZddlZddlZddlmZm Z ddlm Z m Z ddl m Z yddlmZWn!ek rddlmZnXyddlZWnek rdZnXejddkreZeZn eZeZeed sTee_ejjej_d Zeej_nd Zd Z d ej!fdYZ"dS(i(tunicode_literalstprint_functionN(tSIGNATURE_TYPE_QUERYtSIGNATURE_TYPE_BODY(t SIGNATURE_RSAtSIGNATURE_PLAINTEXT(t OAuth1Session(tStringIOiu3uSkipTestcCsK|dtkr7tt|ddddtjdS|||dS(Niitendu tfile(tRuntimeWarningtprinttstrtsyststderrtreal_add_error(tselfttesttexc_info((tX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth1_session.pytpatched_addError!s#u-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEApF1JaMSN8TEsh4N4O/5SpEAVLivJyLH+Cgl3OQBPGgJkt8cg 49oasl+5iJS+VdrILxWM9/JCJyURpUuslX4Eb4eUBtQ0x5BaPa8+S2NLdGTaL7nB OO8o8n0C5FEUU+qlEip79KE8aqOj+OC44VsIquSmOvWIQD26n3fCVlgwoRBD1gzz sDOeaSyzpKrZR851Kh6rEmF2qjJ8jt6EkxMsRNACmBomzgA4M1TTsisSUO87444p e35Z4/n5c735o2fZMrGgMwiJNh7rT8SYxtIkxngioiGnwkxGQxQ4NzPAHg+XSY0J 04pNm7KqTkgtxyrqOANJLIjXlR+U9SQ90NjHVQIDAQABAoIBABuBPOKaWcJt3yzC NGGduoif7KtwSnEaUA+v69KPGa2Zju8uFHPssKD+4dZYRc2qMeunKJLpaGaSjnRh yHyvvOBJCN1nr3lhz6gY5kzJTfwpUFXCOPJlGy4Q+2Xnp4YvcvYqQ9n5DVovDiZ8 vJOBn16xqpudMPLHIa7D5LJ8SY76HBjE+imTXw1EShdh5TOV9bmPFQqH6JFzowRH hyH2DPHuyHJj6cl8FyqJw5lVWzG3n6Prvk7bYHsjmGjurN35UsumNAp6VouNyUP1 RAEcUJega49aIs6/FJ0ENJzQjlsAzVbTleHkpez2aIok+wsWJGJ4SVxAjADOWAaZ uEJPc3UCgYEA1g4ZGrXOuo75p9/MRIepXGpBWxip4V7B9XmO9WzPCv8nMorJntWB msYV1I01aITxadHatO4Gl2xLniNkDyrEQzJ7w38RQgsVK+CqbnC0K9N77QPbHeC1 YQd9RCNyUohOimKvb7jyv798FBU1GO5QI2eNgfnnfteSVXhD2iOoTOsCgYEAxJJ+ 8toxJdnLa0uUsAbql6zeNXGbUBMzu3FomKlyuWuq841jS2kIalaO/TRj5hbnE45j mCjeLgTVO6Ach3Wfk4zrqajqfFJ0zUg/Wexp49lC3RWiV4icBb85Q6bzeJD9Dn9v hjpfWVkczf/NeA1fGH/pcgfkT6Dm706GFFttLL8CgYBl/HeXk1H47xAiHO4dJKnb v0B+X8To/RXamF01r+8BpUoOubOQetdyX7ic+d6deuHu8i6LD/GSCeYJZYFR/KVg AtiW757QYalnq3ZogkhFrVCZP8IRfTPOFBxp752TlyAcrSI7T9pQ47IBe4094KXM CJWSfPgAJkOxd0iU0XJpmwKBgGfQxuMTgSlwYRKFlD1zKap5TdID8fbUbVnth0Q5 GbH7vwlp/qrxCdS/aj0n0irOpbOaW9ccnlrHiqY25VpVMLYIkt3DrDOEiNNx+KNR TItdTwbcSiTYrS4L0/56ydM/H6bsfsXxRjI18hSJqMZiqXqS84OZz2aOn+h7HCzc LEiZAoGASk20wFvilpRKHq79xxFWiDUPHi0x0pp82dYIEntGQkKUWkbSlhgf3MAi 5NEQTDmXdnB+rVeWIvEi+BXfdnNgdn8eC4zSdtF4sIAhYr5VWZo0WVWDhT7u2ccv ZBFymiz8lo3gN57wGUCi9pbZqzV1+ZppX6YTNDdDCE0q+KO3Cec= -----END RSA PRIVATE KEY-----upj8WF8PGjojT82aUDd2EL%2Bz7HCoHInFzWUpiEKMCy%2BJ2cYHWcBS7mXlmFDLgAKV0P%2FyX4TrpXODYnJ6dRWdfghqwDpi%2FlQmB2jxCiGMdJoYxh3c5zDf26gEbGdP6D7OSsp5HUnzH6sNkmVjuE%2FxoJcHJdc23H6GhOs7VJ2LWNdbhKWP%2FMMlTrcoQDn8lz%2Fb24WsJ6ae1txkUzpFOOlLM8aTdNtGL4OtsubOlRhNqnAFq93FyhXg0KjzUyIZzmMX9Vx90jTks5QeBGYcLE0Op2iHb2u%2FO%2BEgdwFchgEwE5LgMUyHUI4F3Wglp28yHOAMjPkI%2FkWMvpxtMrU3Z3KN31WQ%3D%3DtOAuth1SessionTestcs@eZdZdZededdZededdZededdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZededdZdZddZRS(cs(tds$fd_ndS(NuassertIncs||kS(N(t assertTrue(tatb(R(RtWs(thasattrtassertIn(R((RRtsetUpTscsfd}td}|d|_|dtddt}|d|_|dtddt}idd6}|d |_|dd |d d dS( Ncsfd}|S(Ncs_|}t|tr-|d}nd|tdtj}g|_|S(Nuutf-8uoauth_signaturetspec( t isinstancet bytes_typetdecodeRtmockt MagicMocktrequeststResponsetcookies(trtkwargst signaturetresp(tgetterR(Rt fake_send[s  ((R*R+(R(R*Rtverify_signatureZsufoocSs |jdS(Nu Authorization(theaders(R&((RRfsu https://i.btsignature_typecSs|jS(N(turl(R&((RRjsu!application/x-www-form-urlencodedu Content-TypecSs|jS(N(tbody(R&((RRosR-tdatau(RtsendtpostRR(RR,theadertqueryR0R-((RRttest_signature_typesYs    u*oauthlib.oauth1.rfc5849.generate_timestampu&oauthlib.oauth1.rfc5849.generate_noncecCststdnd|_d|_d}td}|||_|dd}tddt}|||_|dd d t }tddt d t }|||_|ddS( Nucryptography module is requireduabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"ufoou https://i.buOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="foo", oauth_signature="%26"tsignature_methoduOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"tsigtrsa_key( t cryptographytunittesttSkipTestt return_valueRR,R2R3RtformattTEST_RSA_OAUTH_SIGNATURERt TEST_RSA_KEY(Rtgenerate_noncetgenerate_timestampR(tauth((Rttest_signature_methodsrs$        cCsud|_d|_td}idd6}d}td}|||_|dd |d d |fgdS( Nuabcu123u hello worlduapplication/xmlu Content-TypeuOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="h2sRqLArjhlc5p3FTkuNogVHlKE%3D"ufoou https://i.bR-tfilesufake(R=RRR,R2R3(RRARBtfake_xmlR-R(RC((Rttest_binary_uploads     cCsGd|_d|_d}td}|||_|ddS(Nuabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="W0haoue5IZAZoaJiYCtfqwMf8x8%3D"ufoou"https://i.b?cjk=%E5%95%A6%E5%95%A6(R=RR,R2R3(RRARBR(RC((Rt test_nonasciis    cCsItd}d}d}||d|}|||d|dS(Nufoouhttps://example.comm/authorizeu asluif023sft request_tokenu ?oauth_token=(Rtauthorization_urlt assertEqual(RRCR/ttokentauth_url((Rttest_authorization_urls  cCsd}td}||}||dd||ddxF|D]8\}}|t|t|t|tqVWdS(Nu7https://i.b/callback?oauth_token=foo&oauth_verifier=barufoou oauth_tokenuoauth_verifierubar(Rtparse_authorization_responseRKtitemsRRt unicode_type(RR/RCR)tktv((Rttest_parse_response_urls  cCstd}|d|_|d}||ddxF|D]8\}}|t|t|t|tqNWdS(Nufoouoauth_token=foouhttps://example.com/tokenu oauth_token( Rt fake_bodyR2tfetch_request_tokenRKRPRRRQ(RRCR)RRRS((Rttest_fetch_request_tokens  cCstd}|d|_|ddtdt}||ddxF|D]8\}}|t |t |t |t qZWdS(Nufoouoauth_token=foouhttps://example.com/tokentverifytstreamu oauth_token( RRUR2RVtFalsetTrueRKRPRRRQ(RRCR)RRRS((Rt0test_fetch_request_token_with_optional_argumentss   cCstddd}|d|_|d}||ddxF|D]8\}}|t|t|t|tqTWdS(Nufootverifierubaruoauth_token=foouhttps://example.com/tokenu oauth_token( RRUR2tfetch_access_tokenRKRPRRRQ(RRCR)RRRS((Rttest_fetch_access_tokens cCstddd}|d|_|ddtdt}||ddxF|D]8\}}|t |t |t |t q`WdS( NufooR]ubaruoauth_token=foouhttps://example.com/tokenRXRYu oauth_token( RRUR2R^RZR[RKRPRRRQ(RRCR)RRRS((Rt/test_fetch_access_token_with_optional_argumentss  cCsS|d|_y|dWn)tk rN}|dt|nXdS(ukAssert that an error is being raised whenever there's no verifier passed in to the client. uoauth_token=foouhttps://example.com/tokenu No client verifier has been set.N(RUR2R^t ValueErrorRKR (RRCtexc((Rt%_test_fetch_access_token_raises_errors cCstd}|d|_|t|jdxdD]~}|d||_y|dWnBtk r}||j||t |j t j q;X| dq;WdS(Nufoounot valid urlencoded response!uhttps://example.com/token(iiiuvalid=responseuValueError not raised(RRUR2t assertRaisesRaRVRKt status_codeRRtresponseR#R$tfail(RRCtcodeterr((Rt!test_fetch_token_invalid_responses  cCs|tddS(Nufoo(RcR(R((Rt(test_fetch_access_token_missing_verifierscCs)td}|jj`||dS(Nufoo(Rt_clienttclientR]Rc(RRC((Rt,test_fetch_access_token_has_verifier_is_nones  cCs td}||jdS(Nufoo(Rt assertFalset authorized(Rtsess((Rttest_authorized_falses cCsPddt}tddtdt}|||_||jdS(NuOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_signature="{sig}"R8ufooR7R9( R>R?RRR@R,R2RoRp(RR(Rq((Rttest_authorized_false_rsas    cCsHtdddd}|d|_|d||jdS(NukeyusecretR]ubaru&oauth_token=foo&oauth_token_secret=baruhttps://example.com/token(RRUR2R^RRp(RRq((Rttest_authorized_trues c Cststdnd|_d|_ddt}tdddtd td d }| d |_ | d | |j dS(Nucryptography module is requireduabcu123uOAuth oauth_nonce="abc", oauth_timestamp="123", oauth_version="1.0", oauth_signature_method="RSA-SHA1", oauth_consumer_key="foo", oauth_verifier="bar", oauth_signature="{sig}"R8ukeyusecretR7R9R]ubaru&oauth_token=foo&oauth_token_secret=baruhttps://example.com/token(R:R;R<R=R>R?RRR@RUR2R^RRp(RRARBR(Rq((Rttest_authorized_true_rsas     csfd}|S(Ncs`|jd}t|tr.|d}n|tdtj}g|_ |S(Nu Authorizationuutf-8R( R-RRR RKR!R"R#R$R%(R&R't auth_headerR)(RR((RR+-s  ((RR(R+((RR(RR,,sicsfd}|S(Ncs4tdtj}g|_|_|_|S(NR(R!R"R#R$R%ttextRe(R&R'R)(R0Re(RR+8s    ((RR0ReR+((R0ReRRU7s(t__name__t __module__RR6R!tpatchRDRGRHRNRTRWR\R_R`RcRjRkRnRrRsRtRuR,RU(((RRRs2              (#t __future__RRR!R;R R#toauthlib.oauth1RRRRtrequests_oauthlibRRt ImportErrortioR:tversionR RQtbytesRtunicodeRR R<t TestResulttaddErrorRRR@R?tTestCaseR(((Rts8           requests-oauthlib-0.8.0/tests/test_oauth2_auth.py0000644000076500000240000000414212201441447022274 0ustar corystaff00000000000000from __future__ import unicode_literals import unittest from oauthlib.oauth2 import WebApplicationClient, MobileApplicationClient from oauthlib.oauth2 import LegacyApplicationClient, BackendApplicationClient from requests import Request from requests_oauthlib import OAuth2 class OAuth2AuthTest(unittest.TestCase): def setUp(self): self.token = { 'token_type': 'Bearer', 'access_token': 'asdfoiw37850234lkjsdfsdf', 'expires_in': '3600' } self.client_id = 'foo' self.clients = [ WebApplicationClient(self.client_id), MobileApplicationClient(self.client_id), LegacyApplicationClient(self.client_id), BackendApplicationClient(self.client_id), ] def test_add_token_to_url(self): url = 'https://example.com/resource?foo=bar' new_url = url + '&access_token=' + self.token['access_token'] for client in self.clients: client.default_token_placement = 'query' auth = OAuth2(client=client, token=self.token) r = Request('GET', url, auth=auth).prepare() self.assertEqual(r.url, new_url) def test_add_token_to_headers(self): token = 'Bearer ' + self.token['access_token'] for client in self.clients: auth = OAuth2(client=client, token=self.token) r = Request('GET', 'https://i.b', auth=auth).prepare() self.assertEqual(r.headers['Authorization'], token) def test_add_token_to_body(self): body = 'foo=bar' new_body = body + '&access_token=' + self.token['access_token'] for client in self.clients: client.default_token_placement = 'body' auth = OAuth2(client=client, token=self.token) r = Request('GET', 'https://i.b', data=body, auth=auth).prepare() self.assertEqual(r.body, new_body) def test_add_nonexisting_token(self): for client in self.clients: auth = OAuth2(client=client) r = Request('GET', 'https://i.b', auth=auth) self.assertRaises(ValueError, r.prepare) requests-oauthlib-0.8.0/tests/test_oauth2_auth.pyc0000644000076500000240000000530512770743363022456 0ustar corystaff00000000000000 'CRcsddlmZddlZddlmZmZddlmZmZddlm Z ddl m Z dej fdYZ dS( i(tunicode_literalsN(tWebApplicationClienttMobileApplicationClient(tLegacyApplicationClienttBackendApplicationClient(tRequest(tOAuth2tOAuth2AuthTestcs5eZdZdZdZdZdZRS(cCsdidd6dd6dd6|_d|_t|jt|jt|jt|jg|_dS(NuBeareru token_typeuasdfoiw37850234lkjsdfsdfu access_tokenu3600u expires_inufoo(ttokent client_idRRRRtclients(tself((tU/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_auth.pytsetUp s     cCsd}|d|jd}x`|jD]U}d|_td|d|j}td|d|}||j|q%WdS( Nu$https://example.com/resource?foo=baru&access_token=u access_tokenuquerytclientRuGETtauth(RR tdefault_token_placementRRtpreparet assertEqualturl(R Rtnew_urlRRtr((R ttest_add_token_to_urls  cCssd|jd}x[|jD]P}td|d|j}tddd|}||jd|qWdS( NuBearer u access_tokenRRuGETu https://i.bRu Authorization(RR RRRRtheaders(R RRRR((R ttest_add_token_to_headers#s  cCsd}|d|jd}xf|jD][}d|_td|d|j}tddd |d |}||j|q%WdS( Nufoo=baru&access_token=u access_tokenubodyRRuGETu https://i.btdataR(RR RRRRRtbody(R Rtnew_bodyRRR((R ttest_add_token_to_body*s  !cCsOxH|jD]=}td|}tddd|}|t|jq WdS(NRuGETu https://i.bR(R RRt assertRaisest ValueErrorR(R RRR((R ttest_add_nonexisting_token3s  (t__name__t __module__R RRRR(((R R s    (t __future__Rtunittesttoauthlib.oauth2RRRRtrequestsRtrequests_oauthlibRtTestCaseR(((R ts  requests-oauthlib-0.8.0/tests/test_oauth2_session.py0000644000076500000240000002251212770742335023032 0ustar corystaff00000000000000from __future__ import unicode_literals import json import mock import time from base64 import b64encode from copy import deepcopy try: from unittest2 import TestCase except ImportError: from unittest import TestCase from oauthlib.common import urlencode from oauthlib.oauth2 import TokenExpiredError, OAuth2Error from oauthlib.oauth2 import MismatchingStateError from oauthlib.oauth2 import WebApplicationClient, MobileApplicationClient from oauthlib.oauth2 import LegacyApplicationClient, BackendApplicationClient from requests_oauthlib import OAuth2Session, TokenUpdated fake_time = time.time() def fake_token(token): def fake_send(r, **kwargs): resp = mock.MagicMock() resp.text = json.dumps(token) return resp return fake_send class OAuth2SessionTest(TestCase): def setUp(self): # For python 2.6 if not hasattr(self, 'assertIn'): self.assertIn = lambda a, b: self.assertTrue(a in b) self.token = { 'token_type': 'Bearer', 'access_token': 'asdfoiw37850234lkjsdfsdf', 'refresh_token': 'sldvafkjw34509s8dfsdf', 'expires_in': '3600', 'expires_at': fake_time + 3600, } self.client_id = 'foo' self.clients = [ WebApplicationClient(self.client_id, code='asdf345xdf'), LegacyApplicationClient(self.client_id), BackendApplicationClient(self.client_id), ] self.all_clients = self.clients + [MobileApplicationClient(self.client_id)] def test_add_token(self): token = 'Bearer ' + self.token['access_token'] def verifier(r, **kwargs): auth_header = r.headers.get('Authorization', None) if 'Authorization'.encode('utf-8') in r.headers: auth_header = r.headers['Authorization'.encode('utf-8')] self.assertEqual(auth_header, token) resp = mock.MagicMock() resp.cookes = [] return resp for client in self.all_clients: auth = OAuth2Session(client=client, token=self.token) auth.send = verifier auth.get('https://i.b') def test_authorization_url(self): url = 'https://example.com/authorize?foo=bar' web = WebApplicationClient(self.client_id) s = OAuth2Session(client=web) auth_url, state = s.authorization_url(url) self.assertIn(state, auth_url) self.assertIn(self.client_id, auth_url) self.assertIn('response_type=code', auth_url) mobile = MobileApplicationClient(self.client_id) s = OAuth2Session(client=mobile) auth_url, state = s.authorization_url(url) self.assertIn(state, auth_url) self.assertIn(self.client_id, auth_url) self.assertIn('response_type=token', auth_url) @mock.patch("time.time", new=lambda: fake_time) def test_refresh_token_request(self): self.expired_token = dict(self.token) self.expired_token['expires_in'] = '-1' del self.expired_token['expires_at'] def fake_refresh(r, **kwargs): if "/refresh" in r.url: self.assertNotIn("Authorization", r.headers) resp = mock.MagicMock() resp.text = json.dumps(self.token) return resp # No auto refresh setup for client in self.clients: auth = OAuth2Session(client=client, token=self.expired_token) self.assertRaises(TokenExpiredError, auth.get, 'https://i.b') # Auto refresh but no auto update for client in self.clients: auth = OAuth2Session(client=client, token=self.expired_token, auto_refresh_url='https://i.b/refresh') auth.send = fake_refresh self.assertRaises(TokenUpdated, auth.get, 'https://i.b') # Auto refresh and auto update def token_updater(token): self.assertEqual(token, self.token) for client in self.clients: auth = OAuth2Session(client=client, token=self.expired_token, auto_refresh_url='https://i.b/refresh', token_updater=token_updater) auth.send = fake_refresh auth.get('https://i.b') def fake_refresh_with_auth(r, **kwargs): if "/refresh" in r.url: self.assertIn("Authorization", r.headers) encoded = b64encode(b"foo:bar") content = (b"Basic " + encoded).decode('latin1') self.assertEqual(r.headers["Authorization"], content) resp = mock.MagicMock() resp.text = json.dumps(self.token) return resp for client in self.clients: auth = OAuth2Session(client=client, token=self.expired_token, auto_refresh_url='https://i.b/refresh', token_updater=token_updater) auth.send = fake_refresh_with_auth auth.get('https://i.b', client_id='foo', client_secret='bar') @mock.patch("time.time", new=lambda: fake_time) def test_token_from_fragment(self): mobile = MobileApplicationClient(self.client_id) response_url = 'https://i.b/callback#' + urlencode(self.token.items()) auth = OAuth2Session(client=mobile) self.assertEqual(auth.token_from_fragment(response_url), self.token) @mock.patch("time.time", new=lambda: fake_time) def test_fetch_token(self): url = 'https://example.com/token' for client in self.clients: auth = OAuth2Session(client=client, token=self.token) auth.send = fake_token(self.token) self.assertEqual(auth.fetch_token(url), self.token) error = {'error': 'invalid_request'} for client in self.clients: auth = OAuth2Session(client=client, token=self.token) auth.send = fake_token(error) self.assertRaises(OAuth2Error, auth.fetch_token, url) def test_cleans_previous_token_before_fetching_new_one(self): """Makes sure the previous token is cleaned before fetching a new one. The reason behind it is that, if the previous token is expired, this method shouldn't fail with a TokenExpiredError, since it's attempting to get a new one (which shouldn't be expired). """ new_token = deepcopy(self.token) past = time.time() - 7200 now = time.time() self.token['expires_at'] = past new_token['expires_at'] = now + 3600 url = 'https://example.com/token' with mock.patch('time.time', lambda: now): for client in self.clients: auth = OAuth2Session(client=client, token=self.token) auth.send = fake_token(new_token) self.assertEqual(auth.fetch_token(url), new_token) def test_web_app_fetch_token(self): # Ensure the state parameter is used, see issue #105. client = OAuth2Session('foo', state='somestate') self.assertRaises(MismatchingStateError, client.fetch_token, 'https://i.b/token', authorization_response='https://i.b/no-state?code=abc') def test_client_id_proxy(self): sess = OAuth2Session('test-id') self.assertEqual(sess.client_id, 'test-id') sess.client_id = 'different-id' self.assertEqual(sess.client_id, 'different-id') sess._client.client_id = 'something-else' self.assertEqual(sess.client_id, 'something-else') del sess.client_id self.assertIsNone(sess.client_id) def test_access_token_proxy(self): sess = OAuth2Session('test-id') self.assertIsNone(sess.access_token) sess.access_token = 'test-token' self.assertEqual(sess.access_token, 'test-token') sess._client.access_token = 'different-token' self.assertEqual(sess.access_token, 'different-token') del sess.access_token self.assertIsNone(sess.access_token) def test_token_proxy(self): token = { 'access_token': 'test-access', } sess = OAuth2Session('test-id', token=token) self.assertEqual(sess.access_token, 'test-access') self.assertEqual(sess.token, token) token['access_token'] = 'something-else' sess.token = token self.assertEqual(sess.access_token, 'something-else') self.assertEqual(sess.token, token) sess._client.access_token = 'different-token' token['access_token'] = 'different-token' self.assertEqual(sess.access_token, 'different-token') self.assertEqual(sess.token, token) # can't delete token attribute with self.assertRaises(AttributeError): del sess.token def test_authorized_false(self): sess = OAuth2Session('foo') self.assertFalse(sess.authorized) @mock.patch("time.time", new=lambda: fake_time) def test_authorized_true(self): def fake_token(token): def fake_send(r, **kwargs): resp = mock.MagicMock() resp.text = json.dumps(token) return resp return fake_send url = 'https://example.com/token' for client in self.clients: sess = OAuth2Session(client=client) sess.send = fake_token(self.token) self.assertFalse(sess.authorized) sess.fetch_token(url) self.assertTrue(sess.authorized) requests-oauthlib-0.8.0/tests/test_oauth2_session.pyc0000644000076500000240000002252712770743363023205 0ustar corystaff00000000000000 Wcs3ddlmZddlZddlZddlZddlmZddlmZyddl m Z Wn!e k rddl m Z nXddl mZddlmZmZddlmZdd lmZmZdd lmZmZdd lmZmZeZd Zd e fdYZdS(i(tunicode_literalsN(t b64encode(tdeepcopy(tTestCase(t urlencode(tTokenExpiredErrort OAuth2Error(tMismatchingStateError(tWebApplicationClienttMobileApplicationClient(tLegacyApplicationClienttBackendApplicationClient(t OAuth2Sessiont TokenUpdatedcsfd}|S(Ncs"t}t|_|S(N(tmockt MagicMocktjsontdumpsttext(trtkwargstresp(ttoken(tX/Users/cory/Documents/Python/requests_org/requests-oauthlib/tests/test_oauth2_session.pyt fake_sends ((RR((RRt fake_tokenstOAuth2SessionTestcseZdZdZdZeddddZeddddZeddd d Z d Z d Z d Z dZ dZdZeddddZRS(cstds$fd_nidd6dd6dd6d d 6td d 6_d _tjddtjtjg_jt jg_ dS(NuassertIncs||kS(N(t assertTrue(tatb(tself(Rt%suBeareru token_typeuasdfoiw37850234lkjsdfsdfu access_tokenusldvafkjw34509s8dfsdfu refresh_tokenu3600u expires_iniu expires_atufootcodeu asdf345xdf( thasattrtassertInt fake_timeRt client_idRR R tclientsR t all_clients(R((RRtsetUp"s  csidjdfd}x?jD]4}td|dj}||_|dq-WdS(NuBearer u access_tokencso|jdd}dd|jkrF|jdd}n|t}g|_|S(Nu Authorizationuutf-8(theaderstgettencodet assertEqualRRtcookes(RRt auth_headerR(RR(Rtverifier9s  tclientRu https://i.b(RR&R tsendR)(RR.R/tauth((RRRttest_add_token6s  cCsd}t|j}td|}||\}}|||||j||d|t|j}td|}||\}}|||||j||d|dS(Nu%https://example.com/authorize?foo=barR/uresponse_type=codeuresponse_type=token(RR$R tauthorization_urlR"R (Rturltwebtstauth_urltstatetmobile((Rttest_authorization_urlGsu time.timetnewcCstS(N(R#(((RRXsc stj_djd<jd=fd}x?jD]4}td|dj}t|jdqBWxNjD]C}td|djdd }||_t |jdqWfd }xKjD]@}td|djdd d |}||_|dqWfd }xWjD]L}td|djdd d |}||_|dd dddqAWdS(Nu-1u expires_inu expires_atcsJd|jkr%d|jnt}tj|_|S(Nu/refreshu Authorization( R4t assertNotInR(RRRRRR(RRR(R(Rt fake_refresh^s  R/Ru https://i.btauto_refresh_urluhttps://i.b/refreshcs|jdS(N(R+R(R(R(Rt token_updaterrsR?csd|jkr[d|jtd}d|d}|jd|nt}t j |_ |S(Nu/refreshu Authorizationsfoo:barsBasic ulatin1( R4R"R(RtdecodeR+RRRRRR(RRtencodedtcontentR(R(Rtfake_refresh_with_auth|s  R$ufoot client_secretubar( tdictRt expired_tokenR%R t assertRaisesRR)R0R (RR=R/R1R?RC((RRttest_refresh_token_requestXs<            cCstS(N(R#(((RRscCsWt|j}dt|j}td|}||||jdS(Nuhttps://i.b/callback#R/(R R$RRtitemsR R+ttoken_from_fragment(RR9t response_urlR1((Rttest_token_from_fragmentscCstS(N(R#(((RRscCsd}xW|jD]L}td|d|j}t|j|_||||jqWidd6}xN|jD]C}td|d|j}t||_|t|j|qwWdS(Nuhttps://example.com/tokenR/Ruinvalid_requestuerror( R%R RRR0R+t fetch_tokenRGR(RR4R/R1terror((Rttest_fetch_tokens    cst|j}td}t||jd<d|ds$