Giter VIP home page Giter VIP logo

python-openid's Introduction

python-openid2

Build Status codecov PyPI PyPI - Python Version

Python OpenID library - OpenID support for servers and consumers.

This is a set of Python packages to support use of the OpenID decentralized identity system in your application. Want to enable single sign-on for your web site? Use the openid.consumer package. Want to run your own OpenID server? Check out openid.server. Includes example code and support for a variety of storage back-ends.

REQUIREMENTS

  • Python 2.7, >=3.5
  • lxml
  • six
  • cryptography

INSTALLATION

To install the base library, just run the following command:

pip install python-openid2

GETTING STARTED

The examples directory includes an example server and consumer implementation. See the README file in that directory for more information on running the examples.

Library documentation is available in html form in the doc directory.

LOGGING

This library offers a logging hook that will record unexpected conditions that occur in library code. If a condition is recoverable, the library will recover and issue a log message. If it is not recoverable, the library will raise an exception. See the documentation for the openid.oidutil module for more on the logging hook.

DOCUMENTATION

The documentation in this library is in Epydoc format, which is detailed at:

http://epydoc.sourceforge.net/

CONTACT

Send bug reports, suggestions, comments, and questions to https://github.com/ziima/python-openid/issues/new

If you have a bugfix or feature you'd like to contribute, don't hesitate to send it to us on GitHub.

python-openid's People

Contributors

cdman avatar cjwatson avatar dairiki avatar davidthewatson avatar dokai avatar justjkk avatar msabramo avatar rodrigoprimo avatar rubys avatar santagada avatar temoto avatar tpazderka avatar tseaver avatar willnorris avatar ziima avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-openid's Issues

Clarify license

Hi there, both the source and setup.py declare it as 'LGPL'. In order to package it for openSUSE, we need a clarification which LGPL version you are referring too. Please update the code accordingly. Thanks!

Authentication error when AX is used

In a situation when attribute exchange is used, server may run out of space in GET request and send the rest of information in additional POST request. In this case authentication fails.

In my case the parameter that goes to POST is janrain_nonce, that generates a bit confusing error message:

OpenID authentication failed: return_to does not match return URL. Expected 'http://mysite.ws/social_login_complete/yandex?janrain_nonce=2011-03-31T07%3A42%3A30ZVdfW0a', got u'http://mysite.ws/social_login_complete/yandex?janrain_nonce=2011-03-31T07%3A42%3A30ZVdfW0a'

If needed I can send client-server exchange protocol dump.

Example consumer works only if authentication response is GET method

The example consumer falls down if the OP sends an authentication response to the RP with POST method

In that case the example consumer reports 501 error: Unsupported method (POST)

This is because a ".do_POST()" isn't defined in examples/consumer.py

What happens is, you start the example consumer, enter an OpenID, send authentication request to OP, OP sends authentication response back to consumer. Authentication response is an indirect response - if the HTTP method is POST vs. GET, the consumer reports 501 error

I think the correct behavior is for the consumer to process the authentication response, like it processes the authentication response if the HTTP method is GET vs. POST. It should report that authentication succeeded or failed, like it does if the HTTP method is GET vs. POST

IOError Broken Pipe on log

Hi guys, I've started encountering a Broken Pipe on our staging server when authenticating using python-openid. We're using a fork of django-openid-provider but the error itself comes from python-openid at the following line:

IOError: [Errno 32] Broken pipe
  File "django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "openid_provider/views.py", line 115, in openid_server
    return prep_response(request, orequest, oresponse, server)
  File "openid_provider/utils.py", line 116, in prep_response
    webresponse = server.encodeResponse(oresponse)
  File "openid/server/server.py", line 1626, in encodeResponse
    return self.encoder.encode(response)
  File "openid/server/server.py", line 1383, in encode
    response = self.signatory.sign(response)
  File "openid/server/server.py", line 1227, in sign
    signed_response.fields = assoc.signMessage(signed_response.fields)
  File "openid/association.py", line 520, in signMessage
    sig = self.getMessageSignature(signed_message)
  File "openid/association.py", line 496, in getMessageSignature
    return oidutil.toBase64(self.sign(pairs))
  File "openid/association.py", line 471, in sign
    kv = kvform.seqToKV(pairs)
  File "openid/kvform.py", line 57, in seqToKV
    err('Value has whitespace at beginning or end: %r' % (v,))
  File "openid/kvform.py", line 25, in err
    oidutil.log(formatted)
  File "openid/oidutil.py", line 109, in log
    sys.stderr.write(message)

Should sys.stderr be the write way to output this instead of logger.error?

This is a server running using Gunicorn+Django and being run from Supervisor. I'm assuming Supervisor is closing stderr as part of its logging.

MySQLStore.createTables fails if MySQL’s default character set is utf8mb4

The issue with with the oid_associations.handle VARCHAR(255) column. It is part of the primary key for the table. MySQL imposes an upper limit on index prefix length in bytes. For the InnoDB backend, the limit is 767 bytes. Since the utf8mb4 character set uses four bytes per character that limit is exceeded. This results in an “OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')” error from MySQL.

The solution, I think, is to explicitly declare the character set to use for oid_associations.handle column (or perhaps for declare the character set for the whole table, as well as the oid_nonces table.) (I haven't looked into this enough to know what character set would be best — is unicode required or would plain ascii work?)

There’s a bit more information here at trac-hacks/authopenid-plugin#11.

What python versions are supported?

What is the official list of support python versions?

05b759c implies that the answer is 2.6, 2.7

The README says "2.3, 2.4, or 2.5". Clearly out of date.

Any interest in py3k?

Missing import in openid.extension

This seemed too lightweight of an issue for a pull request, but the toMessage method of openid.extension.Extension references the warnings module without it having been imported.

Test case:

import openid.extension

ext = openid.extension.Extension()
ext.toMessage()

Even though this use of the method is deprecated, I consider it a bug.

test_parsehtml.py now fails test runTest

python-yadis or python-openid I really don't know which; version 1.1.0.
python version Python 2.7.3

  • Testing of dev-python/python-yadis-1.1.0-r1 with CPython 2.7...
    Checking code (pyflakes)... OK.
    Running tests... putting . in sys.path
    ..............................F.................................................

    FAIL: runTest (test_parsehtml._TestCase)
    24 (test_parsehtml<test1-parsehtml.txt>)

    Traceback (most recent call last):
    File "/mnt/gen2/TmpDir/portage/dev-python/python-yadis-1.1.0-r1/work/python-yadis-1.1.0/yadis/test/test_parsehtml.py", line 36, in runTest
    self.failUnless(self.expected == 'EOF', (self.case, self.expected))
    AssertionError: ('<!bad processing instruction!>\n', 'None')

Ran 80 tests in 0.036s

FAILED (failures=1)

My impression this is triggered by a change in python2.7 earlier this year.
Await your verdict.

distro gentoo..

Yadis XRDS parser vulnerable to various XML DoS attacks

The Yadis XRDS parsing code is vulnerable to various XML-related DoS attacks.
The offending code is openid.yardis.etxrd.parseXRDS, which relies on the XML library imported by openid.oidutil.importElementTree. The vulnerabilities one will be exposed to depends on which XML libraries are being used.

See the defusedxml Pypi page for a discussion of the various attacks, as well as the solution (e.g., use defusedxml). You can also see the issue where this was fixed in the Ruby package.

Since there seems to be no active development on this package, I have no intention of submitting a pull request to fix this issue. I am simply opening this issue so that others can be aware of the implications of using this package.

Reduce anxiety over TypeURIMismatch

This suggestion arose while I was attempting to understand an error message in the log while verifying an authentication response:

Error attempting to use stored discovery information: 
<openid.consumer.consumer.TypeURIMismatch: Required type http://specs.openid.net/auth/2.0/signon 
not found in ['http://specs.openid.net/auth/2.0/server', 'http://openid.net/srv/ax/1.0'] for endpoint <openid.consumer.discover.OpenIDServiceEndpoint 
server_url='https://wire.ncsa.uiuc.edu/openid/provider' claimed_id=None local_id=None 
canonicalID=None used_yadis=True >>

This occurs when I had previously used an OP Identifier as the claimed ID when initializing the authentication. (An OP Identifier is used when user will select an identity at the OP login page; see use of identity_select in spec). Verification fails because the information cached during initialization based on the OP Identifier, while the verification step expects it to be based on the user's OP-local ID. This is detected (in consumer.py:1004) when cached endpoint does not include http://specs.openid.net/auth/2.0/signon among its type_uris, indicating a v2 OpenID.

This is is not a big deal as the verification code (after printing the above error message) turns right around and does a re-discovery on the user's claimed_id, and verification completes successfully. However, I noticed during my googling that others have been puzzled by this (apparently while chasing down perhaps unrelated problems). Indeed, the use of the word "Error" and the citing of the Exception, TypeURIMismatch, suggests that something is actually wrong when I don't think that is actually the case.

(My testing indicates that attempting to use the info cached for the OP Identifier during verification causes verification of the message signature to fail. Is this correct behavior?)

I would then suggest the following change to consumer.py near line 924:

    if not endpoint:
        oidutil.log('No pre-discovered information supplied.')
        endpoint = self._discoverAndVerify(to_match.claimed_id, [to_match])
    ############## v INSERT HERE v ######################
    elif endpoint.isOPIdentifier():
        oidutil.log('Pre-discovered information based on OP-ID; need to rediscover.')
        endpoint = self._discoverAndVerify(to_match.claimed_id, [to_match])
    ############## ^ INSERT HERE ^ ######################
    else:
        # The claimed ID matches, so we use the endpoint that we
        # discovered in initiation. This should be the most common
        # case.
        try:
            self._verifyDiscoverySingle(endpoint, to_match)
        except ProtocolError, e:
            oidutil.log(
                "Error attempting to use stored discovery information: " +
                str(e))

"Discovery verification failure" - claimed_id and identity inconsistency for the same account

Hello, I'd like to bring up an issue we are having in Fedora project which I personally don't understand. I'd like to get some clarity on what's the proper solution - I appreciate any kind of feedback. We are using ipsilon on the server side in Fedora and python-openid + flask-openid on the "client side" in our services which integrate with the centralized authentication system - FAS, backed by ipsilon.

Details of the issue are reported in this ipsilon issue. TL;DR is that ipsilon returns different openid.{identity,claimed_id} whether a user authenticates with an associated email or a username, which confuses python-openid and flask-openid. I can't wrap my head around whether this is an issue in ipsilon or something can be done about the problem in this project.

I was able to pin down the affected code to this snippet:

_LOGGER.warning('Discovery verification failure for %s', claimed_id)
for failure_message in failure_messages:
_LOGGER.warning(' * Endpoint mismatch: %s', failure_message)
raise DiscoveryFailure(
'No matching endpoint found after discovering %s'
% (claimed_id,), None)

dead project?

The last update on pypy was in 2010. Are there any plans for a new version -- at least bug fixes?

Any known problem with python2.7 ?

I am trying to use askbot which django based app which makes use python-openid and I am getting following error on my website.
"Received "invalidate_handle" from server "
Here is link to full apache log.

http://bit.ly/apache_log

Can someone tell me if this is bug with python-openid or with my configuration ?

Getting unsigned ax attributes from an openid provider causes a "NoneType object has no attribute get" error

When dealing with openid ax atrributes, the consumer.py has a SuccessResponse.getSignedNS that returns the signed attributes or None is any of the signed attributes are not signed (link).

IMO this method should raise an exception or just return the signed ones. Returning None means that no attributes were signed at all and also fails when dealing with the result of this method, as instead of an empty array, you get None.

When an OpenID provider redirects to an url with present but unsigned ax attributes, the fromSuccessResponse will fail with a "NoneType object has no attribute get" as this line will try to get the current mode on a None object

Deprecation warning due to invalid escape sequences in Python 3.8

Deprecation warnings are raised due to invalid escape sequences in Python 3.8 . Below is a log of the warnings raised during compiling all the python files. Using raw strings or escaping them will fix this issue.

find . -iname '*.py'  | xargs -P 4 -I{} python -Wall -m py_compile {}

./openid/extensions/draft/pape2.py:30: DeprecationWarning: invalid escape sequence \d
  TIME_VALIDATOR = re.compile('^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ$')
./openid/extensions/draft/pape5.py:35: DeprecationWarning: invalid escape sequence \d
  TIME_VALIDATOR = re.compile('^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ$')

The example consumer/ server only ever responds with "OpenID transaction in progress"

Following the examples README, I only ever receive a bunch of HTML and the message in the title. This is the full output as displayed in my browser.

<html>
<head>
  <title>OpenID transaction in progress</title>
</head>
<body onload="document.forms[0].submit();">
<form id="openid_message" action="http://localhost:8000/openidserver" method="post" accept-charset="UTF-8" 
enctype="application/x-www-form-urlencoded"><input type="hidden" name="openid.ns" value="http://specs.openid.net/auth/2.0" /><input type="hidden" name="openid.realm" value="http://localhost:8001/" /><input type="hidden" 
name="openid.mode" value="checkid_setup" /><input type="hidden" name="openid.return_to" value="http://localhost:8001/process?janrain_nonce=2021-04-28T15%3A12%3A30Zme7GFH" /><input type="hidden" name="openid.identity" 
value="http://localhost:8000/id/jeff" /><input type="hidden" name="openid.claimed_id" value="http://localhost:8000/id/jeff"
 /><input type="hidden" name="openid.assoc_handle" value="{HMAC-SHA1}{NUMBERS}{STUFF}" /><input type="submit" value="Continue" /></form>
<script>
var elements = document.forms[0].elements;
for (var i = 0; i < elements.length; i++) {
  elements[i].style.display = "none";
}
</script>
</body>
</html>

Steps:

python consumer.py
python server.py # in separate terminal

Visit http://localhost:8001 in firefox.

Enter http://localhost:8000/id/jeff in input box, and click Verify

Observed: as above

Expected: the login page as described in the README.

encodeToURL of CheckIDRequest

should it better be:

    for arg, value in self.message.args.items():
        q[arg[1]] = value

instead of hand coded values as otherwise we loos e.g. sreg data?

Can python-openid be used by desktop applications for authentication?

I've looked through the code you offer and it seemed it is designed for OpenID providers and consumers.
I am looking at a module that would help authenticating to an on-line service e.g. StackExchange, from a desktop application, without using an embedded browser.
I've worked on that myself, using Google Accounts as an OpenID provider, but doing this for all providers is quite some work. I don't want to duplicate existing work. Also, although my code is working, I'm not very literate with protocols on the Internet to be sure I'm doing the right thing.

In sum: is it possible to use python-openid for desktop applications to authenticate to provider and consumer?

Thanks.

Serialize YadisServiceManager instance before writing it to session dict

Here:

def store(self, session):

the whole YadisServiceManager instance gets written into the session, which is a dict-like object. This basically requires the web framework writing this session data somewhere (e.g. to a cookie) to use pickle as serializer, while sometimes JSON or others might be desired.

In my special case (Flask + OpenID-ext + itsdangerous-ext) this lead to: <openid.yadis.manager.YadisServiceManager object at 0x9fa6f2c> is not JSON serializable during the authentication process.

Therefore, it would be nice to have the serialization/deserialization done by python-openid, so that it is possible for python-openid to store a string to the session, which should not break any storage backend. By doing so, one could consider only storing the relevant data, because pickling this whole object for sure brings along some overhead.

Thanks for consideration,

Jan-Philip Gehrcke

Proposing a PR to fix a few small typos

Issue Type

[x] Bug (Typo)

Steps to Replicate and Expected Behaviour

  • Examine openid/consumer/consumer.py, openid/test/test_ax.py, openid/test/test_consumer.py and observe paramaters, however expect to see parameters.
  • Examine openid/consumer/consumer.py and observe authenitcation, however expect to see authentication.
  • Examine openid/consumer/consumer.py and observe respones, however expect to see response.
  • Examine openid/extensions/ax.py and observe processsed, however expect to see processed.
  • Examine openid/consumer/consumer.py and observe successfull, however expect to see successful.
  • Examine examples/djopenid/server/views.py and observe intput, however expect to see input.
  • Examine openid/oidutil.py and observe distict, however expect to see distinct.
  • Examine openid/yadis/xri.py and observe comparsion, however expect to see comparison.
  • Examine openid/oidutil.py and observe arguemtns, however expect to see arguments.

Notes

Semi-automated issue generated by
https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

To avoid wasting CI processing resources a branch with the fix has been
prepared but a pull request has not yet been created. A pull request fixing
the issue can be prepared from the link below, feel free to create it or
request @timgates42 create the PR. Alternatively if the fix is undesired please
close the issue with a small comment about the reasoning.

https://github.com/timgates42/python-openid/pull/new/bugfix_typos

Thanks.

Vulnerable to man-in-the-middle attacks when not using pycurl

HTTPS requests made by this package are vulnerable to MITM attacks when the user does not have pycurl installed, because urllib2 does not verify SSL certificates.

While openid.fetchers also has a fetcher for httplib2, unless explicitly registered it will not be chosen as the default fetcher.

At the very least I feel that this should be documented somewhere, but in my opinion the package should simply add a dependency on a library such as Requests that does SSL verification, and avoid the shenanigans of trying to import various other third-party libraries with fallbacks. If this is not feasible, then the httplib2 should at least be prioritized above urllib2, and perhaps a Requests fetcher should be added as the preferred fetcher.

UnicodeDecodeError on discovery

When it is discovered page that contains in attribute value both unicode chars and html entities, UnicodeDecodeError is raised.

Example of code:

I found a possible solution by decoding resp.body in openid/yadis/discover.whereIsYadis() function before findHTMLMeta() function is called.

Internal use of deprecated API

openid.server.server.OpenIDResponse.__init__ uses request.namespace instead of request.message.getOpenIDNamespace(), which generates deprecation warnings.

Problem with response which contains both signed and unsigned fields

When my OpenID provider gives me response containing both signed and unsigned fields, I get an error:

SuccessResponse.getSignedNS: (http://openid.net/srv/ax/1.0, mode) not signed.
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 889, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 879, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 876, in wsgi_app
    rv = self.dispatch_request()
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 695, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/lib/python2.7/site-packages/flaskext/openid.py", line 416, in decorated
    return self.after_login_func(OpenIDResponse(openid_response))
  File "/usr/lib/python2.7/site-packages/flaskext/openid.py", line 151, in __init__
    lookup = RegLookup(resp)
  File "/usr/lib/python2.7/site-packages/flaskext/openid.py", line 112, in __init__
    self.ax_resp = ax.FetchResponse.fromSuccessResponse(resp) or {}
  File "/usr/lib/python2.7/site-packages/openid/extensions/ax.py", line 711, in fromSuccessResponse
    self.parseExtensionArgs(ax_args)
  File "/usr/lib/python2.7/site-packages/openid/extensions/ax.py", line 686, in parseExtensionArgs
    super(FetchResponse, self).parseExtensionArgs(ax_args)
  File "/usr/lib/python2.7/site-packages/openid/extensions/ax.py", line 498, in parseExtensionArgs
    self._checkMode(ax_args)
  File "/usr/lib/python2.7/site-packages/openid/extensions/ax.py", line 80, in _checkMode
    mode = ax_args.get('mode')
AttributeError: 'NoneType' object has no attribute 'get'

From code and comments:
in openid.extensions.ax.FetchResponse.fromSuccessfulResponse():

 @param signed: Whether non-signed args should be
            processsed. If True (the default), only signed arguments
            will be processsed.
...
ax_args = success_response.extensionResponse(self.ns_uri, signed)

in openid.consumer.consumer.SuccessResponse.extensionResponse(self, namespace_uri, require_signed):

 @param require_signed: True if the arguments should be among
        those signed in the response, False if you don't care.

        If require_signed is True and the arguments are not signed,
        return None.

As we can see, FetchResponse.fromSuccessfulResponse() expects success_response.extensionResponse to return a dictionary containing signed fields only, but gets a None.
How can it be fixed?..

python-openid RP fails without warning when date time is wrong

In one of our test setup, the system time was backward from the actual time. Due to this reason, python-openid RP library fails in the final stage authentication, even though OP sends success message, without giving any warning or reason for failure. This makes hard to detect the reason of failure. It would be good to have a warning log message when RP fails for this reason.

Yadis Discover iterates through services

When OpenID requests are created for provider which has several OpenID versions in its XRDS document, the most prior one is not used but instead they are iterated. I believe problem is at line 109 in yadis/manager.py which returns manager.next() instead manager.current()

I am not sure about consequences in YADIS protocol, maybe it is bug in yadis library as well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.