diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmHttpHeader.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmHttpHeader.java new file mode 100644 index 0000000000000000000000000000000000000000..93353d26634b8632bd77f20d55a6ed44cbeafcd1 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmHttpHeader.java @@ -0,0 +1,13 @@ +package gov.anl.aps.dm.common.constants; + +/** + * HTTP headers specific to DM. + */ +public class DmHttpHeader { + + public static final String DM_SET_COOKIE_HEADER = "Set-Cookie"; + public static final String DM_EXCEPTION_TYPE_HEADER = "Dm-Exception-Type"; + public static final String DM_STATUS_CODE_HEADER = "Dm-Status-Code"; + public static final String DM_STATUS_MESSAGE_HEADER = "Dm-Status-Message"; + public static final String DM_SESSION_ROLE_HEADER = "Dm-Session-Role"; +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmProperty.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmProperty.java new file mode 100644 index 0000000000000000000000000000000000000000..23940d842130a0e585ff6377220d662c8d31cccf --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmProperty.java @@ -0,0 +1,10 @@ +package gov.anl.aps.dm.common.constants; + +/** + * DM property names. + */ +public class DmProperty { + + public static final String WEB_SERVICE_URL_PROPERTY_NAME = "dm.webService.url"; + +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmRole.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmRole.java new file mode 100644 index 0000000000000000000000000000000000000000..d25537362e8daec54ffb7a5d550fab39cdaa9a1c --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmRole.java @@ -0,0 +1,34 @@ +package gov.anl.aps.dm.common.constants; + +/** + * DM role enum. + */ +public enum DmRole { + + USER("user"), + ADMIN("admin"); + + private final String type; + + private DmRole(String type) { + this.type = type; + } + + @Override + public String toString() { + return type; + } + + public static DmRole fromString(String type) { + DmRole role = null; + switch (type) { + case "user": + role = USER; + break; + case "admin": + role = ADMIN; + break; + } + return role; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmServiceProtocol.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmServiceProtocol.java new file mode 100644 index 0000000000000000000000000000000000000000..dc875e89776d8aac7ddcf0dfa727c05c35ed6aa1 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmServiceProtocol.java @@ -0,0 +1,34 @@ +package gov.anl.aps.dm.common.constants; + +/** + * DM service protocol enum. + */ +public enum DmServiceProtocol { + + HTTP("http"), + HTTPS("https"); + + private final String type; + + private DmServiceProtocol(String type) { + this.type = type; + } + + @Override + public String toString() { + return type; + } + + public static DmServiceProtocol fromString(String type) { + DmServiceProtocol protocol = null; + switch (type) { + case "http": + protocol = HTTP; + break; + case "https": + protocol = HTTPS; + break; + } + return protocol; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmStatus.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..548722c94ebc8f4f8e8ad46c48af6a7c875b71b8 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/constants/DmStatus.java @@ -0,0 +1,27 @@ +package gov.anl.aps.dm.common.constants; + +/** + * DM status codes. + */ +public class DmStatus { + + public static final int DM_OK = 0; + public static final int DM_ERROR = 1; + public static final int DM_INTERNAL_ERROR = 2; + public static final int DM_COMMUNICATION_ERROR = 3; + public static final int DM_CONFIGURATION_ERROR = 4; + public static final int DM_AUTHORIZATION_ERROR = 5; + public static final int DM_AUTHENTICATION_ERROR = 6; + public static final int DM_DB_ERROR = 7; + public static final int DM_URL_ERROR = 8; + public static final int DM_TIMEOUT_ERROR = 9; + public static final int DM_INVALID_ARGUMENT = 10; + public static final int DM_INVALID_REQUEST = 11; + public static final int DM_INVALID_SESSION = 12; + public static final int DM_COMMAND_FAILED = 13; + public static final int DM_OBJECT_ALREADY_EXISTS = 14; + public static final int DM_OBJECT_NOT_FOUND = 15; + public static final int DM_INVALID_OBJECT_STATE = 16; + public static final int DM_IMAGE_PROCESSING_FAILED = 17; + public static final int DM_EXTERNAL_SERVICE_ERROR = 18; +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/AuthenticationError.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/AuthenticationError.java new file mode 100644 index 0000000000000000000000000000000000000000..9361d06d69d74213751ae8ca3b4fe5d94fbc074c --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/AuthenticationError.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Authentication error exception. + */ +public class AuthenticationError extends DmException { + + /** + * Default constructor. + */ + public AuthenticationError() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public AuthenticationError(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public AuthenticationError(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public AuthenticationError(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_AUTHENTICATION_ERROR; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/AuthorizationError.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/AuthorizationError.java new file mode 100644 index 0000000000000000000000000000000000000000..6a6fbab808344816fb82b8ba46dfe5a62c578cfc --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/AuthorizationError.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Authorization error exception. + */ +public class AuthorizationError extends DmException { + + /** + * Default constructor. + */ + public AuthorizationError() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public AuthorizationError(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public AuthorizationError(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public AuthorizationError(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_AUTHORIZATION_ERROR; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/CommunicationError.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/CommunicationError.java new file mode 100644 index 0000000000000000000000000000000000000000..bd202cef54f0d691f9568b46007328415e5d7f6e --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/CommunicationError.java @@ -0,0 +1,50 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Communication error exception. + */ +public class CommunicationError extends DmException { + + /** + * Default constructor. + */ + public CommunicationError() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public CommunicationError(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public CommunicationError(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public CommunicationError(String message, Throwable throwable) { + super(message, throwable); + } + + + @Override + public int getErrorCode() { + return DmStatus.DM_COMMUNICATION_ERROR; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ConfigurationError.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ConfigurationError.java new file mode 100644 index 0000000000000000000000000000000000000000..acd8c938071e2e6c85e961638a7257c5cbd73523 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ConfigurationError.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Configuration error exception. + */ +public class ConfigurationError extends DmException { + + /** + * Default constructor. + */ + public ConfigurationError() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public ConfigurationError(String message) { + super(message); + } + + /** + * Constructor sing throwable object. + * + * @param throwable throwable object + */ + public ConfigurationError(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public ConfigurationError(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_CONFIGURATION_ERROR; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DbError.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DbError.java new file mode 100644 index 0000000000000000000000000000000000000000..a07885db9ea31e2c3ccb932db03385c3ab8202b5 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DbError.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * DB error exception. + */ +public class DbError extends DmException { + + /** + * Default constructor. + */ + public DbError() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public DbError(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public DbError(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public DbError(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_DB_ERROR; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DmException.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DmException.java new file mode 100644 index 0000000000000000000000000000000000000000..ae88da18e66f6e254caeee6a0ebc4ec2f7f95662 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DmException.java @@ -0,0 +1,84 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Generic DM exception, used as base class for all DM exceptions. + */ +public class DmException extends Exception { + + /** + * Exception keys. + */ + public static final String SIGNATURE_KEY = "__dm_exception__"; + public static final String TYPE_KEY = "type"; + public static final String CODE_KEY = "code"; + public static final String ARGS_KEY = "args"; + + private String error = null; + + /** + * Default constructor. + */ + public DmException() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public DmException(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public DmException(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public DmException(String message, Throwable throwable) { + super(message, throwable); + } + + public int getErrorCode() { + return DmStatus.DM_ERROR; + } + + public void setErrorMessage(String error) { + this.error = error; + } + + public String getErrorMessage() { + if (error != null) { + return error; + } + return super.getMessage(); + } + + /** + * Convert exception to string, overriding string output if error message is + * set. + * + * @return exception string + */ + @Override + public String toString() { + if (error != null) { + return error; + } else { + return super.toString(); + } + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DmExceptionFactory.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DmExceptionFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..637c291c7caf4c84e7432cc0dc163dbe9334f6ee --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/DmExceptionFactory.java @@ -0,0 +1,77 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; +import org.apache.log4j.Logger; + +/** + * DM exception factory class. + * + */ +public class DmExceptionFactory { + + private static final Logger logger + = Logger.getLogger(DmExceptionFactory.class.getName()); + + /** + * Generate DM exception. + * + * @param type exception type + * @param code exception code + * @param error exception error message + * @return generated DM exception + */ + public static DmException generateDmException(String type, int code, String error) { + DmException exc = new DmException(); + try { + String fullType = "gov.anl.aps.dm.common.exceptions." + type; + // Having trouble getting code below to work in all cases, so + // use code for now. + // exc = (DmException) Class.forName(fullType).newInstance(); + switch (code) { + + case DmStatus.DM_AUTHORIZATION_ERROR: + exc = new AuthorizationError(); + break; + case DmStatus.DM_COMMUNICATION_ERROR: + exc = new CommunicationError(); + break; + case DmStatus.DM_INTERNAL_ERROR: + exc = new InternalError(); + break; + case DmStatus.DM_INVALID_ARGUMENT: + exc = new InvalidArgument(); + break; + case DmStatus.DM_INVALID_SESSION: + exc = new InvalidSession(); + break; + case DmStatus.DM_OBJECT_ALREADY_EXISTS: + exc = new ObjectAlreadyExists(); + break; + case DmStatus.DM_OBJECT_NOT_FOUND: + exc = new ObjectNotFound(); + break; + default: + exc = (DmException) Class.forName(fullType).newInstance(); + } + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException ex) { + String err = "Cannot generate exception of type " + type + ": " + ex; + logger.error(err); + } + exc.setErrorMessage(error); + return exc; + } + + /** + * Throw DM exception. + * + * @param type exception type + * @param code exception code + * @param error exception error message + * @throws DmException generated DM exception whenever this method is + * called + */ + public static void throwDmException(String type, int code, String error) throws DmException { + DmException exc = generateDmException(type, code, error); + throw exc; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InternalError.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InternalError.java new file mode 100644 index 0000000000000000000000000000000000000000..955b18b66e098d910e250d47d39058147977aafa --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InternalError.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Internal error exception. + */ +public class InternalError extends DmException { + + /** + * Default constructor. + */ + public InternalError() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public InternalError(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public InternalError(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public InternalError(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_INTERNAL_ERROR; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidArgument.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidArgument.java new file mode 100644 index 0000000000000000000000000000000000000000..feb1990d9ebe43116afdecc7d764663ec42d92c1 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidArgument.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Invalid argument exception. + */ +public class InvalidArgument extends DmException { + + /** + * Default constructor. + */ + public InvalidArgument() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public InvalidArgument(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public InvalidArgument(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public InvalidArgument(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_INVALID_ARGUMENT; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidObjectState.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidObjectState.java new file mode 100644 index 0000000000000000000000000000000000000000..97700d6847b77a031f525bf00fec8827f7526ed3 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidObjectState.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Invalid object state exception. + */ +public class InvalidObjectState extends DmException { + + /** + * Default constructor. + */ + public InvalidObjectState() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public InvalidObjectState(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public InvalidObjectState(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public InvalidObjectState(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_INVALID_OBJECT_STATE; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidRequest.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..fccb3c6eee1d363a1a7053553de78ad88a4d8ec8 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidRequest.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Invalid request exception. + */ +public class InvalidRequest extends DmException { + + /** + * Default constructor. + */ + public InvalidRequest() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public InvalidRequest(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public InvalidRequest(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public InvalidRequest(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_INVALID_REQUEST; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidSession.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidSession.java new file mode 100644 index 0000000000000000000000000000000000000000..569fe7897cadf90f840172b6449092331c0fc2f8 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/InvalidSession.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Invalid session exception. + */ +public class InvalidSession extends DmException { + + /** + * Default constructor. + */ + public InvalidSession() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public InvalidSession(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public InvalidSession(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public InvalidSession(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_INVALID_SESSION; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ObjectAlreadyExists.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ObjectAlreadyExists.java new file mode 100644 index 0000000000000000000000000000000000000000..6e5edf45d512d127f92b72d168abe6e158ef2c71 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ObjectAlreadyExists.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Object already exists exception. + */ +public class ObjectAlreadyExists extends DmException { + + /** + * Default constructor. + */ + public ObjectAlreadyExists() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public ObjectAlreadyExists(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public ObjectAlreadyExists(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public ObjectAlreadyExists(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_OBJECT_ALREADY_EXISTS; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ObjectNotFound.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ObjectNotFound.java new file mode 100644 index 0000000000000000000000000000000000000000..1ad72872968912155f5d70a3085b9c1862149ffe --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/ObjectNotFound.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Object not found exception. + */ +public class ObjectNotFound extends DmException { + + /** + * Default constructor. + */ + public ObjectNotFound() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public ObjectNotFound(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public ObjectNotFound(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public ObjectNotFound(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_OBJECT_NOT_FOUND; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/TimeoutError.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/TimeoutError.java new file mode 100644 index 0000000000000000000000000000000000000000..446ee6d25cf6d686bbee7a3fa585f2405b9d7297 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/exceptions/TimeoutError.java @@ -0,0 +1,49 @@ +package gov.anl.aps.dm.common.exceptions; + +import gov.anl.aps.dm.common.constants.DmStatus; + +/** + * Timeout error. + */ +public class TimeoutError extends DmException { + + /** + * Default constructor. + */ + public TimeoutError() { + super(); + } + + /** + * Constructor using error message. + * + * @param message error message + */ + public TimeoutError(String message) { + super(message); + } + + /** + * Constructor using throwable object. + * + * @param throwable throwable object + */ + public TimeoutError(Throwable throwable) { + super(throwable); + } + + /** + * Constructor using error message and throwable object. + * + * @param message error message + * @param throwable throwable object + */ + public TimeoutError(String message, Throwable throwable) { + super(message, throwable); + } + + @Override + public int getErrorCode() { + return DmStatus.DM_TIMEOUT_ERROR; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/objects/DmObject.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/objects/DmObject.java new file mode 100644 index 0000000000000000000000000000000000000000..82c9d1b2915547f60257e0f50d36cbbdc6f5e92b --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/objects/DmObject.java @@ -0,0 +1,69 @@ +package gov.anl.aps.dm.common.objects; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import gov.anl.aps.dm.common.exceptions.DmException; +import java.io.Serializable; + +/** + * Base DM object class. + */ +public class DmObject implements Serializable { + + protected Long id = null; + protected String name = null; + protected String description = null; + + public DmObject() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + /** + * Conversion to JSON string representation. + * + * @return JSON string + */ + public String toJson() { + Gson gson = new GsonBuilder().create(); + return gson.toJson(this); + } + + /** + * Encode object. + * + * @throws DmException in case of any errors + */ + public void encode() throws DmException { + } + + /** + * Decode object. + * + * @throws DmException in case of any errors + */ + public void decode() throws DmException { + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/objects/DmObjectFactory.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/objects/DmObjectFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f003a16daf5872ef033e473d4961713e3984bad5 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/objects/DmObjectFactory.java @@ -0,0 +1,81 @@ +package gov.anl.aps.dm.common.objects; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import gov.anl.aps.dm.common.exceptions.DmException; +import java.lang.reflect.Type; +import java.util.LinkedList; +import java.util.List; +import org.apache.log4j.Logger; + +/** + * DM object factory class. + */ +public class DmObjectFactory { + + private static final Logger logger = Logger.getLogger(DmObjectFactory.class.getName()); + private static final Gson gson = new GsonBuilder().create(); + + /** + * Create object from JSON string. + * + * @param <T> template class + * @param jsonString JSON string + * @param objectClass object class + * @return generated object + */ + public static <T extends Object> T createObject(String jsonString, Class<T> objectClass) { + logger.debug("Converting JSON string to object " + objectClass + ": " + jsonString); + T object = gson.fromJson(jsonString, objectClass); + return object; + } + + /** + * Create DM object from JSON string. + * + * @param <T> template class + * @param jsonString JSON string + * @param dmClass DM object class + * @return generated DM object + * @throws DmException in case of any errors + */ + public static <T extends DmObject> T createDmObject(String jsonString, Class<T> dmClass) throws DmException { + logger.debug("Converting JSON string to DM object " + dmClass + ": " + jsonString); + T dmObject = gson.fromJson(jsonString, dmClass); + dmObject.decode(); + return dmObject; + } + + /** + * Create list of DM objects from JSON string. + * + * @param <T> template class + * @param jsonString DM string + * @return generated list of DM objects + */ + public static <T extends DmObject> List<T> createDmObjectList(String jsonString) { + // This method does not appear to work as template, so we have + // to write specific methods for each object type. + logger.debug("Converting JSON string to dm object list: " + jsonString); + Type dmType = new TypeToken<LinkedList<T>>() { + }.getType(); + List<T> dmObjectList = gson.fromJson(jsonString, dmType); + return dmObjectList; + } + + /** + * Create list of string objects from JSON string. + * + * @param jsonString JSON string + * @return generated list of string objects + */ + public static List<String> createStringObjectList(String jsonString) { + logger.debug("Converting JSON string to string object list: " + jsonString); + Type dmType = new TypeToken<LinkedList<String>>() { + }.getType(); + List<String> dmObjectList = gson.fromJson(jsonString, dmType); + return dmObjectList; + } + +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/ArgumentUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/ArgumentUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..eca2ae81414350156f500e968d64d09a77c1931e --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/ArgumentUtility.java @@ -0,0 +1,181 @@ +package gov.anl.aps.dm.common.utilities; + +import gov.anl.aps.dm.common.exceptions.InvalidArgument; +import gov.anl.aps.dm.common.exceptions.DmException; +import java.util.Map; +import javax.xml.bind.DatatypeConverter; + +/** + * Utility class for processing and checking function arguments. + */ +public class ArgumentUtility { + + /** + * Check that input string is not null and not empty. + * + * @param arg input argument to be checked + * @return true if input string is not null and not empty, false otherwise + */ + public static boolean isNonEmptyString(String arg) { + return arg != null && !arg.isEmpty(); + } + + /** + * Convert input argument to string. + * + * @param arg input argument to be checked + * @return original argument string representation, or empty string if + * argument is null + */ + public static String toNonNullString(Object arg) { + if (arg == null) { + return ""; + } + return arg.toString(); + } + + /** + * Verify that input string is not null and not empty. + * + * @param argName name of the argument to be verified; used for error + * message + * @param arg input argument to be checked + * @throws InvalidArgument if input string is null or empty + */ + public static void verifyNonEmptyString(String argName, String arg) throws InvalidArgument { + if (arg == null || arg.isEmpty()) { + throw new InvalidArgument(argName + " must be non-empty string."); + } + } + + /** + * Verify that input string contains given pattern. + * + * @param argName name of the argument to be verified; used for error + * message + * @param arg input argument to be checked + * @param pattern string that must be contained in the input argument + * @throws InvalidArgument if input string is null or empty, or if it does + * not contain specified pattern + */ + public static void verifyStringContainsPattern(String argName, String arg, String pattern) throws InvalidArgument { + verifyNonEmptyString(argName, arg); + verifyNonEmptyString("Pattern", pattern); + if (!arg.contains(pattern)) { + throw new InvalidArgument(argName + " must contain pattern " + pattern + "."); + } + } + + /** + * Verify that input integer is not null and greater than zero. + * + * @param argName name of the argument to be verified; used for error + * message + * @param arg input argument to be checked + * @throws InvalidArgument if input number is null or not positive + */ + public static void verifyPositiveInteger(String argName, Integer arg) throws InvalidArgument { + if (arg == null || arg <= 0) { + throw new InvalidArgument(argName + " must be a positive number."); + } + } + + /** + * Verify that input double is not null and greater than zero. + * + * @param argName name of the argument to be verified; used for error + * message + * @param arg input argument to be checked + * @throws InvalidArgument if input number is null or not positive + */ + public static void verifyPositiveDouble(String argName, Double arg) throws InvalidArgument { + if (arg == null || arg <= 0) { + throw new InvalidArgument(argName + " must be a positive number."); + } + } + + /** + * Verify that input object is not null. + * + * @param argName name of the argument to be verified; used for error + * message + * @param arg input argument to be checked + * @throws InvalidArgument if input string is null or empty + */ + public static void verifyNonNullObject(String argName, Object arg) throws InvalidArgument { + if (arg == null) { + throw new InvalidArgument(argName + " cannot be null."); + } + } + + /** + * Add (key,value) pair to map if value is not null or empty. + * + * @param map target map + * @param key key + * @param value string that will be added to map if it is not null or empty + */ + public static void addNonEmptyKeyValuePair(Map<String, String> map, String key, String value) { + if (value != null && !value.isEmpty()) { + map.put(key, value); + } + } + + /** + * Add (key,value) pair to map if value is not null or empty. + * + * @param map target map + * @param key key + * @param valueObject object that will be added to map if it has non-empty + * string representation + */ + public static void addNonEmptyKeyValuePair(Map<String, String> map, String key, Object valueObject) { + if (valueObject != null) { + String value = valueObject.toString(); + if (!value.isEmpty()) { + map.put(key, value); + } + } + } + + /** + * Base 64 encode. + * + * @param input input string + * @return base 64 encoded string + * @throws DmException in case of any errors + */ + public static String encode(String input) throws DmException { + try { + // Input is twice encoded in order to avoid issues like + // '+' being interpreted as space + if (input == null) { + return input; + } + String s1 = DatatypeConverter.printBase64Binary(input.getBytes()); + String s2 = DatatypeConverter.printBase64Binary(s1.getBytes()); + return s2; + } catch (Exception ex) { + throw new DmException(ex); + } + } + + /** + * Base 64 decode. + * + * @param input base 64 encoded string + * @return decoded string + * @throws DmException in case of any errors + */ + public static String decode(String input) throws DmException { + try { + // Input is twice encoded in order to avoid issues like + // '+' being interpreted as space + byte[] ba1 = DatatypeConverter.parseBase64Binary(input); + byte[] ba2 = DatatypeConverter.parseBase64Binary(new String(ba1)); + return new String(ba2); + } catch (Exception ex) { + throw new DmException(ex); + } + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/CollectionUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/CollectionUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..e6138960ebbf40f55f5b7432cc7edae5ccac1397 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/CollectionUtility.java @@ -0,0 +1,101 @@ +package gov.anl.aps.dm.common.utilities; + +import java.util.List; +import java.util.ListIterator; +import javax.faces.model.SelectItem; + +/** + * Utility class for manipulating collections. + */ +public class CollectionUtility { + + /** + * Prepare array of SelectItem objects for menus + * + * @param entities list of objects + * @param selectOne true if resulting array should contain "Select" string + * @return array of SelectItem objects + */ + public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) { + int size = selectOne ? entities.size() + 1 : entities.size(); + SelectItem[] items = new SelectItem[size]; + int i = 0; + if (selectOne) { + items[0] = new SelectItem("", "Select"); + i++; + } + for (Object x : entities) { + items[i++] = new SelectItem(x, x.toString()); + } + return items; + } + + /** + * Prepare display string for a list of objects. + * + * @param list object list + * @param beginDelimiter beginning delimiter + * @param itemDelimiter item delimiter + * @param endDelimiter ending delimiter + * @return list display string + */ + public static String displayItemList(List<?> list, String beginDelimiter, String itemDelimiter, String endDelimiter) { + String result = beginDelimiter; + boolean addItemDelimiter = false; + if (list != null) { + for (Object item : list) { + if (!addItemDelimiter) { + addItemDelimiter = true; + } else { + result += itemDelimiter; + } + result += item.toString(); + } + } + result += endDelimiter; + return result; + } + + /** + * Prepare display string for a list of objects without outside delimiters. + * + * @param list object list + * @param itemDelimiter item delimiter + * @return list display string + */ + public static String displayItemListWithoutOutsideDelimiters(List<?> list, String itemDelimiter) { + String beginDelimiter = ""; + String endDelimiter = ""; + return displayItemList(list, beginDelimiter, itemDelimiter, endDelimiter); + } + + /** + * Prepare display string for a list of objects with spaces as delimiters. + * + * @param list object list + * @return list display string + */ + public static String displayItemListWithoutDelimiters(List<?> list) { + String beginDelimiter = ""; + String itemDelimiter = ""; + String endDelimiter = ""; + return displayItemList(list, beginDelimiter, itemDelimiter, endDelimiter); + } + + /** + * Remove null references from list of objects. + * + * @param list object list + */ + public static void removeNullReferencesFromList(List<?> list) { + if (list == null) { + return; + } + ListIterator iterator = list.listIterator(); + while (iterator.hasNext()) { + if (iterator.next() == null) { + iterator.remove(); + } + } + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/CryptUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/CryptUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..426fc8574d3b34262d734c8d7017ef376ce35e63 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/CryptUtility.java @@ -0,0 +1,110 @@ +package gov.anl.aps.dm.common.utilities; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.util.Random; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import org.apache.log4j.Logger; +import org.primefaces.util.Base64; + +/** + * Utility class for encrypting and verifying passwords. + */ +public class CryptUtility { + + private static final String SecretKeyFactoryType = "PBKDF2WithHmacSHA1"; + private static final int Pbkdf2Iterations = 1003; + private static final int Pbkdf2KeyLengthInBits = 192; + private static final int SaltLengthInBytes = 4; + private static final char[] SaltCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray(); + private static final String SaltDelimiter = "$"; + + private static final Logger logger = Logger.getLogger(CryptUtility.class.getName()); + + /** + * Generate random string. + * + * @param characterSet set to draw characters from + * @param length string length + * @return generated string + */ + public static String randomString(char[] characterSet, int length) { + Random random = new SecureRandom(); + char[] result = new char[length]; + for (int i = 0; i < result.length; i++) { + // picks a random index out of character set > random character + int randomCharIndex = random.nextInt(characterSet.length); + result[i] = characterSet[randomCharIndex]; + } + return new String(result); + } + + /** + * Encrypt password using PBKDF2 key derivation function. + * + * @param password input password + * @return encrypted password + */ + public static String cryptPasswordWithPbkdf2(String password) { + String salt = randomString(SaltCharset, SaltLengthInBytes); + return saltAndCryptPasswordWithPbkdf2(password, salt); + } + + /** + * Apply salt string and encrypt password using PBKDF2 standard. + * + * @param password input password + * @param salt salt string + * @return encrypted password + */ + public static String saltAndCryptPasswordWithPbkdf2(String password, String salt) { + char[] passwordChars = password.toCharArray(); + byte[] saltBytes = salt.getBytes(); + + PBEKeySpec spec = new PBEKeySpec( + passwordChars, + saltBytes, + Pbkdf2Iterations, + Pbkdf2KeyLengthInBits + ); + SecretKeyFactory key; + try { + key = SecretKeyFactory.getInstance(SecretKeyFactoryType); + byte[] hashedPassword = key.generateSecret(spec).getEncoded(); + String encodedPassword = Base64.encodeToString(hashedPassword, true); + return salt + SaltDelimiter + encodedPassword; + } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) { + // Should not happen + logger.error("Password cannot be crypted: " + ex); + } + return null; + } + + /** + * Verify encrypted password. + * + * @param password password to be verified + * @param cryptedPassword original encrypted password + * @return true if passwords match, false otherwise + */ + public static boolean verifyPasswordWithPbkdf2(String password, String cryptedPassword) { + int saltEnd = cryptedPassword.indexOf(SaltDelimiter); + String salt = cryptedPassword.substring(0, saltEnd); + return cryptedPassword.equals(saltAndCryptPasswordWithPbkdf2(password, salt)); + } + + /* + * Main method, used for simple testing. + * + * @param args main arguments + */ + public static void main(String[] args) { + String password = "dm"; + System.out.println("Original password: " + password); + String cryptedPassword = cryptPasswordWithPbkdf2(password); + System.out.println("Crypted password: " + cryptedPassword); + System.out.println("Verified: " + verifyPasswordWithPbkdf2(password, cryptedPassword)); + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/DateUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/DateUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..d1a063fda016fbce291460f4a5ace57e41dc16b6 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/DateUtility.java @@ -0,0 +1,21 @@ +package gov.anl.aps.dm.common.utilities; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Utility class for manipulating dates. + */ +public class DateUtility { + + private static final SimpleDateFormat DateTimeFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + /** + * Format current date. + * + * @return formatted date string + */ + public static String getCurrentDateTime() { + return DateTimeFormat.format(new Date()); + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/FileUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/FileUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..669dd712c6da59bb666bd88adb4edddb9a60e0d5 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/FileUtility.java @@ -0,0 +1,26 @@ +package gov.anl.aps.dm.common.utilities; + +/** + * Utility class for manipulating files. + */ +public class FileUtility { + + /** + * Get file extension. + * + * @param fileName file name + * @return file extension + */ + public static String getFileExtension(String fileName) { + String extension = ""; + if (fileName != null && !fileName.isEmpty()) { + int extIndex = fileName.lastIndexOf('.'); + int dirIndex = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\')); + if (extIndex > dirIndex) { + extension = fileName.substring(extIndex + 1); + } + } + return extension.toLowerCase(); + } + +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/LdapUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/LdapUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..336caf28fe78130d79f49219b0125c9da739ddbd --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/LdapUtility.java @@ -0,0 +1,63 @@ +package gov.anl.aps.dm.common.utilities; + +import gov.anl.aps.dm.portal.utilities.ConfigurationUtility; +import java.util.Hashtable; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import org.apache.log4j.Logger; + +/** + * LDAP utility class for verifying user credentials. + * + * @see NoServerVerificationSSLSocketFactory + */ +public class LdapUtility { + + private static final String LdapUrlPropertyName = "dm.portal.ldapUrl"; + private static final String LdapDnStringPropertyName = "dm.portal.ldapDnString"; + private static final String ldapUrl = ConfigurationUtility.getPortalProperty(LdapUrlPropertyName); + private static final String ldapDnString = ConfigurationUtility.getPortalProperty(LdapDnStringPropertyName); + + private static final Logger logger = Logger.getLogger(LdapUtility.class.getName()); + + /** + * Validate user credentials. + * + * Use username and password to attempt initial connection and bind with + * LDAP server. Successful connection implies that credentials are accepted. + * + * @param username username + * @param password password + * + * @return true if credentials are valid, false otherwise + */ + public static boolean validateCredentials(String username, String password) { + + // dump out immediately if not given password + if (password.isEmpty()) { + return false; + } + + boolean validated = false; + Hashtable env = new Hashtable(); + String dn = ldapDnString.replace("USERNAME", username); + logger.debug("Authenticating: " + dn); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, ldapUrl); + env.put(Context.SECURITY_AUTHENTICATION, "simple"); + env.put(Context.SECURITY_PRINCIPAL, dn); + env.put(Context.SECURITY_CREDENTIALS, password); + // the below property allows us to circumvent server certificate checks + env.put("java.naming.ldap.factory.socket", "gov.anl.aps.dm.common.utilities.NoServerVerificationSSLSocketFactory"); + try { + DirContext ctx = new InitialDirContext(env); + validated = true; + } catch (NamingException ex) { + logger.error(ex); + } + return validated; + } + +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/NoOpTrustManager.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/NoOpTrustManager.java new file mode 100644 index 0000000000000000000000000000000000000000..e0a4936240b064bdc5ac76c4547d14bea1e82808 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/NoOpTrustManager.java @@ -0,0 +1,30 @@ +package gov.anl.aps.dm.common.utilities; + +import java.security.cert.X509Certificate; +import javax.net.ssl.X509TrustManager; + +/** + * Dummy trust manager class. + * + * A trivial implementation of <code>X509TrustManager</code> that doesn't + * actually check the validity of a certificate. This allows us to make SSL + * connections to internal servers without requiring the installation and + * maintenance of certificates in the client keystore. + * + * @see NoServerVerificationSSLSocketFactory + */ +public class NoOpTrustManager implements X509TrustManager { + + @Override + public void checkClientTrusted(X509Certificate[] cert, String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] cert, String authType) { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/NoServerVerificationSSLSocketFactory.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/NoServerVerificationSSLSocketFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..96088b175ebd41a7f3bdf769e2bcf230f80be2e8 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/NoServerVerificationSSLSocketFactory.java @@ -0,0 +1,153 @@ +package gov.anl.aps.dm.common.utilities; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import org.apache.log4j.Logger; + +/** + * SSL socket factory that does not verify server credentials. + * + * A minor extension of <code>SSLSocketFactory</code> that installs a dummy + * trust manager. This allows creation of SSL sockets that don't verify the + * server certificates. + * + * @see NoOpTrustManager + */ +public class NoServerVerificationSSLSocketFactory extends SSLSocketFactory { + + private static final Logger logger = Logger.getLogger(NoServerVerificationSSLSocketFactory.class.getName()); + + private SSLSocketFactory factory; + + /** + * Default constructor. + */ + public NoServerVerificationSSLSocketFactory() { + try { + TrustManager tm = new NoOpTrustManager(); + SSLContext sslcontext = SSLContext.getInstance("TLS"); + sslcontext.init(null, // No KeyManager required + new TrustManager[]{tm}, + new java.security.SecureRandom()); + + factory = (SSLSocketFactory) sslcontext.getSocketFactory(); + } catch (KeyManagementException | NoSuchAlgorithmException ex) { + logger.error(ex); + } + } + + /** + * Get default (no server verification) socket factory. + * + * @return socket factory + */ + public static SocketFactory getDefault() { + return new NoServerVerificationSSLSocketFactory(); + } + + /** + * Create SSL socket layered over an existing socket connected to the named + * host, at a given port. + * + * @param socket existing socket + * @param host + * @param port + * @param autoClose + * @return created socket + * @throws IOException in case of IO errors + */ + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) + throws IOException { + return factory.createSocket(socket, host, port, autoClose); + } + + /** + * Create a socket and connect it to the specified remote address/port, and + * bind it to the specified local address/port. + * + * @param address server network address + * @param port server port + * @param localAddress client network address + * @param localPort client port + * @return created socket + * @throws IOException in case of IO errors + */ + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException { + return factory.createSocket(address, port, localAddress, localPort); + } + + /** + * Create a socket and connect it to the specified remote address/port. + * + * @param address server network address + * @param port server port + * @return created socket + * @throws IOException in case of IO errors + */ + @Override + public Socket createSocket(InetAddress address, int port) throws IOException { + return factory.createSocket(address, port); + } + + /** + * Create a socket and connect it to the specified remote host/port, and + * bind it to the specified local address/port. + * + * @param host server host + * @param port server port + * @param localAddress client network address + * @param localPort client port + * @return created socket + * @throws IOException in case of IO errors + */ + @Override + public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) + throws IOException { + return factory.createSocket(host, port, localAddress, localPort); + } + + /** + * Create a socket and connect it to the specified remote host/port, and + * bind it to the specified local address/port. + * + * @param host server host + * @param port server port + * @return created socket + * @throws IOException in case of IO errors + */ + @Override + public Socket createSocket(String host, int port) throws IOException { + return factory.createSocket(host, port); + } + + /** + * Get default cipher suites from socket factory. + * + * @return list of default ciphers + */ + @Override + public String[] getDefaultCipherSuites() { + return factory.getSupportedCipherSuites(); + } + + /** + * Get supported cipher suites from socket factory. + * + * @return list of supported ciphers + */ + @Override + public String[] getSupportedCipherSuites() { + return factory.getSupportedCipherSuites(); + } + +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/ObjectUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/ObjectUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..41788da35bc4004910a997881ef4d9d9447c5736 --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/ObjectUtility.java @@ -0,0 +1,27 @@ +package gov.anl.aps.dm.common.utilities; + +/** + * Object utility class. + */ +public class ObjectUtility { + + /** + * Verify that two objects are the same. + * + * Object references can be null. + * + * @param <Type> template type of given objects + * @param object1 first object + * @param object2 second object + * @return true if objects are equal, false otherwise + */ + public static <Type> boolean equals(Type object1, Type object2) { + if (object1 == null && object2 == null) { + return true; + } + if (object1 == null || object2 == null) { + return false; + } + return object1.equals(object2); + } +} diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/StringUtility.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/StringUtility.java new file mode 100644 index 0000000000000000000000000000000000000000..e418496b9351999c34169e14f40de0b4e7bdc7da --- /dev/null +++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/common/utilities/StringUtility.java @@ -0,0 +1,36 @@ +package gov.anl.aps.dm.common.utilities; + +/** + * String utility class. + */ +public class StringUtility { + + /** + * Verify that two char sequences are the same. + * + * Input string references can be null. + * + * @param cs1 first sequence + * @param cs2 second sequence + * @return true if char sequences are the same, false otherwise + */ + public static boolean equals(CharSequence cs1, CharSequence cs2) { + if (cs1 == null && cs2 == null) { + return true; + } + if (cs1 == null || cs2 == null) { + return false; + } + return cs1.equals(cs2); + } + + /** + * Capitalize first letter of a given string. + * + * @param input input string + * @return capitalized string + */ + public static String capitalize(String input) { + return input.substring(0, 1).toUpperCase() + input.substring(1); + } +}