use of com.openmeap.digest.DigestException in project OpenMEAP by OpenMEAP.
the class WebViewServlet method service.
@SuppressWarnings("unchecked")
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
logger.trace("in service");
ModelManager mgr = getModelManager();
GlobalSettings settings = mgr.getGlobalSettings();
String validTempPath = settings.validateTemporaryStoragePath();
if (validTempPath != null) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, validTempPath);
}
String pathInfo = request.getPathInfo();
String[] pathParts = pathInfo.split("[/]");
if (pathParts.length < 4) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
String remove = pathParts[1] + "/" + pathParts[2] + "/" + pathParts[3];
String fileRelative = pathInfo.replace(remove, "");
String applicationNameString = URLDecoder.decode(pathParts[APP_NAME_INDEX], FormConstants.CHAR_ENC_DEFAULT);
String archiveHash = URLDecoder.decode(pathParts[APP_VER_INDEX], FormConstants.CHAR_ENC_DEFAULT);
Application app = mgr.getModelService().findApplicationByName(applicationNameString);
ApplicationArchive arch = mgr.getModelService().findApplicationArchiveByHashAndAlgorithm(app, archiveHash, "MD5");
String authSalt = app.getProxyAuthSalt();
String authToken = URLDecoder.decode(pathParts[AUTH_TOKEN_INDEX], FormConstants.CHAR_ENC_DEFAULT);
try {
if (!AuthTokenProvider.validateAuthToken(authSalt, authToken)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
} catch (DigestException e1) {
throw new GenericRuntimeException(e1);
}
File fileFull = new File(arch.getExplodedPath(settings.getTemporaryStoragePath()).getAbsolutePath() + "/" + fileRelative);
try {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor(fileFull.toURL().toString());
response.setContentType(mimeType);
response.setContentLength(Long.valueOf(fileFull.length()).intValue());
InputStream inputStream = null;
OutputStream outputStream = null;
try {
//response.setStatus(HttpServletResponse.SC_FOUND);
inputStream = new FileInputStream(fileFull);
outputStream = response.getOutputStream();
Utils.pipeInputStreamIntoOutputStream(inputStream, outputStream);
} finally {
if (inputStream != null) {
inputStream.close();
}
response.getOutputStream().flush();
response.getOutputStream().close();
}
} catch (FileNotFoundException e) {
logger.error("Exception {}", e);
response.sendError(HttpServletResponse.SC_NOT_FOUND);
} catch (IOException ioe) {
logger.error("Exception {}", ioe);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
use of com.openmeap.digest.DigestException in project OpenMEAP by OpenMEAP.
the class ApplicationManagementServlet method handleArchiveDownload.
private Result handleArchiveDownload(HttpServletRequest request, HttpServletResponse response) {
Result res = new Result();
Error err = new Error();
res.setError(err);
GlobalSettings settings = modelManager.getGlobalSettings();
Map properties = this.getServicesWebProperties();
String nodeKey = (String) properties.get("clusterNodeUrlPrefix");
ClusterNode clusterNode = settings.getClusterNode(nodeKey);
if (nodeKey == null || clusterNode == null) {
// TODO: create a configuration error code
err.setCode(ErrorCode.UNDEFINED);
err.setMessage("A configuration is missing. Please consult the error logs.");
logger.error("For each node in the cluster, the property or environment variable OPENMEAP_CLUSTER_NODE_URL_PREFIX must match the \"Service Url Prefix\" value configured in the administrative interface. This value is currently " + nodeKey + ".");
return res;
}
String pathValidation = clusterNode.validateFileSystemStoragePathPrefix();
if (pathValidation != null) {
err.setCode(ErrorCode.UNDEFINED);
err.setMessage("A configuration is missing. Please consult the error logs.");
logger.error("There is an issue with the location at \"File-system Storage Prefix\". " + pathValidation);
return res;
}
String hash = request.getParameter(UrlParamConstants.APPARCH_HASH);
String hashAlg = request.getParameter(UrlParamConstants.APPARCH_HASH_ALG);
String fileName = null;
if (hash == null || hashAlg == null) {
// look in the apps directory for the archive specified
String appName = request.getParameter(UrlParamConstants.APP_NAME);
String versionId = request.getParameter(UrlParamConstants.APP_VERSION);
ApplicationVersion appVersion = modelManager.getModelService().findAppVersionByNameAndId(appName, versionId);
if (appVersion == null) {
String mesg = "The application version " + versionId + " was not found for application " + appName;
err.setCode(ErrorCode.APPLICATION_VERSION_NOTFOUND);
err.setMessage(mesg);
logger.warn(mesg);
return res;
}
String auth = request.getParameter(UrlParamConstants.AUTH_TOKEN);
com.openmeap.model.dto.Application app = appVersion.getApplication();
try {
if (auth == null || !AuthTokenProvider.validateAuthToken(app.getProxyAuthSalt(), auth)) {
err.setCode(ErrorCode.AUTHENTICATION_FAILURE);
err.setMessage("The \"auth\" token presented is not recognized, missing, or empty.");
return res;
}
} catch (DigestException e) {
throw new GenericRuntimeException(e);
}
hash = appVersion.getArchive().getHash();
hashAlg = appVersion.getArchive().getHashAlgorithm();
fileName = app.getName() + " - " + appVersion.getIdentifier();
} else {
fileName = hashAlg + "-" + hash;
}
File file = ApplicationArchive.getFile(clusterNode.getFileSystemStoragePathPrefix(), hashAlg, hash);
if (!file.exists()) {
String mesg = "The application archive with " + hashAlg + " hash " + hash + " was not found.";
// TODO: create an enumeration for this error
err.setCode(ErrorCode.UNDEFINED);
err.setMessage(mesg);
logger.warn(mesg);
return res;
}
try {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor(file.toURL().toString());
response.setContentType(mimeType);
response.setContentLength(Long.valueOf(file.length()).intValue());
URLCodec codec = new URLCodec();
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".zip\";");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(file));
outputStream = response.getOutputStream();
Utils.pipeInputStreamIntoOutputStream(inputStream, outputStream);
} finally {
if (inputStream != null) {
inputStream.close();
}
//if(outputStream!=null) {outputStream.close();}
}
response.flushBuffer();
} catch (FileNotFoundException e) {
logger.error("Exception {}", e);
} catch (IOException ioe) {
logger.error("Exception {}", ioe);
}
return null;
}
use of com.openmeap.digest.DigestException in project OpenMEAP by OpenMEAP.
the class ServiceManagementServlet method authenticates.
/**
* Validates that the auth in a request passes validation
* @param arg0
* @return
*/
private Boolean authenticates(HttpServletRequest arg0) {
String authSalt = getAuthSalt();
String auth = (String) arg0.getParameter(UrlParamConstants.AUTH_TOKEN);
Boolean isGood;
try {
isGood = AuthTokenProvider.validateAuthToken(authSalt, auth);
} catch (DigestException e) {
throw new GenericRuntimeException(e);
}
logger.debug("Authentication of token \"{}\" with salt \"{}\" returned {}", new Object[] { authSalt, auth, isGood });
return (auth != null && isGood);
}
use of com.openmeap.digest.DigestException in project OpenMEAP by OpenMEAP.
the class ArchiveFileUploadNotifier method processApplicationArchiveFileUpload.
@SuppressWarnings("unchecked")
private ApplicationArchive processApplicationArchiveFileUpload(ApplicationArchive archive, List<ProcessingEvent> events) {
GlobalSettings settings = modelManager.getGlobalSettings();
File tempFile = new File(archive.getNewFileUploaded());
Long size = tempFile.length();
String pathError = settings.validateTemporaryStoragePath();
if (pathError != null) {
logger.error("There is an issue with the global settings temporary storage path: " + settings.validateTemporaryStoragePath() + "\n {}", pathError);
events.add(new MessagesEvent("There is an issue with the global settings temporary storage path: " + settings.validateTemporaryStoragePath() + " - " + pathError));
return null;
}
// determine the md5 hash of the uploaded file
// and rename the temp file by the hash
FileInputStream is = null;
File destinationFile = null;
try {
// that is, they are not used by any other versions
if (archive.getId() != null) {
ArchiveFileHelper.maintainFileSystemCleanliness(modelManager, fileManager, archive, events);
}
String hashValue = null;
ApplicationArchive archiveExists = null;
try {
is = new FileInputStream(tempFile);
hashValue = Utils.hashInputStream("MD5", is);
archiveExists = modelManager.getModelService().findApplicationArchiveByHashAndAlgorithm(archive.getApplication(), hashValue, "MD5");
if (archiveExists != null) {
if (!tempFile.delete()) {
String mesg = String.format("Failed to delete temporary file %s", tempFile.getName());
logger.error(mesg);
events.add(new MessagesEvent(mesg));
}
return archiveExists;
} else {
// if an archive of the hash/alg doesn't exist,
// then we don't want to accidentally change an existing one.
archive = archive.clone();
archive.setId(null);
}
} catch (DigestException de) {
throw new PersistenceException(de);
} finally {
is.close();
}
archive.setHashAlgorithm("MD5");
archive.setHash(hashValue);
destinationFile = archive.getFile(settings.getTemporaryStoragePath());
// even though they are theoretically the same.
if (destinationFile.exists() && !destinationFile.delete()) {
String mesg = String.format("Failed to delete old file (theoretically the same anyways, so proceeding) %s", destinationFile.getName());
logger.error(mesg);
events.add(new MessagesEvent(mesg));
if (!tempFile.delete()) {
mesg = String.format("Failed to delete temporary file %s", tempFile.getName());
logger.error(mesg);
events.add(new MessagesEvent(mesg));
}
} else // into the web-view directory
if (tempFile.renameTo(destinationFile)) {
String mesg = String.format("Uploaded temporary file %s successfully renamed to %s", tempFile.getName(), destinationFile.getName());
logger.debug(mesg);
events.add(new MessagesEvent(mesg));
ArchiveFileHelper.unzipFile(modelManager, fileManager, archive, destinationFile, events);
} else {
String mesg = String.format("Failed to renamed file %s to %s", tempFile.getName(), destinationFile.getName());
logger.error(mesg);
events.add(new MessagesEvent(mesg));
return null;
}
} catch (IOException ioe) {
events.add(new MessagesEvent(ioe.getMessage()));
return null;
}
// determine the compressed and uncompressed size of the zip archive
try {
archive.setBytesLength(size.intValue());
ZipFile zipFile = null;
try {
zipFile = new ZipFile(destinationFile);
Integer uncompressedSize = ZipUtils.getUncompressedSize(zipFile).intValue();
archive.setBytesLengthUncompressed(new Long(uncompressedSize).intValue());
} finally {
if (zipFile != null) {
zipFile.close();
}
}
} catch (IOException ioe) {
logger.error("An exception occurred while calculating the uncompressed size of the archive: {}", ioe);
events.add(new MessagesEvent(String.format("An exception occurred while calculating the uncompressed size of the archive: %s", ioe.getMessage())));
return null;
}
archive.setUrl(ApplicationArchive.URL_TEMPLATE);
return archive;
}
use of com.openmeap.digest.DigestException in project OpenMEAP by OpenMEAP.
the class ApplicationManagementServiceImpl method connectionOpen.
public ConnectionOpenResponse connectionOpen(ConnectionOpenRequest request) throws WebServiceException {
String reqAppArchHashVal = StringUtils.trimToNull(request.getApplication().getHashValue());
String reqAppVerId = StringUtils.trimToNull(request.getApplication().getVersionId());
String reqAppName = StringUtils.trimToNull(request.getApplication().getName());
ConnectionOpenResponse response = new ConnectionOpenResponse();
GlobalSettings settings = modelManager.getGlobalSettings();
if (StringUtils.isBlank(settings.getExternalServiceUrlPrefix()) && logger.isWarnEnabled()) {
logger.warn("The external service url prefix configured in the admin interface is blank. " + "This will probably cause issues downloading application archives.");
}
Application application = getApplication(reqAppName, reqAppVerId);
// Generate a new auth token for the device to present to the proxy
String authToken;
try {
authToken = AuthTokenProvider.newAuthToken(application.getProxyAuthSalt());
} catch (DigestException e) {
throw new GenericRuntimeException(e);
}
response.setAuthToken(authToken);
// If there is a deployment,
// and the version of that deployment differs in hash value or identifier
// then return an update in the response
Deployment lastDeployment = modelManager.getModelService().getLastDeployment(application);
Boolean reqAppVerDiffers = lastDeployment != null && !lastDeployment.getVersionIdentifier().equals(reqAppVerId);
Boolean reqAppArchHashValDiffers = lastDeployment != null && reqAppArchHashVal != null && !lastDeployment.getApplicationArchive().getHash().equals(reqAppArchHashVal);
// the app hash value is different than reported
if (reqAppVerDiffers || reqAppArchHashValDiffers) {
// TODO: I'm not happy with the discrepancies between the model and schema
// ...besides, this update header should be encapsulated somewhere else
ApplicationArchive currentVersionArchive = lastDeployment.getApplicationArchive();
UpdateHeader uh = new UpdateHeader();
uh.setVersionIdentifier(lastDeployment.getVersionIdentifier());
uh.setInstallNeeds(Long.valueOf(currentVersionArchive.getBytesLength() + currentVersionArchive.getBytesLengthUncompressed()));
uh.setStorageNeeds(Long.valueOf(currentVersionArchive.getBytesLengthUncompressed()));
uh.setType(UpdateType.fromValue(lastDeployment.getType().toString()));
uh.setUpdateUrl(currentVersionArchive.getDownloadUrl(settings));
uh.setHash(new Hash());
uh.getHash().setAlgorithm(HashAlgorithm.fromValue(currentVersionArchive.getHashAlgorithm()));
uh.getHash().setValue(currentVersionArchive.getHash());
response.setUpdate(uh);
}
return response;
}
Aggregations