Coverage for turvallisuusneuvonta/csaf/core/rules/mandatory/valid_category_name.py: 90.91%
18 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-18 20:29:38 +00:00
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-18 20:29:38 +00:00
1"""6.1.26 Prohibited Document Category Name
3It must be tested that the document category is not equal to the (case insensitive) name of
4any other profile than "Generic CSAF".
5This does not differentiate between underscore, dash or whitespace.
6This test does only apply for CSAF documents with the profile "Generic CSAF".
7Therefore, it must be skipped if the document category matches one of the values defined for the profile
8other than "Generic CSAF".
10>For CSAF 2.0, the test must be skipped for the following values in /document/category:
11 security_incident_response
12 informational_advisory
13 security_advisory
14 vex
16This is the only test related to the profile "Generic CSAF" as the required fields SHALL be checked by
17validating the JSON schema.
19The relevant path for this test is:
21 /document/category
23Examples 65 for currently prohibited values:
25 Informational Advisory
26 security-incident-response
27 Security Advisory
28 veX
30Example 66 which fails the test:
32 "category": "Security_Incident_Response"
34> The value Security_Incident_Response is the name of a profile where the space was replaced with underscores.
36"""
38ID = (6, 1, 26)
39TOPIC = 'Prohibited Document Category Name'
40BASE_URL = 'https://docs.oasis-open.org/csaf/csaf/v2.0/cs01/csaf-v2.0-cs01.html'
41REFERENCE = f'{BASE_URL}#6126-prohibited-document-category-name'
42CONDITION_PATH = '/document/category'
43CONDITION_JMES_PATH = CONDITION_PATH.lstrip('/').replace('/', '.')
44PATHS = (CONDITION_PATH,)
45PROFILES = (
46 'informational_advisory',
47 'security_advisory',
48 'security_incident_response',
49 'vex',
50)
51MIN_LEN = min(len(profile) for profile in PROFILES)
52STRIP_THESE = ''.join(IRRELEVANT_CHARACTERS := (SPACE := ' ', UNDERSCORE := '_', DASH := '-'))
55def is_valid(text: str) -> bool:
56 """Verify category match per spec (disambiguation)."""
57 if not text: # empty (implementer safeguard) 57 ↛ 58line 57 didn't jump to line 58 because the condition on line 57 was never true
58 return False
60 if not (text_strip := text.strip(STRIP_THESE)) or len(text) < MIN_LEN: # short enough or irrelevant chars only
61 return True
63 # characters other than space present
64 term = UNDERSCORE.join(w for w in text.replace(DASH, SPACE).replace(UNDERSCORE, SPACE).split(SPACE) if w.strip())
65 term_lc_in_profiles = (term_lc := term.lower()) in PROFILES
67 return True if not term_lc_in_profiles or all([term_lc_in_profiles, term_lc == term, text_strip == text]) else False