Passed
Push — master ( 26b7f9...8a68fd )
by Jan
02:33 queued 12s
created

ssg.id_translate   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 27.69%

Importance

Changes 0
Metric Value
eloc 81
dl 0
loc 116
rs 10
c 0
b 0
f 0
ccs 18
cts 65
cp 0.2769
wmc 25

3 Functions

Rating   Name   Duplication   Size   Complexity  
A _split_namespace() 0 10 2
A _tagname_to_abbrev() 0 13 4
A _namespace_to_prefix() 0 9 3

3 Methods

Rating   Name   Duplication   Size   Complexity  
A IDTranslator.generate_id() 0 5 1
A IDTranslator.__init__() 0 2 1
F IDTranslator.translate() 0 50 14
1 2
from __future__ import absolute_import
2 2
from __future__ import print_function
3
4 2
from .xml import ElementTree
5 2
from .constants import oval_namespace as oval_ns
6 2
from .constants import ocil_namespace as ocil_ns
7 2
from .constants import OVALTAG_TO_ABBREV, OCILTAG_TO_ABBREV
8 2
from .constants import OVALREFATTR_TO_TAG, OCILREFATTR_TO_TAG
9
10
11 2
def _split_namespace(tag):
12
    """returns a tuple of (namespace, tag),
13
    removing any fragment id from namespace
14
    """
15
16 2
    if tag[0] == "{":
17 2
        namespace, name = tag[1:].split("}", 1)
18 2
        return (namespace.split("#", 1)[0], name)
19
20 2
    return (None, tag)
21
22
23 2
def _namespace_to_prefix(tag):
24
    namespace, _ = _split_namespace(tag)
25
    if namespace == ocil_ns:
26
        return "ocil"
27
    if namespace == oval_ns:
28
        return "oval"
29
30
    raise RuntimeError(
31
        "Error: unknown checksystem referenced in tag : %s" % tag
32
    )
33
34
35 2
def _tagname_to_abbrev(tag):
36
    namespace, tag = _split_namespace(tag)
37
    if tag == "extend_definition":
38
        return tag
39
    # grab the last part of the tag name to determine its type
40
    tag = tag.rsplit("_", 1)[-1]
41
    if namespace == ocil_ns:
42
        return OCILTAG_TO_ABBREV[tag]
43
    if namespace == oval_ns:
44
        return OVALTAG_TO_ABBREV[tag]
45
46
    raise RuntimeError(
47
        "Error: unknown checksystem referenced in tag : %s" % tag
48
    )
49
50
51 2
class IDTranslator(object):
52
    """This class is designed to handle the mapping of meaningful, human-readable
53
    names to IDs in the formats required by the SCAP checking systems, such as
54
    OVAL and OCIL."""
55
56 2
    def __init__(self, content_id):
57
        self.content_id = content_id
58
59 2
    def generate_id(self, tagname, name):
60
        return "%s:%s-%s:%s:1" % (
61
            _namespace_to_prefix(tagname),
62
            self.content_id, name,
63
            _tagname_to_abbrev(tagname)
64
        )
65
66 2
    def translate(self, tree, store_defname=False):
67
        # decide on usage of .iter or .getiterator method of elementtree class.
68
        # getiterator is deprecated in Python 3.9, but iter is not available in
69
        # older versions
70
        if getattr(tree, "iter", None) == None:
71
            tree_iterator = tree.getiterator()
72
        else:
73
            tree_iterator = tree.iter()
74
        for element in tree_iterator:
75
            idname = element.get("id")
76
            if idname:
77
                # store the old name if requested (for OVAL definitions)
78
                if store_defname and \
79
                        element.tag == "{%s}definition" % oval_ns:
80
                    metadata = element.find("{%s}metadata" % oval_ns)
81
                    if metadata is None:
82
                        metadata = ElementTree.SubElement(element, "metadata")
83
                    defnam = ElementTree.Element(
84
                        "{%s}reference" % oval_ns, ref_id=idname, source=self.content_id)
85
                    metadata.append(defnam)
86
87
                # set the element to the new identifier
88
                element.set("id", self.generate_id(element.tag, idname))
89
                # continue
90
            if element.tag == "{%s}filter" % oval_ns:
91
                element.text = self.generate_id("{%s}state" % oval_ns,
92
                                                element.text)
93
                continue
94
            if element.tag == "{%s#independent}var_ref" % oval_ns:
95
                element.text = self.generate_id("{%s}variable" % oval_ns,
96
                                                element.text)
97
                continue
98
            if element.tag == "{%s}object_reference" % oval_ns:
99
                element.text = self.generate_id("{%s}object" % oval_ns,
100
                                                element.text)
101
                continue
102
            for attr in element.keys():
103
                if attr in OVALREFATTR_TO_TAG.keys():
104
                    element.set(attr, self.generate_id(
105
                        "{%s}%s" % (oval_ns, OVALREFATTR_TO_TAG[attr]),
106
                        element.get(attr)))
107
                if attr in OCILREFATTR_TO_TAG.keys():
108
                    element.set(attr, self.generate_id(
109
                        "{%s}%s" % (ocil_ns, OCILREFATTR_TO_TAG[attr]),
110
                        element.get(attr)))
111
            if element.tag == "{%s}test_action_ref" % ocil_ns:
112
                element.text = self.generate_id("{%s}action" % ocil_ns,
113
                                                element.text)
114
115
        return tree
116