From 276d81974900da11be55e9399f96b4d8836b6e30 Mon Sep 17 00:00:00 2001 From: Huan Phan Date: Tue, 28 May 2024 21:06:11 +0700 Subject: [PATCH 1/2] =?UTF-8?q?refs=202.1.1.=E8=AA=8D=E8=A8=BC=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E3=81=AB=E3=82=88=E3=82=8B=E3=83=AD=E3=82=B0=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=82=A2=E3=82=AF=E3=82=BB=E3=82=B9=E5=88=B6=E5=BE=A1?= =?UTF-8?q?:=20Add=20source=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...teUserNonInteractiveCredentialsAction.java | 116 ++++++++++++------ ...rNonInteractiveCredentialsActionTests.java | 7 +- ...rmalizeRemotePrincipalWithEntitlement.java | 24 ++-- .../WEB-INF/webflow/login/login-webflow.xml | 2 +- 4 files changed, 98 insertions(+), 51 deletions(-) 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..09c72999 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 @@ -581,37 +581,74 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated( } // Call Login Availability API - 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 sn = user.optString("sn").trim(); + final String o = user.optString("o").trim(); + final String ou = user.optString("ou").trim(); + final String displayName = user.optString("displayName").trim(); + final String eduPersonAffiliation = user.optString("eduPersonAffiliation").trim(); + final String eduPersonPrincipalName = user.optString("eduPersonPrincipalName").trim(); + final String eduPersonEntitlement = user.optString("eduPersonEntitlement").trim(); + 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(); + + // send post method to RDM API + final JSONObject bodyObj = new JSONObject(); + bodyObj.put("institution_id", institutionId); + bodyObj.put("mail", username); + bodyObj.put("sn", sn); + 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", eduPersonPrincipalName); + bodyObj.put("eduPersonEntitlement", getStringList(eduPersonEntitlement)); + 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)); + + 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"); + normalizedPayload.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 +689,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 +738,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/webflow/login/login-webflow.xml b/cas-server-webapp/src/main/webapp/WEB-INF/webflow/login/login-webflow.xml index 11c45267..8c259dfd 100644 --- a/cas-server-webapp/src/main/webapp/WEB-INF/webflow/login/login-webflow.xml +++ b/cas-server-webapp/src/main/webapp/WEB-INF/webflow/login/login-webflow.xml @@ -317,7 +317,7 @@ - + From 98afbb907214a85323b2b2881f41baca747d977c Mon Sep 17 00:00:00 2001 From: Huan Phan Date: Mon, 10 Jun 2024 18:56:11 +0700 Subject: [PATCH 2/2] =?UTF-8?q?refs=202.1.1.=E8=AA=8D=E8=A8=BC=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E3=81=AB=E3=82=88=E3=82=8B=E3=83=AD=E3=82=B0=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=82=A2=E3=82=AF=E3=82=BB=E3=82=B9=E5=88=B6=E5=BE=A1?= =?UTF-8?q?:=20Fix=20IT=20bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...teUserNonInteractiveCredentialsAction.java | 20 +++++++------- ...InstitutionLoginAvailabilityFailedView.jsp | 27 ++++--------------- .../WEB-INF/webflow/login/login-webflow.xml | 2 +- 3 files changed, 15 insertions(+), 34 deletions(-) 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 09c72999..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,14 +580,11 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated( throw new InstitutionLoginFailedAttributesMissingException("Missing user's names"); } - // Call Login Availability API - final String sn = user.optString("sn").trim(); + final String email = user.optString("email").trim(); final String o = user.optString("o").trim(); final String ou = user.optString("ou").trim(); - final String displayName = user.optString("displayName").trim(); final String eduPersonAffiliation = user.optString("eduPersonAffiliation").trim(); - final String eduPersonPrincipalName = user.optString("eduPersonPrincipalName").trim(); - final String eduPersonEntitlement = user.optString("eduPersonEntitlement").trim(); + final String entitlement = user.optString("entitlement").trim(); final String eduPersonScopedAffiliation = user.optString("eduPersonScopedAffiliation").trim(); final String eduPersonTargetedID = user.optString("eduPersonTargetedID").trim(); final String eduPersonAssurance = user.optString("eduPersonAssurance").trim(); @@ -601,18 +598,18 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated( final String jaou = user.optString("jaou").trim(); final String gakuninScopedPersonalUniqueCode = user.optString("gakuninScopedPersonalUniqueCode").trim(); - // send post method to RDM API + // Call Login Availability API final JSONObject bodyObj = new JSONObject(); bodyObj.put("institution_id", institutionId); - bodyObj.put("mail", username); - bodyObj.put("sn", sn); + 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", eduPersonPrincipalName); - bodyObj.put("eduPersonEntitlement", getStringList(eduPersonEntitlement)); + bodyObj.put("eduPersonPrincipalName", username); + bodyObj.put("eduPersonEntitlement", getStringList(entitlement)); bodyObj.put("eduPersonScopedAffiliation", getStringList(eduPersonScopedAffiliation)); bodyObj.put("eduPersonTargetedID", getStringList(eduPersonTargetedID)); bodyObj.put("eduPersonAssurance", getStringList(eduPersonAssurance)); @@ -626,6 +623,7 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated( bodyObj.put("jaou", jaou); bodyObj.put("gakuninScopedPersonalUniqueCode", getStringList(gakuninScopedPersonalUniqueCode)); + // send post method to RDM API HttpResponse httpResponse; try { httpResponse = callLoginAvailabilityAPI(bodyObj); @@ -642,7 +640,7 @@ protected PrincipalAuthenticationResult notifyRemotePrincipalAuthenticated( } final JSONObject json = new JSONObject(builder.toString()); final String loginAvailability = (String) json.get("login_availability"); - normalizedPayload.put("login_availability", loginAvailability); + user.put("login_availability", loginAvailability); } catch (final IOException e) { logger.error( "[OSF API] Notify Remote Principal Authenticated Failed: Communication Error - {}", 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" %> + + diff --git a/cas-server-webapp/src/main/webapp/WEB-INF/webflow/login/login-webflow.xml b/cas-server-webapp/src/main/webapp/WEB-INF/webflow/login/login-webflow.xml index 8c259dfd..11c45267 100644 --- a/cas-server-webapp/src/main/webapp/WEB-INF/webflow/login/login-webflow.xml +++ b/cas-server-webapp/src/main/webapp/WEB-INF/webflow/login/login-webflow.xml @@ -317,7 +317,7 @@ - +