Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 7549d16f

History | View | Annotate | Download (56.9 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 fcc1e93f Sofia Papagiannaki
    EmailChange, RESOURCE_SEPARATOR,
82 fcc1e93f Sofia Papagiannaki
    AstakosUserAuthProvider, PendingThirdPartyUser,
83 8a8578c5 Giorgos Korfiatis
    PendingMembershipError,
84 73fbaec4 Sofia Papagiannaki
    ProjectApplication, ProjectMembership, Project)
85 73fbaec4 Sofia Papagiannaki
from astakos.im.util import (
86 73fbaec4 Sofia Papagiannaki
    get_context, prepare_response, get_query, restrict_next)
87 e1a80257 Sofia Papagiannaki
from astakos.im.forms import (
88 f7400729 Kostas Papadimitriou
    LoginForm, InvitationForm,
89 e1a80257 Sofia Papagiannaki
    FeedbackForm, SignApprovalTermsForm,
90 e1a80257 Sofia Papagiannaki
    EmailChangeForm,
91 bfe23b13 Sofia Papagiannaki
    ProjectApplicationForm, ProjectSortForm,
92 73fbaec4 Sofia Papagiannaki
    AddProjectMembersForm, ProjectSearchForm,
93 73fbaec4 Sofia Papagiannaki
    ProjectMembersSortForm)
94 f7400729 Kostas Papadimitriou
from astakos.im.forms import ExtendedProfileForm as ProfileForm
95 f3342849 Sofia Papagiannaki
from astakos.im.functions import (
96 f3342849 Sofia Papagiannaki
    send_feedback, SendMailError,
97 f3342849 Sofia Papagiannaki
    logout as auth_logout,
98 f3342849 Sofia Papagiannaki
    activate as activate_func,
99 73fbaec4 Sofia Papagiannaki
    invite,
100 f3342849 Sofia Papagiannaki
    send_activation as send_activation_func,
101 73fbaec4 Sofia Papagiannaki
    SendNotificationError,
102 c7c0ec58 Giorgos Korfiatis
    reached_pending_application_limit,
103 aad0e329 Giorgos Korfiatis
    accept_membership, reject_membership, remove_membership, cancel_membership,
104 d4660e00 Giorgos Korfiatis
    leave_project, join_project, enroll_member, can_join_request, can_leave_request,
105 8e1a5af5 Georgios D. Tsoukalas
    get_related_project_id, get_by_chain_or_404,
106 8e1a5af5 Georgios D. Tsoukalas
    approve_application, deny_application,
107 8e1a5af5 Georgios D. Tsoukalas
    cancel_application, dismiss_application)
108 f3342849 Sofia Papagiannaki
from astakos.im.settings import (
109 f3342849 Sofia Papagiannaki
    COOKIE_DOMAIN, LOGOUT_NEXT,
110 f3342849 Sofia Papagiannaki
    LOGGING_LEVEL, PAGINATE_BY,
111 a9c7ff8a Sofia Papagiannaki
    RESOURCES_PRESENTATION_DATA, PAGINATE_BY_ALL,
112 3f8570dc Kostas Papadimitriou
    ACTIVATION_REDIRECT_URL,
113 a9c7ff8a Sofia Papagiannaki
    MODERATION_ENABLED)
114 1ebea3d3 Kostas Papadimitriou
from astakos.im.api import get_services_dict
115 48421603 Kostas Papadimitriou
from astakos.im import settings as astakos_settings
116 820b18e0 Sofia Papagiannaki
from astakos.im.api.callpoint import AstakosCallpoint
117 792c2f3b Olga Brani
from astakos.im import auth_providers
118 8cf9b2dd Giorgos Korfiatis
from astakos.im.project_xctx import project_transaction_context
119 8a8578c5 Giorgos Korfiatis
from astakos.im.retry_xctx import RetryException
120 ae497612 Olga Brani
121 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
122 e015e9e6 Sofia Papagiannaki
123 820b18e0 Sofia Papagiannaki
callpoint = AstakosCallpoint()
124 9a06d96f Olga Brani
125 b2ffa772 Sofia Papagiannaki
def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
126 890b0eaf Sofia Papagiannaki
    """
127 890b0eaf Sofia Papagiannaki
    Calls ``django.template.loader.render_to_string`` with an additional ``tab``
128 890b0eaf Sofia Papagiannaki
    keyword argument and returns an ``django.http.HttpResponse`` with the
129 890b0eaf Sofia Papagiannaki
    specified ``status``.
130 890b0eaf Sofia Papagiannaki
    """
131 64cd4730 Antony Chazapis
    if tab is None:
132 881c856c Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
133 64cd4730 Antony Chazapis
    kwargs.setdefault('tab', tab)
134 661c4479 Sofia Papagiannaki
    html = template_loader.render_to_string(
135 5ce3ce4f Sofia Papagiannaki
        template, kwargs, context_instance=context_instance)
136 c301698f Sofia Papagiannaki
    response = HttpResponse(html, status=status)
137 c301698f Sofia Papagiannaki
    return response
138 64cd4730 Antony Chazapis
139 792c2f3b Olga Brani
def requires_auth_provider(provider_id, **perms):
140 792c2f3b Olga Brani
    """
141 792c2f3b Olga Brani
    """
142 792c2f3b Olga Brani
    def decorator(func, *args, **kwargs):
143 792c2f3b Olga Brani
        @wraps(func)
144 792c2f3b Olga Brani
        def wrapper(request, *args, **kwargs):
145 792c2f3b Olga Brani
            provider = auth_providers.get_provider(provider_id)
146 792c2f3b Olga Brani
147 792c2f3b Olga Brani
            if not provider or not provider.is_active():
148 792c2f3b Olga Brani
                raise PermissionDenied
149 792c2f3b Olga Brani
150 792c2f3b Olga Brani
            if provider:
151 792c2f3b Olga Brani
                for pkey, value in perms.iteritems():
152 792c2f3b Olga Brani
                    attr = 'is_available_for_%s' % pkey.lower()
153 792c2f3b Olga Brani
                    if getattr(provider, attr)() != value:
154 279d6e51 Olga Brani
                        #TODO: add session message
155 c630fee6 Kostas Papadimitriou
                        return HttpResponseRedirect(reverse('login'))
156 792c2f3b Olga Brani
            return func(request, *args)
157 792c2f3b Olga Brani
        return wrapper
158 792c2f3b Olga Brani
    return decorator
159 792c2f3b Olga Brani
160 63ecdd20 Sofia Papagiannaki
161 63ecdd20 Sofia Papagiannaki
def requires_anonymous(func):
162 63ecdd20 Sofia Papagiannaki
    """
163 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is not Anonymous and in that case
164 7482228b Sofia Papagiannaki
    redirects to `logout`.
165 63ecdd20 Sofia Papagiannaki
    """
166 63ecdd20 Sofia Papagiannaki
    @wraps(func)
167 63ecdd20 Sofia Papagiannaki
    def wrapper(request, *args):
168 63ecdd20 Sofia Papagiannaki
        if not request.user.is_anonymous():
169 63ecdd20 Sofia Papagiannaki
            next = urlencode({'next': request.build_absolute_uri()})
170 270dd48d Sofia Papagiannaki
            logout_uri = reverse(logout) + '?' + next
171 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(logout_uri)
172 63ecdd20 Sofia Papagiannaki
        return func(request, *args)
173 63ecdd20 Sofia Papagiannaki
    return wrapper
174 63ecdd20 Sofia Papagiannaki
175 5ce3ce4f Sofia Papagiannaki
176 270dd48d Sofia Papagiannaki
def signed_terms_required(func):
177 270dd48d Sofia Papagiannaki
    """
178 badcb2a9 Kostas Papadimitriou
    Decorator checks whether the request.user is Anonymous and in that case
179 270dd48d Sofia Papagiannaki
    redirects to `logout`.
180 270dd48d Sofia Papagiannaki
    """
181 270dd48d Sofia Papagiannaki
    @wraps(func)
182 270dd48d Sofia Papagiannaki
    def wrapper(request, *args, **kwargs):
183 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
184 270dd48d Sofia Papagiannaki
            params = urlencode({'next': request.build_absolute_uri(),
185 5ce3ce4f Sofia Papagiannaki
                                'show_form': ''})
186 270dd48d Sofia Papagiannaki
            terms_uri = reverse('latest_terms') + '?' + params
187 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(terms_uri)
188 270dd48d Sofia Papagiannaki
        return func(request, *args, **kwargs)
189 270dd48d Sofia Papagiannaki
    return wrapper
190 270dd48d Sofia Papagiannaki
191 5ce3ce4f Sofia Papagiannaki
192 badcb2a9 Kostas Papadimitriou
def required_auth_methods_assigned(only_warn=False):
193 badcb2a9 Kostas Papadimitriou
    """
194 badcb2a9 Kostas Papadimitriou
    Decorator that checks whether the request.user has all required auth providers
195 badcb2a9 Kostas Papadimitriou
    assigned.
196 badcb2a9 Kostas Papadimitriou
    """
197 badcb2a9 Kostas Papadimitriou
    required_providers = auth_providers.REQUIRED_PROVIDERS.keys()
198 badcb2a9 Kostas Papadimitriou
199 badcb2a9 Kostas Papadimitriou
    def decorator(func):
200 badcb2a9 Kostas Papadimitriou
        if not required_providers:
201 badcb2a9 Kostas Papadimitriou
            return func
202 badcb2a9 Kostas Papadimitriou
203 badcb2a9 Kostas Papadimitriou
        @wraps(func)
204 badcb2a9 Kostas Papadimitriou
        def wrapper(request, *args, **kwargs):
205 badcb2a9 Kostas Papadimitriou
            if request.user.is_authenticated():
206 badcb2a9 Kostas Papadimitriou
                for required in required_providers:
207 badcb2a9 Kostas Papadimitriou
                    if not request.user.has_auth_provider(required):
208 badcb2a9 Kostas Papadimitriou
                        provider = auth_providers.get_provider(required)
209 badcb2a9 Kostas Papadimitriou
                        if only_warn:
210 badcb2a9 Kostas Papadimitriou
                            messages.error(request,
211 badcb2a9 Kostas Papadimitriou
                                           _(astakos_messages.AUTH_PROVIDER_REQUIRED  % {
212 badcb2a9 Kostas Papadimitriou
                                               'provider': provider.get_title_display}))
213 badcb2a9 Kostas Papadimitriou
                        else:
214 badcb2a9 Kostas Papadimitriou
                            return HttpResponseRedirect(reverse('edit_profile'))
215 badcb2a9 Kostas Papadimitriou
            return func(request, *args, **kwargs)
216 badcb2a9 Kostas Papadimitriou
        return wrapper
217 badcb2a9 Kostas Papadimitriou
    return decorator
218 badcb2a9 Kostas Papadimitriou
219 badcb2a9 Kostas Papadimitriou
220 badcb2a9 Kostas Papadimitriou
def valid_astakos_user_required(func):
221 badcb2a9 Kostas Papadimitriou
    return signed_terms_required(required_auth_methods_assigned()(login_required(func)))
222 badcb2a9 Kostas Papadimitriou
223 badcb2a9 Kostas Papadimitriou
224 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
225 270dd48d Sofia Papagiannaki
@signed_terms_required
226 1f3b4b39 Sofia Papagiannaki
def index(request, login_template_name='im/login.html', profile_template_name='im/profile.html', extra_context=None):
227 890b0eaf Sofia Papagiannaki
    """
228 dcf55476 Sofia Papagiannaki
    If there is logged on user renders the profile page otherwise renders login page.
229 176023aa Kostas Papadimitriou

230 890b0eaf Sofia Papagiannaki
    **Arguments**
231 176023aa Kostas Papadimitriou

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

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

240 890b0eaf Sofia Papagiannaki
    ``extra_context``
241 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
242 176023aa Kostas Papadimitriou

243 890b0eaf Sofia Papagiannaki
    **Template:**
244 176023aa Kostas Papadimitriou

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

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

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

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

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

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

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

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

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

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

306 890b0eaf Sofia Papagiannaki
    **Settings:**
307 176023aa Kostas Papadimitriou

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

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

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

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

369 890b0eaf Sofia Papagiannaki
    **Arguments**
370 176023aa Kostas Papadimitriou

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

375 890b0eaf Sofia Papagiannaki
    ``extra_context``
376 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
377 176023aa Kostas Papadimitriou

378 890b0eaf Sofia Papagiannaki
    **Template:**
379 176023aa Kostas Papadimitriou

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

382 92defad4 Sofia Papagiannaki
    **Settings:**
383 176023aa Kostas Papadimitriou

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

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

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

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

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

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

462 890b0eaf Sofia Papagiannaki
    **Arguments**
463 5ce3ce4f Sofia Papagiannaki

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

468 890b0eaf Sofia Papagiannaki
    ``extra_context``
469 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
470 176023aa Kostas Papadimitriou

471 43332a76 Kostas Papadimitriou
    ``on_success``
472 43332a76 Kostas Papadimitriou
        Resolvable view name to redirect on registration success.
473 43332a76 Kostas Papadimitriou

474 890b0eaf Sofia Papagiannaki
    **Template:**
475 5ce3ce4f Sofia Papagiannaki

476 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
477 890b0eaf Sofia Papagiannaki
    """
478 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
479 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
480 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('edit_profile'))
481 5ce3ce4f Sofia Papagiannaki
482 0a569195 Sofia Papagiannaki
    provider = get_query(request).get('provider', 'local')
483 279d6e51 Olga Brani
    if not auth_providers.get_provider(provider).is_available_for_create():
484 279d6e51 Olga Brani
        raise PermissionDenied
485 279d6e51 Olga Brani
486 6c8a3f7c Sofia Papagiannaki
    id = get_query(request).get('id')
487 6c8a3f7c Sofia Papagiannaki
    try:
488 6c8a3f7c Sofia Papagiannaki
        instance = AstakosUser.objects.get(id=id) if id else None
489 6c8a3f7c Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
490 6c8a3f7c Sofia Papagiannaki
        instance = None
491 6c8a3f7c Sofia Papagiannaki
492 606dea8d Kostas Papadimitriou
    pending_user = None
493 8ab484ea Kostas Papadimitriou
    third_party_token = request.REQUEST.get('third_party_token', None)
494 c630fee6 Kostas Papadimitriou
    if third_party_token:
495 c630fee6 Kostas Papadimitriou
        pending = get_object_or_404(PendingThirdPartyUser,
496 c630fee6 Kostas Papadimitriou
                                    token=third_party_token)
497 c630fee6 Kostas Papadimitriou
        provider = pending.provider
498 c630fee6 Kostas Papadimitriou
        instance = pending.get_user_instance()
499 606dea8d Kostas Papadimitriou
        if pending.existing_user().count() > 0:
500 606dea8d Kostas Papadimitriou
            pending_user = pending.existing_user().get()
501 606dea8d Kostas Papadimitriou
            if request.method == "GET":
502 606dea8d Kostas Papadimitriou
                messages.warning(request, pending_user.get_inactive_message())
503 606dea8d Kostas Papadimitriou
504 606dea8d Kostas Papadimitriou
505 606dea8d Kostas Papadimitriou
    extra_context['pending_user_exists'] = pending_user
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 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
515 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
516 18ffbee1 Sofia Papagiannaki
            user = form.save(commit=False)
517 43332a76 Kostas Papadimitriou
518 43332a76 Kostas Papadimitriou
            # delete previously unverified accounts
519 43332a76 Kostas Papadimitriou
            if AstakosUser.objects.user_exists(user.email):
520 43332a76 Kostas Papadimitriou
                AstakosUser.objects.get_by_identifier(user.email).delete()
521 43332a76 Kostas Papadimitriou
522 8f5a3a06 Sofia Papagiannaki
            try:
523 8f5a3a06 Sofia Papagiannaki
                result = backend.handle_activation(user)
524 8f5a3a06 Sofia Papagiannaki
                status = messages.SUCCESS
525 18ffbee1 Sofia Papagiannaki
                message = result.message
526 792c2f3b Olga Brani
527 792c2f3b Olga Brani
                form.store_user(user, request)
528 792c2f3b Olga Brani
529 ca828a10 Sofia Papagiannaki
                if 'additional_email' in form.cleaned_data:
530 ca828a10 Sofia Papagiannaki
                    additional_email = form.cleaned_data['additional_email']
531 ca828a10 Sofia Papagiannaki
                    if additional_email != user.email:
532 ca828a10 Sofia Papagiannaki
                        user.additionalmail_set.create(email=additional_email)
533 5ce3ce4f Sofia Papagiannaki
                        msg = 'Additional email: %s saved for user %s.' % (
534 6c8a3f7c Sofia Papagiannaki
                            additional_email,
535 6c8a3f7c Sofia Papagiannaki
                            user.email
536 6c8a3f7c Sofia Papagiannaki
                        )
537 b669d9c0 Sofia Papagiannaki
                        logger._log(LOGGING_LEVEL, msg, [])
538 43332a76 Kostas Papadimitriou
539 8f5a3a06 Sofia Papagiannaki
                if user and user.is_active:
540 8f5a3a06 Sofia Papagiannaki
                    next = request.POST.get('next', '')
541 40a0cd8b Sofia Papagiannaki
                    response = prepare_response(request, user, next=next)
542 c3f6cdf1 root
                    transaction.commit()
543 40a0cd8b Sofia Papagiannaki
                    return response
544 43332a76 Kostas Papadimitriou
545 792c2f3b Olga Brani
                transaction.commit()
546 43332a76 Kostas Papadimitriou
                messages.add_message(request, status, message)
547 43332a76 Kostas Papadimitriou
                return HttpResponseRedirect(reverse(on_success))
548 43332a76 Kostas Papadimitriou
549 18ffbee1 Sofia Papagiannaki
            except SendMailError, e:
550 c44955a6 Sofia Papagiannaki
                logger.exception(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 badcb2a9 Kostas Papadimitriou
@required_auth_methods_assigned(only_warn=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 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
614 8f5a3a06 Sofia Papagiannaki
            else:
615 ae497612 Olga Brani
                message = _(astakos_messages.FEEDBACK_SENT)
616 aab4d540 Sofia Papagiannaki
                messages.success(request, message)
617 b9f8f48a Kostas Papadimitriou
            return HttpResponseRedirect(reverse('feedback'))
618 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
619 5ce3ce4f Sofia Papagiannaki
                           feedback_form=form,
620 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
621 5ce3ce4f Sofia Papagiannaki
622 15efc749 Sofia Papagiannaki
623 217994f8 Sofia Papagiannaki
@require_http_methods(["GET"])
624 8e45d6fd Sofia Papagiannaki
@signed_terms_required
625 aab4d540 Sofia Papagiannaki
def logout(request, template='registration/logged_out.html', extra_context=None):
626 63ecdd20 Sofia Papagiannaki
    """
627 b2ffa772 Sofia Papagiannaki
    Wraps `django.contrib.auth.logout`.
628 63ecdd20 Sofia Papagiannaki
    """
629 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
630 7482228b Sofia Papagiannaki
    response = HttpResponse()
631 8e45d6fd Sofia Papagiannaki
    if request.user.is_authenticated():
632 8e45d6fd Sofia Papagiannaki
        email = request.user.email
633 8e45d6fd Sofia Papagiannaki
        auth_logout(request)
634 c630fee6 Kostas Papadimitriou
    else:
635 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
636 c630fee6 Kostas Papadimitriou
        response.status_code = 301
637 c630fee6 Kostas Papadimitriou
        return response
638 c630fee6 Kostas Papadimitriou
639 217994f8 Sofia Papagiannaki
    next = restrict_next(
640 217994f8 Sofia Papagiannaki
        request.GET.get('next'),
641 217994f8 Sofia Papagiannaki
        domain=COOKIE_DOMAIN
642 217994f8 Sofia Papagiannaki
    )
643 c630fee6 Kostas Papadimitriou
644 63ecdd20 Sofia Papagiannaki
    if next:
645 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
646 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
647 0d02a287 Sofia Papagiannaki
    elif LOGOUT_NEXT:
648 0d02a287 Sofia Papagiannaki
        response['Location'] = LOGOUT_NEXT
649 0d02a287 Sofia Papagiannaki
        response.status_code = 301
650 b2ffa772 Sofia Papagiannaki
    else:
651 564a2292 Kostas Papadimitriou
        message = _(astakos_messages.LOGOUT_SUCCESS)
652 564a2292 Kostas Papadimitriou
        last_provider = request.COOKIES.get('astakos_last_login_method', None)
653 564a2292 Kostas Papadimitriou
        if last_provider:
654 564a2292 Kostas Papadimitriou
            provider = auth_providers.get_provider(last_provider)
655 564a2292 Kostas Papadimitriou
            extra_message = provider.get_logout_message_display
656 564a2292 Kostas Papadimitriou
            if extra_message:
657 564a2292 Kostas Papadimitriou
                message += '<br />' + extra_message
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 0a569195 Sofia Papagiannaki
    try:
688 3f8570dc Kostas Papadimitriou
        activate_func(user, greeting_email_template_name,
689 3f8570dc Kostas Papadimitriou
                      helpdesk_email_template_name, verify_email=True)
690 73dcef48 Kostas Papadimitriou
        messages.success(request, _(astakos_messages.ACCOUNT_ACTIVATED))
691 3f8570dc Kostas Papadimitriou
        next = ACTIVATION_REDIRECT_URL or next
692 ef20ea07 Sofia Papagiannaki
        response = prepare_response(request, user, next, renew=True)
693 ef20ea07 Sofia Papagiannaki
        transaction.commit()
694 279d6e51 Olga Brani
        return response
695 ef20ea07 Sofia Papagiannaki
    except SendMailError, e:
696 ef20ea07 Sofia Papagiannaki
        message = e.message
697 ef20ea07 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, message)
698 ef20ea07 Sofia Papagiannaki
        transaction.rollback()
699 279d6e51 Olga Brani
        return index(request)
700 ef20ea07 Sofia Papagiannaki
    except BaseException, e:
701 ef20ea07 Sofia Papagiannaki
        status = messages.ERROR
702 c0b26605 Sofia Papagiannaki
        message = _(astakos_messages.GENERIC_ERROR)
703 ef20ea07 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, message)
704 ef20ea07 Sofia Papagiannaki
        logger.exception(e)
705 ef20ea07 Sofia Papagiannaki
        transaction.rollback()
706 279d6e51 Olga Brani
        return index(request)
707 270dd48d Sofia Papagiannaki
708 5ce3ce4f Sofia Papagiannaki
709 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
710 aab4d540 Sofia Papagiannaki
def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context=None):
711 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
712 270dd48d Sofia Papagiannaki
    term = None
713 270dd48d Sofia Papagiannaki
    terms = None
714 270dd48d Sofia Papagiannaki
    if not term_id:
715 270dd48d Sofia Papagiannaki
        try:
716 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
717 270dd48d Sofia Papagiannaki
        except IndexError:
718 270dd48d Sofia Papagiannaki
            pass
719 270dd48d Sofia Papagiannaki
    else:
720 270dd48d Sofia Papagiannaki
        try:
721 aab4d540 Sofia Papagiannaki
            term = ApprovalTerms.objects.get(id=term_id)
722 aab4d540 Sofia Papagiannaki
        except ApprovalTerms.DoesNotExist, e:
723 270dd48d Sofia Papagiannaki
            pass
724 176023aa Kostas Papadimitriou
725 270dd48d Sofia Papagiannaki
    if not term:
726 ae497612 Olga Brani
        messages.error(request, _(astakos_messages.NO_APPROVAL_TERMS))
727 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('index'))
728 64b5136c Sofia Papagiannaki
    try:
729 64b5136c Sofia Papagiannaki
        f = open(term.location, 'r')
730 64b5136c Sofia Papagiannaki
    except IOError:
731 64b5136c Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
732 64b5136c Sofia Papagiannaki
        return render_response(
733 64b5136c Sofia Papagiannaki
            template_name, context_instance=get_context(request, extra_context))
734 64b5136c Sofia Papagiannaki
735 270dd48d Sofia Papagiannaki
    terms = f.read()
736 176023aa Kostas Papadimitriou
737 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
738 217994f8 Sofia Papagiannaki
        next = restrict_next(
739 217994f8 Sofia Papagiannaki
            request.POST.get('next'),
740 217994f8 Sofia Papagiannaki
            domain=COOKIE_DOMAIN
741 217994f8 Sofia Papagiannaki
        )
742 270dd48d Sofia Papagiannaki
        if not next:
743 6ff7a7ca Sofia Papagiannaki
            next = reverse('index')
744 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
745 270dd48d Sofia Papagiannaki
        if not form.is_valid():
746 270dd48d Sofia Papagiannaki
            return render_response(template_name,
747 5ce3ce4f Sofia Papagiannaki
                                   terms=terms,
748 5ce3ce4f Sofia Papagiannaki
                                   approval_terms_form=form,
749 5ce3ce4f Sofia Papagiannaki
                                   context_instance=get_context(request, extra_context))
750 270dd48d Sofia Papagiannaki
        user = form.save()
751 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
752 270dd48d Sofia Papagiannaki
    else:
753 586967c0 Sofia Papagiannaki
        form = None
754 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
755 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
756 270dd48d Sofia Papagiannaki
        return render_response(template_name,
757 5ce3ce4f Sofia Papagiannaki
                               terms=terms,
758 5ce3ce4f Sofia Papagiannaki
                               approval_terms_form=form,
759 5ce3ce4f Sofia Papagiannaki
                               context_instance=get_context(request, extra_context))
760 5ce3ce4f Sofia Papagiannaki
761 270dd48d Sofia Papagiannaki
762 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
763 49790d9d Sofia Papagiannaki
@transaction.commit_manually
764 49790d9d Sofia Papagiannaki
def change_email(request, activation_key=None,
765 49790d9d Sofia Papagiannaki
                 email_template_name='registration/email_change_email.txt',
766 49790d9d Sofia Papagiannaki
                 form_template_name='registration/email_change_form.html',
767 49790d9d Sofia Papagiannaki
                 confirm_template_name='registration/email_change_done.html',
768 aab4d540 Sofia Papagiannaki
                 extra_context=None):
769 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
770 53e0b8fe Kostas Papadimitriou
771 53e0b8fe Kostas Papadimitriou
772 17ad5d37 Kostas Papadimitriou
    if not astakos_settings.EMAILCHANGE_ENABLED:
773 17ad5d37 Kostas Papadimitriou
        raise PermissionDenied
774 17ad5d37 Kostas Papadimitriou
775 49790d9d Sofia Papagiannaki
    if activation_key:
776 49790d9d Sofia Papagiannaki
        try:
777 49790d9d Sofia Papagiannaki
            user = EmailChange.objects.change_email(activation_key)
778 10a870d5 Kostas Papadimitriou
            if request.user.is_authenticated() and request.user == user or not \
779 10a870d5 Kostas Papadimitriou
                    request.user.is_authenticated():
780 ae497612 Olga Brani
                msg = _(astakos_messages.EMAIL_CHANGED)
781 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
782 49790d9d Sofia Papagiannaki
                transaction.commit()
783 53e0b8fe Kostas Papadimitriou
                return HttpResponseRedirect(reverse('edit_profile'))
784 49790d9d Sofia Papagiannaki
        except ValueError, e:
785 24406ae3 Sofia Papagiannaki
            messages.error(request, e)
786 53e0b8fe Kostas Papadimitriou
            transaction.rollback()
787 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('index'))
788 53e0b8fe Kostas Papadimitriou
789 49790d9d Sofia Papagiannaki
        return render_response(confirm_template_name,
790 53e0b8fe Kostas Papadimitriou
                               modified_user=user if 'user' in locals() \
791 53e0b8fe Kostas Papadimitriou
                               else None, context_instance=get_context(request,
792 5ce3ce4f Sofia Papagiannaki
                                                            extra_context))
793 5ce3ce4f Sofia Papagiannaki
794 49790d9d Sofia Papagiannaki
    if not request.user.is_authenticated():
795 49790d9d Sofia Papagiannaki
        path = quote(request.get_full_path())
796 6ff7a7ca Sofia Papagiannaki
        url = request.build_absolute_uri(reverse('index'))
797 49790d9d Sofia Papagiannaki
        return HttpResponseRedirect(url + '?next=' + path)
798 53e0b8fe Kostas Papadimitriou
799 53e0b8fe Kostas Papadimitriou
    # clean up expired email changes
800 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
801 53e0b8fe Kostas Papadimitriou
        change = request.user.emailchanges.get()
802 53e0b8fe Kostas Papadimitriou
        if change.activation_key_expired():
803 53e0b8fe Kostas Papadimitriou
            change.delete()
804 53e0b8fe Kostas Papadimitriou
            transaction.commit()
805 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('email_change'))
806 53e0b8fe Kostas Papadimitriou
807 49790d9d Sofia Papagiannaki
    form = EmailChangeForm(request.POST or None)
808 49790d9d Sofia Papagiannaki
    if request.method == 'POST' and form.is_valid():
809 49790d9d Sofia Papagiannaki
        try:
810 49790d9d Sofia Papagiannaki
            ec = form.save(email_template_name, request)
811 49790d9d Sofia Papagiannaki
        except SendMailError, e:
812 49790d9d Sofia Papagiannaki
            msg = e
813 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
814 49790d9d Sofia Papagiannaki
            transaction.rollback()
815 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
816 49790d9d Sofia Papagiannaki
        else:
817 ae497612 Olga Brani
            msg = _(astakos_messages.EMAIL_CHANGE_REGISTERED)
818 24406ae3 Sofia Papagiannaki
            messages.success(request, msg)
819 49790d9d Sofia Papagiannaki
            transaction.commit()
820 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
821 53e0b8fe Kostas Papadimitriou
822 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
823 53e0b8fe Kostas Papadimitriou
        messages.warning(request, astakos_messages.PENDING_EMAIL_CHANGE_REQUEST)
824 53e0b8fe Kostas Papadimitriou
825 c0b26605 Sofia Papagiannaki
    return render_response(
826 c0b26605 Sofia Papagiannaki
        form_template_name,
827 c0b26605 Sofia Papagiannaki
        form=form,
828 c0b26605 Sofia Papagiannaki
        context_instance=get_context(request, extra_context)
829 c0b26605 Sofia Papagiannaki
    )
830 1f3b4b39 Sofia Papagiannaki
831 1f3b4b39 Sofia Papagiannaki
832 1f3b4b39 Sofia Papagiannaki
def send_activation(request, user_id, template_name='im/login.html', extra_context=None):
833 792c2f3b Olga Brani
834 badcb2a9 Kostas Papadimitriou
    if request.user.is_authenticated():
835 badcb2a9 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
836 badcb2a9 Kostas Papadimitriou
837 ff81d0d9 Kostas Papadimitriou
    # TODO: check if moderation is only enabled for local login
838 48421603 Kostas Papadimitriou
    if astakos_settings.MODERATION_ENABLED:
839 792c2f3b Olga Brani
        raise PermissionDenied
840 792c2f3b Olga Brani
841 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
842 1f3b4b39 Sofia Papagiannaki
    try:
843 1f3b4b39 Sofia Papagiannaki
        u = AstakosUser.objects.get(id=user_id)
844 1f3b4b39 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
845 c0b26605 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.ACCOUNT_UNKNOWN))
846 1f3b4b39 Sofia Papagiannaki
    else:
847 1f3b4b39 Sofia Papagiannaki
        try:
848 1f3b4b39 Sofia Papagiannaki
            send_activation_func(u)
849 c0b26605 Sofia Papagiannaki
            msg = _(astakos_messages.ACTIVATION_SENT)
850 1f3b4b39 Sofia Papagiannaki
            messages.success(request, msg)
851 1f3b4b39 Sofia Papagiannaki
        except SendMailError, e:
852 1f3b4b39 Sofia Papagiannaki
            messages.error(request, e)
853 ff81d0d9 Kostas Papadimitriou
854 ff81d0d9 Kostas Papadimitriou
    return HttpResponseRedirect(reverse('index'))
855 5ce3ce4f Sofia Papagiannaki
856 73fbaec4 Sofia Papagiannaki
857 73fbaec4 Sofia Papagiannaki
@require_http_methods(["GET"])
858 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
859 666c7490 Sofia Papagiannaki
def resource_usage(request):
860 e9ef5009 Kostas Papadimitriou
861 e9ef5009 Kostas Papadimitriou
    def with_class(entry):
862 e9ef5009 Kostas Papadimitriou
         entry['load_class'] = 'red'
863 e9ef5009 Kostas Papadimitriou
         max_value = float(entry['maxValue'])
864 e9ef5009 Kostas Papadimitriou
         curr_value = float(entry['currValue'])
865 e9ef5009 Kostas Papadimitriou
         entry['ratio_limited']= 0
866 e9ef5009 Kostas Papadimitriou
         if max_value > 0 :
867 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = (curr_value / max_value) * 100
868 e9ef5009 Kostas Papadimitriou
         else:
869 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = 0
870 e9ef5009 Kostas Papadimitriou
         if entry['ratio'] < 66:
871 e9ef5009 Kostas Papadimitriou
             entry['load_class'] = 'yellow'
872 e9ef5009 Kostas Papadimitriou
         if entry['ratio'] < 33:
873 e9ef5009 Kostas Papadimitriou
             entry['load_class'] = 'green'
874 e9ef5009 Kostas Papadimitriou
         if entry['ratio']<0:
875 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = 0
876 e9ef5009 Kostas Papadimitriou
         if entry['ratio']>100:
877 e9ef5009 Kostas Papadimitriou
             entry['ratio_limited'] = 100
878 e9ef5009 Kostas Papadimitriou
         else:
879 e9ef5009 Kostas Papadimitriou
             entry['ratio_limited'] = entry['ratio']
880 e9ef5009 Kostas Papadimitriou
         return entry
881 e9ef5009 Kostas Papadimitriou
882 e9ef5009 Kostas Papadimitriou
    def pluralize(entry):
883 e9ef5009 Kostas Papadimitriou
        entry['plural'] = engine.plural(entry.get('name'))
884 e9ef5009 Kostas Papadimitriou
        return entry
885 e9ef5009 Kostas Papadimitriou
886 a9c7ff8a Sofia Papagiannaki
    resource_usage = None
887 666c7490 Sofia Papagiannaki
    result = callpoint.get_user_usage(request.user.id)
888 820b18e0 Sofia Papagiannaki
    if result.is_success:
889 a9c7ff8a Sofia Papagiannaki
        resource_usage = result.data
890 e9ef5009 Kostas Papadimitriou
        backenddata = map(with_class, result.data)
891 e2497bc5 Sofia Papagiannaki
        backenddata = map(pluralize , backenddata)
892 9a06d96f Olga Brani
    else:
893 820b18e0 Sofia Papagiannaki
        messages.error(request, result.reason)
894 37f8b1a6 Olga Brani
        backenddata = []
895 401089d8 Kostas Papadimitriou
        resource_usage = []
896 401089d8 Kostas Papadimitriou
897 401089d8 Kostas Papadimitriou
    if request.REQUEST.get('json', None):
898 401089d8 Kostas Papadimitriou
        return HttpResponse(json.dumps(backenddata),
899 401089d8 Kostas Papadimitriou
                            mimetype="application/json")
900 401089d8 Kostas Papadimitriou
901 666c7490 Sofia Papagiannaki
    return render_response('im/resource_usage.html',
902 3cbd5e47 Olga Brani
                           context_instance=get_context(request),
903 e9ef5009 Kostas Papadimitriou
                           resource_usage=backenddata,
904 401089d8 Kostas Papadimitriou
                           usage_update_interval=astakos_settings.USAGE_UPDATE_INTERVAL,
905 3cbd5e47 Olga Brani
                           result=result)
906 9a06d96f Olga Brani
907 f432088a Kostas Papadimitriou
# TODO: action only on POST and user should confirm the removal
908 d2633501 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
909 d2633501 Kostas Papadimitriou
@login_required
910 d2633501 Kostas Papadimitriou
@signed_terms_required
911 d2633501 Kostas Papadimitriou
def remove_auth_provider(request, pk):
912 f432088a Kostas Papadimitriou
    try:
913 f432088a Kostas Papadimitriou
        provider = request.user.auth_providers.get(pk=pk)
914 f432088a Kostas Papadimitriou
    except AstakosUserAuthProvider.DoesNotExist:
915 f432088a Kostas Papadimitriou
        raise Http404
916 f432088a Kostas Papadimitriou
917 d2633501 Kostas Papadimitriou
    if provider.can_remove():
918 d2633501 Kostas Papadimitriou
        provider.delete()
919 ca5148f2 Kostas Papadimitriou
        message = astakos_messages.AUTH_PROVIDER_REMOVED % \
920 ca5148f2 Kostas Papadimitriou
                            provider.settings.get_method_prompt_display
921 a53ee093 Kostas Papadimitriou
        user = request.user
922 a53ee093 Kostas Papadimitriou
        logger.info("%s deleted %s provider (%d): %r" % (user.log_display,
923 a53ee093 Kostas Papadimitriou
                                                         provider.module,
924 a53ee093 Kostas Papadimitriou
                                                         int(pk),
925 a53ee093 Kostas Papadimitriou
                                                         provider.info))
926 ca5148f2 Kostas Papadimitriou
        messages.success(request, message)
927 d2633501 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
928 d2633501 Kostas Papadimitriou
    else:
929 f432088a Kostas Papadimitriou
        raise PermissionDenied
930 5ebebb20 Olga Brani
931 792c2f3b Olga Brani
932 5ebebb20 Olga Brani
def how_it_works(request):
933 5ebebb20 Olga Brani
    return render_response(
934 ccab6eb5 Sofia Papagiannaki
        'im/how_it_works.html',
935 ccab6eb5 Sofia Papagiannaki
        context_instance=get_context(request))
936 e1a80257 Sofia Papagiannaki
937 8cf9b2dd Giorgos Korfiatis
@project_transaction_context()
938 172ce682 Sofia Papagiannaki
def _create_object(request, model=None, template_name=None,
939 172ce682 Sofia Papagiannaki
        template_loader=template_loader, extra_context=None, post_save_redirect=None,
940 6556e514 Sofia Papagiannaki
        login_required=False, context_processors=None, form_class=None,
941 8cf9b2dd Giorgos Korfiatis
        msg=None, ctx=None):
942 172ce682 Sofia Papagiannaki
    """
943 4e748491 Sofia Papagiannaki
    Based of django.views.generic.create_update.create_object which displays a
944 172ce682 Sofia Papagiannaki
    summary page before creating the object.
945 172ce682 Sofia Papagiannaki
    """
946 172ce682 Sofia Papagiannaki
    response = None
947 4e748491 Sofia Papagiannaki
948 4e748491 Sofia Papagiannaki
    if extra_context is None: extra_context = {}
949 4e748491 Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
950 4e748491 Sofia Papagiannaki
        return redirect_to_login(request.path)
951 ccab6eb5 Sofia Papagiannaki
    try:
952 f7cf5257 Kostas Papadimitriou
953 172ce682 Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
954 172ce682 Sofia Papagiannaki
        extra_context['edit'] = 0
955 172ce682 Sofia Papagiannaki
        if request.method == 'POST':
956 172ce682 Sofia Papagiannaki
            form = form_class(request.POST, request.FILES)
957 172ce682 Sofia Papagiannaki
            if form.is_valid():
958 172ce682 Sofia Papagiannaki
                verify = request.GET.get('verify')
959 172ce682 Sofia Papagiannaki
                edit = request.GET.get('edit')
960 172ce682 Sofia Papagiannaki
                if verify == '1':
961 172ce682 Sofia Papagiannaki
                    extra_context['show_form'] = False
962 172ce682 Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
963 172ce682 Sofia Papagiannaki
                elif edit == '1':
964 172ce682 Sofia Papagiannaki
                    extra_context['show_form'] = True
965 172ce682 Sofia Papagiannaki
                else:
966 172ce682 Sofia Papagiannaki
                    new_object = form.save()
967 6556e514 Sofia Papagiannaki
                    if not msg:
968 6556e514 Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
969 6556e514 Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
970 172ce682 Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
971 172ce682 Sofia Papagiannaki
                    response = redirect(post_save_redirect, new_object)
972 172ce682 Sofia Papagiannaki
        else:
973 172ce682 Sofia Papagiannaki
            form = form_class()
974 b8f05f8d Sofia Papagiannaki
    except BaseException, e:
975 b8f05f8d Sofia Papagiannaki
        logger.exception(e)
976 b8f05f8d Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
977 8cf9b2dd Giorgos Korfiatis
        if ctx:
978 8cf9b2dd Giorgos Korfiatis
            ctx.mark_rollback()
979 bfe23b13 Sofia Papagiannaki
    finally:
980 172ce682 Sofia Papagiannaki
        if response == None:
981 172ce682 Sofia Papagiannaki
            # Create the template, context, response
982 172ce682 Sofia Papagiannaki
            if not template_name:
983 172ce682 Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
984 172ce682 Sofia Papagiannaki
                     (model._meta.app_label, model._meta.object_name.lower())
985 172ce682 Sofia Papagiannaki
            t = template_loader.get_template(template_name)
986 172ce682 Sofia Papagiannaki
            c = RequestContext(request, {
987 172ce682 Sofia Papagiannaki
                'form': form
988 172ce682 Sofia Papagiannaki
            }, context_processors)
989 172ce682 Sofia Papagiannaki
            apply_extra_context(extra_context, c)
990 172ce682 Sofia Papagiannaki
            response = HttpResponse(t.render(c))
991 172ce682 Sofia Papagiannaki
        return response
992 172ce682 Sofia Papagiannaki
993 8cf9b2dd Giorgos Korfiatis
@project_transaction_context()
994 4e748491 Sofia Papagiannaki
def _update_object(request, model=None, object_id=None, slug=None,
995 4e748491 Sofia Papagiannaki
        slug_field='slug', template_name=None, template_loader=template_loader,
996 4e748491 Sofia Papagiannaki
        extra_context=None, post_save_redirect=None, login_required=False,
997 4e748491 Sofia Papagiannaki
        context_processors=None, template_object_name='object',
998 8cf9b2dd Giorgos Korfiatis
        form_class=None, msg=None, ctx=None):
999 4e748491 Sofia Papagiannaki
    """
1000 4e748491 Sofia Papagiannaki
    Based of django.views.generic.create_update.update_object which displays a
1001 4e748491 Sofia Papagiannaki
    summary page before updating the object.
1002 4e748491 Sofia Papagiannaki
    """
1003 4e748491 Sofia Papagiannaki
    response = None
1004 4e748491 Sofia Papagiannaki
1005 4e748491 Sofia Papagiannaki
    if extra_context is None: extra_context = {}
1006 4e748491 Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
1007 4e748491 Sofia Papagiannaki
        return redirect_to_login(request.path)
1008 f7cf5257 Kostas Papadimitriou
1009 4e748491 Sofia Papagiannaki
    try:
1010 4e748491 Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
1011 4e748491 Sofia Papagiannaki
        obj = lookup_object(model, object_id, slug, slug_field)
1012 f7cf5257 Kostas Papadimitriou
1013 4e748491 Sofia Papagiannaki
        if request.method == 'POST':
1014 4e748491 Sofia Papagiannaki
            form = form_class(request.POST, request.FILES, instance=obj)
1015 4e748491 Sofia Papagiannaki
            if form.is_valid():
1016 4e748491 Sofia Papagiannaki
                verify = request.GET.get('verify')
1017 4e748491 Sofia Papagiannaki
                edit = request.GET.get('edit')
1018 4e748491 Sofia Papagiannaki
                if verify == '1':
1019 4e748491 Sofia Papagiannaki
                    extra_context['show_form'] = False
1020 4e748491 Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
1021 4e748491 Sofia Papagiannaki
                elif edit == '1':
1022 4e748491 Sofia Papagiannaki
                    extra_context['show_form'] = True
1023 f7cf5257 Kostas Papadimitriou
                else:
1024 4e748491 Sofia Papagiannaki
                    obj = form.save()
1025 6556e514 Sofia Papagiannaki
                    if not msg:
1026 6556e514 Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
1027 6556e514 Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
1028 6556e514 Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
1029 4e748491 Sofia Papagiannaki
                    response = redirect(post_save_redirect, obj)
1030 4e748491 Sofia Papagiannaki
        else:
1031 4e748491 Sofia Papagiannaki
            form = form_class(instance=obj)
1032 4e748491 Sofia Papagiannaki
    except BaseException, e:
1033 4e748491 Sofia Papagiannaki
        logger.exception(e)
1034 4e748491 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1035 8cf9b2dd Giorgos Korfiatis
        ctx.mark_rollback()
1036 4e748491 Sofia Papagiannaki
    finally:
1037 4e748491 Sofia Papagiannaki
        if response == None:
1038 4e748491 Sofia Papagiannaki
            if not template_name:
1039 4e748491 Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
1040 4e748491 Sofia Papagiannaki
                    (model._meta.app_label, model._meta.object_name.lower())
1041 4e748491 Sofia Papagiannaki
            t = template_loader.get_template(template_name)
1042 4e748491 Sofia Papagiannaki
            c = RequestContext(request, {
1043 4e748491 Sofia Papagiannaki
                'form': form,
1044 4e748491 Sofia Papagiannaki
                template_object_name: obj,
1045 4e748491 Sofia Papagiannaki
            }, context_processors)
1046 4e748491 Sofia Papagiannaki
            apply_extra_context(extra_context, c)
1047 4e748491 Sofia Papagiannaki
            response = HttpResponse(t.render(c))
1048 4e748491 Sofia Papagiannaki
            populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname))
1049 4e748491 Sofia Papagiannaki
        return response
1050 4e748491 Sofia Papagiannaki
1051 172ce682 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1052 172ce682 Sofia Papagiannaki
@signed_terms_required
1053 172ce682 Sofia Papagiannaki
@login_required
1054 172ce682 Sofia Papagiannaki
def project_add(request):
1055 c7c0ec58 Giorgos Korfiatis
1056 c7c0ec58 Giorgos Korfiatis
    user = request.user
1057 c7c0ec58 Giorgos Korfiatis
    reached, limit = reached_pending_application_limit(user.id)
1058 c7c0ec58 Giorgos Korfiatis
    if reached:
1059 c7c0ec58 Giorgos Korfiatis
        m = _(astakos_messages.PENDING_APPLICATION_LIMIT_ADD) % limit
1060 c7c0ec58 Giorgos Korfiatis
        messages.error(request, m)
1061 c7c0ec58 Giorgos Korfiatis
        next = reverse('astakos.im.views.project_list')
1062 c7c0ec58 Giorgos Korfiatis
        next = restrict_next(next, domain=COOKIE_DOMAIN)
1063 c7c0ec58 Giorgos Korfiatis
        return redirect(next)
1064 c7c0ec58 Giorgos Korfiatis
1065 6556e514 Sofia Papagiannaki
    resource_groups = RESOURCES_PRESENTATION_DATA.get('groups', {})
1066 6556e514 Sofia Papagiannaki
    resource_catalog = ()
1067 172ce682 Sofia Papagiannaki
    result = callpoint.list_resources()
1068 6556e514 Sofia Papagiannaki
    details_fields = [
1069 6556e514 Sofia Papagiannaki
        "name", "homepage", "description","start_date","end_date", "comments"]
1070 6556e514 Sofia Papagiannaki
    membership_fields =[
1071 6556e514 Sofia Papagiannaki
        "member_join_policy", "member_leave_policy", "limit_on_members_number"]
1072 172ce682 Sofia Papagiannaki
    if not result.is_success:
1073 172ce682 Sofia Papagiannaki
        messages.error(
1074 172ce682 Sofia Papagiannaki
            request,
1075 172ce682 Sofia Papagiannaki
            'Unable to retrieve system resources: %s' % result.reason
1076 172ce682 Sofia Papagiannaki
    )
1077 172ce682 Sofia Papagiannaki
    else:
1078 6556e514 Sofia Papagiannaki
        resource_catalog = [
1079 ec2e67f4 Kostas Papadimitriou
            [g, filter(lambda r: r.get('group', '') == g, result.data)] \
1080 6556e514 Sofia Papagiannaki
                for g in resource_groups]
1081 ec2e67f4 Kostas Papadimitriou
1082 ec2e67f4 Kostas Papadimitriou
    # order resources
1083 ec2e67f4 Kostas Papadimitriou
    groups_order = RESOURCES_PRESENTATION_DATA.get('groups_order')
1084 ec2e67f4 Kostas Papadimitriou
    resources_order = RESOURCES_PRESENTATION_DATA.get('resources_order')
1085 76ca5ff0 Kostas Papadimitriou
    resource_catalog = sorted(resource_catalog, key=lambda g:groups_order.index(g[0]))
1086 76ca5ff0 Kostas Papadimitriou
1087 76ca5ff0 Kostas Papadimitriou
    resource_groups_list = sorted([(k,v) for k,v in resource_groups.items()],
1088 76ca5ff0 Kostas Papadimitriou
                                  key=lambda f:groups_order.index(f[0]))
1089 76ca5ff0 Kostas Papadimitriou
    resource_groups = OrderedDict(resource_groups_list)
1090 ec2e67f4 Kostas Papadimitriou
    for index, group in enumerate(resource_catalog):
1091 ec2e67f4 Kostas Papadimitriou
        resource_catalog[index][1] = sorted(resource_catalog[index][1],
1092 ec2e67f4 Kostas Papadimitriou
                                            key=lambda r: resources_order.index(r['str_repr']))
1093 ec2e67f4 Kostas Papadimitriou
1094 ec2e67f4 Kostas Papadimitriou
1095 6556e514 Sofia Papagiannaki
    extra_context = {
1096 6556e514 Sofia Papagiannaki
        'resource_catalog':resource_catalog,
1097 6556e514 Sofia Papagiannaki
        'resource_groups':resource_groups,
1098 6556e514 Sofia Papagiannaki
        'show_form':True,
1099 6556e514 Sofia Papagiannaki
        'details_fields':details_fields,
1100 6556e514 Sofia Papagiannaki
        'membership_fields':membership_fields}
1101 6556e514 Sofia Papagiannaki
    return _create_object(
1102 6556e514 Sofia Papagiannaki
        request,
1103 6556e514 Sofia Papagiannaki
        template_name='im/projects/projectapplication_form.html',
1104 6556e514 Sofia Papagiannaki
        extra_context=extra_context,
1105 6556e514 Sofia Papagiannaki
        post_save_redirect=reverse('project_list'),
1106 6556e514 Sofia Papagiannaki
        form_class=ProjectApplicationForm,
1107 6556e514 Sofia Papagiannaki
        msg=_("The %(verbose_name)s has been received and \
1108 6556e514 Sofia Papagiannaki
                 is under consideration."))
1109 ccab6eb5 Sofia Papagiannaki
1110 e1a80257 Sofia Papagiannaki
1111 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET"])
1112 e1a80257 Sofia Papagiannaki
@signed_terms_required
1113 e1a80257 Sofia Papagiannaki
@login_required
1114 f3342849 Sofia Papagiannaki
def project_list(request):
1115 05617ab9 Kostas Papadimitriou
    projects = ProjectApplication.objects.user_accessible_projects(request.user).select_related()
1116 2743e261 Kostas Papadimitriou
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
1117 2743e261 Kostas Papadimitriou
                                                prefix="my_projects_")
1118 e6d284ef Olga Brani
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(table)
1119 f7cf5257 Kostas Papadimitriou
1120 e1a80257 Sofia Papagiannaki
    return object_list(
1121 e1a80257 Sofia Papagiannaki
        request,
1122 5550bcfb Kostas Papadimitriou
        projects,
1123 71a38edf Sofia Papagiannaki
        template_name='im/projects/project_list.html',
1124 71a38edf Sofia Papagiannaki
        extra_context={
1125 71a38edf Sofia Papagiannaki
            'is_search':False,
1126 5550bcfb Kostas Papadimitriou
            'table': table,
1127 3f0d6293 Kostas Papadimitriou
        })
1128 3f0d6293 Kostas Papadimitriou
1129 e1a80257 Sofia Papagiannaki
1130 f3342849 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1131 e1a80257 Sofia Papagiannaki
@signed_terms_required
1132 e1a80257 Sofia Papagiannaki
@login_required
1133 a75dbd7b Giorgos Korfiatis
@project_transaction_context()
1134 a75dbd7b Giorgos Korfiatis
def project_app_cancel(request, application_id, ctx=None):
1135 a75dbd7b Giorgos Korfiatis
    chain_id = None
1136 a75dbd7b Giorgos Korfiatis
    try:
1137 a75dbd7b Giorgos Korfiatis
        application_id = int(application_id)
1138 a75dbd7b Giorgos Korfiatis
        chain_id = get_related_project_id(application_id)
1139 a75dbd7b Giorgos Korfiatis
        cancel_application(application_id, request.user)
1140 a75dbd7b Giorgos Korfiatis
    except (IOError, PermissionDenied), e:
1141 a75dbd7b Giorgos Korfiatis
        messages.error(request, e)
1142 a75dbd7b Giorgos Korfiatis
    except BaseException, e:
1143 a75dbd7b Giorgos Korfiatis
        logger.exception(e)
1144 a75dbd7b Giorgos Korfiatis
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1145 a75dbd7b Giorgos Korfiatis
        if ctx:
1146 a75dbd7b Giorgos Korfiatis
            ctx.mark_rollback()
1147 a75dbd7b Giorgos Korfiatis
    else:
1148 a75dbd7b Giorgos Korfiatis
        msg = _(astakos_messages.APPLICATION_CANCELLED)
1149 a75dbd7b Giorgos Korfiatis
        messages.success(request, msg)
1150 a75dbd7b Giorgos Korfiatis
1151 a75dbd7b Giorgos Korfiatis
    next = request.GET.get('next')
1152 a75dbd7b Giorgos Korfiatis
    if not next:
1153 a75dbd7b Giorgos Korfiatis
        if chain_id:
1154 a75dbd7b Giorgos Korfiatis
            next = reverse('astakos.im.views.project_detail', args=(chain_id,))
1155 a75dbd7b Giorgos Korfiatis
        else:
1156 a75dbd7b Giorgos Korfiatis
            next = reverse('astakos.im.views.project_list')
1157 a75dbd7b Giorgos Korfiatis
1158 a75dbd7b Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1159 a75dbd7b Giorgos Korfiatis
    return redirect(next)
1160 a75dbd7b Giorgos Korfiatis
1161 a75dbd7b Giorgos Korfiatis
1162 a75dbd7b Giorgos Korfiatis
@require_http_methods(["GET", "POST"])
1163 a75dbd7b Giorgos Korfiatis
@signed_terms_required
1164 a75dbd7b Giorgos Korfiatis
@login_required
1165 3e3743f2 Giorgos Korfiatis
def project_modify(request, application_id):
1166 d4660e00 Giorgos Korfiatis
1167 d4660e00 Giorgos Korfiatis
    try:
1168 d4660e00 Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
1169 d4660e00 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
1170 d4660e00 Giorgos Korfiatis
        raise Http404
1171 d4660e00 Giorgos Korfiatis
1172 beda5f0f Georgios D. Tsoukalas
    user = request.user
1173 beda5f0f Georgios D. Tsoukalas
    if not (user.owns_application(app) or user.is_project_admin(app.id)):
1174 d4660e00 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALLOWED)
1175 d4660e00 Giorgos Korfiatis
        raise PermissionDenied(m)
1176 d4660e00 Giorgos Korfiatis
1177 c7c0ec58 Giorgos Korfiatis
    reached, limit = reached_pending_application_limit(user.id, app)
1178 c7c0ec58 Giorgos Korfiatis
    if reached:
1179 c7c0ec58 Giorgos Korfiatis
        m = _(astakos_messages.PENDING_APPLICATION_LIMIT_MODIFY) % limit
1180 c7c0ec58 Giorgos Korfiatis
        messages.error(request, m)
1181 c7c0ec58 Giorgos Korfiatis
        next = reverse('astakos.im.views.project_list')
1182 c7c0ec58 Giorgos Korfiatis
        next = restrict_next(next, domain=COOKIE_DOMAIN)
1183 c7c0ec58 Giorgos Korfiatis
        return redirect(next)
1184 c7c0ec58 Giorgos Korfiatis
1185 6556e514 Sofia Papagiannaki
    resource_groups = RESOURCES_PRESENTATION_DATA.get('groups', {})
1186 6556e514 Sofia Papagiannaki
    resource_catalog = ()
1187 8327782d Sofia Papagiannaki
    result = callpoint.list_resources()
1188 6556e514 Sofia Papagiannaki
    details_fields = [
1189 6556e514 Sofia Papagiannaki
        "name", "homepage", "description","start_date","end_date", "comments"]
1190 6556e514 Sofia Papagiannaki
    membership_fields =[
1191 3f0d6293 Kostas Papadimitriou
        "member_join_policy", "member_leave_policy", "limit_on_members_number"]
1192 8327782d Sofia Papagiannaki
    if not result.is_success:
1193 8327782d Sofia Papagiannaki
        messages.error(
1194 8327782d Sofia Papagiannaki
            request,
1195 8327782d Sofia Papagiannaki
            'Unable to retrieve system resources: %s' % result.reason
1196 8327782d Sofia Papagiannaki
    )
1197 172ce682 Sofia Papagiannaki
    else:
1198 6556e514 Sofia Papagiannaki
        resource_catalog = [
1199 6556e514 Sofia Papagiannaki
            (g, filter(lambda r: r.get('group', '') == g, result.data)) \
1200 6556e514 Sofia Papagiannaki
                for g in resource_groups]
1201 6556e514 Sofia Papagiannaki
    extra_context = {
1202 6556e514 Sofia Papagiannaki
        'resource_catalog':resource_catalog,
1203 6556e514 Sofia Papagiannaki
        'resource_groups':resource_groups,
1204 6556e514 Sofia Papagiannaki
        'show_form':True,
1205 6556e514 Sofia Papagiannaki
        'details_fields':details_fields,
1206 6003d0a8 Kostas Papadimitriou
        'update_form': True,
1207 6556e514 Sofia Papagiannaki
        'membership_fields':membership_fields}
1208 4e748491 Sofia Papagiannaki
    return _update_object(
1209 f3342849 Sofia Papagiannaki
        request,
1210 73fbaec4 Sofia Papagiannaki
        object_id=application_id,
1211 8327782d Sofia Papagiannaki
        template_name='im/projects/projectapplication_form.html',
1212 37f8b1a6 Olga Brani
        extra_context=extra_context, post_save_redirect=reverse('project_list'),
1213 6556e514 Sofia Papagiannaki
        form_class=ProjectApplicationForm,
1214 6556e514 Sofia Papagiannaki
        msg = _("The %(verbose_name)s has been received and \
1215 6556e514 Sofia Papagiannaki
                    is under consideration."))
1216 17a2f450 Sofia Papagiannaki
1217 e1a80257 Sofia Papagiannaki
1218 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1219 e1a80257 Sofia Papagiannaki
@signed_terms_required
1220 e1a80257 Sofia Papagiannaki
@login_required
1221 3e3743f2 Giorgos Korfiatis
def project_app(request, application_id):
1222 d4660e00 Giorgos Korfiatis
    return common_detail(request, application_id, project_view=False)
1223 3e3743f2 Giorgos Korfiatis
1224 3e3743f2 Giorgos Korfiatis
@require_http_methods(["GET", "POST"])
1225 3e3743f2 Giorgos Korfiatis
@signed_terms_required
1226 3e3743f2 Giorgos Korfiatis
@login_required
1227 ff67242a Giorgos Korfiatis
def project_detail(request, chain_id):
1228 3e3743f2 Giorgos Korfiatis
    return common_detail(request, chain_id)
1229 3e3743f2 Giorgos Korfiatis
1230 8cf9b2dd Giorgos Korfiatis
@project_transaction_context(sync=True)
1231 27900ab0 Sofia Papagiannaki
def addmembers(request, chain_id, addmembers_form, ctx=None):
1232 3e3743f2 Giorgos Korfiatis
    if addmembers_form.is_valid():
1233 3e3743f2 Giorgos Korfiatis
        try:
1234 3e3743f2 Giorgos Korfiatis
            chain_id = int(chain_id)
1235 3e3743f2 Giorgos Korfiatis
            map(lambda u: enroll_member(
1236 3e3743f2 Giorgos Korfiatis
                    chain_id,
1237 3e3743f2 Giorgos Korfiatis
                    u,
1238 3e3743f2 Giorgos Korfiatis
                    request_user=request.user),
1239 3e3743f2 Giorgos Korfiatis
                addmembers_form.valid_users)
1240 3e3743f2 Giorgos Korfiatis
        except (IOError, PermissionDenied), e:
1241 3e3743f2 Giorgos Korfiatis
            messages.error(request, e)
1242 3e3743f2 Giorgos Korfiatis
        except BaseException, e:
1243 8cf9b2dd Giorgos Korfiatis
            if ctx:
1244 8cf9b2dd Giorgos Korfiatis
                ctx.mark_rollback()
1245 3e3743f2 Giorgos Korfiatis
            messages.error(request, e)
1246 f7cf5257 Kostas Papadimitriou
1247 d4660e00 Giorgos Korfiatis
def common_detail(request, chain_or_app_id, project_view=True):
1248 d4660e00 Giorgos Korfiatis
    project = None
1249 d4660e00 Giorgos Korfiatis
    if project_view:
1250 f7e8a6af Giorgos Korfiatis
        chain_id = chain_or_app_id
1251 3e3743f2 Giorgos Korfiatis
        if request.method == 'POST':
1252 27900ab0 Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm(
1253 27900ab0 Sofia Papagiannaki
                request.POST,
1254 27900ab0 Sofia Papagiannaki
                chain_id=int(chain_id),
1255 27900ab0 Sofia Papagiannaki
                request_user=request.user)
1256 27900ab0 Sofia Papagiannaki
            addmembers(request, chain_id, addmembers_form)
1257 efb334ca Sofia Papagiannaki
            if addmembers_form.is_valid():
1258 efb334ca Sofia Papagiannaki
                addmembers_form = AddProjectMembersForm()  # clear form data
1259 27900ab0 Sofia Papagiannaki
        else:
1260 efb334ca Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm()  # initialize form
1261 3e3743f2 Giorgos Korfiatis
1262 f7e8a6af Giorgos Korfiatis
        project, application = get_by_chain_or_404(chain_id)
1263 3e3743f2 Giorgos Korfiatis
        if project:
1264 3e3743f2 Giorgos Korfiatis
            members = project.projectmembership_set.select_related()
1265 3e3743f2 Giorgos Korfiatis
            members_table = tables.ProjectMembersTable(project,
1266 3e3743f2 Giorgos Korfiatis
                                                       members,
1267 3e3743f2 Giorgos Korfiatis
                                                       user=request.user,
1268 3e3743f2 Giorgos Korfiatis
                                                       prefix="members_")
1269 3e3743f2 Giorgos Korfiatis
            RequestConfig(request, paginate={"per_page": PAGINATE_BY}
1270 3e3743f2 Giorgos Korfiatis
                          ).configure(members_table)
1271 3e3743f2 Giorgos Korfiatis
1272 3e3743f2 Giorgos Korfiatis
        else:
1273 3e3743f2 Giorgos Korfiatis
            members_table = None
1274 3f0d6293 Kostas Papadimitriou
1275 3e3743f2 Giorgos Korfiatis
    else: # is application
1276 f7e8a6af Giorgos Korfiatis
        application_id = chain_or_app_id
1277 f7e8a6af Giorgos Korfiatis
        application = get_object_or_404(ProjectApplication, pk=application_id)
1278 3e3743f2 Giorgos Korfiatis
        members_table = None
1279 3e3743f2 Giorgos Korfiatis
        addmembers_form = None
1280 2743e261 Kostas Papadimitriou
1281 9b32e2fb Kostas Papadimitriou
    modifications_table = None
1282 7184f408 Giorgos Korfiatis
1283 d4660e00 Giorgos Korfiatis
    user = request.user
1284 8e1a5af5 Georgios D. Tsoukalas
    is_project_admin = user.is_project_admin(application_id=application.id)
1285 d4660e00 Giorgos Korfiatis
    is_owner = user.owns_application(application)
1286 beda5f0f Georgios D. Tsoukalas
    if not (is_owner or is_project_admin) and not project_view:
1287 d4660e00 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALLOWED)
1288 d4660e00 Giorgos Korfiatis
        raise PermissionDenied(m)
1289 d4660e00 Giorgos Korfiatis
1290 beda5f0f Georgios D. Tsoukalas
    if (not (is_owner or is_project_admin) and project_view and
1291 7f31a7a3 Giorgos Korfiatis
        not user.non_owner_can_view(project)):
1292 d4660e00 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALLOWED)
1293 d4660e00 Giorgos Korfiatis
        raise PermissionDenied(m)
1294 d4660e00 Giorgos Korfiatis
1295 3e3743f2 Giorgos Korfiatis
    following_applications = list(application.pending_modifications())
1296 7184f408 Giorgos Korfiatis
    following_applications.reverse()
1297 3e3743f2 Giorgos Korfiatis
    modifications_table = (
1298 7184f408 Giorgos Korfiatis
        tables.ProjectModificationApplicationsTable(following_applications,
1299 7184f408 Giorgos Korfiatis
                                                    user=request.user,
1300 3e3743f2 Giorgos Korfiatis
                                                    prefix="modifications_"))
1301 9b32e2fb Kostas Papadimitriou
1302 d4660e00 Giorgos Korfiatis
    mem_display = user.membership_display(project) if project else None
1303 d4660e00 Giorgos Korfiatis
    can_join_req = can_join_request(project, user) if project else False
1304 d4660e00 Giorgos Korfiatis
    can_leave_req = can_leave_request(project, user) if project else False
1305 d4660e00 Giorgos Korfiatis
1306 c55e840a Sofia Papagiannaki
    return object_detail(
1307 c55e840a Sofia Papagiannaki
        request,
1308 c55e840a Sofia Papagiannaki
        queryset=ProjectApplication.objects.select_related(),
1309 ff67242a Giorgos Korfiatis
        object_id=application.id,
1310 c55e840a Sofia Papagiannaki
        template_name='im/projects/project_detail.html',
1311 c55e840a Sofia Papagiannaki
        extra_context={
1312 d4660e00 Giorgos Korfiatis
            'project_view': project_view,
1313 c55e840a Sofia Papagiannaki
            'addmembers_form':addmembers_form,
1314 624f5625 Kostas Papadimitriou
            'members_table': members_table,
1315 d4660e00 Giorgos Korfiatis
            'owner_mode': is_owner,
1316 8e1a5af5 Georgios D. Tsoukalas
            'admin_mode': is_project_admin,
1317 db9a498c Kostas Papadimitriou
            'modifications_table': modifications_table,
1318 d4660e00 Giorgos Korfiatis
            'mem_display': mem_display,
1319 d4660e00 Giorgos Korfiatis
            'can_join_request': can_join_req,
1320 d4660e00 Giorgos Korfiatis
            'can_leave_request': can_leave_req,
1321 2743e261 Kostas Papadimitriou
            })
1322 5550bcfb Kostas Papadimitriou
1323 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1324 e1a80257 Sofia Papagiannaki
@signed_terms_required
1325 e1a80257 Sofia Papagiannaki
@login_required
1326 e1a80257 Sofia Papagiannaki
def project_search(request):
1327 5550bcfb Kostas Papadimitriou
    q = request.GET.get('q', '')
1328 a5cef8d0 Kostas Papadimitriou
    form = ProjectSearchForm()
1329 a5cef8d0 Kostas Papadimitriou
    q = q.strip()
1330 48421603 Kostas Papadimitriou
1331 a5cef8d0 Kostas Papadimitriou
    if request.method == "POST":
1332 48421603 Kostas Papadimitriou
        form = ProjectSearchForm(request.POST)
1333 48421603 Kostas Papadimitriou
        if form.is_valid():
1334 48421603 Kostas Papadimitriou
            q = form.cleaned_data['q'].strip()
1335 48421603 Kostas Papadimitriou
        else:
1336 a5cef8d0 Kostas Papadimitriou
            q = None
1337 a5cef8d0 Kostas Papadimitriou
1338 a5cef8d0 Kostas Papadimitriou
    if q is None:
1339 a5cef8d0 Kostas Papadimitriou
        projects = ProjectApplication.objects.none()
1340 a5cef8d0 Kostas Papadimitriou
    else:
1341 324fb588 Sofia Papagiannaki
        accepted_projects = request.user.projectmembership_set.filter(
1342 324fb588 Sofia Papagiannaki
            ~Q(acceptance_date__isnull=True)).values_list('project', flat=True)
1343 a5cef8d0 Kostas Papadimitriou
        projects = ProjectApplication.objects.search_by_name(q)
1344 a5cef8d0 Kostas Papadimitriou
        projects = projects.filter(~Q(project__last_approval_date__isnull=True))
1345 324fb588 Sofia Papagiannaki
        projects = projects.exclude(project__in=accepted_projects)
1346 ca5148f2 Kostas Papadimitriou
1347 2743e261 Kostas Papadimitriou
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
1348 2743e261 Kostas Papadimitriou
                                                prefix="my_projects_")
1349 b87429e1 Olga Brani
    if request.method == "POST":
1350 b87429e1 Olga Brani
        table.caption = _('SEARCH RESULTS')
1351 b87429e1 Olga Brani
    else:
1352 b87429e1 Olga Brani
        table.caption = _('ALL PROJECTS')
1353 ca5148f2 Kostas Papadimitriou
1354 e6d284ef Olga Brani
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(table)
1355 48421603 Kostas Papadimitriou
1356 bfe23b13 Sofia Papagiannaki
    return object_list(
1357 bfe23b13 Sofia Papagiannaki
        request,
1358 a5cef8d0 Kostas Papadimitriou
        projects,
1359 6dadd24a Sofia Papagiannaki
        template_name='im/projects/project_list.html',
1360 a5cef8d0 Kostas Papadimitriou
        extra_context={
1361 a5cef8d0 Kostas Papadimitriou
          'form': form,
1362 a5cef8d0 Kostas Papadimitriou
          'is_search': True,
1363 a5cef8d0 Kostas Papadimitriou
          'q': q,
1364 a5cef8d0 Kostas Papadimitriou
          'table': table
1365 a5cef8d0 Kostas Papadimitriou
        })
1366 bfe23b13 Sofia Papagiannaki
1367 db9a498c Kostas Papadimitriou
@require_http_methods(["POST", "GET"])
1368 e1a80257 Sofia Papagiannaki
@signed_terms_required
1369 e1a80257 Sofia Papagiannaki
@login_required
1370 8cf9b2dd Giorgos Korfiatis
@project_transaction_context(sync=True)
1371 8cf9b2dd Giorgos Korfiatis
def project_join(request, chain_id, ctx=None):
1372 974ee6a6 Sofia Papagiannaki
    next = request.GET.get('next')
1373 73fbaec4 Sofia Papagiannaki
    if not next:
1374 f807da72 Kostas Papadimitriou
        next = reverse('astakos.im.views.project_detail',
1375 ff67242a Giorgos Korfiatis
                       args=(chain_id,))
1376 73fbaec4 Sofia Papagiannaki
1377 bfe23b13 Sofia Papagiannaki
    try:
1378 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1379 bb6a4465 Giorgos Korfiatis
        auto_accepted = join_project(chain_id, request.user)
1380 bb6a4465 Giorgos Korfiatis
        if auto_accepted:
1381 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_JOINED_PROJECT)
1382 bb6a4465 Giorgos Korfiatis
        else:
1383 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_JOIN_REQUEST_SUBMITTED)
1384 bb6a4465 Giorgos Korfiatis
        messages.success(request, m)
1385 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1386 bfe23b13 Sofia Papagiannaki
        messages.error(request, e)
1387 b8f05f8d Sofia Papagiannaki
    except BaseException, e:
1388 b8f05f8d Sofia Papagiannaki
        logger.exception(e)
1389 b8f05f8d Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1390 8cf9b2dd Giorgos Korfiatis
        if ctx:
1391 8cf9b2dd Giorgos Korfiatis
            ctx.mark_rollback()
1392 974ee6a6 Sofia Papagiannaki
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1393 73fbaec4 Sofia Papagiannaki
    return redirect(next)
1394 bfe23b13 Sofia Papagiannaki
1395 c8ed1ca1 Giorgos Korfiatis
@require_http_methods(["POST", "GET"])
1396 e1a80257 Sofia Papagiannaki
@signed_terms_required
1397 e1a80257 Sofia Papagiannaki
@login_required
1398 8cf9b2dd Giorgos Korfiatis
@project_transaction_context(sync=True)
1399 8cf9b2dd Giorgos Korfiatis
def project_leave(request, chain_id, ctx=None):
1400 974ee6a6 Sofia Papagiannaki
    next = request.GET.get('next')
1401 73fbaec4 Sofia Papagiannaki
    if not next:
1402 ed1999ad Kostas Papadimitriou
        next = reverse('astakos.im.views.project_list')
1403 e1a80257 Sofia Papagiannaki
1404 73fbaec4 Sofia Papagiannaki
    try:
1405 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1406 bb6a4465 Giorgos Korfiatis
        auto_accepted = leave_project(chain_id, request.user)
1407 bb6a4465 Giorgos Korfiatis
        if auto_accepted:
1408 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_LEFT_PROJECT)
1409 bb6a4465 Giorgos Korfiatis
        else:
1410 bb6a4465 Giorgos Korfiatis
            m = _(astakos_messages.USER_LEAVE_REQUEST_SUBMITTED)
1411 bb6a4465 Giorgos Korfiatis
        messages.success(request, m)
1412 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1413 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1414 8a8578c5 Giorgos Korfiatis
    except PendingMembershipError as e:
1415 8a8578c5 Giorgos Korfiatis
        raise RetryException()
1416 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1417 aad0e329 Giorgos Korfiatis
        logger.exception(e)
1418 aad0e329 Giorgos Korfiatis
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1419 8cf9b2dd Giorgos Korfiatis
        if ctx:
1420 8cf9b2dd Giorgos Korfiatis
            ctx.mark_rollback()
1421 aad0e329 Giorgos Korfiatis
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1422 aad0e329 Giorgos Korfiatis
    return redirect(next)
1423 aad0e329 Giorgos Korfiatis
1424 aad0e329 Giorgos Korfiatis
@require_http_methods(["POST"])
1425 aad0e329 Giorgos Korfiatis
@signed_terms_required
1426 aad0e329 Giorgos Korfiatis
@login_required
1427 8cf9b2dd Giorgos Korfiatis
@project_transaction_context()
1428 8cf9b2dd Giorgos Korfiatis
def project_cancel(request, chain_id, ctx=None):
1429 aad0e329 Giorgos Korfiatis
    next = request.GET.get('next')
1430 aad0e329 Giorgos Korfiatis
    if not next:
1431 aad0e329 Giorgos Korfiatis
        next = reverse('astakos.im.views.project_list')
1432 aad0e329 Giorgos Korfiatis
1433 aad0e329 Giorgos Korfiatis
    try:
1434 aad0e329 Giorgos Korfiatis
        chain_id = int(chain_id)
1435 aad0e329 Giorgos Korfiatis
        cancel_membership(chain_id, request.user)
1436 bb6a4465 Giorgos Korfiatis
        m = _(astakos_messages.USER_REQUEST_CANCELLED)
1437 bb6a4465 Giorgos Korfiatis
        messages.success(request, m)
1438 aad0e329 Giorgos Korfiatis
    except (IOError, PermissionDenied), e:
1439 aad0e329 Giorgos Korfiatis
        messages.error(request, e)
1440 8a8578c5 Giorgos Korfiatis
    except PendingMembershipError as e:
1441 8a8578c5 Giorgos Korfiatis
        raise RetryException()
1442 aad0e329 Giorgos Korfiatis
    except BaseException, e:
1443 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1444 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1445 8cf9b2dd Giorgos Korfiatis
        if ctx:
1446 8cf9b2dd Giorgos Korfiatis
            ctx.mark_rollback()
1447 f7cf5257 Kostas Papadimitriou
1448 974ee6a6 Sofia Papagiannaki
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1449 73fbaec4 Sofia Papagiannaki
    return redirect(next)
1450 bfe23b13 Sofia Papagiannaki
1451 16b22352 Kostas Papadimitriou
@require_http_methods(["POST"])
1452 e1a80257 Sofia Papagiannaki
@signed_terms_required
1453 e1a80257 Sofia Papagiannaki
@login_required
1454 8cf9b2dd Giorgos Korfiatis
@project_transaction_context(sync=True)
1455 8cf9b2dd Giorgos Korfiatis
def project_accept_member(request, chain_id, user_id, ctx=None):
1456 73fbaec4 Sofia Papagiannaki
    try:
1457 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1458 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1459 ff67242a Giorgos Korfiatis
        m = accept_membership(chain_id, user_id, request.user)
1460 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1461 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1462 8a8578c5 Giorgos Korfiatis
    except PendingMembershipError as e:
1463 8a8578c5 Giorgos Korfiatis
        raise RetryException()
1464 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1465 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1466 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1467 8cf9b2dd Giorgos Korfiatis
        if ctx:
1468 8cf9b2dd Giorgos Korfiatis
            ctx.mark_rollback()
1469 73fbaec4 Sofia Papagiannaki
    else:
1470 5cc7d5b3 Giorgos Korfiatis
        email = escape(m.person.email)
1471 5cc7d5b3 Giorgos Korfiatis
        msg = _(astakos_messages.USER_MEMBERSHIP_ACCEPTED) % email
1472 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1473 ff67242a Giorgos Korfiatis
    return redirect(reverse('project_detail', args=(chain_id,)))
1474 bfe23b13 Sofia Papagiannaki
1475 f3a45fc6 Kostas Papadimitriou
@require_http_methods(["POST"])
1476 bfe23b13 Sofia Papagiannaki
@signed_terms_required
1477 bfe23b13 Sofia Papagiannaki
@login_required
1478 8cf9b2dd Giorgos Korfiatis
@project_transaction_context(sync=True)
1479 8cf9b2dd Giorgos Korfiatis
def project_remove_member(request, chain_id, user_id, ctx=None):
1480 73fbaec4 Sofia Papagiannaki
    try:
1481 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1482 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1483 ff67242a Giorgos Korfiatis
        m = remove_membership(chain_id, user_id, request.user)
1484 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1485 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1486 8a8578c5 Giorgos Korfiatis
    except PendingMembershipError as e:
1487 8a8578c5 Giorgos Korfiatis
        raise RetryException()
1488 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1489 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1490 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1491 8cf9b2dd Giorgos Korfiatis
        if ctx:
1492 8cf9b2dd Giorgos Korfiatis
            ctx.mark_rollback()
1493 73fbaec4 Sofia Papagiannaki
    else:
1494 5cc7d5b3 Giorgos Korfiatis
        email = escape(m.person.email)
1495 5cc7d5b3 Giorgos Korfiatis
        msg = _(astakos_messages.USER_MEMBERSHIP_REMOVED) % email
1496 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1497 ff67242a Giorgos Korfiatis
    return redirect(reverse('project_detail', args=(chain_id,)))
1498 bfe23b13 Sofia Papagiannaki
1499 f3a45fc6 Kostas Papadimitriou
@require_http_methods(["POST"])
1500 e1a80257 Sofia Papagiannaki
@signed_terms_required
1501 e1a80257 Sofia Papagiannaki
@login_required
1502 8cf9b2dd Giorgos Korfiatis
@project_transaction_context()
1503 8cf9b2dd Giorgos Korfiatis
def project_reject_member(request, chain_id, user_id, ctx=None):
1504 73fbaec4 Sofia Papagiannaki
    try:
1505 ff67242a Giorgos Korfiatis
        chain_id = int(chain_id)
1506 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1507 ff67242a Giorgos Korfiatis
        m = reject_membership(chain_id, user_id, request.user)
1508 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1509 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1510 8a8578c5 Giorgos Korfiatis
    except PendingMembershipError as e:
1511 8a8578c5 Giorgos Korfiatis
        raise RetryException()
1512 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1513 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1514 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1515 8cf9b2dd Giorgos Korfiatis
        if ctx:
1516 8cf9b2dd Giorgos Korfiatis
            ctx.mark_rollback()
1517 73fbaec4 Sofia Papagiannaki
    else:
1518 5cc7d5b3 Giorgos Korfiatis
        email = escape(m.person.email)
1519 5cc7d5b3 Giorgos Korfiatis
        msg = _(astakos_messages.USER_MEMBERSHIP_REJECTED) % email
1520 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1521 ff67242a Giorgos Korfiatis
    return redirect(reverse('project_detail', args=(chain_id,)))
1522 c630fee6 Kostas Papadimitriou
1523 8e1a5af5 Georgios D. Tsoukalas
@require_http_methods(["POST", "GET"])
1524 8e1a5af5 Georgios D. Tsoukalas
@signed_terms_required
1525 8e1a5af5 Georgios D. Tsoukalas
@login_required
1526 8e1a5af5 Georgios D. Tsoukalas
@project_transaction_context(sync=True)
1527 8e1a5af5 Georgios D. Tsoukalas
def project_app_approve(request, application_id, ctx=None):
1528 8e1a5af5 Georgios D. Tsoukalas
1529 8e1a5af5 Georgios D. Tsoukalas
    if not request.user.is_project_admin():
1530 8e1a5af5 Georgios D. Tsoukalas
        m = _(astakos_messages.NOT_ALLOWED)
1531 8e1a5af5 Georgios D. Tsoukalas
        raise PermissionDenied(m)
1532 8e1a5af5 Georgios D. Tsoukalas
1533 8e1a5af5 Georgios D. Tsoukalas
    try:
1534 8e1a5af5 Georgios D. Tsoukalas
        app = ProjectApplication.objects.get(id=application_id)
1535 8e1a5af5 Georgios D. Tsoukalas
    except ProjectApplication.DoesNotExist:
1536 8e1a5af5 Georgios D. Tsoukalas
        raise Http404
1537 8e1a5af5 Georgios D. Tsoukalas
1538 8e1a5af5 Georgios D. Tsoukalas
    approve_application(application_id)
1539 8e1a5af5 Georgios D. Tsoukalas
    chain_id = get_related_project_id(application_id)
1540 8e1a5af5 Georgios D. Tsoukalas
    return redirect(reverse('project_detail', args=(chain_id,)))
1541 8e1a5af5 Georgios D. Tsoukalas
1542 8e1a5af5 Georgios D. Tsoukalas
@require_http_methods(["POST", "GET"])
1543 8e1a5af5 Georgios D. Tsoukalas
@signed_terms_required
1544 8e1a5af5 Georgios D. Tsoukalas
@login_required
1545 8e1a5af5 Georgios D. Tsoukalas
@project_transaction_context()
1546 8e1a5af5 Georgios D. Tsoukalas
def project_app_deny(request, application_id, ctx=None):
1547 8e1a5af5 Georgios D. Tsoukalas
1548 8e1a5af5 Georgios D. Tsoukalas
    if not request.user.is_project_admin():
1549 8e1a5af5 Georgios D. Tsoukalas
        m = _(astakos_messages.NOT_ALLOWED)
1550 8e1a5af5 Georgios D. Tsoukalas
        raise PermissionDenied(m)
1551 8e1a5af5 Georgios D. Tsoukalas
1552 8e1a5af5 Georgios D. Tsoukalas
    try:
1553 8e1a5af5 Georgios D. Tsoukalas
        app = ProjectApplication.objects.get(id=application_id)
1554 8e1a5af5 Georgios D. Tsoukalas
    except ProjectApplication.DoesNotExist:
1555 8e1a5af5 Georgios D. Tsoukalas
        raise Http404
1556 8e1a5af5 Georgios D. Tsoukalas
1557 8e1a5af5 Georgios D. Tsoukalas
    deny_application(application_id)
1558 8e1a5af5 Georgios D. Tsoukalas
    return redirect(reverse('project_list'))
1559 8e1a5af5 Georgios D. Tsoukalas
1560 8e1a5af5 Georgios D. Tsoukalas
@require_http_methods(["POST", "GET"])
1561 8e1a5af5 Georgios D. Tsoukalas
@signed_terms_required
1562 8e1a5af5 Georgios D. Tsoukalas
@login_required
1563 8e1a5af5 Georgios D. Tsoukalas
@project_transaction_context()
1564 8e1a5af5 Georgios D. Tsoukalas
def project_app_dismiss(request, application_id, ctx=None):
1565 8e1a5af5 Georgios D. Tsoukalas
    try:
1566 8e1a5af5 Georgios D. Tsoukalas
        app = ProjectApplication.objects.get(id=application_id)
1567 8e1a5af5 Georgios D. Tsoukalas
    except ProjectApplication.DoesNotExist:
1568 8e1a5af5 Georgios D. Tsoukalas
        raise Http404
1569 8e1a5af5 Georgios D. Tsoukalas
1570 8e1a5af5 Georgios D. Tsoukalas
    if not request.user.owns_application(app):
1571 8e1a5af5 Georgios D. Tsoukalas
        m = _(astakos_messages.NOT_ALLOWED)
1572 8e1a5af5 Georgios D. Tsoukalas
        raise PermissionDenied(m)
1573 8e1a5af5 Georgios D. Tsoukalas
1574 8e1a5af5 Georgios D. Tsoukalas
    # XXX: dismiss application also does authorization
1575 8e1a5af5 Georgios D. Tsoukalas
    dismiss_application(application_id, request_user=request.user)
1576 022cc8e2 Giorgos Korfiatis
1577 022cc8e2 Giorgos Korfiatis
    chain_id = None
1578 022cc8e2 Giorgos Korfiatis
    chain_id = get_related_project_id(application_id)
1579 022cc8e2 Giorgos Korfiatis
    if chain_id:
1580 022cc8e2 Giorgos Korfiatis
        next = reverse('project_detail', args=(chain_id,))
1581 022cc8e2 Giorgos Korfiatis
    else:
1582 022cc8e2 Giorgos Korfiatis
        next = reverse('project_list')
1583 022cc8e2 Giorgos Korfiatis
    return redirect(next)
1584 022cc8e2 Giorgos Korfiatis
1585 8e1a5af5 Georgios D. Tsoukalas
1586 003d8fcf Olga Brani
def landing(request):
1587 7549d16f Olga Brani
    services = get_services_dict()
1588 003d8fcf Olga Brani
    return render_response(
1589 003d8fcf Olga Brani
        'im/landing.html',
1590 7549d16f Olga Brani
        services = services,
1591 ff67242a Giorgos Korfiatis
        context_instance=get_context(request))
1592 b87429e1 Olga Brani
1593 b87429e1 Olga Brani
def api_access(request):
1594 b87429e1 Olga Brani
    return render_response(
1595 b87429e1 Olga Brani
        'im/api_access.html',
1596 ca5148f2 Kostas Papadimitriou
        context_instance=get_context(request))