Commit 63ecdd20 authored by Sofia Papagiannaki's avatar Sofia Papagiannaki
Browse files

Set cookie and delete cookie and other minor changes.

* 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
parent a196eb7e
......@@ -33,12 +33,8 @@
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
......
......@@ -31,23 +31,17 @@
# 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
......
......@@ -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)
......
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.core.validators import email_re
......
......@@ -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.')
......
......@@ -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
......@@ -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
......
......@@ -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):
......
......@@ -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')
......
......@@ -31,21 +31,17 @@
# 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'):
......
......@@ -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
......
......@@ -32,11 +32,9 @@
# 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'),
......
......@@ -35,20 +35,15 @@
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)
......
# 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
......@@ -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
......
......@@ -32,13 +32,20 @@
# 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
......@@ -31,39 +31,31 @@
# 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
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment