Handle user session data for both internal and external authentication
[cascardo/ipsilon.git] / ipsilon / providers / openid / meta.py
1 # Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING
2
3 from ipsilon.providers.common import ProviderPageBase
4
5 import cherrypy
6
7
8 class MetaHandler(ProviderPageBase):
9
10     def __init__(self, site, provider, *args, **kwargs):
11         super(MetaHandler, self).__init__(site, provider)
12         self._template_name = None
13         self._take_args = False
14
15     def reply(self, **kwargs):
16         if self._template_name is None:
17             raise ValueError('Template not set')
18         return str(self._template(self._template_name, **kwargs))
19
20     def default(self, *args, **kwargs):
21         if self._take_args:
22             return self.root(*args, **kwargs)
23         raise cherrypy.NotFound()
24
25
26 class XRDSHandler(MetaHandler):
27
28     def __init__(self, *args, **kwargs):
29         super(XRDSHandler, self).__init__(*args, **kwargs)
30         self.default_headers['Content-Type'] = 'application/xrds+xml'
31         self._template_name = 'openid/xrds.xml'
32
33     def GET(self, *args, **kwargs):
34         types = [
35             'http://specs.openid.net/auth/2.0/server',
36             'http://openid.net/server/1.0',
37         ]
38         for _, e in self.cfg.extensions.available().items():
39             types.extend(e.get_type_uris())
40
41         return self.reply(types=types,
42                           uri=self.cfg.endpoint_url)
43
44
45 class UserXRDSHandler(XRDSHandler):
46
47     def __init__(self, *args, **kwargs):
48         super(UserXRDSHandler, self).__init__(*args, **kwargs)
49         self._take_args = True
50
51     def GET(self, *args, **kwargs):
52         if len(args) != 1:
53             raise cherrypy.NotFound()
54         if args[0].endswith('.xrds'):
55             name = args[0][:-5]
56             identity_url = self.cfg.identity_url_template % {'username': name}
57             types = [
58                 'http://specs.openid.net/auth/2.0/signon',
59                 'http://openid.net/signon/1.0',
60             ]
61             for _, e in self.cfg.extensions.available().items():
62                 types.extend(e.get_type_uris())
63
64             return self.reply(types=types,
65                               uri=self.cfg.endpoint_url,
66                               localid=identity_url)
67
68         raise cherrypy.NotFound()
69
70
71 class IDHandler(MetaHandler):
72
73     def __init__(self, *args, **kwargs):
74         super(IDHandler, self).__init__(*args, **kwargs)
75         self._template_name = 'openid/userpage.html'
76         self._take_args = True
77
78     def GET(self, *args, **kwargs):
79         if len(args) != 1:
80             raise cherrypy.NotFound()
81         name = args[0]
82         yadis = '%syadis/%s.xrds' % (self.cfg.endpoint_url, name)
83         cherrypy.response.headers['X-XRDS-Location'] = yadis
84
85         endpoint_url = self.cfg.endpoint_url
86         identity_url = self.cfg.identity_url_template % {'username': name}
87
88         HEAD_LINK = '<link rel="%s" href="%s">'
89         provider_heads = [HEAD_LINK % ('openid2.provider', endpoint_url),
90                           HEAD_LINK % ('openid.server', endpoint_url)]
91         user_heads = [HEAD_LINK % ('openid2.delegate', identity_url),
92                       HEAD_LINK % ('openid.local_id', identity_url)]
93         heads = {'provider': provider_heads, 'user': user_heads}
94
95         return self.reply(title='Userpage', username=name, heads=heads)