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