d27e20dde75f99316138a2f5364f3cd0dc512ee3
[java-idp.git] / src / schemas / metadata_v12_to_v13.xsl
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3
4         v12_to_v13.xsl
5         
6         XSL stylesheet converting a Shibboleth 1.2 sites file into the equivalent for
7         Shibboleth 1.3, which is based on the SAML 1.1 profile of the SAML 2.0
8         metadata format.  No attempt is made to incorporate the separate trust
9         data used by Shibboleth 1.2.
10         
11         Author: Ian A. Young <ian@iay.org.uk>
12
13         $Id$
14 -->
15 <xsl:stylesheet version="1.0"
16         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
17         xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
18         xmlns:shib="urn:mace:shibboleth:1.0"
19         xmlns:shibmeta="urn:mace:shibboleth:metadata:1.0"
20         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21         xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
22         exclude-result-prefixes="shib">
23
24         <!--
25                 Version information for this file.  Remember to peel off the dollar signs
26                 before dropping the text into another versioned file.
27         -->
28         <xsl:param name="cvsId">$Id$</xsl:param>
29
30         <!--
31                 Add a comment to the start of the output file.
32         -->
33         <xsl:template match="/">
34                 <xsl:comment>
35                         <xsl:text>&#10;&#9;***DO NOT EDIT THIS FILE***&#10;&#10;</xsl:text>
36                         <xsl:text>&#9;Converted by:&#10;&#10;&#9;</xsl:text>
37                         <xsl:value-of select="substring-before(substring-after($cvsId, ': '), '$')"/>
38                         <xsl:text>&#10;</xsl:text>
39                 </xsl:comment>
40                 <xsl:apply-templates/>
41         </xsl:template>
42
43         <!--Force UTF-8 encoding for the output.-->
44         <xsl:output omit-xml-declaration="no" method="xml" encoding="UTF-8" indent="yes"/>
45
46         <!--
47                 SiteGroup is the root element for the sites file.  The corresponding element in the new format file
48                 is an EntitiesDescriptor.
49         -->
50         <xsl:template match="shib:SiteGroup">
51                 <EntitiesDescriptor Name="{@Name}">
52                         <xsl:attribute name="xsi:schemaLocation">
53                                 <xsl:text>urn:oasis:names:tc:SAML:2.0:metadata sstc-saml-schema-metadata-2.0.xsd </xsl:text>
54                                 <xsl:text>urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd </xsl:text>
55                                 <xsl:text>http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd</xsl:text>
56                         </xsl:attribute>
57                         <!--
58                                 Pass through text blocks and comments, and any shib elements.
59                                 These may be: OriginSite, DestinationSite or nested SiteGroup.
60                         -->
61                         <xsl:apply-templates select="text()|comment()|shib:*"/>
62                 </EntitiesDescriptor>
63         </xsl:template>
64
65         <!--
66                 Map OriginSite to an EntityDescriptor with a particular format.
67         -->
68         <xsl:template match="shib:OriginSite">
69                 <EntityDescriptor entityID="{@Name}">
70                         <!--
71                                 Copy through comments and text blocks at the start of the output element.
72                                 This means we don't lose comments, but there is no way to guarantee they will
73                                 come out "in the right place".
74                         -->
75                         <xsl:apply-templates select="text()|comment()"/>
76                         <!--
77                                 Map HandleService and AttributeAuthority.  We need to pass in the (possibly empty)
78                                 set of Domain elements as a parameter.
79                         -->
80                         <xsl:apply-templates select="shib:HandleService|shib:AttributeAuthority">
81                                 <xsl:with-param name="Domain" select="shib:Domain"/>
82                         </xsl:apply-templates>
83                         <xsl:call-template name="Alias"/>
84                         <xsl:apply-templates select="shib:Contact"/>
85                 </EntityDescriptor>
86         </xsl:template>
87         
88         <!--
89                 Map HandleService to IDPSSODescriptor.
90         -->
91         <xsl:template match="shib:HandleService">
92                 <xsl:param name="Domain"/>
93                 <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
94                         <!--
95                                 Extensions appears iff there is something to put in it.
96                         -->
97                         <xsl:if test="boolean($Domain)">
98                                 <Extensions>
99                                         <xsl:apply-templates select="$Domain"/>
100                                 </Extensions>
101                         </xsl:if>
102                         <KeyDescriptor use="signing">
103                                 <ds:KeyInfo>
104                                         <ds:KeyName>
105                                                 <xsl:value-of select="@Name"/>
106                                         </ds:KeyName>
107                                 </ds:KeyInfo>
108                         </KeyDescriptor>
109                         <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"
110                                 Location="{@Location}"/>
111                 </IDPSSODescriptor>
112         </xsl:template>
113
114         <!--
115                 Map AttributeAuthority to AttributeAuthorityDescriptor.
116         -->
117         <xsl:template match="shib:AttributeAuthority">
118                 <xsl:param name="Domain"/>
119                 <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
120                         <!--
121                                 Extensions appears iff there is something to put in it.
122                         -->
123                         <xsl:if test="boolean($Domain)">
124                                 <Extensions>
125                                         <xsl:apply-templates select="$Domain"/>
126                                 </Extensions>
127                         </xsl:if>
128                         <AttributeService Binding="urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding"
129                                 Location="{@Location}"/>
130                 </AttributeAuthorityDescriptor>
131         </xsl:template>
132         
133         <!--
134                 Map Domain to a Scope extension.
135         -->
136         <xsl:template match="shib:Domain">
137                 <shibmeta:Scope>
138                         <xsl:apply-templates select="@regexp"/>
139                         <xsl:value-of select="."/>
140                 </shibmeta:Scope>
141         </xsl:template>
142         
143         <!--
144                 Map DestinationSite to an EntityDescriptor with a particular format.
145         -->
146         <xsl:template match="shib:DestinationSite">
147                 <EntityDescriptor entityID="{@Name}">
148                         <!--
149                                 Copy through comments and text blocks at the start of the output element.
150                                 This means we don't lose comments, but there is no way to guarantee they will
151                                 come out "in the right place".
152                         -->
153                         <xsl:apply-templates select="text()|comment()"/>
154                         <!--
155                                 Generate IDPSSODescriptor.
156                         -->
157                         <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol">
158                                 <!--
159                                         Map @ErrorURL (if present) to @errorURL
160                                 -->
161                                 <xsl:apply-templates select="@ErrorURL"/>
162                                 <!--
163                                         Map AttributeRequester elements to KeyDescriptor elements.
164                                 -->
165                                 <xsl:apply-templates select="shib:AttributeRequester"/>
166                                 <!--
167                                         Map the AssertionConsumerServiceURL elements to
168                                         AssertionConsumerService elements.  The latter require unique
169                                         integer indices, so do this by looping over them and using
170                                         position in the loop to generate each index.
171                                 -->
172                                 <xsl:for-each select="shib:AssertionConsumerServiceURL">
173                                         <xsl:apply-templates select=".">
174                                                 <xsl:with-param name="index" select="position()-1"/>
175                                         </xsl:apply-templates>
176                                 </xsl:for-each>
177                         </SPSSODescriptor>
178                         <xsl:call-template name="Alias"/>
179                         <xsl:apply-templates select="shib:Contact"/>
180                 </EntityDescriptor>
181         </xsl:template>
182
183         <!--
184                 Map @ErrorURL to @errorURL
185         -->
186         <xsl:template match="@ErrorURL">
187                 <xsl:attribute name="errorURL"><xsl:value-of select="."/></xsl:attribute>
188         </xsl:template>
189
190         <!--
191                 Map AttributeRequester to KeyDescriptor.
192         -->
193         <xsl:template match="shib:AttributeRequester">
194                 <KeyDescriptor>
195                         <ds:KeyInfo>
196                                 <ds:KeyName>
197                                         <xsl:value-of select="@Name"/>
198                                 </ds:KeyName>
199                         </ds:KeyInfo>
200                 </KeyDescriptor>
201         </xsl:template>
202
203         <!--
204                 Map AssertionConsumerServiceURL to AssertionConsumerService.
205         -->
206         <xsl:template match="shib:AssertionConsumerServiceURL">
207                 <xsl:param name="index"/>
208                 <AssertionConsumerService index="{$index}"
209                         Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="{@Location}"
210                 />
211         </xsl:template>
212
213         <!--
214                 Named template to map a set of Alias elements to a corresponding Organization.
215         -->
216         <xsl:template name="Alias">
217                 <xsl:if test="boolean(shib:Alias)">
218                         <Organization>
219                                 <xsl:apply-templates select="shib:Alias" mode="OrganizationName"/>
220                                 <xsl:apply-templates select="shib:Alias" mode="OrganizationDisplayName"/>
221                                 <xsl:apply-templates select="shib:Alias" mode="OrganizationURL"/>
222                         </Organization>
223                 </xsl:if>
224         </xsl:template>
225
226         <!--
227                 Map Alias to OrganizationName
228         -->
229         <xsl:template match="shib:Alias" mode="OrganizationName">
230                 <OrganizationName>
231                         <xsl:call-template name="copyXmlLang"/>
232                         <xsl:value-of select="."/>
233                 </OrganizationName>
234         </xsl:template>
235
236         <!--
237                 Map Alias to OrganizationDisplayName
238         -->
239         <xsl:template match="shib:Alias" mode="OrganizationDisplayName">
240                 <OrganizationDisplayName>
241                         <xsl:call-template name="copyXmlLang"/>
242                         <xsl:value-of select="."/>
243                 </OrganizationDisplayName>
244         </xsl:template>
245
246         <!--
247                 Map Alias to OrganizationURL
248         -->
249         <xsl:template match="shib:Alias" mode="OrganizationURL">
250                 <OrganizationURL>
251                         <xsl:call-template name="copyXmlLang"/>
252                         <!-- there is nothing to map, but the URL is mandatory -->
253                         <xsl:text>http://www.example.com/</xsl:text>
254                 </OrganizationURL>
255         </xsl:template>
256
257         <!--
258                 Copy an xml:lang attribute, or default to "en" if none present.
259         -->
260         <xsl:template name="copyXmlLang">
261                 <xsl:if test="boolean(@xml:lang)">
262                         <xsl:attribute name="xml:lang"><xsl:value-of select="@xml:lang"/></xsl:attribute>
263                 </xsl:if>
264                 <xsl:if test="not(boolean(@xml:lang))">
265                         <xsl:attribute name="xml:lang">en</xsl:attribute>
266                 </xsl:if>
267         </xsl:template>
268
269         <!--
270                 Map Contact to ContactPerson
271         -->
272         <xsl:template match="shib:Contact">
273                 <ContactPerson contactType="{@Type}">
274                         <!--
275                                 There is no real mapping for the Name attribute, so we rather arbitrarily
276                                 dump that into GivenName rather than trying to split it into a GivenName and
277                                 a SurName or something complicated like that.
278                         -->
279                         <GivenName>
280                                 <xsl:value-of select="@Name"/>
281                         </GivenName>
282                         <!--
283                                 E-mail address, but only if it was present in the original.
284                         -->
285                         <xsl:apply-templates select="@Email" mode="Contact"/>
286                 </ContactPerson>
287         </xsl:template>
288
289         <!--
290                 E-mail address for Contact
291         -->
292         <xsl:template match="@Email" mode="Contact">
293                 <EmailAddress>
294                         <xsl:value-of select="."/>
295                 </EmailAddress>
296         </xsl:template>
297
298         <!--
299                 By default, copy referenced attributes through unchanged.
300         -->
301         <xsl:template match="@*">
302                 <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
303         </xsl:template>
304
305         <!--
306                 By default, copy comments through to the output unchanged, but strip extra text.
307         -->
308         <xsl:template match="comment()">
309                 <xsl:copy/>
310         </xsl:template>
311         <xsl:template match="text()"/>
312
313 </xsl:stylesheet>
314