Set cookie and delete cookie and other minor changes.
authorSofia Papagiannaki <papagian@gmail.com>
Thu, 2 Feb 2012 10:31:24 +0000 (12:31 +0200)
committerSofia Papagiannaki <papagian@gmail.com>
Thu, 2 Feb 2012 10:31:24 +0000 (12:31 +0200)
* move login and setting cookie in one place (prepare_response)
* delete cookie in logout
* delete unused imports
* change requires_anonymous to redirect to logout with next

18 files changed:
astakos/im/admin/forms.py
astakos/im/admin/views.py
astakos/im/api.py
astakos/im/auth_backends.py
astakos/im/backends.py
astakos/im/context_processors.py
astakos/im/forms.py
astakos/im/models.py
astakos/im/target/invitation.py
astakos/im/target/local.py
astakos/im/target/redirect.py
astakos/im/target/shibboleth.py
astakos/im/target/twitter.py
astakos/im/target/util.py [deleted file]
astakos/im/urls.py
astakos/im/util.py
astakos/im/views.py
astakos/settings.py

index 38de725..884cb96 100644 (file)
 
 from django import forms
 from django.utils.translation import ugettext as _
-from django.contrib.auth.forms import UserCreationForm
-from django.conf import settings
-from hashlib import new as newhasher
 
 from astakos.im.models import AstakosUser
-from astakos.im.util import get_or_create_user
 from astakos.im.forms import LocalUserCreationForm
 
 import logging
index aa917e1..bd54ba1 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-import json
 import logging
 import socket
 import csv
-import sys
 
-from datetime import datetime
 from functools import wraps
 from math import ceil
-from random import randint
 from smtplib import SMTPException
-from hashlib import new as newhasher
-from urllib import quote
 
 from django.conf import settings
 from django.core.mail import send_mail
-from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
+from django.http import HttpResponse, HttpResponseRedirect
 from django.shortcuts import redirect
 from django.template.loader import render_to_string
 from django.utils.http import urlencode
@@ -55,13 +49,10 @@ from django.utils.translation import ugettext as _
 from django.core.urlresolvers import reverse
 from django.contrib import messages
 from django.db import transaction
-from django.contrib.auth.models import AnonymousUser
-from django.contrib.sites.models import Site
 
 from astakos.im.models import AstakosUser, Invitation
-from astakos.im.util import isoformat, get_context, get_current_site
+from astakos.im.util import get_context, get_current_site
 from astakos.im.forms import *
-from astakos.im.backends import get_backend
 from astakos.im.views import render_response, index
 from astakos.im.admin.forms import AdminProfileForm
 from astakos.im.admin.forms import AdminUserCreationForm
index 710e28c..009af45 100644 (file)
@@ -40,8 +40,6 @@ from django.utils import simplejson as json
 from astakos.im.faults import BadRequest, Unauthorized, ServiceUnavailable
 from astakos.im.models import AstakosUser
 
-import datetime
-
 def render_fault(request, fault):
     if settings.DEBUG or settings.TEST:
         fault.details = format_exc(fault)
index bc602e8..bae0532 100644 (file)
@@ -1,4 +1,3 @@
-from django.conf import settings
 from django.contrib.auth.backends import ModelBackend
 from django.core.validators import email_re
 
index 520251f..b19066b 100644 (file)
@@ -37,13 +37,9 @@ from django.core.exceptions import ImproperlyConfigured
 from django.core.mail import send_mail
 from django.template.loader import render_to_string
 from django.utils.translation import ugettext as _
-from django.contrib.auth import authenticate, login
-from django.contrib.auth.forms import UserCreationForm
 from django.contrib.sites.models import Site
 from django.contrib import messages
-from django.shortcuts import redirect
 from django.db import transaction
-from django.core.urlresolvers import reverse
 
 from smtplib import SMTPException
 from urllib import quote
@@ -159,9 +155,6 @@ class InvitationsBackend(object):
             if self._is_preaccepted(user):
                 user.is_active = True
                 user.save()
-                # get the raw password from the form
-                user = authenticate(email=user.email, auth_token=user.auth_token)
-                login(self.request, user)
                 message = _('Registration completed. You can now login.')
             else:
                 message = _('Registration completed. You will receive an email upon your account\'s activation.')
index c9c0c54..157f71c 100644 (file)
@@ -43,5 +43,4 @@ def code(request):
     return {'code' : request.GET.get('code', '')}
 
 def invitations(request):
-    return {'invitations_enabled' :settings.INVITATIONS_ENABLED}
-    
\ No newline at end of file
+    return {'invitations_enabled' :settings.INVITATIONS_ENABLED}
\ No newline at end of file
index b80d5cd..ff4aef4 100644 (file)
@@ -35,15 +35,11 @@ from django import forms
 from django.utils.translation import ugettext as _
 from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, PasswordResetForm
 from django.conf import settings
-from django.core.validators import email_re
-from django.conf import settings
 from django.core.mail import send_mail
 from django.contrib.auth.tokens import default_token_generator
 from django.template import Context, loader
 from django.utils.http import int_to_base36
 
-from hashlib import new as newhasher
-
 from astakos.im.models import AstakosUser
 from astakos.im.util import get_current_site
 
index 4d225c5..f96b7d5 100644 (file)
@@ -31,7 +31,6 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-import logging
 import hashlib
 import uuid
 
@@ -42,7 +41,6 @@ from base64 import b64encode
 from django.conf import settings
 from django.db import models
 from django.contrib.auth.models import User, UserManager
-from django.utils.translation import ugettext_lazy as _
 
 from astakos.im.interface import get_quota, set_quota
 
@@ -115,7 +113,6 @@ class AstakosUser(User):
                     self.provider = 'local'
                 self.date_joined = datetime.now()
             self.updated = datetime.now()
-        
         super(AstakosUser, self).save(**kwargs)
     
     def renew_token(self):
index c195bcc..b1b86e7 100644 (file)
@@ -35,13 +35,11 @@ import logging
 
 from datetime import datetime
 
-from django.conf import settings
 from django.http import HttpResponseBadRequest
 from django.contrib.auth import authenticate
 
 from astakos.im.models import Invitation
-from astakos.im.target.util import prepare_response
-from astakos.im.util import get_or_create_user
+from astakos.im.util import get_or_create_user, prepare_response
 
 def login(request):
     code = request.GET.get('code')
index 4939cd7..48dfc75 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
-from django.conf import settings
-from django.template.loader import render_to_string
+from django.http import HttpResponseBadRequest
 from django.shortcuts import render_to_response
 from django.template import RequestContext
 from django.contrib.auth import authenticate
 from django.contrib import messages
 from django.utils.translation import ugettext as _
 
-from astakos.im.target.util import prepare_response, requires_anonymous
+from astakos.im.util import prepare_response
+from astakos.im.views import requires_anonymous
 from astakos.im.models import AstakosUser
 from astakos.im.forms import LoginForm
-from urllib import unquote
-
-from hashlib import new as newhasher
 
 @requires_anonymous
 def login(request, on_failure='login.html'):
index 5c4f7dc..a445c12 100644 (file)
@@ -31,7 +31,6 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.http import HttpResponseBadRequest
 from django.core.urlresolvers import reverse
 from django.shortcuts import redirect
 from django.utils.translation import ugettext as _
@@ -41,8 +40,6 @@ from django.utils.http import urlencode
 from urllib import quote
 from urlparse import urlunsplit, urlsplit
 
-from astakos.im.target.util import prepare_response
-
 def login(request):
     """
     If the request user is authenticated, redirects to `next` request parameter
index 66a75b8..fabbacc 100644 (file)
 # or implied, of GRNET S.A.
 
 from django.http import HttpResponseBadRequest
-from django.core.urlresolvers import reverse
-from django.contrib.auth import authenticate
 
-from astakos.im.target.util import prepare_response
-from astakos.im.util import get_or_create_user
+from astakos.im.util import get_or_create_user, prepare_response
+from astakos.im.views import requires_anonymous
 
 class Tokens:
     # these are mapped by the Shibboleth SP software
@@ -48,7 +46,7 @@ class Tokens:
     SHIB_EP_AFFILIATION = "HTTP_SHIB_EP_AFFILIATION"
     SHIB_SESSION_ID = "HTTP_SHIB_SESSION_ID"
 
-
+@requires_anonymous
 def login(request):
     tokens = request.META
     
@@ -69,8 +67,6 @@ def login(request):
     affiliation = tokens.get(Tokens.SHIB_EP_AFFILIATION, '')
     
     user = get_or_create_user(eppn, realname=realname, affiliation=affiliation, provider='shibboleth', level=0)
-    # in order to login the user we must call authenticate first
-    user = authenticate(email=user.email, auth_token=user.auth_token)
     return prepare_response(request,
                             user,
                             request.GET.get('next'),
index e97f3d0..d1d8123 100644 (file)
 
 import oauth2 as oauth
 import urlparse
-import  traceback
 
 from django.conf import settings
 from django.http import HttpResponse
 from django.utils import simplejson as json
-from django.contrib.auth import authenticate
 from django.contrib import messages
-from django.shortcuts import redirect
 
-from astakos.im.target.util import prepare_response, requires_anonymous
-from astakos.im.util import get_or_create_user, get_context
-from astakos.im.models import AstakosUser, Invitation
-from astakos.im.views import render_response, create_user
-from astakos.im.backends import get_backend
+from astakos.im.util import get_context, prepare_response
+from astakos.im.models import AstakosUser
+from astakos.im.views import render_response, create_user, requires_anonymous
 from astakos.im.forms import LocalUserCreationForm, ThirdPartyUserCreationForm
 from astakos.im.faults import BadRequest
 
@@ -138,8 +133,7 @@ def authenticated(request, backend=None, template_name='login.html', extra_conte
     user = None
     email = request.session.pop('email')
     
-    # signup mode
-    if email:
+    if email: # signup mode
         if not reserved_screen_name(screen_name): 
             try:
                 user = AstakosUser.objects.get(email = email)
@@ -153,16 +147,13 @@ def authenticated(request, backend=None, template_name='login.html', extra_conte
             status = messages.ERROR
             message = '%s@twitter is already registered' % screen_name
             messages.add_message(request, messages.ERROR, message)
-    else:
-        # login mode
+    else: # login mode
         try:
             user = AstakosUser.objects.get(third_party_identifier = screen_name,
                                            provider = 'Twitter')
         except AstakosUser.DoesNotExist:
             messages.add_message(request, messages.ERROR, 'Not registered user')
         if user and user.is_active:
-            #in order to login the user we must call authenticate first
-            user = authenticate(email=user.email, auth_token=user.auth_token)
             return prepare_response(request, user, next)
         elif user and not user.is_active:
             messages.add_message(request, messages.ERROR, 'Inactive account: %s' % user.email)
diff --git a/astakos/im/target/util.py b/astakos/im/target/util.py
deleted file mode 100644 (file)
index d9808f3..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2011-2012 GRNET S.A. All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or
-# without modification, are permitted provided that the following
-# conditions are met:
-# 
-#   1. Redistributions of source code must retain the above
-#      copyright notice, this list of conditions and the following
-#      disclaimer.
-# 
-#   2. Redistributions in binary form must reproduce the above
-#      copyright notice, this list of conditions and the following
-#      disclaimer in the documentation and/or other materials
-#      provided with the distribution.
-# 
-# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
-# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-# 
-# The views and conclusions contained in the software and
-# documentation are those of the authors and should not be
-# interpreted as representing official policies, either expressed
-# or implied, of GRNET S.A.
-
-import datetime
-
-from urlparse import urlsplit, urlunsplit
-from urllib import quote
-from functools import wraps
-
-from django.http import HttpResponse
-from django.utils.http import urlencode
-from django.core.urlresolvers import reverse
-from django.conf import settings
-from django.contrib.auth import login, logout
-
-def prepare_response(request, user, next='', renew=False, skip_login=False):
-    """Return the unique username and the token
-       as 'X-Auth-User' and 'X-Auth-Token' headers,
-       or redirect to the URL provided in 'next'
-       with the 'user' and 'token' as parameters.
-       
-       Reissue the token even if it has not yet
-       expired, if the 'renew' parameter is present
-       or user has not a valid token.
-    """
-    
-    renew = renew or (not user.auth_token)
-    renew = renew or (user.auth_token_expires and user.auth_token_expires < datetime.datetime.now())
-    if renew:
-        user.renew_token()
-        user.save()
-    
-    if next:
-        # TODO: Avoid redirect loops.
-        parts = list(urlsplit(next))
-        if not parts[1] or (parts[1] and request.get_host() != parts[1]):
-            parts[3] = urlencode({'user': user.email, 'token': user.auth_token})
-            next = urlunsplit(parts)
-    
-    if settings.FORCE_PROFILE_UPDATE and not user.is_verified and not user.is_superuser:
-        params = ''
-        if next:
-            params = '?' + urlencode({'next': next})
-        next = reverse('astakos.im.views.edit_profile') + params
-    
-    # user login
-    if not skip_login:
-        login(request, user)
-    
-    response = HttpResponse()
-    
-    # set cookie
-    expire_fmt = user.auth_token_expires.strftime('%a, %d-%b-%Y %H:%M:%S %Z')  
-    cookie_value = quote(user.email + '|' + user.auth_token)
-    response.set_cookie(settings.COOKIE_NAME, value=cookie_value,
-                        expires=expire_fmt, path='/',
-                        domain = settings.COOKIE_DOMAIN)
-    
-    if not next:
-        next = reverse('astakos.im.views.index')
-    
-    response['Location'] = next
-    response.status_code = 302
-    return response
-
-def requires_anonymous(func):
-    """
-    Decorator checkes whether the request.user is an Anonymous and if not
-    logouts the request.user.
-    """
-    @wraps(func)
-    def wrapper(request, *args):
-        if not request.user.is_anonymous():
-            logout(request)
-        return func(request, *args)
-    return wrapper
index 42a1a5e..d04b21d 100644 (file)
@@ -33,7 +33,6 @@
 
 from django.conf import settings
 from django.conf.urls.defaults import patterns, include, url
-from django.core.urlresolvers import reverse
 
 from astakos.im.forms import ExtendedPasswordResetForm
 
index 86b96e7..633c583 100644 (file)
 # or implied, of GRNET S.A.
 
 import logging
+import datetime
+
+from urllib import quote
+from urlparse import urlsplit, urlunsplit
+from functools import wraps
 
 from datetime import tzinfo, timedelta
+from django.http import HttpResponse, urlencode
 from django.conf import settings
 from django.template import RequestContext
 from django.contrib.sites.models import Site
 from django.utils.translation import ugettext as _
-from django.contrib import messages
+from django.contrib.auth import login, authenticate
+from django.core.urlresolvers import reverse
 
 from astakos.im.models import AstakosUser, Invitation
 
@@ -115,4 +122,54 @@ def get_invitation(request):
         raise ValueError(_('Email: %s is reserved' % invitation.username))
     except AstakosUser.DoesNotExist:
         pass
-    return invitation
\ No newline at end of file
+    return invitation
+
+def prepare_response(request, user, next='', renew=False, skip_login=False):
+    """Return the unique username and the token
+       as 'X-Auth-User' and 'X-Auth-Token' headers,
+       or redirect to the URL provided in 'next'
+       with the 'user' and 'token' as parameters.
+       
+       Reissue the token even if it has not yet
+       expired, if the 'renew' parameter is present
+       or user has not a valid token.
+    """
+    
+    renew = renew or (not user.auth_token)
+    renew = renew or (user.auth_token_expires and user.auth_token_expires < datetime.datetime.now())
+    if renew:
+        user.renew_token()
+        user.save()
+    
+    if next:
+        # TODO: Avoid redirect loops.
+        parts = list(urlsplit(next))
+        if not parts[1] or (parts[1] and request.get_host() != parts[1]):
+            parts[3] = urlencode({'user': user.email, 'token': user.auth_token})
+            next = urlunsplit(parts)
+    
+    if settings.FORCE_PROFILE_UPDATE and not user.is_verified and not user.is_superuser:
+        params = ''
+        if next:
+            params = '?' + urlencode({'next': next})
+        next = reverse('astakos.im.views.edit_profile') + params
+    
+    response = HttpResponse()
+    
+    if not skip_login:
+        # authenticate before login
+        user = authenticate(email=user.email, auth_token=user.auth_token)
+        login(request, user)
+        # set cookie
+        expire_fmt = user.auth_token_expires.strftime('%a, %d-%b-%Y %H:%M:%S %Z')
+        cookie_value = quote(user.email + '|' + user.auth_token)
+        response.set_cookie(settings.COOKIE_NAME, value=cookie_value,
+                            expires=expire_fmt, path='/',
+                            domain = settings.COOKIE_DOMAIN)
+    
+    if not next:
+        next = reverse('astakos.im.views.index')
+    
+    response['Location'] = next
+    response.status_code = 302
+    return response
\ No newline at end of file
index 30944ea..7254b9b 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-import json
 import logging
 import socket
-import csv
-import sys
 
-from datetime import datetime
-from functools import wraps
-from math import ceil
 from random import randint
 from smtplib import SMTPException
-from hashlib import new as newhasher
 from urllib import quote
+from functools import wraps
 
 from django.conf import settings
 from django.core.mail import send_mail
-from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
+from django.http import HttpResponse
 from django.shortcuts import redirect
 from django.template.loader import render_to_string
-from django.shortcuts import render_to_response
-from django.utils.http import urlencode
 from django.utils.translation import ugettext as _
 from django.core.urlresolvers import reverse
-from django.contrib.auth.models import AnonymousUser
 from django.contrib.auth.decorators import login_required
-from django.contrib.sites.models import Site
 from django.contrib import messages
 from django.db import transaction
-from django.contrib.auth.forms import UserCreationForm
+from django.contrib.auth.views import logout
+from django.utils.http import urlencode
+from django.http import HttpResponseRedirect
 
 from astakos.im.models import AstakosUser, Invitation
 from astakos.im.backends import get_backend
-from astakos.im.util import get_context, get_current_site, get_invitation
+from astakos.im.util import get_context, get_current_site, prepare_response
 from astakos.im.forms import *
 
 def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
@@ -78,6 +70,21 @@ def render_response(template, tab=None, status=200, context_instance=None, **kwa
     html = render_to_string(template, kwargs, context_instance=context_instance)
     return HttpResponse(html, status=status)
 
+
+def requires_anonymous(func):
+    """
+    Decorator checkes whether the request.user is Anonymous and in that case
+    redirects to `user_logout`.
+    """
+    @wraps(func)
+    def wrapper(request, *args):
+        if not request.user.is_anonymous():
+            next = urlencode({'next': request.build_absolute_uri()})
+            login_uri = reverse(user_logout) + '?' + next
+            return HttpResponseRedirect(login_uri)
+        return func(request, *args)
+    return wrapper
+
 def index(request, login_template_name='login.html', profile_template_name='profile.html', extra_context={}):
     """
     If there is logged on user renders the profile page otherwise renders login page.
@@ -306,9 +313,8 @@ def signup(request, template_name='signup.html', extra_context={}, backend=None)
                     return redirect(url)
                 else:
                     status, message, user = backend.signup(form)
-                    if status == messages.SUCCESS:
-                        if next:
-                            return redirect(next)
+                    if user and user.is_active:
+                        return prepare_response(request, user, next=next)
                     messages.add_message(request, status, message)    
     except (Invitation.DoesNotExist, ValueError), e:
         messages.add_message(request, messages.ERROR, e)
@@ -385,8 +391,8 @@ def create_user(request, form, backend=None, post_data={}, next = None, template
                 for k,v in post_data.items():
                     setattr(user,k, v)
                 user.save()
-                if next:
-                    return redirect(next)
+                if user.is_active():
+                    return prepare_response(request, user, next=next)
             messages.add_message(request, status, message)
         else:
             messages.add_message(request, messages.ERROR, form.errors)
@@ -397,8 +403,14 @@ def create_user(request, form, backend=None, post_data={}, next = None, template
                            context_instance=get_context(request, extra_context))
 
 def user_logout(request):
-    response = HttpResponse()
+    """
+    Wraps `django.contrib.auth.views.logout` and delete the cookie.
+    """
+    response = logout(request)
     response.delete_cookie(settings.COOKIE_NAME)
-    response['Location'] = reverse('django.contrib.auth.views.logout')
-    response.status_code = 302
+    next = request.GET.get('next')
+    if next:
+        response['Location'] = next
+        response.status_code = 302
+        return response
     return response
\ No newline at end of file
index 8e388be..27aa861 100644 (file)
@@ -32,7 +32,6 @@
 # or implied, of GRNET S.A.
 
 from glob import glob
-from os import umask
 from os.path import abspath, dirname, exists, join