NIHVIVO-2696 External user gets an account on first login.
This commit is contained in:
parent
cedd095a07
commit
4282da5ef2
7 changed files with 94 additions and 80 deletions
|
@ -9,6 +9,8 @@ import java.util.Map;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
||||
|
@ -22,13 +24,14 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Tem
|
|||
* Handle the first-time login of an Externally Authenticated user who has no
|
||||
* UserAccount - let's create one!
|
||||
*
|
||||
* If they get here from the login, there should an externalAuthId waiting in
|
||||
* the session. Otherwise, they should get here by submitting the form, which
|
||||
* will have the externalAuthId as a hidden field.
|
||||
* If they get here from the login, there should be an ExternalLoginInfo waiting
|
||||
* in the session. Otherwise, they should get here by submitting the form, which
|
||||
* will have the info in hidden fields.
|
||||
*/
|
||||
public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
||||
private static final String PARAMETER_SUBMIT = "submit";
|
||||
private static final String PARAMETER_EXTERNAL_AUTH_ID = "externalAuthId";
|
||||
private static final String PARAMETER_AFTER_LOGIN_URL = "afterLoginUrl";
|
||||
private static final String PARAMETER_EMAIL_ADDRESS = "emailAddress";
|
||||
private static final String PARAMETER_FIRST_NAME = "firstName";
|
||||
private static final String PARAMETER_LAST_NAME = "lastName";
|
||||
|
@ -41,23 +44,25 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
|
||||
private static final String TEMPLATE_NAME = "userAccounts-firstTimeExternal.ftl";
|
||||
|
||||
private static final String ATTRIBUTE_EXTERNAL_AUTH_ID = UserAccountsFirstTimeExternalPage.class
|
||||
private static final String ATTRIBUTE_EXTERNAL_LOGIN_INFO = UserAccountsFirstTimeExternalPage.class
|
||||
.getName();
|
||||
|
||||
/**
|
||||
* Let some other request set the External Auth ID before redirecting to
|
||||
* here.
|
||||
* Let some other request set the External Auth ID and the afterLogin URL
|
||||
* before redirecting to here.
|
||||
*/
|
||||
public static void setExternalAuthId(HttpServletRequest req,
|
||||
String externalAuthId) {
|
||||
req.getSession().setAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID,
|
||||
externalAuthId);
|
||||
public static void setExternalLoginInfo(HttpServletRequest req,
|
||||
String externalAuthId, String afterLoginUrl) {
|
||||
req.getSession().setAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO,
|
||||
new ExternalLoginInfo(externalAuthId, afterLoginUrl));
|
||||
}
|
||||
|
||||
private final UserAccountsFirstTimeExternalPageStrategy strategy;
|
||||
|
||||
private boolean submit = false;
|
||||
private String externalAuthId = "";
|
||||
private String afterLoginUrl = "";
|
||||
|
||||
private boolean submit = false;
|
||||
private String emailAddress = "";
|
||||
private String firstName = "";
|
||||
private String lastName = "";
|
||||
|
@ -71,7 +76,7 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
this.strategy = UserAccountsFirstTimeExternalPageStrategy.getInstance(
|
||||
vreq, this, isEmailEnabled());
|
||||
|
||||
checkSessionForExternalAuthId();
|
||||
checkSessionForExternalLoginInfo();
|
||||
if (externalAuthId.isEmpty()) {
|
||||
parseRequestParameters();
|
||||
}
|
||||
|
@ -83,20 +88,26 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkSessionForExternalAuthId() {
|
||||
private void checkSessionForExternalLoginInfo() {
|
||||
HttpSession session = vreq.getSession();
|
||||
|
||||
Object o = session.getAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID);
|
||||
session.removeAttribute(ATTRIBUTE_EXTERNAL_AUTH_ID);
|
||||
Object o = session.getAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO);
|
||||
session.removeAttribute(ATTRIBUTE_EXTERNAL_LOGIN_INFO);
|
||||
|
||||
if (o instanceof String) {
|
||||
externalAuthId = (String) o;
|
||||
if (o instanceof ExternalLoginInfo) {
|
||||
externalAuthId = ((ExternalLoginInfo) o).externalAuthId;
|
||||
afterLoginUrl = ((ExternalLoginInfo) o).afterLoginUrl;
|
||||
if (afterLoginUrl == null) {
|
||||
afterLoginUrl = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRequestParameters() {
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
externalAuthId = getStringParameter(PARAMETER_EXTERNAL_AUTH_ID, "");
|
||||
afterLoginUrl = getStringParameter(PARAMETER_AFTER_LOGIN_URL, "");
|
||||
|
||||
submit = isFlagOnRequest(PARAMETER_SUBMIT);
|
||||
emailAddress = getStringParameter(PARAMETER_EMAIL_ADDRESS, "");
|
||||
firstName = getStringParameter(PARAMETER_FIRST_NAME, "");
|
||||
lastName = getStringParameter(PARAMETER_LAST_NAME, "");
|
||||
|
@ -156,10 +167,12 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
public final ResponseValues showPage() {
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
body.put("externalAuthId", externalAuthId);
|
||||
body.put("afterLoginUrl", afterLoginUrl);
|
||||
|
||||
body.put("emailAddress", emailAddress);
|
||||
body.put("firstName", firstName);
|
||||
body.put("lastName", lastName);
|
||||
body.put("externalAuthId", externalAuthId);
|
||||
body.put("formUrls", buildUrlsMap());
|
||||
|
||||
if (!errorCode.isEmpty()) {
|
||||
|
@ -191,4 +204,25 @@ public class UserAccountsFirstTimeExternalPage extends UserAccountsPage {
|
|||
return u;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the afterLoginUrl is missing, go to the home page. If it is relative,
|
||||
* make sure it doesn't start with the cotext path.
|
||||
*/
|
||||
public String getAfterLoginUrl() {
|
||||
if (StringUtils.isEmpty(afterLoginUrl)) {
|
||||
return null;
|
||||
}
|
||||
return afterLoginUrl;
|
||||
}
|
||||
|
||||
private static class ExternalLoginInfo {
|
||||
final String externalAuthId;
|
||||
final String afterLoginUrl;
|
||||
|
||||
public ExternalLoginInfo(String externalAuthId, String afterLoginUrl) {
|
||||
this.externalAuthId = externalAuthId;
|
||||
this.afterLoginUrl = afterLoginUrl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.user;
|
|||
|
||||
import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.EXTERNAL;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
|
||||
|
@ -115,9 +115,7 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
UserAccount userAccount = page.createAccount();
|
||||
Authenticator auth = Authenticator.getInstance(vreq);
|
||||
auth.recordLoginAgainstUserAccount(userAccount, EXTERNAL);
|
||||
LoginProcessBean.removeBean(vreq);
|
||||
|
||||
return showLoginRedirection(vreq);
|
||||
return showLoginRedirection(vreq, page.getAfterLoginUrl());
|
||||
} else {
|
||||
return page.showPage();
|
||||
}
|
||||
|
@ -132,10 +130,31 @@ public class UserAccountsUserController extends FreemarkerHttpServlet {
|
|||
return new RedirectResponseValues("/");
|
||||
}
|
||||
|
||||
private ResponseValues showLoginRedirection(VitroRequest vreq) {
|
||||
LoginRedirector lr = new LoginRedirector(vreq, null);
|
||||
private ResponseValues showLoginRedirection(VitroRequest vreq,
|
||||
String afterLoginUrl) {
|
||||
LoginRedirector lr = new LoginRedirector(vreq, afterLoginUrl);
|
||||
DisplayMessage.setMessage(vreq, lr.assembleWelcomeMessage());
|
||||
String uri = lr.getRedirectionUriForLoggedInUser();
|
||||
return new RedirectResponseValues(uri);
|
||||
return new RedirectResponseValues(stripContextPath(vreq, uri));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO The LoginRedirector gives a URI that includes the context path. But
|
||||
* the RedirectResponseValues wants a URI that does not include the context
|
||||
* path.
|
||||
*
|
||||
* Bridge the gap.
|
||||
*/
|
||||
private String stripContextPath(VitroRequest vreq, String uri) {
|
||||
if ((uri == null) || uri.isEmpty() || uri.equals(vreq.getContextPath())) {
|
||||
return "/";
|
||||
}
|
||||
if (uri.contains("://")) {
|
||||
return uri;
|
||||
}
|
||||
if (uri.startsWith(vreq.getContextPath() + '/')) {
|
||||
return uri.substring(vreq.getContextPath().length());
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,17 +105,6 @@ public abstract class Authenticator {
|
|||
public abstract void recordLoginAgainstUserAccount(UserAccount userAccount,
|
||||
AuthenticationSource authSource);
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Record that the user has logged in but with only external authentication
|
||||
* info, so no internal user account.
|
||||
* - this involves everything except updating the user record.
|
||||
* </pre>
|
||||
*
|
||||
* TODO JB This goes away.
|
||||
*/
|
||||
public abstract void recordLoginWithoutUserAccount(String individualUri);
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Record that the current user has logged out: - notify other users of the
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -123,24 +122,12 @@ public class BasicAuthenticator extends Authenticator {
|
|||
}
|
||||
|
||||
recordLoginOnUserRecord(userAccount);
|
||||
recordLoginWithOrWithoutUserAccount(userAccount.getUri(), authSource);
|
||||
}
|
||||
|
||||
// TODO JB This goes away.
|
||||
@Override
|
||||
public void recordLoginWithoutUserAccount(String individualUri) {
|
||||
recordLoginWithOrWithoutUserAccount(individualUri,
|
||||
AuthenticationSource.EXTERNAL);
|
||||
}
|
||||
|
||||
/** This much is in common on login, whether or not you have a user account. */
|
||||
private void recordLoginWithOrWithoutUserAccount(String userUri,
|
||||
AuthenticationSource authSource) {
|
||||
HttpSession session = request.getSession();
|
||||
createLoginStatusBean(userUri, authSource, session);
|
||||
createLoginStatusBean(userAccount.getUri(), authSource, session);
|
||||
setSessionTimeoutLimit(session);
|
||||
recordInUserSessionMap(userUri, session);
|
||||
notifyOtherUsers(userUri, session);
|
||||
recordInUserSessionMap(userAccount.getUri(), session);
|
||||
notifyOtherUsers(userAccount.getUri(), session);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
|||
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginExternalAuthSetup.ATTRIBUTE_REFERRER;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -16,6 +15,8 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.accounts.user.UserAccountsFirstTimeExternalPage;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
|
||||
|
||||
/**
|
||||
|
@ -57,37 +58,26 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
|
|||
MESSAGE_LOGIN_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String afterLoginUrl = LoginProcessBean.getBean(req).getAfterLoginUrl();
|
||||
removeLoginProcessArtifacts(req);
|
||||
|
||||
UserAccount userAccount = getAuthenticator(req)
|
||||
.getAccountForExternalAuth(externalAuthId);
|
||||
if (userAccount != null) {
|
||||
if (userAccount == null) {
|
||||
log.debug("Creating new account for " + externalAuthId
|
||||
+ ", return to '" + afterLoginUrl + "'");
|
||||
UserAccountsFirstTimeExternalPage.setExternalLoginInfo(req,
|
||||
externalAuthId, afterLoginUrl);
|
||||
resp.sendRedirect(UrlBuilder.getUrl("/accounts/firstTimeExternal"));
|
||||
return;
|
||||
} else {
|
||||
log.debug("Logging in as " + userAccount.getUri());
|
||||
getAuthenticator(req).recordLoginAgainstUserAccount(userAccount,
|
||||
AuthenticationSource.EXTERNAL);
|
||||
new LoginRedirector(req, afterLoginUrl).redirectLoggedInUser(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> associatedUris = getAuthenticator(req)
|
||||
.getAssociatedIndividualUris(userAccount);
|
||||
// TODO JB - this case should lead to creating a new account.
|
||||
if (!associatedUris.isEmpty()) {
|
||||
log.debug("Recognize '" + externalAuthId + "' as self-editor for "
|
||||
+ associatedUris);
|
||||
String uri = associatedUris.get(0);
|
||||
|
||||
getAuthenticator(req).recordLoginWithoutUserAccount(uri);
|
||||
new LoginRedirector(req, afterLoginUrl).redirectLoggedInUser(resp);
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("User is not recognized: " + externalAuthId);
|
||||
removeLoginProcessArtifacts(req);
|
||||
new LoginRedirector(req, afterLoginUrl).redirectUnrecognizedExternalUser(resp,
|
||||
externalAuthId);
|
||||
}
|
||||
|
||||
private void removeLoginProcessArtifacts(HttpServletRequest req) {
|
||||
|
|
|
@ -182,10 +182,4 @@ public class AuthenticatorStub extends Authenticator {
|
|||
"AuthenticatorStub.accountRequiresEditing() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordLoginWithoutUserAccount(String individualUri) {
|
||||
throw new RuntimeException(
|
||||
"AuthenticatorStub.recordLoginWithoutUserAccount() not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
<form method="POST" action="${formUrls.firstTimeExternal}" class="customForm" role="my account">
|
||||
<input type="hidden" name="externalAuthId" value="${externalAuthId}" />
|
||||
<input type="hidden" name="afterLoginUrl" value="${afterLoginUrl}" />
|
||||
|
||||
<label for="first-name">First name<span class="requiredHint"> *</span></label>
|
||||
<input type="text" name="firstName" value="${firstName}" id="first-name" role="input "/>
|
||||
|
|
Loading…
Add table
Reference in a new issue