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