class FSJWKSBundle(JWKSBundle): """ A JWKSBundle that keeps the key information in a :py:class:`fedoidc.file_system.FileSystem` instance. """ def __init__(self, iss, sign_keys=None, fdir='./', key_conv=None): """ :param iss: Issuer ID for this entity :param sign_keys: Signing Keys used by this entity to sign JWTs :param fdir: A directory where JWKS can be stored :param key_conv: Specification of directory key to file name conversion. A set of keys are represented in the local cache as a KeyJar instance and as a JWKS on disc. """ JWKSBundle.__init__(self, iss, sign_keys=sign_keys) self.bundle = FileSystem(fdir, key_conv=key_conv, value_conv={ 'to': keyjar_to_jwks, 'from': jwks_to_keyjar }) def clear(self): self.bundle.clear()
def test_keys_items(): if os.path.isdir(ROOT): shutil.rmtree(ROOT) fs = FileSystem(ROOT) fs['1'] = 'on' assert list(fs.keys()) == ['1'] assert dict([(k, v) for k, v in fs.items()]) == {'1': 'on'}
def test_create_reconnect(): if os.path.isdir(ROOT): shutil.rmtree(ROOT) fs = FileSystem(ROOT) fs['1'] = 'on' fs2 = FileSystem(ROOT) assert list(fs2.keys()) == ['1'] assert dict([(k, v) for k, v in fs2.items()]) == {'1': 'on'}
def setup(keydefs, tool_iss, liss, csms_def, oa, ms_path): sig_keys = build_keyjar(keydefs)[1] key_bundle = make_fs_jwks_bundle(tool_iss, liss, sig_keys, keydefs, './') sig_keys = build_keyjar(keydefs)[1] jb = FSJWKSBundle(tool_iss, sig_keys, 'fo_jwks', key_conv={ 'to': quote_plus, 'from': unquote_plus }) # Need to save the private parts jb.bundle.value_conv['to'] = keyjar_to_jwks_private jb.bundle.sync() operator = {} for entity, _keyjar in jb.items(): operator[entity] = Operator(iss=entity, keyjar=_keyjar) signers = {} for sig, sms_def in csms_def.items(): ms_dir = os.path.join(ms_path, sig) metadata_statements = FileSystem(ms_dir) for name, spec in sms_def.items(): res = make_signed_metadata_statement(spec, operator) metadata_statements[name] = res['ms'] _iss = oa[sig] signers[_iss] = Signer( InternalSigningService(_iss, operator[_iss].keyjar), ms_dir) return signers, key_bundle
def __init__(self, signing_service=None, ms_dir=None, def_context=''): """ :param signing_service: Which signing service this signer can use. :param ms_dir: Where the file copies of the signed metadata statements are kept. Storing/retrieving the signed metadata statements are handled by :py:class:`fedoidc.file_system.FileSystem` instances. One per operations where they are expected to used. :param def_context: Default operation, one out of :py:data:`fedoidc.CONTEXTS` """ self.metadata_statements = {} if isinstance(ms_dir, dict): for key, _dir in ms_dir.items(): if key not in CONTEXTS: raise ValueError('{} not expected operation'.format(key)) self.metadata_statements[key] = FileSystem(_dir, key_conv={ 'to': quote_plus, 'from': unquote_plus }) elif ms_dir: for item in os.listdir(ms_dir): if item not in CONTEXTS: raise ValueError('{} not expected operation'.format(item)) _dir = os.path.join(ms_dir, item) if os.path.isdir(_dir): self.metadata_statements[item] = FileSystem( _dir, key_conv={ 'to': quote_plus, 'from': unquote_plus }) else: self.metadata_statements = MIN_SET self.signing_service = signing_service self.def_context = def_context
def test_detect_change(): if os.path.isdir(ROOT): shutil.rmtree(ROOT) fs = FileSystem(ROOT) fs['1'] = 'one' fs['2'] = 'two' fname = os.path.join(ROOT, '3') fp = open(fname, 'w') fp.write('Three') fp.close() sleep(1) # can't detect changes within 1 second fname = os.path.join(ROOT, '2') fp = open(fname, 'w') fp.write('twee') fp.close() assert set(fs.keys()) == {'1', '2', '3'} assert dict([(k, v) for k, v in fs.items()]) == {'1': 'one', '2': 'twee', '3': 'Three'}
def setup_ms(csms_def, ms_path, mds_dir, base_url, operators): """ :param csms_def: Definition of which signed metadata statements to build :param ms_path: Where to store the signed metadata statements and uris :param mds_dir: Directory where singed metadata statements published using ms_uri are kept :param base_url: Common base URL to all metadata_statement_uris :param operators: Dictionary with federation Operators :return: A tuple of (Signer dictionary and FSJWKSBundle instance) """ mds = MetaDataStore(mds_dir) mds.clear() for iss, sms_def in csms_def.items(): ms_dir = os.path.join(ms_path, quote_plus(iss)) for context, spec in sms_def.items(): _dir = os.path.join(ms_dir, context) metadata_statements = FileSystem(_dir, key_conv={ 'to': quote_plus, 'from': unquote_plus }) metadata_statements.clear() for fo, _desc in spec.items(): res = make_signed_metadata_statement(_desc, operators, mds, base_url) try: metadata_statements.update(res['ms']) except KeyError: pass try: metadata_statements.update(res['ms_uri']) except KeyError: pass signers = {} for iss, sms_def in csms_def.items(): ms_dir = os.path.join(ms_path, quote_plus(iss)) signers[iss] = Signer( InternalSigningService(iss, operators[iss].keyjar), ms_dir) return signers
def test_create(): if os.path.isdir(ROOT): shutil.rmtree(ROOT) fs = FileSystem(ROOT) fs['1'] = 'on' # should be a directory there now with one file assert os.path.isdir(ROOT) assert len(os.listdir(ROOT)) == 1 # and that file should be name '1' and should contain 'on' fname = os.path.join(ROOT, '1') _dat = open(fname, 'r').read() assert _dat == 'on'
} } } KEY_DEFS = [{ "type": "RSA", "key": '', "use": ["sig"] }, { "type": "EC", "crv": "P-256", "use": ["sig"] }] MS_DIR = 'ms_dir_10' fs = FileSystem(MS_DIR) fs.reset() if os.path.isdir('mds'): shutil.rmtree('mds') liss = list(FO.values()) liss.extend(list(OA.values())) signer, keybundle = test_utils.setup(KEY_DEFS, TOOL_ISS, liss, ms_path=MS_DIR, csms_def=SMS_DEF, mds_dir='mds', base_url='https://localhost')
parser.add_argument('-c', dest='test_tool_conf') parser.add_argument('-d', dest='debug', action='store_true') parser.add_argument('-k', dest='insecure', action='store_true') parser.add_argument('-p', dest='port', default=80, type=int) parser.add_argument('-P', dest='path') parser.add_argument('-H', dest='htmldir') parser.add_argument('-t', dest='tls', action='store_true') parser.add_argument(dest="config") args = parser.parse_args() _conf = importlib.import_module(args.config) _ttc = importlib.import_module(args.test_tool_conf) folder = os.path.abspath(os.curdir) _html = FileSystem(args.htmldir) _html.sync() cherrypy.tools.dumplog = cherrypy.Tool('before_finalize', dump_log) cherrypy.config.update({ 'environment': 'production', 'log.error_file': 'site.log', 'tools.trailing_slash.on': False, 'log.screen': True, 'tools.sessions.on': True, 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', 'tools.dumplog.on': True, 'server.socket_host': '0.0.0.0', # listen on all interfaces 'server.socket_port': args.port
'to': quote_plus, 'from': unquote_plus }) jb.bundle.sync() operator = {} for entity, _keyjar in jb.items(): operator[entity] = Operator(iss=entity, keyjar=_keyjar) name = 'https://bogus.example.org' _dir = os.path.join('ms_path', quote_plus(name), 'discovery') metadata_statements = FileSystem(_dir, key_conv={ 'to': quote_plus, 'from': unquote_plus }) fo = "https://edugain.com" # What I want to create is something like # (ms_OA + SK[X]) _kj = build_keyjar(config.KEY_DEFS)[1] req = MetadataStatement( federation_usage='discovery', signing_keys={'keys': [x.serialize() for x in _kj.get_signing_key()]}) # FO(ms_OA + SK[X]) _fo_signer = operator[fo]
}, '/requests': { 'tools.staticdir.dir': 'requests', 'tools.staticdir.debug': True, 'tools.staticdir.on': True, }, '/favicon.ico': { 'tools.staticfile.on': True, 'tools.staticfile.filename': os.path.join(folder, 'static/favicon.ico') } } _conf = importlib.import_module(args.config) if args.htmldir: _html = FileSystem(args.htmldir) else: _html = FileSystem(_conf.PRE_HTML) _html.sync() rest = REST('') webenv = make_webenv(_conf, rest) session_handler = SessionHandler(args.issuer, args.tag, flows=webenv['flow_state'], rest=rest, version=_vers, **webenv) session_handler.iss = args.issuer session_handler.tag = args.tag
} } } KEY_DEFS = [{ "type": "RSA", "key": '', "use": ["sig"] }, { "type": "EC", "crv": "P-256", "use": ["sig"] }] MS_DIR = 'ms_dir_10' fs = FileSystem(MS_DIR) fs.clear() if os.path.isdir('mds'): shutil.rmtree('mds') liss = list(FO.values()) liss.extend(list(OA.values())) signer, keybundle = test_utils.setup(KEY_DEFS, TOOL_ISS, liss, ms_path=MS_DIR, csms_def=SMS_DEF, mds_dir='mds', base_url='https://localhost')