NIHVIVO-1460 implement the ProgramLogin servlet.
This commit is contained in:
parent
192b722de3
commit
3b3111be82
3 changed files with 336 additions and 0 deletions
|
@ -1097,6 +1097,15 @@
|
|||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginExternalAuthReturn</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>programLogin</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>programLogin</servlet-name>
|
||||
<url-pattern>/programLogin</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>logout</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.edit.Logout</servlet-class>
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||
|
||||
import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.INTERNAL;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.User.MAX_PASSWORD_LENGTH;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.User.MIN_PASSWORD_LENGTH;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.User;
|
||||
|
||||
/**
|
||||
* Provide a means for programmatic login If they provide the right parameters,
|
||||
* log them in and send 200. Otherwise, send 403 error.
|
||||
*/
|
||||
public class ProgramLogin extends HttpServlet {
|
||||
public static final String PARAM_USERNAME = "username";
|
||||
public static final String PARAM_PASSWORD = "password";
|
||||
public static final String PARAM_NEW_PASSWORD = "newPassword";
|
||||
public static final int ERROR_CODE = 403;
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
Authenticator auth = Authenticator.getInstance(req);
|
||||
|
||||
String username = req.getParameter(PARAM_USERNAME);
|
||||
String password = req.getParameter(PARAM_PASSWORD);
|
||||
String newPassword = req.getParameter(PARAM_NEW_PASSWORD);
|
||||
|
||||
// username is required
|
||||
if ((username == null) || username.isEmpty()) {
|
||||
resp.sendError(ERROR_CODE, PARAM_USERNAME
|
||||
+ " parameter is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
// password is required
|
||||
if ((password == null) || password.isEmpty()) {
|
||||
resp.sendError(ERROR_CODE, PARAM_PASSWORD
|
||||
+ " parameter is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
// user must exist and password must be correct
|
||||
if (!auth.isExistingUser(username)
|
||||
|| (!auth.isCurrentPassword(username, password))) {
|
||||
resp.sendError(ERROR_CODE, PARAM_USERNAME + " or " + PARAM_PASSWORD
|
||||
+ " is incorrect.");
|
||||
return;
|
||||
}
|
||||
|
||||
User user = auth.getUserByUsername(username);
|
||||
boolean firstTime = (user.getLoginCount() == 0);
|
||||
|
||||
if (firstTime) {
|
||||
// on first-time login, new password is required
|
||||
if ((newPassword == null) || newPassword.isEmpty()) {
|
||||
resp.sendError(ERROR_CODE, "first-time login: "
|
||||
+ PARAM_NEW_PASSWORD + " parameter is required.");
|
||||
return;
|
||||
}
|
||||
|
||||
// on first-time login, new password must be correct length
|
||||
if ((newPassword.length() < MIN_PASSWORD_LENGTH)
|
||||
|| (newPassword.length() > MAX_PASSWORD_LENGTH)) {
|
||||
resp.sendError(ERROR_CODE, PARAM_PASSWORD + " must be between "
|
||||
+ MIN_PASSWORD_LENGTH + " and " + MAX_PASSWORD_LENGTH
|
||||
+ " characters.");
|
||||
return;
|
||||
}
|
||||
|
||||
// on first-time login, new password must be different from old
|
||||
if (auth.isCurrentPassword(username, newPassword)) {
|
||||
resp.sendError(ERROR_CODE, PARAM_NEW_PASSWORD
|
||||
+ " must not be the same as " + PARAM_PASSWORD);
|
||||
return;
|
||||
}
|
||||
|
||||
auth.recordNewPassword(username, newPassword);
|
||||
auth.recordLoginAgainstUserAccount(username, INTERNAL);
|
||||
sendSuccess(resp, "first-time login successful.");
|
||||
return;
|
||||
} else {
|
||||
// not first-time login, new password is not allowed
|
||||
if ((newPassword != null) && (!newPassword.isEmpty())) {
|
||||
resp.sendError(ERROR_CODE, "not first-time login: "
|
||||
+ PARAM_NEW_PASSWORD + " parameter is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
auth.recordLoginAgainstUserAccount(username, INTERNAL);
|
||||
sendSuccess(resp, "login successful.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendSuccess(HttpServletResponse resp, String message)
|
||||
throws IOException {
|
||||
PrintWriter writer = resp.getWriter();
|
||||
writer.println(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
doGet(req, resp);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin.PARAM_NEW_PASSWORD;
|
||||
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin.PARAM_PASSWORD;
|
||||
import static edu.cornell.mannlib.vitro.webapp.controller.authenticate.ProgramLogin.PARAM_USERNAME;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.log4j.Level;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import stubs.javax.servlet.ServletConfigStub;
|
||||
import stubs.javax.servlet.ServletContextStub;
|
||||
import stubs.javax.servlet.http.HttpServletRequestStub;
|
||||
import stubs.javax.servlet.http.HttpServletResponseStub;
|
||||
import stubs.javax.servlet.http.HttpSessionStub;
|
||||
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.User;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.edit.Authenticate;
|
||||
|
||||
/**
|
||||
* Test the basic features of ProgramTest.
|
||||
*/
|
||||
public class ProgramLoginTest extends AbstractTestClass {
|
||||
private static final Log log = LogFactory.getLog(ProgramLoginTest.class);
|
||||
|
||||
private static final String NEW_USER_URI = "new_user_uri";
|
||||
private static final String NEW_USER_NAME = "new_user";
|
||||
private static final String NEW_USER_PASSWORD = "new_user_pw";
|
||||
private static final User NEW_USER = createUser(NEW_USER_URI,
|
||||
NEW_USER_NAME, NEW_USER_PASSWORD, 0);
|
||||
|
||||
private static final String OLD_USER_URI = "old_user_uri";
|
||||
private static final String OLD_USER_NAME = "old_user";
|
||||
private static final String OLD_USER_PASSWORD = "old_user_pw";
|
||||
private static final User OLD_USER = createUser(OLD_USER_URI,
|
||||
OLD_USER_NAME, OLD_USER_PASSWORD, 10);
|
||||
|
||||
private AuthenticatorStub authenticator;
|
||||
private ServletContextStub servletContext;
|
||||
private ServletConfigStub servletConfig;
|
||||
private HttpSessionStub session;
|
||||
private HttpServletRequestStub request;
|
||||
private HttpServletResponseStub response;
|
||||
private ProgramLogin servlet;
|
||||
|
||||
@Before
|
||||
public void setLogging() {
|
||||
setLoggerLevel(this.getClass(), Level.DEBUG);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
authenticator = AuthenticatorStub.setup();
|
||||
authenticator.addUser(NEW_USER);
|
||||
authenticator.addUser(OLD_USER);
|
||||
|
||||
servletContext = new ServletContextStub();
|
||||
|
||||
servletConfig = new ServletConfigStub();
|
||||
servletConfig.setServletContext(servletContext);
|
||||
|
||||
servlet = new ProgramLogin();
|
||||
servlet.init(servletConfig);
|
||||
|
||||
session = new HttpSessionStub();
|
||||
session.setServletContext(servletContext);
|
||||
|
||||
request = new HttpServletRequestStub();
|
||||
request.setSession(session);
|
||||
request.setRequestUrl(new URL("http://this.that/vivo/programLogin"));
|
||||
request.setMethod("GET");
|
||||
|
||||
response = new HttpServletResponseStub();
|
||||
}
|
||||
|
||||
private static User createUser(String uri, String name, String password,
|
||||
int loginCount) {
|
||||
User user = new User();
|
||||
user.setUsername(name);
|
||||
user.setURI(uri);
|
||||
user.setRoleURI(String.valueOf(50));
|
||||
user.setMd5password(Authenticate.applyMd5Encoding(password));
|
||||
user.setLoginCount(loginCount);
|
||||
if (loginCount > 0) {
|
||||
user.setFirstTime(new Date(0));
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
if (servlet != null) {
|
||||
servlet.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noUsername() {
|
||||
executeRequest(null, null, null);
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noPassword() {
|
||||
executeRequest(OLD_USER_NAME, null, null);
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unrecognizedUser() {
|
||||
executeRequest("bogusUsername", "bogusPassword", null);
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongPassword() {
|
||||
executeRequest(OLD_USER_NAME, "bogusPassword", null);
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() {
|
||||
executeRequest(OLD_USER_NAME, OLD_USER_PASSWORD, null);
|
||||
assertSuccess();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newPasswordNotNeeded() {
|
||||
executeRequest(OLD_USER_NAME, OLD_USER_PASSWORD, "unneededPW");
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newPasswordMissing() {
|
||||
executeRequest(NEW_USER_NAME, NEW_USER_PASSWORD, null);
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newPasswordTooLong() {
|
||||
executeRequest(NEW_USER_NAME, NEW_USER_PASSWORD, "reallyLongPassword");
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newPasswordEqualsOldPassword() {
|
||||
executeRequest(NEW_USER_NAME, NEW_USER_PASSWORD, NEW_USER_PASSWORD);
|
||||
assert403();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successWithNewPassword() {
|
||||
executeRequest(NEW_USER_NAME, NEW_USER_PASSWORD, "newerBetter");
|
||||
assertSuccess();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private void executeRequest(String username, String password,
|
||||
String newPassword) {
|
||||
if (username != null) {
|
||||
request.addParameter(PARAM_USERNAME, username);
|
||||
}
|
||||
if (password != null) {
|
||||
request.addParameter(PARAM_PASSWORD, password);
|
||||
}
|
||||
if (newPassword != null) {
|
||||
request.addParameter(PARAM_NEW_PASSWORD, newPassword);
|
||||
}
|
||||
|
||||
try {
|
||||
servlet.doGet(request, response);
|
||||
} catch (ServletException e) {
|
||||
log.error(e, e);
|
||||
fail(e.toString());
|
||||
} catch (IOException e) {
|
||||
log.error(e, e);
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void assert403() {
|
||||
assertEquals("status", 403, response.getStatus());
|
||||
log.debug("Message was '" + response.getErrorMessage() + "'");
|
||||
assertEquals("logged in", false, LoginStatusBean.getBean(session)
|
||||
.isLoggedIn());
|
||||
}
|
||||
|
||||
private void assertSuccess() {
|
||||
assertEquals("status", 200, response.getStatus());
|
||||
assertEquals("logged in", true, LoginStatusBean.getBean(session)
|
||||
.isLoggedIn());
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue