diff --git a/cas-server-support-osf/src/main/java/io/cos/cas/adaptors/postgres/handlers/OpenScienceFrameworkAuthenticationHandler.java b/cas-server-support-osf/src/main/java/io/cos/cas/adaptors/postgres/handlers/OpenScienceFrameworkAuthenticationHandler.java
index 8acd7c0a..90b5c8f1 100644
--- a/cas-server-support-osf/src/main/java/io/cos/cas/adaptors/postgres/handlers/OpenScienceFrameworkAuthenticationHandler.java
+++ b/cas-server-support-osf/src/main/java/io/cos/cas/adaptors/postgres/handlers/OpenScienceFrameworkAuthenticationHandler.java
@@ -28,6 +28,7 @@
import io.cos.cas.authentication.OneTimePasswordRequiredException;
import io.cos.cas.authentication.OpenScienceFrameworkCredential;
import io.cos.cas.authentication.ShouldNotHappenException;
+import io.cos.cas.authentication.exceptions.AccountNotConfirmedIdPLoginException;
import io.cos.cas.authentication.oath.TotpUtils;
import org.jasig.cas.authentication.AccountDisabledException;
@@ -187,9 +188,11 @@ protected final HandlerResult authenticateInternal(final OpenScienceFrameworkCre
}
// Check user's status, and only ACTIVE user can sign in
- if (USER_NOT_CONFIRMED_OSF.equals(userStatus) || USER_NOT_CONFIRMED_IDP.equals(userStatus)) {
+ if (USER_NOT_CONFIRMED_OSF.equals(userStatus)) {
throw new LoginNotAllowedException(username + " is registered but not confirmed");
- } else if (USER_DISABLED.equals(userStatus)) {
+ } else if (USER_NOT_CONFIRMED_IDP.equals(userStatus)) {
+ throw new AccountNotConfirmedIdPLoginException(username + " is registered via external IdP but not confirmed ");
+ } else if (USER_DISABLED.equals(userStatus)) {
throw new AccountDisabledException(username + " is disabled");
} else if (USER_NOT_CLAIMED.equals(userStatus)) {
throw new ShouldNotHappenException(username + " is not claimed");
diff --git a/cas-server-support-osf/src/main/java/io/cos/cas/authentication/exceptions/AccountNotConfirmedIdPLoginException.java b/cas-server-support-osf/src/main/java/io/cos/cas/authentication/exceptions/AccountNotConfirmedIdPLoginException.java
new file mode 100644
index 00000000..94c9ec02
--- /dev/null
+++ b/cas-server-support-osf/src/main/java/io/cos/cas/authentication/exceptions/AccountNotConfirmedIdPLoginException.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2020. Center for Open Science
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.cos.cas.authentication.exceptions;
+
+import javax.security.auth.login.AccountException;
+
+/**
+ * Describes an error condition where authentication occurs from an unconfirmed account created by external identity
+ * provider (IdP) login. This exception only applies to IdPs that require user email confirmation. Currently, there
+ * is only one: ORCiD. Institution IdPs do not require user email confirmation.
+ *
+ * @author Longze Chen
+ * @since 20.0.0
+ */
+public class AccountNotConfirmedIdPLoginException extends AccountException {
+
+ private static final long serialVersionUID = 2165106893184566462L;
+
+ /** Instantiates a new exception (default). */
+ public AccountNotConfirmedIdPLoginException() {
+ super();
+ }
+
+ /**
+ * Instantiates a new exception with a given message.
+ *
+ * @param message the message
+ */
+ public AccountNotConfirmedIdPLoginException(final String message) {
+ super(message);
+ }
+}
diff --git a/cas-server-support-osf/src/main/java/io/cos/cas/web/flow/OpenScienceFrameworkAuthenticationExceptionHandler.java b/cas-server-support-osf/src/main/java/io/cos/cas/web/flow/OpenScienceFrameworkAuthenticationExceptionHandler.java
index 6111cd62..e89494b1 100644
--- a/cas-server-support-osf/src/main/java/io/cos/cas/web/flow/OpenScienceFrameworkAuthenticationExceptionHandler.java
+++ b/cas-server-support-osf/src/main/java/io/cos/cas/web/flow/OpenScienceFrameworkAuthenticationExceptionHandler.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Set;
+import io.cos.cas.authentication.exceptions.AccountNotConfirmedIdPLoginException;
import io.cos.cas.authentication.exceptions.CasClientLoginException;
import io.cos.cas.authentication.exceptions.DelegatedLoginException;
import io.cos.cas.authentication.exceptions.OrcidClientLoginException;
@@ -81,6 +82,7 @@ public class OpenScienceFrameworkAuthenticationExceptionHandler extends Authenti
static {
DEFAULT_ERROR_LIST.add(InvalidVerificationKeyException.class);
DEFAULT_ERROR_LIST.add(LoginNotAllowedException.class);
+ DEFAULT_ERROR_LIST.add(AccountNotConfirmedIdPLoginException.class);
DEFAULT_ERROR_LIST.add(ShouldNotHappenException.class);
DEFAULT_ERROR_LIST.add(RemoteUserFailedLoginException.class);
DEFAULT_ERROR_LIST.add(OneTimePasswordFailedLoginException.class);
diff --git a/cas-server-webapp/src/main/resources/messages.properties b/cas-server-webapp/src/main/resources/messages.properties
index 0fdc43e8..5496732f 100644
--- a/cas-server-webapp/src/main/resources/messages.properties
+++ b/cas-server-webapp/src/main/resources/messages.properties
@@ -146,6 +146,8 @@ screen.badworkstation.message=Please contact OSF Support.
screen.loginnotallowed.button.resendConfirmation=Resend confirmation email
screen.accountdisabled.heading=Account disabled
screen.accountdisabled.message=The OSF account associated with the email has been disabled. Please contact OSF Support to regain access.
diff --git a/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/default/ui/casAccountNotConfirmedIdPLoginView.jsp b/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/default/ui/casAccountNotConfirmedIdPLoginView.jsp
new file mode 100644
index 00000000..37d9237d
--- /dev/null
+++ b/cas-server-webapp/src/main/webapp/WEB-INF/view/jsp/default/ui/casAccountNotConfirmedIdPLoginView.jsp
@@ -0,0 +1,41 @@
+<%--
+
+ Copyright (c) 2020. Center for Open Science
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+--%>
+
+<%-- Login exception page: account created via external IdP login but not confirmed --%>
+
+