Skip to content

Commit

Permalink
Addressing #525, #582, #746, with new unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
wendellpiez authored and david-waltermire committed Apr 8, 2021
1 parent 23bf800 commit 22bb2ae
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<title>ABC Catalog</title>
<last-modified>2020-05-30T14:51:38.311-04:00</last-modified>
<version>1.0</version>
<oscal-version>1.0.0-milestone3</oscal-version>
<oscal-version>1.0.0-rc2</oscal-version>
</metadata>
<group>
<title>Group A of C</title>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<title>Alphabet Catalog</title>
<last-modified>2020-05-30T14:51:41.185-04:00</last-modified>
<version>1.0</version>
<oscal-version>1.0.0-milestone3</oscal-version>
<oscal-version>1.0.0-rc2</oscal-version>
</metadata>
<group>
<title>Group A of C</title>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<title>XYZ Tiny Catalog</title>
<last-modified>2020-05-30T14:51:42.355-04:00</last-modified>
<version>1.0</version>
<oscal-version>1.0.0-milestone3</oscal-version>
<oscal-version>1.0.0-rc2</oscal-version>
</metadata>
<group>
<title>Group X of XYZ</title>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,12 @@
<xsl:variable name="item-okay" select="empty($removal/@item-name) or ($removal/@item-name = local-name($who))"/>
<xsl:variable name="id-okay" select="empty($removal/@id-ref) or ($removal/@id-ref = $who/@id)"/>
<xsl:variable name="name-okay" select="empty($removal/@name-ref) or ($removal/@name-ref/normalize-space(.) = $who/@name/normalize-space(.))"/>
<xsl:variable name="ns-okay" select="empty($removal/@ns[not(normalize-space(.) = $oscal-ns)])
<xsl:variable name="ns-okay" select="empty($removal/@ns-ref[not(normalize-space(.) = $oscal-ns)])
or ($removal/@ns-ref/normalize-space(.) = $who/@ns/normalize-space(.))"/>
<xsl:variable name="oscal-ns-okay" select="empty($removal/@ns-ref[normalize-space(.) = $oscal-ns])
or (($who/@ns/normalize-space(.) = $oscal-ns) or empty($who/@ns))"/>
<xsl:variable name="class-okay" select="empty($removal/@class-ref) or ($removal/@class-ref = oscal:classes($who))"/>
<xsl:sequence select="exists($removal/(@item-name|@id-ref|@name-ref|@ns-ref|@class-ref)) and ($item-okay and $id-okay and $name-okay and $ns-okay and $class-okay)"/>
<xsl:sequence select="exists($removal/(@item-name|@id-ref|@name-ref|@ns-ref|@class-ref)) and ($item-okay and $id-okay and $name-okay and $ns-okay and $oscal-ns-okay and $class-okay)"/>
</xsl:function>

</xsl:stylesheet>
37 changes: 28 additions & 9 deletions src/utils/util/resolver-pipeline/oscal-profile-resolve-select.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<xsl:strip-space elements="catalog group control param guideline select part
metadata back-matter annotation party person org rlink address resource role responsible-party citation
profile import merge custom modify include exclude set alter add"/>
profile import merge custom modify include-controls exclude-controls set alter add"/>

<!--<xsl:param name="profile-origin-uri" required="yes" as="xs:anyURI"/>-->
<xsl:param name="uri-stack-in" select="()" as="xs:anyURI*"/>
Expand Down Expand Up @@ -50,8 +50,8 @@
not, we execute the Ourobouros function, which calls the parent wrapper RESOLVE pipeline
to return a catalog. -->
<xsl:template match="profile" mode="o:select">
<!-- $uri-stack contains an import call stack trace from the point of entry -->
<xsl:param name="uri-stack" tunnel="yes" select="()"/>
<!-- $uri-stack contains an import call stack trace from the point of entry -->
<xsl:variable name="uri-here" select="base-uri(.)"/>
<xsl:if test="not($uri-here = $uri-stack)">
<!--<xsl:sequence select="o:resolve-profile(.,$uri-stack)"/>-->
Expand Down Expand Up @@ -93,10 +93,17 @@
</xsl:template>

<xsl:template match="resource" mode="o:import">
<xsl:apply-templates mode="o:select" select="o:resource-or-warning(rlink/@href)"/>
<xsl:variable name="linked-xml" select="child::rlink[ends-with(@href,'.xml') or matches(@media-type,'xml')][1]"/>
<xsl:apply-templates mode="o:select" select="o:resource-or-warning($linked-xml/@href)"/>
</xsl:template>

<xsl:template priority="1" mode="o:select" match="import">

<!-- OSCAL issue -->
<xsl:variable name="linked-resource" select="key('cross-reference',@href)"/>
<xsl:apply-templates select="$linked-resource" mode="o:import">
<xsl:with-param name="import-instruction" select="." tunnel="yes"/>
</xsl:apply-templates>
<xsl:apply-templates mode="#current" select="o:resource-or-warning(@href)">
<xsl:with-param name="import-instruction" select="." tunnel="yes"/>
</xsl:apply-templates>
Expand Down Expand Up @@ -168,19 +175,19 @@
<xsl:sequence select="some $c in ($importing/include-controls[o:calls-children(.)]/with-id)
satisfies ($c = $candidate/parent::control/@id)"/>
<xsl:sequence select="some $m in ($importing/include-controls/matching)
satisfies (matches($candidate/@id,$m/@pattern))"/>
satisfies (matches($candidate/@id,$m/@pattern/o:glob-as-regex(string(.)) ))"/>
<xsl:sequence select="some $m in ($importing/include/matching[o:calls-children(.)])
satisfies (matches($candidate/parent::control/@id,$m/@pattern))"/>
satisfies (matches($candidate/parent::control/@id,$m/@pattern/o:glob-as-regex(string(.))))"/>
</xsl:variable>
<xsl:variable name="exclude-reasons" as="xs:boolean+">
<xsl:sequence select="exists($candidate/parent::control) and $importing/include-all/@with-child-controls='no'"/>
<xsl:sequence select="some $c in ($importing/exclude-controls/with-id) satisfies ($c = $candidate/@id)"/>
<xsl:sequence select="some $c in ($importing/exclude-controls[o:calls-children(.)]/with-id)
satisfies ($c = $candidate/parent::control/@id)"/>
<xsl:sequence select="some $m in ($importing/exclude-controls/matching)
satisfies (matches($candidate/@id,$m/@pattern))"/>
satisfies (matches($candidate/@id,$m/@pattern/o:glob-as-regex(string(.))))"/>
<xsl:sequence select="some $m in ($importing/exclude-controls[o:calls-children(.)]/matcjomg)
satisfies (matches($candidate/parent::control/@id,$m/@pattern))"/>
satisfies (matches($candidate/parent::control/@id,$m/@pattern/o:glob-as-regex(string(.))))"/>
</xsl:variable>
<!-- predicate [.] filters reasons as booleans -->
<xsl:sequence select="exists($include-reasons[.]) and empty($exclude-reasons[.])"/>
Expand All @@ -202,17 +209,29 @@
<xsl:otherwise>
<xsl:document>
<opr:WARNING>
<xsl:text>Document not found: '</xsl:text>
<xsl:text>Document not acquired: '</xsl:text>
<xsl:value-of select="$href"/>
<xsl:text>' resolved as '</xsl:text>
<xsl:value-of select="$resolved-href"/>
<xsl:text>'</xsl:text>
<xsl:text>' (as OSCAL XML)</xsl:text>
</opr:WARNING>
</xsl:document>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

<!-- XSD regex metacharacters except '*' and '?' https://www.w3.org/TR/xmlschema11-2/#regex-char-metachar -->
<xsl:variable name="metachars" select="('.', '\', '+', '{', '}', '(', ')', '|', '[', ']')"/>
<xsl:variable name="metachar-match" select="'(' || string-join( ($metachars ! ('\' || .)),'|') || ')'"/>

<xsl:function name="o:glob-as-regex">
<xsl:param name="glob" as="xs:string"/>
<xsl:variable name="escaped" select="replace($glob,$metachar-match,'\\$1')"/>
<!-- replace ? with . and * with .* -->
<xsl:sequence select="'^' || ($escaped => replace('\?','.') => replace('\*','.*') ) || '$'"/>
<!--<xsl:sequence select="$escaped"/>-->
</xsl:function>

<xsl:function name="o:resolve-profile">
<xsl:param name="profile" as="element(profile)"/>
<xsl:param name="uri-stack" as="xs:anyURI*"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE x:description [
<!ENTITY filedir "file:/C:/Users/wap1/Documents/usnistgov/OSCAL/src/specifications/profile-resolution/profile-resolution-examples/catalogs" >
]>
<x:description xmlns="http://csrc.nist.gov/ns/oscal/1.0"
xmlns:o="http://csrc.nist.gov/ns/oscal/1.0"
xmlns:opr="http://csrc.nist.gov/ns/oscal/profile-resolution"
xmlns:x="http://www.jenitennison.com/xslt/xspec"
stylesheet="../../oscal-profile-resolve-select.xsl">
<x:scenario label="Simple string">
<x:call function="o:glob-as-regex">
<x:param>ac</x:param>
</x:call>
<x:expect label="Anchored, otherwise the same" select="'^ac$'"/>
</x:scenario>
<x:scenario label="More complex string">
<x:call function="o:glob-as-regex">
<x:param>ac-1(1)</x:param>
</x:call>
<x:expect label="Anchored and escaped" select="'^ac-1\(1\)$'"/>
</x:scenario>
<x:scenario label="More complex string, with ?">
<x:call function="o:glob-as-regex">
<x:param>ac-1(?)</x:param>
</x:call>
<x:expect label="Anchored and escaped with substitution" select="'^ac-1\(.\)$'"/>
</x:scenario>
<x:scenario label="This time with *">
<x:call function="o:glob-as-regex">
<x:param>ac-1(*)</x:param>
</x:call>
<x:expect label="Anchored and escaped with substitution" select="'^ac-1\(.*\)$'"/>
</x:scenario>
</x:description>
135 changes: 135 additions & 0 deletions src/utils/util/resolver-pipeline/testing/1_selected/select-rlink.xspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE x:description [
<!ENTITY filedir "file:/C:/Users/wap1/Documents/usnistgov/OSCAL/src/specifications/profile-resolution/profile-resolution-examples/catalogs" >
]>
<x:description xmlns="http://csrc.nist.gov/ns/oscal/1.0"
xmlns:opr="http://csrc.nist.gov/ns/oscal/profile-resolution"
xmlns:x="http://www.jenitennison.com/xslt/xspec"
stylesheet="../../oscal-profile-resolve-select.xsl">
<x:scenario label="Direct import by file href">
<x:context>
<profile>
<import href="&filedir;/xyz-tiny_catalog.xml">
<include-controls>
<with-id>z3</with-id>
</include-controls>
</import>
</profile>
</x:context>
<x:expect label="Control selected from catalog source">
<profile>
<selection uuid="..." opr:src="...">
<metadata>
<title>XYZ Tiny Catalog</title>
<last-modified>2020-05-30T14:51:42.355-04:00</last-modified>
<version>1.0</version>
<oscal-version>1.0.0-rc2</oscal-version>
</metadata>
<group opr:id="...">
<title>Group X of XYZ</title>
</group>
<group opr:id="...">
<title>Group Y of XYZ</title>
</group>
<group opr:id="...">
<title>Group Z of XYZ</title>
<control id="z3" opr:id="..."><title>Control Z3</title></control>
</group>
</selection>
</profile>
</x:expect>
</x:scenario>
<x:scenario label="Indirect import via resource/rlink">
<x:context>
<profile>
<import href="#6e57d296-39c1-4e83-8107-4dcc2ede751b">
<include-controls>
<with-id>z3</with-id>
</include-controls>
</import>
<back-matter>
<resource uuid="6e57d296-39c1-4e83-8107-4dcc2ede751b">
<title>Tiny Catalog</title>
<rlink href="&filedir;/xyz-tiny_catalog.xml"/>
</resource>
</back-matter>
</profile>
</x:context>
<x:expect label="Control selected from remote resource">
<profile>
<selection uuid="..." opr:src="...">
<metadata>
<title>XYZ Tiny Catalog</title>
<last-modified>2020-05-30T14:51:42.355-04:00</last-modified>
<version>1.0</version>
<oscal-version>1.0.0-rc2</oscal-version>
</metadata>
<group opr:id="...">
<title>Group X of XYZ</title>
</group>
<group opr:id="...">
<title>Group Y of XYZ</title>
</group>
<group opr:id="...">
<title>Group Z of XYZ</title>
<control id="z3" opr:id="..."><title>Control Z3</title></control>
</group>
</selection>
<back-matter>
<resource uuid="6e57d296-39c1-4e83-8107-4dcc2ede751b">
<title>Tiny Catalog</title>
<rlink href="..."/>
</resource>
</back-matter>
</profile>
</x:expect>
</x:scenario>
<x:scenario label="Indirect import via resource/rlink selecting XML">
<x:context>
<profile>
<import href="#6e57d296-39c1-4e83-8107-4dcc2ede751b">
<include-controls>
<with-id>z3</with-id>
</include-controls>
</import>
<back-matter>
<resource uuid="6e57d296-39c1-4e83-8107-4dcc2ede751b">
<title>Tiny Catalog</title>
<rlink href="&filedir;/xyz-tiny_catalog.xml"/>
<rlink href="&filedir;/xyz-tiny_catalog.json"/>
</resource>
</back-matter>
</profile>
</x:context>
<x:expect label="Select all controls, grouped">
<profile>
<selection uuid="..." opr:src="...">
<metadata>
<title>XYZ Tiny Catalog</title>
<last-modified>2020-05-30T14:51:42.355-04:00</last-modified>
<version>1.0</version>
<oscal-version>1.0.0-rc2</oscal-version>
</metadata>
<group opr:id="...">
<title>Group X of XYZ</title>
</group>
<group opr:id="...">
<title>Group Y of XYZ</title>
</group>
<group opr:id="...">
<title>Group Z of XYZ</title>
<control id="z3" opr:id="..."><title>Control Z3</title></control>
</group>
</selection>
<back-matter>
<resource uuid="6e57d296-39c1-4e83-8107-4dcc2ede751b">
<title>Tiny Catalog</title>
<rlink href="..."/>
<rlink href="..."/>
</resource>
</back-matter>
</profile>
</x:expect>
</x:scenario>

</x:description>
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
<import href="&filedir;/xyz-tiny_catalog.xml">
<include-controls>
<!-- any x control -->
<matching pattern="^x\d+$"/>
<matching pattern="x*"/>
</include-controls>
</import>
</profile>
Expand Down
Loading

0 comments on commit 22bb2ae

Please sign in to comment.