Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (35.1 kB)

1 1808f7bc Giorgos Korfiatis
# Copyright 2011, 2012, 2013 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 c630fee6 Kostas Papadimitriou
import astakos.im.messages as astakos_messages
58 c630fee6 Kostas Papadimitriou
59 e7cb4085 Kostas Papadimitriou
from astakos.im import activation_backends
60 3e0a032d Sofia Papagiannaki
from astakos.im.models import AstakosUser, ApprovalTerms, EmailChange, \
61 bea584e1 Giorgos Korfiatis
    AstakosUserAuthProvider, PendingThirdPartyUser, Component
62 3e0a032d Sofia Papagiannaki
from astakos.im.util import get_context, prepare_response, get_query, \
63 3e0a032d Sofia Papagiannaki
    restrict_next
64 3e0a032d Sofia Papagiannaki
from astakos.im.forms import LoginForm, InvitationForm, FeedbackForm, \
65 3e0a032d Sofia Papagiannaki
    SignApprovalTermsForm, EmailChangeForm
66 f7400729 Kostas Papadimitriou
from astakos.im.forms import ExtendedProfileForm as ProfileForm
67 1ca02d1a Kostas Papadimitriou
from synnefo.lib.services import get_public_endpoint
68 3e0a032d Sofia Papagiannaki
from astakos.im.functions import send_feedback, logout as auth_logout, \
69 3e0a032d Sofia Papagiannaki
    invite as invite_func
70 e7cb4085 Kostas Papadimitriou
from astakos.im import settings
71 8998f09a Sofia Papagiannaki
from astakos.im import presentation
72 9d20fe23 Kostas Papadimitriou
from astakos.im import auth_providers as auth
73 4e03ba30 Kostas Papadimitriou
from astakos.im import quotas
74 70e11eaa Sofia Papagiannaki
from astakos.im.views.util import render_response, _resources_catalog
75 70e11eaa Sofia Papagiannaki
from astakos.im.views.decorators import cookie_fix, signed_terms_required,\
76 b6496f0c Kostas Papadimitriou
    required_auth_methods_assigned, valid_astakos_user_required, login_required
77 ae497612 Olga Brani
78 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
79 e015e9e6 Sofia Papagiannaki
80 9a06d96f Olga Brani
81 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
82 222305b7 Sofia Papagiannaki
@cookie_fix
83 270dd48d Sofia Papagiannaki
@signed_terms_required
84 1ecda536 Kostas Papadimitriou
def login(request, template_name='im/login.html', extra_context=None):
85 890b0eaf Sofia Papagiannaki
    """
86 1ecda536 Kostas Papadimitriou
    Renders login page.
87 176023aa Kostas Papadimitriou

88 890b0eaf Sofia Papagiannaki
    **Arguments**
89 176023aa Kostas Papadimitriou

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

389 890b0eaf Sofia Papagiannaki
    **Arguments**
390 5ce3ce4f Sofia Papagiannaki

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

395 890b0eaf Sofia Papagiannaki
    ``extra_context``
396 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
397 176023aa Kostas Papadimitriou

398 43332a76 Kostas Papadimitriou
    ``on_success``
399 43332a76 Kostas Papadimitriou
        Resolvable view name to redirect on registration success.
400 43332a76 Kostas Papadimitriou

401 890b0eaf Sofia Papagiannaki
    **Template:**
402 5ce3ce4f Sofia Papagiannaki

403 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
404 890b0eaf Sofia Papagiannaki
    """
405 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
406 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
407 e7cb4085 Kostas Papadimitriou
        logger.info("%s already signed in, redirect to index",
408 e7cb4085 Kostas Papadimitriou
                    request.user.log_display)
409 e7cb4085 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('index'))
410 5ce3ce4f Sofia Papagiannaki
411 0a569195 Sofia Papagiannaki
    provider = get_query(request).get('provider', 'local')
412 3f40ce16 Kostas Papadimitriou
    try:
413 3f40ce16 Kostas Papadimitriou
        auth.get_provider(provider)
414 3f40ce16 Kostas Papadimitriou
    except auth.InvalidProvider, e:
415 3f40ce16 Kostas Papadimitriou
        messages.error(request, e.message)
416 3f40ce16 Kostas Papadimitriou
        return HttpResponseRedirect(reverse("signup"))
417 3f40ce16 Kostas Papadimitriou
418 9d20fe23 Kostas Papadimitriou
    if not auth.get_provider(provider).get_create_policy:
419 e7cb4085 Kostas Papadimitriou
        logger.error("%s provider not available for signup", provider)
420 279d6e51 Olga Brani
        raise PermissionDenied
421 279d6e51 Olga Brani
422 e7cb4085 Kostas Papadimitriou
    instance = None
423 6c8a3f7c Sofia Papagiannaki
424 e7cb4085 Kostas Papadimitriou
    # user registered using third party provider
425 8ab484ea Kostas Papadimitriou
    third_party_token = request.REQUEST.get('third_party_token', None)
426 9d20fe23 Kostas Papadimitriou
    unverified = None
427 c1f65a1e Kostas Papadimitriou
    pending = None
428 c630fee6 Kostas Papadimitriou
    if third_party_token:
429 e7cb4085 Kostas Papadimitriou
        # retreive third party entry. This was created right after the initial
430 e7cb4085 Kostas Papadimitriou
        # third party provider handshake.
431 c630fee6 Kostas Papadimitriou
        pending = get_object_or_404(PendingThirdPartyUser,
432 c630fee6 Kostas Papadimitriou
                                    token=third_party_token)
433 9d20fe23 Kostas Papadimitriou
434 c630fee6 Kostas Papadimitriou
        provider = pending.provider
435 e7cb4085 Kostas Papadimitriou
436 e7cb4085 Kostas Papadimitriou
        # clone third party instance into the corresponding AstakosUser
437 c630fee6 Kostas Papadimitriou
        instance = pending.get_user_instance()
438 9d20fe23 Kostas Papadimitriou
        get_unverified = AstakosUserAuthProvider.objects.unverified
439 e7cb4085 Kostas Papadimitriou
440 e7cb4085 Kostas Papadimitriou
        # check existing unverified entries
441 9d20fe23 Kostas Papadimitriou
        unverified = get_unverified(pending.provider,
442 9d20fe23 Kostas Papadimitriou
                                    identifier=pending.third_party_identifier)
443 9d20fe23 Kostas Papadimitriou
444 d7030402 Kostas Papadimitriou
        get_verified = AstakosUserAuthProvider.objects.verified
445 d7030402 Kostas Papadimitriou
        verified = get_verified(pending.provider,
446 d7030402 Kostas Papadimitriou
                                identifier=pending.third_party_identifier)
447 d7030402 Kostas Papadimitriou
        if verified:
448 d7030402 Kostas Papadimitriou
            # an existing verified user already exists for the third party
449 d7030402 Kostas Papadimitriou
            # identifier
450 d7030402 Kostas Papadimitriou
            pending.delete()
451 d7030402 Kostas Papadimitriou
            raise Http404
452 d7030402 Kostas Papadimitriou
453 9d20fe23 Kostas Papadimitriou
        if unverified and request.method == 'GET':
454 9d20fe23 Kostas Papadimitriou
            messages.warning(request, unverified.get_pending_registration_msg)
455 8ab484ea Kostas Papadimitriou
456 e7cb4085 Kostas Papadimitriou
    # prepare activation backend based on current request
457 e7cb4085 Kostas Papadimitriou
    if not activation_backend:
458 e7cb4085 Kostas Papadimitriou
        activation_backend = activation_backends.get_backend()
459 e7cb4085 Kostas Papadimitriou
460 e7726e14 Kostas Papadimitriou
    form_kwargs = {'instance': instance, 'request': request}
461 e7cb4085 Kostas Papadimitriou
    if third_party_token:
462 e7cb4085 Kostas Papadimitriou
        form_kwargs['third_party_token'] = third_party_token
463 e7cb4085 Kostas Papadimitriou
464 c1f65a1e Kostas Papadimitriou
    if pending:
465 c1f65a1e Kostas Papadimitriou
        form_kwargs['initial'] = {
466 c1f65a1e Kostas Papadimitriou
            'first_name': pending.first_name,
467 c1f65a1e Kostas Papadimitriou
            'last_name': pending.last_name,
468 c1f65a1e Kostas Papadimitriou
            'email': pending.email
469 c1f65a1e Kostas Papadimitriou
        }
470 c1f65a1e Kostas Papadimitriou
471 e7cb4085 Kostas Papadimitriou
    form = activation_backend.get_signup_form(
472 e7cb4085 Kostas Papadimitriou
        provider, None, **form_kwargs)
473 9d20fe23 Kostas Papadimitriou
474 11d5fd8b Kostas Papadimitriou
475 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
476 e7cb4085 Kostas Papadimitriou
        form = activation_backend.get_signup_form(
477 e7cb4085 Kostas Papadimitriou
            provider,
478 e7cb4085 Kostas Papadimitriou
            request.POST,
479 e7cb4085 Kostas Papadimitriou
            **form_kwargs)
480 e7cb4085 Kostas Papadimitriou
481 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
482 1808f7bc Giorgos Korfiatis
            user = form.create_user()
483 554ef175 Christos Stavrakakis
            result = activation_backend.handle_registration(user)
484 554ef175 Christos Stavrakakis
            if result.status == \
485 554ef175 Christos Stavrakakis
                    activation_backend.Result.PENDING_MODERATION:
486 554ef175 Christos Stavrakakis
                # user should be warned that his account is not active yet
487 554ef175 Christos Stavrakakis
                status = messages.WARNING
488 554ef175 Christos Stavrakakis
            else:
489 554ef175 Christos Stavrakakis
                status = messages.SUCCESS
490 554ef175 Christos Stavrakakis
            message = result.message
491 554ef175 Christos Stavrakakis
            activation_backend.send_result_notifications(result, user)
492 792c2f3b Olga Brani
493 554ef175 Christos Stavrakakis
            # commit user entry
494 554ef175 Christos Stavrakakis
            transaction.commit()
495 554ef175 Christos Stavrakakis
496 554ef175 Christos Stavrakakis
            if user and user.is_active:
497 554ef175 Christos Stavrakakis
                # activation backend directly activated the user
498 554ef175 Christos Stavrakakis
                # log him in
499 554ef175 Christos Stavrakakis
                next = request.POST.get('next', '')
500 554ef175 Christos Stavrakakis
                response = prepare_response(request, user, next=next)
501 554ef175 Christos Stavrakakis
                return response
502 554ef175 Christos Stavrakakis
503 554ef175 Christos Stavrakakis
            messages.add_message(request, status, message)
504 554ef175 Christos Stavrakakis
            return HttpResponseRedirect(reverse(on_success))
505 43332a76 Kostas Papadimitriou
506 8fb8d0cf Giorgos Korfiatis
    return render_response(
507 8fb8d0cf Giorgos Korfiatis
        template_name,
508 8fb8d0cf Giorgos Korfiatis
        signup_form=form,
509 8fb8d0cf Giorgos Korfiatis
        third_party_token=third_party_token,
510 8fb8d0cf Giorgos Korfiatis
        provider=provider,
511 8fb8d0cf Giorgos Korfiatis
        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 8fb8d0cf Giorgos Korfiatis
def feedback(request, template_name='im/feedback.html',
520 8fb8d0cf Giorgos Korfiatis
             email_template_name='im/feedback_mail.txt', extra_context=None):
521 890b0eaf Sofia Papagiannaki
    """
522 890b0eaf Sofia Papagiannaki
    Allows a user to send feedback.
523 176023aa Kostas Papadimitriou

524 8fb8d0cf Giorgos Korfiatis
    In case of GET request renders a form for providing the feedback
525 8fb8d0cf Giorgos Korfiatis
    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 8fb8d0cf Giorgos Korfiatis
        last_provider = request.COOKIES.get(
599 8fb8d0cf Giorgos Korfiatis
            'astakos_last_login_method', 'local')
600 3f40ce16 Kostas Papadimitriou
        try:
601 3f40ce16 Kostas Papadimitriou
            provider = auth.get_provider(last_provider)
602 3f40ce16 Kostas Papadimitriou
        except auth.InvalidProvider:
603 3f40ce16 Kostas Papadimitriou
            provider = auth.get_provider('local')
604 3f40ce16 Kostas Papadimitriou
605 9d20fe23 Kostas Papadimitriou
        message = provider.get_logout_success_msg
606 9d20fe23 Kostas Papadimitriou
        extra = provider.get_logout_success_extra_msg
607 3f40ce16 Kostas Papadimitriou
608 9d20fe23 Kostas Papadimitriou
        if extra:
609 8fb8d0cf Giorgos Korfiatis
            message += "<br />" + extra
610 d21d422a Kostas Papadimitriou
        messages.success(request, message)
611 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
612 c630fee6 Kostas Papadimitriou
        response.status_code = 301
613 49df775e Sofia Papagiannaki
    return response
614 2126d85d Sofia Papagiannaki
615 5ce3ce4f Sofia Papagiannaki
616 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
617 222305b7 Sofia Papagiannaki
@cookie_fix
618 554ef175 Christos Stavrakakis
@transaction.commit_on_success
619 3bb604eb Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt',
620 3bb604eb Sofia Papagiannaki
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
621 2126d85d Sofia Papagiannaki
    """
622 e7cb4085 Kostas Papadimitriou
    Activates the user identified by the ``auth`` request parameter, sends a
623 e7cb4085 Kostas Papadimitriou
    welcome email and renews the user token.
624 176023aa Kostas Papadimitriou

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