Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (56.4 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 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
618 5ce3ce4f Sofia Papagiannaki
                           feedback_form=form,
619 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
620 5ce3ce4f Sofia Papagiannaki
621 15efc749 Sofia Papagiannaki
622 217994f8 Sofia Papagiannaki
@require_http_methods(["GET"])
623 8e45d6fd Sofia Papagiannaki
@signed_terms_required
624 aab4d540 Sofia Papagiannaki
def logout(request, template='registration/logged_out.html', extra_context=None):
625 63ecdd20 Sofia Papagiannaki
    """
626 b2ffa772 Sofia Papagiannaki
    Wraps `django.contrib.auth.logout`.
627 63ecdd20 Sofia Papagiannaki
    """
628 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
629 7482228b Sofia Papagiannaki
    response = HttpResponse()
630 8e45d6fd Sofia Papagiannaki
    if request.user.is_authenticated():
631 8e45d6fd Sofia Papagiannaki
        email = request.user.email
632 8e45d6fd Sofia Papagiannaki
        auth_logout(request)
633 c630fee6 Kostas Papadimitriou
    else:
634 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
635 c630fee6 Kostas Papadimitriou
        response.status_code = 301
636 c630fee6 Kostas Papadimitriou
        return response
637 c630fee6 Kostas Papadimitriou
638 217994f8 Sofia Papagiannaki
    next = restrict_next(
639 217994f8 Sofia Papagiannaki
        request.GET.get('next'),
640 217994f8 Sofia Papagiannaki
        domain=COOKIE_DOMAIN
641 217994f8 Sofia Papagiannaki
    )
642 c630fee6 Kostas Papadimitriou
643 63ecdd20 Sofia Papagiannaki
    if next:
644 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
645 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
646 0d02a287 Sofia Papagiannaki
    elif LOGOUT_NEXT:
647 0d02a287 Sofia Papagiannaki
        response['Location'] = LOGOUT_NEXT
648 0d02a287 Sofia Papagiannaki
        response.status_code = 301
649 b2ffa772 Sofia Papagiannaki
    else:
650 564a2292 Kostas Papadimitriou
        message = _(astakos_messages.LOGOUT_SUCCESS)
651 564a2292 Kostas Papadimitriou
        last_provider = request.COOKIES.get('astakos_last_login_method', None)
652 564a2292 Kostas Papadimitriou
        if last_provider:
653 564a2292 Kostas Papadimitriou
            provider = auth_providers.get_provider(last_provider)
654 564a2292 Kostas Papadimitriou
            extra_message = provider.get_logout_message_display
655 564a2292 Kostas Papadimitriou
            if extra_message:
656 564a2292 Kostas Papadimitriou
                message += '<br />' + extra_message
657 d21d422a Kostas Papadimitriou
        messages.success(request, message)
658 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
659 c630fee6 Kostas Papadimitriou
        response.status_code = 301
660 49df775e Sofia Papagiannaki
    return response
661 2126d85d Sofia Papagiannaki
662 5ce3ce4f Sofia Papagiannaki
663 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
664 683cf244 Sofia Papagiannaki
@transaction.commit_manually
665 3bb604eb Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt',
666 3bb604eb Sofia Papagiannaki
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
667 2126d85d Sofia Papagiannaki
    """
668 683cf244 Sofia Papagiannaki
    Activates the user identified by the ``auth`` request parameter, sends a welcome email
669 683cf244 Sofia Papagiannaki
    and renews the user token.
670 176023aa Kostas Papadimitriou

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