diff --git a/src/main/java/io/cos/cas/osf/authentication/support/OsfInstitutionUtils.java b/src/main/java/io/cos/cas/osf/authentication/support/OsfInstitutionUtils.java index c749f363..0edc7547 100644 --- a/src/main/java/io/cos/cas/osf/authentication/support/OsfInstitutionUtils.java +++ b/src/main/java/io/cos/cas/osf/authentication/support/OsfInstitutionUtils.java @@ -24,18 +24,32 @@ public final class OsfInstitutionUtils { public final static String ORCID_SUFFIX = " (via ORCiD SSO)"; - public static boolean validateInstitutionForLogin(final JpaOsfDao jpaOsfDao, final String id) { - final OsfInstitution institution = jpaOsfDao.findOneInstitutionById(id); + /** + * @param institution the OSF institution to verify + * @return whether the given institution is eligible for institution SSO. + */ + public static boolean validateInstitutionForLogin(final OsfInstitution institution) { return institution != null && institution.getDelegationProtocol() != null && institution.getSsoAvailability() != SsoAvailability.UNAVAILABLE; } - public static String getInstitutionSupportEmail(final JpaOsfDao jpaOsfDao, final String id) { - final OsfInstitution institution = jpaOsfDao.findOneInstitutionById(id); + /** + * @param jpaOsfDao the data access object for OSF DB + * @param institutionId the institution ID + * @return the institution's support email if exists + */ + public static String getInstitutionSupportEmail(final JpaOsfDao jpaOsfDao, final String institutionId) { + final OsfInstitution institution = jpaOsfDao.findOneInstitutionById(institutionId); return institution != null ? institution.getSupportEmail() : null; } + /** + * @param jpaOsfDao the data access object for OSF DB + * @param target the target query param in shibboleth URL + * @param institutionId the institution ID used in shortcut SSO mode + * @return a map of institution name and login URL + */ public static Map getInstitutionLoginUrlMap( final JpaOsfDao jpaOsfDao, final String target, @@ -101,6 +115,12 @@ public static Map getInstitutionLoginUrlMap( return institutionLoginUrlMap; } + /** + * A helper method that sort a map by value instead of key. + * + * @param map the map to sort by value + * @return the sorted map + */ public static > Map sortByValue(final Map map) { final List> list = new LinkedList<>(map.entrySet()); Collections.sort(list, new Comparator>() { diff --git a/src/main/java/io/cos/cas/osf/web/flow/login/OsfAbstractLoginPreparationAction.java b/src/main/java/io/cos/cas/osf/web/flow/login/OsfAbstractLoginPreparationAction.java index 9751e49f..bc72df02 100644 --- a/src/main/java/io/cos/cas/osf/web/flow/login/OsfAbstractLoginPreparationAction.java +++ b/src/main/java/io/cos/cas/osf/web/flow/login/OsfAbstractLoginPreparationAction.java @@ -27,8 +27,6 @@ public abstract class OsfAbstractLoginPreparationAction extends AbstractAuthenti protected static final String PARAMETER_LOGIN_CONTEXT = "osfCasLoginContext"; - protected static final String PARAMETER_SERVICE = "service"; - protected static final String PARAMETER_CAMPAIGN = "campaign"; protected static final String PARAMETER_CAMPAIGN_VALUE = "institution"; diff --git a/src/main/java/io/cos/cas/osf/web/flow/login/OsfDefaultLoginPreparationAction.java b/src/main/java/io/cos/cas/osf/web/flow/login/OsfDefaultLoginPreparationAction.java index 280718a4..f5c608b8 100644 --- a/src/main/java/io/cos/cas/osf/web/flow/login/OsfDefaultLoginPreparationAction.java +++ b/src/main/java/io/cos/cas/osf/web/flow/login/OsfDefaultLoginPreparationAction.java @@ -70,6 +70,7 @@ protected Event doExecute(RequestContext context) { loginContext = new OsfCasLoginContext( institutionLogin, institutionId, + Boolean.FALSE, StringUtils.EMPTY, unsupportedInstitutionLogin, orcidRedirect, @@ -80,6 +81,7 @@ protected Event doExecute(RequestContext context) { } else { loginContext.setInstitutionLogin(institutionLogin); loginContext.setInstitutionId(institutionId); + loginContext.setHiddenSsoAvailability(false); loginContext.setInstitutionSupportEmail(StringUtils.EMPTY); loginContext.setUnsupportedInstitutionLogin(unsupportedInstitutionLogin); loginContext.setOrcidLoginUrl(orcidLoginUrl); diff --git a/src/main/java/io/cos/cas/osf/web/flow/login/OsfInstitutionLoginPreparationAction.java b/src/main/java/io/cos/cas/osf/web/flow/login/OsfInstitutionLoginPreparationAction.java index 142b1785..3624881f 100644 --- a/src/main/java/io/cos/cas/osf/web/flow/login/OsfInstitutionLoginPreparationAction.java +++ b/src/main/java/io/cos/cas/osf/web/flow/login/OsfInstitutionLoginPreparationAction.java @@ -2,6 +2,7 @@ import io.cos.cas.osf.authentication.support.OsfInstitutionUtils; import io.cos.cas.osf.dao.JpaOsfDao; +import io.cos.cas.osf.model.OsfInstitution; import io.cos.cas.osf.web.support.OsfCasLoginContext; import lombok.extern.slf4j.Slf4j; @@ -76,16 +77,20 @@ protected Event doExecute(RequestContext context) { -> (OsfCasLoginContext) requestContext.getFlowScope().get(PARAMETER_LOGIN_CONTEXT)).orElse(null); if (loginContext != null) { institutionId = loginContext.getInstitutionId(); - if (!OsfInstitutionUtils.validateInstitutionForLogin(jpaOsfDao, institutionId)) { + final OsfInstitution institution = jpaOsfDao.findOneInstitutionById(institutionId); + if (!OsfInstitutionUtils.validateInstitutionForLogin(institution)) { loginContext.setInstitutionId(null); - context.getFlowScope().put(PARAMETER_LOGIN_CONTEXT, loginContext); institutionId = null; } else { - final String institutionSupportEmail = OsfInstitutionUtils.getInstitutionSupportEmail(jpaOsfDao, institutionId); + final String institutionSupportEmail = institution.getSupportEmail(); if (institutionSupportEmail != null) { loginContext.setInstitutionSupportEmail(institutionSupportEmail); } + if (institution.getSsoAvailability().isHidden()) { + loginContext.setHiddenSsoAvailability(true); + } } + context.getFlowScope().put(PARAMETER_LOGIN_CONTEXT, loginContext); } final Map institutionLoginUrlMap diff --git a/src/main/java/io/cos/cas/osf/web/support/OsfCasLoginContext.java b/src/main/java/io/cos/cas/osf/web/support/OsfCasLoginContext.java index d0679497..525f762b 100644 --- a/src/main/java/io/cos/cas/osf/web/support/OsfCasLoginContext.java +++ b/src/main/java/io/cos/cas/osf/web/support/OsfCasLoginContext.java @@ -9,10 +9,8 @@ import java.io.Serializable; /** - * This is {@link OsfCasLoginContext}. - * - * Stores OSF-specific information about the current web flow. Extends {@link Serializable} so that it can be put into - * and retrieved from the flow context conveniently. + * This is {@link OsfCasLoginContext}. Stores OSF-specific information about the current web flow. + * Extends {@link Serializable} so that it can be put into and retrieved from the flow context conveniently. * * @author Longze Chen * @since 20.1.0 @@ -28,8 +26,17 @@ public class OsfCasLoginContext implements Serializable { private boolean institutionLogin; + /** + * A verified institution ID. Its being present allows web flow to handle shortcut SSO mode. + */ private String institutionId; + /** + * Indicates whether the institution with {@link this#institutionId} has hidden SSO availability, + * which allows web flow to handle such institutions properly in shortcut SSO mode. + */ + private boolean hiddenSsoAvailability; + private String institutionSupportEmail; private boolean unsupportedInstitutionLogin; @@ -42,7 +49,6 @@ public class OsfCasLoginContext implements Serializable { /** * The default service URL that uses OSF login endpoint with OSF home as destination. - * * e.g. http(s)://[OSF Domain]/login?next=[encoded version of http(s)://[OSF Domain]/] */ private String defaultServiceUrl; diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 25aa8bb5..d602ae13 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -611,6 +611,7 @@ screen.institutionlogin.message.auto=Your institution has partnered with OSF. Pl screen.institutionlogin.heading.select=Your institution screen.institutionlogin.heading.auto=Your institution screen.institutionlogin.link.select=Not your institution? +screen.institutionlogin.link.hidden=Note: Your institution is currently being set up and may not be available. Please check back at a later date. screen.institutionlogin.link.unsupported=I can't find my institution screen.institutionlogin.button.submit=Sign in screen.institutionlogin.osf=Sign in with email diff --git a/src/main/resources/templates/casInstitutionLoginView.html b/src/main/resources/templates/casInstitutionLoginView.html index bdf9f08e..f482072b 100644 --- a/src/main/resources/templates/casInstitutionLoginView.html +++ b/src/main/resources/templates/casInstitutionLoginView.html @@ -31,6 +31,10 @@

+
+

+
+