Spline users plugin, focused on OpenID support.
authorEevee <git@veekun.com>
Tue, 20 Jan 2009 08:28:12 +0000 (00:28 -0800)
committerEevee <git@veekun.com>
Tue, 20 Jan 2009 08:28:12 +0000 (00:28 -0800)
OpenID login itself actually works.  Not much else.

.gitignore [new file with mode: 0644]
setup.py [new file with mode: 0644]
spline/__init__.py [new file with mode: 0644]
spline/plugins/__init__.py [new file with mode: 0644]
spline/plugins/users/__init__.py [new file with mode: 0644]
spline/plugins/users/controllers/__init__.py [new file with mode: 0644]
spline/plugins/users/controllers/accounts.py [new file with mode: 0644]
spline/plugins/users/model/__init__.py [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..f0f68e4
--- /dev/null
@@ -0,0 +1,3 @@
+*.swp
+*.pyc
+*.egg-info
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..63e0bc2
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,16 @@
+from setuptools import setup, find_packages
+setup(
+    name = 'spline-users',
+    version = '0.1',
+    packages = find_packages(),
+    
+    install_requires = ['spline'],
+
+    include_package_data = True,
+
+    zip_safe = False,
+
+    entry_points = {'spline.plugins': 'users = spline.plugins.users:UsersPlugin'},
+
+    namespace_packages = ['spline', 'spline.plugins'],
+)
diff --git a/spline/__init__.py b/spline/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/spline/plugins/__init__.py b/spline/plugins/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/spline/plugins/users/__init__.py b/spline/plugins/users/__init__.py
new file mode 100644 (file)
index 0000000..6a0facf
--- /dev/null
@@ -0,0 +1,13 @@
+from spline.lib.plugin import PluginBase
+
+import controllers.accounts
+import model
+
+class UsersPlugin(PluginBase):
+    def controllers(self):
+        return dict(
+            accounts = controllers.accounts.AccountsController,
+        )
+
+    def model(self):
+        return [model.User, model.OpenID]
diff --git a/spline/plugins/users/controllers/__init__.py b/spline/plugins/users/controllers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/spline/plugins/users/controllers/accounts.py b/spline/plugins/users/controllers/accounts.py
new file mode 100644 (file)
index 0000000..67d62e4
--- /dev/null
@@ -0,0 +1,78 @@
+import logging
+from openid.consumer.consumer import Consumer
+from openid.extensions.sreg import SRegRequest, SRegResponse
+from openid.store.filestore import FileOpenIDStore
+from sqlalchemy.orm.exc import NoResultFound
+
+from pylons import config, request, response, session, tmpl_context as c
+from pylons.controllers.util import abort, redirect_to
+from routes import url_for, request_config
+
+from spline import model
+from spline.model import meta
+from spline.lib.base import BaseController, render
+
+log = logging.getLogger(__name__)
+
+class AccountsController(BaseController):
+
+    openid_store = FileOpenIDStore('/var/tmp')
+
+    def index(self):
+        # Return a rendered template
+        #   return render('/template.mako')
+        # or, Return a response
+        return str(request.headers) + request.environ.get('scheme', '')
+
+    def login_begin(self):
+        """Step one of logging in with OpenID; we redirect to the provider"""
+
+        cons = Consumer(session=session, store=self.openid_store)
+        auth_request = cons.begin(request.params['openid'])
+        sreg_req = SRegRequest(optional=['nickname', 'email', 'dob', 'gender',
+                                         'country', 'language', 'timezone'])
+        auth_request.addExtension(sreg_req)
+
+        host = request.headers['host']
+        protocol = request_config().protocol
+        return_url = url_for(host=host, controller='accounts', action='login_finish')
+        new_url = auth_request.redirectURL(return_to=return_url,
+                                           realm=protocol + '://' + host)
+        redirect_to(new_url)
+
+    def login_finish(self):
+        """Step two of logging in; the OpenID provider redirects back here."""
+
+        cons = Consumer(session=session, store=self.openid_store)
+        host = request.headers['host']
+        return_url = url_for(host=host, controller='accounts', action='login_finish')
+        res = cons.complete(request.params, return_url)
+
+        if res.status != 'success':
+            return 'Error!  %s' % res.message
+
+        try:
+            # Grab an existing user record, if one exists
+            q = meta.Session.query(model.User) \
+                    .filter(model.User.openids.any(openid=res.identity_url))
+            user = q.one()
+        except NoResultFound:
+            # Try to pull a name out of the SReg response
+            sreg_res = SRegResponse.fromSuccessResponse(res)
+            try:
+                username = sreg_res['nickname']
+            except KeyError:
+                username = 'Anonymous'
+
+            # Create db records
+            user = model.User(name=username)
+            meta.Session.add(user)
+            openid = model.OpenID(openid=res.identity_url)
+            user.openids.append(openid)
+            meta.Session.commit()
+
+        # Remember who's logged in, and we're good to go
+        session['user_id'] = user.id
+        session.save()
+
+        return "Hello, %s" % user.name
diff --git a/spline/plugins/users/model/__init__.py b/spline/plugins/users/model/__init__.py
new file mode 100644 (file)
index 0000000..f7a30d1
--- /dev/null
@@ -0,0 +1,17 @@
+from sqlalchemy import Column, ForeignKey
+from sqlalchemy.orm import relation
+from sqlalchemy.types import Integer, Unicode
+
+from spline.model.meta import TableBase
+
+class User(TableBase):
+    __tablename__ = 'users'
+    id = Column(Integer, primary_key=True)
+    name = Column(Unicode(length=20), nullable=False)
+
+class OpenID(TableBase):
+    __tablename__ = 'openid'
+    openid = Column(Unicode(length=255), primary_key=True)
+    user_id = Column(Integer, ForeignKey('users.id'))
+    user = relation(User, lazy=False, backref='openids')
+