Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / api.py @ 963dfc33

History | View | Annotate | Download (6.6 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 7a0c3713 Kostas Papadimitriou
#
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 7a0c3713 Kostas Papadimitriou
#
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 7a0c3713 Kostas Papadimitriou
#
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 7a0c3713 Kostas Papadimitriou
#
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 7a0c3713 Kostas Papadimitriou
#
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 3a9f4931 Sofia Papagiannaki
import logging
35 3a9f4931 Sofia Papagiannaki
36 64cd4730 Antony Chazapis
from traceback import format_exc
37 64cd4730 Antony Chazapis
from time import time, mktime
38 1ae97c83 Sofia Papagiannaki
from urllib import quote
39 1ae97c83 Sofia Papagiannaki
from urlparse import urlparse
40 1ae97c83 Sofia Papagiannaki
41 64cd4730 Antony Chazapis
from django.conf import settings
42 64cd4730 Antony Chazapis
from django.http import HttpResponse
43 64cd4730 Antony Chazapis
from django.utils import simplejson as json
44 1ae97c83 Sofia Papagiannaki
from django.core.urlresolvers import reverse
45 64cd4730 Antony Chazapis
46 863193cb Sofia Papagiannaki
from astakos.im.faults import BadRequest, Unauthorized, InternalServerError
47 0905ccd2 Sofia Papagiannaki
from astakos.im.models import AstakosUser
48 1ae97c83 Sofia Papagiannaki
from astakos.im.settings import CLOUD_SERVICES, INVITATIONS_ENABLED
49 270dd48d Sofia Papagiannaki
from astakos.im.util import has_signed_terms
50 64cd4730 Antony Chazapis
51 3a9f4931 Sofia Papagiannaki
logger = logging.getLogger(__name__)
52 3a9f4931 Sofia Papagiannaki
53 64cd4730 Antony Chazapis
def render_fault(request, fault):
54 a5676ab6 Antony Chazapis
    if isinstance(fault, InternalServerError) and settings.DEBUG:
55 64cd4730 Antony Chazapis
        fault.details = format_exc(fault)
56 7a0c3713 Kostas Papadimitriou
57 64cd4730 Antony Chazapis
    request.serialization = 'text'
58 863193cb Sofia Papagiannaki
    data = fault.message + '\n'
59 863193cb Sofia Papagiannaki
    if fault.details:
60 863193cb Sofia Papagiannaki
        data += '\n' + fault.details
61 64cd4730 Antony Chazapis
    response = HttpResponse(data, status=fault.code)
62 64cd4730 Antony Chazapis
    response['Content-Length'] = len(response.content)
63 863193cb Sofia Papagiannaki
    return response
64 64cd4730 Antony Chazapis
65 64cd4730 Antony Chazapis
def authenticate(request):
66 64cd4730 Antony Chazapis
    # Normal Response Codes: 204
67 863193cb Sofia Papagiannaki
    # Error Response Codes: internalServerError (500)
68 64cd4730 Antony Chazapis
    #                       badRequest (400)
69 64cd4730 Antony Chazapis
    #                       unauthorised (401)
70 64cd4730 Antony Chazapis
    try:
71 64cd4730 Antony Chazapis
        if request.method != 'GET':
72 64cd4730 Antony Chazapis
            raise BadRequest('Method not allowed.')
73 64cd4730 Antony Chazapis
        x_auth_token = request.META.get('HTTP_X_AUTH_TOKEN')
74 64cd4730 Antony Chazapis
        if not x_auth_token:
75 64cd4730 Antony Chazapis
            return render_fault(request, BadRequest('Missing X-Auth-Token'))
76 7a0c3713 Kostas Papadimitriou
77 64cd4730 Antony Chazapis
        try:
78 0905ccd2 Sofia Papagiannaki
            user = AstakosUser.objects.get(auth_token=x_auth_token)
79 0905ccd2 Sofia Papagiannaki
        except AstakosUser.DoesNotExist, e:
80 7a0c3713 Kostas Papadimitriou
            return render_fault(request, Unauthorized('Invalid X-Auth-Token'))
81 7a0c3713 Kostas Papadimitriou
82 64cd4730 Antony Chazapis
        # Check if the is active.
83 0905ccd2 Sofia Papagiannaki
        if not user.is_active:
84 64cd4730 Antony Chazapis
            return render_fault(request, Unauthorized('User inactive'))
85 7a0c3713 Kostas Papadimitriou
86 64cd4730 Antony Chazapis
        # Check if the token has expired.
87 64cd4730 Antony Chazapis
        if (time() - mktime(user.auth_token_expires.timetuple())) > 0:
88 64cd4730 Antony Chazapis
            return render_fault(request, Unauthorized('Authentication expired'))
89 270dd48d Sofia Papagiannaki
        
90 270dd48d Sofia Papagiannaki
        if not has_signed_terms(user):
91 270dd48d Sofia Papagiannaki
            return render_fault(request, Unauthorized('Pending approval terms'))
92 270dd48d Sofia Papagiannaki
        
93 64cd4730 Antony Chazapis
        response = HttpResponse()
94 64cd4730 Antony Chazapis
        response.status=204
95 fc3da598 Sofia Papagiannaki
        user_info = {'username':user.username,
96 fc3da598 Sofia Papagiannaki
                     'uniq':user.email,
97 890b0eaf Sofia Papagiannaki
                     'auth_token':user.auth_token,
98 a314b027 root
                     'auth_token_created':user.auth_token_created.isoformat(),
99 59f598f1 Sofia Papagiannaki
                     'auth_token_expires':user.auth_token_expires.isoformat(),
100 270dd48d Sofia Papagiannaki
                     'has_credits':user.has_credits,
101 270dd48d Sofia Papagiannaki
                     'has_signed_terms':has_signed_terms(user)}
102 64cd4730 Antony Chazapis
        response.content = json.dumps(user_info)
103 863193cb Sofia Papagiannaki
        response['Content-Type'] = 'application/json; charset=UTF-8'
104 863193cb Sofia Papagiannaki
        response['Content-Length'] = len(response.content)
105 64cd4730 Antony Chazapis
        return response
106 64cd4730 Antony Chazapis
    except BaseException, e:
107 3a9f4931 Sofia Papagiannaki
        logger.exception(e)
108 863193cb Sofia Papagiannaki
        fault = InternalServerError('Unexpected error')
109 64cd4730 Antony Chazapis
        return render_fault(request, fault)
110 1ae97c83 Sofia Papagiannaki
111 1ae97c83 Sofia Papagiannaki
def get_services(request):
112 1ae97c83 Sofia Papagiannaki
    if request.method != 'GET':
113 1ae97c83 Sofia Papagiannaki
        raise BadRequest('Method not allowed.')
114 7a0c3713 Kostas Papadimitriou
115 7a0c3713 Kostas Papadimitriou
    callback = request.GET.get('callback', None)
116 1ae97c83 Sofia Papagiannaki
    data = json.dumps(CLOUD_SERVICES)
117 7a0c3713 Kostas Papadimitriou
    mimetype = 'application/json'
118 7a0c3713 Kostas Papadimitriou
119 7a0c3713 Kostas Papadimitriou
    if callback:
120 7a0c3713 Kostas Papadimitriou
        mimetype = 'application/javascript'
121 7a0c3713 Kostas Papadimitriou
        data = '%s(%s)' % (callback, data)
122 7a0c3713 Kostas Papadimitriou
123 7a0c3713 Kostas Papadimitriou
    return HttpResponse(content=data, mimetype=mimetype)
124 1ae97c83 Sofia Papagiannaki
125 cb79e2ed Kostas Papadimitriou
def get_menu(request, with_extra_links=False, with_signout=True):
126 1ae97c83 Sofia Papagiannaki
    location = request.GET.get('location', '')
127 ebd369d0 Sofia Papagiannaki
    exclude = []
128 ebd369d0 Sofia Papagiannaki
    index_url = reverse('index')
129 ebd369d0 Sofia Papagiannaki
    login_url = reverse('login')
130 ebd369d0 Sofia Papagiannaki
    logout_url = reverse('astakos.im.views.logout')
131 26774255 Sofia Papagiannaki
    absolute = lambda (url): request.build_absolute_uri(url)
132 ebd369d0 Sofia Papagiannaki
    l = index_url, login_url, logout_url
133 ebd369d0 Sofia Papagiannaki
    forbidden = []
134 ebd369d0 Sofia Papagiannaki
    for url in l:
135 ebd369d0 Sofia Papagiannaki
        url = url.rstrip('/')
136 ebd369d0 Sofia Papagiannaki
        forbidden.extend([url, url + '/', absolute(url), absolute(url + '/')])
137 ebd369d0 Sofia Papagiannaki
    if location not in forbidden:
138 1ae97c83 Sofia Papagiannaki
        index_url = '%s?next=%s' % (index_url, quote(location))
139 ebd369d0 Sofia Papagiannaki
    l = [{ 'url': absolute(index_url), 'name': "Sign in"}]
140 1ae97c83 Sofia Papagiannaki
    if request.user.is_authenticated():
141 1ae97c83 Sofia Papagiannaki
        l = []
142 ebd369d0 Sofia Papagiannaki
        l.append({ 'url': absolute(reverse('astakos.im.views.index')),
143 26774255 Sofia Papagiannaki
                  'name': request.user.email})
144 26774255 Sofia Papagiannaki
        l.append({ 'url': absolute(reverse('astakos.im.views.edit_profile')),
145 cb79e2ed Kostas Papadimitriou
                  'name': "My account" })
146 cb79e2ed Kostas Papadimitriou
        if with_extra_links:
147 cb79e2ed Kostas Papadimitriou
            if request.user.password:
148 cb79e2ed Kostas Papadimitriou
                l.append({ 'url': absolute(reverse('password_change')),
149 cb79e2ed Kostas Papadimitriou
                          'name': "Change password" })
150 cb79e2ed Kostas Papadimitriou
            if INVITATIONS_ENABLED:
151 cb79e2ed Kostas Papadimitriou
                l.append({ 'url': absolute(reverse('astakos.im.views.invite')),
152 cb79e2ed Kostas Papadimitriou
                          'name': "Invitations" })
153 cb79e2ed Kostas Papadimitriou
            l.append({ 'url': absolute(reverse('astakos.im.views.send_feedback')),
154 cb79e2ed Kostas Papadimitriou
                      'name': "Feedback" })
155 cb79e2ed Kostas Papadimitriou
        if with_signout:
156 cb79e2ed Kostas Papadimitriou
            l.append({ 'url': absolute(reverse('astakos.im.views.logout')),
157 cb79e2ed Kostas Papadimitriou
                      'name': "Sign out"})
158 067961d3 Sofia Papagiannaki
    
159 7a0c3713 Kostas Papadimitriou
    callback = request.GET.get('callback', None)
160 1ae97c83 Sofia Papagiannaki
    data = json.dumps(tuple(l))
161 7a0c3713 Kostas Papadimitriou
    mimetype = 'application/json'
162 7a0c3713 Kostas Papadimitriou
163 7a0c3713 Kostas Papadimitriou
    if callback:
164 7a0c3713 Kostas Papadimitriou
        mimetype = 'application/javascript'
165 7a0c3713 Kostas Papadimitriou
        data = '%s(%s)' % (callback, data)
166 7a0c3713 Kostas Papadimitriou
167 7a0c3713 Kostas Papadimitriou
    return HttpResponse(content=data, mimetype=mimetype)