Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views / im.py @ 554ef175

History | View | Annotate | Download (34.1 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 176023aa 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 176023aa 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 176023aa 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 176023aa 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 176023aa 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 64cd4730 Antony Chazapis
import logging
35 9a06d96f Olga Brani
import inflect
36 9a06d96f Olga Brani
37 9a06d96f Olga Brani
engine = inflect.engine()
38 64cd4730 Antony Chazapis
39 0905ccd2 Sofia Papagiannaki
from urllib import quote
40 a5cef8d0 Kostas Papadimitriou
41 c630fee6 Kostas Papadimitriou
from django.shortcuts import get_object_or_404
42 890b0eaf Sofia Papagiannaki
from django.contrib import messages
43 0be81d73 Sofia Papagiannaki
from django.contrib.auth.models import User
44 01ac12d5 Sofia Papagiannaki
from django.core.urlresolvers import reverse
45 01ac12d5 Sofia Papagiannaki
from django.db import transaction
46 3e0a032d Sofia Papagiannaki
from django.http import HttpResponse, HttpResponseRedirect, Http404
47 01ac12d5 Sofia Papagiannaki
from django.shortcuts import redirect
48 01ac12d5 Sofia Papagiannaki
from django.utils.translation import ugettext as _
49 3e0a032d Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
50 9a06d96f Olga Brani
from django.views.decorators.http import require_http_methods
51 96b44c04 Sofia Papagiannaki
from django.utils import simplejson as json
52 1ca02d1a Kostas Papadimitriou
from django.template import RequestContext
53 1ca02d1a Kostas Papadimitriou
54 1ca02d1a Kostas Papadimitriou
from synnefo_branding import utils as branding
55 1ca02d1a Kostas Papadimitriou
from synnefo_branding import settings as branding_settings
56 734107ef Kostas Papadimitriou
57 7763f5c6 Kostas Papadimitriou
from synnefo.lib import join_urls
58 7763f5c6 Kostas Papadimitriou
59 c630fee6 Kostas Papadimitriou
import astakos.im.messages as astakos_messages
60 c630fee6 Kostas Papadimitriou
61 e7cb4085 Kostas Papadimitriou
from astakos.im import activation_backends
62 3e0a032d Sofia Papagiannaki
from astakos.im.models import AstakosUser, ApprovalTerms, EmailChange, \
63 bea584e1 Giorgos Korfiatis
    AstakosUserAuthProvider, PendingThirdPartyUser, Component
64 3e0a032d Sofia Papagiannaki
from astakos.im.util import get_context, prepare_response, get_query, \
65 3e0a032d Sofia Papagiannaki
    restrict_next
66 3e0a032d Sofia Papagiannaki
from astakos.im.forms import LoginForm, InvitationForm, FeedbackForm, \
67 3e0a032d Sofia Papagiannaki
    SignApprovalTermsForm, EmailChangeForm
68 f7400729 Kostas Papadimitriou
from astakos.im.forms import ExtendedProfileForm as ProfileForm
69 1ca02d1a Kostas Papadimitriou
from synnefo.lib.services import get_public_endpoint
70 3e0a032d Sofia Papagiannaki
from astakos.im.functions import send_feedback, logout as auth_logout, \
71 3e0a032d Sofia Papagiannaki
    invite as invite_func
72 e7cb4085 Kostas Papadimitriou
from astakos.im import settings
73 8998f09a Sofia Papagiannaki
from astakos.im import presentation
74 9d20fe23 Kostas Papadimitriou
from astakos.im import auth_providers as auth
75 4e03ba30 Kostas Papadimitriou
from astakos.im import quotas
76 70e11eaa Sofia Papagiannaki
from astakos.im.views.util import render_response, _resources_catalog
77 70e11eaa Sofia Papagiannaki
from astakos.im.views.decorators import cookie_fix, signed_terms_required,\
78 b6496f0c Kostas Papadimitriou
    required_auth_methods_assigned, valid_astakos_user_required, login_required
79 ae497612 Olga Brani
80 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
81 e015e9e6 Sofia Papagiannaki
82 9a06d96f Olga Brani
83 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
84 222305b7 Sofia Papagiannaki
@cookie_fix
85 270dd48d Sofia Papagiannaki
@signed_terms_required
86 1ecda536 Kostas Papadimitriou
def login(request, template_name='im/login.html', extra_context=None):
87 890b0eaf Sofia Papagiannaki
    """
88 1ecda536 Kostas Papadimitriou
    Renders login page.
89 176023aa Kostas Papadimitriou

90 890b0eaf Sofia Papagiannaki
    **Arguments**
91 176023aa Kostas Papadimitriou

92 1ecda536 Kostas Papadimitriou
    ``template_name``
93 dcf55476 Sofia Papagiannaki
        A custom login template to use. This is optional; if not specified,
94 1e685275 Sofia Papagiannaki
        this will default to ``im/login.html``.
95 176023aa Kostas Papadimitriou

96 890b0eaf Sofia Papagiannaki
    ``extra_context``
97 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
98 890b0eaf Sofia Papagiannaki
    """
99 1ecda536 Kostas Papadimitriou
100 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
101 792c2f3b Olga Brani
102 f7cf5257 Kostas Papadimitriou
    third_party_token = request.GET.get('key', False)
103 f7cf5257 Kostas Papadimitriou
    if third_party_token:
104 f7cf5257 Kostas Papadimitriou
        messages.info(request, astakos_messages.AUTH_PROVIDER_LOGIN_TO_ADD)
105 f7cf5257 Kostas Papadimitriou
106 1ecda536 Kostas Papadimitriou
    if request.user.is_authenticated():
107 1ecda536 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('landing'))
108 1ecda536 Kostas Papadimitriou
109 ef20ea07 Sofia Papagiannaki
    return render_response(
110 ef20ea07 Sofia Papagiannaki
        template_name,
111 1ecda536 Kostas Papadimitriou
        login_form=LoginForm(request=request),
112 1ecda536 Kostas Papadimitriou
        context_instance=get_context(request, extra_context)
113 ef20ea07 Sofia Papagiannaki
    )
114 5ce3ce4f Sofia Papagiannaki
115 64cd4730 Antony Chazapis
116 1ecda536 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
117 1ecda536 Kostas Papadimitriou
@cookie_fix
118 1ecda536 Kostas Papadimitriou
@signed_terms_required
119 1ecda536 Kostas Papadimitriou
def index(request, authenticated_redirect='landing',
120 1ecda536 Kostas Papadimitriou
          anonymous_redirect='login', extra_context=None):
121 1ecda536 Kostas Papadimitriou
    """
122 1ecda536 Kostas Papadimitriou
    If user is authenticated redirect to ``authenticated_redirect`` url.
123 1ecda536 Kostas Papadimitriou
    Otherwise redirects to ``anonymous_redirect`` url.
124 1ecda536 Kostas Papadimitriou

125 1ecda536 Kostas Papadimitriou
    """
126 1ecda536 Kostas Papadimitriou
    if request.user.is_authenticated():
127 1ecda536 Kostas Papadimitriou
        return HttpResponseRedirect(reverse(authenticated_redirect))
128 1ecda536 Kostas Papadimitriou
    return HttpResponseRedirect(reverse(anonymous_redirect))
129 1ecda536 Kostas Papadimitriou
130 1ecda536 Kostas Papadimitriou
131 0504f010 Kostas Papadimitriou
@require_http_methods(["POST"])
132 222305b7 Sofia Papagiannaki
@cookie_fix
133 0504f010 Kostas Papadimitriou
@valid_astakos_user_required
134 0504f010 Kostas Papadimitriou
def update_token(request):
135 0504f010 Kostas Papadimitriou
    """
136 0504f010 Kostas Papadimitriou
    Update api token view.
137 0504f010 Kostas Papadimitriou
    """
138 0504f010 Kostas Papadimitriou
    user = request.user
139 0504f010 Kostas Papadimitriou
    user.renew_token()
140 0504f010 Kostas Papadimitriou
    user.save()
141 0504f010 Kostas Papadimitriou
    messages.success(request, astakos_messages.TOKEN_UPDATED)
142 14c76abe Kostas Papadimitriou
    return HttpResponseRedirect(reverse('api_access'))
143 0504f010 Kostas Papadimitriou
144 0504f010 Kostas Papadimitriou
145 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
146 222305b7 Sofia Papagiannaki
@cookie_fix
147 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
148 554ef175 Christos Stavrakakis
@transaction.commit_on_success
149 aab4d540 Sofia Papagiannaki
def invite(request, template_name='im/invitations.html', extra_context=None):
150 890b0eaf Sofia Papagiannaki
    """
151 890b0eaf Sofia Papagiannaki
    Allows a user to invite somebody else.
152 176023aa Kostas Papadimitriou

153 890b0eaf Sofia Papagiannaki
    In case of GET request renders a form for providing the invitee information.
154 890b0eaf Sofia Papagiannaki
    In case of POST checks whether the user has not run out of invitations and then
155 890b0eaf Sofia Papagiannaki
    sends an invitation email to singup to the service.
156 176023aa Kostas Papadimitriou

157 554ef175 Christos Stavrakakis
    The number of the user invitations is going to be updated only if the email
158 554ef175 Christos Stavrakakis
    has been successfully sent.
159 176023aa Kostas Papadimitriou

160 2cbaacd5 Sofia Papagiannaki
    If the user isn't logged in, redirects to settings.LOGIN_URL.
161 176023aa Kostas Papadimitriou

162 890b0eaf Sofia Papagiannaki
    **Arguments**
163 176023aa Kostas Papadimitriou

164 890b0eaf Sofia Papagiannaki
    ``template_name``
165 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
166 1e685275 Sofia Papagiannaki
        this will default to ``im/invitations.html``.
167 176023aa Kostas Papadimitriou

168 890b0eaf Sofia Papagiannaki
    ``extra_context``
169 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
170 176023aa Kostas Papadimitriou

171 890b0eaf Sofia Papagiannaki
    **Template:**
172 176023aa Kostas Papadimitriou

173 1e685275 Sofia Papagiannaki
    im/invitations.html or ``template_name`` keyword argument.
174 176023aa Kostas Papadimitriou

175 890b0eaf Sofia Papagiannaki
    **Settings:**
176 176023aa Kostas Papadimitriou

177 890b0eaf Sofia Papagiannaki
    The view expectes the following settings are defined:
178 176023aa Kostas Papadimitriou

179 890b0eaf Sofia Papagiannaki
    * LOGIN_URL: login uri
180 890b0eaf Sofia Papagiannaki
    """
181 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
182 64cd4730 Antony Chazapis
    status = None
183 64cd4730 Antony Chazapis
    message = None
184 8f5a3a06 Sofia Papagiannaki
    form = InvitationForm()
185 5ce3ce4f Sofia Papagiannaki
186 18ffbee1 Sofia Papagiannaki
    inviter = request.user
187 64cd4730 Antony Chazapis
    if request.method == 'POST':
188 8f5a3a06 Sofia Papagiannaki
        form = InvitationForm(request.POST)
189 64cd4730 Antony Chazapis
        if inviter.invitations > 0:
190 8f5a3a06 Sofia Papagiannaki
            if form.is_valid():
191 554ef175 Christos Stavrakakis
                email = form.cleaned_data.get('username')
192 554ef175 Christos Stavrakakis
                realname = form.cleaned_data.get('realname')
193 554ef175 Christos Stavrakakis
                invite_func(inviter, email, realname)
194 554ef175 Christos Stavrakakis
                message = _(astakos_messages.INVITATION_SENT) % locals()
195 554ef175 Christos Stavrakakis
                messages.success(request, message)
196 64cd4730 Antony Chazapis
        else:
197 ae497612 Olga Brani
            message = _(astakos_messages.MAX_INVITATION_NUMBER_REACHED)
198 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
199 176023aa Kostas Papadimitriou
200 a196eb7e Sofia Papagiannaki
    sent = [{'email': inv.username,
201 d6ae71a2 root
             'realname': inv.realname,
202 d6ae71a2 root
             'is_consumed': inv.is_consumed}
203 5ce3ce4f Sofia Papagiannaki
            for inv in request.user.invitations_sent.all()]
204 77e2ad52 root
    kwargs = {'inviter': inviter,
205 5ce3ce4f Sofia Papagiannaki
              'sent': sent}
206 0905ccd2 Sofia Papagiannaki
    context = get_context(request, extra_context, **kwargs)
207 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
208 5ce3ce4f Sofia Papagiannaki
                           invitation_form=form,
209 5ce3ce4f Sofia Papagiannaki
                           context_instance=context)
210 5ce3ce4f Sofia Papagiannaki
211 64cd4730 Antony Chazapis
212 1ca02d1a Kostas Papadimitriou
213 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
214 7763f5c6 Kostas Papadimitriou
@required_auth_methods_assigned()
215 7763f5c6 Kostas Papadimitriou
@login_required
216 7763f5c6 Kostas Papadimitriou
@cookie_fix
217 7763f5c6 Kostas Papadimitriou
@signed_terms_required
218 1ca02d1a Kostas Papadimitriou
def api_access_config(request, template_name='im/api_access_config.html',
219 1ca02d1a Kostas Papadimitriou
                      content_type='text/plain', extra_context=None,
220 1ca02d1a Kostas Papadimitriou
                      filename='.kamakirc'):
221 1ca02d1a Kostas Papadimitriou
222 1ca02d1a Kostas Papadimitriou
    if settings.KAMAKI_CONFIG_CLOUD_NAME:
223 1ca02d1a Kostas Papadimitriou
        cloud_name = settings.KAMAKI_CONFIG_CLOUD_NAME
224 1ca02d1a Kostas Papadimitriou
    else:
225 1ca02d1a Kostas Papadimitriou
        cloud_name = branding_settings.SERVICE_NAME.replace(' ', '_').lower()
226 1ca02d1a Kostas Papadimitriou
227 1ca02d1a Kostas Papadimitriou
    url = get_public_endpoint(settings.astakos_services, 'identity')
228 1ca02d1a Kostas Papadimitriou
229 1ca02d1a Kostas Papadimitriou
    context = {
230 1ca02d1a Kostas Papadimitriou
        'user': request.user,
231 1ca02d1a Kostas Papadimitriou
        'services': Component.catalog(),
232 1ca02d1a Kostas Papadimitriou
        'token_url': url,
233 1ca02d1a Kostas Papadimitriou
        'cloud_name': cloud_name
234 1ca02d1a Kostas Papadimitriou
    }
235 1ca02d1a Kostas Papadimitriou
236 1ca02d1a Kostas Papadimitriou
    extra_context = extra_context or {}
237 1ca02d1a Kostas Papadimitriou
    context.update(extra_context)
238 1ca02d1a Kostas Papadimitriou
    content = branding.render_to_string(template_name, context,
239 1ca02d1a Kostas Papadimitriou
                                        RequestContext(request))
240 967a99e1 Kostas Papadimitriou
    response = HttpResponse(content_type=content_type)
241 1ca02d1a Kostas Papadimitriou
    response.status_code = 200
242 1ca02d1a Kostas Papadimitriou
    response['Content-Disposition'] = 'attachment; filename="%s"' % filename
243 1ca02d1a Kostas Papadimitriou
    response.content = content
244 1ca02d1a Kostas Papadimitriou
    return response
245 1ca02d1a Kostas Papadimitriou
246 1ca02d1a Kostas Papadimitriou
247 1ca02d1a Kostas Papadimitriou
@required_auth_methods_assigned()
248 1ca02d1a Kostas Papadimitriou
@login_required
249 1ca02d1a Kostas Papadimitriou
@cookie_fix
250 1ca02d1a Kostas Papadimitriou
@signed_terms_required
251 7763f5c6 Kostas Papadimitriou
def api_access(request, template_name='im/api_access.html',
252 7763f5c6 Kostas Papadimitriou
               extra_context=None):
253 7763f5c6 Kostas Papadimitriou
    """
254 7763f5c6 Kostas Papadimitriou
    API access view.
255 7763f5c6 Kostas Papadimitriou
    """
256 7763f5c6 Kostas Papadimitriou
    context = {}
257 7763f5c6 Kostas Papadimitriou
258 3466f0a3 Kostas Papadimitriou
    url = get_public_endpoint(settings.astakos_services, 'identity')
259 7763f5c6 Kostas Papadimitriou
    context['services'] = Component.catalog()
260 3466f0a3 Kostas Papadimitriou
    context['token_url'] = url
261 31240d2c Olga Brani
    context['user'] = request.user
262 7763f5c6 Kostas Papadimitriou
    context['client_url'] = settings.API_CLIENT_URL
263 7763f5c6 Kostas Papadimitriou
264 7763f5c6 Kostas Papadimitriou
    if extra_context:
265 7763f5c6 Kostas Papadimitriou
        context.update(extra_context)
266 7763f5c6 Kostas Papadimitriou
    context_instance = get_context(request, context)
267 7763f5c6 Kostas Papadimitriou
    return render_response(template_name,
268 7763f5c6 Kostas Papadimitriou
                           context_instance=context_instance)
269 7763f5c6 Kostas Papadimitriou
270 7763f5c6 Kostas Papadimitriou
271 7763f5c6 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
272 9d20fe23 Kostas Papadimitriou
@required_auth_methods_assigned(allow_access=True)
273 890b0eaf Sofia Papagiannaki
@login_required
274 222305b7 Sofia Papagiannaki
@cookie_fix
275 270dd48d Sofia Papagiannaki
@signed_terms_required
276 aab4d540 Sofia Papagiannaki
def edit_profile(request, template_name='im/profile.html', extra_context=None):
277 890b0eaf Sofia Papagiannaki
    """
278 890b0eaf Sofia Papagiannaki
    Allows a user to edit his/her profile.
279 176023aa Kostas Papadimitriou

280 890b0eaf Sofia Papagiannaki
    In case of GET request renders a form for displaying the user information.
281 ce86cd44 Sofia Papagiannaki
    In case of POST updates the user informantion and redirects to ``next``
282 ce86cd44 Sofia Papagiannaki
    url parameter if exists.
283 176023aa Kostas Papadimitriou

284 2cbaacd5 Sofia Papagiannaki
    If the user isn't logged in, redirects to settings.LOGIN_URL.
285 176023aa Kostas Papadimitriou

286 890b0eaf Sofia Papagiannaki
    **Arguments**
287 176023aa Kostas Papadimitriou

288 890b0eaf Sofia Papagiannaki
    ``template_name``
289 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
290 1e685275 Sofia Papagiannaki
        this will default to ``im/profile.html``.
291 176023aa Kostas Papadimitriou

292 890b0eaf Sofia Papagiannaki
    ``extra_context``
293 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
294 176023aa Kostas Papadimitriou

295 890b0eaf Sofia Papagiannaki
    **Template:**
296 176023aa Kostas Papadimitriou

297 1e685275 Sofia Papagiannaki
    im/profile.html or ``template_name`` keyword argument.
298 176023aa Kostas Papadimitriou

299 92defad4 Sofia Papagiannaki
    **Settings:**
300 176023aa Kostas Papadimitriou

301 92defad4 Sofia Papagiannaki
    The view expectes the following settings are defined:
302 176023aa Kostas Papadimitriou

303 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
304 890b0eaf Sofia Papagiannaki
    """
305 aab4d540 Sofia Papagiannaki
    extra_context = extra_context or {}
306 bf0c6de5 Sofia Papagiannaki
    form = ProfileForm(
307 bf0c6de5 Sofia Papagiannaki
        instance=request.user,
308 bf0c6de5 Sofia Papagiannaki
        session_key=request.session.session_key
309 bf0c6de5 Sofia Papagiannaki
    )
310 15efc749 Sofia Papagiannaki
    extra_context['next'] = request.GET.get('next')
311 64cd4730 Antony Chazapis
    if request.method == 'POST':
312 bf0c6de5 Sofia Papagiannaki
        form = ProfileForm(
313 bf0c6de5 Sofia Papagiannaki
            request.POST,
314 bf0c6de5 Sofia Papagiannaki
            instance=request.user,
315 bf0c6de5 Sofia Papagiannaki
            session_key=request.session.session_key
316 bf0c6de5 Sofia Papagiannaki
        )
317 890b0eaf Sofia Papagiannaki
        if form.is_valid():
318 64cd4730 Antony Chazapis
            try:
319 c301698f Sofia Papagiannaki
                prev_token = request.user.auth_token
320 3fbf7863 Kostas Papadimitriou
                user = form.save(request=request)
321 217994f8 Sofia Papagiannaki
                next = restrict_next(
322 217994f8 Sofia Papagiannaki
                    request.POST.get('next'),
323 8998f09a Sofia Papagiannaki
                    domain=settings.COOKIE_DOMAIN
324 217994f8 Sofia Papagiannaki
                )
325 ae497612 Olga Brani
                msg = _(astakos_messages.PROFILE_UPDATED)
326 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
327 2da6f56b Kostas Papadimitriou
328 2da6f56b Kostas Papadimitriou
                if form.email_changed:
329 2da6f56b Kostas Papadimitriou
                    msg = _(astakos_messages.EMAIL_CHANGE_REGISTERED)
330 2da6f56b Kostas Papadimitriou
                    messages.success(request, msg)
331 2da6f56b Kostas Papadimitriou
                if form.password_changed:
332 2da6f56b Kostas Papadimitriou
                    msg = _(astakos_messages.PASSWORD_CHANGED)
333 2da6f56b Kostas Papadimitriou
                    messages.success(request, msg)
334 2da6f56b Kostas Papadimitriou
335 f7400729 Kostas Papadimitriou
                if next:
336 f7400729 Kostas Papadimitriou
                    return redirect(next)
337 f7400729 Kostas Papadimitriou
                else:
338 f7400729 Kostas Papadimitriou
                    return redirect(reverse('edit_profile'))
339 890b0eaf Sofia Papagiannaki
            except ValueError, ve:
340 24406ae3 Sofia Papagiannaki
                messages.success(request, ve)
341 23447441 Sofia Papagiannaki
    elif request.method == "GET":
342 792c2f3b Olga Brani
        request.user.is_verified = True
343 792c2f3b Olga Brani
        request.user.save()
344 792c2f3b Olga Brani
345 792c2f3b Olga Brani
    # existing providers
346 9d20fe23 Kostas Papadimitriou
    user_providers = request.user.get_enabled_auth_providers()
347 9d20fe23 Kostas Papadimitriou
    user_disabled_providers = request.user.get_disabled_auth_providers()
348 792c2f3b Olga Brani
349 792c2f3b Olga Brani
    # providers that user can add
350 792c2f3b Olga Brani
    user_available_providers = request.user.get_available_auth_providers()
351 792c2f3b Olga Brani
352 bea584e1 Giorgos Korfiatis
    extra_context['services'] = Component.catalog().values()
353 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
354 e7cb4085 Kostas Papadimitriou
                           profile_form=form,
355 e7cb4085 Kostas Papadimitriou
                           user_providers=user_providers,
356 e7cb4085 Kostas Papadimitriou
                           user_disabled_providers=user_disabled_providers,
357 e7cb4085 Kostas Papadimitriou
                           user_available_providers=user_available_providers,
358 e7cb4085 Kostas Papadimitriou
                           context_instance=get_context(request,
359 c301698f Sofia Papagiannaki
                                                          extra_context))
360 5ce3ce4f Sofia Papagiannaki
361 64cd4730 Antony Chazapis
362 554ef175 Christos Stavrakakis
@transaction.commit_on_success
363 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
364 222305b7 Sofia Papagiannaki
@cookie_fix
365 e7cb4085 Kostas Papadimitriou
def signup(request, template_name='im/signup.html', on_success='index',
366 e7cb4085 Kostas Papadimitriou
           extra_context=None, activation_backend=None):
367 890b0eaf Sofia Papagiannaki
    """
368 890b0eaf Sofia Papagiannaki
    Allows a user to create a local account.
369 176023aa Kostas Papadimitriou

370 b669d9c0 Sofia Papagiannaki
    In case of GET request renders a form for entering the user information.
371 890b0eaf Sofia Papagiannaki
    In case of POST handles the signup.
372 176023aa Kostas Papadimitriou

373 e7cb4085 Kostas Papadimitriou
    The user activation will be delegated to the backend specified by the
374 e7cb4085 Kostas Papadimitriou
    ``activation_backend`` keyword argument if present, otherwise to the
375 e7cb4085 Kostas Papadimitriou
    ``astakos.im.activation_backends.InvitationBackend`` if
376 e7cb4085 Kostas Papadimitriou
    settings.ASTAKOS_INVITATIONS_ENABLED is True or
377 e7cb4085 Kostas Papadimitriou
    ``astakos.im.activation_backends.SimpleBackend`` if not (see
378 e7cb4085 Kostas Papadimitriou
    activation_backends);
379 5ce3ce4f Sofia Papagiannaki

380 e7cb4085 Kostas Papadimitriou
    Upon successful user creation, if ``next`` url parameter is present the
381 e7cb4085 Kostas Papadimitriou
    user is redirected there otherwise renders the same page with a success
382 e7cb4085 Kostas Papadimitriou
    message.
383 5ce3ce4f Sofia Papagiannaki

384 8f5a3a06 Sofia Papagiannaki
    On unsuccessful creation, renders ``template_name`` with an error message.
385 5ce3ce4f Sofia Papagiannaki

386 890b0eaf Sofia Papagiannaki
    **Arguments**
387 5ce3ce4f Sofia Papagiannaki

388 8f5a3a06 Sofia Papagiannaki
    ``template_name``
389 8f5a3a06 Sofia Papagiannaki
        A custom template to render. This is optional;
390 1e685275 Sofia Papagiannaki
        if not specified, this will default to ``im/signup.html``.
391 176023aa Kostas Papadimitriou

392 890b0eaf Sofia Papagiannaki
    ``extra_context``
393 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
394 176023aa Kostas Papadimitriou

395 43332a76 Kostas Papadimitriou
    ``on_success``
396 43332a76 Kostas Papadimitriou
        Resolvable view name to redirect on registration success.
397 43332a76 Kostas Papadimitriou

398 890b0eaf Sofia Papagiannaki
    **Template:**
399 5ce3ce4f Sofia Papagiannaki

400 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
401 890b0eaf Sofia Papagiannaki
    """
402 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
403 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
404 e7cb4085 Kostas Papadimitriou
        logger.info("%s already signed in, redirect to index",
405 e7cb4085 Kostas Papadimitriou
                    request.user.log_display)
406 e7cb4085 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('index'))
407 5ce3ce4f Sofia Papagiannaki
408 0a569195 Sofia Papagiannaki
    provider = get_query(request).get('provider', 'local')
409 9d20fe23 Kostas Papadimitriou
    if not auth.get_provider(provider).get_create_policy:
410 e7cb4085 Kostas Papadimitriou
        logger.error("%s provider not available for signup", provider)
411 279d6e51 Olga Brani
        raise PermissionDenied
412 279d6e51 Olga Brani
413 e7cb4085 Kostas Papadimitriou
    instance = None
414 6c8a3f7c Sofia Papagiannaki
415 e7cb4085 Kostas Papadimitriou
    # user registered using third party provider
416 8ab484ea Kostas Papadimitriou
    third_party_token = request.REQUEST.get('third_party_token', None)
417 9d20fe23 Kostas Papadimitriou
    unverified = None
418 c630fee6 Kostas Papadimitriou
    if third_party_token:
419 e7cb4085 Kostas Papadimitriou
        # retreive third party entry. This was created right after the initial
420 e7cb4085 Kostas Papadimitriou
        # third party provider handshake.
421 c630fee6 Kostas Papadimitriou
        pending = get_object_or_404(PendingThirdPartyUser,
422 c630fee6 Kostas Papadimitriou
                                    token=third_party_token)
423 9d20fe23 Kostas Papadimitriou
424 c630fee6 Kostas Papadimitriou
        provider = pending.provider
425 e7cb4085 Kostas Papadimitriou
426 e7cb4085 Kostas Papadimitriou
        # clone third party instance into the corresponding AstakosUser
427 c630fee6 Kostas Papadimitriou
        instance = pending.get_user_instance()
428 9d20fe23 Kostas Papadimitriou
        get_unverified = AstakosUserAuthProvider.objects.unverified
429 e7cb4085 Kostas Papadimitriou
430 e7cb4085 Kostas Papadimitriou
        # check existing unverified entries
431 9d20fe23 Kostas Papadimitriou
        unverified = get_unverified(pending.provider,
432 9d20fe23 Kostas Papadimitriou
                                    identifier=pending.third_party_identifier)
433 9d20fe23 Kostas Papadimitriou
434 9d20fe23 Kostas Papadimitriou
        if unverified and request.method == 'GET':
435 9d20fe23 Kostas Papadimitriou
            messages.warning(request, unverified.get_pending_registration_msg)
436 e7cb4085 Kostas Papadimitriou
            if unverified.user.moderated:
437 9d20fe23 Kostas Papadimitriou
                messages.warning(request,
438 9d20fe23 Kostas Papadimitriou
                                 unverified.get_pending_resend_activation_msg)
439 9d20fe23 Kostas Papadimitriou
            else:
440 9d20fe23 Kostas Papadimitriou
                messages.warning(request,
441 9d20fe23 Kostas Papadimitriou
                                 unverified.get_pending_moderation_msg)
442 8ab484ea Kostas Papadimitriou
443 e7cb4085 Kostas Papadimitriou
    # prepare activation backend based on current request
444 e7cb4085 Kostas Papadimitriou
    if not activation_backend:
445 e7cb4085 Kostas Papadimitriou
        activation_backend = activation_backends.get_backend()
446 e7cb4085 Kostas Papadimitriou
447 e7726e14 Kostas Papadimitriou
    form_kwargs = {'instance': instance, 'request': request}
448 e7cb4085 Kostas Papadimitriou
    if third_party_token:
449 e7cb4085 Kostas Papadimitriou
        form_kwargs['third_party_token'] = third_party_token
450 e7cb4085 Kostas Papadimitriou
451 e7cb4085 Kostas Papadimitriou
    form = activation_backend.get_signup_form(
452 e7cb4085 Kostas Papadimitriou
        provider, None, **form_kwargs)
453 9d20fe23 Kostas Papadimitriou
454 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
455 e7cb4085 Kostas Papadimitriou
        form = activation_backend.get_signup_form(
456 e7cb4085 Kostas Papadimitriou
            provider,
457 e7cb4085 Kostas Papadimitriou
            request.POST,
458 e7cb4085 Kostas Papadimitriou
            **form_kwargs)
459 e7cb4085 Kostas Papadimitriou
460 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
461 554ef175 Christos Stavrakakis
            user = form.save(commit=False)
462 554ef175 Christos Stavrakakis
463 554ef175 Christos Stavrakakis
            # delete previously unverified accounts
464 554ef175 Christos Stavrakakis
            if AstakosUser.objects.user_exists(user.email):
465 554ef175 Christos Stavrakakis
                AstakosUser.objects.get_by_identifier(user.email).delete()
466 554ef175 Christos Stavrakakis
467 554ef175 Christos Stavrakakis
            # store_user so that user auth providers get initialized
468 554ef175 Christos Stavrakakis
            form.store_user(user, request)
469 554ef175 Christos Stavrakakis
            result = activation_backend.handle_registration(user)
470 554ef175 Christos Stavrakakis
            if result.status == \
471 554ef175 Christos Stavrakakis
                    activation_backend.Result.PENDING_MODERATION:
472 554ef175 Christos Stavrakakis
                # user should be warned that his account is not active yet
473 554ef175 Christos Stavrakakis
                status = messages.WARNING
474 554ef175 Christos Stavrakakis
            else:
475 554ef175 Christos Stavrakakis
                status = messages.SUCCESS
476 554ef175 Christos Stavrakakis
            message = result.message
477 554ef175 Christos Stavrakakis
            activation_backend.send_result_notifications(result, user)
478 792c2f3b Olga Brani
479 554ef175 Christos Stavrakakis
            # commit user entry
480 554ef175 Christos Stavrakakis
            transaction.commit()
481 554ef175 Christos Stavrakakis
482 554ef175 Christos Stavrakakis
            if user and user.is_active:
483 554ef175 Christos Stavrakakis
                # activation backend directly activated the user
484 554ef175 Christos Stavrakakis
                # log him in
485 554ef175 Christos Stavrakakis
                next = request.POST.get('next', '')
486 554ef175 Christos Stavrakakis
                response = prepare_response(request, user, next=next)
487 554ef175 Christos Stavrakakis
                return response
488 554ef175 Christos Stavrakakis
489 554ef175 Christos Stavrakakis
            messages.add_message(request, status, message)
490 554ef175 Christos Stavrakakis
            return HttpResponseRedirect(reverse(on_success))
491 43332a76 Kostas Papadimitriou
492 8f5a3a06 Sofia Papagiannaki
    return render_response(template_name,
493 5ce3ce4f Sofia Papagiannaki
                           signup_form=form,
494 8ab484ea Kostas Papadimitriou
                           third_party_token=third_party_token,
495 5ce3ce4f Sofia Papagiannaki
                           provider=provider,
496 890b0eaf Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
497 64cd4730 Antony Chazapis
498 5ce3ce4f Sofia Papagiannaki
499 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
500 9d20fe23 Kostas Papadimitriou
@required_auth_methods_assigned(allow_access=True)
501 890b0eaf Sofia Papagiannaki
@login_required
502 222305b7 Sofia Papagiannaki
@cookie_fix
503 270dd48d Sofia Papagiannaki
@signed_terms_required
504 aab4d540 Sofia Papagiannaki
def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context=None):
505 890b0eaf Sofia Papagiannaki
    """
506 890b0eaf Sofia Papagiannaki
    Allows a user to send feedback.
507 176023aa Kostas Papadimitriou

508 890b0eaf Sofia Papagiannaki
    In case of GET request renders a form for providing the feedback information.
509 890b0eaf Sofia Papagiannaki
    In case of POST sends an email to support team.
510 176023aa Kostas Papadimitriou

511 2cbaacd5 Sofia Papagiannaki
    If the user isn't logged in, redirects to settings.LOGIN_URL.
512 176023aa Kostas Papadimitriou

513 890b0eaf Sofia Papagiannaki
    **Arguments**
514 176023aa Kostas Papadimitriou

515 890b0eaf Sofia Papagiannaki
    ``template_name``
516 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
517 1e685275 Sofia Papagiannaki
        this will default to ``im/feedback.html``.
518 176023aa Kostas Papadimitriou

519 890b0eaf Sofia Papagiannaki
    ``extra_context``
520 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
521 176023aa Kostas Papadimitriou

522 890b0eaf Sofia Papagiannaki
    **Template:**
523 176023aa Kostas Papadimitriou

524 1e685275 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
525 176023aa Kostas Papadimitriou

526 890b0eaf Sofia Papagiannaki
    **Settings:**
527 176023aa Kostas Papadimitriou

528 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
529 890b0eaf Sofia Papagiannaki
    """
530 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
531 64cd4730 Antony Chazapis
    if request.method == 'GET':
532 890b0eaf Sofia Papagiannaki
        form = FeedbackForm()
533 890b0eaf Sofia Papagiannaki
    if request.method == 'POST':
534 890b0eaf Sofia Papagiannaki
        if not request.user:
535 890b0eaf Sofia Papagiannaki
            return HttpResponse('Unauthorized', status=401)
536 176023aa Kostas Papadimitriou
537 890b0eaf Sofia Papagiannaki
        form = FeedbackForm(request.POST)
538 890b0eaf Sofia Papagiannaki
        if form.is_valid():
539 e9083112 Sofia Papagiannaki
            msg = form.cleaned_data['feedback_msg']
540 8f5a3a06 Sofia Papagiannaki
            data = form.cleaned_data['feedback_data']
541 860bb9f7 Sofia Papagiannaki
            send_feedback(msg, data, request.user, email_template_name)
542 860bb9f7 Sofia Papagiannaki
            message = _(astakos_messages.FEEDBACK_SENT)
543 860bb9f7 Sofia Papagiannaki
            messages.success(request, message)
544 b9f8f48a Kostas Papadimitriou
            return HttpResponseRedirect(reverse('feedback'))
545 e7cb4085 Kostas Papadimitriou
546 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
547 5ce3ce4f Sofia Papagiannaki
                           feedback_form=form,
548 e7cb4085 Kostas Papadimitriou
                           context_instance=get_context(request,
549 e7cb4085 Kostas Papadimitriou
                                                        extra_context))
550 5ce3ce4f Sofia Papagiannaki
551 15efc749 Sofia Papagiannaki
552 217994f8 Sofia Papagiannaki
@require_http_methods(["GET"])
553 222305b7 Sofia Papagiannaki
@cookie_fix
554 e7cb4085 Kostas Papadimitriou
def logout(request, template='registration/logged_out.html',
555 e7cb4085 Kostas Papadimitriou
           extra_context=None):
556 63ecdd20 Sofia Papagiannaki
    """
557 b2ffa772 Sofia Papagiannaki
    Wraps `django.contrib.auth.logout`.
558 63ecdd20 Sofia Papagiannaki
    """
559 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
560 7482228b Sofia Papagiannaki
    response = HttpResponse()
561 8e45d6fd Sofia Papagiannaki
    if request.user.is_authenticated():
562 8e45d6fd Sofia Papagiannaki
        email = request.user.email
563 8e45d6fd Sofia Papagiannaki
        auth_logout(request)
564 c630fee6 Kostas Papadimitriou
    else:
565 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
566 c630fee6 Kostas Papadimitriou
        response.status_code = 301
567 c630fee6 Kostas Papadimitriou
        return response
568 c630fee6 Kostas Papadimitriou
569 217994f8 Sofia Papagiannaki
    next = restrict_next(
570 217994f8 Sofia Papagiannaki
        request.GET.get('next'),
571 8998f09a Sofia Papagiannaki
        domain=settings.COOKIE_DOMAIN
572 217994f8 Sofia Papagiannaki
    )
573 c630fee6 Kostas Papadimitriou
574 63ecdd20 Sofia Papagiannaki
    if next:
575 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
576 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
577 8998f09a Sofia Papagiannaki
    elif settings.LOGOUT_NEXT:
578 8998f09a Sofia Papagiannaki
        response['Location'] = settings.LOGOUT_NEXT
579 0d02a287 Sofia Papagiannaki
        response.status_code = 301
580 b2ffa772 Sofia Papagiannaki
    else:
581 9d20fe23 Kostas Papadimitriou
        last_provider = request.COOKIES.get('astakos_last_login_method', 'local')
582 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(last_provider)
583 9d20fe23 Kostas Papadimitriou
        message = provider.get_logout_success_msg
584 9d20fe23 Kostas Papadimitriou
        extra = provider.get_logout_success_extra_msg
585 9d20fe23 Kostas Papadimitriou
        if extra:
586 9d20fe23 Kostas Papadimitriou
            message += "<br />"  + extra
587 d21d422a Kostas Papadimitriou
        messages.success(request, message)
588 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
589 c630fee6 Kostas Papadimitriou
        response.status_code = 301
590 49df775e Sofia Papagiannaki
    return response
591 2126d85d Sofia Papagiannaki
592 5ce3ce4f Sofia Papagiannaki
593 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
594 222305b7 Sofia Papagiannaki
@cookie_fix
595 554ef175 Christos Stavrakakis
@transaction.commit_on_success
596 3bb604eb Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt',
597 3bb604eb Sofia Papagiannaki
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
598 2126d85d Sofia Papagiannaki
    """
599 e7cb4085 Kostas Papadimitriou
    Activates the user identified by the ``auth`` request parameter, sends a
600 e7cb4085 Kostas Papadimitriou
    welcome email and renews the user token.
601 176023aa Kostas Papadimitriou

602 554ef175 Christos Stavrakakis
    The user state will be updated only if the email will be send successfully.
603 2126d85d Sofia Papagiannaki
    """
604 2126d85d Sofia Papagiannaki
    token = request.GET.get('auth')
605 2126d85d Sofia Papagiannaki
    next = request.GET.get('next')
606 5ce3ce4f Sofia Papagiannaki
607 e7cb4085 Kostas Papadimitriou
    if request.user.is_authenticated():
608 e7cb4085 Kostas Papadimitriou
        message = _(astakos_messages.LOGGED_IN_WARNING)
609 24406ae3 Sofia Papagiannaki
        messages.error(request, message)
610 a53f77ee Kostas Papadimitriou
        transaction.rollback()
611 92a8abc9 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('index'))
612 5ce3ce4f Sofia Papagiannaki
613 e7cb4085 Kostas Papadimitriou
    try:
614 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(verification_code=token)
615 e7cb4085 Kostas Papadimitriou
    except AstakosUser.DoesNotExist:
616 e7cb4085 Kostas Papadimitriou
        raise Http404
617 e7cb4085 Kostas Papadimitriou
618 e7cb4085 Kostas Papadimitriou
    if user.email_verified:
619 e7cb4085 Kostas Papadimitriou
        message = _(astakos_messages.ACCOUNT_ALREADY_VERIFIED)
620 89d959c9 Kostas Papadimitriou
        messages.error(request, message)
621 89d959c9 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('index'))
622 89d959c9 Kostas Papadimitriou
623 554ef175 Christos Stavrakakis
    backend = activation_backends.get_backend()
624 554ef175 Christos Stavrakakis
    result = backend.handle_verification(user, token)
625 554ef175 Christos Stavrakakis
    backend.send_result_notifications(result, user)
626 554ef175 Christos Stavrakakis
    next = settings.ACTIVATION_REDIRECT_URL or next
627 554ef175 Christos Stavrakakis
    response = HttpResponseRedirect(reverse('index'))
628 554ef175 Christos Stavrakakis
    if user.is_active:
629 554ef175 Christos Stavrakakis
        response = prepare_response(request, user, next, renew=True)
630 554ef175 Christos Stavrakakis
        messages.success(request, _(result.message))
631 e7cb4085 Kostas Papadimitriou
    else:
632 554ef175 Christos Stavrakakis
        messages.warning(request, _(result.message))
633 554ef175 Christos Stavrakakis
634 554ef175 Christos Stavrakakis
    return response
635 270dd48d Sofia Papagiannaki
636 5ce3ce4f Sofia Papagiannaki
637 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
638 222305b7 Sofia Papagiannaki
@cookie_fix
639 e7cb4085 Kostas Papadimitriou
def approval_terms(request, term_id=None,
640 e7cb4085 Kostas Papadimitriou
                   template_name='im/approval_terms.html', extra_context=None):
641 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
642 270dd48d Sofia Papagiannaki
    term = None
643 270dd48d Sofia Papagiannaki
    terms = None
644 270dd48d Sofia Papagiannaki
    if not term_id:
645 270dd48d Sofia Papagiannaki
        try:
646 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
647 270dd48d Sofia Papagiannaki
        except IndexError:
648 270dd48d Sofia Papagiannaki
            pass
649 270dd48d Sofia Papagiannaki
    else:
650 270dd48d Sofia Papagiannaki
        try:
651 aab4d540 Sofia Papagiannaki
            term = ApprovalTerms.objects.get(id=term_id)
652 aab4d540 Sofia Papagiannaki
        except ApprovalTerms.DoesNotExist, e:
653 270dd48d Sofia Papagiannaki
            pass
654 176023aa Kostas Papadimitriou
655 270dd48d Sofia Papagiannaki
    if not term:
656 ae497612 Olga Brani
        messages.error(request, _(astakos_messages.NO_APPROVAL_TERMS))
657 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('index'))
658 64b5136c Sofia Papagiannaki
    try:
659 64b5136c Sofia Papagiannaki
        f = open(term.location, 'r')
660 64b5136c Sofia Papagiannaki
    except IOError:
661 64b5136c Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
662 64b5136c Sofia Papagiannaki
        return render_response(
663 e7cb4085 Kostas Papadimitriou
            template_name, context_instance=get_context(request,
664 e7cb4085 Kostas Papadimitriou
                                                        extra_context))
665 64b5136c Sofia Papagiannaki
666 270dd48d Sofia Papagiannaki
    terms = f.read()
667 176023aa Kostas Papadimitriou
668 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
669 217994f8 Sofia Papagiannaki
        next = restrict_next(
670 217994f8 Sofia Papagiannaki
            request.POST.get('next'),
671 8998f09a Sofia Papagiannaki
            domain=settings.COOKIE_DOMAIN
672 217994f8 Sofia Papagiannaki
        )
673 270dd48d Sofia Papagiannaki
        if not next:
674 6ff7a7ca Sofia Papagiannaki
            next = reverse('index')
675 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
676 270dd48d Sofia Papagiannaki
        if not form.is_valid():
677 270dd48d Sofia Papagiannaki
            return render_response(template_name,
678 5ce3ce4f Sofia Papagiannaki
                                   terms=terms,
679 5ce3ce4f Sofia Papagiannaki
                                   approval_terms_form=form,
680 e7cb4085 Kostas Papadimitriou
                                   context_instance=get_context(request,
681 e7cb4085 Kostas Papadimitriou
                                                                extra_context))
682 270dd48d Sofia Papagiannaki
        user = form.save()
683 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
684 270dd48d Sofia Papagiannaki
    else:
685 586967c0 Sofia Papagiannaki
        form = None
686 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
687 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
688 270dd48d Sofia Papagiannaki
        return render_response(template_name,
689 5ce3ce4f Sofia Papagiannaki
                               terms=terms,
690 5ce3ce4f Sofia Papagiannaki
                               approval_terms_form=form,
691 e7cb4085 Kostas Papadimitriou
                               context_instance=get_context(request,
692 e7cb4085 Kostas Papadimitriou
                                                            extra_context))
693 5ce3ce4f Sofia Papagiannaki
694 270dd48d Sofia Papagiannaki
695 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
696 222305b7 Sofia Papagiannaki
@cookie_fix
697 554ef175 Christos Stavrakakis
@transaction.commit_on_success
698 49790d9d Sofia Papagiannaki
def change_email(request, activation_key=None,
699 49790d9d Sofia Papagiannaki
                 email_template_name='registration/email_change_email.txt',
700 49790d9d Sofia Papagiannaki
                 form_template_name='registration/email_change_form.html',
701 49790d9d Sofia Papagiannaki
                 confirm_template_name='registration/email_change_done.html',
702 aab4d540 Sofia Papagiannaki
                 extra_context=None):
703 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
704 53e0b8fe Kostas Papadimitriou
705 e7cb4085 Kostas Papadimitriou
    if not settings.EMAILCHANGE_ENABLED:
706 17ad5d37 Kostas Papadimitriou
        raise PermissionDenied
707 17ad5d37 Kostas Papadimitriou
708 49790d9d Sofia Papagiannaki
    if activation_key:
709 49790d9d Sofia Papagiannaki
        try:
710 0b817216 Kostas Papadimitriou
            try:
711 0b817216 Kostas Papadimitriou
                email_change = EmailChange.objects.get(
712 0b817216 Kostas Papadimitriou
                    activation_key=activation_key)
713 0b817216 Kostas Papadimitriou
            except EmailChange.DoesNotExist:
714 0b817216 Kostas Papadimitriou
                logger.error("[change-email] Invalid or used activation "
715 0b817216 Kostas Papadimitriou
                             "code, %s", activation_key)
716 0b817216 Kostas Papadimitriou
                raise Http404
717 0b817216 Kostas Papadimitriou
718 0b817216 Kostas Papadimitriou
            if (request.user.is_authenticated() and \
719 0b817216 Kostas Papadimitriou
                request.user == email_change.user) or not \
720 10a870d5 Kostas Papadimitriou
                    request.user.is_authenticated():
721 0b817216 Kostas Papadimitriou
                user = EmailChange.objects.change_email(activation_key)
722 ae497612 Olga Brani
                msg = _(astakos_messages.EMAIL_CHANGED)
723 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
724 49790d9d Sofia Papagiannaki
                transaction.commit()
725 53e0b8fe Kostas Papadimitriou
                return HttpResponseRedirect(reverse('edit_profile'))
726 0b817216 Kostas Papadimitriou
            else:
727 0b817216 Kostas Papadimitriou
                logger.error("[change-email] Access from invalid user, %s %s",
728 0b817216 Kostas Papadimitriou
                             email_change.user, request.user.log_display)
729 0b817216 Kostas Papadimitriou
                raise PermissionDenied
730 49790d9d Sofia Papagiannaki
        except ValueError, e:
731 24406ae3 Sofia Papagiannaki
            messages.error(request, e)
732 53e0b8fe Kostas Papadimitriou
            transaction.rollback()
733 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('index'))
734 53e0b8fe Kostas Papadimitriou
735 49790d9d Sofia Papagiannaki
        return render_response(confirm_template_name,
736 e7cb4085 Kostas Papadimitriou
                               modified_user=user if 'user' in locals()
737 53e0b8fe Kostas Papadimitriou
                               else None, context_instance=get_context(request,
738 e7cb4085 Kostas Papadimitriou
                               extra_context))
739 5ce3ce4f Sofia Papagiannaki
740 49790d9d Sofia Papagiannaki
    if not request.user.is_authenticated():
741 49790d9d Sofia Papagiannaki
        path = quote(request.get_full_path())
742 6ff7a7ca Sofia Papagiannaki
        url = request.build_absolute_uri(reverse('index'))
743 49790d9d Sofia Papagiannaki
        return HttpResponseRedirect(url + '?next=' + path)
744 53e0b8fe Kostas Papadimitriou
745 53e0b8fe Kostas Papadimitriou
    # clean up expired email changes
746 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
747 53e0b8fe Kostas Papadimitriou
        change = request.user.emailchanges.get()
748 53e0b8fe Kostas Papadimitriou
        if change.activation_key_expired():
749 53e0b8fe Kostas Papadimitriou
            change.delete()
750 53e0b8fe Kostas Papadimitriou
            transaction.commit()
751 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('email_change'))
752 53e0b8fe Kostas Papadimitriou
753 49790d9d Sofia Papagiannaki
    form = EmailChangeForm(request.POST or None)
754 49790d9d Sofia Papagiannaki
    if request.method == 'POST' and form.is_valid():
755 554ef175 Christos Stavrakakis
        ec = form.save(request, email_template_name, request)
756 554ef175 Christos Stavrakakis
        msg = _(astakos_messages.EMAIL_CHANGE_REGISTERED)
757 554ef175 Christos Stavrakakis
        messages.success(request, msg)
758 554ef175 Christos Stavrakakis
        transaction.commit()
759 554ef175 Christos Stavrakakis
        return HttpResponseRedirect(reverse('edit_profile'))
760 53e0b8fe Kostas Papadimitriou
761 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
762 53e0b8fe Kostas Papadimitriou
        messages.warning(request, astakos_messages.PENDING_EMAIL_CHANGE_REQUEST)
763 53e0b8fe Kostas Papadimitriou
764 c0b26605 Sofia Papagiannaki
    return render_response(
765 c0b26605 Sofia Papagiannaki
        form_template_name,
766 c0b26605 Sofia Papagiannaki
        form=form,
767 c0b26605 Sofia Papagiannaki
        context_instance=get_context(request, extra_context)
768 c0b26605 Sofia Papagiannaki
    )
769 1f3b4b39 Sofia Papagiannaki
770 1f3b4b39 Sofia Papagiannaki
771 222305b7 Sofia Papagiannaki
@cookie_fix
772 e7cb4085 Kostas Papadimitriou
def send_activation(request, user_id, template_name='im/login.html',
773 e7cb4085 Kostas Papadimitriou
                    extra_context=None):
774 792c2f3b Olga Brani
775 badcb2a9 Kostas Papadimitriou
    if request.user.is_authenticated():
776 e7cb4085 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('index'))
777 badcb2a9 Kostas Papadimitriou
778 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
779 1f3b4b39 Sofia Papagiannaki
    try:
780 1f3b4b39 Sofia Papagiannaki
        u = AstakosUser.objects.get(id=user_id)
781 1f3b4b39 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
782 c0b26605 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.ACCOUNT_UNKNOWN))
783 1f3b4b39 Sofia Papagiannaki
    else:
784 e7cb4085 Kostas Papadimitriou
        if u.email_verified:
785 e7cb4085 Kostas Papadimitriou
            logger.warning("[resend activation] Account already verified: %s",
786 e7cb4085 Kostas Papadimitriou
                           u.log_display)
787 e7cb4085 Kostas Papadimitriou
788 e7cb4085 Kostas Papadimitriou
            messages.error(request,
789 e7cb4085 Kostas Papadimitriou
                           _(astakos_messages.ACCOUNT_ALREADY_VERIFIED))
790 e7cb4085 Kostas Papadimitriou
        else:
791 e7cb4085 Kostas Papadimitriou
            activation_backend = activation_backends.get_backend()
792 e7cb4085 Kostas Papadimitriou
            activation_backend.send_user_verification_email(u)
793 e7cb4085 Kostas Papadimitriou
            messages.success(request, astakos_messages.ACTIVATION_SENT)
794 ff81d0d9 Kostas Papadimitriou
795 ff81d0d9 Kostas Papadimitriou
    return HttpResponseRedirect(reverse('index'))
796 5ce3ce4f Sofia Papagiannaki
797 73fbaec4 Sofia Papagiannaki
798 73fbaec4 Sofia Papagiannaki
@require_http_methods(["GET"])
799 222305b7 Sofia Papagiannaki
@cookie_fix
800 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
801 666c7490 Sofia Papagiannaki
def resource_usage(request):
802 e9ef5009 Kostas Papadimitriou
803 37d59b27 Kostas Papadimitriou
    resources_meta = presentation.RESOURCES
804 37d59b27 Kostas Papadimitriou
805 4e03ba30 Kostas Papadimitriou
    current_usage = quotas.get_user_quotas(request.user)
806 4e03ba30 Kostas Papadimitriou
    current_usage = json.dumps(current_usage['system'])
807 37d59b27 Kostas Papadimitriou
    resource_catalog, resource_groups = _resources_catalog(for_usage=True)
808 37d59b27 Kostas Papadimitriou
    if resource_catalog is False:
809 37d59b27 Kostas Papadimitriou
        # on fail resource_groups contains the result object
810 37d59b27 Kostas Papadimitriou
        result = resource_groups
811 37d59b27 Kostas Papadimitriou
        messages.error(request, 'Unable to retrieve system resources: %s' %
812 37d59b27 Kostas Papadimitriou
                       result.reason)
813 37d59b27 Kostas Papadimitriou
814 4e03ba30 Kostas Papadimitriou
    resource_catalog = json.dumps(resource_catalog)
815 4e03ba30 Kostas Papadimitriou
    resource_groups = json.dumps(resource_groups)
816 37d59b27 Kostas Papadimitriou
    resources_order = json.dumps(resources_meta.get('resources_order'))
817 401089d8 Kostas Papadimitriou
818 666c7490 Sofia Papagiannaki
    return render_response('im/resource_usage.html',
819 3cbd5e47 Olga Brani
                           context_instance=get_context(request),
820 4e03ba30 Kostas Papadimitriou
                           resource_catalog=resource_catalog,
821 4e03ba30 Kostas Papadimitriou
                           resource_groups=resource_groups,
822 4e03ba30 Kostas Papadimitriou
                           resources_order=resources_order,
823 4e03ba30 Kostas Papadimitriou
                           current_usage=current_usage,
824 e7cb4085 Kostas Papadimitriou
                           token_cookie_name=settings.COOKIE_NAME,
825 4e03ba30 Kostas Papadimitriou
                           usage_update_interval=
826 e7cb4085 Kostas Papadimitriou
                           settings.USAGE_UPDATE_INTERVAL)
827 4e03ba30 Kostas Papadimitriou
828 9a06d96f Olga Brani
829 f432088a Kostas Papadimitriou
# TODO: action only on POST and user should confirm the removal
830 327a4c1e Olga Brani
@require_http_methods(["POST"])
831 222305b7 Sofia Papagiannaki
@cookie_fix
832 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
833 d2633501 Kostas Papadimitriou
def remove_auth_provider(request, pk):
834 f432088a Kostas Papadimitriou
    try:
835 9d20fe23 Kostas Papadimitriou
        provider = request.user.auth_providers.get(pk=int(pk)).settings
836 f432088a Kostas Papadimitriou
    except AstakosUserAuthProvider.DoesNotExist:
837 f432088a Kostas Papadimitriou
        raise Http404
838 f432088a Kostas Papadimitriou
839 9d20fe23 Kostas Papadimitriou
    if provider.get_remove_policy:
840 9d20fe23 Kostas Papadimitriou
        messages.success(request, provider.get_removed_msg)
841 9d20fe23 Kostas Papadimitriou
        provider.remove_from_user()
842 d2633501 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
843 d2633501 Kostas Papadimitriou
    else:
844 f432088a Kostas Papadimitriou
        raise PermissionDenied
845 5ebebb20 Olga Brani
846 792c2f3b Olga Brani
847 9d20fe23 Kostas Papadimitriou
@require_http_methods(["GET"])
848 9d20fe23 Kostas Papadimitriou
@required_auth_methods_assigned(allow_access=True)
849 9d20fe23 Kostas Papadimitriou
@login_required
850 222305b7 Sofia Papagiannaki
@cookie_fix
851 9d20fe23 Kostas Papadimitriou
@signed_terms_required
852 003d8fcf Olga Brani
def landing(request):
853 bea584e1 Giorgos Korfiatis
    context = {'services': Component.catalog(orderfor='dashboard')}
854 003d8fcf Olga Brani
    return render_response(
855 003d8fcf Olga Brani
        'im/landing.html',
856 0156e40c Kostas Papadimitriou
        context_instance=get_context(request), **context)
857 b87429e1 Olga Brani
858 ca5148f2 Kostas Papadimitriou
859 0be81d73 Sofia Papagiannaki
@cookie_fix
860 0be81d73 Sofia Papagiannaki
def get_menu(request, with_extra_links=False, with_signout=True):
861 0be81d73 Sofia Papagiannaki
    user = request.user
862 0be81d73 Sofia Papagiannaki
    index_url = reverse('index')
863 0be81d73 Sofia Papagiannaki
864 0be81d73 Sofia Papagiannaki
    if isinstance(user, User) and user.is_authenticated():
865 0be81d73 Sofia Papagiannaki
        l = []
866 0be81d73 Sofia Papagiannaki
        append = l.append
867 0be81d73 Sofia Papagiannaki
        item = MenuItem
868 0be81d73 Sofia Papagiannaki
        item.current_path = request.build_absolute_uri(request.path)
869 0be81d73 Sofia Papagiannaki
        append(item(url=request.build_absolute_uri(reverse('index')),
870 0be81d73 Sofia Papagiannaki
                    name=user.email))
871 0be81d73 Sofia Papagiannaki
        if with_extra_links:
872 0be81d73 Sofia Papagiannaki
            append(item(url=request.build_absolute_uri(reverse('landing')),
873 0be81d73 Sofia Papagiannaki
                        name="Overview"))
874 0be81d73 Sofia Papagiannaki
        if with_signout:
875 0be81d73 Sofia Papagiannaki
            append(item(url=request.build_absolute_uri(reverse('landing')),
876 0be81d73 Sofia Papagiannaki
                        name="Dashboard"))
877 0be81d73 Sofia Papagiannaki
        if with_extra_links:
878 0be81d73 Sofia Papagiannaki
            append(item(url=request.build_absolute_uri(reverse('edit_profile')),
879 0be81d73 Sofia Papagiannaki
                        name="Profile"))
880 0be81d73 Sofia Papagiannaki
881 0be81d73 Sofia Papagiannaki
        if with_extra_links:
882 0be81d73 Sofia Papagiannaki
            if settings.INVITATIONS_ENABLED:
883 0be81d73 Sofia Papagiannaki
                append(item(url=request.build_absolute_uri(reverse('invite')),
884 0be81d73 Sofia Papagiannaki
                            name="Invitations"))
885 0be81d73 Sofia Papagiannaki
886 7763f5c6 Kostas Papadimitriou
            append(item(url=request.build_absolute_uri(reverse('api_access')),
887 7763f5c6 Kostas Papadimitriou
                        name="API access"))
888 7763f5c6 Kostas Papadimitriou
889 0be81d73 Sofia Papagiannaki
            append(item(url=request.build_absolute_uri(reverse('resource_usage')),
890 0be81d73 Sofia Papagiannaki
                        name="Usage"))
891 0be81d73 Sofia Papagiannaki
892 0be81d73 Sofia Papagiannaki
            if settings.PROJECTS_VISIBLE:
893 0be81d73 Sofia Papagiannaki
                append(item(url=request.build_absolute_uri(reverse('project_list')),
894 0be81d73 Sofia Papagiannaki
                            name="Projects"))
895 0be81d73 Sofia Papagiannaki
896 0be81d73 Sofia Papagiannaki
            append(item(url=request.build_absolute_uri(reverse('feedback')),
897 0be81d73 Sofia Papagiannaki
                        name="Contact"))
898 0be81d73 Sofia Papagiannaki
        if with_signout:
899 0be81d73 Sofia Papagiannaki
            append(item(url=request.build_absolute_uri(reverse('logout')),
900 0be81d73 Sofia Papagiannaki
                        name="Sign out"))
901 0be81d73 Sofia Papagiannaki
    else:
902 0be81d73 Sofia Papagiannaki
        l = [{'url': request.build_absolute_uri(index_url),
903 0be81d73 Sofia Papagiannaki
              'name': _("Sign in")}]
904 0be81d73 Sofia Papagiannaki
905 0be81d73 Sofia Papagiannaki
    callback = request.GET.get('callback', None)
906 0be81d73 Sofia Papagiannaki
    data = json.dumps(tuple(l))
907 0be81d73 Sofia Papagiannaki
    mimetype = 'application/json'
908 0be81d73 Sofia Papagiannaki
909 0be81d73 Sofia Papagiannaki
    if callback:
910 0be81d73 Sofia Papagiannaki
        mimetype = 'application/javascript'
911 0be81d73 Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
912 0be81d73 Sofia Papagiannaki
913 0be81d73 Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)
914 0be81d73 Sofia Papagiannaki
915 0be81d73 Sofia Papagiannaki
916 0be81d73 Sofia Papagiannaki
class MenuItem(dict):
917 0be81d73 Sofia Papagiannaki
    current_path = ''
918 0be81d73 Sofia Papagiannaki
919 0be81d73 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
920 0be81d73 Sofia Papagiannaki
        super(MenuItem, self).__init__(*args, **kwargs)
921 0be81d73 Sofia Papagiannaki
        if kwargs.get('url') or kwargs.get('submenu'):
922 0be81d73 Sofia Papagiannaki
            self.__set_is_active__()
923 0be81d73 Sofia Papagiannaki
924 0be81d73 Sofia Papagiannaki
    def __setitem__(self, key, value):
925 0be81d73 Sofia Papagiannaki
        super(MenuItem, self).__setitem__(key, value)
926 0be81d73 Sofia Papagiannaki
        if key in ('url', 'submenu'):
927 0be81d73 Sofia Papagiannaki
            self.__set_is_active__()
928 0be81d73 Sofia Papagiannaki
929 0be81d73 Sofia Papagiannaki
    def __set_is_active__(self):
930 0be81d73 Sofia Papagiannaki
        if self.get('is_active'):
931 0be81d73 Sofia Papagiannaki
            return
932 0be81d73 Sofia Papagiannaki
        if self.current_path.startswith(self.get('url')):
933 0be81d73 Sofia Papagiannaki
            self.__setitem__('is_active', True)
934 0be81d73 Sofia Papagiannaki
        else:
935 0be81d73 Sofia Papagiannaki
            submenu = self.get('submenu', ())
936 0be81d73 Sofia Papagiannaki
            current = (i for i in submenu if i.get('url') == self.current_path)
937 0be81d73 Sofia Papagiannaki
            try:
938 0be81d73 Sofia Papagiannaki
                current_node = current.next()
939 0be81d73 Sofia Papagiannaki
                if not current_node.get('is_active'):
940 0be81d73 Sofia Papagiannaki
                    current_node.__setitem__('is_active', True)
941 0be81d73 Sofia Papagiannaki
                self.__setitem__('is_active', True)
942 0be81d73 Sofia Papagiannaki
            except StopIteration:
943 0be81d73 Sofia Papagiannaki
                return
944 0be81d73 Sofia Papagiannaki
945 0be81d73 Sofia Papagiannaki
    def __setattribute__(self, name, value):
946 0be81d73 Sofia Papagiannaki
        super(MenuItem, self).__setattribute__(name, value)
947 0be81d73 Sofia Papagiannaki
        if name == 'current_path':
948 0be81d73 Sofia Papagiannaki
            self.__set_is_active__()
949 58350a50 Sofia Papagiannaki
950 58350a50 Sofia Papagiannaki
951 58350a50 Sofia Papagiannaki
def get_services(request):
952 58350a50 Sofia Papagiannaki
    callback = request.GET.get('callback', None)
953 58350a50 Sofia Papagiannaki
    mimetype = 'application/json'
954 bea584e1 Giorgos Korfiatis
    data = json.dumps(Component.catalog().values())
955 58350a50 Sofia Papagiannaki
956 58350a50 Sofia Papagiannaki
    if callback:
957 58350a50 Sofia Papagiannaki
        # Consume session messages. When get_services is loaded from an astakos
958 58350a50 Sofia Papagiannaki
        # page, messages should have already been consumed in the html
959 58350a50 Sofia Papagiannaki
        # response. When get_services is loaded from another domain/service we
960 58350a50 Sofia Papagiannaki
        # consume them here so that no stale messages to appear if user visits
961 58350a50 Sofia Papagiannaki
        # an astakos view later on.
962 58350a50 Sofia Papagiannaki
        # TODO: messages could be served to other services/sites in the dict
963 58350a50 Sofia Papagiannaki
        # response of get_services and/or get_menu. Services could handle those
964 58350a50 Sofia Papagiannaki
        # messages respectively.
965 58350a50 Sofia Papagiannaki
        messages_list = list(messages.get_messages(request))
966 58350a50 Sofia Papagiannaki
        mimetype = 'application/javascript'
967 58350a50 Sofia Papagiannaki
        data = '%s(%s)' % (callback, data)
968 58350a50 Sofia Papagiannaki
969 58350a50 Sofia Papagiannaki
    return HttpResponse(content=data, mimetype=mimetype)