redirect.py 5.07 KB
Newer Older
Antony Chazapis's avatar
Antony Chazapis committed
1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#
# 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.

Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
34
from django.core.urlresolvers import reverse
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
35
36
from django.utils.translation import ugettext as _
from django.utils.http import urlencode
37
from django.contrib.auth import authenticate
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
38
from django.http import HttpResponse, HttpResponseBadRequest
39
from django.core.exceptions import ValidationError
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
40

41
from urlparse import urlunsplit, urlsplit, parse_qsl
42

43
from astakos.im.settings import COOKIE_NAME, COOKIE_DOMAIN
44
from astakos.im.util import set_cookie
45
from astakos.im.functions import login as auth_login, logout
46

47
48
49
50
import logging

logger = logging.getLogger(__name__)

51
def login(request):
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
52
    """
53
54
55
56
57
    If there is no ``next`` request parameter redirects to astakos index page
    displaying an error message.
    If the request user is authenticated and has signed the approval terms,
    redirects to `next` request parameter. If not, redirects to approval terms
    in order to return back here after agreeing with the terms.
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
58
    Otherwise, redirects to login in order to return back here after successful login.
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
59
    """
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
60
61
62
63
64
65
66
67
    next = request.GET.get('next')
    if not next:
        return HttpResponseBadRequest(_('No next parameter'))
    force = request.GET.get('force', None)
    response = HttpResponse()
    if force == '':
        logout(request)
        response.delete_cookie(COOKIE_NAME, path='/', domain=COOKIE_DOMAIN)
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
68
    if request.user.is_authenticated():
69
70
        # if user has not signed the approval terms
        # redirect to approval terms with next the request path
71
        if not request.user.signed_terms:
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
            # first build next parameter
            parts = list(urlsplit(request.build_absolute_uri()))
            params = dict(parse_qsl(parts[3], keep_blank_values=True))
            # delete force parameter
            parts[3] = urlencode(params)
            next = urlunsplit(parts)
            
            # build url location
            parts[2] = reverse('latest_terms')
            params = {'next':next}
            parts[3] = urlencode(params)
            url = urlunsplit(parts)
            response['Location'] = url
            response.status_code = 302
            return response
87
        renew = request.GET.get('renew', None)
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
88
89
        if renew == '':
            request.user.renew_token()
90
91
92
93
            try:
                request.user.save()
            except ValidationError, e:
                return HttpResponseBadRequest(e)
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
94
            # authenticate before login
95
96
97
            user = authenticate(email=request.user.email,
                auth_token=request.user.auth_token
            )
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
98
99
100
101
            auth_login(request, user)
            set_cookie(response, user)
            logger.info('Token reset for %s' % request.user.email)
        parts = list(urlsplit(next))
102
103
104
105
        parts[3] = urlencode({'user': request.user.email,
            'token': request.user.auth_token
            }
        )
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
106
107
108
109
        url = urlunsplit(parts)
        response['Location'] = url
        response.status_code = 302
        return response
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
110
    else:
111
        # redirect to login with next the request path
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
112
113
114
115
116
117
118
119
120
121
122
        
        # first build next parameter
        parts = list(urlsplit(request.build_absolute_uri()))
        params = dict(parse_qsl(parts[3], keep_blank_values=True))
        # delete force parameter
        if 'force' in params:
            del params['force']
        parts[3] = urlencode(params)
        next = urlunsplit(parts)
        
        # build url location
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
123
        parts[2] = reverse('index')
Sofia Papagiannaki's avatar
Sofia Papagiannaki committed
124
125
126
127
128
129
        params = {'next':next}
        parts[3] = urlencode(params)
        url = urlunsplit(parts)
        response['Location'] = url
        response.status_code = 302
        return response