Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views / im.py @ a1ed6730

History | View | Annotate | Download (35.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 890b0eaf Sofia Papagiannaki
@transaction.commit_manually
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 890b0eaf Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the number of the
158 890b0eaf Sofia Papagiannaki
    user invitations is going to be updated only if the email 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 8f5a3a06 Sofia Papagiannaki
                try:
192 9a06d96f Olga Brani
                    email = form.cleaned_data.get('username')
193 9a06d96f Olga Brani
                    realname = form.cleaned_data.get('realname')
194 9cdb86fd Sofia Papagiannaki
                    invite_func(inviter, email, realname)
195 ae497612 Olga Brani
                    message = _(astakos_messages.INVITATION_SENT) % locals()
196 24406ae3 Sofia Papagiannaki
                    messages.success(request, message)
197 e7cb4085 Kostas Papadimitriou
                except Exception, e:
198 18ffbee1 Sofia Papagiannaki
                    transaction.rollback()
199 e7cb4085 Kostas Papadimitriou
                    raise
200 18ffbee1 Sofia Papagiannaki
                else:
201 18ffbee1 Sofia Papagiannaki
                    transaction.commit()
202 64cd4730 Antony Chazapis
        else:
203 ae497612 Olga Brani
            message = _(astakos_messages.MAX_INVITATION_NUMBER_REACHED)
204 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
205 176023aa Kostas Papadimitriou
206 a196eb7e Sofia Papagiannaki
    sent = [{'email': inv.username,
207 d6ae71a2 root
             'realname': inv.realname,
208 d6ae71a2 root
             'is_consumed': inv.is_consumed}
209 5ce3ce4f Sofia Papagiannaki
            for inv in request.user.invitations_sent.all()]
210 77e2ad52 root
    kwargs = {'inviter': inviter,
211 5ce3ce4f Sofia Papagiannaki
              'sent': sent}
212 0905ccd2 Sofia Papagiannaki
    context = get_context(request, extra_context, **kwargs)
213 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
214 5ce3ce4f Sofia Papagiannaki
                           invitation_form=form,
215 5ce3ce4f Sofia Papagiannaki
                           context_instance=context)
216 5ce3ce4f Sofia Papagiannaki
217 64cd4730 Antony Chazapis
218 1ca02d1a Kostas Papadimitriou
219 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
220 7763f5c6 Kostas Papadimitriou
@required_auth_methods_assigned()
221 7763f5c6 Kostas Papadimitriou
@login_required
222 7763f5c6 Kostas Papadimitriou
@cookie_fix
223 7763f5c6 Kostas Papadimitriou
@signed_terms_required
224 1ca02d1a Kostas Papadimitriou
def api_access_config(request, template_name='im/api_access_config.html',
225 1ca02d1a Kostas Papadimitriou
                      content_type='text/plain', extra_context=None,
226 1ca02d1a Kostas Papadimitriou
                      filename='.kamakirc'):
227 1ca02d1a Kostas Papadimitriou
228 1ca02d1a Kostas Papadimitriou
    if settings.KAMAKI_CONFIG_CLOUD_NAME:
229 1ca02d1a Kostas Papadimitriou
        cloud_name = settings.KAMAKI_CONFIG_CLOUD_NAME
230 1ca02d1a Kostas Papadimitriou
    else:
231 1ca02d1a Kostas Papadimitriou
        cloud_name = branding_settings.SERVICE_NAME.replace(' ', '_').lower()
232 1ca02d1a Kostas Papadimitriou
233 1ca02d1a Kostas Papadimitriou
    url = get_public_endpoint(settings.astakos_services, 'identity')
234 1ca02d1a Kostas Papadimitriou
235 1ca02d1a Kostas Papadimitriou
    context = {
236 1ca02d1a Kostas Papadimitriou
        'user': request.user,
237 1ca02d1a Kostas Papadimitriou
        'services': Component.catalog(),
238 1ca02d1a Kostas Papadimitriou
        'token_url': url,
239 1ca02d1a Kostas Papadimitriou
        'cloud_name': cloud_name
240 1ca02d1a Kostas Papadimitriou
    }
241 1ca02d1a Kostas Papadimitriou
242 1ca02d1a Kostas Papadimitriou
    extra_context = extra_context or {}
243 1ca02d1a Kostas Papadimitriou
    context.update(extra_context)
244 1ca02d1a Kostas Papadimitriou
    content = branding.render_to_string(template_name, context,
245 1ca02d1a Kostas Papadimitriou
                                        RequestContext(request))
246 967a99e1 Kostas Papadimitriou
    response = HttpResponse(content_type=content_type)
247 1ca02d1a Kostas Papadimitriou
    response.status_code = 200
248 1ca02d1a Kostas Papadimitriou
    response['Content-Disposition'] = 'attachment; filename="%s"' % filename
249 1ca02d1a Kostas Papadimitriou
    response.content = content
250 1ca02d1a Kostas Papadimitriou
    return response
251 1ca02d1a Kostas Papadimitriou
252 1ca02d1a Kostas Papadimitriou
253 1ca02d1a Kostas Papadimitriou
@required_auth_methods_assigned()
254 1ca02d1a Kostas Papadimitriou
@login_required
255 1ca02d1a Kostas Papadimitriou
@cookie_fix
256 1ca02d1a Kostas Papadimitriou
@signed_terms_required
257 7763f5c6 Kostas Papadimitriou
def api_access(request, template_name='im/api_access.html',
258 7763f5c6 Kostas Papadimitriou
               extra_context=None):
259 7763f5c6 Kostas Papadimitriou
    """
260 7763f5c6 Kostas Papadimitriou
    API access view.
261 7763f5c6 Kostas Papadimitriou
    """
262 7763f5c6 Kostas Papadimitriou
    context = {}
263 7763f5c6 Kostas Papadimitriou
264 3466f0a3 Kostas Papadimitriou
    url = get_public_endpoint(settings.astakos_services, 'identity')
265 7763f5c6 Kostas Papadimitriou
    context['services'] = Component.catalog()
266 3466f0a3 Kostas Papadimitriou
    context['token_url'] = url
267 31240d2c Olga Brani
    context['user'] = request.user
268 7763f5c6 Kostas Papadimitriou
    context['client_url'] = settings.API_CLIENT_URL
269 7763f5c6 Kostas Papadimitriou
270 7763f5c6 Kostas Papadimitriou
    if extra_context:
271 7763f5c6 Kostas Papadimitriou
        context.update(extra_context)
272 7763f5c6 Kostas Papadimitriou
    context_instance = get_context(request, context)
273 7763f5c6 Kostas Papadimitriou
    return render_response(template_name,
274 7763f5c6 Kostas Papadimitriou
                           context_instance=context_instance)
275 7763f5c6 Kostas Papadimitriou
276 7763f5c6 Kostas Papadimitriou
277 7763f5c6 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
278 9d20fe23 Kostas Papadimitriou
@required_auth_methods_assigned(allow_access=True)
279 890b0eaf Sofia Papagiannaki
@login_required
280 222305b7 Sofia Papagiannaki
@cookie_fix
281 270dd48d Sofia Papagiannaki
@signed_terms_required
282 aab4d540 Sofia Papagiannaki
def edit_profile(request, template_name='im/profile.html', extra_context=None):
283 890b0eaf Sofia Papagiannaki
    """
284 890b0eaf Sofia Papagiannaki
    Allows a user to edit his/her profile.
285 176023aa Kostas Papadimitriou

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

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

292 890b0eaf Sofia Papagiannaki
    **Arguments**
293 176023aa Kostas Papadimitriou

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

298 890b0eaf Sofia Papagiannaki
    ``extra_context``
299 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
300 176023aa Kostas Papadimitriou

301 890b0eaf Sofia Papagiannaki
    **Template:**
302 176023aa Kostas Papadimitriou

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

305 92defad4 Sofia Papagiannaki
    **Settings:**
306 176023aa Kostas Papadimitriou

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

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

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

379 e7cb4085 Kostas Papadimitriou
    The user activation will be delegated to the backend specified by the
380 e7cb4085 Kostas Papadimitriou
    ``activation_backend`` keyword argument if present, otherwise to the
381 e7cb4085 Kostas Papadimitriou
    ``astakos.im.activation_backends.InvitationBackend`` if
382 e7cb4085 Kostas Papadimitriou
    settings.ASTAKOS_INVITATIONS_ENABLED is True or
383 e7cb4085 Kostas Papadimitriou
    ``astakos.im.activation_backends.SimpleBackend`` if not (see
384 e7cb4085 Kostas Papadimitriou
    activation_backends);
385 5ce3ce4f Sofia Papagiannaki

386 e7cb4085 Kostas Papadimitriou
    Upon successful user creation, if ``next`` url parameter is present the
387 e7cb4085 Kostas Papadimitriou
    user is redirected there otherwise renders the same page with a success
388 e7cb4085 Kostas Papadimitriou
    message.
389 5ce3ce4f Sofia Papagiannaki

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

392 890b0eaf Sofia Papagiannaki
    **Arguments**
393 5ce3ce4f Sofia Papagiannaki

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

398 890b0eaf Sofia Papagiannaki
    ``extra_context``
399 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
400 176023aa Kostas Papadimitriou

401 43332a76 Kostas Papadimitriou
    ``on_success``
402 43332a76 Kostas Papadimitriou
        Resolvable view name to redirect on registration success.
403 43332a76 Kostas Papadimitriou

404 890b0eaf Sofia Papagiannaki
    **Template:**
405 5ce3ce4f Sofia Papagiannaki

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

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

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

528 890b0eaf Sofia Papagiannaki
    **Arguments**
529 176023aa Kostas Papadimitriou

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

534 890b0eaf Sofia Papagiannaki
    ``extra_context``
535 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
536 176023aa Kostas Papadimitriou

537 890b0eaf Sofia Papagiannaki
    **Template:**
538 176023aa Kostas Papadimitriou

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

541 890b0eaf Sofia Papagiannaki
    **Settings:**
542 176023aa Kostas Papadimitriou

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

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