Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / util.py @ cc9e2c94

History | View | Annotate | Download (5.7 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 64cd4730 Antony Chazapis
# 
3 64cd4730 Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 64cd4730 Antony Chazapis
# without modification, are permitted provided that the following
5 64cd4730 Antony Chazapis
# conditions are met:
6 64cd4730 Antony Chazapis
# 
7 64cd4730 Antony Chazapis
#   1. Redistributions of source code must retain the above
8 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
9 64cd4730 Antony Chazapis
#      disclaimer.
10 64cd4730 Antony Chazapis
# 
11 64cd4730 Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
13 64cd4730 Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 64cd4730 Antony Chazapis
#      provided with the distribution.
15 64cd4730 Antony Chazapis
# 
16 64cd4730 Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 64cd4730 Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 64cd4730 Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 64cd4730 Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 64cd4730 Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 64cd4730 Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 64cd4730 Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 64cd4730 Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 64cd4730 Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 64cd4730 Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 64cd4730 Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 64cd4730 Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 64cd4730 Antony Chazapis
# 
29 64cd4730 Antony Chazapis
# The views and conclusions contained in the software and
30 64cd4730 Antony Chazapis
# documentation are those of the authors and should not be
31 64cd4730 Antony Chazapis
# interpreted as representing official policies, either expressed
32 64cd4730 Antony Chazapis
# or implied, of GRNET S.A.
33 64cd4730 Antony Chazapis
34 0905ccd2 Sofia Papagiannaki
import logging
35 63ecdd20 Sofia Papagiannaki
import datetime
36 18ffbee1 Sofia Papagiannaki
import time
37 63ecdd20 Sofia Papagiannaki
38 63ecdd20 Sofia Papagiannaki
from urllib import quote
39 63ecdd20 Sofia Papagiannaki
from urlparse import urlsplit, urlunsplit
40 63ecdd20 Sofia Papagiannaki
from functools import wraps
41 0905ccd2 Sofia Papagiannaki
42 64cd4730 Antony Chazapis
from datetime import tzinfo, timedelta
43 27e26a41 Sofia Papagiannaki
from django.http import HttpResponse, HttpResponseBadRequest, urlencode
44 0905ccd2 Sofia Papagiannaki
from django.template import RequestContext
45 e2125441 Sofia Papagiannaki
from django.contrib.sites.models import Site
46 15efc749 Sofia Papagiannaki
from django.utils.translation import ugettext as _
47 63ecdd20 Sofia Papagiannaki
from django.contrib.auth import login, authenticate
48 63ecdd20 Sofia Papagiannaki
from django.core.urlresolvers import reverse
49 27e26a41 Sofia Papagiannaki
from django.core.exceptions import ValidationError
50 64cd4730 Antony Chazapis
51 270dd48d Sofia Papagiannaki
from astakos.im.models import AstakosUser, Invitation, ApprovalTerms
52 ca34523e Antony Chazapis
from astakos.im.settings import INVITATIONS_PER_LEVEL, COOKIE_NAME, COOKIE_DOMAIN, COOKIE_SECURE, FORCE_PROFILE_UPDATE
53 64cd4730 Antony Chazapis
54 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
55 e015e9e6 Sofia Papagiannaki
56 64cd4730 Antony Chazapis
class UTC(tzinfo):
57 64cd4730 Antony Chazapis
   def utcoffset(self, dt):
58 64cd4730 Antony Chazapis
       return timedelta(0)
59 64cd4730 Antony Chazapis
60 64cd4730 Antony Chazapis
   def tzname(self, dt):
61 64cd4730 Antony Chazapis
       return 'UTC'
62 64cd4730 Antony Chazapis
63 64cd4730 Antony Chazapis
   def dst(self, dt):
64 64cd4730 Antony Chazapis
       return timedelta(0)
65 64cd4730 Antony Chazapis
66 64cd4730 Antony Chazapis
def isoformat(d):
67 64cd4730 Antony Chazapis
   """Return an ISO8601 date string that includes a timezone."""
68 64cd4730 Antony Chazapis
69 64cd4730 Antony Chazapis
   return d.replace(tzinfo=UTC()).isoformat()
70 0905ccd2 Sofia Papagiannaki
71 18ffbee1 Sofia Papagiannaki
def epoch(datetime):
72 18ffbee1 Sofia Papagiannaki
    return int(time.mktime(datetime.timetuple())*1000)
73 18ffbee1 Sofia Papagiannaki
74 0905ccd2 Sofia Papagiannaki
def get_context(request, extra_context={}, **kwargs):
75 0905ccd2 Sofia Papagiannaki
    if not extra_context:
76 0905ccd2 Sofia Papagiannaki
        extra_context = {}
77 0905ccd2 Sofia Papagiannaki
    extra_context.update(kwargs)
78 0905ccd2 Sofia Papagiannaki
    return RequestContext(request, extra_context)
79 e2125441 Sofia Papagiannaki
80 15efc749 Sofia Papagiannaki
def get_invitation(request):
81 15efc749 Sofia Papagiannaki
    """
82 15efc749 Sofia Papagiannaki
    Returns the invitation identified by the ``code``.
83 15efc749 Sofia Papagiannaki
    
84 0a569195 Sofia Papagiannaki
    Raises ValueError if the invitation is consumed or there is another account
85 0a569195 Sofia Papagiannaki
    associated with this email.
86 15efc749 Sofia Papagiannaki
    """
87 15efc749 Sofia Papagiannaki
    code = request.GET.get('code')
88 15efc749 Sofia Papagiannaki
    if request.method == 'POST':
89 15efc749 Sofia Papagiannaki
        code = request.POST.get('code')
90 15efc749 Sofia Papagiannaki
    if not code:
91 15efc749 Sofia Papagiannaki
        return
92 15efc749 Sofia Papagiannaki
    invitation = Invitation.objects.get(code = code)
93 15efc749 Sofia Papagiannaki
    if invitation.is_consumed:
94 1fefe48c Sofia Papagiannaki
        raise ValueError(_('Invitation is used'))
95 0a569195 Sofia Papagiannaki
    if reserved_email(invitation.username):
96 15efc749 Sofia Papagiannaki
        raise ValueError(_('Email: %s is reserved' % invitation.username))
97 63ecdd20 Sofia Papagiannaki
    return invitation
98 63ecdd20 Sofia Papagiannaki
99 8fbf5367 root
def prepare_response(request, user, next='', renew=False):
100 63ecdd20 Sofia Papagiannaki
    """Return the unique username and the token
101 63ecdd20 Sofia Papagiannaki
       as 'X-Auth-User' and 'X-Auth-Token' headers,
102 63ecdd20 Sofia Papagiannaki
       or redirect to the URL provided in 'next'
103 63ecdd20 Sofia Papagiannaki
       with the 'user' and 'token' as parameters.
104 63ecdd20 Sofia Papagiannaki
       
105 63ecdd20 Sofia Papagiannaki
       Reissue the token even if it has not yet
106 63ecdd20 Sofia Papagiannaki
       expired, if the 'renew' parameter is present
107 63ecdd20 Sofia Papagiannaki
       or user has not a valid token.
108 63ecdd20 Sofia Papagiannaki
    """
109 63ecdd20 Sofia Papagiannaki
    renew = renew or (not user.auth_token)
110 63ecdd20 Sofia Papagiannaki
    renew = renew or (user.auth_token_expires and user.auth_token_expires < datetime.datetime.now())
111 63ecdd20 Sofia Papagiannaki
    if renew:
112 63ecdd20 Sofia Papagiannaki
        user.renew_token()
113 27e26a41 Sofia Papagiannaki
        try:
114 27e26a41 Sofia Papagiannaki
            user.save()
115 27e26a41 Sofia Papagiannaki
        except ValidationError, e:
116 27e26a41 Sofia Papagiannaki
            return HttpResponseBadRequest(e) 
117 63ecdd20 Sofia Papagiannaki
    
118 92defad4 Sofia Papagiannaki
    if FORCE_PROFILE_UPDATE and not user.is_verified and not user.is_superuser:
119 63ecdd20 Sofia Papagiannaki
        params = ''
120 63ecdd20 Sofia Papagiannaki
        if next:
121 63ecdd20 Sofia Papagiannaki
            params = '?' + urlencode({'next': next})
122 63ecdd20 Sofia Papagiannaki
        next = reverse('astakos.im.views.edit_profile') + params
123 63ecdd20 Sofia Papagiannaki
    
124 63ecdd20 Sofia Papagiannaki
    response = HttpResponse()
125 63ecdd20 Sofia Papagiannaki
    
126 8fbf5367 root
    # authenticate before login
127 8fbf5367 root
    user = authenticate(email=user.email, auth_token=user.auth_token)
128 8fbf5367 root
    login(request, user)
129 c301698f Sofia Papagiannaki
    set_cookie(response, user)
130 b42b0987 Sofia Papagiannaki
    request.session.set_expiry(user.auth_token_expires)
131 63ecdd20 Sofia Papagiannaki
    
132 63ecdd20 Sofia Papagiannaki
    if not next:
133 63ecdd20 Sofia Papagiannaki
        next = reverse('astakos.im.views.index')
134 63ecdd20 Sofia Papagiannaki
    
135 63ecdd20 Sofia Papagiannaki
    response['Location'] = next
136 63ecdd20 Sofia Papagiannaki
    response.status_code = 302
137 8fbf5367 root
    return response
138 c301698f Sofia Papagiannaki
139 c301698f Sofia Papagiannaki
def set_cookie(response, user):
140 c301698f Sofia Papagiannaki
    expire_fmt = user.auth_token_expires.strftime('%a, %d-%b-%Y %H:%M:%S %Z')
141 c301698f Sofia Papagiannaki
    cookie_value = quote(user.email + '|' + user.auth_token)
142 c301698f Sofia Papagiannaki
    response.set_cookie(COOKIE_NAME, value=cookie_value,
143 c301698f Sofia Papagiannaki
                        expires=expire_fmt, path='/',
144 ca34523e Antony Chazapis
                        domain=COOKIE_DOMAIN, secure=COOKIE_SECURE)
145 270dd48d Sofia Papagiannaki
146 270dd48d Sofia Papagiannaki
class lazy_string(object):
147 270dd48d Sofia Papagiannaki
    def __init__(self, function, *args, **kwargs):
148 270dd48d Sofia Papagiannaki
        self.function=function
149 270dd48d Sofia Papagiannaki
        self.args=args
150 270dd48d Sofia Papagiannaki
        self.kwargs=kwargs
151 270dd48d Sofia Papagiannaki
        
152 270dd48d Sofia Papagiannaki
    def __str__(self):
153 270dd48d Sofia Papagiannaki
        if not hasattr(self, 'str'):
154 270dd48d Sofia Papagiannaki
            self.str=self.function(*self.args, **self.kwargs)
155 270dd48d Sofia Papagiannaki
        return self.str
156 270dd48d Sofia Papagiannaki
157 270dd48d Sofia Papagiannaki
def reverse_lazy(*args, **kwargs):
158 270dd48d Sofia Papagiannaki
    return lazy_string(reverse, *args, **kwargs)
159 270dd48d Sofia Papagiannaki
160 0a569195 Sofia Papagiannaki
def reserved_email(email):
161 0a569195 Sofia Papagiannaki
    return AstakosUser.objects.filter(email = email).count() != 0
162 0a569195 Sofia Papagiannaki
163 0a569195 Sofia Papagiannaki
def get_query(request):
164 0a569195 Sofia Papagiannaki
    return request.__getattribute__(request.method)