diff options
Diffstat (limited to 'sec_certs/sample')
| -rw-r--r-- | sec_certs/sample/cc_maintenance_update.py | 2 | ||||
| -rw-r--r-- | sec_certs/sample/common_criteria.py | 79 | ||||
| -rw-r--r-- | sec_certs/sample/cpe.py | 3 | ||||
| -rw-r--r-- | sec_certs/sample/fips.py | 192 | ||||
| -rw-r--r-- | sec_certs/sample/fips_iut.py | 2 | ||||
| -rw-r--r-- | sec_certs/sample/fips_mip.py | 2 | ||||
| -rw-r--r-- | sec_certs/sample/protection_profile.py | 10 | ||||
| -rw-r--r-- | sec_certs/sample/sar.py | 7 |
8 files changed, 94 insertions, 203 deletions
diff --git a/sec_certs/sample/cc_maintenance_update.py b/sec_certs/sample/cc_maintenance_update.py index 81b9447b..4196c157 100644 --- a/sec_certs/sample/cc_maintenance_update.py +++ b/sec_certs/sample/cc_maintenance_update.py @@ -2,7 +2,7 @@ import logging from datetime import date from typing import ClassVar, Dict, List, Optional, Tuple -import sec_certs.helpers as helpers +import sec_certs.utils.helpers as helpers from sec_certs.sample.common_criteria import CommonCriteriaCert from sec_certs.serialization.json import ComplexSerializableType diff --git a/sec_certs/sample/common_criteria.py b/sec_certs/sample/common_criteria.py index ca935c02..2b594b4e 100644 --- a/sec_certs/sample/common_criteria.py +++ b/sec_certs/sample/common_criteria.py @@ -14,21 +14,24 @@ import numpy as np import requests from bs4 import Tag +import sec_certs.utils.extract +import sec_certs.utils.pdf +import sec_certs.utils.sanitization from sec_certs import constants as constants -from sec_certs import helpers -from sec_certs.cert_rules import SARS_IMPLIED_FROM_EAL, security_level_csv_scan +from sec_certs.cert_rules import SARS_IMPLIED_FROM_EAL, cc_rules, security_level_csv_scan from sec_certs.sample.certificate import Certificate, Heuristics, References, logger from sec_certs.sample.protection_profile import ProtectionProfile from sec_certs.sample.sar import SAR from sec_certs.serialization.json import ComplexSerializableType from sec_certs.serialization.pandas import PandasSerializableType +from sec_certs.utils import helpers HEADERS = { - "anssi": helpers.search_only_headers_anssi, - "bsi": helpers.search_only_headers_bsi, - "nscib": helpers.search_only_headers_nscib, - "niap": helpers.search_only_headers_niap, - "canada": helpers.search_only_headers_canada, + "anssi": sec_certs.utils.extract.search_only_headers_anssi, + "bsi": sec_certs.utils.extract.search_only_headers_bsi, + "nscib": sec_certs.utils.extract.search_only_headers_nscib, + "niap": sec_certs.utils.extract.search_only_headers_niap, + "canada": sec_certs.utils.extract.search_only_headers_canada, } @@ -64,10 +67,16 @@ class CommonCriteriaCert( maintenance_st_link: Optional[str] def __post_init__(self): - super().__setattr__("maintenance_report_link", helpers.sanitize_link(self.maintenance_report_link)) - super().__setattr__("maintenance_st_link", helpers.sanitize_link(self.maintenance_st_link)) - super().__setattr__("maintenance_title", helpers.sanitize_string(self.maintenance_title)) - super().__setattr__("maintenance_date", helpers.sanitize_date(self.maintenance_date)) + super().__setattr__( + "maintenance_report_link", sec_certs.utils.sanitization.sanitize_link(self.maintenance_report_link) + ) + super().__setattr__( + "maintenance_st_link", sec_certs.utils.sanitization.sanitize_link(self.maintenance_st_link) + ) + super().__setattr__( + "maintenance_title", sec_certs.utils.sanitization.sanitize_string(self.maintenance_title) + ) + super().__setattr__("maintenance_date", sec_certs.utils.sanitization.sanitize_date(self.maintenance_date)) @classmethod def from_dict(cls, dct: Dict) -> CommonCriteriaCert.MaintenanceReport: @@ -277,8 +286,13 @@ class CommonCriteriaCert( return None @property - def keywords_rules_cert_id(self) -> Optional[Dict[str, Optional[Dict[str, Dict[str, int]]]]]: - return self.report_keywords.get("rules_cert_id", None) if self.report_keywords else None + def keywords_rules_cert_id(self) -> Optional[Dict[str, int]]: + if not self.report_keywords: + return None + cert_id_matches = self.report_keywords.get("cc_cert_id", None) + if not cert_id_matches: + return None + return sec_certs.utils.extract.flatten_matches(cert_id_matches) @property def keywords_cert_id(self) -> Optional[str]: @@ -373,20 +387,20 @@ class CommonCriteriaCert( self.status = status self.category = category - self.name = helpers.sanitize_string(name) + self.name = sec_certs.utils.sanitization.sanitize_string(name) self.manufacturer = None if manufacturer: - self.manufacturer = helpers.sanitize_string(manufacturer) + self.manufacturer = sec_certs.utils.sanitization.sanitize_string(manufacturer) self.scheme = scheme - self.security_level = helpers.sanitize_security_levels(security_level) - self.not_valid_before = helpers.sanitize_date(not_valid_before) - self.not_valid_after = helpers.sanitize_date(not_valid_after) - self.report_link = helpers.sanitize_link(report_link) - self.st_link = helpers.sanitize_link(st_link) - self.cert_link = helpers.sanitize_link(cert_link) - self.manufacturer_web = helpers.sanitize_link(manufacturer_web) + self.security_level = sec_certs.utils.sanitization.sanitize_security_levels(security_level) + self.not_valid_before = sec_certs.utils.sanitization.sanitize_date(not_valid_before) + self.not_valid_after = sec_certs.utils.sanitization.sanitize_date(not_valid_after) + self.report_link = sec_certs.utils.sanitization.sanitize_link(report_link) + self.st_link = sec_certs.utils.sanitization.sanitize_link(st_link) + self.cert_link = sec_certs.utils.sanitization.sanitize_link(cert_link) + self.manufacturer_web = sec_certs.utils.sanitization.sanitize_link(manufacturer_web) self.protection_profiles = protection_profiles self.maintenance_updates = maintenance_updates self.state = self.InternalState() if not state else state @@ -728,7 +742,7 @@ class CommonCriteriaCert( :param CommonCriteriaCert cert: cert to download the pdf report for :return CommonCriteriaCert: the modified certificate with updated state """ - exit_code = helpers.convert_pdf_file(cert.state.report_pdf_path, cert.state.report_txt_path) + exit_code = sec_certs.utils.pdf.convert_pdf_file(cert.state.report_pdf_path, cert.state.report_txt_path) if exit_code != constants.RETURNCODE_OK: error_msg = "failed to convert report pdf->txt" logger.error(f"Cert dgst: {cert.dgst}" + error_msg) @@ -746,7 +760,7 @@ class CommonCriteriaCert( :param CommonCriteriaCert cert: cert to download the pdf security target for :return CommonCriteriaCert: the modified certificate with updated state """ - exit_code = helpers.convert_pdf_file(cert.state.st_pdf_path, cert.state.st_txt_path) + exit_code = sec_certs.utils.pdf.convert_pdf_file(cert.state.st_pdf_path, cert.state.st_txt_path) if exit_code != constants.RETURNCODE_OK: error_msg = "failed to convert security target pdf->txt" logger.error(f"Cert dgst: {cert.dgst}" + error_msg) @@ -764,7 +778,7 @@ class CommonCriteriaCert( :param CommonCriteriaCert cert: cert to extract the metadata for. :return CommonCriteriaCert: the modified certificate with updated state """ - response, cert.pdf_data.st_metadata = helpers.extract_pdf_metadata(cert.state.st_pdf_path) + response, cert.pdf_data.st_metadata = sec_certs.utils.pdf.extract_pdf_metadata(cert.state.st_pdf_path) if response != constants.RETURNCODE_OK: cert.state.st_extract_ok = False cert.state.errors.append(response) @@ -778,7 +792,7 @@ class CommonCriteriaCert( :param CommonCriteriaCert cert: cert to extract the metadata for. :return CommonCriteriaCert: the modified certificate with updated state """ - response, cert.pdf_data.report_metadata = helpers.extract_pdf_metadata(cert.state.report_pdf_path) + response, cert.pdf_data.report_metadata = sec_certs.utils.pdf.extract_pdf_metadata(cert.state.report_pdf_path) if response != constants.RETURNCODE_OK: cert.state.report_extract_ok = False cert.state.errors.append(response) @@ -835,9 +849,11 @@ class CommonCriteriaCert( :param CommonCriteriaCert cert: certificate to extract the keywords for. :return CommonCriteriaCert: the modified certificate with extracted keywords. """ - response, cert.pdf_data.report_keywords = helpers.extract_keywords(cert.state.report_txt_path) - if response != constants.RETURNCODE_OK: + report_keywords = sec_certs.utils.extract.extract_keywords(cert.state.report_txt_path, cc_rules) + if report_keywords is None: cert.state.report_extract_ok = False + else: + cert.pdf_data.report_keywords = report_keywords return cert @staticmethod @@ -849,10 +865,11 @@ class CommonCriteriaCert( :param CommonCriteriaCert cert: certificate to extract the keywords for. :return CommonCriteriaCert: the modified certificate with extracted keywords. """ - response, cert.pdf_data.st_keywords = helpers.extract_keywords(cert.state.st_txt_path) - if response != constants.RETURNCODE_OK: + st_keywords = sec_certs.utils.extract.extract_keywords(cert.state.st_txt_path, cc_rules) + if st_keywords is None: cert.state.st_extract_ok = False - cert.state.errors.append(response) + else: + cert.pdf_data.st_keywords = st_keywords return cert def compute_heuristics_version(self) -> None: diff --git a/sec_certs/sample/cpe.py b/sec_certs/sample/cpe.py index bbbf1c39..4a026ce1 100644 --- a/sec_certs/sample/cpe.py +++ b/sec_certs/sample/cpe.py @@ -2,9 +2,10 @@ from dataclasses import dataclass from functools import lru_cache from typing import Any, ClassVar, Dict, List, Optional, Tuple -from sec_certs import constants, helpers +from sec_certs import constants from sec_certs.serialization.json import ComplexSerializableType from sec_certs.serialization.pandas import PandasSerializableType +from sec_certs.utils import helpers @dataclass(init=False) diff --git a/sec_certs/sample/fips.py b/sec_certs/sample/fips.py index cd38af6b..6d9b0589 100644 --- a/sec_certs/sample/fips.py +++ b/sec_certs/sample/fips.py @@ -5,7 +5,7 @@ import re from dataclasses import dataclass, field from datetime import datetime from pathlib import Path -from typing import Any, ClassVar, Dict, List, Match, Optional, Pattern, Set, Tuple, Union +from typing import Any, ClassVar, Dict, List, Optional, Pattern, Set, Tuple, Union import requests from bs4 import BeautifulSoup, NavigableString, Tag @@ -13,14 +13,16 @@ from dateutil import parser from tabula import read_pdf import sec_certs.constants as constants -from sec_certs import helpers -from sec_certs.cert_rules import fips_common_rules, fips_rules +import sec_certs.utils.extract +import sec_certs.utils.helpers as helpers +import sec_certs.utils.pdf +import sec_certs.utils.tables +from sec_certs.cert_rules import fips_rules from sec_certs.config.configuration import config -from sec_certs.constants import LINE_SEPARATOR -from sec_certs.helpers import fips_dgst, load_cert_file, normalize_match_string, save_modified_cert_file from sec_certs.sample.certificate import Certificate, Heuristics, References, logger from sec_certs.sample.cpe import CPE from sec_certs.serialization.json import ComplexSerializableType +from sec_certs.utils.helpers import fips_dgst class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuristics"], ComplexSerializableType): @@ -542,7 +544,7 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris items_found = FIPSCertificate._initialize_dictionary() items_found["cert_id"] = int(file.stem) - text = helpers.load_cert_html_file(str(file)) + text = sec_certs.utils.extract.load_cert_html_file(str(file)) soup = BeautifulSoup(text, "html.parser") for div in soup.find_all("div", class_="row padrow"): FIPSCertificate._parse_html_main(div, items_found, pairs) @@ -612,7 +614,7 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris """ cert, pdf_path, txt_path = tup if not cert.state.txt_state: - exit_code = helpers.convert_pdf_file(pdf_path, txt_path) + exit_code = sec_certs.utils.pdf.convert_pdf_file(pdf_path, txt_path) if exit_code != constants.RETURNCODE_OK: logger.error(f"Cert dgst: {cert.cert_id} failed to convert security policy pdf->txt") cert.state.txt_state = False @@ -621,43 +623,12 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris return cert @staticmethod - def _declare_state(text: str) -> bool: - """ - If less then half of the text is formed of alphabet characters, - we declare the security policy as "non-parsable" - :param text: security policy content - :return: True if parsable, otherwise False - """ - return len(text) * 0.5 <= len("".join(filter(str.isalpha, text))) - - @staticmethod def find_keywords(cert: FIPSCertificate) -> Tuple[Optional[Dict], FIPSCertificate]: if not cert.state.txt_state: return None, cert - text, text_with_newlines, unicode_error = load_cert_file( - cert.state.sp_path.with_suffix(".pdf.txt"), -1, LINE_SEPARATOR - ) - - text_to_parse = text_with_newlines if config.use_text_with_newlines_during_parsing else text - - cert.state.txt_state = FIPSCertificate._declare_state(text) - - if config.ignore_first_page: - text_to_parse = text_to_parse[text_to_parse.index("") :] - - items_found, fips_text = FIPSCertificate._parse_cert_file(FIPSCertificate._remove_platforms(text_to_parse)) - - save_modified_cert_file(cert.state.fragment_path.with_suffix(".fips.txt"), fips_text, unicode_error) - - common_items_found, common_text = FIPSCertificate._parse_cert_file_common( - text_to_parse, text_with_newlines, fips_common_rules - ) - - save_modified_cert_file(cert.state.fragment_path.with_suffix(".common.txt"), common_text, unicode_error) - items_found.update(common_items_found) - - return items_found, cert + keywords = sec_certs.utils.extract.extract_keywords(cert.state.sp_path.with_suffix(".pdf.txt"), fips_rules) + return keywords, cert @staticmethod def match_web_algs_to_pdf(cert: FIPSCertificate) -> int: @@ -698,103 +669,6 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris return text_to_parse @staticmethod - def _highlight_matches(items_found_all: Dict, whole_text_with_newlines: str) -> str: - all_matches = [] - for rule_group in items_found_all.keys(): - items_found = items_found_all[rule_group] - for rule in items_found.keys(): - for match in items_found[rule]: - all_matches.append(match) - - # if AES string is removed before AES-128, -128 would be left in text => sort by length first - # sort before replacement based on the length of match - all_matches.sort(key=len, reverse=True) - for match in all_matches: - whole_text_with_newlines = whole_text_with_newlines.replace(match, "x" * len(match)) - - return whole_text_with_newlines - - @staticmethod - def _process_match(rule: Pattern, items_found: Dict, rule_str: str, m: Match[str]) -> None: - # insert rule if at least one match for it was found - if rule not in items_found: - items_found[rule_str] = {} - - match = m.group() - match = normalize_match_string(match) - - match_len = len(match) - if match_len > constants.MAX_ALLOWED_MATCH_LENGTH: - logger.warning("Excessive match with length of {} detected for rule {}".format(match_len, rule)) - - if match not in items_found[rule_str]: - items_found[rule_str][match] = {} - items_found[rule_str][match][constants.TAG_MATCH_COUNTER] = 0 - if constants.APPEND_DETAILED_MATCH_MATCHES: - items_found[rule_str][match][constants.TAG_MATCH_MATCHES] = [] - - items_found[rule_str][match][constants.TAG_MATCH_COUNTER] += 1 - match_span = m.span() - - if constants.APPEND_DETAILED_MATCH_MATCHES: - items_found[rule_str][match][constants.TAG_MATCH_MATCHES].append([match_span[0], match_span[1]]) - - @staticmethod - def _parse_cert_file_common( - text_to_parse: str, whole_text_with_newlines: str, search_rules: Dict - ) -> Tuple[Dict[Pattern, Dict], str]: - # apply all rules - items_found_all: Dict[Pattern, Dict] = {} - for rule_group, rules in search_rules.items(): - if rule_group not in items_found_all: - items_found_all[rule_group] = {} - - items_found = items_found_all[rule_group] - - for rule_str, rule in rules: - for m in re.finditer(rule, text_to_parse): - FIPSCertificate._process_match(rule, items_found, rule_str, m) - - # highlight all found strings (by xxxxx) from the input text and store the rest - - whole_text_with_newlines = FIPSCertificate._highlight_matches(items_found_all, whole_text_with_newlines) - - return items_found_all, whole_text_with_newlines - - @staticmethod - def _parse_cert_file(text_to_parse: str) -> Tuple[Dict[Pattern, Dict], str]: - # apply all rules - items_found_all: Dict = {} - - for rule_group, rules in fips_rules.items(): - if rule_group not in items_found_all: - items_found_all[rule_group] = {} - - items_found: Dict[str, Dict] = items_found_all[rule_group] - - for rule_str, rule in rules: - for m in rule.finditer(text_to_parse): - # insert rule if at least one match for it was found - if rule_str not in items_found: - items_found[rule_str] = {} - - match = m.group() - match = normalize_match_string(match) - - if match == "": - continue - - if match not in items_found[rule_str]: - items_found[rule_str][match] = {} - items_found[rule_str][match][constants.TAG_MATCH_COUNTER] = 0 - - items_found[rule_str][match][constants.TAG_MATCH_COUNTER] += 1 - - text_to_parse = text_to_parse.replace(match, "x" * len(match)) - - return items_found_all, text_to_parse - - @staticmethod def analyze_tables(tup: Tuple[FIPSCertificate, bool]) -> Tuple[bool, FIPSCertificate, List]: """ Searches for tables in pdf documents of the instance. @@ -811,7 +685,7 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris cert_file = cert.state.sp_path txt_file = cert_file.with_suffix(".pdf.txt") with open(txt_file, "r", encoding="utf-8") as f: - tables = helpers.find_tables(f.read(), txt_file) + tables = sec_certs.utils.tables.find_tables(f.read(), txt_file) all_pages = precision and cert.heuristics.unmatched_algs > config.cert_threshold # bool value lst: List = [] @@ -821,7 +695,7 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris except Exception as e: try: logger.error(e) - helpers.repair_pdf(cert_file) + sec_certs.utils.pdf.repair_pdf(cert_file) data = read_pdf(cert_file, pages="all" if all_pages else tables, silent=True) except Exception as ex: @@ -852,16 +726,15 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris return result def _process_to_pop(self, reg_to_match: Pattern, cert: str, to_pop: Set[str]) -> None: - for alg in self.heuristics.keywords["rules_fips_algorithms"]: - for found in self.heuristics.keywords["rules_fips_algorithms"][alg]: - match_in_found = reg_to_match.search(found) - match_in_cert = reg_to_match.search(cert) - if ( - match_in_found is not None - and match_in_cert is not None - and match_in_found.group("id") == match_in_cert.group("id") - ): - to_pop.add(cert) + for found in self.heuristics.keywords["fips_certlike"]["Certlike"]: + match_in_found = reg_to_match.search(found) + match_in_cert = reg_to_match.search(cert) + if ( + match_in_found is not None + and match_in_cert is not None + and match_in_found.group("id") == match_in_cert.group("id") + ): + to_pop.add(cert) for alg_cert in self.heuristics.algorithms: for cert_no in alg_cert["Certificate"]: @@ -877,26 +750,25 @@ class FIPSCertificate(Certificate["FIPSCertificate", "FIPSCertificate.FIPSHeuris return self.heuristics.keywords = copy.deepcopy(self.pdf_scan.keywords) - # TODO figure out why can't I delete this - if self.web_scan.mentioned_certs: - for item, value in self.web_scan.mentioned_certs.items(): - self.heuristics.keywords["rules_cert_id"].update({"caveat_item": {item: value}}) + # # TODO figure out why can't I delete this + # if self.web_scan.mentioned_certs: + # for item, value in self.web_scan.mentioned_certs.items(): + # self.heuristics.keywords["fips_cert_id"].update({"caveat_item": {item: value}}) + # alg_set = self._create_alg_set() - - for rule in self.heuristics.keywords["rules_cert_id"]: + for cert_rule in fips_rules["fips_cert_id"]["Cert"]: to_pop = set() - rr = re.compile(rule) - for cert in self.heuristics.keywords["rules_cert_id"][rule]: + for cert in self.heuristics.keywords["fips_cert_id"]["Cert"]: if cert in alg_set: to_pop.add(cert) continue - self._process_to_pop(rr, cert, to_pop) + self._process_to_pop(cert_rule, cert, to_pop) for r in to_pop: - self.heuristics.keywords["rules_cert_id"][rule].pop(r, None) + self.heuristics.keywords["fips_cert_id"]["Cert"].pop(r, None) - self.heuristics.keywords["rules_cert_id"][rule].pop(self.cert_id, None) + self.heuristics.keywords["fips_cert_id"]["Cert"].pop("#" + str(self.cert_id), None) @staticmethod def get_compare(vendor: str) -> str: diff --git a/sec_certs/sample/fips_iut.py b/sec_certs/sample/fips_iut.py index f078177a..3182585c 100644 --- a/sec_certs/sample/fips_iut.py +++ b/sec_certs/sample/fips_iut.py @@ -6,8 +6,8 @@ from typing import Dict, Iterator, List, Mapping, Optional, Set, Union import requests from bs4 import BeautifulSoup, Tag -from sec_certs.helpers import to_utc from sec_certs.serialization.json import ComplexSerializableType +from sec_certs.utils.helpers import to_utc @dataclass(frozen=True) diff --git a/sec_certs/sample/fips_mip.py b/sec_certs/sample/fips_mip.py index 7c86b7be..0a95c74e 100644 --- a/sec_certs/sample/fips_mip.py +++ b/sec_certs/sample/fips_mip.py @@ -9,8 +9,8 @@ import requests from bs4 import BeautifulSoup, Tag from sec_certs.constants import FIPS_MIP_STATUS_RE -from sec_certs.helpers import to_utc from sec_certs.serialization.json import ComplexSerializableType +from sec_certs.utils.helpers import to_utc logger = logging.getLogger(__name__) diff --git a/sec_certs/sample/protection_profile.py b/sec_certs/sample/protection_profile.py index f97dc9fc..b720fa04 100644 --- a/sec_certs/sample/protection_profile.py +++ b/sec_certs/sample/protection_profile.py @@ -3,7 +3,7 @@ import logging from dataclasses import dataclass from typing import Any, Dict, FrozenSet, Optional -import sec_certs.helpers as helpers +import sec_certs.utils.sanitization as sanitization from sec_certs.serialization.json import ComplexSerializableType logger = logging.getLogger(__name__) @@ -20,8 +20,8 @@ class ProtectionProfile(ComplexSerializableType): pp_ids: Optional[FrozenSet[str]] = None def __post_init__(self): - super().__setattr__("pp_name", helpers.sanitize_string(self.pp_name)) - super().__setattr__("pp_link", helpers.sanitize_link(self.pp_link)) + super().__setattr__("pp_name", sanitization.sanitize_string(self.pp_name)) + super().__setattr__("pp_link", sanitization.sanitize_link(self.pp_link)) @classmethod def from_dict(cls, dct: Dict[str, Any]) -> "ProtectionProfile": @@ -31,8 +31,8 @@ class ProtectionProfile(ComplexSerializableType): @classmethod def from_old_api_dict(cls, dct: Dict[str, Any]) -> "ProtectionProfile": - pp_name = helpers.sanitize_string(dct["csv_scan"]["cc_pp_name"]) - pp_link = helpers.sanitize_link(dct["csv_scan"]["link_pp_document"]) + pp_name = sanitization.sanitize_string(dct["csv_scan"]["cc_pp_name"]) + pp_link = sanitization.sanitize_link(dct["csv_scan"]["link_pp_document"]) pp_ids = frozenset(dct["processed"]["cc_pp_csvid"]) if dct["processed"]["cc_pp_csvid"] else None return cls(pp_name, pp_link, pp_ids) diff --git a/sec_certs/sample/sar.py b/sec_certs/sample/sar.py index ea79c892..31359299 100644 --- a/sec_certs/sample/sar.py +++ b/sec_certs/sample/sar.py @@ -4,7 +4,6 @@ import re from dataclasses import dataclass from typing import Any -from sec_certs.cert_rules import rules_security_assurance_components from sec_certs.serialization.json import ComplexSerializableType SAR_CLASS_MAPPING = { @@ -20,7 +19,7 @@ SAR_CLASS_MAPPING = { } SAR_CLASSES = {x for x in SAR_CLASS_MAPPING} -SAR_DICT_KEY = "rules_security_assurance_components" +SAR_DICT_KEY = "cc_sar" @dataclass(frozen=True, eq=True) @@ -50,7 +49,9 @@ class SAR(ComplexSerializableType): @staticmethod def matches_re(string: str) -> bool: - return any([re.match(x, string) for x in rules_security_assurance_components]) + return any( + [re.match(sar_class + "(?:_[A-Z]{3,4}){1,2}(?:\\.[0-9]){0,2}", string) for sar_class in SAR_CLASS_MAPPING] + ) def __lt__(self, other: Any) -> bool: if not isinstance(other, SAR): |
