Coverage for muuntaa/ack.py: 66.20%

43 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-21 12:16:47 +00:00

1"""Acknowledgements type.""" 

2 

3import logging 

4from typing import Union 

5 

6import lxml.objectify # nosec B410 

7 

8from muuntaa.subtree import Subtree 

9 

10RootType = lxml.objectify.ObjectifiedElement 

11RevHistType = list[dict[str, Union[str, None, tuple[int, ...]]]] 

12 

13 

14class Acknowledgments(Subtree): 

15 """Represent any Acknowledgments objects. 

16 

17 ( 

18 /cvrf:cvrfdoc/cvrf:Acknowledgments, 

19 /cvrf:cvrfdoc/vuln:Vulnerability[i+1]/vuln:Acknowledgments, 

20 ) 

21 """ 

22 

23 def __init__(self, lc_parent_code: str): # TODO: unlitter me and push data upstream 

24 super().__init__() 

25 if lc_parent_code not in ('cvrf', 'vuln'): 25 ↛ 26line 25 didn't jump to line 26 because the condition on line 25 was never true

26 raise KeyError('Acknowledgments can only be hosted by cvrf or vuln') 

27 if lc_parent_code == 'cvrf': 27 ↛ 34line 27 didn't jump to line 34 because the condition on line 27 was always true

28 if self.tree.get('document') is None: 28 ↛ 30line 28 didn't jump to line 30 because the condition on line 28 was always true

29 self.tree['document'] = {} 

30 if self.tree['document'].get('acknowledgments') is None: 30 ↛ 32line 30 didn't jump to line 32 because the condition on line 30 was always true

31 self.tree['document']['acknowledgments'] = [] 

32 self.hook = self.tree['document']['acknowledgments'] 

33 else: 

34 if self.tree.get('vulnerabilities') is None: 

35 self.tree['vulnerabilities'] = {} 

36 if self.tree['vulnerabilities'].get('acknowledgments') is None: 

37 self.tree['vulnerabilities']['acknowledgments'] = [] 

38 self.hook = self.tree['vulnerabilities']['acknowledgments'] 

39 

40 def always(self, root: RootType) -> None: 

41 if root.Acknowledgment is not None: # Acknowledgments if present shall not be empty in CSAF 41 ↛ exitline 41 didn't return from function 'always' because the condition on line 41 was always true

42 pass # All fields optional per CVRF v1.2 

43 

44 def sometimes(self, root: RootType) -> None: 

45 for ack in root.Acknowledgment: 

46 print(ack) 

47 if not any((ack.Name, ack.Organization, ack.Description, ack.URL)): # type: ignore 47 ↛ 48line 47 didn't jump to line 48 because the condition on line 47 was never true

48 logging.warning('Skipping empty Acknowledgment entry, input line: %s', ack.sourceline) 

49 continue 

50 

51 record = {} 

52 

53 if orga := ack.Organization: # type: ignore 53 ↛ 62line 53 didn't jump to line 62 because the condition on line 53 was always true

54 record['organization'] = orga[0].text 

55 if len(orga) > 1: 55 ↛ 56line 55 didn't jump to line 56 because the condition on line 55 was never true

56 logging.warning( 

57 'CSAF 2.0 allows only one organization inside Acknowledgments. ' 

58 'Taking the first occurence, ignoring: %s.', 

59 orga[1:], 

60 ) 

61 

62 if desc := ack.Description: # type: ignore 62 ↛ 65line 62 didn't jump to line 65 because the condition on line 62 was always true

63 record['summary'] = desc[0].text # Single Description elem is asserted on the input 

64 

65 if names := ack.Name: # type: ignore 65 ↛ 68line 65 didn't jump to line 68 because the condition on line 65 was always true

66 record['names'] = [name.text for name in names] # Names can have more entries 

67 

68 if urls := ack.URL: # type: ignore 68 ↛ 71line 68 didn't jump to line 71 because the condition on line 68 was always true

69 record['urls'] = [url.text for url in urls] # URLs can have more entries 

70 

71 self.hook.append(record)