diff options
Diffstat (limited to 'ipsilon/providers/personaidp.py')
-rwxr-xr-x | ipsilon/providers/personaidp.py | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/ipsilon/providers/personaidp.py b/ipsilon/providers/personaidp.py new file mode 100755 index 0000000..355726d --- /dev/null +++ b/ipsilon/providers/personaidp.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# +# Copyright (C) 2014 Ipsilon project Contributors, for licensee see COPYING + +from __future__ import absolute_import + +from ipsilon.providers.common import ProviderBase +from ipsilon.util.plugin import PluginObject +from ipsilon.util import config as pconfig +from ipsilon.info.common import InfoMapping +from ipsilon.providers.persona.auth import Persona +from ipsilon.tools import files + +import json +import M2Crypto +import os + + +class IdpProvider(ProviderBase): + + def __init__(self, *pargs): + super(IdpProvider, self).__init__('persona', 'persona', *pargs) + self.mapping = InfoMapping() + self.page = None + self.basepath = None + self.key = None + self.key_info = None + self.description = """ +Provides Persona authentication infrastructure. """ + + self.new_config( + self.name, + pconfig.String( + 'issuer domain', + 'The issuer domain of the Persona provider', + 'localhost'), + pconfig.String( + 'idp key file', + 'The key where the Persona key is stored.', + 'persona.key'), + pconfig.List( + 'allowed domains', + 'List of domains this IdP is willing to issue claims for.'), + ) + + @property + def issuer_domain(self): + return self.get_config_value('issuer domain') + + @property + def idp_key_file(self): + return self.get_config_value('idp key file') + + @property + def allowed_domains(self): + return self.get_config_value('allowed domains') + + def get_tree(self, site): + self.init_idp() + self.page = Persona(site, self) + # self.admin = AdminPage(site, self) + + return self.page + + def init_idp(self): + # Init IDP data + try: + self.key = M2Crypto.RSA.load_key(self.idp_key_file, + lambda *args: None) + except Exception, e: # pylint: disable=broad-except + self._debug('Failed to init Persona provider: %r' % e) + return None + + def on_enable(self): + super(IdpProvider, self).on_enable() + self.init_idp() + + +class Installer(object): + + def __init__(self, *pargs): + self.name = 'persona' + self.ptype = 'provider' + self.pargs = pargs + + def install_args(self, group): + group.add_argument('--persona', choices=['yes', 'no'], default='yes', + help='Configure Persona Provider') + + def configure(self, opts): + if opts['persona'] != 'yes': + return + + # Check storage path is present or create it + path = os.path.join(opts['data_dir'], 'persona') + if not os.path.exists(path): + os.makedirs(path, 0700) + + keyfile = os.path.join(path, 'persona.key') + exponent = 0x10001 + key = M2Crypto.RSA.gen_key(2048, exponent) + key.save_key(keyfile, cipher=None) + key_n = 0 + for c in key.n[4:]: + key_n = (key_n*256) + ord(c) + wellknown = dict() + wellknown['authentication'] = '/%s/persona/SignIn/' % opts['instance'] + wellknown['provisioning'] = '/%s/persona/' % opts['instance'] + wellknown['public-key'] = {'algorithm': 'RS', + 'e': str(exponent), + 'n': str(key_n)} + with open(os.path.join(opts['wellknown_dir'], 'browserid'), 'w') as f: + f.write(json.dumps(wellknown)) + + # Add configuration data to database + po = PluginObject(*self.pargs) + po.name = 'persona' + po.wipe_data() + po.wipe_config_values() + config = {'issuer domain': opts['hostname'], + 'idp key file': keyfile, + 'allowed domains': opts['hostname']} + po.save_plugin_config(config) + + # Update global config to add login plugin + po.is_enabled = True + po.save_enabled_state() + + # Fixup permissions so only the ipsilon user can read these files + files.fix_user_dirs(path, opts['system_user']) |