Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / api / __init__.py @ ec612228

History | View | Annotate | Download (7.6 kB)

1 6b03a847 Sofia Papagiannaki
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 6b03a847 Sofia Papagiannaki
#
3 6b03a847 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 6b03a847 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 6b03a847 Sofia Papagiannaki
# conditions are met:
6 6b03a847 Sofia Papagiannaki
#
7 6b03a847 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 6b03a847 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 6b03a847 Sofia Papagiannaki
#      disclaimer.
10 6b03a847 Sofia Papagiannaki
#
11 6b03a847 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 6b03a847 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 6b03a847 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 6b03a847 Sofia Papagiannaki
#      provided with the distribution.
15 6b03a847 Sofia Papagiannaki
#
16 6b03a847 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 6b03a847 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 6b03a847 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 6b03a847 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 6b03a847 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 6b03a847 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 6b03a847 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 6b03a847 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 6b03a847 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 6b03a847 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 6b03a847 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 6b03a847 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 6b03a847 Sofia Papagiannaki
#
29 6b03a847 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 6b03a847 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 6b03a847 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 6b03a847 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 6b03a847 Sofia Papagiannaki
34 14c5be5a Sofia Papagiannaki
from functools import wraps
35 14c5be5a Sofia Papagiannaki
from traceback import format_exc
36 14c5be5a Sofia Papagiannaki
from urllib import quote, unquote
37 14c5be5a Sofia Papagiannaki
38 6b03a847 Sofia Papagiannaki
from django.http import HttpResponse
39 6b03a847 Sofia Papagiannaki
from django.utils import simplejson as json
40 14c5be5a Sofia Papagiannaki
from django.conf import settings
41 14c5be5a Sofia Papagiannaki
from django.core.urlresolvers import reverse
42 14c5be5a Sofia Papagiannaki
43 14c5be5a Sofia Papagiannaki
from astakos.im.models import AstakosUser, GroupKind, Service, Resource
44 14c5be5a Sofia Papagiannaki
from astakos.im.api.faults import Fault, ItemNotFound, InternalServerError
45 14c5be5a Sofia Papagiannaki
from astakos.im.settings import INVITATIONS_ENABLED, COOKIE_NAME, EMAILCHANGE_ENABLED
46 6b03a847 Sofia Papagiannaki
47 14c5be5a Sofia Papagiannaki
import logging
48 14c5be5a Sofia Papagiannaki
logger = logging.getLogger(__name__)
49 6b03a847 Sofia Papagiannaki
50 6b03a847 Sofia Papagiannaki
format = ('%a, %d %b %Y %H:%M:%S GMT')
51 6b03a847 Sofia Papagiannaki
52 14c5be5a Sofia Papagiannaki
def render_fault(request, fault):
53 14c5be5a Sofia Papagiannaki
    if isinstance(fault, InternalServerError) and settings.DEBUG:
54 14c5be5a Sofia Papagiannaki
        fault.details = format_exc(fault)
55 14c5be5a Sofia Papagiannaki
56 14c5be5a Sofia Papagiannaki
    request.serialization = 'text'
57 14c5be5a Sofia Papagiannaki
    data = fault.message + '\n'
58 14c5be5a Sofia Papagiannaki
    if fault.details:
59 14c5be5a Sofia Papagiannaki
        data += '\n' + fault.details
60 14c5be5a Sofia Papagiannaki
    response = HttpResponse(data, status=fault.code)
61 14c5be5a Sofia Papagiannaki
    response['Content-Length'] = len(response.content)
62 14c5be5a Sofia Papagiannaki
    return response
63 14c5be5a Sofia Papagiannaki
64 14c5be5a Sofia Papagiannaki
def api_method(http_method=None):
65 14c5be5a Sofia Papagiannaki
    """Decorator function for views that implement an API method."""
66 14c5be5a Sofia Papagiannaki
    def decorator(func):
67 14c5be5a Sofia Papagiannaki
        @wraps(func)
68 14c5be5a Sofia Papagiannaki
        def wrapper(request, *args, **kwargs):
69 14c5be5a Sofia Papagiannaki
            try:
70 14c5be5a Sofia Papagiannaki
                if http_method and request.method != http_method:
71 14c5be5a Sofia Papagiannaki
                    raise BadRequest('Method not allowed.')
72 14c5be5a Sofia Papagiannaki
                response = func(request, *args, **kwargs)
73 14c5be5a Sofia Papagiannaki
                return response
74 14c5be5a Sofia Papagiannaki
            except Fault, fault:
75 14c5be5a Sofia Papagiannaki
                return render_fault(request, fault)
76 14c5be5a Sofia Papagiannaki
            except BaseException, e:
77 14c5be5a Sofia Papagiannaki
                logger.exception('Unexpected error: %s' % e)
78 14c5be5a Sofia Papagiannaki
                fault = InternalServerError('Unexpected error')
79 14c5be5a Sofia Papagiannaki
                return render_fault(request, fault)
80 14c5be5a Sofia Papagiannaki
        return wrapper
81 14c5be5a Sofia Papagiannaki
    return decorator
82 14c5be5a Sofia Papagiannaki
83 6b03a847 Sofia Papagiannaki
def _get_user_by_username(user_id):
84 6b03a847 Sofia Papagiannaki
    try:
85 6b03a847 Sofia Papagiannaki
        user = AstakosUser.objects.get(username = user_id)
86 6b03a847 Sofia Papagiannaki
    except AstakosUser.DoesNotExist, e:
87 6b03a847 Sofia Papagiannaki
        raise ItemNotFound('Invalid userid')
88 6b03a847 Sofia Papagiannaki
    else:
89 6b03a847 Sofia Papagiannaki
        response = HttpResponse()
90 6b03a847 Sofia Papagiannaki
        response.status=200
91 6b03a847 Sofia Papagiannaki
        user_info = {'id':user.id,
92 6b03a847 Sofia Papagiannaki
                     'username':user.username,
93 6b03a847 Sofia Papagiannaki
                     'email':[user.email],
94 6b03a847 Sofia Papagiannaki
                     'name':user.realname,
95 6b03a847 Sofia Papagiannaki
                     'auth_token_created':user.auth_token_created.strftime(format),
96 6b03a847 Sofia Papagiannaki
                     'auth_token_expires':user.auth_token_expires.strftime(format),
97 6b03a847 Sofia Papagiannaki
                     'has_credits':user.has_credits,
98 6b03a847 Sofia Papagiannaki
                     'enabled':user.is_active,
99 6b03a847 Sofia Papagiannaki
                     'groups':[g.name for g in user.groups.all()]}
100 6b03a847 Sofia Papagiannaki
        response.content = json.dumps(user_info)
101 6b03a847 Sofia Papagiannaki
        response['Content-Type'] = 'application/json; charset=UTF-8'
102 6b03a847 Sofia Papagiannaki
        response['Content-Length'] = len(response.content)
103 6b03a847 Sofia Papagiannaki
        return response
104 6b03a847 Sofia Papagiannaki
105 6b03a847 Sofia Papagiannaki
def _get_user_by_email(email):
106 6b03a847 Sofia Papagiannaki
    if not email:
107 6b03a847 Sofia Papagiannaki
        raise BadRequest('Email missing')
108 6b03a847 Sofia Papagiannaki
    try:
109 6b03a847 Sofia Papagiannaki
        user = AstakosUser.objects.get(email = email)
110 6b03a847 Sofia Papagiannaki
    except AstakosUser.DoesNotExist, e:
111 6b03a847 Sofia Papagiannaki
        raise ItemNotFound('Invalid email')
112 6b03a847 Sofia Papagiannaki
    
113 6b03a847 Sofia Papagiannaki
    if not user.is_active:
114 6b03a847 Sofia Papagiannaki
        raise ItemNotFound('Inactive user')
115 6b03a847 Sofia Papagiannaki
    else:
116 6b03a847 Sofia Papagiannaki
        response = HttpResponse()
117 6b03a847 Sofia Papagiannaki
        response.status=200
118 6b03a847 Sofia Papagiannaki
        user_info = {'id':user.id,
119 6b03a847 Sofia Papagiannaki
                     'username':user.username,
120 6b03a847 Sofia Papagiannaki
                     'email':[user.email],
121 6b03a847 Sofia Papagiannaki
                     'enabled':user.is_active,
122 6b03a847 Sofia Papagiannaki
                     'name':user.realname,
123 6b03a847 Sofia Papagiannaki
                     'auth_token_created':user.auth_token_created.strftime(format),
124 6b03a847 Sofia Papagiannaki
                     'auth_token_expires':user.auth_token_expires.strftime(format),
125 6b03a847 Sofia Papagiannaki
                     'has_credits':user.has_credits,
126 6b03a847 Sofia Papagiannaki
                     'groups':[g.name for g in user.groups.all()],
127 6b03a847 Sofia Papagiannaki
                     'user_permissions':[p.codename for p in user.user_permissions.all()]}
128 6b03a847 Sofia Papagiannaki
        response.content = json.dumps(user_info)
129 6b03a847 Sofia Papagiannaki
        response['Content-Type'] = 'application/json; charset=UTF-8'
130 6b03a847 Sofia Papagiannaki
        response['Content-Length'] = len(response.content)
131 14c5be5a Sofia Papagiannaki
        return response
132 14c5be5a Sofia Papagiannaki
133 14c5be5a Sofia Papagiannaki
@api_method(http_method='GET')
134 14c5be5a Sofia Papagiannaki
def get_services(request):
135 14c5be5a Sofia Papagiannaki
    callback = request.GET.get('callback', None)
136 14c5be5a Sofia Papagiannaki
    services = Service.objects.all()
137 14c5be5a Sofia Papagiannaki
    data = tuple({'id':s.pk, 'name':s.name, 'url':s.url, 'icon':s.icon} for s in services)
138 14c5be5a Sofia Papagiannaki
    data = json.dumps(data)
139 14c5be5a Sofia Papagiannaki
    mimetype = 'application/json'
140 14c5be5a Sofia Papagiannaki
141 14c5be5a Sofia Papagiannaki
    if callback:
142 14c5be5a Sofia Papagiannaki
        mimetype = 'application/javascript'
143 14c5be5a Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
144 14c5be5a Sofia Papagiannaki
145 14c5be5a Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)
146 14c5be5a Sofia Papagiannaki
147 14c5be5a Sofia Papagiannaki
@api_method()
148 14c5be5a Sofia Papagiannaki
def get_menu(request, with_extra_links=False, with_signout=True):
149 ec612228 Sofia Papagiannaki
    user = request.user
150 ec612228 Sofia Papagiannaki
    if not isinstance(user, AstakosUser):
151 ec612228 Sofia Papagiannaki
        cookie = unquote(request.COOKIES.get(COOKIE_NAME, ''))
152 ec612228 Sofia Papagiannaki
        email = cookie.partition('|')[0]
153 ec612228 Sofia Papagiannaki
        try:
154 ec612228 Sofia Papagiannaki
            if email:
155 ec612228 Sofia Papagiannaki
                user = AstakosUser.objects.get(email=email, is_active=True)
156 ec612228 Sofia Papagiannaki
        except AstakosUser.DoesNotExist:
157 ec612228 Sofia Papagiannaki
            pass
158 ec612228 Sofia Papagiannaki
    
159 14c5be5a Sofia Papagiannaki
    absolute = lambda (url): request.build_absolute_uri(url)
160 ec612228 Sofia Papagiannaki
    if not isinstance(user, AstakosUser):
161 ec612228 Sofia Papagiannaki
        index_url = reverse('index')
162 ec612228 Sofia Papagiannaki
        l = [{ 'url': absolute(index_url), 'name': "Sign in"}]
163 14c5be5a Sofia Papagiannaki
    else:
164 14c5be5a Sofia Papagiannaki
        l = []
165 6ff7a7ca Sofia Papagiannaki
        l.append(dict(url=absolute(reverse('index')), name=user.email))
166 6ff7a7ca Sofia Papagiannaki
        l.append(dict(url=absolute(reverse('edit_profile')), name="My account"))
167 14c5be5a Sofia Papagiannaki
        if with_extra_links:
168 01ac12d5 Sofia Papagiannaki
            if user.has_usable_password() and user.provider in ('local', ''):
169 6ff7a7ca Sofia Papagiannaki
                l.append(dict(url=absolute(reverse('password_change')), name="Change password"))
170 14c5be5a Sofia Papagiannaki
            if EMAILCHANGE_ENABLED:
171 6ff7a7ca Sofia Papagiannaki
                l.append(dict(url=absolute(reverse('email_change')), name="Change email"))
172 14c5be5a Sofia Papagiannaki
            if INVITATIONS_ENABLED:
173 6ff7a7ca Sofia Papagiannaki
                l.append(dict(url=absolute(reverse('invite')), name="Invitations"))
174 6ff7a7ca Sofia Papagiannaki
            l.append(dict(url=absolute(reverse('feedback')), name="Feedback"))
175 01ac12d5 Sofia Papagiannaki
            l.append(dict(url=absolute(reverse('group_list')), name="Groups"))
176 ffb1e7a8 Sofia Papagiannaki
            l.append(dict(url=absolute(reverse('resource_list')), name="Resources"))
177 14c5be5a Sofia Papagiannaki
        if with_signout:
178 6ff7a7ca Sofia Papagiannaki
            l.append(dict(url=absolute(reverse('logout')), name="Sign out"))
179 14c5be5a Sofia Papagiannaki
180 14c5be5a Sofia Papagiannaki
    callback = request.GET.get('callback', None)
181 14c5be5a Sofia Papagiannaki
    data = json.dumps(tuple(l))
182 14c5be5a Sofia Papagiannaki
    mimetype = 'application/json'
183 14c5be5a Sofia Papagiannaki
184 14c5be5a Sofia Papagiannaki
    if callback:
185 14c5be5a Sofia Papagiannaki
        mimetype = 'application/javascript'
186 14c5be5a Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
187 14c5be5a Sofia Papagiannaki
188 14c5be5a Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)