Skip to content

Commit

Permalink
Merge branch 'release/20.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
cslzchen committed Nov 23, 2020
2 parents 238e73c + 20c31dd commit e30e744
Show file tree
Hide file tree
Showing 4 changed files with 360 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

We follow the CalVer (https://calver.org/) versioning scheme: YY.MINOR.MICRO.

20.3.0 (2020-11-23)
===================

- Supports the department attribute for institution SSO
- Added postman tests for testing SAML institutions

20.2.5 (2020-09-18)
===================

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.security.auth.login.AccountException;
import javax.security.auth.login.FailedLoginException;
import javax.servlet.http.Cookie;
Expand Down Expand Up @@ -170,6 +172,8 @@ public String getInstitutionId() {

private static final String SHIBBOLETH_COOKIE_PREFIX = "_shibsession_";

private static final String LDAP_DN_OU_PREFIX = "ou=";

private static final int SIXTY_SECONDS = 60 * 1000;

/** The Logger Instance. */
Expand Down Expand Up @@ -581,6 +585,22 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated(
isMemberOf
);
}

final String departmentRaw = user.optString("departmentRaw").trim();
// Unlike all the above attributes that are released to us from the institutions, the `eduPerson` is a boolean
// per-institution flag set by CAS in the "institutions-auth.xsl" file. It determines whether the department
// attribute uses the the eduPerson schema (https://wiki.refeds.org/display/STAN/eduPerson).
final boolean eduPerson = user.optBoolean("eduPerson");

String department = "";
if (departmentRaw.isEmpty()) {
logger.warn("[CAS XSLT] Missing department: fullname={}, username={}, institution={}", fullname, username, institutionId);
} else {
department = this.retrieveDepartment(departmentRaw, eduPerson);
}
// Insert the `department` attribute into the payload, which does not overwrite `departmentRaw`.
normalizedPayload.getJSONObject("provider").getJSONObject("user").put("department", department);

final String payload = normalizedPayload.toString();
logger.info(
"[CAS XSLT] All attributes checked: username={}, institution={}, member={}",
Expand Down Expand Up @@ -699,6 +719,42 @@ protected JSONObject normalizeRemotePrincipal(final OpenScienceFrameworkCredenti
return XML.toJSONObject(writer.getBuffer().toString());
}

/**
* Retrieve the department value from the raw department string.
*
* @param departmentRaw the raw department string
* @param eduPerson whether the department attribute uses eduPerson schema
* @return the department value
*/
private String retrieveDepartment(final String departmentRaw, final boolean eduPerson) {

// Return the raw value as it is if institutions do not use eduPerson schema for the department attribute
if (!eduPerson) {
return departmentRaw;
}

// For institutions that use the eduPerson schema, the department must be retrieved from the raw value. Here is
// an example: "ou=Music Department, o=Notre Dame, dc=nd, dc=edu", whose syntax is LDAP Distinguished Names.
try {
final LdapName dn = new LdapName(departmentRaw);
for (int i = dn.size() - 1; i >=0; i--) {
final String rdn = dn.get(i);
if (rdn.startsWith(LDAP_DN_OU_PREFIX)) {
return rdn.substring(LDAP_DN_OU_PREFIX.length());
}
}
} catch (final InvalidNameException | IndexOutOfBoundsException e) {
logger.error(
"[CAS XSLT] Invalid syntax for LDAP Distinguished Names: departmentRaw={}, error={}",
departmentRaw,
e.getMessage()
);
// Return an empty string if the syntax is wrong
return "";
}
return "";
}

public void setInstitutionsAuthUrl(final String institutionsAuthUrl) {
this.institutionsAuthUrl = institutionsAuthUrl;
}
Expand Down
29 changes: 28 additions & 1 deletion etc/institutions-auth.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@
<id>esu</id>
<user>
<!-- Each institution has its customized mapping of attributes -->
<username><xsl:value-of select="//attribute[@name='eppn']/@value"/></username>
<username><xsl:value-of select="//attribute[@name='mail']/@value"/></username>
<fullname><xsl:value-of select="//attribute[@name='displayedName']/@value"/></fullname>
<familyName><xsl:value-of select="//attribute[@name='sn']/@value"/></familyName>
<givenName><xsl:value-of select="//attribute[@name='givenName']/@value"/></givenName>
<departmentRaw><xsl:value-of select="//attribute[@name='department']/@value"/></departmentRaw>
<eduPerson>true</eduPerson>
<middleNames/>
<suffix/>
</user>
Expand Down Expand Up @@ -83,13 +85,36 @@
</user>
</xsl:when>
<!-- Princeton University (PU) -->
<!--
The departmentRaw and eduPerson attributes are for local testing purpose only.
Princeton does not release such an attribute yet.
-->
<xsl:when test="$idp='https://idp.princeton.edu/idp/shibboleth'">
<id>pu</id>
<user>
<username><xsl:value-of select="//attribute[@name='mail']/@value"/></username>
<fullname><xsl:value-of select="//attribute[@name='displayName']/@value"/></fullname>
<familyName><xsl:value-of select="//attribute[@name='sn']/@value"/></familyName>
<givenName><xsl:value-of select="//attribute[@name='givenName']/@value"/></givenName>
<departmentRaw><xsl:value-of select="//attribute[@name='department']/@value"/></departmentRaw>
<eduPerson>true</eduPerson>
<suffix/>
</user>
</xsl:when>
<!-- University of Arizona (UA) -->
<!--
The departmentRaw and eduPerson attributes are both for production and local testing purposes.
University of Arizona is the first institution to release the department attribute to OSF.
-->
<xsl:when test="$idp='urn:mace:incommon:arizona.edu'">
<id>ua</id>
<user>
<username><xsl:value-of select="//attribute[@name='mail']/@value"/></username>
<fullname><xsl:value-of select="//attribute[@name='displayName']/@value"/></fullname>
<familyName><xsl:value-of select="//attribute[@name='sn']/@value"/></familyName>
<givenName><xsl:value-of select="//attribute[@name='givenName']/@value"/></givenName>
<departmentRaw><xsl:value-of select="//attribute[@name='department']/@value"/></departmentRaw>
<eduPerson>false</eduPerson>
<middleNames/>
<suffix/>
</user>
Expand Down Expand Up @@ -150,6 +175,8 @@
<fullname><xsl:value-of select="//attribute[@name='displayName']/@value"/></fullname>
<familyName><xsl:value-of select="//attribute[@name='sn']/@value"/></familyName>
<givenName><xsl:value-of select="//attribute[@name='givenName']/@value"/></givenName>
<departmentRaw><xsl:value-of select="//attribute[@name='department']/@value"/></departmentRaw>
<eduPerson>false</eduPerson>
<middleNames/>
<suffix/>
</user>
Expand Down
Loading

0 comments on commit e30e744

Please sign in to comment.