aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam Janovsky2020-11-24 11:05:52 +0100
committerAdam Janovsky2020-11-24 11:05:52 +0100
commit6bcfceb79b628953a505ee5e6df44569cf396e35 (patch)
tree9a318735cb88d65bf888defc199529ba23f46881
parentd73f9adf65ce237e026814fa4175533dcfc84b82 (diff)
downloadsec-certs-6bcfceb79b628953a505ee5e6df44569cf396e35.tar.gz
sec-certs-6bcfceb79b628953a505ee5e6df44569cf396e35.tar.zst
sec-certs-6bcfceb79b628953a505ee5e6df44569cf396e35.zip
Fix to_dict() copies, inherit serialization
The methods to_dict() in Certificate and Dataset classes and subclasses now use copy of their self.__dict__. Furthermore, if possible, to_dict() and from_dict() methods are now inherited from the superclass.
-rw-r--r--sec_certs/certificate.py30
-rw-r--r--sec_certs/dataset.py18
2 files changed, 15 insertions, 33 deletions
diff --git a/sec_certs/certificate.py b/sec_certs/certificate.py
index 2840cc75..5c33f9e9 100644
--- a/sec_certs/certificate.py
+++ b/sec_certs/certificate.py
@@ -4,15 +4,18 @@ from dataclasses import dataclass
import logging
from pathlib import Path
import os
+import copy
from . import helpers, extract_certificates
from abc import ABC, abstractmethod
from bs4 import Tag, BeautifulSoup, NavigableString
-from typing import Union, Optional, List, Dict, ClassVar
+from typing import Union, Optional, List, Dict, ClassVar, TypeVar, Type
class Certificate(ABC):
- def __init__(self):
+ T = TypeVar('T', bound='Certificate')
+
+ def __init__(self, *args, **kwargs):
pass
def __repr__(self) -> str:
@@ -30,12 +33,11 @@ class Certificate(ABC):
return self.dgst == other.dgst
def to_dict(self):
- return self.__dict__
+ return copy.deepcopy(self.__dict__)
@classmethod
- @abstractmethod
- def from_dict(cls, dct: dict) -> 'Certificate':
- raise NotImplementedError('Mot meant to be implemented')
+ def from_dict(cls: Type[T], dct: dict) -> T:
+ return cls(*tuple(dct.values()))
class FIPSCertificate(Certificate):
@@ -110,11 +112,6 @@ class FIPSCertificate(Certificate):
def dgst(self) -> str:
return self.cert_id
- @classmethod
- def from_dict(cls, dct: dict) -> 'FIPSCertificate':
- args = tuple(dct.values())
- return FIPSCertificate(*args)
-
@staticmethod
def extract_filename(file: str) -> str:
"""
@@ -338,7 +335,7 @@ class CommonCriteriaCert(Certificate):
super().__setattr__('maintainance_date', helpers.sanitize_date(self.maintainance_date))
def to_dict(self):
- return self.__dict__
+ return copy.deepcopy(self.__dict__)
@classmethod
def from_dict(cls, dct):
@@ -360,7 +357,7 @@ class CommonCriteriaCert(Certificate):
super().__setattr__('pp_link', helpers.sanitize_link(self.pp_link))
def to_dict(self):
- return self.__dict__
+ return copy.deepcopy(self.__dict__)
def __lt__(self, other):
return self.pp_name < other.pp_name
@@ -426,16 +423,11 @@ class CommonCriteriaCert(Certificate):
if self.src != other.src:
self.src = self.src + ' + ' + other.src
- def to_dict(self) -> dict:
- return self.__dict__
-
@classmethod
def from_dict(cls, dct: dict) -> 'CommonCriteriaCert':
dct['maintainance_updates'] = set(dct['maintainance_updates'])
dct['protection_profiles'] = set(dct['protection_profiles'])
- args = tuple(dct.values())
-
- return cls(*args)
+ return super(cls, CommonCriteriaCert).from_dict(dct)
@classmethod
def from_html_row(cls, row: Tag, category: str) -> 'CommonCriteriaCert':
diff --git a/sec_certs/dataset.py b/sec_certs/dataset.py
index 785e3977..73efd66a 100644
--- a/sec_certs/dataset.py
+++ b/sec_certs/dataset.py
@@ -1,6 +1,7 @@
import os
import re
from datetime import datetime, date
+import copy
from tabula import read_pdf
@@ -59,9 +60,9 @@ class Dataset(ABC):
pass
def to_dict(self):
- return {'root_dir': self.root_dir, 'timestamp': self.timestamp, 'sha256_digest': self.sha256_digest,
+ return copy.deepcopy({'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())}
+ 'description': self.description, 'n_certs': len(self), 'certs': list(self.certs.values())})
@classmethod
def from_dict(cls, dct: Dict):
@@ -200,7 +201,7 @@ class CCDataset(Dataset):
n_all = len(df_base)
n_deduplicated = len(df_base.drop_duplicates(subset=['dgst']))
- if n_dup := n_all - n_deduplicated > 0:
+ if (n_dup := n_all - n_deduplicated) > 0:
logging.warning(f'The CSV {file} contains {n_dup} duplicates by the primary key.')
df_base = df_base.drop_duplicates(subset=['dgst'])
@@ -328,17 +329,6 @@ class FIPSDataset(Dataset):
def fragments_dir(self) -> Path:
return self.root_dir / 'fragments'
- def to_dict(self):
- ## Different - we dont want list
- 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_dict(cls, dct: Dict):
- certs = {x.dgst: x for x in dct['certs']}
- return cls(certs, dct['root_dir'], dct['name'], dct['description'])
-
def find_empty_pdfs(self) -> (List, List):
missing = []
not_available = []