Commits

Anonymous committed 0a77674

[svn r16] - clean decorator.
- urls are now localized
- new patch of django_openidconsummer that solve yadis import
- remove friendsnippets import

  • Participants
  • Parent commits 8834c5f

Comments (0)

Files changed (5)

File decorators.py

  limitations under the License.
 """
 
-from django.contrib.auth.models import User
 from django.http import HttpResponseRedirect
-from django.utils.encoding import smart_str, iri_to_uri
-from django.utils.translation import ugettext as _
-from django.utils.http import urlquote_plus
-from django.core.urlresolvers import resolve,reverse
+from django.utils.encoding import iri_to_uri
+from django.core.urlresolvers import reverse
 
-from django_openidconsumer.views import get_url_host
 
 
-def username_test(view_func, view_name='django_authopenid.views.account_settings'):
+def username_control(view_name):
     """
     decorator that test if user is authenticated and if
     username in request.path is the one used by authenticated
     the "good" page. Url is also changed.
     """
 
-    def decorate(request, *args, **kwargs):
-        username = None
-        if 'username' in kwargs:
-            username = kwargs['username']
+    def _username_controller(view_func):
+        def _username_controlled(request, *args, **kwargs):
+            response = view_func(request, *args, **kwargs)
+            username = None
+            if 'username' in kwargs:
+                username = kwargs['username']
 
-        if not request.user.is_authenticated():
-            msg = _("In order to change settings for %s, you should be authenticated." % username)
-            redirect_to = "%s?next=%s&msg=%s" % (
-                reverse('django_authopenid.views.signin'), 
-                request.path, urlquote_plus(msg))
-            return HttpResponseRedirect(redirect_to)
+            if not username or username!=request.user.username: 
+                kwargs['username'] = request.user.username
+                redirect_to=iri_to_uri(reverse(view_name, kwargs=kwargs))
+                return HttpResponseRedirect(redirect_to)
 
-        if not username or username!=request.user.username: 
-            kwargs['username'] = request.user.username
-            redirect_to=iri_to_uri(reverse(view_name, kwargs=kwargs))
-            return HttpResponseRedirect(redirect_to)
+            return response
+        return _username_controlled
 
-        return view_func(request, *args, **kwargs)
-
-    return decorate
-
-
+    return _username_controller

File django_openid_r19.diff

-Index: util.py
-===================================================================
---- util.py	(revision 19)
-+++ util.py	(working copy)
-@@ -1,10 +1,13 @@
- from openid.store.interface import OpenIDStore
- from openid.association import Association as OIDAssociation
-+from django.db.models.query import Q
-+from django.conf import settings
-+
-+import openid.store
- from yadis import xri
- 
--import time, base64, md5
-+import time, base64, md5, operator
- 
--from django.conf import settings
- from models import Association, Nonce
- 
- class OpenID:
-@@ -70,27 +73,37 @@
-         for assoc in assocs:
-             assoc.delete()
-         return assocs_exist
--    
--    def storeNonce(self, nonce):
--        nonce, created = Nonce.objects.get_or_create(
--            nonce = nonce, defaults={'expires': int(time.time())}
--        )
--    
--    def useNonce(self, nonce):
-+
-+    def useNonce(self, server_url, timestamp, salt):
-+        if abs(timestamp - time.time()) > openid.store.nonce.SKEW:
-+            return False
-+        
-+        query =[
-+                Q(server_url__exact=server_url),
-+                Q(timestamp__exact=timestamp),
-+                Q(salt__exact=salt),
-+        ]
-         try:
--            nonce = Nonce.objects.get(nonce = nonce)
-+            ononce = Nonce.objects.get(reduce(operator.and_, query))
-         except Nonce.DoesNotExist:
--            return 0
-+            ononce = Nonce(
-+                    server_url=server_url,
-+                    timestamp=timestamp,
-+                    salt=salt
-+            );
-+            ononce.save()
-+            return True
-         
--        # Now check nonce has not expired
--        nonce_age = int(time.time()) - nonce.expires
--        if nonce_age > self.max_nonce_age:
--            present = 0
--        else:
--            present = 1
--        nonce.delete()
--        return present
--    
-+        ononce.delete()
-+
-+        return False
-+   
-+    def cleanupNonce(self):
-+        Nonce.objects.filter(timestamp<int(time.time()) - nonce.SKEW).delete()
-+
-+    def cleaupAssociations(self):
-+        Association.objects.extra(where=['issued + lifetimeint<(%s)' % time.time()]).delete()
-+
-     def getAuthKey(self):
-         # Use first AUTH_KEY_LEN characters of md5 hash of SECRET_KEY
-         return md5.new(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
-@@ -101,6 +114,6 @@
- def from_openid_response(openid_response):
-     issued = int(time.time())
-     return OpenID(
--        openid_response.identity_url, issued, openid_response.signed_args, 
--        openid_response.extensionResponse('sreg')
-+        openid_response.identity_url, issued, openid_response.signed_fields, 
-+        openid_response.extensionResponse('sreg', False)
-     )
-Index: views.py
-===================================================================
---- views.py	(revision 19)
-+++ views.py	(working copy)
-@@ -2,6 +2,7 @@
- from django.shortcuts import render_to_response as render
- from django.template import RequestContext
- from django.conf import settings
-+from django.utils.http import urlquote_plus, urlquote
- 
- import md5, re, time, urllib
- from openid.consumer.consumer import Consumer, \
-@@ -11,6 +12,8 @@
- 
- from util import OpenID, DjangoOpenIDStore, from_openid_response
- 
-+from forms import OpenidSigninForm
-+
- from django.utils.html import escape
- 
- def get_url_host(request):
-@@ -42,67 +45,67 @@
-         on_failure=None):
-     
-     on_failure = on_failure or default_on_failure
--    
--    if request.GET.get('logo'):
--        # Makes for a better demo
--        return logo(request)
--    
-     extension_args = extension_args or {}
--    if sreg:
--        extension_args['sreg.optional'] = sreg
--    trust_root = getattr(
--        settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
--    )
--    redirect_to = redirect_to or getattr(
--        settings, 'OPENID_REDIRECT_TO',
--        # If not explicitly set, assume current URL with complete/ appended
--        get_full_url(request).split('?')[0] + 'complete/'
--    )
--    # In case they were lazy...
--    if not redirect_to.startswith('http://'):
--        redirect_to =  get_url_host(request) + redirect_to
-     
--    if request.GET.get('next') and is_valid_next_url(request.GET['next']):
--        if '?' in redirect_to:
--            join = '&'
--        else:
--            join = '?'
--        redirect_to += join + urllib.urlencode({
-+    next = ''
-+    if request.GET.get('next'):
-+        next = urllib.urlencode({
-             'next': request.GET['next']
-         })
--    
--    user_url = request.POST.get('openid_url', None)
--    if not user_url:
--        request_path = request.path
--        if request.GET.get('next'):
--            request_path += '?' + urllib.urlencode({
--                'next': request.GET['next']
--            })
-         
--        return render('openid_signin.html', {
--            'action': request_path,
--            'logo': request.path + '?logo=1',
--        })
-+  
-+    form_signin = OpenidSigninForm(initial={'next':next})
-+    if request.POST:
-+        form_signin = OpenidSigninForm(request.POST)
-+        if form_signin.is_valid():
-+            consumer = Consumer(request.session, DjangoOpenIDStore())
-+            try:
-+                auth_request = consumer.begin(form_signin.cleaned_data['openid_url'])
-+            except DiscoveryFailure:
-+                return on_failure(request, "The OpenID was invalid")
-+
-+            if sreg:
-+                extension_args['sreg.optional'] = sreg
-+            
-+            trust_root = getattr(
-+                    settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
-+                )
-+        
-+            redirect_to = redirect_to or getattr(
-+                settings, 'OPENID_REDIRECT_TO',
-+                # If not explicitly set, assume current URL with complete/ appended
-+                get_full_url(request).split('?')[0] + 'complete/'
-+            )
-+
-+            # TODO: add redirect_to in form 
-+            if not redirect_to.startswith('http://'):
-+                redirect_to =  get_url_host(request) + redirect_to
-+
-+
-+            if 'next' in form_signin.cleaned_data and next != "":
-+                if '?' in redirect_to:
-+                    join = '&'
-+                else:
-+                    join = '?'
-+                redirect_to += join + urllib.urlencode({
-+                    'next': form_signin.cleaned_data['next']
-+                })
-     
--    if xri.identifierScheme(user_url) == 'XRI' and getattr(
--        settings, 'OPENID_DISALLOW_INAMES', False
--        ):
--        return on_failure(request, 'i-names are not supported')
-+            # Add extension args (for things like simple registration)
-+            for name, value in extension_args.items():
-+                namespace, key = name.split('.', 1)
-+                auth_request.addExtensionArg(namespace, key, value)
-     
--    consumer = Consumer(request.session, DjangoOpenIDStore())
--    try:
--        auth_request = consumer.begin(user_url)
--    except DiscoveryFailure:
--        return on_failure(request, "The OpenID was invalid")
-+            redirect_url = auth_request.redirectURL(trust_root, redirect_to)
-+            return HttpResponseRedirect(redirect_url)
-+
-+    return render('openid_signin.html', {
-+            'form': form_signin,
-+            'action': request.path,
-+            'logo': request.path + 'logo/',
-+            'openids': request.session['openids'],
-+        })
-     
--    # Add extension args (for things like simple registration)
--    for name, value in extension_args.items():
--        namespace, key = name.split('.', 1)
--        auth_request.addExtensionArg(namespace, key, value)
--    
--    redirect_url = auth_request.redirectURL(trust_root, redirect_to)
--    return HttpResponseRedirect(redirect_url)
--
- def complete(request, on_success=None, on_failure=None):
-     on_success = on_success or default_on_success
-     on_failure = on_failure or default_on_failure
-Index: models.py
-===================================================================
---- models.py	(revision 19)
-+++ models.py	(working copy)
-@@ -1,11 +1,14 @@
- from django.db import models
- 
- class Nonce(models.Model):
--    nonce = models.CharField(maxlength=8)
--    expires = models.IntegerField()
--    def __str__(self):
--        return "Nonce: %s" % self.nonce
-+    server_url = models.CharField(maxlength=255)
-+    timestamp = models.IntegerField()
-+    salt = models.CharField(max_length=40)
-+    
-+    def __unicode__(self):
-+        return u"Nonce: %s" % self.id
- 
-+    
- class Association(models.Model):
-     server_url = models.TextField(maxlength=2047)
-     handle = models.CharField(maxlength=255)
-@@ -13,5 +16,7 @@
-     issued = models.IntegerField()
-     lifetime = models.IntegerField()
-     assoc_type = models.TextField(maxlength=64)
--    def __str__(self):
--        return "Association: %s, %s" % (self.server_url, self.handle)
-+    
-+    def __unicode__(self):
-+        return u"Association: %s, %s" % (self.server_url, self.handle)
-+
-Index: urls.py
-===================================================================
---- urls.py	(revision 0)
-+++ urls.py	(revision 0)
-@@ -0,0 +1,10 @@
-+from django.conf.urls.defaults import patterns
-+
-+urlpatterns = patterns('',
-+    (r'^$', 'django_openidconsumer.views.begin'),
-+    (r'^logo/$', 'django_openidconsumer.views.logo'),
-+    (r'^signout/$', 'django_openidconsumer.views.signout'),
-+    (r'^complete/$', 'django_openidconsumer.views.complete'),
-+
-+    
-+)
-Index: forms.py
-===================================================================
---- forms.py	(revision 0)
-+++ forms.py	(revision 0)
-@@ -0,0 +1,29 @@
-+from django import newforms as forms
-+from django.utils.translation import ugettext as _
-+from django.conf import settings
-+
-+from yadis import xri
-+
-+import re
-+
-+class OpenidSigninForm(forms.Form):
-+    openid_url = forms.CharField(max_length=255, widget=forms.widgets.TextInput(attrs={'class': 'required openid'}))
-+    next = forms.CharField(max_length=255,widget=forms.HiddenInput(), required=False)
-+
-+    def clean_openid_url(self):
-+        if 'openid_url' in self.cleaned_data:
-+            openid_url = self.cleaned_data['openid_url']
-+            if xri.identifierScheme(openid_url) == 'XRI' and getattr(
-+                settings, 'OPENID_DISALLOW_INAMES', False
-+                ):
-+                raise forms.ValidationError(_('i-names are not supported'))
-+            return self.cleaned_data['openid_url']
-+
-+    def clean_next(self):
-+        if 'next' in self.cleaned_data and self.cleaned_data['next'] != "":
-+            next_url_re = re.compile('^/[-\w/]+$')
-+            if not next_url_re.match(self.cleaned_data['next']):
-+                raise forms.ValidationError(_('next url "%s" is invalid' % self.cleaned_data['next']))
-+            return self.cleaned_data['next']
-+
-+
-Index: templates/openid_signin.html
-===================================================================
---- templates/openid_signin.html	(revision 19)
-+++ templates/openid_signin.html	(working copy)
-@@ -1,3 +1,5 @@
-+{% load i18n %}
-+
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-   "http://www.w3.org/TR/html4/strict.dtd">
- <html>
-@@ -13,10 +15,24 @@
- </head>
- <body>
- <h1>Sign in with your OpenID</h1>
--
--<form action="{{ action }}" method="post">
--<p><input class="openid" type="text" name="openid_url"> <input type="submit" value="Sign in"></p>
--</form>
--
-+{% if form.errors %}
-+<p class="errors">{% trans "Please correct errors below:" %}<br />
-+	{% if form.openid_url.errors %} 
-+		<span class="error">{{ form.openid_url.errors|join:", " }}</span>
-+	{% endif %}
-+	{% if form.next.errors %} 
-+		<span class="error">{{ form.next.errors|join:", " }}</span>
-+	{% endif %}
-+</p>
-+{% endif %}
-+<form name="fopenid" action="{{ action }}" method="post">
-+    {{ form.next }}
-+	<fieldset>
-+		<legend>{% trans "Sign In Using Your OpenID" %}</legend>
-+        <div class="form-row"><label for="id_openid_ul">{% trans "OpenId URL :" %}</label><br />{{ form.openid_url }}</div>     
-+        <div class="submit-row "><input name="bsignin" type="submit" value="{% trans "Sign in with OPENID" %}"></div>
-+		
-+	</fieldset>
-+</form>	
- </body>
- </html>

File django_openidconsummer_r19_2.diff

+Index: util.py
+===================================================================
+--- util.py	(revision 19)
++++ util.py	(working copy)
+@@ -1,10 +1,18 @@
+ from openid.store.interface import OpenIDStore
+ from openid.association import Association as OIDAssociation
+-from yadis import xri
++from django.db.models.query import Q
++from django.conf import settings
+ 
+-import time, base64, md5
++import openid.store
+ 
+-from django.conf import settings
++# needed for some linux distributions like debian
++try:
++    from openid.yadis import xri
++except:
++    from yadis import xri
++
++import time, base64, md5, operator
++
+ from models import Association, Nonce
+ 
+ class OpenID:
+@@ -70,27 +78,37 @@
+         for assoc in assocs:
+             assoc.delete()
+         return assocs_exist
+-    
+-    def storeNonce(self, nonce):
+-        nonce, created = Nonce.objects.get_or_create(
+-            nonce = nonce, defaults={'expires': int(time.time())}
+-        )
+-    
+-    def useNonce(self, nonce):
++
++    def useNonce(self, server_url, timestamp, salt):
++        if abs(timestamp - time.time()) > openid.store.nonce.SKEW:
++            return False
++        
++        query =[
++                Q(server_url__exact=server_url),
++                Q(timestamp__exact=timestamp),
++                Q(salt__exact=salt),
++        ]
+         try:
+-            nonce = Nonce.objects.get(nonce = nonce)
++            ononce = Nonce.objects.get(reduce(operator.and_, query))
+         except Nonce.DoesNotExist:
+-            return 0
++            ononce = Nonce(
++                    server_url=server_url,
++                    timestamp=timestamp,
++                    salt=salt
++            );
++            ononce.save()
++            return True
+         
+-        # Now check nonce has not expired
+-        nonce_age = int(time.time()) - nonce.expires
+-        if nonce_age > self.max_nonce_age:
+-            present = 0
+-        else:
+-            present = 1
+-        nonce.delete()
+-        return present
+-    
++        ononce.delete()
++
++        return False
++   
++    def cleanupNonce(self):
++        Nonce.objects.filter(timestamp<int(time.time()) - nonce.SKEW).delete()
++
++    def cleaupAssociations(self):
++        Association.objects.extra(where=['issued + lifetimeint<(%s)' % time.time()]).delete()
++
+     def getAuthKey(self):
+         # Use first AUTH_KEY_LEN characters of md5 hash of SECRET_KEY
+         return md5.new(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
+@@ -101,6 +119,6 @@
+ def from_openid_response(openid_response):
+     issued = int(time.time())
+     return OpenID(
+-        openid_response.identity_url, issued, openid_response.signed_args, 
+-        openid_response.extensionResponse('sreg')
++        openid_response.identity_url, issued, openid_response.signed_fields, 
++        openid_response.extensionResponse('sreg', False)
+     )
+Index: views.py
+===================================================================
+--- views.py	(revision 19)
++++ views.py	(working copy)
+@@ -2,15 +2,24 @@
+ from django.shortcuts import render_to_response as render
+ from django.template import RequestContext
+ from django.conf import settings
++from django.utils.http import urlquote_plus, urlquote
+ 
+ import md5, re, time, urllib
+ from openid.consumer.consumer import Consumer, \
+     SUCCESS, CANCEL, FAILURE, SETUP_NEEDED
+ from openid.consumer.discover import DiscoveryFailure
+-from yadis import xri
+ 
++# needed for some linux distributions like debian
++try:
++    from openid.yadis import xri
++except:
++    from yadis import xriœ
++
++
+ from util import OpenID, DjangoOpenIDStore, from_openid_response
+ 
++from forms import OpenidSigninForm
++
+ from django.utils.html import escape
+ 
+ def get_url_host(request):
+@@ -42,67 +51,67 @@
+         on_failure=None):
+     
+     on_failure = on_failure or default_on_failure
+-    
+-    if request.GET.get('logo'):
+-        # Makes for a better demo
+-        return logo(request)
+-    
+     extension_args = extension_args or {}
+-    if sreg:
+-        extension_args['sreg.optional'] = sreg
+-    trust_root = getattr(
+-        settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
+-    )
+-    redirect_to = redirect_to or getattr(
+-        settings, 'OPENID_REDIRECT_TO',
+-        # If not explicitly set, assume current URL with complete/ appended
+-        get_full_url(request).split('?')[0] + 'complete/'
+-    )
+-    # In case they were lazy...
+-    if not redirect_to.startswith('http://'):
+-        redirect_to =  get_url_host(request) + redirect_to
+     
+-    if request.GET.get('next') and is_valid_next_url(request.GET['next']):
+-        if '?' in redirect_to:
+-            join = '&'
+-        else:
+-            join = '?'
+-        redirect_to += join + urllib.urlencode({
++    next = ''
++    if request.GET.get('next'):
++        next = urllib.urlencode({
+             'next': request.GET['next']
+         })
+-    
+-    user_url = request.POST.get('openid_url', None)
+-    if not user_url:
+-        request_path = request.path
+-        if request.GET.get('next'):
+-            request_path += '?' + urllib.urlencode({
+-                'next': request.GET['next']
+-            })
+         
+-        return render('openid_signin.html', {
+-            'action': request_path,
+-            'logo': request.path + '?logo=1',
+-        })
++  
++    form_signin = OpenidSigninForm(initial={'next':next})
++    if request.POST:
++        form_signin = OpenidSigninForm(request.POST)
++        if form_signin.is_valid():
++            consumer = Consumer(request.session, DjangoOpenIDStore())
++            try:
++                auth_request = consumer.begin(form_signin.cleaned_data['openid_url'])
++            except DiscoveryFailure:
++                return on_failure(request, "The OpenID was invalid")
++
++            if sreg:
++                extension_args['sreg.optional'] = sreg
++            
++            trust_root = getattr(
++                    settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
++                )
++        
++            redirect_to = redirect_to or getattr(
++                settings, 'OPENID_REDIRECT_TO',
++                # If not explicitly set, assume current URL with complete/ appended
++                get_full_url(request).split('?')[0] + 'complete/'
++            )
++
++            # TODO: add redirect_to in form 
++            if not redirect_to.startswith('http://'):
++                redirect_to =  get_url_host(request) + redirect_to
++
++
++            if 'next' in form_signin.cleaned_data and next != "":
++                if '?' in redirect_to:
++                    join = '&'
++                else:
++                    join = '?'
++                redirect_to += join + urllib.urlencode({
++                    'next': form_signin.cleaned_data['next']
++                })
+     
+-    if xri.identifierScheme(user_url) == 'XRI' and getattr(
+-        settings, 'OPENID_DISALLOW_INAMES', False
+-        ):
+-        return on_failure(request, 'i-names are not supported')
++            # Add extension args (for things like simple registration)
++            for name, value in extension_args.items():
++                namespace, key = name.split('.', 1)
++                auth_request.addExtensionArg(namespace, key, value)
+     
+-    consumer = Consumer(request.session, DjangoOpenIDStore())
+-    try:
+-        auth_request = consumer.begin(user_url)
+-    except DiscoveryFailure:
+-        return on_failure(request, "The OpenID was invalid")
++            redirect_url = auth_request.redirectURL(trust_root, redirect_to)
++            return HttpResponseRedirect(redirect_url)
++
++    return render('openid_signin.html', {
++            'form': form_signin,
++            'action': request.path,
++            'logo': request.path + 'logo/',
++            'openids': request.session['openids'],
++        })
+     
+-    # Add extension args (for things like simple registration)
+-    for name, value in extension_args.items():
+-        namespace, key = name.split('.', 1)
+-        auth_request.addExtensionArg(namespace, key, value)
+-    
+-    redirect_url = auth_request.redirectURL(trust_root, redirect_to)
+-    return HttpResponseRedirect(redirect_url)
+-
+ def complete(request, on_success=None, on_failure=None):
+     on_success = on_success or default_on_success
+     on_failure = on_failure or default_on_failure
+Index: models.py
+===================================================================
+--- models.py	(revision 19)
++++ models.py	(working copy)
+@@ -1,11 +1,14 @@
+ from django.db import models
+ 
+ class Nonce(models.Model):
+-    nonce = models.CharField(maxlength=8)
+-    expires = models.IntegerField()
+-    def __str__(self):
+-        return "Nonce: %s" % self.nonce
++    server_url = models.CharField(maxlength=255)
++    timestamp = models.IntegerField()
++    salt = models.CharField(max_length=40)
++    
++    def __unicode__(self):
++        return u"Nonce: %s" % self.id
+ 
++    
+ class Association(models.Model):
+     server_url = models.TextField(maxlength=2047)
+     handle = models.CharField(maxlength=255)
+@@ -13,5 +16,7 @@
+     issued = models.IntegerField()
+     lifetime = models.IntegerField()
+     assoc_type = models.TextField(maxlength=64)
+-    def __str__(self):
+-        return "Association: %s, %s" % (self.server_url, self.handle)
++    
++    def __unicode__(self):
++        return u"Association: %s, %s" % (self.server_url, self.handle)
++
+Index: urls.py
+===================================================================
+--- urls.py	(revision 0)
++++ urls.py	(revision 0)
+@@ -0,0 +1,10 @@
++from django.conf.urls.defaults import patterns
++
++urlpatterns = patterns('',
++    (r'^$', 'django_openidconsumer.views.begin'),
++    (r'^logo/$', 'django_openidconsumer.views.logo'),
++    (r'^signout/$', 'django_openidconsumer.views.signout'),
++    (r'^complete/$', 'django_openidconsumer.views.complete'),
++
++    
++)
+Index: forms.py
+===================================================================
+--- forms.py	(revision 0)
++++ forms.py	(revision 0)
+@@ -0,0 +1,33 @@
++from django import newforms as forms
++from django.utils.translation import ugettext as _
++from django.conf import settings
++
++# needed for some linux distributions like debian
++try:
++    from openid.yadis import xri
++except:
++    from yadis import xri
++
++import re
++
++class OpenidSigninForm(forms.Form):
++    openid_url = forms.CharField(max_length=255, widget=forms.widgets.TextInput(attrs={'class': 'required openid'}))
++    next = forms.CharField(max_length=255,widget=forms.HiddenInput(), required=False)
++
++    def clean_openid_url(self):
++        if 'openid_url' in self.cleaned_data:
++            openid_url = self.cleaned_data['openid_url']
++            if xri.identifierScheme(openid_url) == 'XRI' and getattr(
++                settings, 'OPENID_DISALLOW_INAMES', False
++                ):
++                raise forms.ValidationError(_('i-names are not supported'))
++            return self.cleaned_data['openid_url']
++
++    def clean_next(self):
++        if 'next' in self.cleaned_data and self.cleaned_data['next'] != "":
++            next_url_re = re.compile('^/[-\w/]+$')
++            if not next_url_re.match(self.cleaned_data['next']):
++                raise forms.ValidationError(_('next url "%s" is invalid' % self.cleaned_data['next']))
++            return self.cleaned_data['next']
++
++
+Index: templates/openid_signin.html
+===================================================================
+--- templates/openid_signin.html	(revision 19)
++++ templates/openid_signin.html	(working copy)
+@@ -1,3 +1,5 @@
++{% load i18n %}
++
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+ <html>
+@@ -13,10 +15,24 @@
+ </head>
+ <body>
+ <h1>Sign in with your OpenID</h1>
+-
+-<form action="{{ action }}" method="post">
+-<p><input class="openid" type="text" name="openid_url"> <input type="submit" value="Sign in"></p>
+-</form>
+-
++{% if form.errors %}
++<p class="errors">{% trans "Please correct errors below:" %}<br />
++	{% if form.openid_url.errors %} 
++		<span class="error">{{ form.openid_url.errors|join:", " }}</span>
++	{% endif %}
++	{% if form.next.errors %} 
++		<span class="error">{{ form.next.errors|join:", " }}</span>
++	{% endif %}
++</p>
++{% endif %}
++<form name="fopenid" action="{{ action }}" method="post">
++    {{ form.next }}
++	<fieldset>
++		<legend>{% trans "Sign In Using Your OpenID" %}</legend>
++        <div class="form-row"><label for="id_openid_ul">{% trans "OpenId URL :" %}</label><br />{{ form.openid_url }}</div>     
++        <div class="submit-row "><input name="bsignin" type="submit" value="{% trans "Sign in with OPENID" %}"></div>
++		
++	</fieldset>
++</form>	
+ </body>
+ </html>
 from django.conf.urls.defaults import patterns
 
-urlpatterns = patterns('',
+urlpatterns = patterns('django_authopenid.views',
      # manage account registration
-    (r'^signin/$', 'django_authopenid.views.signin'),
-    (r'^signout/$', 'django_authopenid.views.signout'),
-    (r'^complete/$', 'django_authopenid.views.complete_signin'),
-    (r'^register/$', 'django_authopenid.views.register'),
-    (r'^signup/$', 'django_authopenid.views.signup'),
-    (r'^signup/$', 'django_authopenid.views.signup'),
-    ('^sendpw/$', 'django_authopenid.views.sendpw'),
+    url(r'^%s$' % _('signin/'), 'signin', name='user_signin'),
+    url(r'^%s$' % _('signout/'), 'signout', name='user_signout'),
+    url(r'^%s%s$' % (_('signin/'), _('complete/')), 'complete_signin', name='user_complete_signin'),
+    url(r'^%s$' % _('register/'), 'register', name='user_register'),
+    url(r'^%s$' % _('signup/'), 'signup', name='user_signup'),
+    url(r'^%s$' % _('password/'), 'sendpw', name='user_sendpw'),
+    url(r'^%s%s$' % (_('password/'), _('confirm/')), 'confirmchangepw', name='user_confirmchangepw'),
 
     # manage account settings
-    (r'^(?P<username>\w+)/$', 'django_authopenid.views.account_settings'),
-    (r'^$', 'django_authopenid.views.account_settings'),
-    (r'^(?P<username>\w+)/changepw/$', 'django_authopenid.views.changepw'),
-    (r'^(?P<username>\w+)/changeemail/$', 'django_authopenid.views.changeemail'),
-    (r'^(?P<username>\w+)/changeopenid/$', 'django_authopenid.views.changeopenid'),
-    (r'^(?P<username>\w+)/delete/$', 'django_authopenid.views.delete'),
-    (r'^sendpw/confirm/$', 'django_authopenid.views.confirmchangepw'),
-
+    url(r'^(?P<username>\w+)/$', 'account_settings', name='user_account_settings'),
+    url(r'^$', 'account_settings', name='user_account_settings'),
+    url(r'^(?P<username>\w+)/%s$' % _('password/'), 'changepw', name='user_changepw'),
+    url(r'^(?P<username>\w+)/%s$' % _('email/'), 'changeemail', name='user_changeemail'),
+    url(r'^(?P<username>\w+)/%s$' % _('openid/'), 'changeopenid', name='user_changeopenid'),
+    url(r'^(?P<username>\w+)/%s$' % _('delete/'), 'delete', name='user_delete'),
+    
+    
 )
 from django.conf import settings
 from django.contrib.auth.models import User
 from django.contrib.auth import authenticate,login,logout
+from django.contrib.auth.decorators import login_required
 from django.core.urlresolvers import reverse
 from django.utils.html import escape
 from django.utils.translation import ugettext as _
 
 from openid.consumer.consumer import Consumer
 from openid.consumer.discover import DiscoveryFailure
-from yadis import xri
+
+
+# needed for some linux distributions like debian
+try:
+    from openid.yadis import xri
+except:
+    from yadis import xri
 
 import urllib
 
 
                 extension_args['sreg.optional'] = 'email,nickname'
                 redirect_to = "%s?next=%s" % (
-                        get_url_host(request) + reverse('django_authopenid.views.complete_signin'), 
+                        get_url_host(request) + reverse('user_complete_signin'), 
                         urllib.urlencode({'next':next}))
 
                 return ask_openid(request, 
         'form2': form_signin,
         'action': request.path,
         'msg':  request.GET.get('msg',''),
-        'sendpw_url': reverse('django_authopenid.views.sendpw'),
+        'sendpw_url': reverse('user_sendpw'),
     })
 
 def complete_signin(request):
     if openids and len(openids)>0:
         openid = openids[-1] # Last authenticated OpenID
     else:
-         return HttpResponseRedirect(reverse('django_authopenid.views.signin') + next)
+         return HttpResponseRedirect(reverse('user_signin') + next)
 
     nickname = openid.sreg.get('nickname', '')
     email = openid.sreg.get('email', '')
     return render('authopenid/complete.html', {
         'form1': form1,
         'form2': form2,
-        'action': reverse('django_authopenid.views.register'),
+        'action': reverse('user_register'),
         'nickname': nickname,
         'email': email
     }, context_instance=RequestContext(request))
 
     template : "authopenid/openid.html"
     """
-    request_path=reverse('friendsnippets.django_authopenid.views.signin')
+    request_path=reverse('user_signin')
     if request.GET.get('next'):
         request_path += '?' + urllib.urlencode({
             'next': request.GET['next']
 
     templates: authopenid/signup.html, authopenid/confirm_email.txt
     """
-    action_signin = reverse('django_authopenid.views.signin')
+    action_signin = reverse('user_signin')
 
     next = request.GET.get('next', '/')
     form = RegistrationForm(initial={'next':next})
         'action_signin': action_signin,
         },context_instance=RequestContext(request))
 
-    
+@login_required   
 def signout(request):
     """
     signout from the website. Remove openid from session and kill it.
     return HttpResponseRedirect(next)
 
 
-
+@login_required
+@username_control ('user_account_settings')
 def account_settings(request,username=None):
     """
     index pages to changes some basic account settings :
     return render('account/settings.html',
             {'msg': msg, 'settings_path': request.path, 'is_openid': is_openid},
             context_instance=RequestContext(request))
-account_settings = username_test(account_settings, 'django_authopenid.views.account_settings')
 
-
+@login_required
+@username_control('user_changepw')
 def changepw(request,username):
     """
     change password view.
             u.set_password(form.cleaned_data['password1'])
             u.save()
             msg=_("Password changed.") 
-            redirect="%s?msg=%s" % (reverse('django_authopenid.views.account_settings',kwargs={'username': request.user.username}),urlquote_plus(msg))
+            redirect="%s?msg=%s" % (reverse('user_account_settings',kwargs={'username': request.user.username}),urlquote_plus(msg))
             return HttpResponseRedirect(redirect)
     else:
         form=ChangepwForm(initial={'username':request.user.username})
     return render('account/changepw.html', {'form': form },
                                 context_instance=RequestContext(request))
 
-changepw = username_test(changepw, 'django_authopenid.views.changepw')
 
-
+@login_required
+@username_control('user_changeemail')
 def changeemail(request,username):
     """ 
     changeemail view. It require password or openid to allow change.
                 u.email = form.cleaned_data['email']
                 u.save()
                 msg=_("Email changed.") 
-                redirect="%s?msg=%s" % (reverse('django_authopenid.views.account_settings', kwargs={'username': request.user.username}),urlquote_plus(msg))
+                redirect="%s?msg=%s" % (reverse('user_account_settings', kwargs={'username': request.user.username}),urlquote_plus(msg))
                 return HttpResponseRedirect(redirect)
             else:
-                redirect_to = "%s?new_email=%s" % (get_url_host(request) + reverse('django_authopenid.views.changeemail',kwargs={'username':username}),form.cleaned_data['email'])
+                redirect_to = "%s?new_email=%s" % (get_url_host(request) + reverse('user_changeemail',kwargs={'username':username}),form.cleaned_data['email'])
                 
                 return ask_openid(request, form.cleaned_data['password'], redirect_to, on_failure=emailopenid_failure)    
     elif not request.POST and 'openid.mode' in request.GET:
     
     return render('account/changeemail.html', 
             {'form': form }, context_instance=RequestContext(request))
-changeemail = username_test(changeemail, 'django_authopenid.views.changeemail')
 
 def emailopenid_success(request, identity_url, openid_response):
     openid=from_openid_response(openid_response)
         u.save()
     msg=_("Email Changed.")
 
-    redirect="%s?msg=%s" % (reverse('django_authopenid.views.account_settings',kwargs={'username': request.user.username}),urlquote_plus(msg))
+    redirect="%s?msg=%s" % (reverse('user_account_settings',kwargs={'username': request.user.username}),urlquote_plus(msg))
     return HttpResponseRedirect(redirect)
     
 
 def emailopenid_failure(request, message):
-    redirect_to="%s?msg=%s" % (reverse('django_authopenid.views.changeemail',kwargs={'username':request.user.username}), urlquote_plus(message))
+    redirect_to="%s?msg=%s" % (reverse('user_changeemail',kwargs={'username':request.user.username}), urlquote_plus(message))
 
     return HttpResponseRedirect(redirect_to)
  
 
-
+@login_required
+@username_control('user_changeopenid')
 def changeopenid(request, username):
     """
     change openid view. Allow user to change openid associated to its username.
     if request.POST and has_openid:
         form=ChangeopenidForm(request.POST)
         if form.is_valid():
-            redirect_to = get_url_host(request) + reverse('django_authopenid.views.changeopenid',kwargs={'username':username})
+            redirect_to = get_url_host(request) + reverse('user_changeopenid',kwargs={'username':username})
             return ask_openid(request, form.cleaned_data['openid_url'], redirect_to, on_failure=changeopenid_failure)
     elif not request.POST and has_openid:
         if 'openid.mode' in request.GET:
     return render('account/changeopenid.html', {'form': form,
         'has_openid': has_openid, 'msg': msg }, context_instance=RequestContext(request))
 
-changeopenid = username_test(changeopenid, 'django_authopenid.views.changeopenid')
 
 def changeopenid_success(request, identity_url, openid_response):
     openid=from_openid_response(openid_response)
     request.session['openids'].append(openid)
 
     msg=_("Openid %s associated with your account." % identity_url) 
-    redirect="%s?msg=%s" % (reverse('django_authopenid.views.account_settings', kwargs={'username':request.user.username}), urlquote_plus(msg))
+    redirect="%s?msg=%s" % (reverse('user_account_settings', kwargs={'username':request.user.username}), urlquote_plus(msg))
     return HttpResponseRedirect(redirect)
     
 
 def changeopenid_failure(request, message):
-    redirect_to="%s?msg=%s" % (reverse('django_authopenid.views.changeopenid',kwargs={'username':request.user.username}), urlquote_plus(message))
+    redirect_to="%s?msg=%s" % (reverse('user_changeopenid',kwargs={'username':request.user.username}), urlquote_plus(message))
     return HttpResponseRedirect(redirect_to)
-    
+
+@login_required
+@username_control('user_delete')
 def delete(request,username):
     """
     delete view. Allow user to delete its account. Password/openid are required to 
         if form.is_valid():
             if not form.test_openid:
                 u.delete()
-                from friendsnippets.django_openidconsumer.views import signout
                 return signout(request)
             else:
-                redirect_to = get_url_host(request) + reverse('django_authopenid.views.delete',kwargs={'username':username})
+                redirect_to = get_url_host(request) + reverse('user_delete',kwargs={'username':username})
                 return ask_openid(request, form.cleaned_data['password'], redirect_to, on_failure=deleteopenid_failure)
     elif not request.POST and 'openid.mode' in request.GET:
         return complete(request, deleteopenid_success, deleteopenid_failure) 
     return render('account/delete.html', {'form': form, 'msg': msg, },
                                         context_instance=RequestContext(request))
 
-delete = username_test(delete, 'django_authopenid.views.delete')
 
 def deleteopenid_success(request, identity_url, openid_response):
     openid=from_openid_response(openid_response)
     
 
 def deleteopenid_failure(request, message):
-    redirect_to="%s?msg=%s" % (reverse('django_authopenid.views.delete',kwargs={'username':request.user.username}), urlquote_plus(message))
+    redirect_to="%s?msg=%s" % (reverse('user_delete',kwargs={'username':request.user.username}), urlquote_plus(message))
 
     return HttpResponseRedirect(redirect_to)
 
                 'confirm_key': confirm_key,
                 'username': form.user_cache.username,
                 'password': new_pw,
-                'url_confirm': reverse('django_authopenid.views.confirmchangepw'),
+                'url_confirm': reverse('user_confirmchangepw'),
             })
             message = message_template.render(message_context)
             send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [form.user_cache.email])
         q = UserPasswordQueue.objects.get(confirm_key__exact=confirm_key)
     except:
         msg=_("Can not change password. Confirmation key '%s' isn't registered." % confirm_key) 
-        redirect="%s?msg=%s" % (reverse('django_authopenid.views.sendpw'),urlquote_plus(msg))
+        redirect="%s?msg=%s" % (reverse('user_sendpw'),urlquote_plus(msg))
         return HttpResponseRedirect(redirect)
 
     try:
         user = User.objects.get(id=q.user.id)
     except:
         msg=_("Can not change password. User don't exist anymore in our database.") 
-        redirect="%s?msg=%s" % (reverse('django_authopenid.views.sendpw'),urlquote_plus(msg))
+        redirect="%s?msg=%s" % (reverse('user_sendpw'),urlquote_plus(msg))
         return HttpResponseRedirect(redirect)
 
     user.set_password(q.new_password)
     user.save()
     q.delete()
     msg=_("Password changed for %s. You could now sign-in" % user.username) 
-    redirect="%s?msg=%s" % (reverse('django_authopenid.views.signin'), 
+    redirect="%s?msg=%s" % (reverse('user_signin'), 
                                         urlquote_plus(msg))
 
     return HttpResponseRedirect(redirect)