Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 672d445a

History | View | Annotate | Download (18.7 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 64cd4730 Antony Chazapis
from django.core.mail import send_mail
42 63ecdd20 Sofia Papagiannaki
from django.http import HttpResponse
43 64cd4730 Antony Chazapis
from django.shortcuts import redirect
44 64cd4730 Antony Chazapis
from django.template.loader import render_to_string
45 64cd4730 Antony Chazapis
from django.utils.translation import ugettext as _
46 64cd4730 Antony Chazapis
from django.core.urlresolvers import reverse
47 890b0eaf Sofia Papagiannaki
from django.contrib.auth.decorators import login_required
48 890b0eaf Sofia Papagiannaki
from django.contrib import messages
49 890b0eaf Sofia Papagiannaki
from django.db import transaction
50 7482228b Sofia Papagiannaki
from django.contrib.auth import logout as auth_logout
51 63ecdd20 Sofia Papagiannaki
from django.utils.http import urlencode
52 683cf244 Sofia Papagiannaki
from django.http import HttpResponseRedirect, HttpResponseBadRequest
53 8316698a Sofia Papagiannaki
from django.db.utils import IntegrityError
54 270dd48d Sofia Papagiannaki
from django.contrib.auth.views import password_change
55 64cd4730 Antony Chazapis
56 270dd48d Sofia Papagiannaki
from astakos.im.models import AstakosUser, Invitation, ApprovalTerms
57 4e30244e Sofia Papagiannaki
from astakos.im.activation_backends import get_backend, SimpleBackend
58 270dd48d Sofia Papagiannaki
from astakos.im.util import get_context, prepare_response, set_cookie, has_signed_terms
59 15efc749 Sofia Papagiannaki
from astakos.im.forms import *
60 8f5a3a06 Sofia Papagiannaki
from astakos.im.functions import send_greeting, send_feedback, SendMailError
61 4e30244e Sofia Papagiannaki
from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, COOKIE_NAME, COOKIE_DOMAIN, IM_MODULES, SITENAME, LOGOUT_NEXT
62 f36af44a Antony Chazapis
from astakos.im.functions import invite as invite_func
63 64cd4730 Antony Chazapis
64 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
65 e015e9e6 Sofia Papagiannaki
66 c301698f Sofia Papagiannaki
def render_response(template, tab=None, status=200, reset_cookie=False, context_instance=None, **kwargs):
67 890b0eaf Sofia Papagiannaki
    """
68 890b0eaf Sofia Papagiannaki
    Calls ``django.template.loader.render_to_string`` with an additional ``tab``
69 890b0eaf Sofia Papagiannaki
    keyword argument and returns an ``django.http.HttpResponse`` with the
70 890b0eaf Sofia Papagiannaki
    specified ``status``.
71 890b0eaf Sofia Papagiannaki
    """
72 64cd4730 Antony Chazapis
    if tab is None:
73 881c856c Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
74 64cd4730 Antony Chazapis
    kwargs.setdefault('tab', tab)
75 0905ccd2 Sofia Papagiannaki
    html = render_to_string(template, kwargs, context_instance=context_instance)
76 c301698f Sofia Papagiannaki
    response = HttpResponse(html, status=status)
77 c301698f Sofia Papagiannaki
    if reset_cookie:
78 c301698f Sofia Papagiannaki
        set_cookie(response, context_instance['request'].user)
79 c301698f Sofia Papagiannaki
    return response
80 64cd4730 Antony Chazapis
81 63ecdd20 Sofia Papagiannaki
82 63ecdd20 Sofia Papagiannaki
def requires_anonymous(func):
83 63ecdd20 Sofia Papagiannaki
    """
84 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is not Anonymous and in that case
85 7482228b Sofia Papagiannaki
    redirects to `logout`.
86 63ecdd20 Sofia Papagiannaki
    """
87 63ecdd20 Sofia Papagiannaki
    @wraps(func)
88 63ecdd20 Sofia Papagiannaki
    def wrapper(request, *args):
89 63ecdd20 Sofia Papagiannaki
        if not request.user.is_anonymous():
90 63ecdd20 Sofia Papagiannaki
            next = urlencode({'next': request.build_absolute_uri()})
91 270dd48d Sofia Papagiannaki
            logout_uri = reverse(logout) + '?' + next
92 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(logout_uri)
93 63ecdd20 Sofia Papagiannaki
        return func(request, *args)
94 63ecdd20 Sofia Papagiannaki
    return wrapper
95 63ecdd20 Sofia Papagiannaki
96 270dd48d Sofia Papagiannaki
def signed_terms_required(func):
97 270dd48d Sofia Papagiannaki
    """
98 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is Anonymous and in that case
99 270dd48d Sofia Papagiannaki
    redirects to `logout`.
100 270dd48d Sofia Papagiannaki
    """
101 270dd48d Sofia Papagiannaki
    @wraps(func)
102 270dd48d Sofia Papagiannaki
    def wrapper(request, *args, **kwargs):
103 270dd48d Sofia Papagiannaki
        if request.user.is_authenticated() and not has_signed_terms(request.user):
104 270dd48d Sofia Papagiannaki
            params = urlencode({'next': request.build_absolute_uri(),
105 270dd48d Sofia Papagiannaki
                              'show_form':''})
106 270dd48d Sofia Papagiannaki
            terms_uri = reverse('latest_terms') + '?' + params
107 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(terms_uri)
108 270dd48d Sofia Papagiannaki
        return func(request, *args, **kwargs)
109 270dd48d Sofia Papagiannaki
    return wrapper
110 270dd48d Sofia Papagiannaki
111 270dd48d Sofia Papagiannaki
@signed_terms_required
112 1e685275 Sofia Papagiannaki
def index(request, login_template_name='im/login.html', profile_template_name='im/profile.html', extra_context={}):
113 890b0eaf Sofia Papagiannaki
    """
114 dcf55476 Sofia Papagiannaki
    If there is logged on user renders the profile page otherwise renders login page.
115 176023aa Kostas Papadimitriou

116 890b0eaf Sofia Papagiannaki
    **Arguments**
117 176023aa Kostas Papadimitriou

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

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

126 890b0eaf Sofia Papagiannaki
    ``extra_context``
127 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
128 176023aa Kostas Papadimitriou

129 890b0eaf Sofia Papagiannaki
    **Template:**
130 176023aa Kostas Papadimitriou

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

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

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

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

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

157 890b0eaf Sofia Papagiannaki
    **Arguments**
158 176023aa Kostas Papadimitriou

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

163 890b0eaf Sofia Papagiannaki
    ``extra_context``
164 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
165 176023aa Kostas Papadimitriou

166 890b0eaf Sofia Papagiannaki
    **Template:**
167 176023aa Kostas Papadimitriou

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

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

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

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

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

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

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

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

237 890b0eaf Sofia Papagiannaki
    ``extra_context``
238 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
239 176023aa Kostas Papadimitriou

240 890b0eaf Sofia Papagiannaki
    **Template:**
241 176023aa Kostas Papadimitriou

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

244 92defad4 Sofia Papagiannaki
    **Settings:**
245 176023aa Kostas Papadimitriou

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

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

278 890b0eaf Sofia Papagiannaki
    In case of GET request renders a form for providing the user information.
279 890b0eaf Sofia Papagiannaki
    In case of POST handles the signup.
280 176023aa Kostas Papadimitriou

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

297 176023aa Kostas Papadimitriou

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

302 890b0eaf Sofia Papagiannaki
    ``extra_context``
303 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
304 176023aa Kostas Papadimitriou

305 890b0eaf Sofia Papagiannaki
    **Template:**
306 890b0eaf Sofia Papagiannaki
    
307 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
308 1e685275 Sofia Papagiannaki
    im/signup_complete.html or ``on_success`` keyword argument. 
309 890b0eaf Sofia Papagiannaki
    """
310 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
311 0d02a287 Sofia Papagiannaki
        return HttpResponseRedirect(reverse('astakos.im.views.index'))
312 4e30244e Sofia Papagiannaki
    
313 4e30244e Sofia Papagiannaki
    query_dict = request.__getattribute__(request.method)
314 4e30244e Sofia Papagiannaki
    provider = query_dict.get('provider', 'local')
315 890b0eaf Sofia Papagiannaki
    try:
316 18ffbee1 Sofia Papagiannaki
        if not backend:
317 18ffbee1 Sofia Papagiannaki
            backend = get_backend(request)
318 8f5a3a06 Sofia Papagiannaki
        form = backend.get_signup_form(provider)
319 15efc749 Sofia Papagiannaki
    except (Invitation.DoesNotExist, ValueError), e:
320 4e30244e Sofia Papagiannaki
        form = SimpleBackend(request).get_signup_form(provider)
321 18ffbee1 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, e)
322 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
323 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
324 18ffbee1 Sofia Papagiannaki
            user = form.save(commit=False)
325 8f5a3a06 Sofia Papagiannaki
            try:
326 8f5a3a06 Sofia Papagiannaki
                result = backend.handle_activation(user)
327 8f5a3a06 Sofia Papagiannaki
                status = messages.SUCCESS
328 18ffbee1 Sofia Papagiannaki
                message = result.message
329 18ffbee1 Sofia Papagiannaki
                user.save()
330 8f5a3a06 Sofia Papagiannaki
                if user and user.is_active:
331 8f5a3a06 Sofia Papagiannaki
                    next = request.POST.get('next', '')
332 8f5a3a06 Sofia Papagiannaki
                    return prepare_response(request, user, next=next)
333 8f5a3a06 Sofia Papagiannaki
                messages.add_message(request, status, message)
334 8f5a3a06 Sofia Papagiannaki
                return render_response(on_success,
335 8f5a3a06 Sofia Papagiannaki
                                       context_instance=get_context(request, extra_context))
336 18ffbee1 Sofia Papagiannaki
            except SendMailError, e:
337 18ffbee1 Sofia Papagiannaki
                status = messages.ERROR
338 18ffbee1 Sofia Papagiannaki
                message = e.message
339 18ffbee1 Sofia Papagiannaki
                messages.add_message(request, status, message)
340 18ffbee1 Sofia Papagiannaki
            except BaseException, e:
341 18ffbee1 Sofia Papagiannaki
                status = messages.ERROR
342 18ffbee1 Sofia Papagiannaki
                message = _('Something went wrong.')
343 18ffbee1 Sofia Papagiannaki
                messages.add_message(request, status, message)
344 8f5a3a06 Sofia Papagiannaki
    return render_response(template_name,
345 18ffbee1 Sofia Papagiannaki
                           signup_form = form,
346 890b0eaf Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
347 64cd4730 Antony Chazapis
348 890b0eaf Sofia Papagiannaki
@login_required
349 270dd48d Sofia Papagiannaki
@signed_terms_required
350 8f5a3a06 Sofia Papagiannaki
def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context={}):
351 890b0eaf Sofia Papagiannaki
    """
352 890b0eaf Sofia Papagiannaki
    Allows a user to send feedback.
353 176023aa Kostas Papadimitriou

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

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

359 890b0eaf Sofia Papagiannaki
    **Arguments**
360 176023aa Kostas Papadimitriou

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

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

368 890b0eaf Sofia Papagiannaki
    **Template:**
369 176023aa Kostas Papadimitriou

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

372 890b0eaf Sofia Papagiannaki
    **Settings:**
373 176023aa Kostas Papadimitriou

374 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
375 2cbaacd5 Sofia Papagiannaki
    * ASTAKOS_DEFAULT_CONTACT_EMAIL: List of feedback recipients
376 890b0eaf Sofia Papagiannaki
    """
377 64cd4730 Antony Chazapis
    if request.method == 'GET':
378 890b0eaf Sofia Papagiannaki
        form = FeedbackForm()
379 890b0eaf Sofia Papagiannaki
    if request.method == 'POST':
380 890b0eaf Sofia Papagiannaki
        if not request.user:
381 890b0eaf Sofia Papagiannaki
            return HttpResponse('Unauthorized', status=401)
382 176023aa Kostas Papadimitriou
383 890b0eaf Sofia Papagiannaki
        form = FeedbackForm(request.POST)
384 890b0eaf Sofia Papagiannaki
        if form.is_valid():
385 8f5a3a06 Sofia Papagiannaki
            msg = form.cleaned_data['feedback_msg'],
386 8f5a3a06 Sofia Papagiannaki
            data = form.cleaned_data['feedback_data']
387 538ccdd5 Sofia Papagiannaki
            try:
388 8f5a3a06 Sofia Papagiannaki
                send_feedback(msg, data, request.user, email_template_name)
389 8f5a3a06 Sofia Papagiannaki
            except SendMailError, e:
390 8f5a3a06 Sofia Papagiannaki
                message = e.message
391 8f5a3a06 Sofia Papagiannaki
                status = messages.ERROR
392 8f5a3a06 Sofia Papagiannaki
            else:
393 538ccdd5 Sofia Papagiannaki
                message = _('Feedback successfully sent')
394 538ccdd5 Sofia Papagiannaki
                status = messages.SUCCESS
395 538ccdd5 Sofia Papagiannaki
            messages.add_message(request, status, message)
396 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
397 8f5a3a06 Sofia Papagiannaki
                           feedback_form = form,
398 6b4f9fb2 Sofia Papagiannaki
                           context_instance = get_context(request, extra_context))
399 15efc749 Sofia Papagiannaki
400 7482228b Sofia Papagiannaki
def logout(request, template='registration/logged_out.html', extra_context={}):
401 63ecdd20 Sofia Papagiannaki
    """
402 7482228b Sofia Papagiannaki
    Wraps `django.contrib.auth.logout` and delete the cookie.
403 63ecdd20 Sofia Papagiannaki
    """
404 7482228b Sofia Papagiannaki
    auth_logout(request)
405 7482228b Sofia Papagiannaki
    response = HttpResponse()
406 28ff5b5d Antony Chazapis
    response.delete_cookie(COOKIE_NAME, path='/', domain=COOKIE_DOMAIN)
407 63ecdd20 Sofia Papagiannaki
    next = request.GET.get('next')
408 63ecdd20 Sofia Papagiannaki
    if next:
409 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
410 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
411 63ecdd20 Sofia Papagiannaki
        return response
412 0d02a287 Sofia Papagiannaki
    elif LOGOUT_NEXT:
413 0d02a287 Sofia Papagiannaki
        response['Location'] = LOGOUT_NEXT
414 0d02a287 Sofia Papagiannaki
        response.status_code = 301
415 0d02a287 Sofia Papagiannaki
        return response
416 0d02a287 Sofia Papagiannaki
    messages.add_message(request, messages.SUCCESS, _('You have successfully logged out.'))
417 49df775e Sofia Papagiannaki
    context = get_context(request, extra_context)
418 49df775e Sofia Papagiannaki
    response.write(render_to_string(template, context_instance=context))
419 49df775e Sofia Papagiannaki
    return response
420 2126d85d Sofia Papagiannaki
421 683cf244 Sofia Papagiannaki
@transaction.commit_manually
422 683cf244 Sofia Papagiannaki
def activate(request, email_template_name='im/welcome_email.txt', on_failure=''):
423 2126d85d Sofia Papagiannaki
    """
424 683cf244 Sofia Papagiannaki
    Activates the user identified by the ``auth`` request parameter, sends a welcome email
425 683cf244 Sofia Papagiannaki
    and renews the user token.
426 176023aa Kostas Papadimitriou

427 683cf244 Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the user state will be updated
428 683cf244 Sofia Papagiannaki
    only if the email will be send successfully.
429 2126d85d Sofia Papagiannaki
    """
430 2126d85d Sofia Papagiannaki
    token = request.GET.get('auth')
431 2126d85d Sofia Papagiannaki
    next = request.GET.get('next')
432 2126d85d Sofia Papagiannaki
    try:
433 2126d85d Sofia Papagiannaki
        user = AstakosUser.objects.get(auth_token=token)
434 2126d85d Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
435 683cf244 Sofia Papagiannaki
        return HttpResponseBadRequest(_('No such user'))
436 176023aa Kostas Papadimitriou
437 2126d85d Sofia Papagiannaki
    user.is_active = True
438 8316698a Sofia Papagiannaki
    user.email_verified = True
439 2126d85d Sofia Papagiannaki
    user.save()
440 683cf244 Sofia Papagiannaki
    try:
441 683cf244 Sofia Papagiannaki
        send_greeting(user, email_template_name)
442 683cf244 Sofia Papagiannaki
        response = prepare_response(request, user, next, renew=True)
443 683cf244 Sofia Papagiannaki
        transaction.commit()
444 683cf244 Sofia Papagiannaki
        return response
445 8f5a3a06 Sofia Papagiannaki
    except SendEmailError, e:
446 8f5a3a06 Sofia Papagiannaki
        message = e.message
447 683cf244 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, message)
448 683cf244 Sofia Papagiannaki
        transaction.rollback()
449 683cf244 Sofia Papagiannaki
        return signup(request, on_failure='im/signup.html')
450 18ffbee1 Sofia Papagiannaki
    except BaseException, e:
451 18ffbee1 Sofia Papagiannaki
        status = messages.ERROR
452 18ffbee1 Sofia Papagiannaki
        message = _('Something went wrong.')
453 18ffbee1 Sofia Papagiannaki
        logger.exception(e)
454 18ffbee1 Sofia Papagiannaki
        transaction.rollback()
455 18ffbee1 Sofia Papagiannaki
        return signup(request, on_failure='im/signup.html')
456 270dd48d Sofia Papagiannaki
457 270dd48d Sofia Papagiannaki
def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context={}):
458 270dd48d Sofia Papagiannaki
    term = None
459 270dd48d Sofia Papagiannaki
    terms = None
460 270dd48d Sofia Papagiannaki
    if not term_id:
461 270dd48d Sofia Papagiannaki
        try:
462 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
463 270dd48d Sofia Papagiannaki
        except IndexError:
464 270dd48d Sofia Papagiannaki
            pass
465 270dd48d Sofia Papagiannaki
    else:
466 270dd48d Sofia Papagiannaki
        try:
467 270dd48d Sofia Papagiannaki
             term = ApprovalTerms.objects.get(id=term_id)
468 270dd48d Sofia Papagiannaki
        except ApprovalTermDoesNotExist, e:
469 270dd48d Sofia Papagiannaki
            pass
470 176023aa Kostas Papadimitriou
471 270dd48d Sofia Papagiannaki
    if not term:
472 176023aa Kostas Papadimitriou
        return HttpResponseRedirect(reverse('astakos.im.views.index'))
473 270dd48d Sofia Papagiannaki
    f = open(term.location, 'r')
474 270dd48d Sofia Papagiannaki
    terms = f.read()
475 176023aa Kostas Papadimitriou
476 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
477 270dd48d Sofia Papagiannaki
        next = request.POST.get('next')
478 270dd48d Sofia Papagiannaki
        if not next:
479 8f5a3a06 Sofia Papagiannaki
            next = reverse('astakos.im.views.index')
480 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
481 270dd48d Sofia Papagiannaki
        if not form.is_valid():
482 270dd48d Sofia Papagiannaki
            return render_response(template_name,
483 270dd48d Sofia Papagiannaki
                           terms = terms,
484 8f5a3a06 Sofia Papagiannaki
                           approval_terms_form = form,
485 270dd48d Sofia Papagiannaki
                           context_instance = get_context(request, extra_context))
486 270dd48d Sofia Papagiannaki
        user = form.save()
487 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
488 270dd48d Sofia Papagiannaki
    else:
489 586967c0 Sofia Papagiannaki
        form = None
490 586967c0 Sofia Papagiannaki
        if request.user.is_authenticated() and not has_signed_terms(request.user):
491 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
492 270dd48d Sofia Papagiannaki
        return render_response(template_name,
493 270dd48d Sofia Papagiannaki
                               terms = terms,
494 8f5a3a06 Sofia Papagiannaki
                               approval_terms_form = form,
495 270dd48d Sofia Papagiannaki
                               context_instance = get_context(request, extra_context))
496 270dd48d Sofia Papagiannaki
497 270dd48d Sofia Papagiannaki
@signed_terms_required
498 270dd48d Sofia Papagiannaki
def change_password(request):
499 176023aa Kostas Papadimitriou
    return password_change(request, post_change_redirect=reverse('astakos.im.views.edit_profile'))