Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / target / __init__.py @ ccaadd41

History | View | Annotate | Download (8 kB)

1 dd5f8f4d Kostas Papadimitriou
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 dd5f8f4d Kostas Papadimitriou
#
3 dd5f8f4d Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 dd5f8f4d Kostas Papadimitriou
# without modification, are permitted provided that the following
5 dd5f8f4d Kostas Papadimitriou
# conditions are met:
6 dd5f8f4d Kostas Papadimitriou
#
7 dd5f8f4d Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 dd5f8f4d Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 dd5f8f4d Kostas Papadimitriou
#      disclaimer.
10 dd5f8f4d Kostas Papadimitriou
#
11 dd5f8f4d Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 dd5f8f4d Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 dd5f8f4d Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 dd5f8f4d Kostas Papadimitriou
#      provided with the distribution.
15 dd5f8f4d Kostas Papadimitriou
#
16 dd5f8f4d Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 dd5f8f4d Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 dd5f8f4d Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 dd5f8f4d Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 dd5f8f4d Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 dd5f8f4d Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 dd5f8f4d Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 dd5f8f4d Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 dd5f8f4d Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 dd5f8f4d Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 dd5f8f4d Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 dd5f8f4d Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 dd5f8f4d Kostas Papadimitriou
#
29 dd5f8f4d Kostas Papadimitriou
# The views and conclusions contained in the software and
30 dd5f8f4d Kostas Papadimitriou
# documentation are those of the authors and should not be
31 dd5f8f4d Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 dd5f8f4d Kostas Papadimitriou
# or implied, of GRNET S.A.
33 dd5f8f4d Kostas Papadimitriou
34 dd5f8f4d Kostas Papadimitriou
import json
35 dd5f8f4d Kostas Papadimitriou
36 dd5f8f4d Kostas Papadimitriou
from django.contrib import messages
37 dd5f8f4d Kostas Papadimitriou
from django.utils.translation import ugettext as _
38 dd5f8f4d Kostas Papadimitriou
from django.http import HttpResponseRedirect
39 dd5f8f4d Kostas Papadimitriou
from django.core.urlresolvers import reverse
40 dd5f8f4d Kostas Papadimitriou
41 c8d89a3c Kostas Papadimitriou
from astakos.im.models import PendingThirdPartyUser, AstakosUser
42 c8d89a3c Kostas Papadimitriou
from astakos.im.util import get_query, login_url
43 dd5f8f4d Kostas Papadimitriou
from astakos.im import messages as astakos_messages
44 dd5f8f4d Kostas Papadimitriou
from astakos.im import auth_providers
45 dd5f8f4d Kostas Papadimitriou
from astakos.im.util import prepare_response, get_context
46 dd5f8f4d Kostas Papadimitriou
from astakos.im.views import requires_anonymous, render_response
47 dd5f8f4d Kostas Papadimitriou
48 dd5f8f4d Kostas Papadimitriou
49 0e79735c Kostas Papadimitriou
def init_third_party_session(request):
50 0e79735c Kostas Papadimitriou
    params = dict(request.GET.items())
51 0e79735c Kostas Papadimitriou
    request.session['third_party_request_params'] = params
52 0e79735c Kostas Papadimitriou
53 0e79735c Kostas Papadimitriou
54 0e79735c Kostas Papadimitriou
def get_third_party_session_params(request):
55 0e79735c Kostas Papadimitriou
    if 'third_party_request_params' in request.session:
56 0e79735c Kostas Papadimitriou
        params = request.session['third_party_request_params']
57 0e79735c Kostas Papadimitriou
        del request.session['third_party_request_params']
58 0e79735c Kostas Papadimitriou
        return params
59 0e79735c Kostas Papadimitriou
    return {}
60 0e79735c Kostas Papadimitriou
61 0e79735c Kostas Papadimitriou
62 dd5f8f4d Kostas Papadimitriou
def add_pending_auth_provider(request, third_party_token):
63 dd5f8f4d Kostas Papadimitriou
    if third_party_token:
64 dd5f8f4d Kostas Papadimitriou
        # use requests to assign the account he just authenticated with with
65 dd5f8f4d Kostas Papadimitriou
        # a third party provider account
66 dd5f8f4d Kostas Papadimitriou
        try:
67 dd5f8f4d Kostas Papadimitriou
            request.user.add_pending_auth_provider(third_party_token)
68 dd5f8f4d Kostas Papadimitriou
        except PendingThirdPartyUser.DoesNotExist:
69 dd5f8f4d Kostas Papadimitriou
            messages.error(request, _(astakos_messages.AUTH_PROVIDER_ADD_FAILED))
70 dd5f8f4d Kostas Papadimitriou
71 dd5f8f4d Kostas Papadimitriou
72 dd5f8f4d Kostas Papadimitriou
def get_pending_key(request):
73 0e79735c Kostas Papadimitriou
    third_party_token = get_query(request).get('key', request.session.get('pending_key', False))
74 0e79735c Kostas Papadimitriou
    if 'pending_key' in request.session:
75 0e79735c Kostas Papadimitriou
        del request.session['pending_key']
76 dd5f8f4d Kostas Papadimitriou
    return third_party_token
77 dd5f8f4d Kostas Papadimitriou
78 dd5f8f4d Kostas Papadimitriou
79 dd5f8f4d Kostas Papadimitriou
def handle_third_party_signup(request, userid, provider_module, third_party_key,
80 dd5f8f4d Kostas Papadimitriou
                              provider_info={},
81 dd5f8f4d Kostas Papadimitriou
                              pending_user_params={},
82 dd5f8f4d Kostas Papadimitriou
                              template="im/third_party_check_local.html",
83 dd5f8f4d Kostas Papadimitriou
                              extra_context={}):
84 dd5f8f4d Kostas Papadimitriou
85 dd5f8f4d Kostas Papadimitriou
    # user wants to add another third party login method
86 dd5f8f4d Kostas Papadimitriou
    if third_party_key:
87 dd5f8f4d Kostas Papadimitriou
        messages.error(request, _(astakos_messages.AUTH_PROVIDER_INVALID_LOGIN))
88 dd5f8f4d Kostas Papadimitriou
        return HttpResponseRedirect(reverse('login') + "?key=%s" % third_party_key)
89 dd5f8f4d Kostas Papadimitriou
90 dd5f8f4d Kostas Papadimitriou
    provider = auth_providers.get_provider(provider_module)
91 dd5f8f4d Kostas Papadimitriou
    if not provider.is_available_for_create():
92 dd5f8f4d Kostas Papadimitriou
        messages.error(request,
93 dd5f8f4d Kostas Papadimitriou
                       _(astakos_messages.AUTH_PROVIDER_INVALID_LOGIN))
94 dd5f8f4d Kostas Papadimitriou
        return HttpResponseRedirect(reverse('login'))
95 dd5f8f4d Kostas Papadimitriou
96 c8d89a3c Kostas Papadimitriou
    # identifier not stored in astakos models, create pending profile
97 dd5f8f4d Kostas Papadimitriou
    user, created = PendingThirdPartyUser.objects.get_or_create(
98 dd5f8f4d Kostas Papadimitriou
        third_party_identifier=userid,
99 dd5f8f4d Kostas Papadimitriou
        provider=provider_module,
100 dd5f8f4d Kostas Papadimitriou
    )
101 dd5f8f4d Kostas Papadimitriou
    # update pending user
102 dd5f8f4d Kostas Papadimitriou
    for param, value in pending_user_params.iteritems():
103 dd5f8f4d Kostas Papadimitriou
        setattr(user, param, value)
104 dd5f8f4d Kostas Papadimitriou
105 dd5f8f4d Kostas Papadimitriou
    user.info = json.dumps(provider_info)
106 dd5f8f4d Kostas Papadimitriou
    user.generate_token()
107 dd5f8f4d Kostas Papadimitriou
    user.save()
108 dd5f8f4d Kostas Papadimitriou
109 dd5f8f4d Kostas Papadimitriou
    extra_context['provider'] = provider_module
110 dd5f8f4d Kostas Papadimitriou
    extra_context['provider_title'] = provider.get_title_display
111 dd5f8f4d Kostas Papadimitriou
    extra_context['token'] = user.token
112 dd5f8f4d Kostas Papadimitriou
    extra_context['signup_url'] = reverse('signup') + \
113 dd5f8f4d Kostas Papadimitriou
                                "?third_party_token=%s" % user.token
114 dd5f8f4d Kostas Papadimitriou
    extra_context['add_url'] = reverse('index') + \
115 dd5f8f4d Kostas Papadimitriou
                                "?key=%s#other-login-methods" % user.token
116 dd5f8f4d Kostas Papadimitriou
    extra_context['can_create'] = provider.is_available_for_create()
117 dd5f8f4d Kostas Papadimitriou
    extra_context['can_add'] = provider.is_available_for_add()
118 dd5f8f4d Kostas Papadimitriou
119 a148ae08 Kostas Papadimitriou
    return HttpResponseRedirect(extra_context['signup_url'])
120 a148ae08 Kostas Papadimitriou
    #return render_response(
121 a148ae08 Kostas Papadimitriou
        #template,
122 a148ae08 Kostas Papadimitriou
        #context_instance=get_context(request, extra_context)
123 a148ae08 Kostas Papadimitriou
    #)
124 dd5f8f4d Kostas Papadimitriou
125 c8d89a3c Kostas Papadimitriou
126 c8d89a3c Kostas Papadimitriou
127 c8d89a3c Kostas Papadimitriou
def handle_third_party_login(request, provider_module, identifier,
128 0e79735c Kostas Papadimitriou
                             provider_info=None, affiliation=None,
129 0e79735c Kostas Papadimitriou
                             third_party_key=None):
130 c8d89a3c Kostas Papadimitriou
131 c8d89a3c Kostas Papadimitriou
    if not provider_info:
132 c8d89a3c Kostas Papadimitriou
        provider_info = {}
133 c8d89a3c Kostas Papadimitriou
134 c8d89a3c Kostas Papadimitriou
    if not affiliation:
135 c8d89a3c Kostas Papadimitriou
        affiliation = provider_module.title()
136 c8d89a3c Kostas Papadimitriou
137 c8d89a3c Kostas Papadimitriou
    next_redirect = request.GET.get('next', request.session.get('next_url', None))
138 c8d89a3c Kostas Papadimitriou
    if 'next_url' in request.session:
139 c8d89a3c Kostas Papadimitriou
        del request.session['next_url']
140 c8d89a3c Kostas Papadimitriou
141 0e79735c Kostas Papadimitriou
    third_party_request_params = get_third_party_session_params(request)
142 0e79735c Kostas Papadimitriou
    from_login = third_party_request_params.get('from_login', False)
143 0e79735c Kostas Papadimitriou
144 c8d89a3c Kostas Papadimitriou
    # an existing user accessed the view
145 c8d89a3c Kostas Papadimitriou
    if request.user.is_authenticated():
146 c8d89a3c Kostas Papadimitriou
147 c8d89a3c Kostas Papadimitriou
        if request.user.has_auth_provider(provider_module, identifier=identifier):
148 c8d89a3c Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
149 c8d89a3c Kostas Papadimitriou
150 c8d89a3c Kostas Papadimitriou
        # automatically add identifier provider to user
151 c8d89a3c Kostas Papadimitriou
        user = request.user
152 c8d89a3c Kostas Papadimitriou
        if not request.user.can_add_auth_provider(provider_module,
153 c8d89a3c Kostas Papadimitriou
                                                  identifier=identifier):
154 c8d89a3c Kostas Papadimitriou
            # TODO: handle existing uuid message separately
155 c8d89a3c Kostas Papadimitriou
            messages.error(request, _(astakos_messages.AUTH_PROVIDER_ADD_FAILED) +
156 c8d89a3c Kostas Papadimitriou
                          u' ' + _(astakos_messages.AUTH_PROVIDER_ADD_EXISTS))
157 c8d89a3c Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
158 c8d89a3c Kostas Papadimitriou
159 c8d89a3c Kostas Papadimitriou
        user.add_auth_provider(provider_module, identifier=identifier,
160 c8d89a3c Kostas Papadimitriou
                               affiliation=affiliation,
161 c8d89a3c Kostas Papadimitriou
                               provider_info=provider_info)
162 ca5148f2 Kostas Papadimitriou
        provider = auth_providers.get_provider(provider_module)
163 ca5148f2 Kostas Papadimitriou
        message = _(astakos_messages.AUTH_PROVIDER_ADDED) % provider.get_method_prompt_display
164 ca5148f2 Kostas Papadimitriou
        messages.success(request, message)
165 c8d89a3c Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
166 c8d89a3c Kostas Papadimitriou
167 c8d89a3c Kostas Papadimitriou
    # astakos user exists ?
168 0e79735c Kostas Papadimitriou
    try:
169 0e79735c Kostas Papadimitriou
        user = AstakosUser.objects.get_auth_provider_user(
170 0e79735c Kostas Papadimitriou
            provider_module,
171 0e79735c Kostas Papadimitriou
            identifier=identifier,
172 0e79735c Kostas Papadimitriou
            user__email_verified=True,
173 0e79735c Kostas Papadimitriou
        )
174 0e79735c Kostas Papadimitriou
    except AstakosUser.DoesNotExist:
175 0e79735c Kostas Papadimitriou
        # TODO: add a message ? redirec to login ?
176 0e79735c Kostas Papadimitriou
        if astakos_messages.AUTH_PROVIDER_SIGNUP_FROM_LOGIN:
177 0e79735c Kostas Papadimitriou
            messages.warning(request,
178 0e79735c Kostas Papadimitriou
                             astakos_messages.AUTH_PROVIDER_SIGNUP_FROM_LOGIN)
179 0e79735c Kostas Papadimitriou
        raise
180 0e79735c Kostas Papadimitriou
181 0e79735c Kostas Papadimitriou
    if not third_party_key:
182 0e79735c Kostas Papadimitriou
        third_party_key = get_pending_key(request)
183 0e79735c Kostas Papadimitriou
184 c8d89a3c Kostas Papadimitriou
    if user.is_active:
185 c8d89a3c Kostas Papadimitriou
        # authenticate user
186 c8d89a3c Kostas Papadimitriou
        response = prepare_response(request,
187 c8d89a3c Kostas Papadimitriou
                                user,
188 c8d89a3c Kostas Papadimitriou
                                next_redirect,
189 c8d89a3c Kostas Papadimitriou
                                'renew' in request.GET)
190 c8d89a3c Kostas Papadimitriou
        provider = auth_providers.get_provider(provider_module)
191 c8d89a3c Kostas Papadimitriou
        messages.success(request, _(astakos_messages.LOGIN_SUCCESS) %
192 c8d89a3c Kostas Papadimitriou
                         _(provider.get_login_message_display))
193 c8d89a3c Kostas Papadimitriou
        add_pending_auth_provider(request, third_party_key)
194 c8d89a3c Kostas Papadimitriou
        response.set_cookie('astakos_last_login_method', provider_module)
195 c8d89a3c Kostas Papadimitriou
        return response
196 c8d89a3c Kostas Papadimitriou
    else:
197 c8d89a3c Kostas Papadimitriou
        message = user.get_inactive_message()
198 c8d89a3c Kostas Papadimitriou
        messages.error(request, message)
199 c8d89a3c Kostas Papadimitriou
        return HttpResponseRedirect(login_url(request))