Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 304acb60

History | View | Annotate | Download (29.1 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 176023aa Kostas Papadimitriou
#
3 64cd4730 Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 64cd4730 Antony Chazapis
# without modification, are permitted provided that the following
5 64cd4730 Antony Chazapis
# conditions are met:
6 176023aa Kostas Papadimitriou
#
7 64cd4730 Antony Chazapis
#   1. Redistributions of source code must retain the above
8 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
9 64cd4730 Antony Chazapis
#      disclaimer.
10 176023aa Kostas Papadimitriou
#
11 64cd4730 Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
13 64cd4730 Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 64cd4730 Antony Chazapis
#      provided with the distribution.
15 176023aa Kostas Papadimitriou
#
16 64cd4730 Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 64cd4730 Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 64cd4730 Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 64cd4730 Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 64cd4730 Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 64cd4730 Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 64cd4730 Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 64cd4730 Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 64cd4730 Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 64cd4730 Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 64cd4730 Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 64cd4730 Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 176023aa Kostas Papadimitriou
#
29 64cd4730 Antony Chazapis
# The views and conclusions contained in the software and
30 64cd4730 Antony Chazapis
# documentation are those of the authors and should not be
31 64cd4730 Antony Chazapis
# interpreted as representing official policies, either expressed
32 64cd4730 Antony Chazapis
# or implied, of GRNET S.A.
33 64cd4730 Antony Chazapis
34 64cd4730 Antony Chazapis
import logging
35 64cd4730 Antony Chazapis
import socket
36 64cd4730 Antony Chazapis
37 64cd4730 Antony Chazapis
from smtplib import SMTPException
38 0905ccd2 Sofia Papagiannaki
from urllib import quote
39 63ecdd20 Sofia Papagiannaki
from functools import wraps
40 64cd4730 Antony Chazapis
41 890b0eaf Sofia Papagiannaki
from django.contrib import messages
42 01ac12d5 Sofia Papagiannaki
from django.contrib.auth.decorators import login_required
43 270dd48d Sofia Papagiannaki
from django.contrib.auth.views import password_change
44 27e26a41 Sofia Papagiannaki
from django.core.exceptions import ValidationError
45 01ac12d5 Sofia Papagiannaki
from django.core.mail import send_mail
46 01ac12d5 Sofia Papagiannaki
from django.core.urlresolvers import reverse
47 01ac12d5 Sofia Papagiannaki
from django.db import transaction
48 d1757ca7 Sofia Papagiannaki
from django.db.models import Q
49 01ac12d5 Sofia Papagiannaki
from django.db.utils import IntegrityError
50 01ac12d5 Sofia Papagiannaki
from django.forms.fields import URLField
51 01ac12d5 Sofia Papagiannaki
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, \
52 01ac12d5 Sofia Papagiannaki
    HttpResponseRedirect, HttpResponseBadRequest
53 01ac12d5 Sofia Papagiannaki
from django.shortcuts import redirect
54 01ac12d5 Sofia Papagiannaki
from django.template.loader import render_to_string
55 01ac12d5 Sofia Papagiannaki
from django.utils.http import urlencode
56 01ac12d5 Sofia Papagiannaki
from django.utils.translation import ugettext as _
57 8e45d6fd Sofia Papagiannaki
from django.views.generic.create_update import *
58 8e45d6fd Sofia Papagiannaki
from django.views.generic.list_detail import *
59 64cd4730 Antony Chazapis
60 8e45d6fd Sofia Papagiannaki
from astakos.im.models import AstakosUser, Invitation, ApprovalTerms, AstakosGroup
61 4e30244e Sofia Papagiannaki
from astakos.im.activation_backends import get_backend, SimpleBackend
62 1662ac2d Sofia Papagiannaki
from astakos.im.util import get_context, prepare_response, set_cookie, get_query
63 15efc749 Sofia Papagiannaki
from astakos.im.forms import *
64 111f3da6 Sofia Papagiannaki
from astakos.im.functions import send_greeting, send_feedback, SendMailError, \
65 23b9b72f Sofia Papagiannaki
    invite as invite_func, logout as auth_logout, activate as activate_func, switch_account_to_shibboleth
66 b669d9c0 Sofia Papagiannaki
from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, COOKIE_NAME, COOKIE_DOMAIN, IM_MODULES, SITENAME, LOGOUT_NEXT, LOGGING_LEVEL
67 64cd4730 Antony Chazapis
68 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
69 e015e9e6 Sofia Papagiannaki
70 c301698f Sofia Papagiannaki
def render_response(template, tab=None, status=200, reset_cookie=False, context_instance=None, **kwargs):
71 890b0eaf Sofia Papagiannaki
    """
72 890b0eaf Sofia Papagiannaki
    Calls ``django.template.loader.render_to_string`` with an additional ``tab``
73 890b0eaf Sofia Papagiannaki
    keyword argument and returns an ``django.http.HttpResponse`` with the
74 890b0eaf Sofia Papagiannaki
    specified ``status``.
75 890b0eaf Sofia Papagiannaki
    """
76 64cd4730 Antony Chazapis
    if tab is None:
77 881c856c Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
78 64cd4730 Antony Chazapis
    kwargs.setdefault('tab', tab)
79 0905ccd2 Sofia Papagiannaki
    html = render_to_string(template, kwargs, context_instance=context_instance)
80 c301698f Sofia Papagiannaki
    response = HttpResponse(html, status=status)
81 c301698f Sofia Papagiannaki
    if reset_cookie:
82 c301698f Sofia Papagiannaki
        set_cookie(response, context_instance['request'].user)
83 c301698f Sofia Papagiannaki
    return response
84 64cd4730 Antony Chazapis
85 63ecdd20 Sofia Papagiannaki
86 63ecdd20 Sofia Papagiannaki
def requires_anonymous(func):
87 63ecdd20 Sofia Papagiannaki
    """
88 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is not Anonymous and in that case
89 7482228b Sofia Papagiannaki
    redirects to `logout`.
90 63ecdd20 Sofia Papagiannaki
    """
91 63ecdd20 Sofia Papagiannaki
    @wraps(func)
92 63ecdd20 Sofia Papagiannaki
    def wrapper(request, *args):
93 63ecdd20 Sofia Papagiannaki
        if not request.user.is_anonymous():
94 63ecdd20 Sofia Papagiannaki
            next = urlencode({'next': request.build_absolute_uri()})
95 270dd48d Sofia Papagiannaki
            logout_uri = reverse(logout) + '?' + next
96 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(logout_uri)
97 63ecdd20 Sofia Papagiannaki
        return func(request, *args)
98 63ecdd20 Sofia Papagiannaki
    return wrapper
99 63ecdd20 Sofia Papagiannaki
100 270dd48d Sofia Papagiannaki
def signed_terms_required(func):
101 270dd48d Sofia Papagiannaki
    """
102 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is Anonymous and in that case
103 270dd48d Sofia Papagiannaki
    redirects to `logout`.
104 270dd48d Sofia Papagiannaki
    """
105 270dd48d Sofia Papagiannaki
    @wraps(func)
106 270dd48d Sofia Papagiannaki
    def wrapper(request, *args, **kwargs):
107 1662ac2d Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms():
108 270dd48d Sofia Papagiannaki
            params = urlencode({'next': request.build_absolute_uri(),
109 270dd48d Sofia Papagiannaki
                              'show_form':''})
110 270dd48d Sofia Papagiannaki
            terms_uri = reverse('latest_terms') + '?' + params
111 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(terms_uri)
112 270dd48d Sofia Papagiannaki
        return func(request, *args, **kwargs)
113 270dd48d Sofia Papagiannaki
    return wrapper
114 270dd48d Sofia Papagiannaki
115 270dd48d Sofia Papagiannaki
@signed_terms_required
116 1e685275 Sofia Papagiannaki
def index(request, login_template_name='im/login.html', profile_template_name='im/profile.html', extra_context={}):
117 890b0eaf Sofia Papagiannaki
    """
118 dcf55476 Sofia Papagiannaki
    If there is logged on user renders the profile page otherwise renders login page.
119 176023aa Kostas Papadimitriou

120 890b0eaf Sofia Papagiannaki
    **Arguments**
121 176023aa Kostas Papadimitriou

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

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

130 890b0eaf Sofia Papagiannaki
    ``extra_context``
131 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
132 176023aa Kostas Papadimitriou

133 890b0eaf Sofia Papagiannaki
    **Template:**
134 176023aa Kostas Papadimitriou

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

137 890b0eaf Sofia Papagiannaki
    """
138 dcf55476 Sofia Papagiannaki
    template_name = login_template_name
139 dcf55476 Sofia Papagiannaki
    if request.user.is_authenticated():
140 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('edit_profile'))
141 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
142 672d445a Sofia Papagiannaki
                           login_form = LoginForm(request=request),
143 0905ccd2 Sofia Papagiannaki
                           context_instance = get_context(request, extra_context))
144 64cd4730 Antony Chazapis
145 890b0eaf Sofia Papagiannaki
@login_required
146 270dd48d Sofia Papagiannaki
@signed_terms_required
147 890b0eaf Sofia Papagiannaki
@transaction.commit_manually
148 1e685275 Sofia Papagiannaki
def invite(request, template_name='im/invitations.html', extra_context={}):
149 890b0eaf Sofia Papagiannaki
    """
150 890b0eaf Sofia Papagiannaki
    Allows a user to invite somebody else.
151 176023aa Kostas Papadimitriou

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

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

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

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

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

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

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

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

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

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

178 890b0eaf Sofia Papagiannaki
    * LOGIN_URL: login uri
179 2cbaacd5 Sofia Papagiannaki
    * ASTAKOS_DEFAULT_CONTACT_EMAIL: service support email
180 2cbaacd5 Sofia Papagiannaki
    * ASTAKOS_DEFAULT_FROM_EMAIL: from email
181 890b0eaf Sofia Papagiannaki
    """
182 64cd4730 Antony Chazapis
    status = None
183 64cd4730 Antony Chazapis
    message = None
184 8f5a3a06 Sofia Papagiannaki
    form = InvitationForm()
185 5ed6816e Sofia Papagiannaki
    
186 18ffbee1 Sofia Papagiannaki
    inviter = request.user
187 64cd4730 Antony Chazapis
    if request.method == 'POST':
188 8f5a3a06 Sofia Papagiannaki
        form = InvitationForm(request.POST)
189 64cd4730 Antony Chazapis
        if inviter.invitations > 0:
190 8f5a3a06 Sofia Papagiannaki
            if form.is_valid():
191 8f5a3a06 Sofia Papagiannaki
                try:
192 8f5a3a06 Sofia Papagiannaki
                    invitation = form.save()
193 8f5a3a06 Sofia Papagiannaki
                    invite_func(invitation, inviter)
194 8f5a3a06 Sofia Papagiannaki
                    message = _('Invitation sent to %s' % invitation.username)
195 24406ae3 Sofia Papagiannaki
                    messages.success(request, message)
196 8f5a3a06 Sofia Papagiannaki
                except SendMailError, e:
197 8f5a3a06 Sofia Papagiannaki
                    message = e.message
198 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
199 8f5a3a06 Sofia Papagiannaki
                    transaction.rollback()
200 18ffbee1 Sofia Papagiannaki
                except BaseException, e:
201 18ffbee1 Sofia Papagiannaki
                    message = _('Something went wrong.')
202 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
203 18ffbee1 Sofia Papagiannaki
                    logger.exception(e)
204 18ffbee1 Sofia Papagiannaki
                    transaction.rollback()
205 18ffbee1 Sofia Papagiannaki
                else:
206 18ffbee1 Sofia Papagiannaki
                    transaction.commit()
207 64cd4730 Antony Chazapis
        else:
208 64cd4730 Antony Chazapis
            message = _('No invitations left')
209 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
210 176023aa Kostas Papadimitriou
211 a196eb7e Sofia Papagiannaki
    sent = [{'email': inv.username,
212 d6ae71a2 root
             'realname': inv.realname,
213 d6ae71a2 root
             'is_consumed': inv.is_consumed}
214 18ffbee1 Sofia Papagiannaki
             for inv in request.user.invitations_sent.all()]
215 77e2ad52 root
    kwargs = {'inviter': inviter,
216 a196eb7e Sofia Papagiannaki
              'sent':sent}
217 0905ccd2 Sofia Papagiannaki
    context = get_context(request, extra_context, **kwargs)
218 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
219 8f5a3a06 Sofia Papagiannaki
                           invitation_form = form,
220 0905ccd2 Sofia Papagiannaki
                           context_instance = context)
221 64cd4730 Antony Chazapis
222 890b0eaf Sofia Papagiannaki
@login_required
223 270dd48d Sofia Papagiannaki
@signed_terms_required
224 1e685275 Sofia Papagiannaki
def edit_profile(request, template_name='im/profile.html', extra_context={}):
225 890b0eaf Sofia Papagiannaki
    """
226 890b0eaf Sofia Papagiannaki
    Allows a user to edit his/her profile.
227 176023aa Kostas Papadimitriou

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

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

234 890b0eaf Sofia Papagiannaki
    **Arguments**
235 176023aa Kostas Papadimitriou

236 890b0eaf Sofia Papagiannaki
    ``template_name``
237 890b0eaf Sofia Papagiannaki
        A custom 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 ``template_name`` keyword argument.
246 176023aa Kostas Papadimitriou

247 92defad4 Sofia Papagiannaki
    **Settings:**
248 176023aa Kostas Papadimitriou

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

251 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
252 890b0eaf Sofia Papagiannaki
    """
253 15efc749 Sofia Papagiannaki
    form = ProfileForm(instance=request.user)
254 15efc749 Sofia Papagiannaki
    extra_context['next'] = request.GET.get('next')
255 c301698f Sofia Papagiannaki
    reset_cookie = False
256 64cd4730 Antony Chazapis
    if request.method == 'POST':
257 15efc749 Sofia Papagiannaki
        form = ProfileForm(request.POST, instance=request.user)
258 890b0eaf Sofia Papagiannaki
        if form.is_valid():
259 64cd4730 Antony Chazapis
            try:
260 c301698f Sofia Papagiannaki
                prev_token = request.user.auth_token
261 c301698f Sofia Papagiannaki
                user = form.save()
262 c301698f Sofia Papagiannaki
                reset_cookie = user.auth_token != prev_token
263 c301698f Sofia Papagiannaki
                form = ProfileForm(instance=user)
264 1a3675a0 Sofia Papagiannaki
                next = request.POST.get('next')
265 1a3675a0 Sofia Papagiannaki
                if next:
266 1a3675a0 Sofia Papagiannaki
                    return redirect(next)
267 890b0eaf Sofia Papagiannaki
                msg = _('Profile has been updated successfully')
268 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
269 890b0eaf Sofia Papagiannaki
            except ValueError, ve:
270 24406ae3 Sofia Papagiannaki
                messages.success(request, ve)
271 23447441 Sofia Papagiannaki
    elif request.method == "GET":
272 304acb60 Olga Brani
        if not request.user.is_verified:
273 304acb60 Olga Brani
            request.user.is_verified = True
274 304acb60 Olga Brani
            request.user.save()
275 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
276 c301698f Sofia Papagiannaki
                           reset_cookie = reset_cookie,
277 8f5a3a06 Sofia Papagiannaki
                           profile_form = form,
278 0905ccd2 Sofia Papagiannaki
                           context_instance = get_context(request,
279 c301698f Sofia Papagiannaki
                                                          extra_context))
280 64cd4730 Antony Chazapis
281 8f5a3a06 Sofia Papagiannaki
def signup(request, template_name='im/signup.html', on_success='im/signup_complete.html', extra_context={}, backend=None):
282 890b0eaf Sofia Papagiannaki
    """
283 890b0eaf Sofia Papagiannaki
    Allows a user to create a local account.
284 176023aa Kostas Papadimitriou

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

288 890b0eaf Sofia Papagiannaki
    The user activation will be delegated to the backend specified by the ``backend`` keyword argument
289 8f5a3a06 Sofia Papagiannaki
    if present, otherwise to the ``astakos.im.activation_backends.InvitationBackend``
290 8f5a3a06 Sofia Papagiannaki
    if settings.ASTAKOS_INVITATIONS_ENABLED is True or ``astakos.im.activation_backends.SimpleBackend`` if not
291 8f5a3a06 Sofia Papagiannaki
    (see activation_backends);
292 890b0eaf Sofia Papagiannaki
    
293 b669d9c0 Sofia Papagiannaki
    Upon successful user creation, if ``next`` url parameter is present the user is redirected there
294 890b0eaf Sofia Papagiannaki
    otherwise renders the same page with a success message.
295 64cd4730 Antony Chazapis
    
296 8f5a3a06 Sofia Papagiannaki
    On unsuccessful creation, renders ``template_name`` with an error message.
297 890b0eaf Sofia Papagiannaki
    
298 890b0eaf Sofia Papagiannaki
    **Arguments**
299 890b0eaf Sofia Papagiannaki
    
300 8f5a3a06 Sofia Papagiannaki
    ``template_name``
301 8f5a3a06 Sofia Papagiannaki
        A custom template to render. This is optional;
302 1e685275 Sofia Papagiannaki
        if not specified, this will default to ``im/signup.html``.
303 176023aa Kostas Papadimitriou

304 f7e8a159 Sofia Papagiannaki
    ``on_success``
305 f7e8a159 Sofia Papagiannaki
        A custom template to render in case of success. This is optional;
306 1e685275 Sofia Papagiannaki
        if not specified, this will default to ``im/signup_complete.html``.
307 176023aa Kostas Papadimitriou

308 890b0eaf Sofia Papagiannaki
    ``extra_context``
309 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
310 176023aa Kostas Papadimitriou

311 890b0eaf Sofia Papagiannaki
    **Template:**
312 890b0eaf Sofia Papagiannaki
    
313 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
314 1e685275 Sofia Papagiannaki
    im/signup_complete.html or ``on_success`` keyword argument. 
315 890b0eaf Sofia Papagiannaki
    """
316 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
317 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('edit_profile'))
318 4e30244e Sofia Papagiannaki
    
319 0a569195 Sofia Papagiannaki
    provider = get_query(request).get('provider', 'local')
320 890b0eaf Sofia Papagiannaki
    try:
321 18ffbee1 Sofia Papagiannaki
        if not backend:
322 18ffbee1 Sofia Papagiannaki
            backend = get_backend(request)
323 8f5a3a06 Sofia Papagiannaki
        form = backend.get_signup_form(provider)
324 0a569195 Sofia Papagiannaki
    except Exception, e:
325 4e30244e Sofia Papagiannaki
        form = SimpleBackend(request).get_signup_form(provider)
326 24406ae3 Sofia Papagiannaki
        messages.error(request, e)
327 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
328 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
329 18ffbee1 Sofia Papagiannaki
            user = form.save(commit=False)
330 8f5a3a06 Sofia Papagiannaki
            try:
331 8f5a3a06 Sofia Papagiannaki
                result = backend.handle_activation(user)
332 8f5a3a06 Sofia Papagiannaki
                status = messages.SUCCESS
333 18ffbee1 Sofia Papagiannaki
                message = result.message
334 18ffbee1 Sofia Papagiannaki
                user.save()
335 ca828a10 Sofia Papagiannaki
                if 'additional_email' in form.cleaned_data:
336 ca828a10 Sofia Papagiannaki
                    additional_email = form.cleaned_data['additional_email']
337 ca828a10 Sofia Papagiannaki
                    if additional_email != user.email:
338 ca828a10 Sofia Papagiannaki
                        user.additionalmail_set.create(email=additional_email)
339 b669d9c0 Sofia Papagiannaki
                        msg = 'Additional email: %s saved for user %s.' % (additional_email, user.email)
340 b669d9c0 Sofia Papagiannaki
                        logger._log(LOGGING_LEVEL, msg, [])
341 8f5a3a06 Sofia Papagiannaki
                if user and user.is_active:
342 8f5a3a06 Sofia Papagiannaki
                    next = request.POST.get('next', '')
343 8f5a3a06 Sofia Papagiannaki
                    return prepare_response(request, user, next=next)
344 8f5a3a06 Sofia Papagiannaki
                messages.add_message(request, status, message)
345 8f5a3a06 Sofia Papagiannaki
                return render_response(on_success,
346 8f5a3a06 Sofia Papagiannaki
                                       context_instance=get_context(request, extra_context))
347 18ffbee1 Sofia Papagiannaki
            except SendMailError, e:
348 18ffbee1 Sofia Papagiannaki
                message = e.message
349 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
350 18ffbee1 Sofia Papagiannaki
            except BaseException, e:
351 18ffbee1 Sofia Papagiannaki
                message = _('Something went wrong.')
352 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
353 0a569195 Sofia Papagiannaki
                logger.exception(e)
354 8f5a3a06 Sofia Papagiannaki
    return render_response(template_name,
355 18ffbee1 Sofia Papagiannaki
                           signup_form = form,
356 0a569195 Sofia Papagiannaki
                           provider = provider,
357 890b0eaf Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
358 64cd4730 Antony Chazapis
359 890b0eaf Sofia Papagiannaki
@login_required
360 270dd48d Sofia Papagiannaki
@signed_terms_required
361 8f5a3a06 Sofia Papagiannaki
def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context={}):
362 890b0eaf Sofia Papagiannaki
    """
363 890b0eaf Sofia Papagiannaki
    Allows a user to send feedback.
364 176023aa Kostas Papadimitriou

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

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

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

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

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

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

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

383 890b0eaf Sofia Papagiannaki
    **Settings:**
384 176023aa Kostas Papadimitriou

385 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
386 2cbaacd5 Sofia Papagiannaki
    * ASTAKOS_DEFAULT_CONTACT_EMAIL: List of feedback recipients
387 890b0eaf Sofia Papagiannaki
    """
388 64cd4730 Antony Chazapis
    if request.method == 'GET':
389 890b0eaf Sofia Papagiannaki
        form = FeedbackForm()
390 890b0eaf Sofia Papagiannaki
    if request.method == 'POST':
391 890b0eaf Sofia Papagiannaki
        if not request.user:
392 890b0eaf Sofia Papagiannaki
            return HttpResponse('Unauthorized', status=401)
393 176023aa Kostas Papadimitriou
394 890b0eaf Sofia Papagiannaki
        form = FeedbackForm(request.POST)
395 890b0eaf Sofia Papagiannaki
        if form.is_valid():
396 e9083112 Sofia Papagiannaki
            msg = form.cleaned_data['feedback_msg']
397 8f5a3a06 Sofia Papagiannaki
            data = form.cleaned_data['feedback_data']
398 538ccdd5 Sofia Papagiannaki
            try:
399 8f5a3a06 Sofia Papagiannaki
                send_feedback(msg, data, request.user, email_template_name)
400 8f5a3a06 Sofia Papagiannaki
            except SendMailError, e:
401 8f5a3a06 Sofia Papagiannaki
                status = messages.ERROR
402 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
403 8f5a3a06 Sofia Papagiannaki
            else:
404 538ccdd5 Sofia Papagiannaki
                message = _('Feedback successfully sent')
405 24406ae3 Sofia Papagiannaki
                messages.succeess(request, message)
406 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
407 8f5a3a06 Sofia Papagiannaki
                           feedback_form = form,
408 6b4f9fb2 Sofia Papagiannaki
                           context_instance = get_context(request, extra_context))
409 15efc749 Sofia Papagiannaki
410 8e45d6fd Sofia Papagiannaki
@signed_terms_required
411 7482228b Sofia Papagiannaki
def logout(request, template='registration/logged_out.html', extra_context={}):
412 63ecdd20 Sofia Papagiannaki
    """
413 7482228b Sofia Papagiannaki
    Wraps `django.contrib.auth.logout` and delete the cookie.
414 63ecdd20 Sofia Papagiannaki
    """
415 7482228b Sofia Papagiannaki
    response = HttpResponse()
416 8e45d6fd Sofia Papagiannaki
    if request.user.is_authenticated():
417 8e45d6fd Sofia Papagiannaki
        email = request.user.email
418 8e45d6fd Sofia Papagiannaki
        auth_logout(request)
419 8e45d6fd Sofia Papagiannaki
        response.delete_cookie(COOKIE_NAME, path='/', domain=COOKIE_DOMAIN)
420 8e45d6fd Sofia Papagiannaki
        msg = 'Cookie deleted for %s' % email
421 8e45d6fd Sofia Papagiannaki
        logger._log(LOGGING_LEVEL, msg, [])
422 63ecdd20 Sofia Papagiannaki
    next = request.GET.get('next')
423 63ecdd20 Sofia Papagiannaki
    if next:
424 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
425 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
426 63ecdd20 Sofia Papagiannaki
        return response
427 0d02a287 Sofia Papagiannaki
    elif LOGOUT_NEXT:
428 0d02a287 Sofia Papagiannaki
        response['Location'] = LOGOUT_NEXT
429 0d02a287 Sofia Papagiannaki
        response.status_code = 301
430 0d02a287 Sofia Papagiannaki
        return response
431 24406ae3 Sofia Papagiannaki
    messages.success(request, _('You have successfully logged out.'))
432 49df775e Sofia Papagiannaki
    context = get_context(request, extra_context)
433 49df775e Sofia Papagiannaki
    response.write(render_to_string(template, context_instance=context))
434 49df775e Sofia Papagiannaki
    return response
435 2126d85d Sofia Papagiannaki
436 683cf244 Sofia Papagiannaki
@transaction.commit_manually
437 3e295388 Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt', helpdesk_email_template_name='im/helpdesk_notification.txt'):
438 2126d85d Sofia Papagiannaki
    """
439 683cf244 Sofia Papagiannaki
    Activates the user identified by the ``auth`` request parameter, sends a welcome email
440 683cf244 Sofia Papagiannaki
    and renews the user token.
441 176023aa Kostas Papadimitriou

442 683cf244 Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the user state will be updated
443 683cf244 Sofia Papagiannaki
    only if the email will be send successfully.
444 2126d85d Sofia Papagiannaki
    """
445 2126d85d Sofia Papagiannaki
    token = request.GET.get('auth')
446 2126d85d Sofia Papagiannaki
    next = request.GET.get('next')
447 2126d85d Sofia Papagiannaki
    try:
448 2126d85d Sofia Papagiannaki
        user = AstakosUser.objects.get(auth_token=token)
449 2126d85d Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
450 683cf244 Sofia Papagiannaki
        return HttpResponseBadRequest(_('No such user'))
451 0a569195 Sofia Papagiannaki
    
452 d1757ca7 Sofia Papagiannaki
    if user.is_active:
453 23b9b72f Sofia Papagiannaki
        message = _('Account already active.')
454 24406ae3 Sofia Papagiannaki
        messages.error(request, message)
455 23b9b72f Sofia Papagiannaki
        return index(request)
456 8e45d6fd Sofia Papagiannaki
        
457 0a569195 Sofia Papagiannaki
    try:
458 d1757ca7 Sofia Papagiannaki
        local_user = AstakosUser.objects.get(~Q(id = user.id), email=user.email, is_active=True)
459 0a569195 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
460 27e26a41 Sofia Papagiannaki
        try:
461 3e295388 Sofia Papagiannaki
            activate_func(user, greeting_email_template_name, helpdesk_email_template_name, verify_email=True)
462 23b9b72f Sofia Papagiannaki
            response = prepare_response(request, user, next, renew=True)
463 23b9b72f Sofia Papagiannaki
            transaction.commit()
464 23b9b72f Sofia Papagiannaki
            return response
465 23b9b72f Sofia Papagiannaki
        except SendMailError, e:
466 23b9b72f Sofia Papagiannaki
            message = e.message
467 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
468 23b9b72f Sofia Papagiannaki
            transaction.rollback()
469 23b9b72f Sofia Papagiannaki
            return index(request)
470 23b9b72f Sofia Papagiannaki
        except BaseException, e:
471 23b9b72f Sofia Papagiannaki
            message = _('Something went wrong.')
472 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
473 23b9b72f Sofia Papagiannaki
            logger.exception(e)
474 23b9b72f Sofia Papagiannaki
            transaction.rollback()
475 23b9b72f Sofia Papagiannaki
            return index(request)
476 0a569195 Sofia Papagiannaki
    else:
477 23b9b72f Sofia Papagiannaki
        try:
478 3e295388 Sofia Papagiannaki
            user = switch_account_to_shibboleth(user, local_user, greeting_email_template_name)
479 23b9b72f Sofia Papagiannaki
            response = prepare_response(request, user, next, renew=True)
480 23b9b72f Sofia Papagiannaki
            transaction.commit()
481 23b9b72f Sofia Papagiannaki
            return response
482 23b9b72f Sofia Papagiannaki
        except SendMailError, e:
483 23b9b72f Sofia Papagiannaki
            message = e.message
484 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
485 23b9b72f Sofia Papagiannaki
            transaction.rollback()
486 23b9b72f Sofia Papagiannaki
            return index(request)
487 23b9b72f Sofia Papagiannaki
        except BaseException, e:
488 23b9b72f Sofia Papagiannaki
            message = _('Something went wrong.')
489 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
490 23b9b72f Sofia Papagiannaki
            logger.exception(e)
491 23b9b72f Sofia Papagiannaki
            transaction.rollback()
492 23b9b72f Sofia Papagiannaki
            return index(request)
493 270dd48d Sofia Papagiannaki
494 270dd48d Sofia Papagiannaki
def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context={}):
495 270dd48d Sofia Papagiannaki
    term = None
496 270dd48d Sofia Papagiannaki
    terms = None
497 270dd48d Sofia Papagiannaki
    if not term_id:
498 270dd48d Sofia Papagiannaki
        try:
499 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
500 270dd48d Sofia Papagiannaki
        except IndexError:
501 270dd48d Sofia Papagiannaki
            pass
502 270dd48d Sofia Papagiannaki
    else:
503 270dd48d Sofia Papagiannaki
        try:
504 270dd48d Sofia Papagiannaki
             term = ApprovalTerms.objects.get(id=term_id)
505 270dd48d Sofia Papagiannaki
        except ApprovalTermDoesNotExist, e:
506 270dd48d Sofia Papagiannaki
            pass
507 176023aa Kostas Papadimitriou
508 270dd48d Sofia Papagiannaki
    if not term:
509 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('index'))
510 270dd48d Sofia Papagiannaki
    f = open(term.location, 'r')
511 270dd48d Sofia Papagiannaki
    terms = f.read()
512 176023aa Kostas Papadimitriou
513 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
514 270dd48d Sofia Papagiannaki
        next = request.POST.get('next')
515 270dd48d Sofia Papagiannaki
        if not next:
516 6ff7a7ca Sofia Papagiannaki
            next = reverse('index')
517 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
518 270dd48d Sofia Papagiannaki
        if not form.is_valid():
519 270dd48d Sofia Papagiannaki
            return render_response(template_name,
520 270dd48d Sofia Papagiannaki
                           terms = terms,
521 8f5a3a06 Sofia Papagiannaki
                           approval_terms_form = form,
522 270dd48d Sofia Papagiannaki
                           context_instance = get_context(request, extra_context))
523 270dd48d Sofia Papagiannaki
        user = form.save()
524 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
525 270dd48d Sofia Papagiannaki
    else:
526 586967c0 Sofia Papagiannaki
        form = None
527 1662ac2d Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms():
528 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
529 270dd48d Sofia Papagiannaki
        return render_response(template_name,
530 270dd48d Sofia Papagiannaki
                               terms = terms,
531 8f5a3a06 Sofia Papagiannaki
                               approval_terms_form = form,
532 270dd48d Sofia Papagiannaki
                               context_instance = get_context(request, extra_context))
533 270dd48d Sofia Papagiannaki
534 270dd48d Sofia Papagiannaki
@signed_terms_required
535 270dd48d Sofia Papagiannaki
def change_password(request):
536 1039bab1 Sofia Papagiannaki
    return password_change(request,
537 6ff7a7ca Sofia Papagiannaki
                            post_change_redirect=reverse('edit_profile'),
538 1039bab1 Sofia Papagiannaki
                            password_change_form=ExtendedPasswordChangeForm)
539 49790d9d Sofia Papagiannaki
540 8e45d6fd Sofia Papagiannaki
@signed_terms_required
541 8e45d6fd Sofia Papagiannaki
@login_required
542 49790d9d Sofia Papagiannaki
@transaction.commit_manually
543 49790d9d Sofia Papagiannaki
def change_email(request, activation_key=None,
544 49790d9d Sofia Papagiannaki
                 email_template_name='registration/email_change_email.txt',
545 49790d9d Sofia Papagiannaki
                 form_template_name='registration/email_change_form.html',
546 49790d9d Sofia Papagiannaki
                 confirm_template_name='registration/email_change_done.html',
547 49790d9d Sofia Papagiannaki
                 extra_context={}):
548 49790d9d Sofia Papagiannaki
    if activation_key:
549 49790d9d Sofia Papagiannaki
        try:
550 49790d9d Sofia Papagiannaki
            user = EmailChange.objects.change_email(activation_key)
551 49790d9d Sofia Papagiannaki
            if request.user.is_authenticated() and request.user == user:
552 49790d9d Sofia Papagiannaki
                msg = _('Email changed successfully.')
553 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
554 49790d9d Sofia Papagiannaki
                auth_logout(request)
555 49790d9d Sofia Papagiannaki
                response = prepare_response(request, user)
556 49790d9d Sofia Papagiannaki
                transaction.commit()
557 49790d9d Sofia Papagiannaki
                return response
558 49790d9d Sofia Papagiannaki
        except ValueError, e:
559 24406ae3 Sofia Papagiannaki
            messages.error(request, e)
560 49790d9d Sofia Papagiannaki
        return render_response(confirm_template_name,
561 49790d9d Sofia Papagiannaki
                               modified_user = user if 'user' in locals() else None,
562 49790d9d Sofia Papagiannaki
                               context_instance = get_context(request,
563 49790d9d Sofia Papagiannaki
                                                              extra_context))
564 49790d9d Sofia Papagiannaki
    
565 49790d9d Sofia Papagiannaki
    if not request.user.is_authenticated():
566 49790d9d Sofia Papagiannaki
        path = quote(request.get_full_path())
567 6ff7a7ca Sofia Papagiannaki
        url = request.build_absolute_uri(reverse('index'))
568 49790d9d Sofia Papagiannaki
        return HttpResponseRedirect(url + '?next=' + path)
569 49790d9d Sofia Papagiannaki
    form = EmailChangeForm(request.POST or None)
570 49790d9d Sofia Papagiannaki
    if request.method == 'POST' and form.is_valid():
571 49790d9d Sofia Papagiannaki
        try:
572 49790d9d Sofia Papagiannaki
            ec = form.save(email_template_name, request)
573 49790d9d Sofia Papagiannaki
        except SendMailError, e:
574 49790d9d Sofia Papagiannaki
            msg = e
575 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
576 49790d9d Sofia Papagiannaki
            transaction.rollback()
577 49790d9d Sofia Papagiannaki
        except IntegrityError, e:
578 49790d9d Sofia Papagiannaki
            msg = _('There is already a pending change email request.')
579 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
580 49790d9d Sofia Papagiannaki
        else:
581 49790d9d Sofia Papagiannaki
            msg = _('Change email request has been registered succefully.\
582 49790d9d Sofia Papagiannaki
                    You are going to receive a verification email in the new address.')
583 24406ae3 Sofia Papagiannaki
            messages.success(request, msg)
584 49790d9d Sofia Papagiannaki
            transaction.commit()
585 49790d9d Sofia Papagiannaki
    return render_response(form_template_name,
586 49790d9d Sofia Papagiannaki
                           form = form,
587 49790d9d Sofia Papagiannaki
                           context_instance = get_context(request,
588 8e45d6fd Sofia Papagiannaki
                                                          extra_context))
589 8e45d6fd Sofia Papagiannaki
590 8e45d6fd Sofia Papagiannaki
@signed_terms_required
591 01ac12d5 Sofia Papagiannaki
@login_required
592 8e45d6fd Sofia Papagiannaki
def group_add(request):
593 8e45d6fd Sofia Papagiannaki
    return create_object(request,
594 01ac12d5 Sofia Papagiannaki
                         form_class=get_astakos_group_creation_form(request),
595 01ac12d5 Sofia Papagiannaki
                         post_save_redirect = '/im/group/%(id)s/')
596 8e45d6fd Sofia Papagiannaki
597 8e45d6fd Sofia Papagiannaki
@signed_terms_required
598 8e45d6fd Sofia Papagiannaki
@login_required
599 ade90760 Sofia Papagiannaki
def group_list(request):
600 01ac12d5 Sofia Papagiannaki
    list = AstakosGroup.objects.filter(membership__person=request.user)
601 8e45d6fd Sofia Papagiannaki
    return object_list(request, queryset=list)
602 8e45d6fd Sofia Papagiannaki
603 8e45d6fd Sofia Papagiannaki
@signed_terms_required
604 8e45d6fd Sofia Papagiannaki
@login_required
605 8e45d6fd Sofia Papagiannaki
def group_detail(request, group_id):
606 8e45d6fd Sofia Papagiannaki
    try:
607 8e45d6fd Sofia Papagiannaki
        group = AstakosGroup.objects.select_related().get(id=group_id)
608 8e45d6fd Sofia Papagiannaki
    except AstakosGroup.DoesNotExist:
609 6ff7a7ca Sofia Papagiannaki
        return HttpResponseBadRequest(_('Invalid group.'))
610 8e45d6fd Sofia Papagiannaki
    return object_detail(request,
611 01ac12d5 Sofia Papagiannaki
                         AstakosGroup.objects.all(),
612 01ac12d5 Sofia Papagiannaki
                         object_id=group_id,
613 01ac12d5 Sofia Papagiannaki
                         extra_context = {'form':get_astakos_group_policy_creation_form(group),
614 ffb1e7a8 Sofia Papagiannaki
                                          'quota':group.quota,
615 01ac12d5 Sofia Papagiannaki
                                          'more_policies':group.has_undefined_policies})
616 8e45d6fd Sofia Papagiannaki
617 8e45d6fd Sofia Papagiannaki
@signed_terms_required
618 8e45d6fd Sofia Papagiannaki
@login_required
619 8e45d6fd Sofia Papagiannaki
def group_policies_list(request, group_id):
620 8e45d6fd Sofia Papagiannaki
    list = AstakosGroupQuota.objects.filter(group__id=group_id)
621 8e45d6fd Sofia Papagiannaki
    return object_list(request, queryset=list)
622 8e45d6fd Sofia Papagiannaki
623 8e45d6fd Sofia Papagiannaki
@signed_terms_required
624 01ac12d5 Sofia Papagiannaki
@login_required
625 8e45d6fd Sofia Papagiannaki
def group_policies_add(request, group_id):
626 8e45d6fd Sofia Papagiannaki
    try:
627 8e45d6fd Sofia Papagiannaki
        group = AstakosGroup.objects.select_related().get(id=group_id)
628 8e45d6fd Sofia Papagiannaki
    except AstakosGroup.DoesNotExist:
629 373daf6a Sofia Papagiannaki
        return HttpResponseBadRequest(_('Invalid group.'))
630 8e45d6fd Sofia Papagiannaki
    return create_object(request,
631 01ac12d5 Sofia Papagiannaki
                         form_class=get_astakos_group_policy_creation_form(group),
632 01ac12d5 Sofia Papagiannaki
                         template_name = 'im/astakosgroup_detail.html',
633 01ac12d5 Sofia Papagiannaki
                         post_save_redirect = reverse('group_detail', kwargs=dict(group_id=group_id)),
634 01ac12d5 Sofia Papagiannaki
                         extra_context = {'group':group,
635 ffb1e7a8 Sofia Papagiannaki
                                          'quota':group.quota,
636 01ac12d5 Sofia Papagiannaki
                                          'more_policies':group.has_undefined_policies})
637 8e45d6fd Sofia Papagiannaki
@signed_terms_required
638 8e45d6fd Sofia Papagiannaki
@login_required
639 8e45d6fd Sofia Papagiannaki
def group_approval_request(request, group_id):
640 8e45d6fd Sofia Papagiannaki
    return HttpResponse()
641 01ac12d5 Sofia Papagiannaki
642 01ac12d5 Sofia Papagiannaki
@signed_terms_required
643 01ac12d5 Sofia Papagiannaki
@login_required
644 304acb60 Olga Brani
def group_search(request, extra_context={}, **kwargs):
645 01ac12d5 Sofia Papagiannaki
    join_forms = {}
646 01ac12d5 Sofia Papagiannaki
    if request.method == 'GET':
647 01ac12d5 Sofia Papagiannaki
        form = AstakosGroupSearchForm()
648 01ac12d5 Sofia Papagiannaki
    else:
649 01ac12d5 Sofia Papagiannaki
        form = AstakosGroupSearchForm(get_query(request))
650 01ac12d5 Sofia Papagiannaki
        if form.is_valid():
651 01ac12d5 Sofia Papagiannaki
            q = form.cleaned_data['q'].strip()
652 01ac12d5 Sofia Papagiannaki
            q = URLField().to_python(q)
653 01ac12d5 Sofia Papagiannaki
            queryset = AstakosGroup.objects.select_related().filter(name=q)
654 01ac12d5 Sofia Papagiannaki
            f = MembershipCreationForm
655 01ac12d5 Sofia Papagiannaki
            for g in queryset:
656 01ac12d5 Sofia Papagiannaki
                join_forms[g.name] = f(dict(group=g,
657 01ac12d5 Sofia Papagiannaki
                                            person=request.user,
658 01ac12d5 Sofia Papagiannaki
                                            date_requested=datetime.now().strftime("%d/%m/%Y")))
659 304acb60 Olga Brani
            return object_list(request,
660 304acb60 Olga Brani
                                queryset,
661 304acb60 Olga Brani
                                template_name='im/astakosgroup_list.html',
662 304acb60 Olga Brani
                                extra_context=dict(form=form, is_search=True, join_forms=join_forms))
663 304acb60 Olga Brani
    return render_response(template='im/astakosgroup_list.html',
664 304acb60 Olga Brani
                            form = form,
665 304acb60 Olga Brani
                            context_instance=get_context(request))
666 01ac12d5 Sofia Papagiannaki
667 01ac12d5 Sofia Papagiannaki
@signed_terms_required
668 01ac12d5 Sofia Papagiannaki
@login_required
669 01ac12d5 Sofia Papagiannaki
def group_join(request, group_id):
670 01ac12d5 Sofia Papagiannaki
    return create_object(request,
671 01ac12d5 Sofia Papagiannaki
                         model=Membership,
672 01ac12d5 Sofia Papagiannaki
                         template_name='im/astakosgroup_list.html',
673 01ac12d5 Sofia Papagiannaki
                         post_save_redirect = reverse('group_detail', kwargs=dict(group_id=group_id)))
674 01ac12d5 Sofia Papagiannaki
675 01ac12d5 Sofia Papagiannaki
@signed_terms_required
676 01ac12d5 Sofia Papagiannaki
@login_required
677 01ac12d5 Sofia Papagiannaki
def group_leave(request, group_id):
678 01ac12d5 Sofia Papagiannaki
    try:
679 01ac12d5 Sofia Papagiannaki
        m = Membership.objects.select_related().get(group__id=group_id, person=request.user)
680 01ac12d5 Sofia Papagiannaki
    except Membership.DoesNotExist:
681 01ac12d5 Sofia Papagiannaki
        return HttpResponseBadRequest(_('Invalid membership.'))
682 01ac12d5 Sofia Papagiannaki
    if request.user in m.group.owner.all():
683 01ac12d5 Sofia Papagiannaki
        return HttpResponseForbidden(_('Owner can not leave the group.'))
684 01ac12d5 Sofia Papagiannaki
    return delete_object(request,
685 01ac12d5 Sofia Papagiannaki
                         model=Membership,
686 01ac12d5 Sofia Papagiannaki
                         object_id = m.id,
687 01ac12d5 Sofia Papagiannaki
                         template_name='im/astakosgroup_list.html',
688 01ac12d5 Sofia Papagiannaki
                         post_delete_redirect = reverse('group_detail', kwargs=dict(group_id=group_id)))
689 01ac12d5 Sofia Papagiannaki
690 01ac12d5 Sofia Papagiannaki
def handle_membership():
691 01ac12d5 Sofia Papagiannaki
    def decorator(func):
692 01ac12d5 Sofia Papagiannaki
        @wraps(func)
693 ffb1e7a8 Sofia Papagiannaki
        def wrapper(request, group_id, user_id):
694 01ac12d5 Sofia Papagiannaki
            try:
695 ffb1e7a8 Sofia Papagiannaki
                m = Membership.objects.select_related().get(group__id=group_id, person__id=user_id)
696 01ac12d5 Sofia Papagiannaki
            except Membership.DoesNotExist:
697 01ac12d5 Sofia Papagiannaki
                return HttpResponseBadRequest(_('Invalid membership.'))
698 01ac12d5 Sofia Papagiannaki
            else:
699 01ac12d5 Sofia Papagiannaki
                if request.user not in m.group.owner.all():
700 01ac12d5 Sofia Papagiannaki
                    return HttpResponseForbidden(_('User is not a group owner.'))
701 01ac12d5 Sofia Papagiannaki
                func(request, m)
702 01ac12d5 Sofia Papagiannaki
                return render_response(template='im/astakosgroup_detail.html',
703 01ac12d5 Sofia Papagiannaki
                                       context_instance=get_context(request),
704 01ac12d5 Sofia Papagiannaki
                                       object=m.group,
705 ffb1e7a8 Sofia Papagiannaki
                                       quota=m.group.quota,
706 01ac12d5 Sofia Papagiannaki
                                       more_policies=m.group.has_undefined_policies)
707 01ac12d5 Sofia Papagiannaki
        return wrapper
708 01ac12d5 Sofia Papagiannaki
    return decorator
709 01ac12d5 Sofia Papagiannaki
710 01ac12d5 Sofia Papagiannaki
@signed_terms_required
711 01ac12d5 Sofia Papagiannaki
@login_required
712 01ac12d5 Sofia Papagiannaki
@handle_membership()
713 01ac12d5 Sofia Papagiannaki
def approve_member(request, membership):
714 01ac12d5 Sofia Papagiannaki
    try:
715 01ac12d5 Sofia Papagiannaki
        membership.approve()
716 01ac12d5 Sofia Papagiannaki
        realname = membership.person.realname
717 01ac12d5 Sofia Papagiannaki
        msg = _('%s has been successfully joined the group.' % realname)
718 01ac12d5 Sofia Papagiannaki
        messages.success(request, msg)
719 01ac12d5 Sofia Papagiannaki
    except BaseException, e:
720 01ac12d5 Sofia Papagiannaki
        logger.exception(e)
721 01ac12d5 Sofia Papagiannaki
        msg = _('Something went wrong during %s\'s approval.' % realname)
722 01ac12d5 Sofia Papagiannaki
        messages.error(request, msg)
723 7cb372c7 Sofia Papagiannaki
    
724 01ac12d5 Sofia Papagiannaki
@signed_terms_required
725 01ac12d5 Sofia Papagiannaki
@login_required
726 01ac12d5 Sofia Papagiannaki
@handle_membership()
727 01ac12d5 Sofia Papagiannaki
def disapprove_member(request, membership):
728 01ac12d5 Sofia Papagiannaki
    try:
729 01ac12d5 Sofia Papagiannaki
        membership.disapprove()
730 01ac12d5 Sofia Papagiannaki
        realname = membership.person.realname
731 01ac12d5 Sofia Papagiannaki
        msg = _('%s has been successfully removed from the group.' % realname)
732 01ac12d5 Sofia Papagiannaki
        messages.success(request, msg)
733 01ac12d5 Sofia Papagiannaki
    except BaseException, e:
734 01ac12d5 Sofia Papagiannaki
        logger.exception(e)
735 01ac12d5 Sofia Papagiannaki
        msg = _('Something went wrong during %s\'s disapproval.' % realname)
736 01ac12d5 Sofia Papagiannaki
        messages.error(request, msg)
737 ffb1e7a8 Sofia Papagiannaki
738 ffb1e7a8 Sofia Papagiannaki
@signed_terms_required
739 ffb1e7a8 Sofia Papagiannaki
@login_required
740 ffb1e7a8 Sofia Papagiannaki
def resource_list(request):
741 ffb1e7a8 Sofia Papagiannaki
    return render_response(template='im/astakosuserquota_list.html',
742 ffb1e7a8 Sofia Papagiannaki
                           context_instance=get_context(request),
743 ffb1e7a8 Sofia Papagiannaki
                           quota=request.user.quota)