diff options
| author | Adam Janovsky | 2020-11-16 11:20:22 +0100 |
|---|---|---|
| committer | Adam Janovsky | 2020-11-16 11:20:22 +0100 |
| commit | 629a99b49c4a0f5cf02a44dcc131e9c159c2f5cf (patch) | |
| tree | 0b0d4eb0b3dea6c7aed4cf7c023268318f0da672 | |
| parent | 069b98ccaf01432c6163fad26c23371532b1112c (diff) | |
| download | sec-certs-629a99b49c4a0f5cf02a44dcc131e9c159c2f5cf.tar.gz sec-certs-629a99b49c4a0f5cf02a44dcc131e9c159c2f5cf.tar.zst sec-certs-629a99b49c4a0f5cf02a44dcc131e9c159c2f5cf.zip | |
added deserialization from json
| -rw-r--r-- | sec_certs/certificate.py | 33 | ||||
| -rw-r--r-- | sec_certs/dataset.py | 34 |
2 files changed, 48 insertions, 19 deletions
diff --git a/sec_certs/certificate.py b/sec_certs/certificate.py index 91b9fb97..9ec073c2 100644 --- a/sec_certs/certificate.py +++ b/sec_certs/certificate.py @@ -74,21 +74,29 @@ class CommonCriteriaCert(Certificate): def to_dict(self): return self.__dict__ + @classmethod + def from_dict(cls, dct): + return cls(*tuple(dct.values())) + @dataclass(eq=True, frozen=True) class ProtectionProfile: """ Object for holding protection profiles. """ - name: str - link: Optional[str] + pp_name: str + pp_link: Optional[str] def __post_init__(self): - super().__setattr__('name', helpers.sanitize_string(self.name)) - super().__setattr__('link', helpers.sanitize_link(self.link)) + super().__setattr__('pp_name', helpers.sanitize_string(self.pp_name)) + super().__setattr__('pp_link', helpers.sanitize_link(self.pp_link)) def to_dict(self): return self.__dict__ + @classmethod + def from_dict(cls, dct): + return cls(*tuple(dct.values())) + def __init__(self, category: str, name: str, manufacturer: str, scheme: str, security_level: Union[str, set], not_valid_before: date, not_valid_after: date, report_link: str, st_link: str, src: str, cert_link: Optional[str], @@ -110,7 +118,7 @@ class CommonCriteriaCert(Certificate): self.cert_link = helpers.sanitize_link(cert_link) self.manufacturer_web = helpers.sanitize_link(manufacturer_web) self.protection_profiles = protection_profiles - self.maintainances = maintainance_updates + self.maintainance_updates = maintainance_updates @property def dgst(self) -> str: @@ -133,10 +141,9 @@ class CommonCriteriaCert(Certificate): setattr(self, att, getattr(other, att)) elif self.src == 'csv' and other.src == 'html' and att == 'protection_profiles': setattr(self, att, getattr(other, att)) - elif att == 'maintainances': - # TODO Fix me: This is a simplification. Basically take the longer list of maintainances as a ground truth. - if len(getattr(self, att)) < len(getattr(other, att)): - setattr(self, att, getattr(other, att)) + elif self.src == 'csv' and other.src == 'html' and att == 'maintainance_updates': + # TODO Fix me: This is a simplification. At the moment html contains more reliable info + setattr(self, att, getattr(other, att)) elif att == 'src': pass # This is expected else: @@ -150,8 +157,12 @@ class CommonCriteriaCert(Certificate): @classmethod def from_dict(cls, dct: dict) -> 'CommonCriteriaCert': - # TODO: Implement me - pass + dct['maintainance_updates'] = set(dct['maintainance_updates']) + dct['protection_profiles'] = set(dct['protection_profiles']) + + args = tuple(dct.values()) + + return cls(*args) @classmethod def from_html_row(cls, row: Tag, category: str) -> 'CommonCriteriaCert': diff --git a/sec_certs/dataset.py b/sec_certs/dataset.py index a0b8f030..b50285c5 100644 --- a/sec_certs/dataset.py +++ b/sec_certs/dataset.py @@ -20,25 +20,41 @@ class DatasetJSONEncoder(json.JSONEncoder): return list(obj) if isinstance(obj, date): return str(obj) + if isinstance(obj, Path): + return str(obj) if isinstance(obj, CommonCriteriaCert.ProtectionProfile): return obj.to_dict() if isinstance(obj, CommonCriteriaCert.MaintainanceReport): return obj.to_dict() if isinstance(obj, Dataset): - return list(obj.certs.values()) + return obj.to_dict() return super().default(obj) +class DatasetJSONDecoder(json.JSONDecoder): + def __init__(self, *args, **kwargs): + json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **kwargs) + + def object_hook(self, obj): + if 'root_dir' in obj: # TODO: This is a heavy simplification + return CCDataset.from_dict(obj) + if 'pp_name' in obj and 'pp_link' in obj: + return CommonCriteriaCert.ProtectionProfile.from_dict(obj) + if 'maintainance_date' in obj and 'maintainance_title' in obj and 'maintainance_report_link' in obj and 'maintainance_st_link': + return CommonCriteriaCert.MaintainanceReport.from_dict(obj) + if 'category' in obj: # TODO: This is heavy simplification. + return CommonCriteriaCert.from_dict(obj) + + class Dataset(ABC): def __init__(self, certs: dict, root_dir: Path, name: str = 'dataset name', description: str = 'dataset_description'): - self.certs = certs self.root_dir = root_dir - self.timestamp = datetime.now() self.sha256_digest = 'not implemented' self.name = name self.description = description + self.certs = certs def __iter__(self): for cert in self.certs.values(): @@ -59,18 +75,20 @@ class Dataset(ABC): def __str__(self) -> str: return 'Not implemented' - def to_json(self): - pass - def to_csv(self): pass def to_dataframe(self): pass + def to_dict(self): + return {'root_dir': self.root_dir, 'timestamp': self.timestamp, 'sha256_digest': self.sha256_digest, 'name': self.name, + 'description': self.description, 'n_certs': len(self), 'certs': list(self.certs.values())} + @classmethod - def from_json(cls): - pass + def from_dict(cls, dct: Dict): + certs = {x.dgst: x for x in dct['certs']} + return cls(certs, dct['root_dir'], dct['name'], dct['description']) @classmethod def from_csv(cls): |
