diff --git a/cas-server-support-osf/src/main/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsAction.java b/cas-server-support-osf/src/main/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsAction.java index c47bf3fb..166a1014 100644 --- a/cas-server-support-osf/src/main/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsAction.java +++ b/cas-server-support-osf/src/main/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsAction.java @@ -580,38 +580,73 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated( throw new InstitutionLoginFailedAttributesMissingException("Missing user's names"); } - // Call Login Availability API + final String email = user.optString("email").trim(); + final String o = user.optString("o").trim(); + final String ou = user.optString("ou").trim(); + final String eduPersonAffiliation = user.optString("eduPersonAffiliation").trim(); final String entitlement = user.optString("entitlement").trim(); - if (!StringUtils.isEmpty(entitlement)) { - // send post method to RDM API - final JSONObject bodyObj = new JSONObject(); - final String normalizeEntitlement = entitlement.replace("\\;", ";"); - bodyObj.put("institution_id", institutionId); - bodyObj.put("entitlements", getEntitlements(normalizeEntitlement)); - user.put("entitlement", normalizeEntitlement); // normalize entitlement in payload - - HttpResponse httpResponse; - try { - httpResponse = callLoginAvailabilityAPI(bodyObj); - final BufferedReader bf = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent())); - String bodyData = ""; - final StringBuilder builder = new StringBuilder(); - while ((bodyData = bf.readLine()) != null) { - builder.append(bodyData); - } - final JSONObject json = new JSONObject(builder.toString()); - final boolean isLoginAvailability = (Boolean) json.get("login_availability"); - if (!isLoginAvailability) { - throw new InstitutionLoginAvailabilityException(); - } - } catch (final IOException e) { - logger.error( - "[OSF API] Notify Remote Principal Authenticated Failed: Communication Error - {}", - e.getMessage() - ); - throw new InstitutionLoginFailedOsfApiException("Communication Error between OSF CAS and OSF API"); + final String eduPersonScopedAffiliation = user.optString("eduPersonScopedAffiliation").trim(); + final String eduPersonTargetedID = user.optString("eduPersonTargetedID").trim(); + final String eduPersonAssurance = user.optString("eduPersonAssurance").trim(); + final String eduPersonUniqueId = user.optString("eduPersonUniqueId").trim(); + final String eduPersonOrcid = user.optString("eduPersonOrcid").trim(); + final String isMemberOf = user.optString("isMemberOf").trim(); + final String jasn = user.optString("jasn").trim(); + final String jaGivenName = user.optString("jaGivenName").trim(); + final String jaDisplayName = user.optString("jaDisplayName").trim(); + final String jao = user.optString("jao").trim(); + final String jaou = user.optString("jaou").trim(); + final String gakuninScopedPersonalUniqueCode = user.optString("gakuninScopedPersonalUniqueCode").trim(); + + // Call Login Availability API + final JSONObject bodyObj = new JSONObject(); + bodyObj.put("institution_id", institutionId); + bodyObj.put("mail", email); + bodyObj.put("sn", familyName); + bodyObj.put("o", getStringList(o)); + bodyObj.put("ou", ou); + bodyObj.put("givenName", givenName); + bodyObj.put("displayName", fullname); + bodyObj.put("eduPersonAffiliation", getStringList(eduPersonAffiliation)); + bodyObj.put("eduPersonPrincipalName", username); + bodyObj.put("eduPersonEntitlement", getStringList(entitlement)); + bodyObj.put("eduPersonScopedAffiliation", getStringList(eduPersonScopedAffiliation)); + bodyObj.put("eduPersonTargetedID", getStringList(eduPersonTargetedID)); + bodyObj.put("eduPersonAssurance", getStringList(eduPersonAssurance)); + bodyObj.put("eduPersonUniqueId", eduPersonUniqueId); + bodyObj.put("eduPersonOrcid", getStringList(eduPersonOrcid)); + bodyObj.put("isMemberOf", getStringList(isMemberOf)); + bodyObj.put("jasn", jasn); + bodyObj.put("jaGivenName", jaGivenName); + bodyObj.put("jaDisplayName", jaDisplayName); + bodyObj.put("jao", getStringList(jao)); + bodyObj.put("jaou", jaou); + bodyObj.put("gakuninScopedPersonalUniqueCode", getStringList(gakuninScopedPersonalUniqueCode)); + + // send post method to RDM API + HttpResponse httpResponse; + try { + httpResponse = callLoginAvailabilityAPI(bodyObj); + final int statusCode = httpResponse.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_FORBIDDEN) { + throw new InstitutionLoginAvailabilityException(); } + final BufferedReader bf = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent())); + String bodyData = ""; + final StringBuilder builder = new StringBuilder(); + while ((bodyData = bf.readLine()) != null) { + builder.append(bodyData); + } + final JSONObject json = new JSONObject(builder.toString()); + final String loginAvailability = (String) json.get("login_availability"); + user.put("login_availability", loginAvailability); + } catch (final IOException e) { + logger.error( + "[OSF API] Notify Remote Principal Authenticated Failed: Communication Error - {}", + e.getMessage() + ); + throw new InstitutionLoginFailedOsfApiException("Communication Error between OSF CAS and OSF API"); } final String payload = normalizedPayload.toString(); @@ -652,7 +687,7 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated( // Step 4 - Make the OSF API request with the encrypted payload. try { - final HttpResponse httpResponse = Request.Post(this.institutionsAuthUrl) + httpResponse = Request.Post(this.institutionsAuthUrl) .addHeader(new BasicHeader("Content-Type", "text/plain")) .bodyString(jweString, ContentType.APPLICATION_JSON) .execute() @@ -701,20 +736,21 @@ protected HttpResponse callLoginAvailabilityAPI(final JSONObject bodyObj) throws } /** - * Gets the entitlements. + * Get list of string. * - * @param entitlement the entitlement - * @return the entitlements + * @param value value + * @return list of string */ - protected List getEntitlements(final String entitlement) { - final List entitlements = new ArrayList(); - if (!StringUtils.isEmpty(entitlement)) { - final String[] arr = entitlement.split(";"); + protected List getStringList(final String value) { + final String normalizedValue = value.replace("\\;", ";"); + final List values = new ArrayList(); + if (!StringUtils.isEmpty(normalizedValue)) { + final String[] arr = normalizedValue.split(";"); for (final String str : arr) { - entitlements.add(str.trim()); + values.add(str.trim()); } } - return entitlements; + return values; } /** diff --git a/cas-server-support-osf/src/test/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsActionTests.java b/cas-server-support-osf/src/test/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsActionTests.java index 2bd48c19..909ea2f7 100644 --- a/cas-server-support-osf/src/test/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsActionTests.java +++ b/cas-server-support-osf/src/test/java/io/cos/cas/authentication/handler/support/OpenScienceFrameworkPrincipalFromRequestRemoteUserNonInteractiveCredentialsActionTests.java @@ -117,6 +117,8 @@ public void handleInstitutionValidRemotePrincipal() throws Exception { final OpenScienceFrameworkCredential osfCredential = new OpenScienceFrameworkCredential(); osfCredential.setUsername(AbstractTestUtils.CONST_MAIL); osfCredential.setInstitutionId(AbstractTestUtils.CONST_INSTITUTION_ID); + osfRemoteAuthenticate + .setInstitutionsLoginAvailabilityUrl(AbstractTestUtils.CONST_INSTITUTION_LOGIN_AVAILABILITY_URL); try { osfRemoteAuthenticate.notifyRemotePrincipalAuthenticated(osfCredential); } catch (final AccountException e) { @@ -254,7 +256,7 @@ public void verifyLoginAvailabilityGetEntitlementFlow() throws Exception { List entitlementList = new ArrayList(); // Verify in case single entitlement - entitlementList = osfRemoteAuthenticate.getEntitlements(AbstractTestUtils.CONST_SINGLE_ENTITLEMENT_INPUT); + entitlementList = osfRemoteAuthenticate.getStringList(AbstractTestUtils.CONST_SINGLE_ENTITLEMENT_INPUT); assertEquals(entitlementList.size(), AbstractTestUtils.CONST_SINGLE_ENTITLEMENTS_OUTPUT.length); } @@ -272,7 +274,7 @@ public void verifyLoginAvailabilitySingleEntitlementFlow() throws Exception { osfCredential.setUsername(AbstractTestUtils.CONST_MAIL); osfRemoteAuthenticate.setSingleEntitlement(true); - osfRemoteAuthenticate.setLoginAvailability(true); + osfRemoteAuthenticate.setLoginAvailability("can login"); osfRemoteAuthenticate .setInstitutionsLoginAvailabilityUrl(AbstractTestUtils.CONST_INSTITUTION_LOGIN_AVAILABILITY_URL); @@ -296,7 +298,6 @@ public void verifyLoginAvailabilityExceptionFlow() throws Exception { osfCredential.setUsername(AbstractTestUtils.CONST_MAIL); osfRemoteAuthenticate.setSingleEntitlement(true); - osfRemoteAuthenticate.setLoginAvailability(false); osfRemoteAuthenticate .setInstitutionsLoginAvailabilityUrl(AbstractTestUtils.CONST_INSTITUTION_LOGIN_AVAILABILITY_URL); osfRemoteAuthenticate.notifyRemotePrincipalAuthenticated(osfCredential); diff --git a/cas-server-support-osf/src/test/java/io/cos/cas/mock/MockNormalizeRemotePrincipalWithEntitlement.java b/cas-server-support-osf/src/test/java/io/cos/cas/mock/MockNormalizeRemotePrincipalWithEntitlement.java index 6b81906d..76b01cf9 100644 --- a/cas-server-support-osf/src/test/java/io/cos/cas/mock/MockNormalizeRemotePrincipalWithEntitlement.java +++ b/cas-server-support-osf/src/test/java/io/cos/cas/mock/MockNormalizeRemotePrincipalWithEntitlement.java @@ -3,12 +3,15 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import org.apache.http.HttpStatus; import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.entity.BasicHttpEntity; import org.jasig.cas.CentralAuthenticationService; import org.json.JSONObject; import org.mockito.Mockito; +import org.springframework.util.StringUtils; import io.cos.cas.AbstractTestUtils; import io.cos.cas.authentication.OpenScienceFrameworkCredential; @@ -21,12 +24,12 @@ public class MockNormalizeRemotePrincipalWithEntitlement extends MockNormalizeRemotePrincipal { private boolean isSingleEntitlement; - private boolean isLoginAvailability; + private String loginAvailability; public MockNormalizeRemotePrincipalWithEntitlement(final CentralAuthenticationService centralAuthenticationService) { super(centralAuthenticationService); this.isSingleEntitlement = false; - this.isLoginAvailability = false; + this.loginAvailability = ""; } @Override @@ -38,7 +41,7 @@ protected JSONObject normalizeRemotePrincipal(final OpenScienceFrameworkCredenti user.put("fullname", AbstractTestUtils.CONST_DISPLAY_NAME); if (isSingleEntitlement) { - user.put("entitlement", AbstractTestUtils.CONST_SINGLE_ENTITLEMENT_INPUT); + user.put("eduPersonEntitlement", AbstractTestUtils.CONST_SINGLE_ENTITLEMENT_INPUT); } provider.put("id", credential.getInstitutionId()); @@ -49,13 +52,18 @@ protected JSONObject normalizeRemotePrincipal(final OpenScienceFrameworkCredenti protected HttpResponse callLoginAvailabilityAPI(final JSONObject bodyObj) throws IOException, ClientProtocolException { final HttpResponse mockedResponse = Mockito.mock(HttpResponse.class); + final StatusLine statusLine = Mockito.mock(StatusLine.class); final BasicHttpEntity entity = new BasicHttpEntity(); - String bodyResponse = "{\"login_availability\":false,\"meta\":{\"version\":\"2.0\"}}"; - if (this.isLoginAvailability) { - bodyResponse = "{\"login_availability\":true,\"meta\":{\"version\":\"2.0\"}}"; + String bodyResponse = "{\"meta\":{\"version\":\"2.0\"}}"; + if (StringUtils.hasText(this.loginAvailability)) { + bodyResponse = "{\"login_availability\":\"" + this.loginAvailability + "\",\"meta\":{\"version\":\"2.0\"}}"; + Mockito.when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK); + } else { + Mockito.when(statusLine.getStatusCode()).thenReturn(HttpStatus.SC_FORBIDDEN); } entity.setContent(new ByteArrayInputStream(bodyResponse.getBytes())); + Mockito.when(mockedResponse.getStatusLine()).thenReturn(statusLine); Mockito.when(mockedResponse.getEntity()).thenReturn(entity); return mockedResponse; } @@ -64,8 +72,8 @@ public void setSingleEntitlement(final boolean isSingleEntitlement) { this.isSingleEntitlement = isSingleEntitlement; } - public void setLoginAvailability(final boolean isLoginAvailability) { - this.isLoginAvailability = isLoginAvailability; + public void setLoginAvailability(final String loginAvailability) { + this.loginAvailability = loginAvailability; } } diff --git a/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/default/ui/casInstitutionLoginAvailabilityFailedView.jsp b/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/default/ui/casInstitutionLoginAvailabilityFailedView.jsp index 3e8064c7..ec79a5e0 100644 --- a/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/default/ui/casInstitutionLoginAvailabilityFailedView.jsp +++ b/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/default/ui/casInstitutionLoginAvailabilityFailedView.jsp @@ -16,26 +16,9 @@ --%> -<%-- Login availability failed page --%> +<%-- Login availability failed redirect page --%> - - -
-

-

-
- - - - - - - - - - +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> + +