Projet

Général

Profil

Télécharger (3,61 ko) Statistiques
| Branche: | Révision:

root / larpe / trunk / saml2.ptl @ 8843f79b

1
import os
2
import urlparse
3

    
4
import lasso
5

    
6
from quixote import get_request, get_response, redirect, get_field, get_publisher
7
from quixote.http_request import parse_header
8
from quixote.directory import Directory
9
from quixote import get_user, get_session, get_session_manager
10

    
11
from users import User
12
import misc
13
import template
14

    
15
from liberty import SOAPException, soap_call
16

    
17

    
18
class RootDirectory(Directory):
19
    _q_exports = ['login', 'singleSignOnArtifact',
20
            ('metadata.xml', 'metadata'), 'public_key']
21

    
22
    def _q_index(self):
23
        raise errors.AccessError()
24

    
25
    def login(self):
26
        return self.perform_login()
27

    
28
    def perform_login(self, idp = None):
29
        server = misc.get_lasso_server(protocol = 'saml2')
30
        if not server:
31
            return template.error_page(_('SAML 2.0 support not yet configured.'))
32
        login = lasso.Login(server)
33
        login.initAuthnRequest(idp, lasso.HTTP_METHOD_REDIRECT)
34
        login.request.nameIDPolicy.format = lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT
35
        login.request.nameIDPolicy.allowCreate = True
36
        login.request.forceAuthn = False
37
        login.request.isPassive = False
38
        # login.request.consent = /* XXX */
39
        login.buildAuthnRequestMsg()
40
        return redirect(login.msgUrl)
41
        
42

    
43
    def singleSignOnArtifact(self):
44
        server = misc.get_lasso_server(protocol = 'saml2')
45
        if not server:
46
            return template.error_page(_('SAML 2.0 support not yet configured.'))
47
        login = lasso.Login(server)
48
        request = get_request()
49
        login.initRequest(request.get_query(), lasso.HTTP_METHOD_ARTIFACT_GET)
50
        login.buildRequestMsg()
51
        try:
52
            soap_answer = soap_call(login.msgUrl, login.msgBody)
53
        except SOAPException:
54
            return template.error_page(_("Failure to communicate with identity provider"))
55

    
56
        login.processResponseMsg(soap_answer)
57

    
58
        login.acceptSso()
59
        session = get_session()
60
        if login.isSessionDirty:
61
            if login.session:
62
                session.lasso_session_dump = login.session.dump()
63
            else:
64
                session.lasso_session_dump = None
65
        user = self.lookup_user(session, login)
66
        if user:
67
            session.set_user(user.id)
68
        else:
69
            session.set_user('anonymous-%s' % login.nameIdentifier.content)
70
            session.lasso_anonymous_identity_dump = login.identity.dump()
71

    
72
        response = get_response()
73
        if session.after_url:
74
            after_url = session.after_url
75
            session.after_url = None
76
            return redirect(after_url)
77
        response.set_status(303)
78
        response.headers['location'] = urlparse.urljoin(request.get_url(), str('..'))
79
        response.content_type = 'text/plain'
80
        return "Your browser should redirect you"
81

    
82
    def lookup_user(self, session, login):
83
        ni = login.nameIdentifier.content
84
        session.name_identifier = ni
85
        nis = list(User.select(lambda x: ni in x.name_identifiers))
86
        if nis:
87
            user = nis[0]
88
        else:
89
            return None
90

    
91
        user.lasso_dump = login.identity.dump()
92
        user.store()
93
        return user
94

    
95

    
96
    def metadata(self):
97
        response = get_response()
98
        response.set_content_type('text/xml', 'utf-8')
99
        metadata = unicode(open(misc.get_abs_path(
100
                        misc.cfg['sp']['saml2_metadata'])).read(), 'utf-8')
101
        return metadata
102

    
103
    def public_key(self):
104
        response = get_response()
105
        response.set_content_type('application/octet-stream')
106
        publickey = file(misc.get_abs_path(misc.cfg['sp']['publickey'])).read()
107
        return publickey
108

    
109

    
110

    
(15-15/20)