Skip to content

Commit

Permalink
Added IdP and SP InC baseline compliance xslts
Browse files Browse the repository at this point in the history
  • Loading branch information
nckroy committed Aug 17, 2017
1 parent 05f5263 commit 27547a7
Show file tree
Hide file tree
Showing 2 changed files with 457 additions and 0 deletions.
234 changes: 234 additions & 0 deletions lib/list_all_IdP_baseline_compliance_csv.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2017 Internet2
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--
list_all_IdP_baseline_compliance_csv.xsl
This XSL transform takes a SAML metadata aggregate and produces a list of
IdP DisplayNames as would be seen on a typical discovery interface. The script
matches on every entity descriptor with an IdP role and produces a CSV file
with the following fields:
1. IdP Display Name: mdui:DisplayName or md:OrganizationDisplayName (in that order)
2. IdP Privacy URL or NONE
3. IdP Logo present TRUE/FALSE
4. IdP Tech contact or NONE
5. IdP Admin contact or NONE
6. IdP Security contact or NONE
7. IdP Entity ID: @entityID
8. IdP Discovery: "hide" or "show"
9. Registrar ID: @registrationAuthority
The IdP Display Name field is set to "NONE" if neither mdui:DisplayName nor
md:OrganizationDisplayName exist in the entity descriptor. The IdP Discovery
field depends on the presence (resp., absence) of the hide-from-discovery
entity attribute.
BUG: Incorrectly processes an entity with multiple IDPSSODescriptor elements
-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute"
xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi"
xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:remd="http://refeds.org/metadata"
xmlns:icmd="http://id.incommon.org/metadata">

<!-- search-and-replace constants -->
<xsl:variable name="double_quote" select="'&quot;'"/>
<xsl:variable name="double_double_quote" select="'&quot;&quot;'"/>

<!-- output is plain text -->
<xsl:output method="text"/>

<!-- output the heading line -->
<xsl:template match="/">
<xsl:text>IdP Display Name, IdP Privacy URL,IdP Logo Present,IdP Tech Contact,IdP Admin Contact,IdP Security Contact,IdP Entity ID,IdP Discovery,Registrar ID</xsl:text>
<xsl:text>&#x0a;</xsl:text>
<xsl:apply-templates/>
</xsl:template>

<!-- match all entity descriptors with an IdP role -->
<xsl:template match="//md:EntityDescriptor[md:IDPSSODescriptor]">

<!-- compute the normalized values of mdui:DisplayName and md:OrganizationDisplayName -->
<xsl:variable name="displayName" select="normalize-space(md:IDPSSODescriptor/md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en'])"/>
<xsl:variable name="orgDisplayName" select="normalize-space(md:Organization/md:OrganizationDisplayName[@xml:lang='en'])"/>
<xsl:variable name="privacyURL" select="normalize-space(md:IDPSSODescriptor/md:Extensions/mdui:UIInfo/mdui:PrivacyStatementURL[@xml:lang='en'])"/>
<xsl:variable name="logo" select="normalize-space(md:IDPSSODescriptor/md:Extensions/mdui:UIInfo/mdui:Logo)"/>
<xsl:variable name="techContact" select="normalize-space(md:ContactPerson[@contactType='technical']/md:EmailAddress)"/>
<xsl:variable name="adminContact" select="normalize-space(md:ContactPerson[@contactType='administrative']/md:EmailAddress)"/>
<xsl:variable name="rEFEDSSecurityContact" select="normalize-space(md:ContactPerson[@remd:contactType='http://refeds.org/metadata/contactType/security']/md:EmailAddress)"/>
<xsl:variable name="inCommonSecurityContact" select="normalize-space(md:ContactPerson[@icmd:contactType='http://id.incommon.org/metadata/contactType/security']/md:EmailAddress)"/>

<!-- output either mdui:DisplayName or md:OrganizationDisplayName or "NONE" (in that order) -->
<xsl:choose>
<xsl:when test="$displayName != ''">
<!-- escape literal double quotes in mdui:DisplayName -->
<xsl:variable name="escapedDisplayName">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="string" select="$displayName"/>
<xsl:with-param name="search" select="$double_quote"/>
<xsl:with-param name="replace" select="$double_double_quote"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>"</xsl:text>
<xsl:value-of select="$escapedDisplayName"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:when test="$orgDisplayName != ''">
<!-- escape literal double quotes in md:OrganizationDisplayName -->
<xsl:variable name="escapedOrgDisplayName">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="string" select="$orgDisplayName"/>
<xsl:with-param name="search" select="$double_quote"/>
<xsl:with-param name="replace" select="$double_double_quote"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>"</xsl:text>
<xsl:value-of select="$escapedOrgDisplayName"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>NONE</xsl:text>
</xsl:otherwise>
</xsl:choose>

<!-- output either mdui:privacyURL or "NONE" (in that order) -->
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="$privacyURL != ''">
<xsl:text>"</xsl:text>
<xsl:value-of select="$privacyURL"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>NONE</xsl:text>
</xsl:otherwise>
</xsl:choose>

<!-- output Logo Present "TRUE" or "FALSE" -->
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="$logo != ''">
<xsl:text>TRUE</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>FALSE</xsl:text>
</xsl:otherwise>
</xsl:choose>

<!-- output either tech contact or "NONE" (in that order) -->
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="$techContact != ''">
<xsl:text>"</xsl:text>
<xsl:value-of select="$techContact"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>NONE</xsl:text>
</xsl:otherwise>
</xsl:choose>

<!-- output either admin contact or "NONE" (in that order) -->
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="$adminContact != ''">
<xsl:text>"</xsl:text>
<xsl:value-of select="$adminContact"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>NONE</xsl:text>
</xsl:otherwise>
</xsl:choose>

<!-- output either REFEDS security contact, InCommon security contact or "NONE" (in that order) -->
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="$rEFEDSSecurityContact != ''">
<xsl:text>"</xsl:text>
<xsl:value-of select="$rEFEDSSecurityContact"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:when test="$inCommonSecurityContact != ''">
<xsl:text>"</xsl:text>
<xsl:value-of select="$inCommonSecurityContact"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>NONE</xsl:text>
</xsl:otherwise>
</xsl:choose>

<!-- output the IdP entityID -->
<xsl:text>,</xsl:text>
<xsl:value-of select="@entityID"/>

<!-- output "hide" or "show" depending on the hide-from-discovery entity attribute -->
<xsl:text>,</xsl:text>
<xsl:choose>
<xsl:when test="md:Extensions/mdattr:EntityAttributes/saml:Attribute[@Name='http://macedir.org/entity-category']/saml:AttributeValue[text()='http://refeds.org/category/hide-from-discovery']">
<xsl:text>hide</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>show</xsl:text>
</xsl:otherwise>
</xsl:choose>

<!-- output the registrar ID -->
<xsl:text>,</xsl:text>
<xsl:value-of select="md:Extensions/mdrpi:RegistrationInfo/@registrationAuthority"/>

<xsl:text>&#x0a;</xsl:text>
</xsl:template>

<!--
A named template that performs global (recursive) search-and-replace on a string
(similar to fn:replace(string, pattern, replace) in XSLT 2.0).
See: http://stackoverflow.com/questions/3067113/xslt-string-replace/3067130#3067130
-->
<xsl:template name="string-replace-all">
<xsl:param name="string"/>
<xsl:param name="search"/>
<xsl:param name="replace"/>
<xsl:choose>
<xsl:when test="$string = '' or $search = '' or not($search)">
<!-- Prevent this routine from hanging -->
<xsl:value-of select="$string"/>
</xsl:when>
<xsl:when test="contains($string, $search)">
<xsl:value-of select="substring-before($string, $search)"/>
<xsl:value-of select="$replace"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="string" select="substring-after($string, $search)"/>
<xsl:with-param name="search" select="$search"/>
<xsl:with-param name="replace" select="$replace"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template match="text()">
<!-- do nothing -->
</xsl:template>
</xsl:stylesheet>
Loading

0 comments on commit 27547a7

Please sign in to comment.