Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 673f8f42

History | View | Annotate | Download (58 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 6e029beb Sofia Papagiannaki
import calendar
36 9a06d96f Olga Brani
import inflect
37 9a06d96f Olga Brani
38 9a06d96f Olga Brani
engine = inflect.engine()
39 64cd4730 Antony Chazapis
40 0905ccd2 Sofia Papagiannaki
from urllib import quote
41 63ecdd20 Sofia Papagiannaki
from functools import wraps
42 c0b26605 Sofia Papagiannaki
from datetime import datetime
43 76ca5ff0 Kostas Papadimitriou
from synnefo.lib.ordereddict import OrderedDict
44 64cd4730 Antony Chazapis
45 a5cef8d0 Kostas Papadimitriou
from django_tables2 import RequestConfig
46 a5cef8d0 Kostas Papadimitriou
47 c630fee6 Kostas Papadimitriou
from django.shortcuts import get_object_or_404
48 890b0eaf Sofia Papagiannaki
from django.contrib import messages
49 01ac12d5 Sofia Papagiannaki
from django.contrib.auth.decorators import login_required
50 01ac12d5 Sofia Papagiannaki
from django.core.urlresolvers import reverse
51 01ac12d5 Sofia Papagiannaki
from django.db import transaction
52 01ac12d5 Sofia Papagiannaki
from django.db.utils import IntegrityError
53 73fbaec4 Sofia Papagiannaki
from django.http import (
54 73fbaec4 Sofia Papagiannaki
    HttpResponse, HttpResponseBadRequest,
55 73fbaec4 Sofia Papagiannaki
    HttpResponseForbidden, HttpResponseRedirect,
56 73fbaec4 Sofia Papagiannaki
    HttpResponseBadRequest, Http404)
57 01ac12d5 Sofia Papagiannaki
from django.shortcuts import redirect
58 661c4479 Sofia Papagiannaki
from django.template import RequestContext, loader as template_loader
59 01ac12d5 Sofia Papagiannaki
from django.utils.http import urlencode
60 efb334ca Sofia Papagiannaki
from django.utils.html import escape
61 564a2292 Kostas Papadimitriou
from django.utils.safestring import mark_safe
62 01ac12d5 Sofia Papagiannaki
from django.utils.translation import ugettext as _
63 e1a80257 Sofia Papagiannaki
from django.views.generic.create_update import (
64 4e748491 Sofia Papagiannaki
    apply_extra_context, lookup_object, delete_object, get_model_and_form_class)
65 f3342849 Sofia Papagiannaki
from django.views.generic.list_detail import object_list, object_detail
66 661c4479 Sofia Papagiannaki
from django.core.xheaders import populate_xheaders
67 792c2f3b Olga Brani
from django.core.exceptions import ValidationError, PermissionDenied
68 c0b26605 Sofia Papagiannaki
from django.template.loader import render_to_string
69 9a06d96f Olga Brani
from django.views.decorators.http import require_http_methods
70 29b0ec5a Sofia Papagiannaki
from django.db.models import Q
71 bfe23b13 Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
72 96b44c04 Sofia Papagiannaki
from django.utils import simplejson as json
73 d886c63d Sofia Papagiannaki
from django.contrib.auth.views import redirect_to_login
74 c0b26605 Sofia Papagiannaki
75 c630fee6 Kostas Papadimitriou
import astakos.im.messages as astakos_messages
76 c630fee6 Kostas Papadimitriou
77 29b0ec5a Sofia Papagiannaki
from astakos.im.activation_backends import get_backend, SimpleBackend
78 5550bcfb Kostas Papadimitriou
from astakos.im import tables
79 e1a80257 Sofia Papagiannaki
from astakos.im.models import (
80 73fbaec4 Sofia Papagiannaki
    AstakosUser, ApprovalTerms,
81 26551b92 Kostas Papadimitriou
    EmailChange, AstakosUserAuthProvider, PendingThirdPartyUser,
82 0156e40c Kostas Papadimitriou
    ProjectApplication, ProjectMembership, Project, Service)
83 73fbaec4 Sofia Papagiannaki
from astakos.im.util import (
84 73fbaec4 Sofia Papagiannaki
    get_context, prepare_response, get_query, restrict_next)
85 e1a80257 Sofia Papagiannaki
from astakos.im.forms import (
86 f7400729 Kostas Papadimitriou
    LoginForm, InvitationForm,
87 e1a80257 Sofia Papagiannaki
    FeedbackForm, SignApprovalTermsForm,
88 e1a80257 Sofia Papagiannaki
    EmailChangeForm,
89 bfe23b13 Sofia Papagiannaki
    ProjectApplicationForm, ProjectSortForm,
90 73fbaec4 Sofia Papagiannaki
    AddProjectMembersForm, ProjectSearchForm,
91 73fbaec4 Sofia Papagiannaki
    ProjectMembersSortForm)
92 f7400729 Kostas Papadimitriou
from astakos.im.forms import ExtendedProfileForm as ProfileForm
93 f3342849 Sofia Papagiannaki
from astakos.im.functions import (
94 f3342849 Sofia Papagiannaki
    send_feedback, SendMailError,
95 f3342849 Sofia Papagiannaki
    logout as auth_logout,
96 f3342849 Sofia Papagiannaki
    activate as activate_func,
97 9cdb86fd Sofia Papagiannaki
    invite as invite_func,
98 f3342849 Sofia Papagiannaki
    send_activation as send_activation_func,
99 73fbaec4 Sofia Papagiannaki
    SendNotificationError,
100 c7c0ec58 Giorgos Korfiatis
    reached_pending_application_limit,
101 aad0e329 Giorgos Korfiatis
    accept_membership, reject_membership, remove_membership, cancel_membership,
102 d4660e00 Giorgos Korfiatis
    leave_project, join_project, enroll_member, can_join_request, can_leave_request,
103 8e1a5af5 Georgios D. Tsoukalas
    get_related_project_id, get_by_chain_or_404,
104 8e1a5af5 Georgios D. Tsoukalas
    approve_application, deny_application,
105 8e1a5af5 Georgios D. Tsoukalas
    cancel_application, dismiss_application)
106 f3342849 Sofia Papagiannaki
from astakos.im.settings import (
107 f3342849 Sofia Papagiannaki
    COOKIE_DOMAIN, LOGOUT_NEXT,
108 f3342849 Sofia Papagiannaki
    LOGGING_LEVEL, PAGINATE_BY,
109 4161cb70 Giorgos Korfiatis
    PAGINATE_BY_ALL,
110 3f8570dc Kostas Papadimitriou
    ACTIVATION_REDIRECT_URL,
111 a9c7ff8a Sofia Papagiannaki
    MODERATION_ENABLED)
112 75380308 Kostas Papadimitriou
from astakos.im import presentation
113 1ebea3d3 Kostas Papadimitriou
from astakos.im.api import get_services_dict
114 48421603 Kostas Papadimitriou
from astakos.im import settings as astakos_settings
115 820b18e0 Sofia Papagiannaki
from astakos.im.api.callpoint import AstakosCallpoint
116 9d20fe23 Kostas Papadimitriou
from astakos.im import auth_providers as auth
117 39b2cb50 Giorgos Korfiatis
from synnefo.lib.db.transaction import commit_on_success_strict
118 39b2cb50 Giorgos Korfiatis
from astakos.im.ctx import ExceptionHandler
119 ae497612 Olga Brani
120 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
121 e015e9e6 Sofia Papagiannaki
122 820b18e0 Sofia Papagiannaki
callpoint = AstakosCallpoint()
123 9a06d96f Olga Brani
124 b2ffa772 Sofia Papagiannaki
def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
125 890b0eaf Sofia Papagiannaki
    """
126 890b0eaf Sofia Papagiannaki
    Calls ``django.template.loader.render_to_string`` with an additional ``tab``
127 890b0eaf Sofia Papagiannaki
    keyword argument and returns an ``django.http.HttpResponse`` with the
128 890b0eaf Sofia Papagiannaki
    specified ``status``.
129 890b0eaf Sofia Papagiannaki
    """
130 64cd4730 Antony Chazapis
    if tab is None:
131 881c856c Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
132 64cd4730 Antony Chazapis
    kwargs.setdefault('tab', tab)
133 661c4479 Sofia Papagiannaki
    html = template_loader.render_to_string(
134 5ce3ce4f Sofia Papagiannaki
        template, kwargs, context_instance=context_instance)
135 c301698f Sofia Papagiannaki
    response = HttpResponse(html, status=status)
136 c301698f Sofia Papagiannaki
    return response
137 64cd4730 Antony Chazapis
138 792c2f3b Olga Brani
def requires_auth_provider(provider_id, **perms):
139 792c2f3b Olga Brani
    """
140 792c2f3b Olga Brani
    """
141 792c2f3b Olga Brani
    def decorator(func, *args, **kwargs):
142 792c2f3b Olga Brani
        @wraps(func)
143 792c2f3b Olga Brani
        def wrapper(request, *args, **kwargs):
144 9d20fe23 Kostas Papadimitriou
            provider = auth.get_provider(provider_id)
145 792c2f3b Olga Brani
146 792c2f3b Olga Brani
            if not provider or not provider.is_active():
147 792c2f3b Olga Brani
                raise PermissionDenied
148 792c2f3b Olga Brani
149 9d20fe23 Kostas Papadimitriou
            for pkey, value in perms.iteritems():
150 9d20fe23 Kostas Papadimitriou
                attr = 'get_%s_policy' % pkey.lower()
151 9d20fe23 Kostas Papadimitriou
                if getattr(provider, attr) != value:
152 9d20fe23 Kostas Papadimitriou
                    #TODO: add session message
153 9d20fe23 Kostas Papadimitriou
                    return HttpResponseRedirect(reverse('login'))
154 792c2f3b Olga Brani
            return func(request, *args)
155 792c2f3b Olga Brani
        return wrapper
156 792c2f3b Olga Brani
    return decorator
157 792c2f3b Olga Brani
158 63ecdd20 Sofia Papagiannaki
159 63ecdd20 Sofia Papagiannaki
def requires_anonymous(func):
160 63ecdd20 Sofia Papagiannaki
    """
161 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is not Anonymous and in that case
162 7482228b Sofia Papagiannaki
    redirects to `logout`.
163 63ecdd20 Sofia Papagiannaki
    """
164 63ecdd20 Sofia Papagiannaki
    @wraps(func)
165 63ecdd20 Sofia Papagiannaki
    def wrapper(request, *args):
166 63ecdd20 Sofia Papagiannaki
        if not request.user.is_anonymous():
167 63ecdd20 Sofia Papagiannaki
            next = urlencode({'next': request.build_absolute_uri()})
168 270dd48d Sofia Papagiannaki
            logout_uri = reverse(logout) + '?' + next
169 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(logout_uri)
170 63ecdd20 Sofia Papagiannaki
        return func(request, *args)
171 63ecdd20 Sofia Papagiannaki
    return wrapper
172 63ecdd20 Sofia Papagiannaki
173 5ce3ce4f Sofia Papagiannaki
174 270dd48d Sofia Papagiannaki
def signed_terms_required(func):
175 270dd48d Sofia Papagiannaki
    """
176 badcb2a9 Kostas Papadimitriou
    Decorator checks whether the request.user is Anonymous and in that case
177 270dd48d Sofia Papagiannaki
    redirects to `logout`.
178 270dd48d Sofia Papagiannaki
    """
179 270dd48d Sofia Papagiannaki
    @wraps(func)
180 270dd48d Sofia Papagiannaki
    def wrapper(request, *args, **kwargs):
181 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
182 270dd48d Sofia Papagiannaki
            params = urlencode({'next': request.build_absolute_uri(),
183 5ce3ce4f Sofia Papagiannaki
                                'show_form': ''})
184 270dd48d Sofia Papagiannaki
            terms_uri = reverse('latest_terms') + '?' + params
185 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(terms_uri)
186 270dd48d Sofia Papagiannaki
        return func(request, *args, **kwargs)
187 270dd48d Sofia Papagiannaki
    return wrapper
188 270dd48d Sofia Papagiannaki
189 5ce3ce4f Sofia Papagiannaki
190 9d20fe23 Kostas Papadimitriou
def required_auth_methods_assigned(allow_access=False):
191 badcb2a9 Kostas Papadimitriou
    """
192 badcb2a9 Kostas Papadimitriou
    Decorator that checks whether the request.user has all required auth providers
193 badcb2a9 Kostas Papadimitriou
    assigned.
194 badcb2a9 Kostas Papadimitriou
    """
195 badcb2a9 Kostas Papadimitriou
196 badcb2a9 Kostas Papadimitriou
    def decorator(func):
197 badcb2a9 Kostas Papadimitriou
        @wraps(func)
198 badcb2a9 Kostas Papadimitriou
        def wrapper(request, *args, **kwargs):
199 badcb2a9 Kostas Papadimitriou
            if request.user.is_authenticated():
200 9d20fe23 Kostas Papadimitriou
                missing = request.user.missing_required_providers()
201 9d20fe23 Kostas Papadimitriou
                if missing:
202 9d20fe23 Kostas Papadimitriou
                    for provider in missing:
203 9d20fe23 Kostas Papadimitriou
                        messages.error(request,
204 9d20fe23 Kostas Papadimitriou
                                       provider.get_required_msg)
205 9d20fe23 Kostas Papadimitriou
                    if not allow_access:
206 9d20fe23 Kostas Papadimitriou
                        return HttpResponseRedirect(reverse('edit_profile'))
207 badcb2a9 Kostas Papadimitriou
            return func(request, *args, **kwargs)
208 badcb2a9 Kostas Papadimitriou
        return wrapper
209 badcb2a9 Kostas Papadimitriou
    return decorator
210 badcb2a9 Kostas Papadimitriou
211 badcb2a9 Kostas Papadimitriou
212 badcb2a9 Kostas Papadimitriou
def valid_astakos_user_required(func):
213 badcb2a9 Kostas Papadimitriou
    return signed_terms_required(required_auth_methods_assigned()(login_required(func)))
214 badcb2a9 Kostas Papadimitriou
215 badcb2a9 Kostas Papadimitriou
216 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
217 270dd48d Sofia Papagiannaki
@signed_terms_required
218 1f3b4b39 Sofia Papagiannaki
def index(request, login_template_name='im/login.html', profile_template_name='im/profile.html', extra_context=None):
219 890b0eaf Sofia Papagiannaki
    """
220 dcf55476 Sofia Papagiannaki
    If there is logged on user renders the profile page otherwise renders login page.
221 176023aa Kostas Papadimitriou

222 890b0eaf Sofia Papagiannaki
    **Arguments**
223 176023aa Kostas Papadimitriou

224 dcf55476 Sofia Papagiannaki
    ``login_template_name``
225 dcf55476 Sofia Papagiannaki
        A custom login template to use. This is optional; if not specified,
226 1e685275 Sofia Papagiannaki
        this will default to ``im/login.html``.
227 176023aa Kostas Papadimitriou

228 dcf55476 Sofia Papagiannaki
    ``profile_template_name``
229 dcf55476 Sofia Papagiannaki
        A custom profile template to use. This is optional; if not specified,
230 1e685275 Sofia Papagiannaki
        this will default to ``im/profile.html``.
231 176023aa Kostas Papadimitriou

232 890b0eaf Sofia Papagiannaki
    ``extra_context``
233 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
234 176023aa Kostas Papadimitriou

235 890b0eaf Sofia Papagiannaki
    **Template:**
236 176023aa Kostas Papadimitriou

237 1e685275 Sofia Papagiannaki
    im/profile.html or im/login.html or ``template_name`` keyword argument.
238 176023aa Kostas Papadimitriou

239 890b0eaf Sofia Papagiannaki
    """
240 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
241 dcf55476 Sofia Papagiannaki
    template_name = login_template_name
242 dcf55476 Sofia Papagiannaki
    if request.user.is_authenticated():
243 f534fb96 Sofia Papagiannaki
        return HttpResponseRedirect(reverse('astakos.im.views.edit_profile'))
244 792c2f3b Olga Brani
245 f7cf5257 Kostas Papadimitriou
    third_party_token = request.GET.get('key', False)
246 f7cf5257 Kostas Papadimitriou
    if third_party_token:
247 f7cf5257 Kostas Papadimitriou
        messages.info(request, astakos_messages.AUTH_PROVIDER_LOGIN_TO_ADD)
248 f7cf5257 Kostas Papadimitriou
249 ef20ea07 Sofia Papagiannaki
    return render_response(
250 ef20ea07 Sofia Papagiannaki
        template_name,
251 ef20ea07 Sofia Papagiannaki
        login_form = LoginForm(request=request),
252 ef20ea07 Sofia Papagiannaki
        context_instance = get_context(request, extra_context)
253 ef20ea07 Sofia Papagiannaki
    )
254 5ce3ce4f Sofia Papagiannaki
255 64cd4730 Antony Chazapis
256 0504f010 Kostas Papadimitriou
@require_http_methods(["POST"])
257 0504f010 Kostas Papadimitriou
@valid_astakos_user_required
258 0504f010 Kostas Papadimitriou
def update_token(request):
259 0504f010 Kostas Papadimitriou
    """
260 0504f010 Kostas Papadimitriou
    Update api token view.
261 0504f010 Kostas Papadimitriou
    """
262 0504f010 Kostas Papadimitriou
    user = request.user
263 0504f010 Kostas Papadimitriou
    user.renew_token()
264 0504f010 Kostas Papadimitriou
    user.save()
265 0504f010 Kostas Papadimitriou
    messages.success(request, astakos_messages.TOKEN_UPDATED)
266 0504f010 Kostas Papadimitriou
    return HttpResponseRedirect(reverse('edit_profile'))
267 0504f010 Kostas Papadimitriou
268 0504f010 Kostas Papadimitriou
269 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
270 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
271 890b0eaf Sofia Papagiannaki
@transaction.commit_manually
272 aab4d540 Sofia Papagiannaki
def invite(request, template_name='im/invitations.html', extra_context=None):
273 890b0eaf Sofia Papagiannaki
    """
274 890b0eaf Sofia Papagiannaki
    Allows a user to invite somebody else.
275 176023aa Kostas Papadimitriou

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

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

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

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

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

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

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

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

298 890b0eaf Sofia Papagiannaki
    **Settings:**
299 176023aa Kostas Papadimitriou

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

302 890b0eaf Sofia Papagiannaki
    * LOGIN_URL: login uri
303 890b0eaf Sofia Papagiannaki
    """
304 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
305 64cd4730 Antony Chazapis
    status = None
306 64cd4730 Antony Chazapis
    message = None
307 8f5a3a06 Sofia Papagiannaki
    form = InvitationForm()
308 5ce3ce4f Sofia Papagiannaki
309 18ffbee1 Sofia Papagiannaki
    inviter = request.user
310 64cd4730 Antony Chazapis
    if request.method == 'POST':
311 8f5a3a06 Sofia Papagiannaki
        form = InvitationForm(request.POST)
312 64cd4730 Antony Chazapis
        if inviter.invitations > 0:
313 8f5a3a06 Sofia Papagiannaki
            if form.is_valid():
314 8f5a3a06 Sofia Papagiannaki
                try:
315 9a06d96f Olga Brani
                    email = form.cleaned_data.get('username')
316 9a06d96f Olga Brani
                    realname = form.cleaned_data.get('realname')
317 9cdb86fd Sofia Papagiannaki
                    invite_func(inviter, email, realname)
318 ae497612 Olga Brani
                    message = _(astakos_messages.INVITATION_SENT) % locals()
319 24406ae3 Sofia Papagiannaki
                    messages.success(request, message)
320 8f5a3a06 Sofia Papagiannaki
                except SendMailError, e:
321 8f5a3a06 Sofia Papagiannaki
                    message = e.message
322 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
323 8f5a3a06 Sofia Papagiannaki
                    transaction.rollback()
324 18ffbee1 Sofia Papagiannaki
                except BaseException, e:
325 ae497612 Olga Brani
                    message = _(astakos_messages.GENERIC_ERROR)
326 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
327 18ffbee1 Sofia Papagiannaki
                    logger.exception(e)
328 18ffbee1 Sofia Papagiannaki
                    transaction.rollback()
329 18ffbee1 Sofia Papagiannaki
                else:
330 18ffbee1 Sofia Papagiannaki
                    transaction.commit()
331 64cd4730 Antony Chazapis
        else:
332 ae497612 Olga Brani
            message = _(astakos_messages.MAX_INVITATION_NUMBER_REACHED)
333 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
334 176023aa Kostas Papadimitriou
335 a196eb7e Sofia Papagiannaki
    sent = [{'email': inv.username,
336 d6ae71a2 root
             'realname': inv.realname,
337 d6ae71a2 root
             'is_consumed': inv.is_consumed}
338 5ce3ce4f Sofia Papagiannaki
            for inv in request.user.invitations_sent.all()]
339 77e2ad52 root
    kwargs = {'inviter': inviter,
340 5ce3ce4f Sofia Papagiannaki
              'sent': sent}
341 0905ccd2 Sofia Papagiannaki
    context = get_context(request, extra_context, **kwargs)
342 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
343 5ce3ce4f Sofia Papagiannaki
                           invitation_form=form,
344 5ce3ce4f Sofia Papagiannaki
                           context_instance=context)
345 5ce3ce4f Sofia Papagiannaki
346 64cd4730 Antony Chazapis
347 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
348 9d20fe23 Kostas Papadimitriou
@required_auth_methods_assigned(allow_access=True)
349 890b0eaf Sofia Papagiannaki
@login_required
350 270dd48d Sofia Papagiannaki
@signed_terms_required
351 aab4d540 Sofia Papagiannaki
def edit_profile(request, template_name='im/profile.html', extra_context=None):
352 890b0eaf Sofia Papagiannaki
    """
353 890b0eaf Sofia Papagiannaki
    Allows a user to edit his/her profile.
354 176023aa Kostas Papadimitriou

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

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

361 890b0eaf Sofia Papagiannaki
    **Arguments**
362 176023aa Kostas Papadimitriou

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

367 890b0eaf Sofia Papagiannaki
    ``extra_context``
368 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
369 176023aa Kostas Papadimitriou

370 890b0eaf Sofia Papagiannaki
    **Template:**
371 176023aa Kostas Papadimitriou

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

374 92defad4 Sofia Papagiannaki
    **Settings:**
375 176023aa Kostas Papadimitriou

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

378 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
379 890b0eaf Sofia Papagiannaki
    """
380 aab4d540 Sofia Papagiannaki
    extra_context = extra_context or {}
381 bf0c6de5 Sofia Papagiannaki
    form = ProfileForm(
382 bf0c6de5 Sofia Papagiannaki
        instance=request.user,
383 bf0c6de5 Sofia Papagiannaki
        session_key=request.session.session_key
384 bf0c6de5 Sofia Papagiannaki
    )
385 15efc749 Sofia Papagiannaki
    extra_context['next'] = request.GET.get('next')
386 64cd4730 Antony Chazapis
    if request.method == 'POST':
387 bf0c6de5 Sofia Papagiannaki
        form = ProfileForm(
388 bf0c6de5 Sofia Papagiannaki
            request.POST,
389 bf0c6de5 Sofia Papagiannaki
            instance=request.user,
390 bf0c6de5 Sofia Papagiannaki
            session_key=request.session.session_key
391 bf0c6de5 Sofia Papagiannaki
        )
392 890b0eaf Sofia Papagiannaki
        if form.is_valid():
393 64cd4730 Antony Chazapis
            try:
394 c301698f Sofia Papagiannaki
                prev_token = request.user.auth_token
395 3fbf7863 Kostas Papadimitriou
                user = form.save(request=request)
396 217994f8 Sofia Papagiannaki
                next = restrict_next(
397 217994f8 Sofia Papagiannaki
                    request.POST.get('next'),
398 217994f8 Sofia Papagiannaki
                    domain=COOKIE_DOMAIN
399 217994f8 Sofia Papagiannaki
                )
400 ae497612 Olga Brani
                msg = _(astakos_messages.PROFILE_UPDATED)
401 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
402 2da6f56b Kostas Papadimitriou
403 2da6f56b Kostas Papadimitriou
                if form.email_changed:
404 2da6f56b Kostas Papadimitriou
                    msg = _(astakos_messages.EMAIL_CHANGE_REGISTERED)
405 2da6f56b Kostas Papadimitriou
                    messages.success(request, msg)
406 2da6f56b Kostas Papadimitriou
                if form.password_changed:
407 2da6f56b Kostas Papadimitriou
                    msg = _(astakos_messages.PASSWORD_CHANGED)
408 2da6f56b Kostas Papadimitriou
                    messages.success(request, msg)
409 2da6f56b Kostas Papadimitriou
410 f7400729 Kostas Papadimitriou
                if next:
411 f7400729 Kostas Papadimitriou
                    return redirect(next)
412 f7400729 Kostas Papadimitriou
                else:
413 f7400729 Kostas Papadimitriou
                    return redirect(reverse('edit_profile'))
414 890b0eaf Sofia Papagiannaki
            except ValueError, ve:
415 24406ae3 Sofia Papagiannaki
                messages.success(request, ve)
416 23447441 Sofia Papagiannaki
    elif request.method == "GET":
417 792c2f3b Olga Brani
        request.user.is_verified = True
418 792c2f3b Olga Brani
        request.user.save()
419 792c2f3b Olga Brani
420 792c2f3b Olga Brani
    # existing providers
421 9d20fe23 Kostas Papadimitriou
    user_providers = request.user.get_enabled_auth_providers()
422 9d20fe23 Kostas Papadimitriou
    user_disabled_providers = request.user.get_disabled_auth_providers()
423 792c2f3b Olga Brani
424 792c2f3b Olga Brani
    # providers that user can add
425 792c2f3b Olga Brani
    user_available_providers = request.user.get_available_auth_providers()
426 792c2f3b Olga Brani
427 1ebea3d3 Kostas Papadimitriou
    extra_context['services'] = get_services_dict()
428 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
429 8f5a3a06 Sofia Papagiannaki
                           profile_form = form,
430 792c2f3b Olga Brani
                           user_providers = user_providers,
431 9d20fe23 Kostas Papadimitriou
                           user_disabled_providers = user_disabled_providers,
432 792c2f3b Olga Brani
                           user_available_providers = user_available_providers,
433 0905ccd2 Sofia Papagiannaki
                           context_instance = get_context(request,
434 c301698f Sofia Papagiannaki
                                                          extra_context))
435 5ce3ce4f Sofia Papagiannaki
436 64cd4730 Antony Chazapis
437 10ed0073 Sofia Papagiannaki
@transaction.commit_manually
438 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
439 43332a76 Kostas Papadimitriou
def signup(request, template_name='im/signup.html', on_success='index', extra_context=None, backend=None):
440 890b0eaf Sofia Papagiannaki
    """
441 890b0eaf Sofia Papagiannaki
    Allows a user to create a local account.
442 176023aa Kostas Papadimitriou

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

446 890b0eaf Sofia Papagiannaki
    The user activation will be delegated to the backend specified by the ``backend`` keyword argument
447 8f5a3a06 Sofia Papagiannaki
    if present, otherwise to the ``astakos.im.activation_backends.InvitationBackend``
448 8f5a3a06 Sofia Papagiannaki
    if settings.ASTAKOS_INVITATIONS_ENABLED is True or ``astakos.im.activation_backends.SimpleBackend`` if not
449 8f5a3a06 Sofia Papagiannaki
    (see activation_backends);
450 5ce3ce4f Sofia Papagiannaki

451 b669d9c0 Sofia Papagiannaki
    Upon successful user creation, if ``next`` url parameter is present the user is redirected there
452 890b0eaf Sofia Papagiannaki
    otherwise renders the same page with a success message.
453 5ce3ce4f Sofia Papagiannaki

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

456 890b0eaf Sofia Papagiannaki
    **Arguments**
457 5ce3ce4f Sofia Papagiannaki

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

462 890b0eaf Sofia Papagiannaki
    ``extra_context``
463 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
464 176023aa Kostas Papadimitriou

465 43332a76 Kostas Papadimitriou
    ``on_success``
466 43332a76 Kostas Papadimitriou
        Resolvable view name to redirect on registration success.
467 43332a76 Kostas Papadimitriou

468 890b0eaf Sofia Papagiannaki
    **Template:**
469 5ce3ce4f Sofia Papagiannaki

470 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
471 890b0eaf Sofia Papagiannaki
    """
472 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
473 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
474 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('edit_profile'))
475 5ce3ce4f Sofia Papagiannaki
476 0a569195 Sofia Papagiannaki
    provider = get_query(request).get('provider', 'local')
477 9d20fe23 Kostas Papadimitriou
    if not auth.get_provider(provider).get_create_policy:
478 279d6e51 Olga Brani
        raise PermissionDenied
479 279d6e51 Olga Brani
480 6c8a3f7c Sofia Papagiannaki
    id = get_query(request).get('id')
481 6c8a3f7c Sofia Papagiannaki
    try:
482 6c8a3f7c Sofia Papagiannaki
        instance = AstakosUser.objects.get(id=id) if id else None
483 6c8a3f7c Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
484 6c8a3f7c Sofia Papagiannaki
        instance = None
485 6c8a3f7c Sofia Papagiannaki
486 8ab484ea Kostas Papadimitriou
    third_party_token = request.REQUEST.get('third_party_token', None)
487 9d20fe23 Kostas Papadimitriou
    unverified = None
488 c630fee6 Kostas Papadimitriou
    if third_party_token:
489 c630fee6 Kostas Papadimitriou
        pending = get_object_or_404(PendingThirdPartyUser,
490 c630fee6 Kostas Papadimitriou
                                    token=third_party_token)
491 9d20fe23 Kostas Papadimitriou
492 c630fee6 Kostas Papadimitriou
        provider = pending.provider
493 c630fee6 Kostas Papadimitriou
        instance = pending.get_user_instance()
494 9d20fe23 Kostas Papadimitriou
        get_unverified = AstakosUserAuthProvider.objects.unverified
495 9d20fe23 Kostas Papadimitriou
        unverified = get_unverified(pending.provider,
496 9d20fe23 Kostas Papadimitriou
                                    identifier=pending.third_party_identifier)
497 9d20fe23 Kostas Papadimitriou
498 9d20fe23 Kostas Papadimitriou
        if unverified and request.method == 'GET':
499 9d20fe23 Kostas Papadimitriou
            messages.warning(request, unverified.get_pending_registration_msg)
500 9d20fe23 Kostas Papadimitriou
            if unverified.user.activation_sent:
501 9d20fe23 Kostas Papadimitriou
                messages.warning(request,
502 9d20fe23 Kostas Papadimitriou
                                 unverified.get_pending_resend_activation_msg)
503 9d20fe23 Kostas Papadimitriou
            else:
504 9d20fe23 Kostas Papadimitriou
                messages.warning(request,
505 9d20fe23 Kostas Papadimitriou
                                 unverified.get_pending_moderation_msg)
506 8ab484ea Kostas Papadimitriou
507 890b0eaf Sofia Papagiannaki
    try:
508 18ffbee1 Sofia Papagiannaki
        if not backend:
509 18ffbee1 Sofia Papagiannaki
            backend = get_backend(request)
510 6c8a3f7c Sofia Papagiannaki
        form = backend.get_signup_form(provider, instance)
511 0a569195 Sofia Papagiannaki
    except Exception, e:
512 4e30244e Sofia Papagiannaki
        form = SimpleBackend(request).get_signup_form(provider)
513 24406ae3 Sofia Papagiannaki
        messages.error(request, e)
514 9d20fe23 Kostas Papadimitriou
515 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
516 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
517 18ffbee1 Sofia Papagiannaki
            user = form.save(commit=False)
518 43332a76 Kostas Papadimitriou
519 43332a76 Kostas Papadimitriou
            # delete previously unverified accounts
520 43332a76 Kostas Papadimitriou
            if AstakosUser.objects.user_exists(user.email):
521 43332a76 Kostas Papadimitriou
                AstakosUser.objects.get_by_identifier(user.email).delete()
522 43332a76 Kostas Papadimitriou
523 8f5a3a06 Sofia Papagiannaki
            try:
524 9d20fe23 Kostas Papadimitriou
                form.store_user(user, request)
525 9d20fe23 Kostas Papadimitriou
526 8f5a3a06 Sofia Papagiannaki
                result = backend.handle_activation(user)
527 8f5a3a06 Sofia Papagiannaki
                status = messages.SUCCESS
528 18ffbee1 Sofia Papagiannaki
                message = result.message
529 792c2f3b Olga Brani
530 ca828a10 Sofia Papagiannaki
                if 'additional_email' in form.cleaned_data:
531 ca828a10 Sofia Papagiannaki
                    additional_email = form.cleaned_data['additional_email']
532 ca828a10 Sofia Papagiannaki
                    if additional_email != user.email:
533 ca828a10 Sofia Papagiannaki
                        user.additionalmail_set.create(email=additional_email)
534 5ce3ce4f Sofia Papagiannaki
                        msg = 'Additional email: %s saved for user %s.' % (
535 6c8a3f7c Sofia Papagiannaki
                            additional_email,
536 6c8a3f7c Sofia Papagiannaki
                            user.email
537 6c8a3f7c Sofia Papagiannaki
                        )
538 b669d9c0 Sofia Papagiannaki
                        logger._log(LOGGING_LEVEL, msg, [])
539 43332a76 Kostas Papadimitriou
540 8f5a3a06 Sofia Papagiannaki
                if user and user.is_active:
541 8f5a3a06 Sofia Papagiannaki
                    next = request.POST.get('next', '')
542 40a0cd8b Sofia Papagiannaki
                    response = prepare_response(request, user, next=next)
543 c3f6cdf1 root
                    transaction.commit()
544 40a0cd8b Sofia Papagiannaki
                    return response
545 43332a76 Kostas Papadimitriou
546 792c2f3b Olga Brani
                transaction.commit()
547 43332a76 Kostas Papadimitriou
                messages.add_message(request, status, message)
548 43332a76 Kostas Papadimitriou
                return HttpResponseRedirect(reverse(on_success))
549 43332a76 Kostas Papadimitriou
550 18ffbee1 Sofia Papagiannaki
            except SendMailError, e:
551 18ffbee1 Sofia Papagiannaki
                status = messages.ERROR
552 18ffbee1 Sofia Papagiannaki
                message = e.message
553 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
554 10ed0073 Sofia Papagiannaki
                transaction.rollback()
555 18ffbee1 Sofia Papagiannaki
            except BaseException, e:
556 678b2236 Sofia Papagiannaki
                logger.exception(e)
557 ae497612 Olga Brani
                message = _(astakos_messages.GENERIC_ERROR)
558 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
559 0a569195 Sofia Papagiannaki
                logger.exception(e)
560 10ed0073 Sofia Papagiannaki
                transaction.rollback()
561 43332a76 Kostas Papadimitriou
562 8f5a3a06 Sofia Papagiannaki
    return render_response(template_name,
563 5ce3ce4f Sofia Papagiannaki
                           signup_form=form,
564 8ab484ea Kostas Papadimitriou
                           third_party_token=third_party_token,
565 5ce3ce4f Sofia Papagiannaki
                           provider=provider,
566 890b0eaf Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
567 64cd4730 Antony Chazapis
568 5ce3ce4f Sofia Papagiannaki
569 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
570 9d20fe23 Kostas Papadimitriou
@required_auth_methods_assigned(allow_access=True)
571 890b0eaf Sofia Papagiannaki
@login_required
572 270dd48d Sofia Papagiannaki
@signed_terms_required
573 aab4d540 Sofia Papagiannaki
def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context=None):
574 890b0eaf Sofia Papagiannaki
    """
575 890b0eaf Sofia Papagiannaki
    Allows a user to send feedback.
576 176023aa Kostas Papadimitriou

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

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

582 890b0eaf Sofia Papagiannaki
    **Arguments**
583 176023aa Kostas Papadimitriou

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

588 890b0eaf Sofia Papagiannaki
    ``extra_context``
589 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
590 176023aa Kostas Papadimitriou

591 890b0eaf Sofia Papagiannaki
    **Template:**
592 176023aa Kostas Papadimitriou

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

595 890b0eaf Sofia Papagiannaki
    **Settings:**
596 176023aa Kostas Papadimitriou

597 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
598 890b0eaf Sofia Papagiannaki
    """
599 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
600 64cd4730 Antony Chazapis
    if request.method == 'GET':
601 890b0eaf Sofia Papagiannaki
        form = FeedbackForm()
602 890b0eaf Sofia Papagiannaki
    if request.method == 'POST':
603 890b0eaf Sofia Papagiannaki
        if not request.user:
604 890b0eaf Sofia Papagiannaki
            return HttpResponse('Unauthorized', status=401)
605 176023aa Kostas Papadimitriou
606 890b0eaf Sofia Papagiannaki
        form = FeedbackForm(request.POST)
607 890b0eaf Sofia Papagiannaki
        if form.is_valid():
608 e9083112 Sofia Papagiannaki
            msg = form.cleaned_data['feedback_msg']
609 8f5a3a06 Sofia Papagiannaki
            data = form.cleaned_data['feedback_data']
610 538ccdd5 Sofia Papagiannaki
            try:
611 8f5a3a06 Sofia Papagiannaki
                send_feedback(msg, data, request.user, email_template_name)
612 8f5a3a06 Sofia Papagiannaki
            except SendMailError, e:
613 8d15889c Sofia Papagiannaki
                message = e.message
614 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
615 8f5a3a06 Sofia Papagiannaki
            else:
616 ae497612 Olga Brani
                message = _(astakos_messages.FEEDBACK_SENT)
617 aab4d540 Sofia Papagiannaki
                messages.success(request, message)
618 b9f8f48a Kostas Papadimitriou
            return HttpResponseRedirect(reverse('feedback'))
619 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
620 5ce3ce4f Sofia Papagiannaki
                           feedback_form=form,
621 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
622 5ce3ce4f Sofia Papagiannaki
623 15efc749 Sofia Papagiannaki
624 217994f8 Sofia Papagiannaki
@require_http_methods(["GET"])
625 8e45d6fd Sofia Papagiannaki
@signed_terms_required
626 aab4d540 Sofia Papagiannaki
def logout(request, template='registration/logged_out.html', extra_context=None):
627 63ecdd20 Sofia Papagiannaki
    """
628 b2ffa772 Sofia Papagiannaki
    Wraps `django.contrib.auth.logout`.
629 63ecdd20 Sofia Papagiannaki
    """
630 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
631 7482228b Sofia Papagiannaki
    response = HttpResponse()
632 8e45d6fd Sofia Papagiannaki
    if request.user.is_authenticated():
633 8e45d6fd Sofia Papagiannaki
        email = request.user.email
634 8e45d6fd Sofia Papagiannaki
        auth_logout(request)
635 c630fee6 Kostas Papadimitriou
    else:
636 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
637 c630fee6 Kostas Papadimitriou
        response.status_code = 301
638 c630fee6 Kostas Papadimitriou
        return response
639 c630fee6 Kostas Papadimitriou
640 217994f8 Sofia Papagiannaki
    next = restrict_next(
641 217994f8 Sofia Papagiannaki
        request.GET.get('next'),
642 217994f8 Sofia Papagiannaki
        domain=COOKIE_DOMAIN
643 217994f8 Sofia Papagiannaki
    )
644 c630fee6 Kostas Papadimitriou
645 63ecdd20 Sofia Papagiannaki
    if next:
646 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
647 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
648 0d02a287 Sofia Papagiannaki
    elif LOGOUT_NEXT:
649 0d02a287 Sofia Papagiannaki
        response['Location'] = LOGOUT_NEXT
650 0d02a287 Sofia Papagiannaki
        response.status_code = 301
651 b2ffa772 Sofia Papagiannaki
    else:
652 9d20fe23 Kostas Papadimitriou
        last_provider = request.COOKIES.get('astakos_last_login_method', 'local')
653 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(last_provider)
654 9d20fe23 Kostas Papadimitriou
        message = provider.get_logout_success_msg
655 9d20fe23 Kostas Papadimitriou
        extra = provider.get_logout_success_extra_msg
656 9d20fe23 Kostas Papadimitriou
        if extra:
657 9d20fe23 Kostas Papadimitriou
            message += "<br />"  + extra
658 d21d422a Kostas Papadimitriou
        messages.success(request, message)
659 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
660 c630fee6 Kostas Papadimitriou
        response.status_code = 301
661 49df775e Sofia Papagiannaki
    return response
662 2126d85d Sofia Papagiannaki
663 5ce3ce4f Sofia Papagiannaki
664 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
665 683cf244 Sofia Papagiannaki
@transaction.commit_manually
666 3bb604eb Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt',
667 3bb604eb Sofia Papagiannaki
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
668 2126d85d Sofia Papagiannaki
    """
669 683cf244 Sofia Papagiannaki
    Activates the user identified by the ``auth`` request parameter, sends a welcome email
670 683cf244 Sofia Papagiannaki
    and renews the user token.
671 176023aa Kostas Papadimitriou

672 683cf244 Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the user state will be updated
673 683cf244 Sofia Papagiannaki
    only if the email will be send successfully.
674 2126d85d Sofia Papagiannaki
    """
675 2126d85d Sofia Papagiannaki
    token = request.GET.get('auth')
676 2126d85d Sofia Papagiannaki
    next = request.GET.get('next')
677 2126d85d Sofia Papagiannaki
    try:
678 2126d85d Sofia Papagiannaki
        user = AstakosUser.objects.get(auth_token=token)
679 2126d85d Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
680 279d6e51 Olga Brani
        return HttpResponseBadRequest(_(astakos_messages.ACCOUNT_UNKNOWN))
681 5ce3ce4f Sofia Papagiannaki
682 92a8abc9 Kostas Papadimitriou
    if user.is_active or user.email_verified:
683 ae497612 Olga Brani
        message = _(astakos_messages.ACCOUNT_ALREADY_ACTIVE)
684 24406ae3 Sofia Papagiannaki
        messages.error(request, message)
685 92a8abc9 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('index'))
686 5ce3ce4f Sofia Papagiannaki
687 89d959c9 Kostas Papadimitriou
    if not user.activation_sent:
688 89d959c9 Kostas Papadimitriou
        provider = user.get_auth_provider()
689 89d959c9 Kostas Papadimitriou
        message = user.get_inactive_message(provider.module)
690 89d959c9 Kostas Papadimitriou
        messages.error(request, message)
691 89d959c9 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('index'))
692 89d959c9 Kostas Papadimitriou
693 0a569195 Sofia Papagiannaki
    try:
694 3f8570dc Kostas Papadimitriou
        activate_func(user, greeting_email_template_name,
695 3f8570dc Kostas Papadimitriou
                      helpdesk_email_template_name, verify_email=True)
696 73dcef48 Kostas Papadimitriou
        messages.success(request, _(astakos_messages.ACCOUNT_ACTIVATED))
697 3f8570dc Kostas Papadimitriou
        next = ACTIVATION_REDIRECT_URL or next
698 ef20ea07 Sofia Papagiannaki
        response = prepare_response(request, user, next, renew=True)
699 ef20ea07 Sofia Papagiannaki
        transaction.commit()
700 279d6e51 Olga Brani
        return response
701 ef20ea07 Sofia Papagiannaki
    except SendMailError, e:
702 ef20ea07 Sofia Papagiannaki
        message = e.message
703 ef20ea07 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, message)
704 ef20ea07 Sofia Papagiannaki
        transaction.rollback()
705 279d6e51 Olga Brani
        return index(request)
706 ef20ea07 Sofia Papagiannaki
    except BaseException, e:
707 ef20ea07 Sofia Papagiannaki
        status = messages.ERROR
708 c0b26605 Sofia Papagiannaki
        message = _(astakos_messages.GENERIC_ERROR)
709 ef20ea07 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, message)
710 ef20ea07 Sofia Papagiannaki
        logger.exception(e)
711 ef20ea07 Sofia Papagiannaki
        transaction.rollback()
712 279d6e51 Olga Brani
        return index(request)
713 270dd48d Sofia Papagiannaki
714 5ce3ce4f Sofia Papagiannaki
715 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
716 aab4d540 Sofia Papagiannaki
def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context=None):
717 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
718 270dd48d Sofia Papagiannaki
    term = None
719 270dd48d Sofia Papagiannaki
    terms = None
720 270dd48d Sofia Papagiannaki
    if not term_id:
721 270dd48d Sofia Papagiannaki
        try:
722 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
723 270dd48d Sofia Papagiannaki
        except IndexError:
724 270dd48d Sofia Papagiannaki
            pass
725 270dd48d Sofia Papagiannaki
    else:
726 270dd48d Sofia Papagiannaki
        try:
727 aab4d540 Sofia Papagiannaki
            term = ApprovalTerms.objects.get(id=term_id)
728 aab4d540 Sofia Papagiannaki
        except ApprovalTerms.DoesNotExist, e:
729 270dd48d Sofia Papagiannaki
            pass
730 176023aa Kostas Papadimitriou
731 270dd48d Sofia Papagiannaki
    if not term:
732 ae497612 Olga Brani
        messages.error(request, _(astakos_messages.NO_APPROVAL_TERMS))
733 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('index'))
734 64b5136c Sofia Papagiannaki
    try:
735 64b5136c Sofia Papagiannaki
        f = open(term.location, 'r')
736 64b5136c Sofia Papagiannaki
    except IOError:
737 64b5136c Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
738 64b5136c Sofia Papagiannaki
        return render_response(
739 64b5136c Sofia Papagiannaki
            template_name, context_instance=get_context(request, extra_context))
740 64b5136c Sofia Papagiannaki
741 270dd48d Sofia Papagiannaki
    terms = f.read()
742 176023aa Kostas Papadimitriou
743 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
744 217994f8 Sofia Papagiannaki
        next = restrict_next(
745 217994f8 Sofia Papagiannaki
            request.POST.get('next'),
746 217994f8 Sofia Papagiannaki
            domain=COOKIE_DOMAIN
747 217994f8 Sofia Papagiannaki
        )
748 270dd48d Sofia Papagiannaki
        if not next:
749 6ff7a7ca Sofia Papagiannaki
            next = reverse('index')
750 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
751 270dd48d Sofia Papagiannaki
        if not form.is_valid():
752 270dd48d Sofia Papagiannaki
            return render_response(template_name,
753 5ce3ce4f Sofia Papagiannaki
                                   terms=terms,
754 5ce3ce4f Sofia Papagiannaki
                                   approval_terms_form=form,
755 5ce3ce4f Sofia Papagiannaki
                                   context_instance=get_context(request, extra_context))
756 270dd48d Sofia Papagiannaki
        user = form.save()
757 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
758 270dd48d Sofia Papagiannaki
    else:
759 586967c0 Sofia Papagiannaki
        form = None
760 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
761 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
762 270dd48d Sofia Papagiannaki
        return render_response(template_name,
763 5ce3ce4f Sofia Papagiannaki
                               terms=terms,
764 5ce3ce4f Sofia Papagiannaki
                               approval_terms_form=form,
765 5ce3ce4f Sofia Papagiannaki
                               context_instance=get_context(request, extra_context))
766 5ce3ce4f Sofia Papagiannaki
767 270dd48d Sofia Papagiannaki
768 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
769 49790d9d Sofia Papagiannaki
@transaction.commit_manually
770 49790d9d Sofia Papagiannaki
def change_email(request, activation_key=None,
771 49790d9d Sofia Papagiannaki
                 email_template_name='registration/email_change_email.txt',
772 49790d9d Sofia Papagiannaki
                 form_template_name='registration/email_change_form.html',
773 49790d9d Sofia Papagiannaki
                 confirm_template_name='registration/email_change_done.html',
774 aab4d540 Sofia Papagiannaki
                 extra_context=None):
775 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
776 53e0b8fe Kostas Papadimitriou
777 53e0b8fe Kostas Papadimitriou
778 17ad5d37 Kostas Papadimitriou
    if not astakos_settings.EMAILCHANGE_ENABLED:
779 17ad5d37 Kostas Papadimitriou
        raise PermissionDenied
780 17ad5d37 Kostas Papadimitriou
781 49790d9d Sofia Papagiannaki
    if activation_key:
782 49790d9d Sofia Papagiannaki
        try:
783 49790d9d Sofia Papagiannaki
            user = EmailChange.objects.change_email(activation_key)
784 10a870d5 Kostas Papadimitriou
            if request.user.is_authenticated() and request.user == user or not \
785 10a870d5 Kostas Papadimitriou
                    request.user.is_authenticated():
786 ae497612 Olga Brani
                msg = _(astakos_messages.EMAIL_CHANGED)
787 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
788 49790d9d Sofia Papagiannaki
                transaction.commit()
789 53e0b8fe Kostas Papadimitriou
                return HttpResponseRedirect(reverse('edit_profile'))
790 49790d9d Sofia Papagiannaki
        except ValueError, e:
791 24406ae3 Sofia Papagiannaki
            messages.error(request, e)
792 53e0b8fe Kostas Papadimitriou
            transaction.rollback()
793 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('index'))
794 53e0b8fe Kostas Papadimitriou
795 49790d9d Sofia Papagiannaki
        return render_response(confirm_template_name,
796 53e0b8fe Kostas Papadimitriou
                               modified_user=user if 'user' in locals() \
797 53e0b8fe Kostas Papadimitriou
                               else None, context_instance=get_context(request,
798 5ce3ce4f Sofia Papagiannaki
                                                            extra_context))
799 5ce3ce4f Sofia Papagiannaki
800 49790d9d Sofia Papagiannaki
    if not request.user.is_authenticated():
801 49790d9d Sofia Papagiannaki
        path = quote(request.get_full_path())
802 6ff7a7ca Sofia Papagiannaki
        url = request.build_absolute_uri(reverse('index'))
803 49790d9d Sofia Papagiannaki
        return HttpResponseRedirect(url + '?next=' + path)
804 53e0b8fe Kostas Papadimitriou
805 53e0b8fe Kostas Papadimitriou
    # clean up expired email changes
806 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
807 53e0b8fe Kostas Papadimitriou
        change = request.user.emailchanges.get()
808 53e0b8fe Kostas Papadimitriou
        if change.activation_key_expired():
809 53e0b8fe Kostas Papadimitriou
            change.delete()
810 53e0b8fe Kostas Papadimitriou
            transaction.commit()
811 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('email_change'))
812 53e0b8fe Kostas Papadimitriou
813 49790d9d Sofia Papagiannaki
    form = EmailChangeForm(request.POST or None)
814 49790d9d Sofia Papagiannaki
    if request.method == 'POST' and form.is_valid():
815 49790d9d Sofia Papagiannaki
        try:
816 9d20fe23 Kostas Papadimitriou
            ec = form.save(request, email_template_name, request)
817 49790d9d Sofia Papagiannaki
        except SendMailError, e:
818 49790d9d Sofia Papagiannaki
            msg = e
819 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
820 49790d9d Sofia Papagiannaki
            transaction.rollback()
821 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
822 49790d9d Sofia Papagiannaki
        else:
823 ae497612 Olga Brani
            msg = _(astakos_messages.EMAIL_CHANGE_REGISTERED)
824 24406ae3 Sofia Papagiannaki
            messages.success(request, msg)
825 49790d9d Sofia Papagiannaki
            transaction.commit()
826 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
827 53e0b8fe Kostas Papadimitriou
828 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
829 53e0b8fe Kostas Papadimitriou
        messages.warning(request, astakos_messages.PENDING_EMAIL_CHANGE_REQUEST)
830 53e0b8fe Kostas Papadimitriou
831 c0b26605 Sofia Papagiannaki
    return render_response(
832 c0b26605 Sofia Papagiannaki
        form_template_name,
833 c0b26605 Sofia Papagiannaki
        form=form,
834 c0b26605 Sofia Papagiannaki
        context_instance=get_context(request, extra_context)
835 c0b26605 Sofia Papagiannaki
    )
836 1f3b4b39 Sofia Papagiannaki
837 1f3b4b39 Sofia Papagiannaki
838 1f3b4b39 Sofia Papagiannaki
def send_activation(request, user_id, template_name='im/login.html', extra_context=None):
839 792c2f3b Olga Brani
840 badcb2a9 Kostas Papadimitriou
    if request.user.is_authenticated():
841 badcb2a9 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
842 badcb2a9 Kostas Papadimitriou
843 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
844 1f3b4b39 Sofia Papagiannaki
    try:
845 1f3b4b39 Sofia Papagiannaki
        u = AstakosUser.objects.get(id=user_id)
846 1f3b4b39 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
847 c0b26605 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.ACCOUNT_UNKNOWN))
848 1f3b4b39 Sofia Papagiannaki
    else:
849 9d20fe23 Kostas Papadimitriou
        if not u.activation_sent and astakos_settings.MODERATION_ENABLED:
850 9d20fe23 Kostas Papadimitriou
            raise PermissionDenied
851 1f3b4b39 Sofia Papagiannaki
        try:
852 1f3b4b39 Sofia Papagiannaki
            send_activation_func(u)
853 c0b26605 Sofia Papagiannaki
            msg = _(astakos_messages.ACTIVATION_SENT)
854 1f3b4b39 Sofia Papagiannaki
            messages.success(request, msg)
855 1f3b4b39 Sofia Papagiannaki
        except SendMailError, e:
856 1f3b4b39 Sofia Papagiannaki
            messages.error(request, e)
857 ff81d0d9 Kostas Papadimitriou
858 ff81d0d9 Kostas Papadimitriou
    return HttpResponseRedirect(reverse('index'))
859 5ce3ce4f Sofia Papagiannaki
860 73fbaec4 Sofia Papagiannaki
861 73fbaec4 Sofia Papagiannaki
@require_http_methods(["GET"])
862 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
863 666c7490 Sofia Papagiannaki
def resource_usage(request):
864 e9ef5009 Kostas Papadimitriou
865 e9ef5009 Kostas Papadimitriou
    def with_class(entry):
866 e9ef5009 Kostas Papadimitriou
         entry['load_class'] = 'red'
867 e9ef5009 Kostas Papadimitriou
         max_value = float(entry['maxValue'])
868 e9ef5009 Kostas Papadimitriou
         curr_value = float(entry['currValue'])
869 e9ef5009 Kostas Papadimitriou
         entry['ratio_limited']= 0
870 e9ef5009 Kostas Papadimitriou
         if max_value > 0 :
871 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = (curr_value / max_value) * 100
872 e9ef5009 Kostas Papadimitriou
         else:
873 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = 0
874 e9ef5009 Kostas Papadimitriou
         if entry['ratio'] < 66:
875 e9ef5009 Kostas Papadimitriou
             entry['load_class'] = 'yellow'
876 e9ef5009 Kostas Papadimitriou
         if entry['ratio'] < 33:
877 e9ef5009 Kostas Papadimitriou
             entry['load_class'] = 'green'
878 e9ef5009 Kostas Papadimitriou
         if entry['ratio']<0:
879 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = 0
880 e9ef5009 Kostas Papadimitriou
         if entry['ratio']>100:
881 e9ef5009 Kostas Papadimitriou
             entry['ratio_limited'] = 100
882 e9ef5009 Kostas Papadimitriou
         else:
883 e9ef5009 Kostas Papadimitriou
             entry['ratio_limited'] = entry['ratio']
884 e9ef5009 Kostas Papadimitriou
         return entry
885 e9ef5009 Kostas Papadimitriou
886 e9ef5009 Kostas Papadimitriou
    def pluralize(entry):
887 e9ef5009 Kostas Papadimitriou
        entry['plural'] = engine.plural(entry.get('name'))
888 e9ef5009 Kostas Papadimitriou
        return entry
889 e9ef5009 Kostas Papadimitriou
890 a9c7ff8a Sofia Papagiannaki
    resource_usage = None
891 666c7490 Sofia Papagiannaki
    result = callpoint.get_user_usage(request.user.id)
892 820b18e0 Sofia Papagiannaki
    if result.is_success:
893 a9c7ff8a Sofia Papagiannaki
        resource_usage = result.data
894 e9ef5009 Kostas Papadimitriou
        backenddata = map(with_class, result.data)
895 e2497bc5 Sofia Papagiannaki
        backenddata = map(pluralize , backenddata)
896 9a06d96f Olga Brani
    else:
897 820b18e0 Sofia Papagiannaki
        messages.error(request, result.reason)
898 37f8b1a6 Olga Brani
        backenddata = []
899 401089d8 Kostas Papadimitriou
        resource_usage = []
900 401089d8 Kostas Papadimitriou
901 401089d8 Kostas Papadimitriou
    if request.REQUEST.get('json', None):
902 401089d8 Kostas Papadimitriou
        return HttpResponse(json.dumps(backenddata),
903 401089d8 Kostas Papadimitriou
                            mimetype="application/json")
904 401089d8 Kostas Papadimitriou
905 666c7490 Sofia Papagiannaki
    return render_response('im/resource_usage.html',
906 3cbd5e47 Olga Brani
                           context_instance=get_context(request),
907 e9ef5009 Kostas Papadimitriou
                           resource_usage=backenddata,
908 401089d8 Kostas Papadimitriou
                           usage_update_interval=astakos_settings.USAGE_UPDATE_INTERVAL,
909 3cbd5e47 Olga Brani
                           result=result)
910 9a06d96f Olga Brani
911 f432088a Kostas Papadimitriou
# TODO: action only on POST and user should confirm the removal
912 d2633501 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
913 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
914 d2633501 Kostas Papadimitriou
def remove_auth_provider(request, pk):
915 f432088a Kostas Papadimitriou
    try:
916 9d20fe23 Kostas Papadimitriou
        provider = request.user.auth_providers.get(pk=int(pk)).settings
917 f432088a Kostas Papadimitriou
    except AstakosUserAuthProvider.DoesNotExist:
918 f432088a Kostas Papadimitriou
        raise Http404
919 f432088a Kostas Papadimitriou
920 9d20fe23 Kostas Papadimitriou
    if provider.get_remove_policy:
921 9d20fe23 Kostas Papadimitriou
        messages.success(request, provider.get_removed_msg)
922 9d20fe23 Kostas Papadimitriou
        provider.remove_from_user()
923 d2633501 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
924 d2633501 Kostas Papadimitriou
    else:
925 f432088a Kostas Papadimitriou
        raise PermissionDenied
926 5ebebb20 Olga Brani
927 792c2f3b Olga Brani
928 5ebebb20 Olga Brani
def how_it_works(request):
929 5ebebb20 Olga Brani
    return render_response(
930 ccab6eb5 Sofia Papagiannaki
        'im/how_it_works.html',
931 ccab6eb5 Sofia Papagiannaki
        context_instance=get_context(request))
932 e1a80257 Sofia Papagiannaki
933 39b2cb50 Giorgos Korfiatis
934 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
935 172ce682 Sofia Papagiannaki
def _create_object(request, model=None, template_name=None,
936 172ce682 Sofia Papagiannaki
        template_loader=template_loader, extra_context=None, post_save_redirect=None,
937 6556e514 Sofia Papagiannaki
        login_required=False, context_processors=None, form_class=None,
938 39b2cb50 Giorgos Korfiatis
        msg=None):
939 172ce682 Sofia Papagiannaki
    """
940 4e748491 Sofia Papagiannaki
    Based of django.views.generic.create_update.create_object which displays a
941 172ce682 Sofia Papagiannaki
    summary page before creating the object.
942 172ce682 Sofia Papagiannaki
    """
943 172ce682 Sofia Papagiannaki
    response = None
944 4e748491 Sofia Papagiannaki
945 4e748491 Sofia Papagiannaki
    if extra_context is None: extra_context = {}
946 4e748491 Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
947 4e748491 Sofia Papagiannaki
        return redirect_to_login(request.path)
948 ccab6eb5 Sofia Papagiannaki
    try:
949 f7cf5257 Kostas Papadimitriou
950 172ce682 Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
951 172ce682 Sofia Papagiannaki
        extra_context['edit'] = 0
952 172ce682 Sofia Papagiannaki
        if request.method == 'POST':
953 172ce682 Sofia Papagiannaki
            form = form_class(request.POST, request.FILES)
954 172ce682 Sofia Papagiannaki
            if form.is_valid():
955 172ce682 Sofia Papagiannaki
                verify = request.GET.get('verify')
956 172ce682 Sofia Papagiannaki
                edit = request.GET.get('edit')
957 172ce682 Sofia Papagiannaki
                if verify == '1':
958 172ce682 Sofia Papagiannaki
                    extra_context['show_form'] = False
959 172ce682 Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
960 172ce682 Sofia Papagiannaki
                elif edit == '1':
961 172ce682 Sofia Papagiannaki
                    extra_context['show_form'] = True
962 172ce682 Sofia Papagiannaki
                else:
963 172ce682 Sofia Papagiannaki
                    new_object = form.save()
964 6556e514 Sofia Papagiannaki
                    if not msg:
965 6556e514 Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
966 6556e514 Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
967 172ce682 Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
968 172ce682 Sofia Papagiannaki
                    response = redirect(post_save_redirect, new_object)
969 172ce682 Sofia Papagiannaki
        else:
970 172ce682 Sofia Papagiannaki
            form = form_class()
971 39b2cb50 Giorgos Korfiatis
    except (IOError, PermissionDenied), e:
972 39b2cb50 Giorgos Korfiatis
        messages.error(request, e)
973 39b2cb50 Giorgos Korfiatis
        return None
974 39b2cb50 Giorgos Korfiatis
    else:
975 172ce682 Sofia Papagiannaki
        if response == None:
976 172ce682 Sofia Papagiannaki
            # Create the template, context, response
977 172ce682 Sofia Papagiannaki
            if not template_name:
978 172ce682 Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
979 172ce682 Sofia Papagiannaki
                     (model._meta.app_label, model._meta.object_name.lower())
980 172ce682 Sofia Papagiannaki
            t = template_loader.get_template(template_name)
981 172ce682 Sofia Papagiannaki
            c = RequestContext(request, {
982 172ce682 Sofia Papagiannaki
                'form': form
983 172ce682 Sofia Papagiannaki
            }, context_processors)
984 172ce682 Sofia Papagiannaki
            apply_extra_context(extra_context, c)
985 172ce682 Sofia Papagiannaki
            response = HttpResponse(t.render(c))
986 172ce682 Sofia Papagiannaki
        return response
987 172ce682 Sofia Papagiannaki
988 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
989 4e748491 Sofia Papagiannaki
def _update_object(request, model=None, object_id=None, slug=None,
990 4e748491 Sofia Papagiannaki
        slug_field='slug', template_name=None, template_loader=template_loader,
991 4e748491 Sofia Papagiannaki
        extra_context=None, post_save_redirect=None, login_required=False,
992 4e748491 Sofia Papagiannaki
        context_processors=None, template_object_name='object',
993 39b2cb50 Giorgos Korfiatis
        form_class=None, msg=None):
994 4e748491 Sofia Papagiannaki
    """
995 4e748491 Sofia Papagiannaki
    Based of django.views.generic.create_update.update_object which displays a
996 4e748491 Sofia Papagiannaki
    summary page before updating the object.
997 4e748491 Sofia Papagiannaki
    """
998 4e748491 Sofia Papagiannaki
    response = None
999 4e748491 Sofia Papagiannaki
1000 4e748491 Sofia Papagiannaki
    if extra_context is None: extra_context = {}
1001 4e748491 Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
1002 4e748491 Sofia Papagiannaki
        return redirect_to_login(request.path)
1003 f7cf5257 Kostas Papadimitriou
1004 4e748491 Sofia Papagiannaki
    try:
1005 4e748491 Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
1006 4e748491 Sofia Papagiannaki
        obj = lookup_object(model, object_id, slug, slug_field)
1007 f7cf5257 Kostas Papadimitriou
1008 4e748491 Sofia Papagiannaki
        if request.method == 'POST':
1009 4e748491 Sofia Papagiannaki
            form = form_class(request.POST, request.FILES, instance=obj)
1010 4e748491 Sofia Papagiannaki
            if form.is_valid():
1011 4e748491 Sofia Papagiannaki
                verify = request.GET.get('verify')
1012 4e748491 Sofia Papagiannaki
                edit = request.GET.get('edit')
1013 4e748491 Sofia Papagiannaki
                if verify == '1':
1014 4e748491 Sofia Papagiannaki
                    extra_context['show_form'] = False
1015 4e748491 Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
1016 4e748491 Sofia Papagiannaki
                elif edit == '1':
1017 4e748491 Sofia Papagiannaki
                    extra_context['show_form'] = True
1018 f7cf5257 Kostas Papadimitriou
                else:
1019 4e748491 Sofia Papagiannaki
                    obj = form.save()
1020 6556e514 Sofia Papagiannaki
                    if not msg:
1021 6556e514 Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
1022 6556e514 Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
1023 6556e514 Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
1024 4e748491 Sofia Papagiannaki
                    response = redirect(post_save_redirect, obj)
1025 4e748491 Sofia Papagiannaki
        else:
1026 4e748491 Sofia Papagiannaki
            form = form_class(instance=obj)
1027 39b2cb50 Giorgos Korfiatis
    except (IOError, PermissionDenied), e:
1028 39b2cb50 Giorgos Korfiatis
        messages.error(request, e)
1029 39b2cb50 Giorgos Korfiatis
        return None
1030 39b2cb50 Giorgos Korfiatis
    else:
1031 4e748491 Sofia Papagiannaki
        if response == None:
1032 4e748491 Sofia Papagiannaki
            if not template_name:
1033 4e748491 Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
1034 4e748491 Sofia Papagiannaki
                    (model._meta.app_label, model._meta.object_name.lower())
1035 4e748491 Sofia Papagiannaki
            t = template_loader.get_template(template_name)
1036 4e748491 Sofia Papagiannaki
            c = RequestContext(request, {
1037 4e748491 Sofia Papagiannaki
                'form': form,
1038 4e748491 Sofia Papagiannaki
                template_object_name: obj,
1039 4e748491 Sofia Papagiannaki
            }, context_processors)
1040 4e748491 Sofia Papagiannaki
            apply_extra_context(extra_context, c)
1041 4e748491 Sofia Papagiannaki
            response = HttpResponse(t.render(c))
1042 4e748491 Sofia Papagiannaki
            populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname))
1043 4e748491 Sofia Papagiannaki
        return response
1044 4e748491 Sofia Papagiannaki
1045 75380308 Kostas Papadimitriou
1046 75380308 Kostas Papadimitriou
def _resources_catalog(request):
1047 75380308 Kostas Papadimitriou
    """
1048 75380308 Kostas Papadimitriou
    `resource_catalog` contains a list of tuples. Each tuple contains the group
1049 75380308 Kostas Papadimitriou
    key the resource is assigned to and resources list of dicts that contain
1050 75380308 Kostas Papadimitriou
    resource information.
1051 75380308 Kostas Papadimitriou
    `resource_groups` contains information about the groups
1052 75380308 Kostas Papadimitriou
    """
1053 75380308 Kostas Papadimitriou
    # presentation data
1054 75380308 Kostas Papadimitriou
    resource_groups = presentation.RESOURCES.get('groups', {})
1055 75380308 Kostas Papadimitriou
    resource_catalog = ()
1056 0156e40c Kostas Papadimitriou
    resource_keys = []
1057 75380308 Kostas Papadimitriou
1058 75380308 Kostas Papadimitriou
    # resources in database
1059 75380308 Kostas Papadimitriou
    result = callpoint.list_resources()
1060 75380308 Kostas Papadimitriou
    if not result.is_success:
1061 75380308 Kostas Papadimitriou
        messages.error(request, 'Unable to retrieve system resources: %s' %
1062 75380308 Kostas Papadimitriou
                                result.reason)
1063 75380308 Kostas Papadimitriou
    else:
1064 75380308 Kostas Papadimitriou
        # initialize resource_catalog to contain all group/resource information
1065 75380308 Kostas Papadimitriou
        for r in result.data:
1066 75380308 Kostas Papadimitriou
            if not r.get('group') in resource_groups:
1067 75380308 Kostas Papadimitriou
                resource_groups[r.get('group')] = {'icon': 'unknown'}
1068 75380308 Kostas Papadimitriou
1069 75380308 Kostas Papadimitriou
        resource_keys = [r.get('str_repr') for r in result.data]
1070 75380308 Kostas Papadimitriou
        resource_catalog = [[g, filter(lambda r: r.get('group', '') == g,
1071 75380308 Kostas Papadimitriou
                                       result.data)] for g in resource_groups]
1072 75380308 Kostas Papadimitriou
1073 75380308 Kostas Papadimitriou
    # order groups, also include unknown groups
1074 75380308 Kostas Papadimitriou
    groups_order = presentation.RESOURCES.get('groups_order')
1075 75380308 Kostas Papadimitriou
    for g in resource_groups.keys():
1076 75380308 Kostas Papadimitriou
        if not g in groups_order:
1077 75380308 Kostas Papadimitriou
            groups_order.append(g)
1078 75380308 Kostas Papadimitriou
1079 75380308 Kostas Papadimitriou
    # order resources, also include unknown resources
1080 75380308 Kostas Papadimitriou
    resources_order = presentation.RESOURCES.get('resources_order')
1081 75380308 Kostas Papadimitriou
    for r in resource_keys:
1082 75380308 Kostas Papadimitriou
        if not r in resources_order:
1083 75380308 Kostas Papadimitriou
            resources_order.append(r)
1084 75380308 Kostas Papadimitriou
1085 75380308 Kostas Papadimitriou
    # sort catalog groups
1086 75380308 Kostas Papadimitriou
    resource_catalog = sorted(resource_catalog,
1087 75380308 Kostas Papadimitriou
                              key=lambda g: groups_order.index(g[0]))
1088 75380308 Kostas Papadimitriou
1089 75380308 Kostas Papadimitriou
    # sort groups
1090 75380308 Kostas Papadimitriou
    def groupindex(g):
1091 75380308 Kostas Papadimitriou
        return groups_order.index(g[0])
1092 75380308 Kostas Papadimitriou
    resource_groups_list = sorted([(k, v) for k, v in resource_groups.items()],
1093 75380308 Kostas Papadimitriou
                                  key=groupindex)
1094 75380308 Kostas Papadimitriou
    resource_groups = OrderedDict(resource_groups_list)
1095 75380308 Kostas Papadimitriou
1096 75380308 Kostas Papadimitriou
    # sort resources
1097 75380308 Kostas Papadimitriou
    def resourceindex(r):
1098 75380308 Kostas Papadimitriou
        return resources_order.index(r['str_repr'])
1099 75380308 Kostas Papadimitriou
    for index, group in enumerate(resource_catalog):
1100 75380308 Kostas Papadimitriou
        resource_catalog[index][1] = sorted(resource_catalog[index][1],
1101 75380308 Kostas Papadimitriou
                                            key=resourceindex)
1102 75380308 Kostas Papadimitriou
        if len(resource_catalog[index][1]) == 0:
1103 75380308 Kostas Papadimitriou
            resource_catalog.pop(index)
1104 75380308 Kostas Papadimitriou
            for gindex, g in enumerate(resource_groups):
1105 75380308 Kostas Papadimitriou
                if g[0] == group[0]:
1106 75380308 Kostas Papadimitriou
                    resource_groups.pop(gindex)
1107 75380308 Kostas Papadimitriou
1108 75380308 Kostas Papadimitriou
    return resource_catalog, resource_groups
1109 75380308 Kostas Papadimitriou
1110 75380308 Kostas Papadimitriou
1111 172ce682 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1112 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1113 172ce682 Sofia Papagiannaki
def project_add(request):
1114 c7c0ec58 Giorgos Korfiatis
    user = request.user
1115 c7c0ec58 Giorgos Korfiatis
    reached, limit = reached_pending_application_limit(user.id)
1116 db472f3d Giorgos Korfiatis
    if not user.is_project_admin() and reached:
1117 c7c0ec58 Giorgos Korfiatis
        m = _(astakos_messages.PENDING_APPLICATION_LIMIT_ADD) % limit
1118 c7c0ec58 Giorgos Korfiatis
        messages.error(request, m)
1119 c7c0ec58 Giorgos Korfiatis
        next = reverse('astakos.im.views.project_list')
1120 c7c0ec58 Giorgos Korfiatis
        next = restrict_next(next, domain=COOKIE_DOMAIN)
1121 c7c0ec58 Giorgos Korfiatis
        return redirect(next)
1122 c7c0ec58 Giorgos Korfiatis
1123 75380308 Kostas Papadimitriou
    details_fields = ["name", "homepage", "description", "start_date",
1124 75380308 Kostas Papadimitriou
                      "end_date", "comments"]
1125 75380308 Kostas Papadimitriou
    membership_fields = ["member_join_policy", "member_leave_policy",
1126 75380308 Kostas Papadimitriou
                         "limit_on_members_number"]
1127 75380308 Kostas Papadimitriou
    resource_catalog, resource_groups = _resources_catalog(request)
1128 6556e514 Sofia Papagiannaki
    extra_context = {
1129 75380308 Kostas Papadimitriou
        'resource_catalog': resource_catalog,
1130 75380308 Kostas Papadimitriou
        'resource_groups': resource_groups,
1131 75380308 Kostas Papadimitriou
        'show_form': True,
1132 75380308 Kostas Papadimitriou
        'details_fields': details_fields,
1133 75380308 Kostas Papadimitriou
        'membership_fields': membership_fields}
1134 39b2cb50 Giorgos Korfiatis
1135 39b2cb50 Giorgos Korfiatis
    response = None
1136 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1137 39b2cb50 Giorgos Korfiatis
        response = _create_object(
1138 39b2cb50 Giorgos Korfiatis
            request,
1139 39b2cb50 Giorgos Korfiatis
            template_name='im/projects/projectapplication_form.html',
1140 39b2cb50 Giorgos Korfiatis
            extra_context=extra_context,
1141 39b2cb50 Giorgos Korfiatis
            post_save_redirect=reverse('project_list'),
1142 39b2cb50 Giorgos Korfiatis
            form_class=ProjectApplicationForm,
1143 39b2cb50 Giorgos Korfiatis
            msg=_("The %(verbose_name)s has been received and "
1144 39b2cb50 Giorgos Korfiatis
                  "is under consideration."),
1145 39b2cb50 Giorgos Korfiatis
            )
1146 39b2cb50 Giorgos Korfiatis
1147 39b2cb50 Giorgos Korfiatis
    if response is not None:
1148 39b2cb50 Giorgos Korfiatis
        return response
1149 39b2cb50 Giorgos Korfiatis
1150 39b2cb50 Giorgos Korfiatis
    next = reverse('astakos.im.views.project_list')
1151 39b2cb50 Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1152 39b2cb50 Giorgos Korfiatis
    return redirect(next)
1153 ccab6eb5 Sofia Papagiannaki
1154 e1a80257 Sofia Papagiannaki
1155 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET"])
1156 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1157 f3342849 Sofia Papagiannaki
def project_list(request):
1158 05617ab9 Kostas Papadimitriou
    projects = ProjectApplication.objects.user_accessible_projects(request.user).select_related()
1159 2743e261 Kostas Papadimitriou
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
1160 2743e261 Kostas Papadimitriou
                                                prefix="my_projects_")
1161 e6d284ef Olga Brani
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(table)
1162 f7cf5257 Kostas Papadimitriou
1163 e1a80257 Sofia Papagiannaki
    return object_list(
1164 e1a80257 Sofia Papagiannaki
        request,
1165 5550bcfb Kostas Papadimitriou
        projects,
1166 71a38edf Sofia Papagiannaki
        template_name='im/projects/project_list.html',
1167 71a38edf Sofia Papagiannaki
        extra_context={
1168 71a38edf Sofia Papagiannaki
            'is_search':False,
1169 5550bcfb Kostas Papadimitriou
            'table': table,
1170 3f0d6293 Kostas Papadimitriou
        })
1171 3f0d6293 Kostas Papadimitriou
1172 e1a80257 Sofia Papagiannaki
1173 d12e522d Kostas Papadimitriou
@require_http_methods(["POST"])
1174 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1175 39b2cb50 Giorgos Korfiatis
def project_app_cancel(request, application_id):
1176 39b2cb50 Giorgos Korfiatis
    next = request.GET.get('next')
1177 a75dbd7b Giorgos Korfiatis
    chain_id = None
1178 a75dbd7b Giorgos Korfiatis
1179 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1180 39b2cb50 Giorgos Korfiatis
        chain_id = _project_app_cancel(request, application_id)
1181 39b2cb50 Giorgos Korfiatis
1182 a75dbd7b Giorgos Korfiatis
    if not next:
1183 a75dbd7b Giorgos Korfiatis
        if chain_id:
1184 a75dbd7b Giorgos Korfiatis
            next = reverse('astakos.im.views.project_detail', args=(chain_id,))
1185 a75dbd7b Giorgos Korfiatis
        else:
1186 a75dbd7b Giorgos Korfiatis
            next = reverse('astakos.im.views.project_list')
1187 a75dbd7b Giorgos Korfiatis
1188 a75dbd7b Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1189 a75dbd7b Giorgos Korfiatis
    return redirect(next)
1190 a75dbd7b Giorgos Korfiatis
1191 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1192 39b2cb50 Giorgos Korfiatis
def _project_app_cancel(request, application_id):
1193 39b2cb50 Giorgos Korfiatis
    chain_id = None
1194 39b2cb50 Giorgos Korfiatis
    try:
1195 39b2cb50 Giorgos Korfiatis
        application_id = int(application_id)
1196 39b2cb50 Giorgos Korfiatis
        chain_id = get_related_project_id(application_id)
1197 39b2cb50 Giorgos Korfiatis
        cancel_application(application_id, request.user)
1198 39b2cb50 Giorgos Korfiatis
    except (IOError, PermissionDenied), e:
1199 39b2cb50 Giorgos Korfiatis
        messages.error(request, e)
1200 39b2cb50 Giorgos Korfiatis
    else:
1201 39b2cb50 Giorgos Korfiatis
        msg = _(astakos_messages.APPLICATION_CANCELLED)
1202 39b2cb50 Giorgos Korfiatis
        messages.success(request, msg)
1203 39b2cb50 Giorgos Korfiatis
        return chain_id
1204 39b2cb50 Giorgos Korfiatis
1205 a75dbd7b Giorgos Korfiatis
1206 a75dbd7b Giorgos Korfiatis
@require_http_methods(["GET", "POST"])
1207 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1208 3e3743f2 Giorgos Korfiatis
def project_modify(request, application_id):
1209 d4660e00 Giorgos Korfiatis
1210 d4660e00 Giorgos Korfiatis
    try:
1211 d4660e00 Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
1212 d4660e00 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
1213 d4660e00 Giorgos Korfiatis
        raise Http404
1214 d4660e00 Giorgos Korfiatis
1215 beda5f0f Georgios D. Tsoukalas
    user = request.user
1216 beda5f0f Georgios D. Tsoukalas
    if not (user.owns_application(app) or user.is_project_admin(app.id)):
1217 d4660e00 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALLOWED)
1218 d4660e00 Giorgos Korfiatis
        raise PermissionDenied(m)
1219 d4660e00 Giorgos Korfiatis
1220 db472f3d Giorgos Korfiatis
    owner_id = app.owner_id
1221 db472f3d Giorgos Korfiatis
    reached, limit = reached_pending_application_limit(owner_id, app)
1222 db472f3d Giorgos Korfiatis
    if not user.is_project_admin() and reached:
1223 c7c0ec58 Giorgos Korfiatis
        m = _(astakos_messages.PENDING_APPLICATION_LIMIT_MODIFY) % limit
1224 c7c0ec58 Giorgos Korfiatis
        messages.error(request, m)
1225 c7c0ec58 Giorgos Korfiatis
        next = reverse('astakos.im.views.project_list')
1226 c7c0ec58 Giorgos Korfiatis
        next = restrict_next(next, domain=COOKIE_DOMAIN)
1227 c7c0ec58 Giorgos Korfiatis
        return redirect(next)
1228 c7c0ec58 Giorgos Korfiatis
1229 75380308 Kostas Papadimitriou
    details_fields = ["name", "homepage", "description", "start_date",
1230 75380308 Kostas Papadimitriou
                      "end_date", "comments"]
1231 75380308 Kostas Papadimitriou
    membership_fields = ["member_join_policy", "member_leave_policy",
1232 75380308 Kostas Papadimitriou
                         "limit_on_members_number"]
1233 75380308 Kostas Papadimitriou
    resource_catalog, resource_groups = _resources_catalog(request)
1234 6556e514 Sofia Papagiannaki
    extra_context = {
1235 75380308 Kostas Papadimitriou
        'resource_catalog': resource_catalog,
1236 75380308 Kostas Papadimitriou
        'resource_groups': resource_groups,
1237 75380308 Kostas Papadimitriou
        'show_form': True,
1238 75380308 Kostas Papadimitriou
        'details_fields': details_fields,
1239 6003d0a8 Kostas Papadimitriou
        'update_form': True,
1240 75380308 Kostas Papadimitriou
        'membership_fields': membership_fields
1241 75380308 Kostas Papadimitriou
    }
1242 17a2f450 Sofia Papagiannaki
1243 39b2cb50 Giorgos Korfiatis
    response = None
1244 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1245 75380308 Kostas Papadimitriou
        response = _update_object(
1246 39b2cb50 Giorgos Korfiatis
            request,
1247 39b2cb50 Giorgos Korfiatis
            object_id=application_id,
1248 39b2cb50 Giorgos Korfiatis
            template_name='im/projects/projectapplication_form.html',
1249 75380308 Kostas Papadimitriou
            extra_context=extra_context,
1250 75380308 Kostas Papadimitriou
            post_save_redirect=reverse('project_list'),
1251 39b2cb50 Giorgos Korfiatis
            form_class=ProjectApplicationForm,
1252 75380308 Kostas Papadimitriou
            msg=_("The %(verbose_name)s has been received and is under "
1253 75380308 Kostas Papadimitriou
                  "consideration."))
1254 39b2cb50 Giorgos Korfiatis
1255 39b2cb50 Giorgos Korfiatis
    if response is not None:
1256 39b2cb50 Giorgos Korfiatis
        return response
1257 39b2cb50 Giorgos Korfiatis
1258 39b2cb50 Giorgos Korfiatis
    next = reverse('astakos.im.views.project_list')
1259 39b2cb50 Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1260 39b2cb50 Giorgos Korfiatis
    return redirect(next)
1261 e1a80257 Sofia Papagiannaki
1262 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1263 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1264 3e3743f2 Giorgos Korfiatis
def project_app(request, application_id):
1265 d4660e00 Giorgos Korfiatis
    return common_detail(request, application_id, project_view=False)
1266 3e3743f2 Giorgos Korfiatis
1267 3e3743f2 Giorgos Korfiatis
@require_http_methods(["GET", "POST"])
1268 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1269 ff67242a Giorgos Korfiatis
def project_detail(request, chain_id):
1270 3e3743f2 Giorgos Korfiatis
    return common_detail(request, chain_id)
1271 3e3743f2 Giorgos Korfiatis
1272 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1273 39b2cb50 Giorgos Korfiatis
def addmembers(request, chain_id, addmembers_form):
1274 3e3743f2 Giorgos Korfiatis
    if addmembers_form.is_valid():
1275 3e3743f2 Giorgos Korfiatis
        try:
1276 3e3743f2 Giorgos Korfiatis
            chain_id = int(chain_id)
1277 3e3743f2 Giorgos Korfiatis
            map(lambda u: enroll_member(
1278 3e3743f2 Giorgos Korfiatis
                    chain_id,
1279 3e3743f2 Giorgos Korfiatis
                    u,
1280 3e3743f2 Giorgos Korfiatis
                    request_user=request.user),
1281 3e3743f2 Giorgos Korfiatis
                addmembers_form.valid_users)
1282 3e3743f2 Giorgos Korfiatis
        except (IOError, PermissionDenied), e:
1283 3e3743f2 Giorgos Korfiatis
            messages.error(request, e)
1284 f7cf5257 Kostas Papadimitriou
1285 d4660e00 Giorgos Korfiatis
def common_detail(request, chain_or_app_id, project_view=True):
1286 d4660e00 Giorgos Korfiatis
    project = None
1287 d4660e00 Giorgos Korfiatis
    if project_view:
1288 f7e8a6af Giorgos Korfiatis
        chain_id = chain_or_app_id
1289 3e3743f2 Giorgos Korfiatis
        if request.method == 'POST':
1290 27900ab0 Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm(
1291 27900ab0 Sofia Papagiannaki
                request.POST,
1292 27900ab0 Sofia Papagiannaki
                chain_id=int(chain_id),
1293 27900ab0 Sofia Papagiannaki
                request_user=request.user)
1294 39b2cb50 Giorgos Korfiatis
            with ExceptionHandler(request):
1295 39b2cb50 Giorgos Korfiatis
                addmembers(request, chain_id, addmembers_form)
1296 39b2cb50 Giorgos Korfiatis
1297 efb334ca Sofia Papagiannaki
            if addmembers_form.is_valid():
1298 efb334ca Sofia Papagiannaki
                addmembers_form = AddProjectMembersForm()  # clear form data
1299 27900ab0 Sofia Papagiannaki
        else:
1300 efb334ca Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm()  # initialize form
1301 3e3743f2 Giorgos Korfiatis
1302 f7e8a6af Giorgos Korfiatis
        project, application = get_by_chain_or_404(chain_id)
1303 3e3743f2 Giorgos Korfiatis
        if project:
1304 3e3743f2 Giorgos Korfiatis
            members = project.projectmembership_set.select_related()
1305 3e3743f2 Giorgos Korfiatis
            members_table = tables.ProjectMembersTable(project,
1306 3e3743f2 Giorgos Korfiatis
                                                       members,
1307 3e3743f2 Giorgos Korfiatis
                                                       user=request.user,
1308 3e3743f2 Giorgos Korfiatis
                                                       prefix="members_")
1309 3e3743f2 Giorgos Korfiatis
            RequestConfig(request, paginate={"per_page": PAGINATE_BY}
1310 3e3743f2 Giorgos Korfiatis
                          ).configure(members_table)
1311 3e3743f2 Giorgos Korfiatis
1312 3e3743f2 Giorgos Korfiatis
        else:
1313 3e3743f2 Giorgos Korfiatis
            members_table = None
1314 3f0d6293 Kostas Papadimitriou
1315 3e3743f2 Giorgos Korfiatis
    else: # is application
1316 f7e8a6af Giorgos Korfiatis
        application_id = chain_or_app_id
1317 f7e8a6af Giorgos Korfiatis
        application = get_object_or_404(ProjectApplication, pk=application_id)
1318 3e3743f2 Giorgos Korfiatis
        members_table = None
1319 3e3743f2 Giorgos Korfiatis
        addmembers_form = None
1320 2743e261 Kostas Papadimitriou
1321 9b32e2fb Kostas Papadimitriou
    modifications_table = None
1322 7184f408 Giorgos Korfiatis
1323 d4660e00 Giorgos Korfiatis
    user = request.user
1324 8e1a5af5 Georgios D. Tsoukalas
    is_project_admin = user.is_project_admin(application_id=application.id)
1325 d4660e00 Giorgos Korfiatis
    is_owner = user.owns_application(application)
1326 beda5f0f Georgios D. Tsoukalas
    if not (is_owner or is_project_admin) and not project_view:
1327 d4660e00 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALLOWED)
1328 d4660e00 Giorgos Korfiatis
        raise PermissionDenied(m)
1329 d4660e00 Giorgos Korfiatis
1330 beda5f0f Georgios D. Tsoukalas
    if (not (is_owner or is_project_admin) and project_view and
1331 7f31a7a3 Giorgos Korfiatis
        not user.non_owner_can_view(project)):
1332 d4660e00 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALLOWED)
1333 d4660e00 Giorgos Korfiatis
        raise PermissionDenied(m)
1334 d4660e00 Giorgos Korfiatis
1335 3e3743f2 Giorgos Korfiatis
    following_applications = list(application.pending_modifications())
1336 7184f408 Giorgos Korfiatis
    following_applications.reverse()
1337 3e3743f2 Giorgos Korfiatis
    modifications_table = (
1338 7184f408 Giorgos Korfiatis
        tables.ProjectModificationApplicationsTable(following_applications,
1339 7184f408 Giorgos Korfiatis
                                                    user=request.user,
1340 3e3743f2 Giorgos Korfiatis
                                                    prefix="modifications_"))
1341 9b32e2fb Kostas Papadimitriou
1342 d4660e00 Giorgos Korfiatis
    mem_display = user.membership_display(project) if project else None
1343 d4660e00 Giorgos Korfiatis
    can_join_req = can_join_request(project, user) if project else False
1344 d4660e00 Giorgos Korfiatis
    can_leave_req = can_leave_request(project, user) if project else False
1345 d4660e00 Giorgos Korfiatis
1346 c55e840a Sofia Papagiannaki
    return object_detail(
1347 c55e840a Sofia Papagiannaki
        request,
1348 c55e840a Sofia Papagiannaki
        queryset=ProjectApplication.objects.select_related(),
1349 ff67242a Giorgos Korfiatis
        object_id=application.id,
1350 c55e840a Sofia Papagiannaki
        template_name='im/projects/project_detail.html',
1351 c55e840a Sofia Papagiannaki
        extra_context={
1352 d4660e00 Giorgos Korfiatis
            'project_view': project_view,
1353 c55e840a Sofia Papagiannaki
            'addmembers_form':addmembers_form,
1354 624f5625 Kostas Papadimitriou
            'members_table': members_table,
1355 d4660e00 Giorgos Korfiatis
            'owner_mode': is_owner,
1356 8e1a5af5 Georgios D. Tsoukalas
            'admin_mode': is_project_admin,
1357 db9a498c Kostas Papadimitriou
            'modifications_table': modifications_table,
1358 d4660e00 Giorgos Korfiatis
            'mem_display': mem_display,
1359 d4660e00 Giorgos Korfiatis
            'can_join_request': can_join_req,
1360 d4660e00 Giorgos Korfiatis
            'can_leave_request': can_leave_req,
1361 2743e261 Kostas Papadimitriou
            })
1362 5550bcfb Kostas Papadimitriou
1363 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1364 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1365 e1a80257 Sofia Papagiannaki
def project_search(request):
1366 5550bcfb Kostas Papadimitriou
    q = request.GET.get('q', '')
1367 a5cef8d0 Kostas Papadimitriou
    form = ProjectSearchForm()
1368 a5cef8d0 Kostas Papadimitriou
    q = q.strip()
1369 48421603 Kostas Papadimitriou
1370 a5cef8d0 Kostas Papadimitriou
    if request.method == "POST":
1371 48421603 Kostas Papadimitriou
        form = ProjectSearchForm(request.POST)
1372 48421603 Kostas Papadimitriou
        if form.is_valid():
1373 48421603 Kostas Papadimitriou
            q = form.cleaned_data['q'].strip()
1374 48421603 Kostas Papadimitriou
        else:
1375 a5cef8d0 Kostas Papadimitriou
            q = None
1376 a5cef8d0 Kostas Papadimitriou
1377 a5cef8d0 Kostas Papadimitriou
    if q is None:
1378 a5cef8d0 Kostas Papadimitriou
        projects = ProjectApplication.objects.none()
1379 a5cef8d0 Kostas Papadimitriou
    else:
1380 324fb588 Sofia Papagiannaki
        accepted_projects = request.user.projectmembership_set.filter(
1381 324fb588 Sofia Papagiannaki
            ~Q(acceptance_date__isnull=True)).values_list('project', flat=True)
1382 a5cef8d0 Kostas Papadimitriou
        projects = ProjectApplication.objects.search_by_name(q)
1383 a5cef8d0 Kostas Papadimitriou
        projects = projects.filter(~Q(project__last_approval_date__isnull=True))
1384 324fb588 Sofia Papagiannaki
        projects = projects.exclude(project__in=accepted_projects)
1385 ca5148f2 Kostas Papadimitriou
1386 2743e261 Kostas Papadimitriou
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
1387 2743e261 Kostas Papadimitriou
                                                prefix="my_projects_")
1388 b87429e1 Olga Brani
    if request.method == "POST":
1389 b87429e1 Olga Brani
        table.caption = _('SEARCH RESULTS')
1390 b87429e1 Olga Brani
    else:
1391 b87429e1 Olga Brani
        table.caption = _('ALL PROJECTS')
1392 ca5148f2 Kostas Papadimitriou
1393 e6d284ef Olga Brani
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(table)
1394 48421603 Kostas Papadimitriou
1395 bfe23b13 Sofia Papagiannaki
    return object_list(
1396 bfe23b13 Sofia Papagiannaki
        request,
1397 a5cef8d0 Kostas Papadimitriou
        projects,
1398 6dadd24a Sofia Papagiannaki
        template_name='im/projects/project_list.html',
1399 a5cef8d0 Kostas Papadimitriou
        extra_context={
1400 a5cef8d0 Kostas Papadimitriou
          'form': form,
1401 a5cef8d0 Kostas Papadimitriou
          'is_search': True,
1402 a5cef8d0 Kostas Papadimitriou
          'q': q,
1403 a5cef8d0 Kostas Papadimitriou
          'table': table
1404 a5cef8d0 Kostas Papadimitriou
        })
1405 bfe23b13 Sofia Papagiannaki
1406 44f2d10d Kostas Papadimitriou
@require_http_methods(["POST"])
1407 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1408 39b2cb50 Giorgos Korfiatis
def project_join(request, chain_id):
1409 974ee6a6 Sofia Papagiannaki
    next = request.GET.get('next')
1410 73fbaec4 Sofia Papagiannaki
    if not next:
1411 f807da72 Kostas Papadimitriou
        next = reverse('astakos.im.views.project_detail',
1412 ff67242a Giorgos Korfiatis
                       args=(chain_id,))
1413 73fbaec4 Sofia Papagiannaki
1414 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1415 39b2cb50 Giorgos Korfiatis
        _project_join(request, chain_id)
1416 39b2cb50 Giorgos Korfiatis
1417 39b2cb50 Giorgos Korfiatis
1418 39b2cb50 Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1419 39b2cb50 Giorgos Korfiatis
    return redirect(next)
1420 39b2cb50 Giorgos Korfiatis
1421 39b2cb50 Giorgos Korfiatis
1422 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1423 39b2cb50 Giorgos Korfiatis
def _project_join(request, chain_id):
1424 bfe23b13 Sofia Papagiannaki
    try:
1425 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1426 9bca7701 Giorgos Korfiatis
        auto_accepted = join_project(chain_id, request.user.id)
1427 bb6a4465 Giorgos Korfiatis
        if auto_accepted:
1428 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_JOINED_PROJECT)
1429 bb6a4465 Giorgos Korfiatis
        else:
1430 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_JOIN_REQUEST_SUBMITTED)
1431 bb6a4465 Giorgos Korfiatis
        messages.success(request, m)
1432 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1433 bfe23b13 Sofia Papagiannaki
        messages.error(request, e)
1434 39b2cb50 Giorgos Korfiatis
1435 bfe23b13 Sofia Papagiannaki
1436 44f2d10d Kostas Papadimitriou
@require_http_methods(["POST"])
1437 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1438 39b2cb50 Giorgos Korfiatis
def project_leave(request, chain_id):
1439 974ee6a6 Sofia Papagiannaki
    next = request.GET.get('next')
1440 73fbaec4 Sofia Papagiannaki
    if not next:
1441 ed1999ad Kostas Papadimitriou
        next = reverse('astakos.im.views.project_list')
1442 e1a80257 Sofia Papagiannaki
1443 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1444 39b2cb50 Giorgos Korfiatis
        _project_leave(request, chain_id)
1445 39b2cb50 Giorgos Korfiatis
1446 39b2cb50 Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1447 39b2cb50 Giorgos Korfiatis
    return redirect(next)
1448 39b2cb50 Giorgos Korfiatis
1449 39b2cb50 Giorgos Korfiatis
1450 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1451 39b2cb50 Giorgos Korfiatis
def _project_leave(request, chain_id):
1452 73fbaec4 Sofia Papagiannaki
    try:
1453 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1454 9bca7701 Giorgos Korfiatis
        auto_accepted = leave_project(chain_id, request.user.id)
1455 bb6a4465 Giorgos Korfiatis
        if auto_accepted:
1456 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_LEFT_PROJECT)
1457 bb6a4465 Giorgos Korfiatis
        else:
1458 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_LEAVE_REQUEST_SUBMITTED)
1459 bb6a4465 Giorgos Korfiatis
        messages.success(request, m)
1460 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1461 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1462 39b2cb50 Giorgos Korfiatis
1463 aad0e329 Giorgos Korfiatis
1464 aad0e329 Giorgos Korfiatis
@require_http_methods(["POST"])
1465 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1466 39b2cb50 Giorgos Korfiatis
def project_cancel(request, chain_id):
1467 aad0e329 Giorgos Korfiatis
    next = request.GET.get('next')
1468 aad0e329 Giorgos Korfiatis
    if not next:
1469 aad0e329 Giorgos Korfiatis
        next = reverse('astakos.im.views.project_list')
1470 aad0e329 Giorgos Korfiatis
1471 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1472 39b2cb50 Giorgos Korfiatis
        _project_cancel(request, chain_id)
1473 39b2cb50 Giorgos Korfiatis
1474 39b2cb50 Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1475 39b2cb50 Giorgos Korfiatis
    return redirect(next)
1476 39b2cb50 Giorgos Korfiatis
1477 39b2cb50 Giorgos Korfiatis
1478 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1479 39b2cb50 Giorgos Korfiatis
def _project_cancel(request, chain_id):
1480 aad0e329 Giorgos Korfiatis
    try:
1481 aad0e329 Giorgos Korfiatis
        chain_id = int(chain_id)
1482 aad0e329 Giorgos Korfiatis
        cancel_membership(chain_id, request.user)
1483 bb6a4465 Giorgos Korfiatis
        m = _(astakos_messages.USER_REQUEST_CANCELLED)
1484 bb6a4465 Giorgos Korfiatis
        messages.success(request, m)
1485 aad0e329 Giorgos Korfiatis
    except (IOError, PermissionDenied), e:
1486 aad0e329 Giorgos Korfiatis
        messages.error(request, e)
1487 f7cf5257 Kostas Papadimitriou
1488 bfe23b13 Sofia Papagiannaki
1489 16b22352 Kostas Papadimitriou
@require_http_methods(["POST"])
1490 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1491 39b2cb50 Giorgos Korfiatis
def project_accept_member(request, chain_id, user_id):
1492 39b2cb50 Giorgos Korfiatis
1493 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1494 39b2cb50 Giorgos Korfiatis
        _project_accept_member(request, chain_id, user_id)
1495 39b2cb50 Giorgos Korfiatis
1496 39b2cb50 Giorgos Korfiatis
    return redirect(reverse('project_detail', args=(chain_id,)))
1497 39b2cb50 Giorgos Korfiatis
1498 39b2cb50 Giorgos Korfiatis
1499 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1500 39b2cb50 Giorgos Korfiatis
def _project_accept_member(request, chain_id, user_id):
1501 73fbaec4 Sofia Papagiannaki
    try:
1502 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1503 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1504 ff67242a Giorgos Korfiatis
        m = accept_membership(chain_id, user_id, request.user)
1505 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1506 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1507 73fbaec4 Sofia Papagiannaki
    else:
1508 5cc7d5b3 Giorgos Korfiatis
        email = escape(m.person.email)
1509 5cc7d5b3 Giorgos Korfiatis
        msg = _(astakos_messages.USER_MEMBERSHIP_ACCEPTED) % email
1510 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1511 39b2cb50 Giorgos Korfiatis
1512 bfe23b13 Sofia Papagiannaki
1513 f3a45fc6 Kostas Papadimitriou
@require_http_methods(["POST"])
1514 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1515 39b2cb50 Giorgos Korfiatis
def project_remove_member(request, chain_id, user_id):
1516 39b2cb50 Giorgos Korfiatis
1517 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1518 39b2cb50 Giorgos Korfiatis
        _project_remove_member(request, chain_id, user_id)
1519 39b2cb50 Giorgos Korfiatis
1520 39b2cb50 Giorgos Korfiatis
    return redirect(reverse('project_detail', args=(chain_id,)))
1521 39b2cb50 Giorgos Korfiatis
1522 39b2cb50 Giorgos Korfiatis
1523 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1524 39b2cb50 Giorgos Korfiatis
def _project_remove_member(request, chain_id, user_id):
1525 73fbaec4 Sofia Papagiannaki
    try:
1526 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1527 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1528 ff67242a Giorgos Korfiatis
        m = remove_membership(chain_id, user_id, request.user)
1529 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1530 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1531 73fbaec4 Sofia Papagiannaki
    else:
1532 5cc7d5b3 Giorgos Korfiatis
        email = escape(m.person.email)
1533 5cc7d5b3 Giorgos Korfiatis
        msg = _(astakos_messages.USER_MEMBERSHIP_REMOVED) % email
1534 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1535 39b2cb50 Giorgos Korfiatis
1536 bfe23b13 Sofia Papagiannaki
1537 f3a45fc6 Kostas Papadimitriou
@require_http_methods(["POST"])
1538 9d20fe23 Kostas Papadimitriou
@valid_astakos_user_required
1539 39b2cb50 Giorgos Korfiatis
def project_reject_member(request, chain_id, user_id):
1540 39b2cb50 Giorgos Korfiatis
1541 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1542 39b2cb50 Giorgos Korfiatis
        _project_reject_member(request, chain_id, user_id)
1543 39b2cb50 Giorgos Korfiatis
1544 39b2cb50 Giorgos Korfiatis
    return redirect(reverse('project_detail', args=(chain_id,)))
1545 39b2cb50 Giorgos Korfiatis
1546 39b2cb50 Giorgos Korfiatis
1547 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1548 39b2cb50 Giorgos Korfiatis
def _project_reject_member(request, chain_id, user_id):
1549 73fbaec4 Sofia Papagiannaki
    try:
1550 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1551 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1552 ff67242a Giorgos Korfiatis
        m = reject_membership(chain_id, user_id, request.user)
1553 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1554 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1555 73fbaec4 Sofia Papagiannaki
    else:
1556 5cc7d5b3 Giorgos Korfiatis
        email = escape(m.person.email)
1557 5cc7d5b3 Giorgos Korfiatis
        msg = _(astakos_messages.USER_MEMBERSHIP_REJECTED) % email
1558 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1559 39b2cb50 Giorgos Korfiatis
1560 c630fee6 Kostas Papadimitriou
1561 d12e522d Kostas Papadimitriou
@require_http_methods(["POST"])
1562 8e1a5af5 Georgios D. Tsoukalas
@signed_terms_required
1563 8e1a5af5 Georgios D. Tsoukalas
@login_required
1564 39b2cb50 Giorgos Korfiatis
def project_app_approve(request, application_id):
1565 8e1a5af5 Georgios D. Tsoukalas
1566 8e1a5af5 Georgios D. Tsoukalas
    if not request.user.is_project_admin():
1567 8e1a5af5 Georgios D. Tsoukalas
        m = _(astakos_messages.NOT_ALLOWED)
1568 8e1a5af5 Georgios D. Tsoukalas
        raise PermissionDenied(m)
1569 8e1a5af5 Georgios D. Tsoukalas
1570 8e1a5af5 Georgios D. Tsoukalas
    try:
1571 8e1a5af5 Georgios D. Tsoukalas
        app = ProjectApplication.objects.get(id=application_id)
1572 8e1a5af5 Georgios D. Tsoukalas
    except ProjectApplication.DoesNotExist:
1573 8e1a5af5 Georgios D. Tsoukalas
        raise Http404
1574 8e1a5af5 Georgios D. Tsoukalas
1575 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1576 39b2cb50 Giorgos Korfiatis
        _project_app_approve(request, application_id)
1577 39b2cb50 Giorgos Korfiatis
1578 8e1a5af5 Georgios D. Tsoukalas
    chain_id = get_related_project_id(application_id)
1579 8e1a5af5 Georgios D. Tsoukalas
    return redirect(reverse('project_detail', args=(chain_id,)))
1580 8e1a5af5 Georgios D. Tsoukalas
1581 39b2cb50 Giorgos Korfiatis
1582 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1583 39b2cb50 Giorgos Korfiatis
def _project_app_approve(request, application_id):
1584 39b2cb50 Giorgos Korfiatis
    approve_application(application_id)
1585 39b2cb50 Giorgos Korfiatis
1586 39b2cb50 Giorgos Korfiatis
1587 d12e522d Kostas Papadimitriou
@require_http_methods(["POST"])
1588 8e1a5af5 Georgios D. Tsoukalas
@signed_terms_required
1589 8e1a5af5 Georgios D. Tsoukalas
@login_required
1590 39b2cb50 Giorgos Korfiatis
def project_app_deny(request, application_id):
1591 8e1a5af5 Georgios D. Tsoukalas
1592 249026ef Kostas Papadimitriou
    reason = request.POST.get('reason', None)
1593 249026ef Kostas Papadimitriou
    if not reason:
1594 249026ef Kostas Papadimitriou
        reason = None
1595 249026ef Kostas Papadimitriou
1596 8e1a5af5 Georgios D. Tsoukalas
    if not request.user.is_project_admin():
1597 8e1a5af5 Georgios D. Tsoukalas
        m = _(astakos_messages.NOT_ALLOWED)
1598 8e1a5af5 Georgios D. Tsoukalas
        raise PermissionDenied(m)
1599 8e1a5af5 Georgios D. Tsoukalas
1600 8e1a5af5 Georgios D. Tsoukalas
    try:
1601 8e1a5af5 Georgios D. Tsoukalas
        app = ProjectApplication.objects.get(id=application_id)
1602 8e1a5af5 Georgios D. Tsoukalas
    except ProjectApplication.DoesNotExist:
1603 8e1a5af5 Georgios D. Tsoukalas
        raise Http404
1604 8e1a5af5 Georgios D. Tsoukalas
1605 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1606 39b2cb50 Giorgos Korfiatis
        _project_app_deny(request, application_id, reason)
1607 39b2cb50 Giorgos Korfiatis
1608 8e1a5af5 Georgios D. Tsoukalas
    return redirect(reverse('project_list'))
1609 8e1a5af5 Georgios D. Tsoukalas
1610 39b2cb50 Giorgos Korfiatis
1611 39b2cb50 Giorgos Korfiatis
@commit_on_success_strict()
1612 39b2cb50 Giorgos Korfiatis
def _project_app_deny(request, application_id, reason):
1613 39b2cb50 Giorgos Korfiatis
    deny_application(application_id, reason=reason)
1614 39b2cb50 Giorgos Korfiatis
1615 39b2cb50 Giorgos Korfiatis
1616 d12e522d Kostas Papadimitriou
@require_http_methods(["POST"])
1617 8e1a5af5 Georgios D. Tsoukalas
@signed_terms_required
1618 8e1a5af5 Georgios D. Tsoukalas
@login_required
1619 39b2cb50 Giorgos Korfiatis
def project_app_dismiss(request, application_id):
1620 8e1a5af5 Georgios D. Tsoukalas
    try:
1621 8e1a5af5 Georgios D. Tsoukalas
        app = ProjectApplication.objects.get(id=application_id)
1622 8e1a5af5 Georgios D. Tsoukalas
    except ProjectApplication.DoesNotExist:
1623 8e1a5af5 Georgios D. Tsoukalas
        raise Http404
1624 8e1a5af5 Georgios D. Tsoukalas
1625 8e1a5af5 Georgios D. Tsoukalas
    if not request.user.owns_application(app):
1626 8e1a5af5 Georgios D. Tsoukalas
        m = _(astakos_messages.NOT_ALLOWED)
1627 8e1a5af5 Georgios D. Tsoukalas
        raise PermissionDenied(m)
1628 8e1a5af5 Georgios D. Tsoukalas
1629 39b2cb50 Giorgos Korfiatis
    with ExceptionHandler(request):
1630 39b2cb50 Giorgos Korfiatis
        _project_app_dismiss(request, application_id)
1631 022cc8e2 Giorgos Korfiatis
1632 022cc8e2 Giorgos Korfiatis
    chain_id = None
1633 022cc8e2 Giorgos Korfiatis
    chain_id = get_related_project_id(application_id)
1634 022cc8e2 Giorgos Korfiatis
    if chain_id:
1635 022cc8e2 Giorgos Korfiatis
        next = reverse('project_detail', args=(chain_id,))
1636 022cc8e2 Giorgos Korfiatis
    else:
1637 022cc8e2 Giorgos Korfiatis
        next = reverse('project_list')
1638 022cc8e2 Giorgos Korfiatis
    return redirect(next)
1639 022cc8e2 Giorgos Korfiatis
1640 39b2cb50 Giorgos Korfiatis
1641 39b2cb50 Giorgos Korfiatis
def _project_app_dismiss(request, application_id):
1642 39b2cb50 Giorgos Korfiatis
    # XXX: dismiss application also does authorization
1643 39b2cb50 Giorgos Korfiatis
    dismiss_application(application_id, request_user=request.user)
1644 39b2cb50 Giorgos Korfiatis
1645 39b2cb50 Giorgos Korfiatis
1646 9d20fe23 Kostas Papadimitriou
@require_http_methods(["GET"])
1647 9d20fe23 Kostas Papadimitriou
@required_auth_methods_assigned(allow_access=True)
1648 9d20fe23 Kostas Papadimitriou
@login_required
1649 9d20fe23 Kostas Papadimitriou
@signed_terms_required
1650 003d8fcf Olga Brani
def landing(request):
1651 0156e40c Kostas Papadimitriou
    context = {'services': Service.catalog(orderfor='dashboard')}
1652 003d8fcf Olga Brani
    return render_response(
1653 003d8fcf Olga Brani
        'im/landing.html',
1654 0156e40c Kostas Papadimitriou
        context_instance=get_context(request), **context)
1655 b87429e1 Olga Brani
1656 ca5148f2 Kostas Papadimitriou
1657 b87429e1 Olga Brani
def api_access(request):
1658 b87429e1 Olga Brani
    return render_response(
1659 b87429e1 Olga Brani
        'im/api_access.html',
1660 ca5148f2 Kostas Papadimitriou
        context_instance=get_context(request))