Add OpenIDP Provider
[cascardo/ipsilon.git] / ipsilon / providers / openidp.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2014  Ipsilon project Contributors, for licensee see COPYING
4
5 from __future__ import absolute_import
6
7 from ipsilon.providers.common import ProviderBase
8 from ipsilon.providers.common import FACILITY
9 from ipsilon.providers.openid.auth import OpenID
10 from ipsilon.providers.openid.extensions.common import LoadExtensions
11 from ipsilon.util.plugin import PluginObject
12
13 from openid.server.server import Server
14 # TODO: Move this to the database
15 from openid.store.memstore import MemoryStore
16
17
18 class IdpProvider(ProviderBase):
19
20     def __init__(self):
21         super(IdpProvider, self).__init__('openid', 'openid')
22         self.page = None
23         self.server = None
24         self.basepath = None
25         self.extensions = None
26         self.description = """
27 Provides OpenID 2.0 authentication infrastructure. """
28
29         self._options = {
30             'default email domain': [
31                 """Default email domain, for users missing email property.""",
32                 'string',
33                 'example.com'
34             ],
35             'endpoint url': [
36                 """The Absolute URL of the OpenID provider""",
37                 'string',
38                 'http://localhost:8080/idp/openid/'
39             ],
40             'identity url template': [
41                 """The templated URL where identities are exposed.""",
42                 'string',
43                 'http://localhost:8080/idp/openid/id/%(username)s'
44             ],
45             'trusted roots': [
46                 """List of trusted relying parties.""",
47                 'list',
48                 []
49             ],
50             'untrusted roots': [
51                 """List of untrusted relying parties.""",
52                 'list',
53                 []
54             ],
55             'enabled extensions': [
56                 """List of enabled extensions""",
57                 'list',
58                 []
59             ],
60         }
61
62     @property
63     def endpoint_url(self):
64         url = self.get_config_value('endpoint url')
65         if url.endswith('/'):
66             return url
67         else:
68             return url+'/'
69
70     @property
71     def default_email_domain(self):
72         return self.get_config_value('default email domain')
73
74     @property
75     def identity_url_template(self):
76         url = self.get_config_value('identity url template')
77         if url.endswith('/'):
78             return url
79         else:
80             return url+'/'
81
82     @property
83     def trusted_roots(self):
84         return self.get_config_value('trusted roots')
85
86     @property
87     def untrusted_roots(self):
88         return self.get_config_value('untrusted roots')
89
90     @property
91     def enabled_extensions(self):
92         return self.get_config_value('enabled extensions')
93
94     def get_tree(self, site):
95         self.init_idp()
96         self.page = OpenID(site, self)
97         # self.admin = AdminPage(site, self)
98
99         # Expose OpenID presence in the root
100         headers = site[FACILITY]['root'].default_headers
101         headers['X-XRDS-Location'] = self.endpoint_url+'XRDS'
102
103         html_heads = site[FACILITY]['root'].html_heads
104         HEAD_LINK = '<link rel="%s" href="%s">'
105         openid_heads = [HEAD_LINK % ('openid2.provider', self.endpoint_url),
106                         HEAD_LINK % ('openid.server', self.endpoint_url)]
107         html_heads['openid'] = openid_heads
108
109         return self.page
110
111     def init_idp(self):
112         self.server = Server(MemoryStore(), op_endpoint=self.endpoint_url)
113         loader = LoadExtensions(self.enabled_extensions)
114         self.extensions = loader.get_extensions()
115
116     def on_enable(self):
117         self.init_idp()
118
119
120 class Installer(object):
121
122     def __init__(self):
123         self.name = 'openid'
124         self.ptype = 'provider'
125
126     def install_args(self, group):
127         group.add_argument('--openid', choices=['yes', 'no'], default='yes',
128                            help='Configure OpenID Provider')
129
130     def configure(self, opts):
131         if opts['openid'] != 'yes':
132             return
133
134         proto = 'https'
135         if opts['secure'].lower() == 'no':
136             proto = 'http'
137         url = '%s://%s/%s/openid/' % (
138             proto, opts['hostname'], opts['instance'])
139
140         # Add configuration data to database
141         po = PluginObject()
142         po.name = 'openid'
143         po.wipe_data()
144
145         po.wipe_config_values(FACILITY)
146         config = {'endpoint url': url,
147                   'identity_url_template': '%sid/%%(username)s' % url,
148                   'enabled': '1'}
149         po.set_config(config)
150         po.save_plugin_config(FACILITY)