<?xml version="1.0" encoding="UTF-8"?>
<!--
    This file is an EXAMPLE configuration file for use within 
    a SAML WebSSO federation containing various example attributes,
    encoders, and a couple of example data connectors.
 
    Deployers should refer to the Identity Provider 4 documentation
 
    https://wiki.shibboleth.net/confluence/display/IDP4/AttributeResolverConfiguration
 
    for a complete list of components and their options.
-->
 
<AttributeResolver
        xmlns="urn:mace:shibboleth:2.0:resolver"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
 
    <!-- ========================================== -->
    <!--      Attribute Definitions                 -->
    <!-- ========================================== -->
 
    <!-- Schema: Core schema attributes-->
 
    <!-- givenName -->
    <AttributeDefinition xsi:type="Simple" id="givenName">
        <InputDataConnector ref="myLDAP" attributeNames="givenName"/>
    </AttributeDefinition>
 
    <!-- sn -->
    <AttributeDefinition xsi:type="Simple" id="sn">
        <InputDataConnector ref="myLDAP" attributeNames="sn"/>
    </AttributeDefinition>
 
    <!-- displayName, alternative 1: direct myLDAP lookup -->
    <!-- use this if the displayName is stored in myLDAP -->
    <AttributeDefinition xsi:type="Simple" id="displayName">
        <InputDataConnector ref="myLDAP" attributeNames="displayName"/>
    </AttributeDefinition>
 
    <!-- displayName, alternative 2: create from givenName and sn -->
    <!--
    <AttributeDefinition xsi:type="Template" id="displayName">
        <InputAttributeDefinition ref="givenName"/>
        <InputAttributeDefinition ref="sn"/>
        <Template>${givenName} ${sn}</Template>
    </AttributeDefinition>
    -->
 
    <!-- mail -->
    <AttributeDefinition xsi:type="Simple" id="mail">
        <InputDataConnector ref="myLDAP" attributeNames="mail"/>
    </AttributeDefinition>
 
    <!-- eduPersonPrincipalName, alternative 1: direct myLDAP lookup  -->
    <!-- use this if the eduPersonPrincipalName is stored in myLDAP -->
    <!--
    <AttributeDefinition xsi:type="Prescoped" id="eduPersonPrincipalName">
        <InputDataConnector ref="myLDAP" attributeNames="eduPersonPrincipalName"/>
    </AttributeDefinition>
    -->
 
    <!-- eduPersonPrincipalName, alternative 2: create from login name -->
    <!-- Change the attributeNames as appropriate to your IDM & LDAP -->
    <AttributeDefinition xsi:type="Scoped" id="eduPersonPrincipalName" scope="%{idp.scope}">
        <InputDataConnector ref="myLDAP" attributeNames="uid"/>
    </AttributeDefinition>
 
    <!-- samlPairwiseID, alternative 1: stored value  -->
    <!-- use this if the samlPairwiseID input is stored via DataConnector myStoredId -->
    <!--
    <AttributeDefinition xsi:type="Scoped" id="samlPairwiseID" scope="%{idp.scope}">
        <InputDataConnector ref="myStoredId" attributeNames="storedId"/>
    </AttributeDefinition>
    -->
 
    <!-- samlPairwiseID, alternative 2: computed value  -->
    <!-- use this if the samlPairwiseID is computed via DataConnector computed -->
    <AttributeDefinition xsi:type="Scoped" id="samlPairwiseID" scope="%{idp.scope}">
        <InputDataConnector ref="computed" attributeNames="ComputedID" />
    </AttributeDefinition>
 
    <!-- samlSubjectID -->
    <AttributeDefinition xsi:type="Scoped" id="samlSubjectID" scope="%{idp.scope}">
        <InputAttributeDefinition ref="subjectIdHash"/>
    </AttributeDefinition>
 
    <!-- subjectIdHash -->
    <AttributeDefinition xsi:type="ScriptedAttribute" id="subjectIdHash" dependencyOnly="true">
        <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}" />
        <Script><![CDATA[
            var digestUtils = Java.type("org.apache.commons.codec.digest.DigestUtils");
            var saltedHash = digestUtils.sha256Hex(%{idp.persistentId.sourceAttribute}.getValues().get(0) + "%{idp.persistentId.salt}");
            subjectIdHash.addValue(saltedHash);
        ]]></Script>
    </AttributeDefinition>
 
    <!-- eduPersonTargetedID, alternative 1: stored value  -->
    <!-- 
    <AttributeDefinition xsi:type="SAML2NameID" id="eduPersonTargetedID" nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
        <InputDataConnector ref="myStoredId" attributeNames="storedId" />
        <AttributeEncoder xsi:type="SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID"/>
    </AttributeDefinition>
    -->
    <!-- eduPersonTargetedID, alternative 2: computed value  -->
    <AttributeDefinition xsi:type="SAML2NameID" id="eduPersonTargetedID" nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">
        <InputDataConnector ref="computed" attributeNames="ComputedID" />
        <AttributeEncoder xsi:type="SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID"/>
    </AttributeDefinition>
 
    <!-- schacPersonalUniqueCode -->
    <!-- example source attribute imatrikulacnecislo has to comply ESI requirements -->
    <!-- https://www.safeid.sk/attributes:services:erasmus -->
    <!-- 
    <AttributeDefinition xsi:type="Template" id="schacPersonalUniqueCode">
        <InputDataConnector ref="myLDAP" attributeNames="imatrikulacnecislo"/>
        <DisplayName xml:lang="sk">Európsky identifikátor študenta (ESI)</DisplayName>
        <DisplayName xml:lang="en">European Student Identifier (ESI)</DisplayName>
        <Template>urn:schac:personalUniqueCode:int:esi:%{idp.scope}:${imatrikulacnecislo}</Template>
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.14" friendlyName="schacPersonalUniqueCode" encodeType="false"/>
    </AttributeDefinition>
    -->
 
    <!-- eduPersonAffiliation, alternative 1: direct myLDAP lookup -->
    <!-- use this if the eduPersonAffiliation is stored in myLDAP -->
    <AttributeDefinition xsi:type="Simple" id="eduPersonAffiliation">
        <InputDataConnector ref="myLDAP" attributeNames="eduPersonAffiliation"/>
    </AttributeDefinition>
 
    <!-- eduPersonScopedAffiliation -->
    <AttributeDefinition xsi:type="Scoped" id="eduPersonScopedAffiliation" scope="%{idp.scope}">
        <InputAttributeDefinition ref="eduPersonAffiliation"/>
    </AttributeDefinition>
 
    <!-- eduPersonEntitlement -->
    <!-- Assign the common-lib-terms entitlement to all members and library-walk-in users -->
    <!-- Assert that all your subjects with an affiliation of member have had their identity sufficiently verified that they can all request personal certificates via TCS -->
    <!-- You'll need to adapt that second part as needed, depending on what parts of your community you intend to offer the TCS personal service to.  -->
    <AttributeDefinition id="eduPersonEntitlement" xsi:type="Mapped">
        <InputAttributeDefinition ref="eduPersonAffiliation" />
        <ValueMap>
            <ReturnValue>urn:mace:dir:entitlement:common-lib-terms</ReturnValue>
            <SourceValue>member</SourceValue>
            <SourceValue>library-walk-in</SourceValue>
        </ValueMap>
        <ValueMap>
            <ReturnValue>urn:mace:terena.org:tcs:personal-user</ReturnValue>
            <SourceValue>member</SourceValue>
        </ValueMap>
    </AttributeDefinition>
 
    <!-- schacHomeOrganization -->
    <AttributeDefinition xsi:type="Simple" id="schacHomeOrganization">
        <InputDataConnector ref="staticAttributes" attributeNames="schacHomeOrganization"/>
        <DisplayName xml:lang="sk">Doména organizácie</DisplayName>
        <DisplayName xml:lang="en">Home organization domain</DisplayName>
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.9"/>
    </AttributeDefinition>
 
    <!-- schacHomeOrganizationType -->
    <AttributeDefinition xsi:type="Simple" id="schacHomeOrganizationType">
        <InputDataConnector ref="staticAttributes" attributeNames="schacHomeOrganizationType"/>
        <DisplayName xml:lang="sk">Typ organizácie</DisplayName>
        <DisplayName xml:lang="en">Home organization type</DisplayName>
        <AttributeEncoder xsi:type="SAML2String" name="urn:oid:1.3.6.1.4.1.25178.1.2.10"/>
    </AttributeDefinition>
 
    <!-- ========================================== -->
    <!--      Data Connectors                       -->
    <!-- ========================================== -->
 
    <DataConnector id="staticAttributes" xsi:type="Static">
 
        <Attribute id="o">
            <Value>Meno univerzity</Value>
        </Attribute>
 
        <Attribute id="schacHomeOrganization">
            <Value>%{idp.scope}</Value>
        </Attribute>
 
        <Attribute id="schacHomeOrganizationType">
            <Value>urn:schac:homeOrganizationType:eu:higherEducationInstitution</Value>
            <!-- This value is for EU higher education institution, other allowed values are:
            - urn:schac:homeOrganizationType:eu:educationInstitution
            - urn:schac:homeOrganizationType:int:NREN
            - urn:schac:homeOrganizationType:int:universityHospital
            - urn:schac:homeOrganizationType:int:NRENAffiliate
            - urn:schac:homeOrganizationType:int:other
            -->
        </Attribute>
 
    </DataConnector>
 
    <!-- Example LDAP Connector (DataConnector myLDAP depends on ldap.properties). -->
    <!-- https://wiki.shibboleth.net/confluence/display/IDP4/LDAPConnector -->
    <DataConnector id="myLDAP" xsi:type="LDAPDirectory"
        ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}"
        baseDN="%{idp.attribute.resolver.LDAP.baseDN}" 
        principal="%{idp.attribute.resolver.LDAP.bindDN}"
        principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}"
        useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}"
        connectTimeout="%{idp.attribute.resolver.LDAP.connectTimeout}"
        trustFile="%{idp.attribute.resolver.LDAP.trustCertificates}"
        responseTimeout="%{idp.attribute.resolver.LDAP.responseTimeout}">
        <FilterTemplate>
            <![CDATA[
                %{idp.attribute.resolver.LDAP.searchFilter}
            ]]>
        </FilterTemplate>
        <ConnectionPool
            minPoolSize="%{idp.pool.LDAP.minSize:3}"
            maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
            blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
            validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}"
            validateTimerPeriod="%{idp.pool.LDAP.validatePeriod:PT5M}"
            validateDN="%{idp.pool.LDAP.validateDN:}"
            validateFilter="%{idp.pool.LDAP.validateFilter:(objectClass=*)}"
            expirationTime="%{idp.pool.LDAP.idleTime:PT10M}"/>
    </DataConnector>
 
    <!-- DataConnector for stored pairwise-id (depends on saml-nameid.properties). -->
    <!-- https://wiki.shibboleth.net/confluence/display/IDP4/PersistentNameIDGenerationConfiguration -->
    <!-- 
    <DataConnector id="myStoredId"
        xsi:type="StoredId"
        generatedAttributeID="storedId"
        salt="%{idp.persistentId.salt}"
        algorithm="%{idp.persistentId.algorithm:SHA}"
        encoding="%{idp.persistentId.encoding:BASE32}"
        queryTimeout="0">
        <InputAttributeDefinition ref="%{idp.persistentId.sourceAttribute}"/>
        <BeanManagedConnection>shibboleth.MySQLDataSource</BeanManagedConnection>
    </DataConnector>
    -->
 
    <!-- DataConector for computed pairwise-id (depends on saml-nameid.properties). -->
    <!-- https://wiki.shibboleth.net/confluence/display/IDP4/PersistentNameIDGenerationConfiguration -->
    <DataConnector id="computed"
        xsi:type="ComputedId"
        generatedAttributeID="ComputedID"
        salt="%{idp.persistentId.salt}"
        algorithm="%{idp.persistentId.algorithm:SHA}"
        encoding="%{idp.persistentId.encoding:BASE32}">
        <InputDataConnector ref="myLDAP" attributeNames="%{idp.persistentId.sourceAttribute}" />
    </DataConnector>
 
</AttributeResolver>