Statistics
| Branch: | Tag: | Revision:

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

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 c2c4af89 Georgios D. Tsoukalas
from django.conf import settings as django_settings
81 c2c4af89 Georgios D. Tsoukalas
82 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
83 e015e9e6 Sofia Papagiannaki
84 9a06d96f Olga Brani
85 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
86 222305b7 Sofia Papagiannaki
@cookie_fix
87 270dd48d Sofia Papagiannaki
@signed_terms_required
88 1ecda536 Kostas Papadimitriou
def login(request, template_name='im/login.html', extra_context=None):
89 890b0eaf Sofia Papagiannaki
    """
90 1ecda536 Kostas Papadimitriou
    Renders login page.
91 176023aa Kostas Papadimitriou

92 890b0eaf Sofia Papagiannaki
    **Arguments**
93 176023aa Kostas Papadimitriou

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

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

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

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

159 890b0eaf Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the number of the
160 890b0eaf Sofia Papagiannaki
    user invitations is going to be updated only if the email has been successfully sent.
161 176023aa Kostas Papadimitriou

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

164 890b0eaf Sofia Papagiannaki
    **Arguments**
165 176023aa Kostas Papadimitriou

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

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

173 890b0eaf Sofia Papagiannaki
    **Template:**
174 176023aa Kostas Papadimitriou

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

177 890b0eaf Sofia Papagiannaki
    **Settings:**
178 176023aa Kostas Papadimitriou

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

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

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

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

294 890b0eaf Sofia Papagiannaki
    **Arguments**
295 176023aa Kostas Papadimitriou

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

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

303 890b0eaf Sofia Papagiannaki
    **Template:**
304 176023aa Kostas Papadimitriou

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

307 92defad4 Sofia Papagiannaki
    **Settings:**
308 176023aa Kostas Papadimitriou

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

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

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

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

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

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

394 890b0eaf Sofia Papagiannaki
    **Arguments**
395 5ce3ce4f Sofia Papagiannaki

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

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

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

406 890b0eaf Sofia Papagiannaki
    **Template:**
407 5ce3ce4f Sofia Papagiannaki

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

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

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

530 890b0eaf Sofia Papagiannaki
    **Arguments**
531 176023aa Kostas Papadimitriou

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

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

539 890b0eaf Sofia Papagiannaki
    **Template:**
540 176023aa Kostas Papadimitriou

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

543 890b0eaf Sofia Papagiannaki
    **Settings:**
544 176023aa Kostas Papadimitriou

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

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