Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / target / shibboleth.py @ fffa19d2

History | View | Annotate | Download (7.7 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 64cd4730 Antony Chazapis
# 
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 64cd4730 Antony Chazapis
# 
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 64cd4730 Antony Chazapis
# 
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 64cd4730 Antony Chazapis
# 
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 64cd4730 Antony Chazapis
# 
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
from django.http import HttpResponseBadRequest
35 18ffbee1 Sofia Papagiannaki
from django.utils.translation import ugettext as _
36 18ffbee1 Sofia Papagiannaki
from django.contrib import messages
37 18ffbee1 Sofia Papagiannaki
from django.template import RequestContext
38 dda2e499 Sofia Papagiannaki
from django.views.decorators.http import require_http_methods
39 ef20ea07 Sofia Papagiannaki
from django.db.models import Q
40 ef20ea07 Sofia Papagiannaki
from django.core.exceptions import ValidationError
41 ef20ea07 Sofia Papagiannaki
from django.http import HttpResponseRedirect
42 ef20ea07 Sofia Papagiannaki
from django.core.urlresolvers import reverse
43 ef20ea07 Sofia Papagiannaki
from urlparse import urlunsplit, urlsplit
44 ef20ea07 Sofia Papagiannaki
from django.utils.http import urlencode
45 64cd4730 Antony Chazapis
46 6151009c Sofia Papagiannaki
from astakos.im.util import prepare_response, get_context, get_invitation
47 8f5a3a06 Sofia Papagiannaki
from astakos.im.views import requires_anonymous, render_response
48 ef20ea07 Sofia Papagiannaki
from astakos.im.settings import ENABLE_LOCAL_ACCOUNT_MIGRATION, BASEURL
49 ef20ea07 Sofia Papagiannaki
50 ef20ea07 Sofia Papagiannaki
from astakos.im.models import AstakosUser, PendingThirdPartyUser
51 4e30244e Sofia Papagiannaki
from astakos.im.forms import LoginForm
52 4e30244e Sofia Papagiannaki
from astakos.im.activation_backends import get_backend, SimpleBackend
53 64cd4730 Antony Chazapis
54 ef20ea07 Sofia Papagiannaki
import logging
55 ef20ea07 Sofia Papagiannaki
56 ef20ea07 Sofia Papagiannaki
logger = logging.getLogger(__name__)
57 ef20ea07 Sofia Papagiannaki
58 64cd4730 Antony Chazapis
class Tokens:
59 64cd4730 Antony Chazapis
    # these are mapped by the Shibboleth SP software
60 64cd4730 Antony Chazapis
    SHIB_EPPN = "HTTP_EPPN" # eduPersonPrincipalName
61 64cd4730 Antony Chazapis
    SHIB_NAME = "HTTP_SHIB_INETORGPERSON_GIVENNAME"
62 64cd4730 Antony Chazapis
    SHIB_SURNAME = "HTTP_SHIB_PERSON_SURNAME"
63 64cd4730 Antony Chazapis
    SHIB_CN = "HTTP_SHIB_PERSON_COMMONNAME"
64 64cd4730 Antony Chazapis
    SHIB_DISPLAYNAME = "HTTP_SHIB_INETORGPERSON_DISPLAYNAME"
65 64cd4730 Antony Chazapis
    SHIB_EP_AFFILIATION = "HTTP_SHIB_EP_AFFILIATION"
66 64cd4730 Antony Chazapis
    SHIB_SESSION_ID = "HTTP_SHIB_SESSION_ID"
67 ca828a10 Sofia Papagiannaki
    SHIB_MAIL = "HTTP_SHIB_MAIL"
68 64cd4730 Antony Chazapis
69 dda2e499 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
70 63ecdd20 Sofia Papagiannaki
@requires_anonymous
71 ef20ea07 Sofia Papagiannaki
def login(
72 ef20ea07 Sofia Papagiannaki
    request,
73 1f3b4b39 Sofia Papagiannaki
    login_template='im/login.html',
74 1f3b4b39 Sofia Papagiannaki
    signup_template='im/third_party_check_local.html',
75 678b2236 Sofia Papagiannaki
    extra_context=None
76 678b2236 Sofia Papagiannaki
):
77 ef20ea07 Sofia Papagiannaki
    extra_context = extra_context or {}
78 ef20ea07 Sofia Papagiannaki
79 4e30244e Sofia Papagiannaki
    tokens = request.META
80 4e30244e Sofia Papagiannaki
    
81 fffa19d2 Sofia Papagiannaki
#     try:
82 fffa19d2 Sofia Papagiannaki
#         eppn = tokens.get(Tokens.SHIB_EPPN)
83 fffa19d2 Sofia Papagiannaki
#         if not eppn:
84 fffa19d2 Sofia Papagiannaki
#             raise KeyError(_('Missing unique token in request'))
85 fffa19d2 Sofia Papagiannaki
#         if Tokens.SHIB_DISPLAYNAME in tokens:
86 fffa19d2 Sofia Papagiannaki
#             realname = tokens[Tokens.SHIB_DISPLAYNAME]
87 fffa19d2 Sofia Papagiannaki
#         elif Tokens.SHIB_CN in tokens:
88 fffa19d2 Sofia Papagiannaki
#             realname = tokens[Tokens.SHIB_CN]
89 fffa19d2 Sofia Papagiannaki
#         elif Tokens.SHIB_NAME in tokens and Tokens.SHIB_SURNAME in tokens:
90 fffa19d2 Sofia Papagiannaki
#             realname = tokens[Tokens.SHIB_NAME] + ' ' + tokens[Tokens.SHIB_SURNAME]
91 fffa19d2 Sofia Papagiannaki
#         else:
92 fffa19d2 Sofia Papagiannaki
#             raise KeyError(_('Missing user name in request'))
93 fffa19d2 Sofia Papagiannaki
#     except KeyError, e:
94 fffa19d2 Sofia Papagiannaki
#         extra_context['login_form'] = LoginForm(request=request)
95 fffa19d2 Sofia Papagiannaki
#         messages.error(request, e)
96 fffa19d2 Sofia Papagiannaki
#         return render_response(
97 fffa19d2 Sofia Papagiannaki
#             login_template,
98 fffa19d2 Sofia Papagiannaki
#             context_instance=get_context(request, extra_context)
99 fffa19d2 Sofia Papagiannaki
#         )
100 fffa19d2 Sofia Papagiannaki
#     
101 fffa19d2 Sofia Papagiannaki
#     affiliation = tokens.get(Tokens.SHIB_EP_AFFILIATION, '')
102 fffa19d2 Sofia Papagiannaki
#     email = tokens.get(Tokens.SHIB_MAIL, '')
103 4e30244e Sofia Papagiannaki
    
104 fffa19d2 Sofia Papagiannaki
    eppn, realname, affiliation, email = 'shibboleth1', 'shib Boleth', '', '' 
105 1f3b4b39 Sofia Papagiannaki
    
106 64cd4730 Antony Chazapis
    try:
107 ef20ea07 Sofia Papagiannaki
        user = AstakosUser.objects.get(
108 ef20ea07 Sofia Papagiannaki
            provider='shibboleth',
109 ef20ea07 Sofia Papagiannaki
            third_party_identifier=eppn
110 ef20ea07 Sofia Papagiannaki
        )
111 18ffbee1 Sofia Papagiannaki
        if user.is_active:
112 18ffbee1 Sofia Papagiannaki
            return prepare_response(request,
113 18ffbee1 Sofia Papagiannaki
                                    user,
114 18ffbee1 Sofia Papagiannaki
                                    request.GET.get('next'),
115 18ffbee1 Sofia Papagiannaki
                                    'renew' in request.GET)
116 1f3b4b39 Sofia Papagiannaki
        elif not user.activation_sent:
117 1f3b4b39 Sofia Papagiannaki
            message = _('Your request is pending activation')
118 1f3b4b39 Sofia Papagiannaki
            messages.error(request, message)
119 18ffbee1 Sofia Papagiannaki
        else:
120 fffa19d2 Sofia Papagiannaki
            urls = {}
121 fffa19d2 Sofia Papagiannaki
            urls['send_activation'] = reverse(
122 fffa19d2 Sofia Papagiannaki
                'send_activation',
123 fffa19d2 Sofia Papagiannaki
                kwargs={'user_id':user.id}
124 fffa19d2 Sofia Papagiannaki
            )
125 fffa19d2 Sofia Papagiannaki
            urls['signup'] = reverse(
126 fffa19d2 Sofia Papagiannaki
                'shibboleth_signup',
127 fffa19d2 Sofia Papagiannaki
                args= [user.username]
128 fffa19d2 Sofia Papagiannaki
            )   
129 fffa19d2 Sofia Papagiannaki
            message = _(
130 fffa19d2 Sofia Papagiannaki
                'You have not followed the activation link. \
131 fffa19d2 Sofia Papagiannaki
                <a href="%(send_activation)s">Resend activation email?</a> or \
132 fffa19d2 Sofia Papagiannaki
                <a href="%(signup)s">Provide new email?</a>' % urls
133 fffa19d2 Sofia Papagiannaki
            )
134 1f3b4b39 Sofia Papagiannaki
            messages.error(request, message)
135 1f3b4b39 Sofia Papagiannaki
        return render_response(login_template,
136 1f3b4b39 Sofia Papagiannaki
                               login_form = LoginForm(request=request),
137 1f3b4b39 Sofia Papagiannaki
                               context_instance=RequestContext(request))
138 8f5a3a06 Sofia Papagiannaki
    except AstakosUser.DoesNotExist, e:
139 ef20ea07 Sofia Papagiannaki
        # First time
140 ef20ea07 Sofia Papagiannaki
        try:
141 ef20ea07 Sofia Papagiannaki
            user, created = PendingThirdPartyUser.objects.get_or_create(
142 ef20ea07 Sofia Papagiannaki
                third_party_identifier=eppn,
143 ef20ea07 Sofia Papagiannaki
                provider='shibboleth',
144 ef20ea07 Sofia Papagiannaki
                defaults=dict(
145 ef20ea07 Sofia Papagiannaki
                    realname=realname,
146 ef20ea07 Sofia Papagiannaki
                    affiliation=affiliation,
147 ef20ea07 Sofia Papagiannaki
                    email=email
148 ef20ea07 Sofia Papagiannaki
                )
149 ef20ea07 Sofia Papagiannaki
            )
150 ef20ea07 Sofia Papagiannaki
            user.save()
151 ef20ea07 Sofia Papagiannaki
        except BaseException, e:
152 ef20ea07 Sofia Papagiannaki
            logger.exception(e)
153 1f3b4b39 Sofia Papagiannaki
            template = login_template
154 ef20ea07 Sofia Papagiannaki
            extra_context['login_form'] = LoginForm(request=request)
155 ef20ea07 Sofia Papagiannaki
            messages.error(request, _('Something went wrong.'))
156 ef20ea07 Sofia Papagiannaki
        else:
157 ef20ea07 Sofia Papagiannaki
            if not ENABLE_LOCAL_ACCOUNT_MIGRATION:
158 ef20ea07 Sofia Papagiannaki
                url = reverse(
159 fffa19d2 Sofia Papagiannaki
                    'shibboleth_signup',
160 fffa19d2 Sofia Papagiannaki
                    args= [user.username]
161 ef20ea07 Sofia Papagiannaki
                )
162 ef20ea07 Sofia Papagiannaki
                return HttpResponseRedirect(url)
163 ef20ea07 Sofia Papagiannaki
            else:
164 1f3b4b39 Sofia Papagiannaki
                template = signup_template
165 fffa19d2 Sofia Papagiannaki
                extra_context['username'] = user.username
166 ef20ea07 Sofia Papagiannaki
        
167 ef20ea07 Sofia Papagiannaki
        extra_context['provider']='shibboleth'
168 ef20ea07 Sofia Papagiannaki
        return render_response(
169 ef20ea07 Sofia Papagiannaki
            template,
170 ef20ea07 Sofia Papagiannaki
            context_instance=get_context(request, extra_context)
171 ef20ea07 Sofia Papagiannaki
        )
172 ef20ea07 Sofia Papagiannaki
173 ef20ea07 Sofia Papagiannaki
@require_http_methods(["GET"])
174 ef20ea07 Sofia Papagiannaki
@requires_anonymous
175 678b2236 Sofia Papagiannaki
def signup(
176 678b2236 Sofia Papagiannaki
    request,
177 fffa19d2 Sofia Papagiannaki
    username,
178 678b2236 Sofia Papagiannaki
    backend=None,
179 678b2236 Sofia Papagiannaki
    on_creation_template='im/third_party_registration.html',
180 678b2236 Sofia Papagiannaki
    extra_context=None
181 ef20ea07 Sofia Papagiannaki
):
182 ef20ea07 Sofia Papagiannaki
    extra_context = extra_context or {}
183 ef20ea07 Sofia Papagiannaki
    try:
184 ef20ea07 Sofia Papagiannaki
        pending = PendingThirdPartyUser.objects.get(username=username)
185 ef20ea07 Sofia Papagiannaki
    except BaseException, e:
186 fffa19d2 Sofia Papagiannaki
        try:
187 fffa19d2 Sofia Papagiannaki
            user = AstakosUser.objects.get(username=username)
188 fffa19d2 Sofia Papagiannaki
        except BaseException, e:
189 fffa19d2 Sofia Papagiannaki
            logger.exception(e)
190 fffa19d2 Sofia Papagiannaki
            return HttpResponseBadRequest(_('Invalid key.'))
191 ef20ea07 Sofia Papagiannaki
    else:
192 ef20ea07 Sofia Papagiannaki
        d = pending.__dict__
193 ef20ea07 Sofia Papagiannaki
        d.pop('_state', None)
194 ef20ea07 Sofia Papagiannaki
        d.pop('id', None)
195 ef20ea07 Sofia Papagiannaki
        user = AstakosUser(**d)
196 fffa19d2 Sofia Papagiannaki
    try:
197 fffa19d2 Sofia Papagiannaki
        backend = backend or get_backend(request)
198 fffa19d2 Sofia Papagiannaki
    except ImproperlyConfigured, e:
199 fffa19d2 Sofia Papagiannaki
        messages.error(request, e)
200 fffa19d2 Sofia Papagiannaki
    else:
201 fffa19d2 Sofia Papagiannaki
        extra_context['form'] = backend.get_signup_form(
202 fffa19d2 Sofia Papagiannaki
            provider='shibboleth',
203 fffa19d2 Sofia Papagiannaki
            instance=user
204 fffa19d2 Sofia Papagiannaki
        )
205 ef20ea07 Sofia Papagiannaki
    extra_context['provider']='shibboleth'
206 ef20ea07 Sofia Papagiannaki
    return render_response(
207 ef20ea07 Sofia Papagiannaki
            on_creation_template,
208 ef20ea07 Sofia Papagiannaki
            context_instance=get_context(request, extra_context)
209 ef20ea07 Sofia Papagiannaki
    )