Metadata-Version: 2.1
Name: PyFxA
Version: 0.7.7
Summary: Firefox Accounts client library for Python
Home-page: https://github.com/mozilla/PyFxA
Author: Mozilla Services
Author-email: services-dev@mozilla.org
License: MPLv2.0
Keywords: firefox accounts authentication
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
License-File: LICENSE.txt

===========================================================
PyFxA: Python library for interacting with Firefox Accounts
===========================================================

.. image:: https://travis-ci.org/mozilla/PyFxA.svg?branch=master
    :target: https://travis-ci.org/mozilla/PyFxA

This is python library for interacting with the Firefox Accounts ecosystem.

Eventually, it is planned to provide easy support for the following features:

* being a direct firefox accounts authentication client
* being an FxA OAuth Service Provider
* accessing attached services
* helps interactions with Firefox Account servers wiht requests Authentication plugins.

But none of that is ready yet; caveat emptor.


Firefox Accounts
================

Currently, basic auth-server operations should work like so:

.. code-block:: python

    from fxa.core import Client

    client = Client("https://api.accounts.firefox.com")
    client.create_account("test@example.com", "MySecretPassword")

    session = client.login("test@example.com", "MySecretPassword")
    cert = session.sign_certificate(myPublicKey)
    session.change_password("MySecretPassword", "ThisIsEvenMoreSecret")


FxA OAuth Relier
================

Trade the authentication code against a longer lived OAuth token:

.. code-block:: python

    from fxa.oauth import Client

    client = Client()
    token = client.trade_code("client-id", "client-secret", "code-1234")


Verify an OAuth token:

.. code-block:: python

    from fxa.oauth import Client
    from fxa.errors import ClientError

    client = Client()

    try:
        profile = client.verify_token("123456...")
    except ClientError:
        print "Invalid token"

    print("User id", profile["user"])


Testing email addresses
=======================

There's also very basic integration with restmail.net, to allow for
testing with live email addresses.  It works like this:

.. code-block:: python

    from fxa.core import Client
    from fxa.tests.utils import TestEmailAccount

    # Create a testing account using an @restmail.net address.
    acct = TestEmailAccount()
    client = Client("https://api.accounts.firefox.com")
    session = client.create_account(acct.email, "MySecretPassword")

    # Verify the account using the code from email.
    acct.fetch()
    for m in acct.messages:
        if "x-verify-code" in m["headers"]:
            session.verify_email_code(m["headers"]["x-verify-code"])

    ...

    # Destroy the account once you're done with it.
    acct.clear()
    client.destroy_account(acct.email, "MySecretPassword")


Passing tokens and assertions to other applications
===================================================

PyFxA provides a ``fxa-client`` that you can use to export Bearer
Tokens and Browser ID assertions.


Get a Bearer Token for an existing account
------------------------------------------

.. code-block:: bash

    fxa-client --bearer --auth you@domain.tld \
        --account-server https://api.accounts.firefox.com/v1 \
        --oauth-server https://oauth.accounts.firefox.com/v1

    Please enter a password for you@domain.tld: 

    # ---- BEARER TOKEN INFO ----
    # User: you@domain.tld
    # Scopes: profile
    # Account: https://api.accounts.firefox.com/v1
    # Oauth: https://oauth.accounts.firefox.com/v1
    # ---------------------------
    export OAUTH_BEARER_TOKEN="3f5106b203c...b728ef93fe29203aad44ee816a45b2f2ff57a6aed7a3"


Create a new account Bearer Token on stage
------------------------------------------

.. code-block:: bash

    fxa-client --bearer --create --prefix hello

    # ---- BEARER TOKEN INFO ----
    # User: hello-89331eba46e970dc1686ba2dc4583fc9@restmail.net
    # Scopes: profile
    # Account: https://api-accounts.stage.mozaws.net/v1
    # Oauth: https://oauth.stage.mozaws.net/v1
    # ---------------------------
    export OAUTH_BEARER_TOKEN="ecb5285d59b28e6768fe60d76e6994877ffb16d3232c...72bdee05ea8a5"


Create a new account BrowserID assertion on stage
-------------------------------------------------

.. code-block:: bash

    fxa-client --browserid --create --audience https://token.stage.mozaws.net/ --prefix syncto
    # ---- BROWSER ID ASSERTION INFO ----
    # User: syncto-5bcf63598bf6026a6833035821742d3e@restmail.net
    # Audience: https://token.stage.mozaws.net/
    # Account: https://api-accounts.stage.mozaws.net/v1
    # ------------------------------------
    export FXA_BROWSERID_ASSERTION="eyJhbGciOiJSUzI1NiJ9.eyJw......VNKcPu6Uc9Y4pCuGcdM0UwaA"
    export FXA_CLIENT_STATE="abaa31cc3b16aaf6759f2cba164a54be"


With Requests
=============

Using Firefox Account BrowserID with Requests
---------------------------------------------

You can use the ``FxABrowserIDAuth`` to build the BrowserID assertion:

.. code-block:: python

    from fxa.core import Client
    from fxa.plugins.requests import FxABrowserIDAuth

    email = acct.email
    password = "MySecretPassword"

    raw_resp = requests.get('https://token.services.mozilla.com/1.0/sync/1.5',
                            auth=FxABrowserIDAuth(email, password,
                                                  with_client_state=True))

    raw_resp.raise_for_status()
    resp = raw_resp.json()
    user_id = resp['uid']


Using Firefox Account Bearer Token with Requests
------------------------------------------------

You can use the ``FxABearerTokenAuth`` to build the Bearer Token:

.. code-block:: python

    from fxa.core import Client
    from fxa.plugins.requests import FxABearerTokenAuth

    email = acct.email
    password = "MySecretPassword"

    raw_resp = requests.get('https://profile.accounts.firefox.com/v1/profile',
                            auth=FxABearerTokenAuth(email, password,
                                                    ['profile'], client_id))

    raw_resp.raise_for_status()
    resp = raw_resp.json()
    user_id = resp['uid']


With HTTPie
===========

Using Firefox Account BrowserID with HTTPie
-------------------------------------------

You can use the httpie plugin provided with PyFxA to build the BrowserID request:

.. code-block:: http

    BID_WITH_CLIENT_STATE=True \
        http GET https://token.services.mozilla.com/1.0/sync/1.5 \
        --auth-type=fxa-browserid --auth "email:password" -v

    GET /1.0/sync/1.5 HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Authorization: BrowserID eyJhbG..._EqaQ
    Connection: keep-alive
    Host: token.services.mozilla.com
    User-Agent: HTTPie/0.9.2
    X-Client-State: 97b945...920fac4d4d5f0dc6...2992

    HTTP/1.1 200 OK
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-Conditions-Accepted
    Access-Control-Allow-Methods: GET, POST, OPTIONS
    Access-Control-Max-Age: 1728000
    Connection: keep-alive
    Content-Length: 414
    Content-Type: application/json; charset=UTF-8
    Date: Tue, 21 Jul 2015 10:48:42 GMT
    X-Timestamp: 1437475722

    {
        "api_endpoint": "https://sync-230-us-west-2.sync.services.mozilla.com/1.5/99283757",
        "duration": 3600,
        "hashalg": "sha256",
        "id": "eyJub2RlI....FlYzdiMCIsICJ1aWQiOiAyMDIzODc3NX2Bvj5zv..7S2jRaw__-....eh3hiSVWA==",
        "key": "lSw-MvgK....ebu9JsX-yXS70NkiXu....6wWgVzU0Q=",
        "uid": 99283757
    }

.. note::

    You can configure the audience by settings the ``BID_AUDIENCE``
    environment variable.

	You can also compute the Token Server client state using the
	``BID_WITH_CLIENT_STATE`` environment variable.


Using Firefox Account Bearer Tokens with HTTPie
-----------------------------------------------

You can use the httpie plugin provided with PyFxA to build the Bearer
token request:

.. code-block:: http

    $ http GET https://profile.accounts.firefox.com/v1/profile \
        --auth-type fxa-bearer --auth "email:password" -v

    GET /v1/profile HTTP/1.1
    Accept: */*
    Accept-Encoding: gzip, deflate
    Authorization: Bearer 98e05e12ba...0d61231e88daf91
    Connection: keep-alive
    Host: profile.accounts.firefox.com
    User-Agent: HTTPie/0.9.2

    HTTP/1.1 200 OK
    Connection: keep-alive
    Content-Length: 92
    Content-Type: application/json; charset=utf-8
    Date: Tue, 21 Jul 2015 14:47:32 GMT
    Server: nginx
    access-control-allow-headers: Authorization, Content-Type, If-None-Match
    access-control-allow-methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS
    access-control-allow-origin: *
    access-control-expose-headers: WWW-Authenticate, Server-Authorization
    access-control-max-age: 86400
    cache-control: no-cache
    content-encoding: gzip
    etag: "d1cf22901b3e3be527c06e27689be705bb22a172"
    strict-transport-security: max-age=15552000; includeSubdomains
    vary: accept-encoding

    {
        "email": "email@address.com",
        "uid": "63b91ca4ec19ad79f320eaf5815d75e9"
    }

.. note::

    You can configure the following:

      - FXA_CLIENT_ID: To choose the CLIENT_ID (default to Firefox Dev id)
      - FXA_SCOPES: To choose the list of scopes
      - FXA_ACCOUNT_SERVER_URL: To select the account server url
        (default to: https://api.accounts.firefox.com/v1)
      - FXA_OAUTH_SERVER_URL: To select the oauth server url
        (default to: https://oauth.accounts.firefox.com/v1)


CHANGELOG
#########

This document describes changes between each past release.

0.7.7 (2020-07-17)
==================

- Fix incorrect validation of JWKs passed to oauth.Client constructor,
  which was actually *preventing* the caller from setting a correct value
  rather than checking that they did so.


0.7.6 (2020-07-10)
==================

- Add ability to configure a fixed list of JWT access token keys,
  by passing them as an argument to `oauth.Client()` rather than
  fetching them at runtime from the server.
- Fix verification of JWT access token `typ` header.
  (Thankfully it was failing closed rather than failing open).
- Fix verification of `scope` list obtained from a JWT access token.
  (Thankfully it was failing closed rather than failing open).


0.7.5 (2020-07-06)
==================

- Add support for `reason` and `verification_method` keyword arguments
  to the `login` method.


0.7.4 (2020-06-10)
==================

- Perform more complete checking of the `state` parameter when authorizing
  an OAuth code.
- When verifying OAuth access tokens, try to verify them locally as a JWT
  rather than passing them to the remote verification endpoint.


0.7.3 (2019-07-26)
==================

- Allow specifying a `ttl` when redeeming an authorization code.


0.7.2 (2019-06-03)
==================

- Several cleans for Python3 compatibility; thanks Tomáš Chvátal!
- Fix a bug could accidentally introduce multiple slashes into
  the result of oauth.Client.get_redirect_url.


0.7.1 (2019-03-18)
==================

- Fix test bustage due to session verification.


0.7.0 (2019-03-18)
==================

- Add support for TOTP.


0.6.0 (2018-05-04)
==================

- Add support for PKCE challenge and response in the OAuth flow.
- Add ability to supply `keys_jwk` when starting an OAuth flow.
- Improve scope-matching logic based on new FxA testcases,
  including handling of URL-format scopes.


0.5.0 (2018-01-12)
==================

- Add ability to login with unblock codes.
- Tell testrunners to ignore some test helper utilities.


0.4.0 (2017-??-??)
==================

- Use `pkg_resources` to handle package version. (#45)
- Add a shortcut for authorizing oauth codes directly from a core.Session,
  rater than requiring the caller to explicitly create an assertion.


0.3.0 (2016-09-07)
==================

- Add a ``verify_email_code(uid, code)`` method to the ``core.Client`` (#43).


0.2.0 (2016-05-11)
==================

- Make sure fxa.tests.utils can be used without installing PyFxA tests dependencies. (#41)


0.1.3 (2016-04-22)
==================

- Update the User-Agent so that we can detect PyFxA calls. (#40)


0.1.2 (2016-04-21)
==================

- Correctly send request to the Auth server.


0.1.1 (2016-01-13)
==================

- Correctly configure cert duration while generating BrowserID Assertion (#39)


0.1.0 (2016-01-07)
==================

- Add fxa-client CLI tool (#36)
- Remove support for Python 2.6 (#38)


0.0.9 (2015-08-15)
==================

- Remove the mention stating that PyFxA is still highly experimental (#31)
- Do not rely on the package to be installed in order to be used (#32)


0.0.8 (2015-08-14)
==================

- Update setup.py to handle utf-8 characters in README and CHANGES files (#29)
- Add cache functionality to the Auth plugins (#30)


0.0.7 (2015-07-23)
==================

- Use grequests if available to use PyFxA with the gevent ecosystem.
- Add the oauth /destroy operation.
- Profile fetch skips fields you don't have permission to read.
- Add the BrowserID requests Auth module and related HTTPie plugin.
- Add the BearerToken requests Auth module and related HTTPie plugin.
- Add PyOpenSSL support for secure SSL requests handling with Python 2.


0.0.6 (2015-03-20)
==================

- Expose unicode in oauth cache, not bytestrings.


0.0.5 (2015-03-19)
==================

- Specify minimum required version of `requests` dependency.


0.0.4 (2015-03-11)
==================

- Add a basic API for retrieving profile information
   with an OAuth token.


0.0.3 (2015-02-20)
==================

- Refacotor oauth.Client to take id/secret as constructor args.
- Add basic caching on oauth token verification.
- Accept option "/v1" suffix on server URLs.
- Add get_identity_assertion() method to core.Session.
- Add methods to oauth.Client for authorizing codes and tokens.
- Add a new error hierarchy for trust-related errors.
- Additional sanity-checking in oauth scope checks.


0.0.2 (2015-01-05)
==================

- Initial release; includes basic auth and oauth functionality.
