/*******************************************************************************
* Copyright (c) 2010, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.internal.server.servlets.useradmin;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.orion.internal.server.servlets.Activator;
import org.eclipse.orion.internal.server.servlets.ServletResourceHandler;
import org.eclipse.orion.internal.server.servlets.workspace.WorkspaceResourceHandler;
import org.eclipse.orion.internal.server.servlets.workspace.authorization.AuthorizationService;
import org.eclipse.orion.server.core.LogHelper;
import org.eclipse.orion.server.core.OrionConfiguration;
import org.eclipse.orion.server.core.PreferenceHelper;
import org.eclipse.orion.server.core.ServerConstants;
import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.orion.server.core.UserEmailUtil;
import org.eclipse.orion.server.core.metastore.IMetaStore;
import org.eclipse.orion.server.core.metastore.ProjectInfo;
import org.eclipse.orion.server.core.metastore.UserInfo;
import org.eclipse.orion.server.core.metastore.WorkspaceInfo;
import org.eclipse.orion.server.core.users.UserConstants;
import org.eclipse.orion.server.servlets.OrionServlet;
import org.eclipse.osgi.util.NLS;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A user handler for Orion User API v 1.0.
*/
public class UserHandlerV1 extends ServletResourceHandler<String> {
/**
* The minimum length of a password.
*/
private static final int PASSWORD_MIN_LENGTH = 8;
/**
* The rows query parameter from the /users URL
*/
private static final String ROWS = "rows"; //$NON-NLS-1$
/**
* The start query parameter from the /users URL
*/
private static final String START = "start"; //$NON-NLS-1$
/**
* The maximum length of a username.
*/
private static final int USERNAME_MAX_LENGTH = 20;
/**
* The minimum length of a username.
*/
private static final int USERNAME_MIN_LENGTH = 3;
/**
* JSON representation key for the users list. The value's data type is a String.
*/
public static final String USERS = "Users"; //$NON-NLS-1$
/**
* JSON representation key for the number of users in the entire users list. The value's data type is a Integer.
*/
public static final String USERS_LENGTH = "UsersLength"; //$NON-NLS-1$
/**
* JSON representation key for the rows number in the users list. The value's data type is a Integer.
*/
public static final String USERS_ROWS = "UsersRows"; //$NON-NLS-1$
/**
* JSON representation key for the start number in the users list. The value's data type is an Integer.
*/
public static final String USERS_START = "UsersStart"; //$NON-NLS-1$
private ServletResourceHandler<IStatus> statusHandler;
UserHandlerV1(ServletResourceHandler<IStatus> statusHandler) {
this.statusHandler = statusHandler;
}
private JSONObject formJson(UserInfo userInfo, URI location, String contextPath) throws JSONException, CoreException {
JSONObject json = new JSONObject();
json.put(UserConstants.USER_NAME, userInfo.getUserName());
json.put(UserConstants.FULL_NAME, userInfo.getFullName());
json.put(UserConstants.LOCATION, contextPath + location.getPath());
String email = userInfo.getProperty(UserConstants.EMAIL);
json.put(UserConstants.EMAIL, email);
boolean emailConfirmed = (email != null && email.length() > 0) ? userInfo.getProperty(UserConstants.EMAIL_CONFIRMATION_ID) == null : false;
json.put(UserConstants.EMAIL_CONFIRMED, emailConfirmed);
json.put(UserConstants.HAS_PASSWORD, userInfo.getProperty(UserConstants.PASSWORD) == null ? false : true);
if (userInfo.getProperty(UserConstants.OAUTH) != null) {
json.put(UserConstants.OAUTH, userInfo.getProperty(UserConstants.OAUTH));
}
if (userInfo.getProperty(UserConstants.OPENID) != null) {
json.put(UserConstants.OPENID, userInfo.getProperty(UserConstants.OPENID));
}
json.put(UserConstants.LAST_LOGIN_TIMESTAMP, userInfo.getProperty(UserConstants.LAST_LOGIN_TIMESTAMP));
json.put(UserConstants.DISK_USAGE_TIMESTAMP, userInfo.getProperty(UserConstants.DISK_USAGE_TIMESTAMP));
json.put(UserConstants.DISK_USAGE, userInfo.getProperty(UserConstants.DISK_USAGE));
return json;
}
private List<String> getAllUsers() throws CoreException {
// For Bug 372270 - changing the admin getUsers() to return a sorted list.
List<String> users = OrionConfiguration.getMetaStore().readAllUsers();
Collections.sort(users, new Comparator<String>() {
@Override
public int compare(String userId1, String userId2) {
return userId1.compareTo(userId2);
}
});
return users;
}
private String getUniqueEmailConfirmationId() {
return System.currentTimeMillis() + "-" + Math.random();
}
@Override
public boolean handleRequest(HttpServletRequest request, HttpServletResponse response, String userPathInfo) throws ServletException {
// handle calls to /users
if (userPathInfo == null) {
try {
switch (getMethod(request)) {
case GET:
return handleUsersGet(request, response);
case POST:
JSONObject json = OrionServlet.readJSONRequest(request);
if (!json.has(UserConstants.RESET)) {
return handleUserCreate(request, response, json);
}
default:
return false;
}
} catch (JSONException e) {
return statusHandler.handleRequest(request, response,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Syntax error in request", e));
} catch (Exception e) {
throw new ServletException("Error handling users", e);
}
}
// handle calls to /users/[username]
String[] userPathInfoParts = userPathInfo.split("\\/", 2);
String username = userPathInfoParts[1];
try {
switch (getMethod(request)) {
case GET:
return handleUserGet(request, response, username);
case PUT:
return handleUserPut(request, response, username);
case DELETE:
return handleUserDelete(request, response, username);
case POST:
JSONObject json = OrionServlet.readJSONRequest(request);
if (json.has(UserConstants.RESET)) {
return handleUserReset(request, response, username, json);
}
default:
return false;
}
} catch (JSONException e) {
return statusHandler.handleRequest(request, response,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Syntax error in request", e));
} catch (Exception e) {
throw new ServletException(NLS.bind("Error handling user: {0}", username), e);
}
}
private boolean handleUserCreate(HttpServletRequest req, HttpServletResponse resp, JSONObject json)
throws ServletException, IOException, JSONException, CoreException {
String username = json.has(UserConstants.USER_NAME) ? json.getString(UserConstants.USER_NAME) : null;
String fullname = json.has(UserConstants.FULL_NAME) ? json.getString(UserConstants.FULL_NAME) : null;
String email = json.has(UserConstants.EMAIL) ? json.getString(UserConstants.EMAIL) : null;
String password = json.has(UserConstants.PASSWORD) ? json.getString(UserConstants.PASSWORD) : null;
String identifier = json.has("identifier") ? json.getString("identifier") : null;
boolean isEmailRequired = Boolean.TRUE.toString().equalsIgnoreCase(PreferenceHelper.getString(ServerConstants.CONFIG_AUTH_USER_CREATION_FORCE_EMAIL));
if (fullname == null) {
fullname = username;
}
String msg = validateLogin(username);
if (msg != null) {
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
}
String passwordMsg = validatePassword(password);
if (passwordMsg != null) {
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, passwordMsg, null));
}
if (isEmailRequired && (email == null || email.length() == 0)) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "User email is mandatory.", null));
}
UserInfo userInfo = null;
try {
userInfo = OrionConfiguration.getMetaStore().readUserByProperty(UserConstants.USER_NAME, username, false, false);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage(), e));
}
if (userInfo != null) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "User " + username + " already exists.", null));
}
if (email != null && email.length() > 0) {
if (!email.contains("@")) { //$NON-NLS-1$
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Invalid user email.", null));
}
userInfo = null;
try {
userInfo = OrionConfiguration.getMetaStore().readUserByProperty(UserConstants.EMAIL, email.toLowerCase(), false, false);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage(), e));
}
if (userInfo != null) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, NLS.bind("Email address already in use: {0}.", email), null));
}
}
userInfo = new UserInfo();
userInfo.setUserName(username);
userInfo.setFullName(fullname);
userInfo.setProperty(UserConstants.PASSWORD, password);
if (identifier != null) {
userInfo.setProperty(UserConstants.OAUTH, identifier);
}
if (email != null && email.length() > 0) {
userInfo.setProperty(UserConstants.EMAIL, email);
}
if (isEmailRequired) {
userInfo.setProperty(UserConstants.BLOCKED, "true");
userInfo.setProperty(UserConstants.EMAIL_CONFIRMATION_ID, getUniqueEmailConfirmationId());
}
try {
OrionConfiguration.getMetaStore().createUser(userInfo);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, NLS.bind("Error creating user: {0}", username), null));
}
Logger logger = LoggerFactory.getLogger("org.eclipse.orion.server.account"); //$NON-NLS-1$
if (logger.isInfoEnabled()) {
logger.info("Account created: " + username); //$NON-NLS-1$
}
try {
// give the user access to their own user profile
String location = UserConstants.LOCATION_USERS_SERVLET + '/' + userInfo.getUniqueId();
AuthorizationService.addUserRight(userInfo.getUniqueId(), location);
} catch (CoreException e) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "User rights could not be added.", e));
}
URI userLocation = URIUtil.append(ServletResourceHandler.getURI(req), userInfo.getUniqueId());
if (isEmailRequired) {
try {
UserEmailUtil.getUtil().sendEmailConfirmation(req, userInfo);
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_CREATED,
NLS.bind(
"Your account {0} has been successfully created. You have been sent an email address verification. Follow the instructions in this email to login to your account.",
username),
null));
} catch (URISyntaxException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST,
"Could not send confirmation email to " + userInfo.getProperty(UserConstants.EMAIL), null));
}
}
OrionServlet.writeJSONResponse(req, resp, formJson(userInfo, userLocation, req.getContextPath()));
if (email != null && email.length() > 0 && UserEmailUtil.getUtil().isEmailConfigured()) {
try {
UserEmailUtil.getUtil().sendEmailConfirmation(req, userInfo);
} catch (URISyntaxException e) {
LogHelper.log(e);
}
}
resp.setStatus(HttpServletResponse.SC_CREATED);
return true;
}
private boolean handleUserDelete(HttpServletRequest req, HttpServletResponse resp, String username) throws ServletException {
UserInfo userInfo = null;
try {
userInfo = OrionConfiguration.getMetaStore().readUserByProperty(UserConstants.USER_NAME, username, false, false);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Removing " + username + " failed.", e));
}
if (userInfo == null) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "User " + username + " could not be found.", null));
}
// Delete user from metadata store
try {
@SuppressWarnings("unused")
Activator r = Activator.getDefault();
final IMetaStore metastore = OrionConfiguration.getMetaStore();
if (userInfo.getWorkspaceIds().size() > 0) {
for (String workspaceId : userInfo.getWorkspaceIds()) {
WorkspaceInfo workspaceInfo = metastore.readWorkspace(workspaceId);
if (workspaceInfo.getProjectNames().size() > 0) {
for (String projectName : workspaceInfo.getProjectNames()) {
ProjectInfo projectInfo = metastore.readProject(workspaceId, projectName);
if (projectInfo != null) {
WorkspaceResourceHandler.removeProject(username, workspaceInfo, projectInfo);
}
}
}
}
}
metastore.deleteUser(username);
} catch (CoreException e) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Removing " + username + " failed.", e));
}
Logger logger = LoggerFactory.getLogger("org.eclipse.orion.server.account"); //$NON-NLS-1$
if (logger.isInfoEnabled()) {
logger.info("Account deleted: " + username); //$NON-NLS-1$
}
return true;
}
private boolean handleUserGet(HttpServletRequest req, HttpServletResponse resp, String username)
throws IOException, JSONException, ServletException, CoreException {
UserInfo userInfo = OrionConfiguration.getMetaStore().readUserByProperty(UserConstants.USER_NAME, username, false, false);
if (userInfo == null) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, "User not found " + username, null));
}
URI location = ServletResourceHandler.getURI(req);
OrionServlet.writeJSONResponse(req, resp, formJson(userInfo, location, req.getContextPath()));
return true;
}
private boolean handleUserPut(HttpServletRequest req, HttpServletResponse resp, String username)
throws ServletException, IOException, CoreException, JSONException {
JSONObject data = OrionServlet.readJSONRequest(req);
UserInfo userInfo = null;
try {
userInfo = OrionConfiguration.getMetaStore().readUserByProperty(UserConstants.USER_NAME, username, false, false);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage(), e));
}
if (userInfo == null) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "User " + username + " could not be found.", null));
}
String emailConfirmationid = userInfo.getProperty(UserConstants.EMAIL_CONFIRMATION_ID);
// users other than admin have to know the old password to set a new one
if (!isAdmin(req.getRemoteUser())) {
if (data.has(UserConstants.PASSWORD) && userInfo.getProperty(UserConstants.PASSWORD) != null && (!data.has(UserConstants.OLD_PASSWORD)
|| !userInfo.getProperty(UserConstants.PASSWORD).equals(data.getString(UserConstants.OLD_PASSWORD)))) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Invalid old password", null));
}
}
String newPassword = null;
if (data.has(UserConstants.PASSWORD)) {
newPassword = data.getString(UserConstants.PASSWORD);
}
String passwordMsg = validatePassword(newPassword);
if (data.has(UserConstants.OLD_PASSWORD) && passwordMsg != null) {
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, passwordMsg, null));
}
if (data.has(UserConstants.USER_NAME)) {
userInfo.setUserName(data.getString(UserConstants.USER_NAME));
}
if (data.has(UserConstants.FULL_NAME)) {
userInfo.setFullName(data.getString(UserConstants.FULL_NAME));
}
if (data.has(UserConstants.PASSWORD)) {
userInfo.setProperty(UserConstants.PASSWORD, data.getString(UserConstants.PASSWORD));
}
if (data.has(UserConstants.EMAIL)) {
userInfo.setProperty(UserConstants.EMAIL, data.getString(UserConstants.EMAIL));
}
if (data.has(UserConstants.OAUTH)) {
UserInfo existing = OrionConfiguration.getMetaStore().readUserByProperty(UserConstants.OAUTH, ".*\\Q" + data.getString(UserConstants.OAUTH) + "\\E.*", true, false);
if (existing != null) {
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_CONFLICT, "This account is already linked to another user", null));
}
userInfo.setProperty(UserConstants.OAUTH, data.getString(UserConstants.OAUTH));
}
if (data.has(UserConstants.OPENID)) {
userInfo.setProperty(UserConstants.OPENID, data.getString(UserConstants.OPENID));
}
try {
OrionConfiguration.getMetaStore().updateUser(userInfo);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage(), e));
}
if (userInfo.getProperty(UserConstants.EMAIL_CONFIRMATION_ID) != null
&& !userInfo.getProperty(UserConstants.EMAIL_CONFIRMATION_ID).equals(emailConfirmationid)) {
try {
UserEmailUtil.getUtil().sendEmailConfirmation(req, userInfo);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.INFO, HttpServletResponse.SC_OK,
"Confirmation email has been sent to " + userInfo.getProperty(UserConstants.EMAIL), null));
} catch (Exception e) {
LogHelper.log(new Status(IStatus.ERROR, Activator.PI_SERVER_SERVLETS,
"Error while sending email" + (e.getMessage() == null ? "" : ": " + e.getMessage())
+ ". See http://wiki.eclipse.org/Orion/Server_admin_guide#Email_configuration for email configuration guide."));
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST,
"Could not send confirmation email to " + userInfo.getProperty(UserConstants.EMAIL), null));
}
}
return true;
}
private boolean handleUserReset(HttpServletRequest req, HttpServletResponse resp, String username, JSONObject json) throws ServletException, JSONException {
String password = json.getString(UserConstants.PASSWORD);
if (username == null || username.length() == 0) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "User name not specified.", null));
}
UserInfo userInfo = null;
try {
userInfo = OrionConfiguration.getMetaStore().readUserByProperty(UserConstants.USER_NAME, username, false, false);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage(), e));
}
if (userInfo == null) {
return statusHandler.handleRequest(req, resp,
new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, "User " + username + " could not be found.", null));
}
String passwordMsg = validatePassword(password);
if (passwordMsg != null) {
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, passwordMsg, null));
}
try {
userInfo.setProperty(UserConstants.PASSWORD, password);
OrionConfiguration.getMetaStore().updateUser(userInfo);
} catch (CoreException e) {
LogHelper.log(e);
return statusHandler.handleRequest(req, resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage(), e));
}
return true;
}
private boolean handleUsersGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, CoreException {
List<String> users = getAllUsers();
String startParam = req.getParameter(START);
String rowsParam = req.getParameter(ROWS);
int start = 0, rows = 0, count = 0;
if (startParam != null && !(startParam.length() == 0)) {
start = Integer.parseInt(startParam);
if (start < 0) {
start = 0;
}
} else {
start = 0;
}
if (rowsParam != null && !(rowsParam.length() == 0)) {
rows = Integer.parseInt(rowsParam);
if (rows < 0) {
rows = 20; // default is to return 20 at a time
}
} else {
// if there's no start and no rows then return the default first 20 users
rows = 20; // default is to return 20 at a time
}
ArrayList<JSONObject> userJSONs = new ArrayList<JSONObject>();
URI location = ServletResourceHandler.getURI(req);
for (String userId : users) {
if (count >= start + rows) {
break;
}
if (count++ < start) {
continue;
}
URI userLocation = URIUtil.append(location, userId);
UserInfo userInfo = OrionConfiguration.getMetaStore().readUser(userId);
userJSONs.add(formJson(userInfo, userLocation, req.getContextPath()));
}
JSONObject json = new JSONObject();
json.put(USERS, userJSONs);
json.put(USERS_START, start);
json.put(USERS_ROWS, rows);
json.put(USERS_LENGTH, users.size());
OrionServlet.writeJSONResponse(req, resp, json);
return true;
}
/**
* Returns true if this user is an administrator, and false otherwise
*/
private boolean isAdmin(String user) {
String creators = PreferenceHelper.getString(ServerConstants.CONFIG_AUTH_USER_CREATION, null);
if (creators != null) {
String[] admins = creators.split(",");
for (String admin : admins) {
if (admin.equals(user)) {
return true;
}
}
}
return false;
}
/**
* Validates that the provided login is valid. Login must consistent of alphanumeric characters only for now.
*
* @return <code>null</code> if the login is valid, and otherwise a string message stating the reason why it is not
* valid.
*/
private String validateLogin(String login) {
if (login == null || login.length() == 0) {
return "User login not specified";
}
String passwordVerificationDisabled = PreferenceHelper.getString(ServerConstants.CONFIG_AUTH_DISABLE_ACCOUNT_RULES, "false").toLowerCase(); //$NON-NLS-1$
if ("false".equals(passwordVerificationDisabled)) {
int length = login.length();
if (length < USERNAME_MIN_LENGTH) {
return NLS.bind("Username must contain at least {0} characters", USERNAME_MIN_LENGTH);
}
if (length > USERNAME_MAX_LENGTH) {
return NLS.bind("Username must contain no more than {0} characters", USERNAME_MAX_LENGTH);
}
}
for (int i = 0; i < login.length(); i++) {
if (!Character.isLetterOrDigit(login.charAt(i))) {
return NLS.bind("Username {0} contains invalid character ''{1}''", login, login.charAt(i));
}
}
return null;
}
/**
* Validates the provided password is valid. The password must be at least PASSWORD_MIN_LENGTH characters long and
* contain a mix of alpha and non alpha characters.
*
* @param password
* The provided password
* @return <code>null</code> if the password is valid, and otherwise a string message stating the reason why it is
* not valid.
*/
private String validatePassword(String password) {
if ((password == null || password.length() == 0)) {
return "Password not specified.";
}
String passwordVerificationDisabled = PreferenceHelper.getString(ServerConstants.CONFIG_AUTH_DISABLE_ACCOUNT_RULES, "false").toLowerCase(); //$NON-NLS-1$
if ("false".equals(passwordVerificationDisabled)) {
if (password.length() < PASSWORD_MIN_LENGTH) {
return NLS.bind("Password must be at least {0} characters long", PASSWORD_MIN_LENGTH);
}
if (Pattern.matches("[a-zA-Z]+", password) || Pattern.matches("[^a-zA-Z]+", password)) {
return "Password must contain at least one alpha character and one non alpha character";
}
}
return null;
}
}