def __init__(self, data, keys=None): """ :param dict data: The formatted catalog data. :param keys: The keys to use for verifying remote data. :type keys: :py:class:`~king_phisher.security_keys.SecurityKeys` """ self.security_keys = keys or security_keys.SecurityKeys() """The :py:class:`~king_phisher.security_keys.SecurityKeys` used for verifying remote data.""" self.created = dateutil.parser.parse(data['created']) """The timestamp of when the remote data was generated.""" self.created_by = data['created-by'] self.id = data['id'] """The unique identifier of this catalog.""" self.maintainers = tuple(maintainer['id'] for maintainer in data['maintainers']) """ A tuple containing the maintainers of the catalog and repositories. These are also the key identities that should be present for verifying the remote data. """ self.repositories = dict( (repo['id'], Repository(repo, keys=self.security_keys)) for repo in data['repositories']) """A dict of the :py:class:`.Repository` objects included in this catalog keyed by their id.""" self.logger.info("initialized catalog with {0:,} repositories".format( len(self.repositories)))
def __init__(self, data, keys=None): """ :param dict data: The formatted repository data. :param keys: The keys to use for verifying remote data. :type keys: :py:class:`~king_phisher.security_keys.SecurityKeys` """ self.security_keys = keys or security_keys.SecurityKeys() """The :py:class:`~king_phisher.security_keys.SecurityKeys` used for verifying remote data.""" created = data.get('created') if isinstance(created, str): self.created = dateutil.parser.parse(created) else: self.created = None self._req_sess = requests.Session() self._req_sess.mount('file://', requests_file.FileAdapter()) self.description = data.get('description') self.homepage = data.get('homepage') """The URL of the homepage for this repository if it was specified.""" for key in ('title', 'url-base'): if isinstance(data.get(key), str) and data[key]: continue raise KeyError('repository data is missing non-empty string key: ' + key) self.title = data['title'] """The title string of this repository.""" self.url_base = data['url-base'] """The base URL string of files included in this repository.""" self.collections = utilities.FreezableDict() """The dictionary of the different collection types included in this repository.""" if 'collections-include' in data: # include-files is reversed so the dictionary can get .update()'ed and the first seen will be the value kept for include in reversed(data['collections-include']): include_data = self._fetch_json(include) if 'collections' not in include_data: self.logger.warning("included file {0} missing 'collections' entry".format(include['path'])) continue include_data = include_data['collections'] for collection_type in include.get('types', COLLECTION_TYPES): if collection_type not in include_data: continue collection = include_data.get(collection_type) if collection is None: continue self._add_collection_data(collection_type, collection) if 'collections' in data: for collection_type in COLLECTION_TYPES: collection = data['collections'].get(collection_type) if collection is None: continue self._add_collection_data(collection_type, collection) item_count = sum(len(collection) for collection in self.collections.values()) self.logger.debug("initialized catalog repository with {0} collection types and {1} total items".format(len(self.collections), item_count)) for collection_type, collection in self.collections.items(): collection.freeze() self.collections[collection_type] = Collection(self, collection_type, collection) self.collections.freeze()
def __init__(self, data, keys=None): """ :param dict data: The formatted repository data. :param keys: The keys to use for verifying remote data. :type keys: :py:class:`~king_phisher.security_keys.SecurityKeys` """ self.security_keys = keys or security_keys.SecurityKeys() """The :py:class:`~king_phisher.security_keys.SecurityKeys` used for verifying remote data.""" self._req_sess = requests.Session() self._req_sess.mount('file://', requests_file.FileAdapter()) self.description = data.get('description') self.homepage = data.get('homepage') """The URL of the homepage for this repository if it was specified.""" self.id = data['id'] """The unique identifier of this repository.""" self.title = data['title'] """The title string of this repository.""" self.url_base = data['url-base'] """The base URL string of files included in this repository.""" self.collections = utilities.FreezableDict() """The dictionary of the different collection types included in this repository.""" if 'collections-include' in data: # include-files is reversed so the dictionary can get .update()'ed and the first seen will be the value kept for include in reversed(data['collections-include']): include_data = self._fetch_json(include) utilities.validate_json_schema( include_data, 'king-phisher.catalog.collections') include_data = include_data['collections'] for collection_type in include.get('types', COLLECTION_TYPES): collection = include_data.get(collection_type) if collection is None: continue self._add_collection_data(collection_type, collection) if 'collections' in data: for collection_type in COLLECTION_TYPES: collection = data['collections'].get(collection_type) if collection is None: continue self._add_collection_data(collection_type, collection) item_count = sum( len(collection) for collection in self.collections.values()) self.logger.debug( "initialized catalog repository with {0} collection types and {1} total items" .format(len(self.collections), item_count)) for collection_type, collection in self.collections.items(): collection.freeze() self.collections[collection_type] = Collection( self, collection_type, collection) self.collections.freeze()
def from_url(cls, url, keys=None, encoding='utf-8'): """ Initialize a new :py:class:`.Catalog` object from a resource at the specified URL. :param str url: The URL to the catalog data to load. :param keys: The keys to use for verifying remote data. :type keys: :py:class:`~king_phisher.security_keys.SecurityKeys` :param str encoding: The encoding of the catalog data. :return: The new catalog instance. :rtype: :py:class:`.Catalog` """ keys = keys or security_keys.SecurityKeys() req_sess = requests.Session() req_sess.mount('file://', requests_file.FileAdapter()) cls.logger.debug('fetching catalog from: ' + url) resp = req_sess.get(url) data = resp.content.decode(encoding) data = serializers.JSON.loads(data) keys.verify_dict(data, signature_encoding='base64') return cls(data, keys=keys)
def __init__(self, data, keys=None): """ :param dict data: The formatted catalog data. :param keys: The keys to use for verifying remote data. :type keys: :py:class:`~king_phisher.security_keys.SecurityKeys` """ self.security_keys = keys or security_keys.SecurityKeys() """The :py:class:`~king_phisher.security_keys.SecurityKeys` used for verifying remote data.""" self.created = None """The timestamp of when the remote data was generated.""" created = data.get('created') if isinstance(created, str): self.created = dateutil.parser.parse(created) self.maintainers = tuple(maintainer['id'] for maintainer in data.get('maintainers', [])) """ A tuple containing the maintainers of the catalog and repositories. These are also the key identities that should be present for verifying the remote data. """ self.repositories = tuple(Repository(repo, keys=self.security_keys) for repo in data['repositories']) """A tuple of the :py:class:`.Repository` objects included in this catalog.""" self.logger.info("initialized catalog with {0:,} repositories".format(len(self.repositories)))