incubator-heraldry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ket...@apache.org
Subject svn commit: r463041 [1/7] - in /incubator/heraldry/libraries/python/openid/trunk: ./ admin/ doc/ examples/ openid/ openid/consumer/ openid/server/ openid/store/ openid/test/
Date Wed, 11 Oct 2006 23:11:50 GMT
Author: keturn
Date: Wed Oct 11 16:11:47 2006
New Revision: 463041

URL: http://svn.apache.org/viewvc?view=rev&rev=463041
Log:
Initial import of Python OpenID libraries from JanRain.

This is the 1.x version of the library, with support for OpenID 1.1 plus
Yadis and XRI.

Previous development history for this library may be found in the 
darcs repository at
http://www.openidenabled.com/resources/repos/python/openid/

Added:
    incubator/heraldry/libraries/python/openid/trunk/COPYING
    incubator/heraldry/libraries/python/openid/trunk/INSTALL
    incubator/heraldry/libraries/python/openid/trunk/MANIFEST.in
    incubator/heraldry/libraries/python/openid/trunk/NEWS
    incubator/heraldry/libraries/python/openid/trunk/README
    incubator/heraldry/libraries/python/openid/trunk/admin/
    incubator/heraldry/libraries/python/openid/trunk/admin/combo-setup.py   (with props)
    incubator/heraldry/libraries/python/openid/trunk/admin/makechangelog   (with props)
    incubator/heraldry/libraries/python/openid/trunk/admin/makedoc   (with props)
    incubator/heraldry/libraries/python/openid/trunk/admin/runtests   (with props)
    incubator/heraldry/libraries/python/openid/trunk/admin/setversion   (with props)
    incubator/heraldry/libraries/python/openid/trunk/admin/tagrelease   (with props)
    incubator/heraldry/libraries/python/openid/trunk/darcs-ignore
    incubator/heraldry/libraries/python/openid/trunk/doc/
    incubator/heraldry/libraries/python/openid/trunk/examples/
    incubator/heraldry/libraries/python/openid/trunk/examples/README
    incubator/heraldry/libraries/python/openid/trunk/examples/__init__.py
    incubator/heraldry/libraries/python/openid/trunk/examples/consumer.py   (with props)
    incubator/heraldry/libraries/python/openid/trunk/examples/server.py   (with props)
    incubator/heraldry/libraries/python/openid/trunk/openid/
    incubator/heraldry/libraries/python/openid/trunk/openid/__init__.py
    incubator/heraldry/libraries/python/openid/trunk/openid/association.py
    incubator/heraldry/libraries/python/openid/trunk/openid/consumer/
    incubator/heraldry/libraries/python/openid/trunk/openid/consumer/__init__.py
    incubator/heraldry/libraries/python/openid/trunk/openid/consumer/consumer.py
    incubator/heraldry/libraries/python/openid/trunk/openid/consumer/discover.py
    incubator/heraldry/libraries/python/openid/trunk/openid/consumer/parse.py
    incubator/heraldry/libraries/python/openid/trunk/openid/cryptutil.py
    incubator/heraldry/libraries/python/openid/trunk/openid/dh.py
    incubator/heraldry/libraries/python/openid/trunk/openid/kvform.py
    incubator/heraldry/libraries/python/openid/trunk/openid/oidutil.py
    incubator/heraldry/libraries/python/openid/trunk/openid/server/
    incubator/heraldry/libraries/python/openid/trunk/openid/server/__init__.py
    incubator/heraldry/libraries/python/openid/trunk/openid/server/server.py
    incubator/heraldry/libraries/python/openid/trunk/openid/server/trustroot.py
    incubator/heraldry/libraries/python/openid/trunk/openid/store/
    incubator/heraldry/libraries/python/openid/trunk/openid/store/__init__.py
    incubator/heraldry/libraries/python/openid/trunk/openid/store/dumbstore.py
    incubator/heraldry/libraries/python/openid/trunk/openid/store/filestore.py
    incubator/heraldry/libraries/python/openid/trunk/openid/store/interface.py
    incubator/heraldry/libraries/python/openid/trunk/openid/store/sqlstore.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/
    incubator/heraldry/libraries/python/openid/trunk/openid/test/__init__.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/_memstore.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/association.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/consumer.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/cryptutil.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/datadriven.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/dh.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/dhpriv
    incubator/heraldry/libraries/python/openid/trunk/openid/test/kvform.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/linkparse.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/linkparse.txt
    incubator/heraldry/libraries/python/openid/trunk/openid/test/n2b64
    incubator/heraldry/libraries/python/openid/trunk/openid/test/oidutil.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/server.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/storetest.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/test_discover.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/test_htmldiscover.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/test_openidyadis.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/trustroot.py
    incubator/heraldry/libraries/python/openid/trunk/openid/test/trustroot.txt
    incubator/heraldry/libraries/python/openid/trunk/setup.cfg
    incubator/heraldry/libraries/python/openid/trunk/setup.py

Added: incubator/heraldry/libraries/python/openid/trunk/COPYING
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/COPYING?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/COPYING (added)
+++ incubator/heraldry/libraries/python/openid/trunk/COPYING Wed Oct 11 16:11:47 2006
@@ -0,0 +1,21 @@
+Python OpenID - OpenID consumer and server library
+
+Copyright (C) 2005, 2006 Janrain, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+More info about Python OpenID:
+openid@janrain.com
+http://www.openidenabled.com/openid/libraries/python

Added: incubator/heraldry/libraries/python/openid/trunk/INSTALL
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/INSTALL?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/INSTALL (added)
+++ incubator/heraldry/libraries/python/openid/trunk/INSTALL Wed Oct 11 16:11:47 2006
@@ -0,0 +1,7 @@
+INSTALLATION
+============
+
+To install the base library, just run the following command:
+
+python setup.py install
+

Added: incubator/heraldry/libraries/python/openid/trunk/MANIFEST.in
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/MANIFEST.in?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/MANIFEST.in (added)
+++ incubator/heraldry/libraries/python/openid/trunk/MANIFEST.in Wed Oct 11 16:11:47 2006
@@ -0,0 +1,5 @@
+include COPYING INSTALL CHANGELOG MANIFEST.in NEWS
+graft admin
+recursive-include examples README *.py
+recursive-include openid/test dhpriv linkparse.txt n2b64 trustroot.txt *.py
+recursive-include doc *.css *.html

Added: incubator/heraldry/libraries/python/openid/trunk/NEWS
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/NEWS?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/NEWS (added)
+++ incubator/heraldry/libraries/python/openid/trunk/NEWS Wed Oct 11 16:11:47 2006
@@ -0,0 +1,142 @@
+What's New in Python OpenID 1.1.2
+=================================
+
+i-name Support
+--------------
+
+This version of the library allows the use of XRI as OpenID identifiers,
+allowing users to log in with their i-names.  For full XRI compatibility,
+relying parties integrating this library should take note of the user's
+CanonicalID, as described in the "Identifying the End User" section of the
+OpenID 2.0 specification.
+
+Bug Fixes
+---------
+
+A variety of bug fixes were included in this release, mostly relating to
+international issues such as dealing with other character sets, Unicode,
+incorrectly flagging certain Norwegian trust roots as suspect, and operation
+of the filesystem-backed store on exotic platforms.
+
+Dependencies
+------------
+
+ * urljr 1.0.1
+ * yadis 1.1.0
+
+
+What's New in Python OpenID 1.1.0
+=================================
+
+Version 1.1 of the Python OpenID library implements recent changes to
+the OpenID specification as well as making API changes that should
+make integration with applications easier.
+
+Yadis Support
+-------------
+
+One of the major changes to OpenID since the last release has been the
+approval of Yadis discovery as the preferred way to specify the OpenID
+metadata for an identity URL instead of using <link> tags in
+HTML. This library does Yadis discovery, and if that fails, it falls
+back to old-style discovery.
+
+Some advantages of Yadis support are:
+
+ * Support for fallback if your primary OpenID provider is not available
+
+ * Support for load-balancing between OpenID servers
+
+ * Easy interoperability for different identity services
+
+For more information about Yadis, see http://yadis.org/ or
+http://www.openidenabled.com/yadis/
+
+Extension Support
+-----------------
+
+OpenID also has formalized support for extensions. Extensions are a
+mechanism for transferring information from the consumer to the server
+and from the server to the consumer in the process of performing
+OpenID authentication. Extensions are implemented as additional
+namespaced query arguments that go along with standard OpenID requests
+and responses. This library provides a simple API for adding extension
+arguments to requests and extracting extension responses from replies.
+
+Dependencies
+------------
+
+These dependencies should be available from wherever you acquired the
+OpenID library.
+
+ * urljr - The fetcher abstraction from the previous OpenID library
+   has been extended and is also used for the Yadis library. Because
+   the Yadis library is useful without the OpenID library, the HTTP
+   fetching code has been rolled into its own package. Additionally,
+   the library now has the concept of a default fetcher to make APIs
+   simpler.
+
+ * yadis - The Yadis library provides a general discovery layer that
+   has been adopted by OpenID as well as other identity-related
+   protocols. Most OpenID identity URLs will work without the Yadis
+   library, but as time goes on, this library will be more and more
+   important.
+
+Consumer API
+------------
+
+The consumer API has been changed for more natural use as well as to
+support extension arguments.
+
+ * OpenIDConsumer(store, [fetcher], [immediate]) is now
+   Consumer(session, store)
+
+  - The session object is a dictionary-like object that should be
+    tied to the requesting HTTP agent, for example, using a session
+    ID cookie. It is used for Yadis fallback and holding the state
+    of the OpenID transaction between the redirect to the server
+    and the response. The values that are placed in the session are
+    namespaced, so there should not be a conflict with other uses
+    of the same session. The session namespace is an attribute of
+    the Consumer object.
+
+  - Because the consumer object now does session management, it is
+    necessary to construct a new consumer object for every
+    request. Creating consumer objects is light-weight.
+
+ * OpenIDConsumer.beginAuth(user_url) is now Consumer.begin(user_url)
+   and either returns an AuthRequest object or raises an
+   exception. There is no more tuple unpacking or status codes.
+
+ * OpenIDConsumer.constructRedirect(authreq, return_to, trust_root) is
+   now AuthRequest.redirectURL(trust_root, return_to, [immediate]).
+
+ * OpenIDConsumer.completeAuth(token, query) is now
+   Consumer.complete(query). It no longer returns a tuple. Instead it
+   returns an object that has a status code and additional information
+   about the response. See the API documentation for more information.
+
+Server API
+----------
+
+The server API has been changed for greater extensibility.  Instead
+of taking an "is_authorized" callback, processing happens in several
+stages, allowing you to insert extension data into the response
+before it is signed and returned.  See the documentation for the
+openid.server.server module.
+
+Fetcher API
+-----------
+
+ * fetcher was openid.consumer.fetchers.OpenIDHTTPFetcher, is now
+   urljr.fetchers.HTTPFetcher.  get() and post() have been replaced by
+   fetch(), see urljr.fetchers for details.
+
+Upgrading
+---------
+
+The server changed the way it indexes associations in the store, so if
+you're upgrading a server installation, we recommend you clear the old
+records from your store when you do so.  As a consequence, consumers
+will re-establish associations with your server a little sooner than
+they would have otherwise.

Added: incubator/heraldry/libraries/python/openid/trunk/README
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/README?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/README (added)
+++ incubator/heraldry/libraries/python/openid/trunk/README Wed Oct 11 16:11:47 2006
@@ -0,0 +1,36 @@
+This is the Python OpenID library.
+
+
+INSTALLATION
+============
+
+To install the base library, just run the following command:
+
+python setup.py install
+
+
+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.
+
+
+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
+dev@lists.openidenabled.com.
+

Added: incubator/heraldry/libraries/python/openid/trunk/admin/combo-setup.py
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/admin/combo-setup.py?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/admin/combo-setup.py (added)
+++ incubator/heraldry/libraries/python/openid/trunk/admin/combo-setup.py Wed Oct 11 16:11:47 2006
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+
+# based on Twisted/admin/sumo-setup.py, (c) Twisted Matrix Laboratories,
+# licensed BSD-style.
+# modified May 2006 by JanRain, Inc.
+
+"""
+Distutils-launcher for OpenID and dependencies.
+"""
+
+import sys, os, glob
+
+subprojects = [
+    'urljr',
+    'yadis',
+    'openid',
+    ]
+
+
+def runInDir(dir, f, *args, **kw):
+    origdir = os.path.abspath('.')
+    os.chdir(dir)
+    try:
+        return f(*args, **kw)
+    finally:
+        os.chdir(origdir)
+
+def runSetup(project, args):
+    dir = getProjDir(project)
+
+    setupPy = os.path.join(dir, 'setup.py')
+    if not os.path.exists(setupPy):
+        sys.stderr.write("Error: No such project '%s'.\n" % (project,))
+        sys.stderr.write(" (File '%s' not found)\n" % (setupPy,))
+        sys.exit(1)
+
+    result = runInDir(dir, os.spawnv,
+                          os.P_WAIT, sys.executable,
+                          [sys.executable, 'setup.py'] + args)
+    if result != 0:
+        sys.stderr.write("Error: Subprocess exited with result %d for project %s\n" %
+                         (result, project))
+        sys.exit(1)
+
+
+def getProjDir(proj):
+    globst = 'python-%s-*' % (proj,)
+    gl = glob.glob(globst)
+    assert len(gl) == 1, 'Wrong number of %s found!?' % (proj,)
+    dir = gl[0]
+    return dir
+
+def printProjectInfo(out=sys.stdout):
+    out.write(
+"""Python OpenID packages
+Usage: setup.py <project> <distutils args...>
+       setup.py all <distutils args..>
+
+E.g. setup.py all install
+or   setup.py core --help
+
+""")
+    out.write("%-10s %-10s\n" % ("Project", "Version"))
+
+    for project in subprojects:
+        dir = getProjDir(project)
+        ver = dir.split('-')[-1]
+        out.write(" %-10s %-10s\n" % (project, ver))
+
+
+def main(args):
+    os.environ["PYTHONPATH"] = "." + os.pathsep + os.getenv("PYTHONPATH", "")
+    if len(args) == 0 or args[0] in ('-h', '--help'):
+        printProjectInfo()
+        sys.exit(0)
+
+    # if it's not a project name, it's a command name
+    if args[0] not in ['all'] + subprojects:
+        project = 'all'
+    else:
+        project = args[0]
+        args = args[1:]
+
+    if project == 'all':
+        for project in subprojects:
+            runSetup(project, args)
+    else:
+        runSetup(project, args)
+
+if __name__ == "__main__":
+    try:
+        main(sys.argv[1:])
+    except KeyboardInterrupt:
+        sys.exit(1)

Propchange: incubator/heraldry/libraries/python/openid/trunk/admin/combo-setup.py
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/admin/makechangelog
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/admin/makechangelog?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/admin/makechangelog (added)
+++ incubator/heraldry/libraries/python/openid/trunk/admin/makechangelog Wed Oct 11 16:11:47 2006
@@ -0,0 +1,2 @@
+#!/bin/bash
+darcs changes --from-tag '^release-' --summary > CHANGELOG

Propchange: incubator/heraldry/libraries/python/openid/trunk/admin/makechangelog
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/admin/makedoc
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/admin/makedoc?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/admin/makedoc (added)
+++ incubator/heraldry/libraries/python/openid/trunk/admin/makedoc Wed Oct 11 16:11:47 2006
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+rm -rf doc/*
+epydoc --html --output doc/ --name "Python-OpenID" --top openid \
+    --url "http://www.openidenabled.com/" --inheritance listed \
+    --ignore-param-mismatch --no-private \
+    openid/__init__.py \
+    openid/dh.py \
+    openid/association.py \
+    openid/consumer/__init__.py \
+    openid/consumer/consumer.py \
+    openid/consumer/discover.py \
+    openid/server/__init__.py \
+    openid/server/server.py \
+    openid/server/trustroot.py \
+    openid/store/__init__.py \
+    openid/store/interface.py \
+    openid/store/filestore.py \
+    openid/store/dumbstore.py \
+    openid/store/sqlstore.py

Propchange: incubator/heraldry/libraries/python/openid/trunk/admin/makedoc
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/admin/runtests
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/admin/runtests?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/admin/runtests (added)
+++ incubator/heraldry/libraries/python/openid/trunk/admin/runtests Wed Oct 11 16:11:47 2006
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+import sys
+
+test_modules = [
+    'cryptutil',
+    'storetest',
+    'oidutil',
+    'dh',
+    ]
+
+def fixpath():
+    import os.path
+    try:
+        d = os.path.dirname(__file__)
+    except NameError:
+        d = os.path.dirname(sys.argv[0])
+    parent = os.path.normpath(os.path.join(d, '..'))
+    if parent not in sys.path:
+        print "putting %s in sys.path" % (parent,)
+        sys.path.insert(0, parent)
+
+def otherTests():
+    failed = []
+    for module_name in test_modules:
+        print 'Testing %s...' % (module_name,) ,
+        sys.stdout.flush()
+        module_name = 'openid.test.' + module_name
+        try:
+            test_mod = __import__(module_name, {}, {}, [None])
+        except ImportError:
+            print 'Failed to import test %r' % (module_name,)
+            failed.append(module_name)
+        else:
+            try:
+                test_mod.test()
+            except (SystemExit, KeyboardInterrupt):
+                raise
+            except:
+                sys.excepthook(*sys.exc_info())
+                failed.append(module_name)
+            else:
+                print 'Succeeded.'
+
+
+    return failed
+
+def pyunitTests():
+    import unittest
+    from openid.test import test_htmldiscover
+    from openid.test import test_openidyadis
+    from openid.test import test_discover
+    from openid.test import consumer
+    from openid.test import kvform
+    from openid.test import server
+    from openid.test import oidutil
+    from openid.test import linkparse
+    from openid.test import trustroot
+    from openid.test import association
+
+    pyunit_modules = [
+        server,
+        consumer,
+        association,
+        ]
+
+    # Some modules have data-driven tests, and they use custom methods
+    # to build the test suite:
+    custom_modules = [
+        oidutil,
+        linkparse,
+        trustroot,
+        test_openidyadis,
+        test_discover,
+        test_htmldiscover,
+        kvform,
+        ]
+
+    loader = unittest.TestLoader()
+    s = unittest.TestSuite()
+
+    for m in pyunit_modules:
+        s.addTest(loader.loadTestsFromModule(m))
+
+    for m in custom_modules:
+        s.addTest(m.pyUnitTests())
+
+    runner = unittest.TextTestRunner() # verbosity=2)
+
+    return runner.run(s)
+
+
+try:
+    bool
+except NameError:
+    def bool(x):
+        return not not x
+
+def main():
+    fixpath()
+    other_failed = otherTests()
+    pyunit_result = pyunitTests()
+
+    if other_failed:
+        print 'Failures:', ', '.join(other_failed)
+
+    failed = bool(other_failed) or bool(not pyunit_result.wasSuccessful())
+    return failed
+
+if __name__ == '__main__':
+    sys.exit(main() and 1 or 0)

Propchange: incubator/heraldry/libraries/python/openid/trunk/admin/runtests
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/admin/setversion
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/admin/setversion?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/admin/setversion (added)
+++ incubator/heraldry/libraries/python/openid/trunk/admin/setversion Wed Oct 11 16:11:47 2006
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+cat <<EOF | \
+    xargs sed -i 's/\[library version:[^]]*\]/[library version:'"$1"']/'
+setup.py
+openid/__init__.py
+EOF

Propchange: incubator/heraldry/libraries/python/openid/trunk/admin/setversion
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/admin/tagrelease
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/admin/tagrelease?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/admin/tagrelease (added)
+++ incubator/heraldry/libraries/python/openid/trunk/admin/tagrelease Wed Oct 11 16:11:47 2006
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+VERSION="$1"
+VERSION_PATTERN='^[0-9]\+\.[0-9]\+\.[0-9]\+\(-[a-z0-9-]\+\)\?$'
+
+echo "$VERSION" | grep -e "$VERSION_PATTERN" 2>&1 >/dev/null || {
+    echo "$VERSION"
+    echo "Malformed version number. Expected X.X.X or X.X.X-name." 1>&2
+    exit 1
+}
+
+cd $(dirname $(dirname $(readlink --canonicalize "$0")))
+./admin/setversion "$VERSION"
+darcs record -m 'Set version number to '"$VERSION" && darcs tag "release-$VERSION"

Propchange: incubator/heraldry/libraries/python/openid/trunk/admin/tagrelease
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/darcs-ignore
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/darcs-ignore?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/darcs-ignore (added)
+++ incubator/heraldry/libraries/python/openid/trunk/darcs-ignore Wed Oct 11 16:11:47 2006
@@ -0,0 +1,40 @@
+# Boring file regexps:
+\.hi$
+\.o$
+\.o\.cmd$
+\.ko$
+\.ko\.cmd$
+\.mod\.c$
+(^|/)\.tmp_versions($|/)
+(^|/)CVS($|/)
+(^|/)RCS($|/)
+~$
+#(^|/)\.[^/]
+(^|/)_darcs($|/)
+\.bak$
+\.BAK$
+\.orig$
+(^|/)vssver\.scc$
+\.swp$
+(^|/)MT($|/)
+(^|/)\{arch\}($|/)
+(^|/).arch-ids($|/)
+(^|/),
+\.class$
+\.prof$
+(^|/)\.DS_Store$
+(^|/)BitKeeper($|/)
+(^|/)ChangeSet($|/)
+(^|/)\.svn($|/)
+\.py[co]$
+\#
+\.cvsignore$
+(^|/)Thumbs\.db$
+^doc/
+^MANIFEST$
+^CHANGELOG$
+^dist$
+(^|/)sstore$
+(^|/)cstore$
+^build$
+(^|/)_trial_temp($|/)

Added: incubator/heraldry/libraries/python/openid/trunk/examples/README
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/examples/README?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/examples/README (added)
+++ incubator/heraldry/libraries/python/openid/trunk/examples/README Wed Oct 11 16:11:47 2006
@@ -0,0 +1,58 @@
+The examples directory contains a working server and consumer that use
+the openid libraries.  They are both written using python's standard
+BaseHTTPServer.
+
+
+To run the example system:
+
+1. Make sure you've installed the library, as explained in the
+   installation instructions.
+
+2. Start the consumer server:
+
+        python consumer.py --port 8001
+
+
+3. In another terminal, start the identity server:
+
+        python server.py --port 8000
+
+   (Hit Ctrl-C in either server's window to stop that server.)
+
+
+4. Open your web broswer, and go to the consumer server:
+
+        http://localhost:8001/
+
+   Note that all pages the consumer server shows will have "Python OpenID
+   Consumer Example" across the top.
+
+
+5. Enter an identity url managed by the sample identity server:
+
+        http://localhost:8000/bob
+
+
+6. The browser will be redirected to the sample server, which will be
+   requesting that you log in to proceed.  Enter the username for the
+   identity URL into the login box:
+
+        bob
+
+   Note that all pages the identity server shows will have "Python
+   OpenID Server Example" across the top.
+
+
+7. After you log in as bob, the server example will ask you if you
+   want to allow http://localhost:8001/ to know your identity.  Say
+   yes.
+
+
+8. You should end up back on the consumer site, at a page indicating
+   you've logged in successfully.
+
+
+That's a basic OpenID login procedure.  You can continue through it,
+playing with variations to see how they work.  The python code is
+intended to be a straightforward example of how to use the python
+OpenID library to function as either an identity server or consumer.
\ No newline at end of file

Added: incubator/heraldry/libraries/python/openid/trunk/examples/__init__.py
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/examples/__init__.py?view=auto&rev=463041
==============================================================================
    (empty)

Added: incubator/heraldry/libraries/python/openid/trunk/examples/consumer.py
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/examples/consumer.py?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/examples/consumer.py (added)
+++ incubator/heraldry/libraries/python/openid/trunk/examples/consumer.py Wed Oct 11 16:11:47 2006
@@ -0,0 +1,380 @@
+#!/usr/bin/env python
+"""
+Simple example for an OpenID consumer.
+
+Once you understand this example you'll know the basics of OpenID
+and using the Python OpenID library. You can then move on to more
+robust examples, and integrating OpenID into your application.
+"""
+__copyright__ = 'Copyright 2005, Janrain, Inc.'
+
+from Cookie import SimpleCookie
+import cgi
+import urlparse
+import cgitb
+import sys
+
+def quoteattr(s):
+    qs = cgi.escape(s, 1)
+    return '"%s"' % (qs,)
+
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+
+try:
+    import openid
+except ImportError:
+    print >>sys.stderr, """
+Failed to import the OpenID library. In order to use this example, you
+must either install the library (see INSTALL in the root of the
+distribution) or else add the library to python's import path (the
+PYTHONPATH environment variable).
+
+For more information, see the README in the root of the library
+distribution or http://www.openidenabled.com/
+"""
+    sys.exit(1)
+
+from openid.store import filestore
+from openid.consumer import consumer
+from openid.oidutil import appendArgs
+from openid.cryptutil import randomString
+from yadis.discover import DiscoveryFailure
+from urljr.fetchers import HTTPFetchingError
+
+class OpenIDHTTPServer(HTTPServer):
+    """http server that contains a reference to an OpenID consumer and
+    knows its base URL.
+    """
+    def __init__(self, store, *args, **kwargs):
+        HTTPServer.__init__(self, *args, **kwargs)
+        self.sessions = {}
+        self.store = store
+
+        if self.server_port != 80:
+            self.base_url = ('http://%s:%s/' %
+                             (self.server_name, self.server_port))
+        else:
+            self.base_url = 'http://%s/' % (self.server_name,)
+
+class OpenIDRequestHandler(BaseHTTPRequestHandler):
+    """Request handler that knows how to verify an OpenID identity."""
+    SESSION_COOKIE_NAME = 'pyoidconsexsid'
+
+    session = None
+
+    def getConsumer(self):
+        return consumer.Consumer(self.getSession(), self.server.store)
+
+    def getSession(self):
+        """Return the existing session or a new session"""
+        if self.session is not None:
+            return self.session
+
+        # Get value of cookie header that was sent
+        cookie_str = self.headers.get('Cookie')
+        if cookie_str:
+            cookie_obj = SimpleCookie(cookie_str)
+            sid_morsel = cookie_obj.get(self.SESSION_COOKIE_NAME, None)
+            if sid_morsel is not None:
+                sid = sid_morsel.value
+            else:
+                sid = None
+        else:
+            sid = None
+
+        # If a session id was not set, create a new one
+        if sid is None:
+            sid = randomString(16, '0123456789abcdef')
+            session = None
+        else:
+            session = self.server.sessions.get(sid)
+
+        # If no session exists for this session ID, create one
+        if session is None:
+            session = self.server.sessions[sid] = {}
+
+        session['id'] = sid
+        self.session = session
+        return session
+
+    def setSessionCookie(self):
+        sid = self.getSession()['id']
+        session_cookie = '%s=%s;' % (self.SESSION_COOKIE_NAME, sid)
+        self.send_header('Set-Cookie', session_cookie)
+
+    def do_GET(self):
+        """Dispatching logic. There are three paths defined:
+
+          / - Display an empty form asking for an identity URL to
+              verify
+          /verify - Handle form submission, initiating OpenID verification
+          /process - Handle a redirect from an OpenID server
+
+        Any other path gets a 404 response. This function also parses
+        the query parameters.
+
+        If an exception occurs in this function, a traceback is
+        written to the requesting browser.
+        """
+        try:
+            self.parsed_uri = urlparse.urlparse(self.path)
+            self.query = {}
+            for k, v in cgi.parse_qsl(self.parsed_uri[4]):
+                self.query[k] = v
+
+            path = self.parsed_uri[2]
+            if path == '/':
+                self.render()
+            elif path == '/verify':
+                self.doVerify()
+            elif path == '/process':
+                self.doProcess()
+            else:
+                self.notFound()
+
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.send_response(500)
+            self.send_header('Content-type', 'text/html')
+            self.setSessionCookie()
+            self.end_headers()
+            self.wfile.write(cgitb.html(sys.exc_info(), context=10))
+
+    def doVerify(self):
+        """Process the form submission, initating OpenID verification.
+        """
+
+        # First, make sure that the user entered something
+        openid_url = self.query.get('openid_url')
+        if not openid_url:
+            self.render('Enter an OpenID Identifier to verify.',
+                        css_class='error', form_contents=openid_url)
+            return
+
+        oidconsumer = self.getConsumer()
+        try:
+            request = oidconsumer.begin(openid_url)
+        except HTTPFetchingError, exc:
+            fetch_error_string = 'Error in discovery: %s' % (
+                cgi.escape(str(exc.why)))
+            self.render(fetch_error_string,
+                        css_class='error',
+                        form_contents=openid_url)
+        except DiscoveryFailure, exc:
+            fetch_error_string = 'Error in discovery: %s' % (
+                cgi.escape(str(exc[0])))
+            self.render(fetch_error_string,
+                        css_class='error',
+                        form_contents=openid_url)
+        else:
+            if request is None:
+                msg = 'No OpenID services found for <code>%s</code>' % (
+                    cgi.escape(openid_url),)
+                self.render(msg, css_class='error', form_contents=openid_url)
+            else:
+                # Then, ask the library to begin the authorization.
+                # Here we find out the identity server that will verify the
+                # user's identity, and get a token that allows us to
+                # communicate securely with the identity server.
+
+                trust_root = self.server.base_url
+                return_to = self.buildURL('process')
+                redirect_url = request.redirectURL(trust_root, return_to)
+
+                self.redirect(redirect_url)
+
+    def doProcess(self):
+        """Handle the redirect from the OpenID server.
+        """
+        oidconsumer = self.getConsumer()
+
+        # Ask the library to check the response that the server sent
+        # us.  Status is a code indicating the response type. info is
+        # either None or a string containing more information about
+        # the return type.
+        info = oidconsumer.complete(self.query)
+
+        css_class = 'error'
+        if info.status == consumer.FAILURE and info.identity_url:
+            # In the case of failure, if info is non-None, it is the
+            # URL that we were verifying. We include it in the error
+            # message to help the user figure out what happened.
+            fmt = "Verification of %s failed."
+            message = fmt % (cgi.escape(info.identity_url),)
+        elif info.status == consumer.SUCCESS:
+            # Success means that the transaction completed without
+            # error. If info is None, it means that the user cancelled
+            # the verification.
+            css_class = 'alert'
+
+            # This is a successful verification attempt. If this
+            # was a real application, we would do our login,
+            # comment posting, etc. here.
+            fmt = "You have successfully verified %s as your identity."
+            message = fmt % (cgi.escape(info.identity_url),)
+            if info.endpoint.canonicalID:
+                # You should authorize i-name users by their canonicalID,
+                # rather than their more human-friendly identifiers.  That
+                # way their account with you is not compromised if their
+                # i-name registration expires and is bought by someone else.
+                message += ("  This is an i-name, and its persistent ID is %s"
+                            % (cgi.escape(info.endpoint.canonicalID),))
+        elif info.status == consumer.CANCEL:
+            # cancelled
+            message = 'Verification cancelled'
+        else:
+            # Either we don't understand the code or there is no
+            # openid_url included with the error. Give a generic
+            # failure message. The library should supply debug
+            # information in a log.
+            message = 'Verification failed.'
+
+        self.render(message, css_class, info.identity_url)
+
+    def buildURL(self, action, **query):
+        """Build a URL relative to the server base_url, with the given
+        query parameters added."""
+        base = urlparse.urljoin(self.server.base_url, action)
+        return appendArgs(base, query)
+
+    def redirect(self, redirect_url):
+        """Send a redirect response to the given URL to the browser."""
+        response = """\
+Location: %s
+Content-type: text/plain
+
+Redirecting to %s""" % (redirect_url, redirect_url)
+        self.send_response(302)
+        self.setSessionCookie()
+        self.wfile.write(response)
+
+    def notFound(self):
+        """Render a page with a 404 return code and a message."""
+        fmt = 'The path <q>%s</q> was not understood by this server.'
+        msg = fmt % (self.path,)
+        openid_url = self.query.get('openid_url')
+        self.render(msg, 'error', openid_url, status=404)
+
+    def render(self, message=None, css_class='alert', form_contents=None,
+               status=200, title="Python OpenID Consumer Example"):
+        """Render a page."""
+        self.send_response(status)
+        self.pageHeader(title)
+        if message:
+            self.wfile.write("<div class='%s'>" % (css_class,))
+            self.wfile.write(message)
+            self.wfile.write("</div>")
+        self.pageFooter(form_contents)
+
+    def pageHeader(self, title):
+        """Render the page header"""
+        self.setSessionCookie()
+        self.wfile.write('''\
+Content-type: text/html
+
+<html>
+  <head><title>%s</title></head>
+  <style type="text/css">
+      * {
+        font-family: verdana,sans-serif;
+      }
+      body {
+        width: 50em;
+        margin: 1em;
+      }
+      div {
+        padding: .5em;
+      }
+      table {
+        margin: none;
+        padding: none;
+      }
+      .alert {
+        border: 1px solid #e7dc2b;
+        background: #fff888;
+      }
+      .error {
+        border: 1px solid #ff0000;
+        background: #ffaaaa;
+      }
+      #verify-form {
+        border: 1px solid #777777;
+        background: #dddddd;
+        margin-top: 1em;
+        padding-bottom: 0em;
+      }
+  </style>
+  <body>
+    <h1>%s</h1>
+    <p>
+      This example consumer uses the <a href=
+      "http://www.openidenabled.com/openid/libraries/python" >Python
+      OpenID</a> library. It just verifies that the identifier that you enter
+      is your identifier.
+    </p>
+''' % (title, title))
+
+    def pageFooter(self, form_contents):
+        """Render the page footer"""
+        if not form_contents:
+            form_contents = ''
+
+        self.wfile.write('''\
+    <div id="verify-form">
+      <form method="get" action=%s>
+        Identifier:
+        <input type="text" name="openid_url" value=%s />
+        <input type="submit" value="Verify" />
+      </form>
+    </div>
+  </body>
+</html>
+''' % (quoteattr(self.buildURL('verify')), quoteattr(form_contents)))
+
+def main(host, port, data_path):
+    # Instantiate OpenID consumer store and OpenID consumer.  If you
+    # were connecting to a database, you would create the database
+    # connection and instantiate an appropriate store here.
+    store = filestore.FileOpenIDStore(data_path)
+
+    addr = (host, port)
+    server = OpenIDHTTPServer(store, addr, OpenIDRequestHandler)
+
+    print 'Server running at:'
+    print server.base_url
+    server.serve_forever()
+
+if __name__ == '__main__':
+    host = 'localhost'
+    data_path = 'cstore'
+    port = 8001
+
+    try:
+        import optparse
+    except ImportError:
+        pass # Use defaults (for Python 2.2)
+    else:
+        parser = optparse.OptionParser('Usage:\n %prog [options]')
+        parser.add_option(
+            '-d', '--data-path', dest='data_path', default=data_path,
+            help='Data directory for storing OpenID consumer state. '
+            'Defaults to "%default" in the current directory.')
+        parser.add_option(
+            '-p', '--port', dest='port', type='int', default=port,
+            help='Port on which to listen for HTTP requests. '
+            'Defaults to port %default.')
+        parser.add_option(
+            '-s', '--host', dest='host', default=host,
+            help='Host on which to listen for HTTP requests. '
+            'Also used for generating URLs. Defaults to %default.')
+
+        options, args = parser.parse_args()
+        if args:
+            parser.error('Expected no arguments. Got %r' % args)
+
+        host = options.host
+        port = options.port
+        data_path = options.data_path
+
+    main(host, port, data_path)

Propchange: incubator/heraldry/libraries/python/openid/trunk/examples/consumer.py
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/examples/server.py
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/examples/server.py?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/examples/server.py (added)
+++ incubator/heraldry/libraries/python/openid/trunk/examples/server.py Wed Oct 11 16:11:47 2006
@@ -0,0 +1,610 @@
+#!/usr/bin/env python
+
+__copyright__ = 'Copyright 2005, Janrain, Inc.'
+
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from urlparse import urlparse
+
+import time
+import Cookie
+import cgi
+import cgitb
+import sys
+
+def quoteattr(s):
+    qs = cgi.escape(s, 1)
+    return '"%s"' % (qs,)
+
+try:
+    import openid
+except ImportError:
+    print >>sys.stderr, """
+Failed to import the OpenID library. In order to use this example, you
+must either install the library (see INSTALL in the root of the
+distribution) or else add the library to python's import path (the
+PYTHONPATH environment variable).
+
+For more information, see the README in the root of the library
+distribution or http://www.openidenabled.com/
+"""
+    sys.exit(1)
+
+from openid import oidutil
+from openid.server import server
+from openid.store.filestore import FileOpenIDStore
+
+class OpenIDHTTPServer(HTTPServer):
+    """
+    http server that contains a reference to an OpenID Server and
+    knows its base URL.
+    """
+    def __init__(self, oidserver, *args, **kwargs):
+        HTTPServer.__init__(self, *args, **kwargs)
+
+        if self.server_port != 80:
+            self.base_url = ('http://%s:%s/' %
+                             (self.server_name, self.server_port))
+        else:
+            self.base_url = 'http://%s/' % (self.server_name,)
+
+        self.openid = oidserver
+        self.approved = {}
+        self.lastCheckIDRequest = {}
+
+class ServerHandler(BaseHTTPRequestHandler):
+    def __init__(self, *args, **kwargs):
+        self.user = None
+        BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
+
+
+    def do_GET(self):
+        try:
+            self.parsed_uri = urlparse(self.path)
+            self.query = {}
+            for k, v in cgi.parse_qsl(self.parsed_uri[4]):
+                self.query[k] = v
+
+            self.setUser()
+
+            path = self.parsed_uri[2].lower()
+
+            if path == '/':
+                self.showMainPage()
+            elif path == '/openidserver':
+                self.serverEndPoint(self.query)
+
+            elif path == '/login':
+                self.showLoginPage('/', '/')
+            elif path == '/loginsubmit':
+                self.doLogin()
+            else:
+                self.showIdPage(path)
+
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.send_response(500)
+            self.send_header('Content-type', 'text/html')
+            self.end_headers()
+            self.wfile.write(cgitb.html(sys.exc_info(), context=10))
+
+    def do_POST(self):
+        try:
+            self.parsed_uri = urlparse(self.path)
+
+            self.setUser()
+            content_length = int(self.headers['Content-Length'])
+            post_data = self.rfile.read(content_length)
+
+            self.query = {}
+            for k, v in cgi.parse_qsl(post_data):
+                self.query[k] = v
+
+            path = self.parsed_uri[2]
+            if path == '/openidserver':
+                self.serverEndPoint(self.query)
+
+            elif path == '/allow':
+                self.handleAllow(self.query)
+            else:
+                self.send_response(404)
+                self.end_headers()
+
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except:
+            self.send_response(500)
+            self.send_header('Content-type', 'text/html')
+            self.end_headers()
+            self.wfile.write(cgitb.html(sys.exc_info(), context=10))
+
+    def handleAllow(self, query):
+        # pretend this next bit is keying off the user's session or something,
+        # right?
+        request = self.server.lastCheckIDRequest.get(self.user)
+
+        if 'yes' in query:
+            identity = request.identity
+            trust_root = request.trust_root
+            if self.query.get('remember', 'no') == 'yes':
+                duration = 'always'
+            else:
+                duration = 'once'
+
+            self.server.approved[(identity, trust_root)] = duration
+
+            if 'login_as' in query:
+                self.user = self.query['login_as']
+
+            response = request.answer(True)
+
+        elif 'no' in query:
+            response = request.answer(False)
+
+        else:
+            assert False, 'strange allow post.  %r' % (query,)
+
+        self.displayResponse(response)
+
+
+    def setUser(self):
+        cookies = self.headers.get('Cookie')
+        if cookies:
+            morsel = Cookie.BaseCookie(cookies).get('user')
+            if morsel:
+                self.user = morsel.value
+
+    def isAuthorized(self, identity_url, trust_root):
+        if self.user is None:
+            return False
+
+        if identity_url != self.server.base_url + self.user:
+            return False
+
+        key = (identity_url, trust_root)
+        approval = self.server.approved.get(key)
+        if approval == 'once':
+            del self.server.approved[key]
+
+        return approval is not None
+
+    def serverEndPoint(self, query):
+        try:
+            request = self.server.openid.decodeRequest(query)
+        except server.ProtocolError, why:
+            self.displayResponse(why)
+            return
+
+        if request is None:
+            # Display text indicating that this is an endpoint.
+            self.showAboutPage()
+            return
+
+        if request.mode in ["checkid_immediate", "checkid_setup"]:
+            if (self.user and
+                self.isAuthorized(request.identity, request.trust_root)):
+                response = request.answer(True)
+            elif request.immediate:
+                response = request.answer(
+                    False, server_url=self.server.base_url + 'openidserver')
+            else:
+                self.server.lastCheckIDRequest[self.user] = request
+                self.showDecidePage(request)
+                return
+        else:
+            response = self.server.openid.handleRequest(request)
+        self.displayResponse(response)
+
+    def displayResponse(self, response):
+        try:
+            webresponse = self.server.openid.encodeResponse(response)
+        except server.EncodingError, why:
+            text = why.response.encodeToKVForm()
+            self.showErrorPage('<pre>%s</pre>' % cgi.escape(text))
+            return
+
+        self.send_response(webresponse.code)
+        for header, value in webresponse.headers.iteritems():
+            self.send_header(header, value)
+        self.writeUserHeader()
+        self.end_headers()
+
+        if webresponse.body:
+            self.wfile.write(webresponse.body)
+
+    def doLogin(self):
+        if 'submit' in self.query:
+            if 'user' in self.query:
+                self.user = self.query['user']
+            else:
+                self.user = None
+            self.redirect(self.query['success_to'])
+        elif 'cancel' in self.query:
+            self.redirect(self.query['fail_to'])
+        else:
+            assert 0, 'strange login %r' % (self.query,)
+
+    def redirect(self, url):
+        self.send_response(302)
+        self.send_header('Location', url)
+        self.writeUserHeader()
+
+        self.end_headers()
+
+    def writeUserHeader(self):
+        if self.user is None:
+            t1970 = time.gmtime(0)
+            expires = time.strftime(
+                'Expires=%a, %d-%b-%y %H:%M:%S GMT', t1970)
+            self.send_header('Set-Cookie', 'user=;%s' % expires)
+        else:
+            self.send_header('Set-Cookie', 'user=%s' % self.user)
+
+    def showAboutPage(self):
+        endpoint_url = self.server.base_url + 'openidserver'
+
+        def link(url):
+            url_attr = quoteattr(url)
+            url_text = cgi.escape(url)
+            return '<a href=%s><code>%s</code></a>' % (url_attr, url_text)
+
+        def term(url, text):
+            return '<dt>%s</dt><dd>%s</dd>' % (link(url), text)
+
+        resources = [
+            (self.server.base_url, "This example server's home page"),
+            ('http://www.openidenabled.com/',
+             'An OpenID community Web site, home of this library'),
+            ('http://www.openid.net/', 'the official OpenID Web site'),
+            ]
+
+        resource_markup = ''.join([term(url, text) for url, text in resources])
+
+        self.showPage(200, 'This is an OpenID server', msg="""\
+        <p>%s is an OpenID server endpoint.<p>
+        <p>For more information about OpenID, see:</p>
+        <dl>
+        %s
+        </dl>
+        """ % (link(endpoint_url), resource_markup,))
+
+    def showErrorPage(self, error_message):
+        self.showPage(400, 'Error Processing Request', err='''\
+        <p>%s</p>
+        <!--
+
+        This is a large comment.  It exists to make this page larger.
+        That is unfortunately necessary because of the "smart"
+        handling of pages returned with an error code in IE.
+
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+        *************************************************************
+
+        -->
+        ''' % error_message)
+
+    def showDecidePage(self, request):
+        expected_user = request.identity[len(self.server.base_url):]
+
+        if expected_user == self.user:
+            msg = '''\
+            <p>A new site has asked for your identity.  If you
+            approve, the site represented by the trust root below will
+            be told that you control identity URL listed below. (If
+            you are using a delegated identity, the site will take
+            care of reversing the delegation on its own.)</p>'''
+
+            fdata = {
+                'identity': request.identity,
+                'trust_root': request.trust_root,
+                }
+            form = '''\
+            <table>
+              <tr><td>Identity:</td><td>%(identity)s</td></tr>
+              <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr>
+            </table>
+            <p>Allow this authentication to proceed?</p>
+            <form method="POST" action="/allow">
+              <input type="checkbox" id="remember" name="remember" value="yes"
+                  checked="checked" /><label for="remember">Remember this
+                  decision</label><br />
+              <input type="submit" name="yes" value="yes" />
+              <input type="submit" name="no" value="no" />
+            </form>''' % fdata
+        else:
+            mdata = {
+                'expected_user': expected_user,
+                'user': self.user,
+                }
+            msg = '''\
+            <p>A site has asked for an identity belonging to
+            %(expected_user)s, but you are logged in as %(user)s.  To
+            log in as %(expected_user)s and approve the login request,
+            hit OK below.  The "Remember this decision" checkbox
+            applies only to the trust root decision.</p>''' % mdata
+
+            fdata = {
+                'identity': request.identity,
+                'trust_root': request.trust_root,
+                'expected_user': expected_user,
+                }
+            form = '''\
+            <table>
+              <tr><td>Identity:</td><td>%(identity)s</td></tr>
+              <tr><td>Trust Root:</td><td>%(trust_root)s</td></tr>
+            </table>
+            <p>Allow this authentication to proceed?</p>
+            <form method="POST" action="/allow">
+              <input type="checkbox" id="remember" name="remember" value="yes"
+                  checked="checked" /><label for="remember">Remember this
+                  decision</label><br />
+              <input type="hidden" name="login_as" value="%(expected_user)s"/>
+              <input type="submit" name="yes" value="yes" />
+              <input type="submit" name="no" value="no" />
+            </form>''' % fdata
+
+        self.showPage(200, 'Approve OpenID request?', msg=msg, form=form)
+
+    def showIdPage(self, path):
+        tag = '<link rel="openid.server" href="%sopenidserver">' %\
+              self.server.base_url
+        ident = self.server.base_url + path[1:]
+
+        approved_trust_roots = []
+        for (aident, trust_root) in self.server.approved.keys():
+            if aident == ident:
+                trs = '<li><tt>%s</tt></li>\n' % cgi.escape(trust_root)
+                approved_trust_roots.append(trs)
+
+        if approved_trust_roots:
+            prepend = '<p>Approved trust roots:</p>\n<ul>\n'
+            approved_trust_roots.insert(0, prepend)
+            approved_trust_roots.append('</ul>\n')
+            msg = ''.join(approved_trust_roots)
+        else:
+            msg = ''
+
+        self.showPage(200, 'An Identity Page', link_tag=tag, msg='''\
+        <p>This is an identity page for %s.</p>
+        %s
+        ''' % (ident, msg))
+
+    def showMainPage(self):
+        if self.user:
+            openid_url = self.server.base_url + self.user
+            user_message = """\
+            <p>You are logged in as %s. Your OpenID identity URL is
+            <tt><a href=%s>%s</a></tt>. Enter that URL at an OpenID
+            consumer to test this server.</p>
+            """ % (self.user, quoteattr(openid_url), openid_url)
+        else:
+            user_message = """\
+            <p>This server uses a cookie to remember who you are in
+            order to simulate a standard Web user experience. You are
+            not <a href='/login'>logged in</a>.</p>"""
+
+        self.showPage(200, 'Main Page', msg='''\
+        <p>This is a simple OpenID server implemented using the <a
+        href="http://openid.schtuff.com/">Python OpenID
+        library</a>.</p>
+
+        %s
+
+        <p>To use this server with a consumer, the consumer must be
+        able to fetch HTTP pages from this web server. If this
+        computer is behind a firewall, you will not be able to use
+        OpenID consumers outside of the firewall with it.</p>
+
+        <p>The URL for this server is <a href=%s><tt>%s</tt></a>.</p>
+        ''' % (user_message, quoteattr(self.server.base_url), self.server.base_url))
+
+    def showLoginPage(self, success_to, fail_to):
+        self.showPage(200, 'Login Page', form='''\
+        <h2>Login</h2>
+        <p>You may log in with any name. This server does not use
+        passwords because it is just a sample of how to use the OpenID
+        library.</p>
+        <form method="GET" action="/loginsubmit">
+          <input type="hidden" name="success_to" value="%s" />
+          <input type="hidden" name="fail_to" value="%s" />
+          <input type="text" name="user" value="" />
+          <input type="submit" name="submit" value="Log In" />
+          <input type="submit" name="cancel" value="Cancel" />
+        </form>
+        ''' % (success_to, fail_to))
+
+    def showPage(self, response_code, title,
+                 link_tag='', msg=None, err=None, form=None):
+
+        if self.user is None:
+            user_link = '<a href="/login">not logged in</a>.'
+        else:
+            user_link = 'logged in as <a href="/%s">%s</a>.<br /><a href="/loginsubmit?submit=true&success_to=/login">Log out</a>' % \
+                        (self.user, self.user)
+
+        body = ''
+
+        if err is not None:
+            body +=  '''\
+            <div class="error">
+              %s
+            </div>
+            ''' % err
+
+        if msg is not None:
+            body += '''\
+            <div class="message">
+              %s
+            </div>
+            ''' % msg
+
+        if form is not None:
+            body += '''\
+            <div class="form">
+              %s
+            </div>
+            ''' % form
+
+        contents = {
+            'title': 'Python OpenID Server Example - ' + title,
+            'link_tag': link_tag,
+            'body': body,
+            'user_link': user_link,
+            }
+
+        self.send_response(response_code)
+        self.writeUserHeader()
+
+        self.wfile.write('''\
+Content-type: text/html
+
+<html>
+  <head>
+    <title>%(title)s</title>
+    %(link_tag)s
+  </head>
+  <style type="text/css">
+      h1 a:link {
+          color: black;
+          text-decoration: none;
+      }
+      h1 a:visited {
+          color: black;
+          text-decoration: none;
+      }
+      h1 a:hover {
+          text-decoration: underline;
+      }
+      body {
+        font-family: verdana,sans-serif;
+        width: 50em;
+        margin: 1em;
+      }
+      div {
+        padding: .5em;
+      }
+      table {
+        margin: none;
+        padding: none;
+      }
+      .banner {
+        padding: none 1em 1em 1em;
+        width: 100%%;
+      }
+      .leftbanner {
+        text-align: left;
+      }
+      .rightbanner {
+        text-align: right;
+        font-size: smaller;
+      }
+      .error {
+        border: 1px solid #ff0000;
+        background: #ffaaaa;
+        margin: .5em;
+      }
+      .message {
+        border: 1px solid #2233ff;
+        background: #eeeeff;
+        margin: .5em;
+      }
+      .form {
+        border: 1px solid #777777;
+        background: #ddddcc;
+        margin: .5em;
+        margin-top: 1em;
+        padding-bottom: 0em;
+      }
+      dd {
+        margin-bottom: 0.5em;
+      }
+  </style>
+  <body>
+    <table class="banner">
+      <tr>
+        <td class="leftbanner">
+          <h1><a href="/">Python OpenID Server Example</a></h1>
+        </td>
+        <td class="rightbanner">
+          You are %(user_link)s
+        </td>
+      </tr>
+    </table>
+%(body)s
+  </body>
+</html>
+''' % contents)
+
+
+def main(host, port, data_path):
+    # Instantiate OpenID consumer store and OpenID consumer.  If you
+    # were connecting to a database, you would create the database
+    # connection and instantiate an appropriate store here.
+    if port == 80:
+        server_url = 'http://%s/openidserver' % host
+    else:
+        server_url = 'http://%s:%s/openidserver' % (host, port)
+    store = FileOpenIDStore(data_path)
+    oidserver = server.Server(store)
+
+    addr = (host, port)
+    httpserver = OpenIDHTTPServer(oidserver, addr, ServerHandler)
+
+    print 'Server running at:'
+    print httpserver.base_url
+    httpserver.serve_forever()
+
+if __name__ == '__main__':
+    host = 'localhost'
+    data_path = 'sstore'
+    port = 8000
+
+    try:
+        import optparse
+    except ImportError:
+        pass # Use defaults (for Python 2.2)
+    else:
+        parser = optparse.OptionParser('Usage:\n %prog [options]')
+        parser.add_option(
+            '-d', '--data-path', dest='data_path', default=data_path,
+            help='Data directory for storing OpenID consumer state. '
+            'Defaults to "%default" in the current directory.')
+        parser.add_option(
+            '-p', '--port', dest='port', type='int', default=port,
+            help='Port on which to listen for HTTP requests. '
+            'Defaults to port %default.')
+        parser.add_option(
+            '-s', '--host', dest='host', default=host,
+            help='Host on which to listen for HTTP requests. '
+            'Also used for generating URLs. Defaults to %default.')
+
+        options, args = parser.parse_args()
+        if args:
+            parser.error('Expected no arguments. Got %r' % args)
+
+        host = options.host
+        port = options.port
+        data_path = options.data_path
+
+    main(host, port, data_path)

Propchange: incubator/heraldry/libraries/python/openid/trunk/examples/server.py
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/heraldry/libraries/python/openid/trunk/openid/__init__.py
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/openid/__init__.py?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/openid/__init__.py (added)
+++ incubator/heraldry/libraries/python/openid/trunk/openid/__init__.py Wed Oct 11 16:11:47 2006
@@ -0,0 +1,21 @@
+"""
+This package is an implementation of the OpenID specification in
+Python.  It contains code for both server and consumer
+implementations.  For information on implementing an OpenID consumer,
+see the C{L{openid.consumer.consumer}} module.  For information on
+implementing an OpenID server, see the C{L{openid.server.server}}
+module.
+"""
+
+__version__ = '[library version:1.1.2-rc1]'[17:-1]
+
+# Parse the version info
+try:
+    version_info = map(int, __version__.split('.'))
+except ValueError:
+    version_info = (None, None, None)
+else:
+    if len(version_info) != 3:
+        version_info = (None, None, None)
+    else:
+        version_info = tuple(version_info)

Added: incubator/heraldry/libraries/python/openid/trunk/openid/association.py
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/openid/association.py?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/openid/association.py (added)
+++ incubator/heraldry/libraries/python/openid/trunk/openid/association.py Wed Oct 11 16:11:47 2006
@@ -0,0 +1,321 @@
+"""
+This module contains code for dealing with associations between
+consumers and servers.
+"""
+
+import time
+
+from openid import cryptutil
+from openid import kvform
+from openid import oidutil
+
+class Association(object):
+    """
+    This class represents an association between a server and a
+    consumer.  In general, users of this library will never see
+    instances of this object.  The only exception is if you implement
+    a custom C{L{OpenIDStore<openid.store.interface.OpenIDStore>}}.
+
+    If you do implement such a store, it will need to store the values
+    of the C{L{handle}}, C{L{secret}}, C{L{issued}}, C{L{lifetime}}, and
+    C{L{assoc_type}} instance variables.
+
+    @ivar handle: This is the handle the server gave this association.
+
+    @type handle: C{str}
+
+
+    @ivar secret: This is the shared secret the server generated for
+        this association.
+
+    @type secret: C{str}
+
+
+    @ivar issued: This is the time this association was issued, in
+        seconds since 00:00 GMT, January 1, 1970.  (ie, a unix
+        timestamp)
+
+    @type issued: C{int}
+
+
+    @ivar lifetime: This is the amount of time this association is
+        good for, measured in seconds since the association was
+        issued.
+
+    @type lifetime: C{int}
+
+
+    @ivar assoc_type: This is the type of association this instance
+        represents.  The only valid value of this field at this time
+        is C{'HMAC-SHA1'}, but new types may be defined in the future.
+
+    @type assoc_type: C{str}
+
+
+    @sort: __init__, fromExpiresIn, getExpiresIn, __eq__, __ne__,
+        handle, secret, issued, lifetime, assoc_type
+    """
+
+    # This is a HMAC-SHA1 specific value.
+    SIG_LENGTH = 20
+
+    # The ordering and name of keys as stored by serialize
+    assoc_keys = [
+        'version',
+        'handle',
+        'secret',
+        'issued',
+        'lifetime',
+        'assoc_type',
+        ]
+
+    def fromExpiresIn(cls, expires_in, handle, secret, assoc_type):
+        """
+        This is an alternate constructor used by the OpenID consumer
+        library to create associations.  C{L{OpenIDStore
+        <openid.store.interface.OpenIDStore>}} implementations
+        shouldn't use this constructor.
+
+
+        @param expires_in: This is the amount of time this association
+            is good for, measured in seconds since the association was
+            issued.
+
+        @type expires_in: C{int}
+
+
+        @param handle: This is the handle the server gave this
+            association.
+
+        @type handle: C{str}
+
+
+        @param secret: This is the shared secret the server generated
+            for this association.
+
+        @type secret: C{str}
+
+
+        @param assoc_type: This is the type of association this
+            instance represents.  The only valid value of this field
+            at this time is C{'HMAC-SHA1'}, but new types may be
+            defined in the future.
+
+        @type assoc_type: C{str}
+        """
+        issued = int(time.time())
+        lifetime = expires_in
+        return cls(handle, secret, issued, lifetime, assoc_type)
+
+    fromExpiresIn = classmethod(fromExpiresIn)
+
+    def __init__(self, handle, secret, issued, lifetime, assoc_type):
+        """
+        This is the standard constructor for creating an association.
+
+
+        @param handle: This is the handle the server gave this
+            association.
+
+        @type handle: C{str}
+
+
+        @param secret: This is the shared secret the server generated
+            for this association.
+
+        @type secret: C{str}
+
+
+        @param issued: This is the time this association was issued,
+            in seconds since 00:00 GMT, January 1, 1970.  (ie, a unix
+            timestamp)
+
+        @type issued: C{int}
+
+
+        @param lifetime: This is the amount of time this association
+            is good for, measured in seconds since the association was
+            issued.
+
+        @type lifetime: C{int}
+
+
+        @param assoc_type: This is the type of association this
+            instance represents.  The only valid value of this field
+            at this time is C{'HMAC-SHA1'}, but new types may be
+            defined in the future.
+
+        @type assoc_type: C{str}
+        """
+        if assoc_type != 'HMAC-SHA1':
+            fmt = 'HMAC-SHA1 is the only supported association type (got %r)'
+            raise ValueError(fmt % (assoc_type,))
+
+        self.handle = handle
+        self.secret = secret
+        self.issued = issued
+        self.lifetime = lifetime
+        self.assoc_type = assoc_type
+
+    def getExpiresIn(self, now=None):
+        """
+        This returns the number of seconds this association is still
+        valid for, or C{0} if the association is no longer valid.
+
+
+        @return: The number of seconds this association is still valid
+            for, or C{0} if the association is no longer valid.
+
+        @rtype: C{int}
+        """
+        if now is None:
+            now = int(time.time())
+
+        return max(0, self.issued + self.lifetime - now)
+
+    expiresIn = property(getExpiresIn)
+
+    def __eq__(self, other):
+        """
+        This checks to see if two C{L{Association}} instances
+        represent the same association.
+
+
+        @return: C{True} if the two instances represent the same
+            association, C{False} otherwise.
+
+        @rtype: C{bool}
+        """
+        return type(self) is type(other) and self.__dict__ == other.__dict__
+
+    def __ne__(self, other):
+        """
+        This checks to see if two C{L{Association}} instances
+        represent different associations.
+
+
+        @return: C{True} if the two instances represent different
+            associations, C{False} otherwise.
+
+        @rtype: C{bool}
+        """
+        return not (self == other)
+
+    def serialize(self):
+        """
+        Convert an association to KV form.
+
+        @return: String in KV form suitable for deserialization by
+            deserialize.
+
+        @rtype: str
+        """
+        data = {
+            'version':'2',
+            'handle':self.handle,
+            'secret':oidutil.toBase64(self.secret),
+            'issued':str(int(self.issued)),
+            'lifetime':str(int(self.lifetime)),
+            'assoc_type':self.assoc_type
+            }
+
+        assert len(data) == len(self.assoc_keys)
+        pairs = []
+        for field_name in self.assoc_keys:
+            pairs.append((field_name, data[field_name]))
+
+        return kvform.seqToKV(pairs, strict=True)
+
+    def deserialize(cls, assoc_s):
+        """
+        Parse an association as stored by serialize().
+
+        inverse of serialize
+
+
+        @param assoc_s: Association as serialized by serialize()
+
+        @type assoc_s: str
+
+
+        @return: instance of this class
+        """
+        pairs = kvform.kvToSeq(assoc_s, strict=True)
+        keys = []
+        values = []
+        for k, v in pairs:
+            keys.append(k)
+            values.append(v)
+
+        if keys != cls.assoc_keys:
+            raise ValueError('Unexpected key values: %r', keys)
+
+        version, handle, secret, issued, lifetime, assoc_type = values
+        if version != '2':
+            raise ValueError('Unknown version: %r' % version)
+        issued = int(issued)
+        lifetime = int(lifetime)
+        secret = oidutil.fromBase64(secret)
+        return cls(handle, secret, issued, lifetime, assoc_type)
+
+    deserialize = classmethod(deserialize)
+
+    def sign(self, pairs):
+        """
+        Generate a signature for a sequence of (key, value) pairs
+
+
+        @param pairs: The pairs to sign, in order
+
+        @type pairs: sequence of (str, str)
+
+
+        @return: The binary signature of this sequence of pairs
+
+        @rtype: str
+        """
+        assert self.assoc_type == 'HMAC-SHA1'
+        kv = kvform.seqToKV(pairs)
+        return cryptutil.hmacSha1(self.secret, kv)
+
+    def signDict(self, fields, data, prefix='openid.'):
+        """
+        Generate a signature for some fields in a dictionary
+
+
+        @param fields: The fields to sign, in order
+
+        @type fields: sequence of str
+
+
+        @param data: Dictionary of values to sign
+
+        @type data: {str:str}
+
+
+        @return: the signature, base64 encoded
+
+        @rtype: str
+        """
+        pairs = []
+        for field in fields:
+            pairs.append((field, data.get(prefix + field, '')))
+
+        return oidutil.toBase64(self.sign(pairs))
+
+    def addSignature(self, fields, data, prefix='openid.'):
+        sig = self.signDict(fields, data, prefix)
+        signed = ','.join(fields)
+        data[prefix + 'sig'] = sig
+        data[prefix + 'signed'] = signed
+
+    def checkSignature(self, data, prefix='openid.'):
+        try:
+            signed = data[prefix + 'signed']
+            fields = signed.split(',')
+            expected_sig = self.signDict(fields, data, prefix)
+            request_sig = data[prefix + 'sig']
+        except KeyError:
+            return False
+
+        return request_sig == expected_sig

Added: incubator/heraldry/libraries/python/openid/trunk/openid/consumer/__init__.py
URL: http://svn.apache.org/viewvc/incubator/heraldry/libraries/python/openid/trunk/openid/consumer/__init__.py?view=auto&rev=463041
==============================================================================
--- incubator/heraldry/libraries/python/openid/trunk/openid/consumer/__init__.py (added)
+++ incubator/heraldry/libraries/python/openid/trunk/openid/consumer/__init__.py Wed Oct 11 16:11:47 2006
@@ -0,0 +1,4 @@
+"""
+This package contains the portions of the library used only when
+implementing an OpenID consumer.
+"""



Mime
View raw message