[PATCH] Make it possible to configure Patchwork to delegate user authentication to an OpenID provider.
Guilherme Salgado
guilherme.salgado at linaro.org
Fri Feb 18 06:53:17 EST 2011
The default still is to authenticate against the local user database
Also, instead using RegistrationForm's profile_callback to register
UserProfiles we now use a signal handler for post_save on User, so that
a UserProfile is always created, regardless of how the new User is created.
Signed-off-by: Guilherme Salgado <guilherme.salgado at linaro.org>
---
I think this would be a nice addition and the change itself is not very
intrusive.
There's just one gotcha which I haven't dealt with yet. The 'register' link
is still shown at the top right when the user is not logged in, but it doesn't
make sense when using OpenID. Maybe one alternative would be to have just the
'login' link there and provide a link to /accounts/register from
/accounts/login?
apps/patchwork/context_processors.py | 6 +++---
apps/patchwork/forms.py | 8 +++++---
apps/patchwork/models.py | 11 +++++++++--
apps/patchwork/tests/utils.py | 4 ----
apps/patchwork/utils.py | 5 -----
apps/settings.py | 16 +++++++++++++++-
apps/urls.py | 5 ++---
docs/INSTALL | 15 +++++++++++++++
templates/base.html | 2 +-
9 files changed, 50 insertions(+), 22 deletions(-)
diff --git a/apps/patchwork/context_processors.py b/apps/patchwork/context_processors.py
index f4ab5a9..b458eef 100644
--- a/apps/patchwork/context_processors.py
+++ b/apps/patchwork/context_processors.py
@@ -17,9 +17,9 @@
# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+from django.conf import settings
from patchwork.models import Bundle
-from patchwork.utils import order_map, get_order
def bundle(request):
user = request.user
@@ -28,5 +28,5 @@ def bundle(request):
return {'bundles': Bundle.objects.filter(owner = user)}
-def patchlists(request):
-
+def login_url(request):
+ return dict(login_url=settings.LOGIN_URL)
diff --git a/apps/patchwork/forms.py b/apps/patchwork/forms.py
index 1c5aeef..72c2c42 100644
--- a/apps/patchwork/forms.py
+++ b/apps/patchwork/forms.py
@@ -45,9 +45,11 @@ class RegistrationForm(RegistrationFormUniqueEmail):
user.last_name = self.cleaned_data.get('last_name', '')
user.save()
- # saving the userprofile causes the firstname/lastname to propagate
- # to the person objects.
- user.get_profile().save()
+ # XXX: I think the code below is no longer needed as the signal
+ # handler responsible for creating the UserProfile already saves it.
+ # saving the userprofile causes the firstname/lastname to propagate
+ # to the person objects.
+ user.get_profile().save()
return user
diff --git a/apps/patchwork/models.py b/apps/patchwork/models.py
index 6842622..3ee007f 100644
--- a/apps/patchwork/models.py
+++ b/apps/patchwork/models.py
@@ -18,6 +18,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from django.db import models
+from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.contrib.sites.models import Site
@@ -126,8 +127,8 @@ class UserProfile(models.Model):
person.save()
else:
for person in people:
- person.link_to_user(self.user)
- person.save()
+ person.link_to_user(self.user)
+ person.save()
def __str__(self):
return self.name()
@@ -400,3 +401,9 @@ class UserPersonConfirmation(models.Model):
super(UserPersonConfirmation, self).save()
+def register_userprofile(sender, **kwargs):
+ if kwargs['created']:
+ UserProfile(user=kwargs['instance']).save()
+
+
+post_save.connect(register_userprofile, User)
diff --git a/apps/patchwork/tests/utils.py b/apps/patchwork/tests/utils.py
index a85e168..819e5b9 100644
--- a/apps/patchwork/tests/utils.py
+++ b/apps/patchwork/tests/utils.py
@@ -59,10 +59,6 @@ def create_user():
user = User.objects.create_user(userid, email, userid)
user.save()
-
- profile = UserProfile(user = user)
- profile.save()
-
return user
def create_maintainer(project):
diff --git a/apps/patchwork/utils.py b/apps/patchwork/utils.py
index fa26aef..ba019e6 100644
--- a/apps/patchwork/utils.py
+++ b/apps/patchwork/utils.py
@@ -200,8 +200,3 @@ def set_patches(user, project, action, data, patches, context):
context.add_message(str)
return (errors, form)
-
-def userprofile_register_callback(user):
- profile = UserProfile(user = user)
- profile.save()
-
diff --git a/apps/settings.py b/apps/settings.py
index 68837b3..32886de 100644
--- a/apps/settings.py
+++ b/apps/settings.py
@@ -69,6 +69,12 @@ ROOT_URLCONF = 'apps.urls'
LOGIN_URL = '/accounts/login'
LOGIN_REDIRECT_URL = '/user/'
+# If you want to make your Patchwork instance an OpenID relying party, you
+# just need to uncomment the lines below.
+# OPENID_CREATE_USERS = True
+# OPENID_UPDATE_DETAILS_FROM_SREG = True
+# LOGIN_URL = '/openid/login/'
+# OPENID_SSO_SERVER_URL = 'https://login.launchpad.net/'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
@@ -80,7 +86,14 @@ TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
- "django.core.context_processors.media")
+ "django.core.context_processors.media",
+ "patchwork.context_processors.login_url",
+ )
+
+AUTHENTICATION_BACKENDS = (
+ 'django_openid_auth.auth.OpenIDBackend',
+ 'django.contrib.auth.backends.ModelBackend',
+)
AUTH_PROFILE_MODULE = "patchwork.userprofile"
@@ -90,6 +103,7 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
+ 'django_openid_auth',
'patchwork',
'registration',
)
diff --git a/apps/urls.py b/apps/urls.py
index 5c4ac57..de0769e 100644
--- a/apps/urls.py
+++ b/apps/urls.py
@@ -23,17 +23,16 @@ from patchwork.admin import admin_site
from registration.views import register
from patchwork.forms import RegistrationForm
-from patchwork.utils import userprofile_register_callback
urlpatterns = patterns('',
# Example:
+ (r'^openid/', include('django_openid_auth.urls')),
(r'^', include('patchwork.urls')),
# override the default registration form
url(r'^accounts/register/$',
register,
- {'form_class': RegistrationForm,
- 'profile_callback': userprofile_register_callback},
+ {'form_class': RegistrationForm},
name='registration_register'),
(r'^accounts/', include('registration.urls')),
diff --git a/docs/INSTALL b/docs/INSTALL
index 57e8042..aac619f 100644
--- a/docs/INSTALL
+++ b/docs/INSTALL
@@ -92,6 +92,21 @@ in brackets):
cd ../python
ln -s ../lib/packages/django-registration/registration ./registration
+ Two other libraries we may use, in case you use OpenID for
+ authentication, are django-openid-auth and the Python OpenID library.
+ The former is named python-django-openid-auth in Debian/Ubuntu and the
+ latter python-openid, but if they're not available in your
+ distribution, you can follow the steps below to get them:
+
+ cd lib/packages
+ wget http://launchpad.net/django-openid-auth/trunk/0.3/+download/django-openid-auth-0.3.tar.gz
+ wget --no-check-certificate https://github.com/openid/python-openid/tarball/2.2.5 -O python-openid-2.2.5.tgz
+ tar zxvf django-openid-auth-0.3.tar.gz
+ tar zxvf python-openid-2.2.5.tgz
+ cd ../python
+ ln -s ../packages/django-openid-auth-0.3/django_openid_auth ./django_openid_auth
+ ln -s ../packages/openid-python-openid-b666238/openid ./openid
+
We also use some Javascript libraries:
cd lib/packages
diff --git a/templates/base.html b/templates/base.html
index ec0204d..365200e 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -28,7 +28,7 @@
<a href="{% url patchwork.views.user.profile %}">profile</a> ::
<a href="{% url auth_logout %}">logout</a>
{% else %}
- <a href="{% url auth_login %}">login</a>
+ <a href="{{ login_url }}">login</a>
<br/>
<a href="{% url registration_register %}">register</a>
<br/>
--
1.7.1
More information about the Patchwork
mailing list