From b5f86cb0fca1d6feb52a7906a8394c8537aeedea Mon Sep 17 00:00:00 2001 From: Rick Herrick <jrherrick@wustl.edu> Date: Tue, 1 Nov 2016 03:33:06 -0500 Subject: [PATCH] XNAT-4557 XNAT-4558 Added support for preference aliases. Moved notification preference change handling to SmtpHandlerMethod. --- build.gradle | 2 +- .../dcm/id/ClassicDicomObjectIdentifier.java | 36 +- .../nrg/pipeline/XnatPipelineLauncher.java | 20 +- .../java/org/nrg/viewer/QCImageCreator.java | 2 +- .../InsufficientPrivilegesException.java | 25 ++ .../xapi/rest/XapiRestControllerAdvice.java | 12 + .../rest/notifications/NotificationsApi.java | 385 ++++++++---------- .../nrg/xapi/rest/settings/SiteConfigApi.java | 56 ++- .../org/nrg/xapi/rest/users/UsersApi.java | 16 +- .../java/org/nrg/xnat/archive/Transfer.java | 2 +- .../configuration/NotificationsConfig.java | 22 +- .../xnat/configuration/PreferencesConfig.java | 27 -- .../xnat/configuration/SchedulerConfig.java | 6 +- .../SiteConfigPreferenceHandler.java | 60 ++- .../methods/FeatureServicesHandlerMethod.java | 5 +- .../methods/InitializedHandlerMethod.java | 106 +++++ .../methods/RequiredChannelHandlerMethod.java | 2 +- .../methods/RoleServicesHandlerMethod.java | 2 +- .../listeners/methods/SmtpHandlerMethod.java | 66 ++- ...atUserProviderPreferenceHandlerMethod.java | 52 +++ .../xnat/helpers/prearchive/PrearcUtils.java | 45 +- .../restlet/actions/TriggerPipelines.java | 2 +- .../resources/ProjtExptPipelineResource.java | 4 +- .../modules/actions/ManagePipeline.java | 2 +- .../modules/actions/PipelineActions.java | 2 +- .../turbine/modules/actions/QDECAction.java | 2 +- .../xnat/turbine/utils/ArcSpecManager.java | 17 +- .../org/nrg/xnat/utils/XnatUserProvider.java | 28 +- .../xnat/preferences/site-config.properties | 62 --- .../xnat/spawner/site-admin-elements.yaml | 53 ++- .../webapp/WEB-INF/conf/services.properties | 91 ----- .../webapp/resources/samples/prefs-init.ini | 30 ++ .../samples}/xnat-conf.properties | 0 .../webapp/scripts/project/settingsTabMgmt.js | 4 +- src/main/webapp/setup/site-setup.yaml | 18 +- .../webapp/xdat-templates/layouts/Default.vm | 2 +- .../xdat-templates/macros/TurbineMacros.vm | 8 +- .../webapp/xnat-templates/layouts/Index.vm | 2 +- .../navigations/HeaderIncludes.vm | 10 +- .../navigations/XNATQuickSearch.vm | 2 +- .../screens/xnat_ctSessionData/edit/scans.vm | 4 +- .../actionsBox/ManageFiles.vm | 2 +- .../xnat_imageSessionData/edit/scans.vm | 4 +- .../screens/xnat_mrSessionData/edit/scans.vm | 4 +- .../screens/xnat_petSessionData/edit/scans.vm | 4 +- .../xnat_petmrSessionData/edit/scans.vm | 2 +- .../actionsBox/ManageFiles.vm | 2 +- .../xnat_subjectData_assessor.vm | 4 +- 48 files changed, 659 insertions(+), 655 deletions(-) create mode 100644 src/main/java/org/nrg/xapi/exceptions/InsufficientPrivilegesException.java create mode 100644 src/main/java/org/nrg/xnat/event/listeners/methods/InitializedHandlerMethod.java create mode 100644 src/main/java/org/nrg/xnat/event/listeners/methods/XnatUserProviderPreferenceHandlerMethod.java delete mode 100644 src/main/resources/META-INF/xnat/preferences/site-config.properties delete mode 100644 src/main/webapp/WEB-INF/conf/services.properties create mode 100644 src/main/webapp/resources/samples/prefs-init.ini rename src/main/webapp/{WEB-INF/conf => resources/samples}/xnat-conf.properties (100%) diff --git a/build.gradle b/build.gradle index 59c17d7f..9543b208 100644 --- a/build.gradle +++ b/build.gradle @@ -465,7 +465,7 @@ dependencies { runtime "org.codehaus.groovy.modules.http-builder:http-builder:0.7.2" runtime "net.imagej:ij:1.50e" runtime "net.bull.javamelody:javamelody-core:1.58.0" - runtime "org.javassist:javassist:3.20.0-GA" + runtime "org.javassist:javassist:3.21.0-GA" providedCompile "javax.servlet:javax.servlet-api:${vServletApi}" diff --git a/src/main/java/org/nrg/dcm/id/ClassicDicomObjectIdentifier.java b/src/main/java/org/nrg/dcm/id/ClassicDicomObjectIdentifier.java index 628f3aa0..34b19420 100644 --- a/src/main/java/org/nrg/dcm/id/ClassicDicomObjectIdentifier.java +++ b/src/main/java/org/nrg/dcm/id/ClassicDicomObjectIdentifier.java @@ -19,31 +19,19 @@ import java.util.List; import java.util.regex.Pattern; public class ClassicDicomObjectIdentifier extends CompositeDicomObjectIdentifier { - private static final ImmutableList<Extractor> aaExtractors, sessionExtractors, subjectExtractors; - static { - final ImmutableList.Builder<Extractor> aab = new ImmutableList.Builder<Extractor>(); - aab.add(new ContainedAssignmentExtractor(Tag.PatientComments, "AA", Pattern.CASE_INSENSITIVE), - new ContainedAssignmentExtractor(Tag.StudyComments, "AA", Pattern.CASE_INSENSITIVE)); - aaExtractors = aab.build(); - - final ImmutableList.Builder<Extractor> sessb = new ImmutableList.Builder<Extractor>(); - sessb.add(new ContainedAssignmentExtractor(Tag.PatientComments, "Session", Pattern.CASE_INSENSITIVE), - new ContainedAssignmentExtractor(Tag.StudyComments, "Session", Pattern.CASE_INSENSITIVE), - new TextExtractor(Tag.PatientID)); - sessionExtractors = sessb.build(); - - final ImmutableList.Builder<Extractor> subjb = new ImmutableList.Builder<Extractor>(); - subjb.add(new ContainedAssignmentExtractor(Tag.PatientComments, "Subject", Pattern.CASE_INSENSITIVE), - new ContainedAssignmentExtractor(Tag.StudyComments, "Subject", Pattern.CASE_INSENSITIVE), - new TextExtractor(Tag.PatientName)); - subjectExtractors = subjb.build(); - } - - public static List<Extractor> getAAExtractors() { return aaExtractors; } - public static List<Extractor> getSessionExtractors() { return sessionExtractors; } - public static List<Extractor> getSubjectExtractors() { return subjectExtractors; } + private static final ImmutableList<Extractor> attributeExtractors = new ImmutableList.Builder<Extractor>().add(new ContainedAssignmentExtractor(Tag.PatientComments, "AA", Pattern.CASE_INSENSITIVE)) + .add(new ContainedAssignmentExtractor(Tag.StudyComments, "AA", Pattern.CASE_INSENSITIVE)) + .build(); + private static final ImmutableList<Extractor> sessionExtractors = new ImmutableList.Builder<Extractor>().add(new ContainedAssignmentExtractor(Tag.PatientComments, "Session", Pattern.CASE_INSENSITIVE)) + .add(new ContainedAssignmentExtractor(Tag.StudyComments, "Session", Pattern.CASE_INSENSITIVE)) + .add(new TextExtractor(Tag.PatientID)) + .build(); + private static final ImmutableList<Extractor> subjectExtractors = new ImmutableList.Builder<Extractor>().add(new ContainedAssignmentExtractor(Tag.PatientComments, "Subject", Pattern.CASE_INSENSITIVE)) + .add(new ContainedAssignmentExtractor(Tag.StudyComments, "Subject", Pattern.CASE_INSENSITIVE)) + .add(new TextExtractor(Tag.PatientName)) + .build(); public ClassicDicomObjectIdentifier() { - super(new Xnat15DicomProjectIdentifier(), subjectExtractors, sessionExtractors, aaExtractors); + super(new Xnat15DicomProjectIdentifier(), subjectExtractors, sessionExtractors, attributeExtractors); } } diff --git a/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java b/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java index 61e6b935..cea37377 100644 --- a/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java +++ b/src/main/java/org/nrg/pipeline/XnatPipelineLauncher.java @@ -621,7 +621,7 @@ public class XnatPipelineLauncher { xnatPipelineLauncher.setParameter("useremail", user.getEmail()); xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user)); xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); xnatPipelineLauncher.setId(imageSession.getId()); @@ -651,24 +651,6 @@ public class XnatPipelineLauncher { return xnatPipelineLauncher; } - public static XnatPipelineLauncher GetBareLauncherForExperiment(RunData data, Context context, XnatExperimentdata imageSession) throws Exception { - XnatPipelineLauncher xnatPipelineLauncher = new XnatPipelineLauncher(data, context); - xnatPipelineLauncher.setSupressNotification(true); - UserI user = XDAT.getUserDetails(); - xnatPipelineLauncher.setParameter("useremail", user.getEmail()); - xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user)); - xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); - xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); - - xnatPipelineLauncher.setId(imageSession.getId()); - xnatPipelineLauncher.setLabel(imageSession.getLabel()); - xnatPipelineLauncher.setDataType(imageSession.getXSIType()); - xnatPipelineLauncher.setExternalId(imageSession.getProject()); - - return xnatPipelineLauncher; - } - public static XnatPipelineLauncher GetLauncher(RunData data, Context context, XnatImagesessiondata imageSession) throws Exception { XnatPipelineLauncher xnatPipelineLauncher = GetLauncherForExperiment(data, context, imageSession); String path = imageSession.getArchivePath(); diff --git a/src/main/java/org/nrg/viewer/QCImageCreator.java b/src/main/java/org/nrg/viewer/QCImageCreator.java index fc1fbec6..5e252b89 100644 --- a/src/main/java/org/nrg/viewer/QCImageCreator.java +++ b/src/main/java/org/nrg/viewer/QCImageCreator.java @@ -49,7 +49,7 @@ public class QCImageCreator { xnatPipelineLauncher.setParameter("session", mrSession.getId() ); xnatPipelineLauncher.setParameter("notify", "0" ); xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); xnatPipelineLauncher.setParameter("useremail", user.getEmail()); xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); diff --git a/src/main/java/org/nrg/xapi/exceptions/InsufficientPrivilegesException.java b/src/main/java/org/nrg/xapi/exceptions/InsufficientPrivilegesException.java new file mode 100644 index 00000000..83f82fac --- /dev/null +++ b/src/main/java/org/nrg/xapi/exceptions/InsufficientPrivilegesException.java @@ -0,0 +1,25 @@ +/* + * web: org.nrg.xapi.exceptions.DataFormatException + * XNAT http://www.xnat.org + * Copyright (c) 2016, Washington University School of Medicine and Howard Hughes Medical Institute + * All Rights Reserved + * + * Released under the Simplified BSD. + */ + +package org.nrg.xapi.exceptions; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.BAD_REQUEST) +public class InsufficientPrivilegesException extends ApiException { + public InsufficientPrivilegesException(final String username) { + super(HttpStatus.BAD_REQUEST.value(), username); + } + + @Override + public String getMessage() { + return String.format("The user %s has insufficient privileges for the requested operation.", super.getMessage()); + } +} diff --git a/src/main/java/org/nrg/xapi/rest/XapiRestControllerAdvice.java b/src/main/java/org/nrg/xapi/rest/XapiRestControllerAdvice.java index 9e59bd1b..14a04d5e 100644 --- a/src/main/java/org/nrg/xapi/rest/XapiRestControllerAdvice.java +++ b/src/main/java/org/nrg/xapi/rest/XapiRestControllerAdvice.java @@ -17,6 +17,8 @@ import org.nrg.framework.exceptions.NrgServiceError; import org.nrg.framework.exceptions.NrgServiceException; import org.nrg.framework.exceptions.NrgServiceRuntimeException; import org.nrg.xapi.exceptions.DataFormatException; +import org.nrg.xapi.exceptions.InsufficientPrivilegesException; +import org.nrg.xapi.exceptions.NotFoundException; import org.nrg.xapi.exceptions.ResourceAlreadyExistsException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +47,11 @@ public class XapiRestControllerAdvice { return handleException(request, exception.getMessage(), exception); } + @ExceptionHandler(InsufficientPrivilegesException.class) + public ModelAndView handleInsufficientPrivilegesException(final HttpServletRequest request, final DataFormatException exception) { + return handleException(request, exception.getMessage(), exception); + } + @ExceptionHandler(ResourceAlreadyExistsException.class) public ModelAndView handleDataFormatException(final HttpServletRequest request, final ResourceAlreadyExistsException exception) { return handleException(request, exception.getMessage(), exception); @@ -66,6 +73,11 @@ public class XapiRestControllerAdvice { return handleException(HttpStatus.BAD_REQUEST, request, "Unable to find requested file or resource: " + exception.getMessage(), exception); } + @ExceptionHandler(NotFoundException.class) + public ModelAndView handleNotFoundException(final HttpServletRequest request, final NotFoundException exception) { + return handleException(HttpStatus.BAD_REQUEST, request, exception.getMessage(), exception); + } + @ExceptionHandler(ConfigServiceException.class) public ModelAndView handleConfigServiceException(final HttpServletRequest request, final ConfigServiceException exception) { return handleException(HttpStatus.INTERNAL_SERVER_ERROR, request, "An error occurred when accessing the configuration service: " + exception.getMessage(), exception); diff --git a/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java b/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java index 8e4577e3..a748afe9 100644 --- a/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java +++ b/src/main/java/org/nrg/xapi/rest/notifications/NotificationsApi.java @@ -12,12 +12,11 @@ package org.nrg.xapi.rest.notifications; import io.swagger.annotations.*; import org.apache.commons.lang3.StringUtils; import org.nrg.framework.annotations.XapiRestController; -import org.nrg.framework.exceptions.NrgServiceError; -import org.nrg.framework.exceptions.NrgServiceRuntimeException; import org.nrg.framework.services.SerializerService; import org.nrg.prefs.exceptions.InvalidPreferenceName; import org.nrg.xapi.exceptions.InitializationException; import org.nrg.xdat.preferences.NotificationsPreferences; +import org.nrg.xdat.preferences.SmtpServer; import org.nrg.xdat.rest.AbstractXapiRestController; import org.nrg.xdat.security.services.RoleHolder; import org.nrg.xdat.security.services.UserManagementServiceI; @@ -28,7 +27,6 @@ import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.web.bind.annotation.*; import javax.inject.Inject; @@ -58,10 +56,9 @@ public class NotificationsApi extends AbstractXapiRestController { + "by calling the POST version of this method."; @Inject - public NotificationsApi(final UserManagementServiceI userManagementService, final RoleHolder roleHolder, final NotificationsPreferences notificationsPrefs, final JavaMailSenderImpl javaMailSender, final XnatAppInfo appInfo, final SerializerService serializer) { + public NotificationsApi(final UserManagementServiceI userManagementService, final RoleHolder roleHolder, final NotificationsPreferences notificationsPrefs, final XnatAppInfo appInfo, final SerializerService serializer) { super(userManagementService, roleHolder); _notificationsPrefs = notificationsPrefs; - _javaMailSender = javaMailSender; _appInfo = appInfo; _serializer = serializer; } @@ -124,7 +121,7 @@ public class NotificationsApi extends AbstractXapiRestController { } else if (StringUtils.equals(name, "emailRecipientUpdate")) { _notificationsPrefs.setEmailRecipientUpdate(properties.getProperty(name)); } else if (StringUtils.equals(name, "smtpServer")) { - _notificationsPrefs.setSmtpServer(_serializer.deserializeJson(properties.getProperty(name), SerializerService.TYPE_REF_MAP_STRING_STRING)); + _notificationsPrefs.setSmtpServer(_serializer.deserializeJson(properties.getProperty(name), SmtpServer.class)); } else { _notificationsPrefs.set(properties.getProperty(name), name); } @@ -137,32 +134,12 @@ public class NotificationsApi extends AbstractXapiRestController { _log.error("An error occurred deserializing the preference: " + name + ", which is just lame."); } } - - // If any of the SMTP properties changed, then change the values for - if (properties.containsKey("smtpServer") || properties.containsKey("host") || properties.containsKey("port") || properties.containsKey("protocol") || properties.containsKey("username") || properties.containsKey("password")) { - final String host = _notificationsPrefs.getHostname(); - final int port = _notificationsPrefs.getPort(); - final String protocol = _notificationsPrefs.getProtocol(); - final String username = _notificationsPrefs.getUsername(); - final String password = _notificationsPrefs.getPassword(); - - logConfigurationSubmit(host, port, protocol, username, password, properties); - - setHost(host, false); - setPort(port); - setProtocol(protocol); - setUsername(username); - setPassword(password); - - _javaMailSender.setJavaMailProperties(getSubmittedProperties(properties)); - } - return new ResponseEntity<>(HttpStatus.OK); } @ApiOperation(value = "Returns the full SMTP server configuration.", - notes = "Returns the configuration as a map of the standard Java mail sender properties–host, port, protocol, username, and password–along with any extended properties required for the configuration, e.g. configuring SSL- or TLS-secured SMTP services.", - response = Properties.class) + notes = "Returns the configuration as a map of the standard Java mail sender properties–host, port, protocol, username, and password–along with any extended properties required for the configuration, e.g. configuring SSL- or TLS-secured SMTP services.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "SMTP service configuration properties successfully retrieved."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set site configuration properties."), @@ -176,39 +153,18 @@ public class NotificationsApi extends AbstractXapiRestController { if (_log.isDebugEnabled()) { _log.debug("User " + getSessionUser().getUsername() + " requested the site SMTP service configuration."); } - final Properties properties = new Properties(); - properties.setProperty("host", _javaMailSender.getHost()); - final int port = _javaMailSender.getPort(); - if (port > 0) { - properties.setProperty("port", Integer.toString(port)); - } - final String protocol = _javaMailSender.getProtocol(); - if (StringUtils.isNotBlank(protocol)) { - properties.setProperty("protocol", protocol); - } - final String username = _javaMailSender.getUsername(); - if (StringUtils.isNotBlank(username)) { - properties.setProperty("username", username); - } - final String password = _javaMailSender.getPassword(); - if (StringUtils.isNotBlank(password)) { - properties.setProperty("password", password); - } - for (final String property : _javaMailSender.getJavaMailProperties().stringPropertyNames()) { - properties.setProperty(property, _javaMailSender.getJavaMailProperties().getProperty(property)); - } - return new ResponseEntity<>(properties, HttpStatus.OK); + return new ResponseEntity<>(_notificationsPrefs.getSmtpServer().asProperties(), HttpStatus.OK); } @ApiOperation(value = "Sets the mail service properties. This return the SMTP server configuration as it exists after being set.", - notes = POST_PROPERTIES_NOTES, - response = Properties.class) + notes = POST_PROPERTIES_NOTES, + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service properties successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service properties."), @ApiResponse(code = 500, message = "Unexpected error")}) @RequestMapping(value = {"smtp"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST}) - public ResponseEntity<Properties> setAllMailProperties(@ApiParam("The value to set for the email host.") @RequestParam(value = "host", required = false, defaultValue = NOT_SET) final String host, + public ResponseEntity<Properties> setAllMailProperties(@ApiParam("The value to set for the email host.") @RequestParam(value = "hostname", required = false, defaultValue = NOT_SET) final String hostname, @ApiParam("The value to set for the email port.") @RequestParam(value = "port", required = false, defaultValue = "-1") final int port, @ApiParam("The value to set for the email username.") @RequestParam(value = "username", required = false, defaultValue = NOT_SET) final String username, @ApiParam("The value to set for the email password.") @RequestParam(value = "password", required = false, defaultValue = NOT_SET) final String password, @@ -220,28 +176,22 @@ public class NotificationsApi extends AbstractXapiRestController { } cleanProperties(properties); - logConfigurationSubmit(host, port, username, password, protocol, properties); + logConfigurationSubmit(hostname, port, username, password, protocol, properties); - setHost(host, true); - setPort(port); - setProtocol(protocol); - setUsername(username); - setPassword(password); - - _javaMailSender.setJavaMailProperties(getSubmittedProperties(properties)); + _notificationsPrefs.setSmtpServer(new SmtpServer(hostname, port, protocol, username, password, properties)); return getSmtpServerProperties(); } @ApiOperation(value = "Sets the submitted mail service properties. This returns the SMTP server configuration as it exists after being set.", - notes = PUT_PROPERTIES_NOTES, - response = Properties.class) + notes = PUT_PROPERTIES_NOTES, + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service properties successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service properties."), @ApiResponse(code = 500, message = "Unexpected error")}) @RequestMapping(value = {"smtp"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.PUT}) - public ResponseEntity<Properties> setSubmittedMailProperties(@ApiParam("The value to set for the email host.") @RequestParam(value = "host", required = false, defaultValue = NOT_SET) final String host, + public ResponseEntity<Properties> setSubmittedMailProperties(@ApiParam("The value to set for the email host.") @RequestParam(value = "hostname", required = false, defaultValue = NOT_SET) final String host, @ApiParam("The value to set for the email port.") @RequestParam(value = "port", required = false, defaultValue = "-1") final int port, @ApiParam("The value to set for the email username.") @RequestParam(value = "username", required = false, defaultValue = NOT_SET) final String username, @ApiParam("The value to set for the email password.") @RequestParam(value = "password", required = false, defaultValue = NOT_SET) final String password, @@ -254,23 +204,14 @@ public class NotificationsApi extends AbstractXapiRestController { logConfigurationSubmit(host, port, username, password, protocol, properties); - setHost(host, false); - setPort(port); - setProtocol(protocol); - setUsername(username); - setPassword(password); - if (properties != null) { - for (final String property : properties.stringPropertyNames()) { - _javaMailSender.getJavaMailProperties().setProperty(property, properties.getProperty(property)); - } - } + _notificationsPrefs.setSmtpServer(new SmtpServer(host, port, username, password, protocol, properties)); return getSmtpServerProperties(); } @ApiOperation(value = "Sets the mail service host.", - notes = "Sets the mail service host.", - response = Properties.class) + notes = "Sets the mail service host.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service host successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service host."), @@ -284,13 +225,13 @@ public class NotificationsApi extends AbstractXapiRestController { if (_log.isInfoEnabled()) { _log.info("User " + getSessionUser().getLogin() + " setting mail host to: " + host); } - setHost(host, true); + _notificationsPrefs.setSmtpHostname(host); return getSmtpServerProperties(); } @ApiOperation(value = "Sets the mail service port.", - notes = "Sets the mail service port.", - response = Properties.class) + notes = "Sets the mail service port.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service port successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service port."), @@ -304,13 +245,13 @@ public class NotificationsApi extends AbstractXapiRestController { if (_log.isInfoEnabled()) { _log.info("User " + getSessionUser().getLogin() + " setting mail port to: " + port); } - setPort(port); + _notificationsPrefs.setSmtpPort(port); return getSmtpServerProperties(); } @ApiOperation(value = "Sets the mail service protocol.", - notes = "Sets the mail service protocol.", - response = Properties.class) + notes = "Sets the mail service protocol.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service protocol successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service protocol."), @@ -324,13 +265,13 @@ public class NotificationsApi extends AbstractXapiRestController { if (_log.isInfoEnabled()) { _log.info("User " + getSessionUser().getLogin() + " setting mail protocol to: " + protocol); } - setProtocol(protocol); + _notificationsPrefs.setSmtpProtocol(protocol); return getSmtpServerProperties(); } @ApiOperation(value = "Sets the mail service username.", - notes = "Sets the mail service username.", - response = Properties.class) + notes = "Sets the mail service username.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service username successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service username."), @@ -344,13 +285,13 @@ public class NotificationsApi extends AbstractXapiRestController { if (_log.isInfoEnabled()) { _log.info("User " + getSessionUser().getLogin() + " setting mail username to: " + username); } - setUsername(username); + _notificationsPrefs.setSmtpUsername(username); return getSmtpServerProperties(); } @ApiOperation(value = "Sets the mail service password.", - notes = "Sets the mail service password.", - response = Properties.class) + notes = "Sets the mail service password.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service password successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service password."), @@ -364,20 +305,56 @@ public class NotificationsApi extends AbstractXapiRestController { if (_log.isInfoEnabled()) { _log.info("User " + getSessionUser().getLogin() + " setting mail password to: ********"); } - setPassword(password); + _notificationsPrefs.setSmtpPassword(password); return getSmtpServerProperties(); } + @ApiOperation(value = "Gets the value for a specified Java mail property.", + notes = "The value is always returned as a string.", + response = String.class) + @ApiResponses({@ApiResponse(code = 200, message = "Property found and returned."), + @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), + @ApiResponse(code = 403, message = "Not authorized to set the mail service properties."), + @ApiResponse(code = 404, message = "Specified key not found in the mail service properties."), + @ApiResponse(code = 500, message = "Unexpected error")}) + @RequestMapping(value = {"smtp/property/{property}"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.GET}) + public ResponseEntity<String> getExtendedProperty(@ApiParam(value = "The mail property to be retrieved.", required = true) @PathVariable final String property) { + final HttpStatus status = isPermitted(); + if (status != null) { + return new ResponseEntity<>(status); + } + if (!_notificationsPrefs.getSmtpServer().getMailProperties().containsKey(property)) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + _log.info("User {} retrieving value for property {}", getSessionUser().getLogin(), property); + return new ResponseEntity<>(_notificationsPrefs.getSmtpMailProperty(property), HttpStatus.OK); + } + @ApiOperation(value = "Sets a Java mail property with the submitted name and value.", - notes = "Setting a property to an empty value will remove the property.", - response = Properties.class) + notes = "Setting a property to an existing value will overwrite the existing value. The value returned by this function contains the previous value (if any).", + response = String.class) + @ApiResponses({@ApiResponse(code = 200, message = "Property found and returned."), + @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), + @ApiResponse(code = 403, message = "Not authorized to set the mail service properties."), + @ApiResponse(code = 404, message = "Specified key not found in the mail service properties."), + @ApiResponse(code = 500, message = "Unexpected error")}) + @RequestMapping(value = {"smtp/property/{property}"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.PUT}) + public ResponseEntity<String> setExtendedProperty(@ApiParam(value = "The name of the extended mail property to set.", required = true) @PathVariable final String property, + @ApiParam(value = "The value to set for the extended mail property.", required = true) @RequestBody final String value) { + return setExtendedPropertyFromPath(property, value); + } + + @ApiOperation(value = "Sets a Java mail property with the submitted name and value.", + notes = "Setting a property to an existing value will overwrite the existing value. The value returned by this function contains the previous value (if any).", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Mail service password successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the mail service password."), + @ApiResponse(code = 404, message = "Specified key not found in the mail service properties."), @ApiResponse(code = 500, message = "Unexpected error")}) @RequestMapping(value = {"smtp/property/{property}/{value}"}, produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.PUT}) - public ResponseEntity<Properties> setExtendedProperty(@ApiParam(value = "The value to set for the email password.", required = true) @PathVariable final String property, - @ApiParam(value = "The value to set for the email password.", required = true) @PathVariable final String value) { + public ResponseEntity<String> setExtendedPropertyFromPath(@ApiParam(value = "The name of the extended mail property to set.", required = true) @PathVariable final String property, + @ApiParam(value = "The value to set for the extended mail property.", required = true) @PathVariable final String value) { final HttpStatus status = isPermitted(); if (status != null) { return new ResponseEntity<>(status); @@ -385,13 +362,33 @@ public class NotificationsApi extends AbstractXapiRestController { if (_log.isInfoEnabled()) { _log.info("User " + getSessionUser().getLogin() + " setting mail password to: ********"); } - setProperty(property, value); - return getSmtpServerProperties(); + return new ResponseEntity<>(_notificationsPrefs.setSmtpMailProperty(property, value), HttpStatus.OK); + } + + @ApiOperation(value = "Removes the value for a specified Java mail property.", + notes = "This completely removes the specified mail property. The value returned by this function contains the previous value (if any).", + response = String.class) + @ApiResponses({@ApiResponse(code = 200, message = "Property found and returned."), + @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), + @ApiResponse(code = 403, message = "Not authorized to set the mail service properties."), + @ApiResponse(code = 404, message = "Specified key not found in the mail service properties."), + @ApiResponse(code = 500, message = "Unexpected error")}) + @RequestMapping(value = "smtp/property/{property}", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.DELETE) + public ResponseEntity<String> removeExtendedProperty(@ApiParam(value = "The mail property to be removed.", required = true) @PathVariable final String property) { + final HttpStatus status = isPermitted(); + if (status != null) { + return new ResponseEntity<>(status); + } + if (!_notificationsPrefs.getSmtpServer().getMailProperties().containsKey(property)) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + _log.info("User {} removing value for property {}", getSessionUser().getLogin(), property); + return new ResponseEntity<>(_notificationsPrefs.removeSmtpMailProperty(property), HttpStatus.OK); } @ApiOperation(value = "Sets the email message for contacting help.", - notes = "Sets the email message that people should receive when contacting help.", - response = Void.class) + notes = "Sets the email message that people should receive when contacting help.", + response = Void.class) @ApiResponses({@ApiResponse(code = 200, message = "Help email message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the help email message."), @@ -403,8 +400,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets the email message for user registration.", - notes = "Sets the email message that people should receive when they register. Link for email validation is auto-populated.", - response = Properties.class) + notes = "Sets the email message that people should receive when they register. Link for email validation is auto-populated.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "User registration email message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the user registration email message."), @@ -416,8 +413,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets the email message for forgot username.", - notes = "Sets the email message that people should receive when they click that they forgot their username.", - response = Properties.class) + notes = "Sets the email message that people should receive when they click that they forgot their username.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Forgot username email message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the forgot username email message."), @@ -429,8 +426,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets the email message for password reset.", - notes = "Sets the email message that people should receive when they click to reset their password. Link for password reset is auto-populated.", - response = Properties.class) + notes = "Sets the email message that people should receive when they click to reset their password. Link for password reset is auto-populated.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Password reset message successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the password reset message."), @@ -442,8 +439,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns the email message for contacting help.", - notes = "This returns the email message that people should receive when contacting help.", - response = String.class) + notes = "This returns the email message that people should receive when contacting help.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for contacting help successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for contacting help."), @@ -454,8 +451,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns the email message for user registration.", - notes = "This returns the email message that people should receive when they register. Link for email validation is auto-populated.", - response = String.class) + notes = "This returns the email message that people should receive when they register. Link for email validation is auto-populated.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for user registration successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for user registration."), @@ -466,8 +463,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns the email message for forgot username.", - notes = "This returns the email message that people should receive when they click that they forgot their username.", - response = String.class) + notes = "This returns the email message that people should receive when they click that they forgot their username.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for forgot username successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for forgot username."), @@ -478,8 +475,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns the email message for password reset.", - notes = "This returns the email message that people should receive when they click to reset their password. Link for password reset is auto-populated.", - response = String.class) + notes = "This returns the email message that people should receive when they click to reset their password. Link for password reset is auto-populated.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for password reset successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for password reset."), @@ -490,8 +487,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets whether admins should be notified of user registration.", - notes = "Sets whether admins should be notified of user registration.", - response = Void.class) + notes = "Sets whether admins should be notified of user registration.", + response = Void.class) @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of user registration successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of user registration."), @@ -503,8 +500,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets whether admins should be notified of pipeline processing submit.", - notes = "Sets whether admins should be notified of pipeline processing submit.", - response = Properties.class) + notes = "Sets whether admins should be notified of pipeline processing submit.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of pipeline processing submit successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of pipeline processing submit."), @@ -516,8 +513,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets whether admins should be notified of project access requests.", - notes = "Sets whether admins should be notified of project access requests.", - response = Properties.class) + notes = "Sets whether admins should be notified of project access requests.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of project access requests successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of project access requests."), @@ -529,8 +526,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets whether admins should be notified of session transfer.", - notes = "Sets whether admins should be notified of session transfer by user.", - response = Properties.class) + notes = "Sets whether admins should be notified of session transfer by user.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Whether admins should be notified of session transfer successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether admins should be notified of session transfer."), @@ -542,8 +539,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns whether admins should be notified of user registration.", - notes = "This returns whether admins should be notified of user registration.", - response = Boolean.class) + notes = "This returns whether admins should be notified of user registration.", + response = Boolean.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for contacting help successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for contacting help."), @@ -554,8 +551,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns whether admins should be notified of pipeline processing submit.", - notes = "This returns whether admins should be notified of pipeline processing submit.", - response = Boolean.class) + notes = "This returns whether admins should be notified of pipeline processing submit.", + response = Boolean.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for user registration successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for user registration."), @@ -566,8 +563,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns whether admins should be notified of project access requests.", - notes = "This returns whether admins should be notified of project access requests.", - response = Boolean.class) + notes = "This returns whether admins should be notified of project access requests.", + response = Boolean.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for forgot username successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for forgot username."), @@ -578,8 +575,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns whether admins should be notified of session transfer.", - notes = "This returns whether admins should be notified of session transfer.", - response = Boolean.class) + notes = "This returns whether admins should be notified of session transfer.", + response = Boolean.class) @ApiResponses({@ApiResponse(code = 200, message = "Email message for password reset successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get email message for password reset."), @@ -590,8 +587,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets whether non-users should be able to subscribe to notifications.", - notes = "Sets whether non-users should be able to subscribe to notifications.", - response = Properties.class) + notes = "Sets whether non-users should be able to subscribe to notifications.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Whether non-users should be able to subscribe to notifications."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set whether non-users should be able to subscribe to notifications."), @@ -603,8 +600,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns whether non-users should be able to subscribe to notifications.", - notes = "This returns whether non-users should be able to subscribe to notifications.", - response = Boolean.class) + notes = "This returns whether non-users should be able to subscribe to notifications.", + response = Boolean.class) @ApiResponses({@ApiResponse(code = 200, message = "Whether non-users should be able to subscribe to notifications successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get whether non-users should be able to subscribe to notifications."), @@ -615,8 +612,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets the email addresses for error notifications.", - notes = "Sets the email addresses that should be subscribed to error notifications.", - response = Void.class) + notes = "Sets the email addresses that should be subscribed to error notifications.", + response = Void.class) @ApiResponses({@ApiResponse(code = 200, message = "Error subscribers successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the error subscribers."), @@ -628,8 +625,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets the email addresses for issue notifications.", - notes = "Sets the email addresses that should be subscribed to issue notifications.", - response = Properties.class) + notes = "Sets the email addresses that should be subscribed to issue notifications.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Issue subscribers successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the issue subscribers."), @@ -641,8 +638,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets the email addresses for new user notifications.", - notes = "Sets the email addresses that should be subscribed to new user notifications.", - response = Properties.class) + notes = "Sets the email addresses that should be subscribed to new user notifications.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "New user subscribers successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the new user subscribers."), @@ -654,8 +651,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Sets the email addresses for update notifications.", - notes = "Sets the email addresses that should be subscribed to update notifications.", - response = Properties.class) + notes = "Sets the email addresses that should be subscribed to update notifications.", + response = Properties.class) @ApiResponses({@ApiResponse(code = 200, message = "Update subscribers successfully set."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to set the update subscribers."), @@ -667,8 +664,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns list of email addresses subscribed to error notifications.", - notes = "This returns a list of all the email addresses that are subscribed to receive error notifications.", - response = String.class) + notes = "This returns a list of all the email addresses that are subscribed to receive error notifications.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Error notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @@ -679,8 +676,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns list of email addresses subscribed to issue notifications.", - notes = "This returns a list of all the email addresses that are subscribed to receive issue notifications.", - response = String.class) + notes = "This returns a list of all the email addresses that are subscribed to receive issue notifications.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Issue notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @@ -691,8 +688,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns list of email addresses subscribed to new user notifications.", - notes = "This returns a list of all the email addresses that are subscribed to receive new user notifications.", - response = String.class) + notes = "This returns a list of all the email addresses that are subscribed to receive new user notifications.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "New user notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @@ -703,8 +700,8 @@ public class NotificationsApi extends AbstractXapiRestController { } @ApiOperation(value = "Returns list of email addresses subscribed to update notifications.", - notes = "This returns a list of all the email addresses that are subscribed to receive update notifications.", - response = String.class) + notes = "This returns a list of all the email addresses that are subscribed to receive update notifications.", + response = String.class) @ApiResponses({@ApiResponse(code = 200, message = "Update notification subscribers successfully returned."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "Not authorized to get subscribers for email notifications."), @@ -714,51 +711,27 @@ public class NotificationsApi extends AbstractXapiRestController { return new ResponseEntity<>(_notificationsPrefs.getEmailRecipientUpdate(), HttpStatus.OK); } - protected Properties getSubmittedProperties(final Properties properties) { - // Set all of the submitted properties. - final Properties javaMailProperties = new Properties(); - if (properties != null) { - for (final String property : properties.stringPropertyNames()) { - final String value = properties.getProperty(property); - if (StringUtils.isNotBlank(value)) { - javaMailProperties.setProperty(property, value); - } - } - } - - // Find any existing properties that weren't submitted... - final Properties existing = _javaMailSender.getJavaMailProperties(); - for (final String property : existing.stringPropertyNames()) { - if (!javaMailProperties.containsKey(property)) { - // Set the value to "", this will remove the property. - javaMailProperties.setProperty(property, ""); - } - } - return javaMailProperties; - } - private Properties convertToProperties(final Map<String, Object> preferenceMap) throws IOException { final Properties properties = new Properties(); for (final String key : preferenceMap.keySet()) { - final Object object = preferenceMap.get(key); - String tempVal = ""; - if(object!=null){ - if(String.class.isAssignableFrom(object.getClass())){ - tempVal = (String)object; - } - else{ + final Object object = preferenceMap.get(key); + String tempVal = ""; + if (object != null) { + if (String.class.isAssignableFrom(object.getClass())) { + tempVal = (String) object; + } else { tempVal = _serializer.toJson(object); } } - final String value = tempVal; + final String value = tempVal; properties.setProperty(key, value); } return properties; } private void cleanProperties(final Properties properties) { - if (properties.containsKey("host")) { - properties.remove("host"); + if (properties.containsKey("hostname")) { + properties.remove("hostname"); } if (properties.containsKey("port")) { properties.remove("port"); @@ -772,47 +745,20 @@ public class NotificationsApi extends AbstractXapiRestController { if (properties.containsKey("password")) { properties.remove("password"); } - } - - private void setHost(final String host, final boolean freakOutIfBlank) { - if (freakOutIfBlank && StringUtils.isBlank(host)) { - throw new NrgServiceRuntimeException(NrgServiceError.ConfigurationError, "You can not set the SMTP server address to an empty value!"); - } - if (StringUtils.isNotBlank(host)) { - _javaMailSender.setHost(host); - } - } - - private void setPort(final int port) { - if (port != -1) { - _javaMailSender.setPort(port); + if (properties.containsKey("smtpHostname")) { + properties.remove("smtpHostname"); } - } - - private void setProtocol(final String protocol) { - if (!StringUtils.equals(NOT_SET, protocol)) { - _javaMailSender.setProtocol(protocol); + if (properties.containsKey("smtpPort")) { + properties.remove("smtpPort"); } - } - - private void setUsername(final String username) { - if (!StringUtils.equals(NOT_SET, username)) { - _javaMailSender.setUsername(username); + if (properties.containsKey("smtpProtocol")) { + properties.remove("smtpProtocol"); } - } - - private void setPassword(final String password) { - if (!StringUtils.equals(NOT_SET, password)) { - _javaMailSender.setPassword(password); + if (properties.containsKey("smtpUsername")) { + properties.remove("smtpUsername"); } - } - - private void setProperty(final String property, final String value) { - final Properties properties = _javaMailSender.getJavaMailProperties(); - if (properties.containsKey(property) && StringUtils.isBlank(value)) { - properties.remove(property); - } else { - properties.setProperty(property, value); + if (properties.containsKey("smtpPassword")) { + properties.remove("smtpPassword"); } } @@ -834,11 +780,10 @@ public class NotificationsApi extends AbstractXapiRestController { } } - private static final Logger _log = LoggerFactory.getLogger(NotificationsApi.class); - private static final String NOT_SET = "NotSet"; + private static final Logger _log = LoggerFactory.getLogger(NotificationsApi.class); + private static final String NOT_SET = "NotSet"; private final NotificationsPreferences _notificationsPrefs; - private final JavaMailSenderImpl _javaMailSender; private final XnatAppInfo _appInfo; private final SerializerService _serializer; } diff --git a/src/main/java/org/nrg/xapi/rest/settings/SiteConfigApi.java b/src/main/java/org/nrg/xapi/rest/settings/SiteConfigApi.java index b45ddd15..708cc462 100644 --- a/src/main/java/org/nrg/xapi/rest/settings/SiteConfigApi.java +++ b/src/main/java/org/nrg/xapi/rest/settings/SiteConfigApi.java @@ -13,14 +13,17 @@ import com.google.common.base.Joiner; import io.swagger.annotations.*; import org.apache.commons.lang3.StringUtils; import org.nrg.framework.annotations.XapiRestController; +import org.nrg.framework.exceptions.NrgServiceRuntimeException; import org.nrg.prefs.exceptions.InvalidPreferenceName; +import org.nrg.xapi.exceptions.ApiException; import org.nrg.xapi.exceptions.InitializationException; +import org.nrg.xapi.exceptions.InsufficientPrivilegesException; +import org.nrg.xapi.exceptions.NotFoundException; import org.nrg.xdat.preferences.SiteConfigPreferences; import org.nrg.xdat.rest.AbstractXapiRestController; import org.nrg.xdat.security.services.RoleHolder; import org.nrg.xdat.security.services.UserManagementServiceI; import org.nrg.xnat.services.XnatAppInfo; -import org.nrg.xnat.turbine.utils.ArcSpecManager; import org.nrg.xnat.utils.XnatHttpUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -102,7 +105,7 @@ public class SiteConfigApi extends AbstractXapiRestController { @ApiResponse(code = 403, message = "Not authorized to set site configuration properties."), @ApiResponse(code = 500, message = "Unexpected error")}) @RequestMapping(consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE}, method = RequestMethod.POST) - public ResponseEntity<Void> setSiteConfigProperties(@ApiParam(value = "The map of site configuration properties to be set.", required = true) @RequestBody final Map<String, String> properties) throws InitializationException { + public ResponseEntity<Void> setSiteConfigProperties(@ApiParam(value = "The map of site configuration properties to be set.", required = true) @RequestBody final Map<String, String> properties) throws ApiException, InitializationException { final HttpStatus status = isPermitted(); if (status != null) { return new ResponseEntity<>(status); @@ -116,6 +119,12 @@ public class SiteConfigApi extends AbstractXapiRestController { if (isInitializing && name.equals("initialized")) { continue; } + if (name.equals("receivedFileUser")) { + final HttpStatus setStatus = setReceivedFileUser(properties.get(name)); + if (setStatus != null) { + return new ResponseEntity<>(setStatus); + } + } _preferences.set(properties.get(name), name); if (_log.isInfoEnabled()) { _log.info("Set property {} to value: {}", name, properties.get(name)); @@ -127,10 +136,7 @@ public class SiteConfigApi extends AbstractXapiRestController { // If we're initializing... if (isInitializing) { - // Make the final initialization call. - initialize(); - - // Now make the initialized setting true. + // Now make the initialized setting true. This will kick off the initialized event handler. _preferences.setInitialized(true); } @@ -191,7 +197,8 @@ public class SiteConfigApi extends AbstractXapiRestController { @ApiResponse(code = 403, message = "Not authorized to set site configuration properties."), @ApiResponse(code = 500, message = "Unexpected error")}) @RequestMapping(value = "{property}", consumes = {MediaType.TEXT_PLAIN_VALUE, MediaType.APPLICATION_JSON_VALUE}, produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST) - public ResponseEntity<Void> setSiteConfigProperty(@ApiParam(value = "The property to be set.", required = true) @PathVariable("property") final String property, @ApiParam("The value to be set for the property.") @RequestBody final String value) throws InitializationException { + public ResponseEntity<Void> setSiteConfigProperty(@ApiParam(value = "The property to be set.", required = true) @PathVariable("property") final String property, + @ApiParam("The value to be set for the property.") @RequestBody final String value) throws InitializationException, ApiException { final HttpStatus status = isPermitted(); if (status != null) { return new ResponseEntity<>(status); @@ -202,8 +209,12 @@ public class SiteConfigApi extends AbstractXapiRestController { } if (StringUtils.equals("initialized", property) && StringUtils.equals("true", value)) { - initialize(); _preferences.setInitialized(true); + } else if (StringUtils.equals("receivedFileUser", property)) { + final HttpStatus setStatus = setReceivedFileUser(value); + if (setStatus != null) { + return new ResponseEntity<>(setStatus); + } } else { try { _preferences.set(value, property); @@ -268,6 +279,24 @@ public class SiteConfigApi extends AbstractXapiRestController { return new ResponseEntity<>(_appInfo.getFormattedUptime(), HttpStatus.OK); } + private HttpStatus setReceivedFileUser(final String value) throws InsufficientPrivilegesException, NotFoundException { + try { + _preferences.setReceivedFileUser(value); + } catch (NrgServiceRuntimeException e) { + switch (e.getServiceError()) { + case PermissionsViolation: + throw new InsufficientPrivilegesException(e.getMessage()); + case UserNotFoundError: + throw new NotFoundException("No user with the name " + e.getMessage() + " was found."); + case Unknown: + default: + _log.error("An unknown error occurred trying to set the received file user to value " + value, e); + return HttpStatus.INTERNAL_SERVER_ERROR; + } + } + return null; + } + private Map<String, Object> getPreferences() { if (!_hasFoundPreferences) { return _preferences.getPreferenceMap(); @@ -277,17 +306,6 @@ public class SiteConfigApi extends AbstractXapiRestController { return preferences; } - private void initialize() throws InitializationException { - // In the case where the application hasn't yet been initialized, this operation should mean that the system is - // being initialized from the set-up page. In that case, we need to propagate a few properties to the arc-spec - // persistence to support - try { - ArcSpecManager.initialize(getSessionUser()); - } catch (Exception e) { - throw new InitializationException(e); - } - } - private static final Logger _log = LoggerFactory.getLogger(SiteConfigApi.class); private final SiteConfigPreferences _preferences; diff --git a/src/main/java/org/nrg/xapi/rest/users/UsersApi.java b/src/main/java/org/nrg/xapi/rest/users/UsersApi.java index 248ccc1c..0f3412df 100644 --- a/src/main/java/org/nrg/xapi/rest/users/UsersApi.java +++ b/src/main/java/org/nrg/xapi/rest/users/UsersApi.java @@ -134,20 +134,30 @@ public class UsersApi extends AbstractXapiRestController { } else { username = principal.toString(); } - final Map<String, Object> sessionData = new HashMap<>(); final List<SessionInformation> sessions = _sessionRegistry.getAllSessions(principal, false); + + // Sometimes there are no sessions, which is weird but OK, we don't want to see those entries. + final int count = sessions.size(); + if (count == 0) { + continue; + } + + // Now add user with a session or more to the list of active users. final ArrayList<String> sessionIds = new ArrayList<>(); for (final SessionInformation session : sessions) { sessionIds.add(session.getSessionId()); } + + final Map<String, Object> sessionData = new HashMap<>(); sessionData.put("sessions", sessionIds); - sessionData.put("count", sessions.size()); + sessionData.put("count", count); + activeUsers.put(username, sessionData); } return new ResponseEntity<>(activeUsers, HttpStatus.OK); } - @ApiOperation(value = "Get information about active sessions for the indicated user.", notes = "Returns a map containing a list of session IDs usernames for users that have at least one currently active session, i.e. logged in or associated with a valid application session. This also includes the number of active sessions for each user.", response = String.class, responseContainer = "List") + @ApiOperation(value = "Get information about active sessions for the indicated user.", notes = "Returns a map containing a list of session IDs and usernames for users that have at least one currently active session, i.e. logged in or associated with a valid application session. This also includes the number of active sessions for each user.", response = String.class, responseContainer = "List") @ApiResponses({@ApiResponse(code = 200, message = "A list of active users."), @ApiResponse(code = 401, message = "Must be authenticated to access the XNAT REST API."), @ApiResponse(code = 403, message = "You do not have sufficient permissions to access the list of usernames."), diff --git a/src/main/java/org/nrg/xnat/archive/Transfer.java b/src/main/java/org/nrg/xnat/archive/Transfer.java index 367114e0..a8f6c11c 100644 --- a/src/main/java/org/nrg/xnat/archive/Transfer.java +++ b/src/main/java/org/nrg/xnat/archive/Transfer.java @@ -130,7 +130,7 @@ public class Transfer { xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user)); xnatPipelineLauncher.setParameter("adminemail", admin_email); xnatPipelineLauncher.setParameter("xnatserver", system); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); xnatPipelineLauncher.setParameter("sessionType", mr.getXSIType()); xnatPipelineLauncher.setParameter("xnat_project", mr.getProject()); xnatPipelineLauncher.setParameter("logDir", XDAT.getSiteConfigPreferences().getCachePath() + "logs" + "/" + "transfer"); diff --git a/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java b/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java index 188e2c98..9b98c513 100644 --- a/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java +++ b/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java @@ -18,6 +18,7 @@ import org.nrg.notify.renderers.ChannelRenderer; import org.nrg.notify.renderers.NrgMailChannelRenderer; import org.nrg.xdat.preferences.NotificationsPreferences; import org.nrg.xdat.preferences.SiteConfigPreferences; +import org.nrg.xdat.preferences.SmtpServer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -27,7 +28,6 @@ import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Properties; @Configuration @ComponentScan({"org.nrg.mail.services", "org.nrg.notify.services.impl", "org.nrg.notify.daos"}) @@ -35,20 +35,16 @@ public class NotificationsConfig { @Bean public JavaMailSenderImpl mailSender(final NotificationsPreferences preferences) throws IOException, SiteConfigurationException { - final Map<String, String> smtp = preferences.getSmtpServer(); + final SmtpServer smtp = preferences.getSmtpServer(); final JavaMailSenderImpl sender = new JavaMailSenderImpl(); if(smtp!=null) { - sender.setHost(StringUtils.defaultIfBlank(smtp.remove("host"), "localhost")); - sender.setPort(Integer.parseInt(StringUtils.defaultIfBlank(smtp.remove("port"), "25"))); - sender.setUsername(StringUtils.defaultIfBlank(smtp.remove("username"), "")); - sender.setPassword(StringUtils.defaultIfBlank(smtp.remove("password"), "")); - sender.setProtocol(StringUtils.defaultIfBlank(smtp.remove("protocol"), "smtp")); - if (smtp.size() > 0) { - final Properties properties = new Properties(); - for (final String property : smtp.keySet()) { - properties.setProperty(property, smtp.get(property)); - } - sender.setJavaMailProperties(properties); + sender.setHost(StringUtils.defaultIfBlank(smtp.getHostname(), "localhost")); + sender.setPort(smtp.getPort()); + sender.setUsername(StringUtils.defaultIfBlank(smtp.getUsername(), "")); + sender.setPassword(StringUtils.defaultIfBlank(smtp.getPassword(), "")); + sender.setProtocol(StringUtils.defaultIfBlank(smtp.getProtocol(), "smtp")); + if (smtp.getMailProperties().size() > 0) { + sender.setJavaMailProperties(smtp.getMailProperties()); } } return sender; diff --git a/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java b/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java index 2c6e1578..8262729f 100644 --- a/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java +++ b/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java @@ -9,26 +9,19 @@ package org.nrg.xnat.configuration; -import org.nrg.config.exceptions.SiteConfigurationException; import org.nrg.config.services.ConfigService; -import org.nrg.config.services.SiteConfigurationService; import org.nrg.config.services.UserConfigurationService; import org.nrg.config.services.impl.DefaultConfigService; import org.nrg.config.services.impl.DefaultUserConfigurationService; import org.nrg.prefs.configuration.NrgPrefsConfiguration; -import org.nrg.prefs.services.NrgPreferenceService; import org.nrg.prefs.services.PreferenceService; -import org.nrg.xdat.preferences.SiteConfigPreferences; import org.nrg.xnat.resolvers.XnatPreferenceEntityResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.core.env.Environment; import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; @Configuration @ComponentScan("org.nrg.config.daos") @@ -45,26 +38,6 @@ public class PreferencesConfig { return new DefaultUserConfigurationService(configService()); } - @Bean - public SiteConfigurationService siteConfigurationService(final SiteConfigPreferences preferences, final NrgPreferenceService nrgPreferenceService, final ConfigService configService, final Environment environment) throws ClassNotFoundException, IllegalAccessException, InstantiationException, SiteConfigurationException { - final Class<? extends SiteConfigurationService> clazz = Class.forName(preferences.getSiteConfigurationService()).asSubclass(SiteConfigurationService.class); - try { - @SuppressWarnings("unchecked") - final Constructor<? extends SiteConfigurationService> constructor = clazz.getConstructor(NrgPreferenceService.class, Environment.class); - return constructor.newInstance(nrgPreferenceService, environment); - } catch (NoSuchMethodException | InvocationTargetException ignored) { - // No worries, it just doesn't have that constructor. - } - try { - @SuppressWarnings("unchecked") - final Constructor<? extends SiteConfigurationService> constructor = clazz.getConstructor(ConfigService.class, Environment.class); - return constructor.newInstance(configService, environment); - } catch (NoSuchMethodException | InvocationTargetException ignored) { - // No worries, it just doesn't have that constructor. - } - return clazz.newInstance(); - } - @Bean public XnatPreferenceEntityResolver defaultResolver(final PreferenceService preferenceService) throws IOException { return new XnatPreferenceEntityResolver(preferenceService); diff --git a/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java b/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java index d867e03f..21a34ed9 100644 --- a/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java +++ b/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java @@ -71,12 +71,12 @@ public class SchedulerConfig implements SchedulingConfigurer { _service.triggerEvent(new PreferenceEvent("inactivityBeforeLockout", String.valueOf(_siteConfigPreferences.getInactivityBeforeLockout()))); _service.triggerEvent(new PreferenceEvent("maxFailedLoginsLockoutDuration", String.valueOf(_siteConfigPreferences.getMaxFailedLoginsLockoutDuration()))); _service.triggerEvent(new PreferenceEvent("emailPrefix", String.valueOf(_notificationsPreferences.getEmailPrefix()))); - _service.triggerEvent(new PreferenceEvent("host", String.valueOf(_notificationsPreferences.getHostname()))); + _service.triggerEvent(new PreferenceEvent("smtpHostname", String.valueOf(_notificationsPreferences.getSmtpHostname()))); _service.triggerEvent(new PreferenceEvent("requireLogin", String.valueOf(_siteConfigPreferences.getRequireLogin()))); - _service.triggerEvent(new PreferenceEvent("security.channel", String.valueOf(_siteConfigPreferences.getSecurityChannel()))); + _service.triggerEvent(new PreferenceEvent("securityChannel", String.valueOf(_siteConfigPreferences.getSecurityChannel()))); _service.triggerEvent(new PreferenceEvent("passwordExpirationType", String.valueOf(_siteConfigPreferences.getPasswordExpirationType()))); _service.triggerEvent(new PreferenceEvent("archivePath", String.valueOf(_siteConfigPreferences.getArchivePath()))); - _service.triggerEvent(new PreferenceEvent("security.services.role.default", String.valueOf(_siteConfigPreferences.getRoleService()))); + _service.triggerEvent(new PreferenceEvent("roleService", String.valueOf(_siteConfigPreferences.getRoleService()))); _service.triggerEvent(new PreferenceEvent("checksums", String.valueOf(_siteConfigPreferences.getChecksums()))); _service.triggerEvent(new PreferenceEvent("sitewidePetTracers", String.valueOf(_siteConfigPreferences.getSitewidePetTracers()))); diff --git a/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java b/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java index 6e29b30a..3af8c555 100644 --- a/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java +++ b/src/main/java/org/nrg/xnat/event/listeners/SiteConfigPreferenceHandler.java @@ -9,8 +9,6 @@ package org.nrg.xnat.event.listeners; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.nrg.prefs.events.AbstractPreferenceHandler; import org.nrg.prefs.events.PreferenceHandlerMethod; import org.nrg.xdat.preferences.PreferenceEvent; @@ -24,35 +22,31 @@ import java.util.List; @Service public class SiteConfigPreferenceHandler extends AbstractPreferenceHandler<PreferenceEvent> { - private String _toolId=SiteConfigPreferences.SITE_CONFIG_TOOL_ID; - private final List<PreferenceHandlerMethod> _methods = new ArrayList<>(); - - @Inject - public SiteConfigPreferenceHandler(final EventBus eventBus){ - super(eventBus); - } - - @Override - public String getToolId() { - return _toolId; - } - - @Override - public void setToolId(String toolId) { - _toolId=toolId; - } - - @Override - public List<PreferenceHandlerMethod> getMethods(){ - return _methods; - } - - @Override - public void addMethod(PreferenceHandlerMethod method){ - _methods.add(method); - } - - private static final Log _log = LogFactory.getLog(SiteConfigPreferenceHandler.class); - - + private String _toolId = SiteConfigPreferences.SITE_CONFIG_TOOL_ID; + private final List<PreferenceHandlerMethod> _methods = new ArrayList<>(); + + @Inject + public SiteConfigPreferenceHandler(final EventBus eventBus) { + super(eventBus); + } + + @Override + public String getToolId() { + return _toolId; + } + + @Override + public void setToolId(String toolId) { + _toolId = toolId; + } + + @Override + public List<PreferenceHandlerMethod> getMethods() { + return _methods; + } + + @Override + public void addMethod(PreferenceHandlerMethod method) { + _methods.add(method); + } } diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/FeatureServicesHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/FeatureServicesHandlerMethod.java index a3f8a091..4e682c48 100644 --- a/src/main/java/org/nrg/xnat/event/listeners/methods/FeatureServicesHandlerMethod.java +++ b/src/main/java/org/nrg/xnat/event/listeners/methods/FeatureServicesHandlerMethod.java @@ -11,8 +11,6 @@ package org.nrg.xnat.event.listeners.methods; import com.google.common.collect.ImmutableList; import org.nrg.xdat.security.helpers.Features; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.Arrays; @@ -46,7 +44,6 @@ public class FeatureServicesHandlerMethod extends AbstractSiteConfigPreferenceHa Features.setFeatureRepositoryServiceToSiteConfigPreference(); } - private static final Logger _log = LoggerFactory.getLogger(FeatureServicesHandlerMethod.class); - private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("security.services.feature.default", "security.services.featureRepository.default")); + private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("featureService", "featureRepositoryService")); } diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/InitializedHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/InitializedHandlerMethod.java new file mode 100644 index 00000000..ea96b98c --- /dev/null +++ b/src/main/java/org/nrg/xnat/event/listeners/methods/InitializedHandlerMethod.java @@ -0,0 +1,106 @@ +/* + * web: org.nrg.xnat.event.listeners.methods.RequiredChannelHandlerMethod + * XNAT http://www.xnat.org + * Copyright (c) 2016, Washington University School of Medicine and Howard Hughes Medical Institute + * All Rights Reserved + * + * Released under the Simplified BSD. + */ + +package org.nrg.xnat.event.listeners.methods; + +import com.google.common.collect.ImmutableList; +import org.nrg.framework.exceptions.NrgServiceError; +import org.nrg.framework.exceptions.NrgServiceRuntimeException; +import org.nrg.xapi.exceptions.InitializationException; +import org.nrg.xdat.preferences.SiteConfigPreferences; +import org.nrg.xnat.turbine.utils.ArcSpecManager; +import org.nrg.xnat.utils.XnatUserProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +@Component +public class InitializedHandlerMethod extends AbstractSiteConfigPreferenceHandlerMethod { + @Autowired + public InitializedHandlerMethod(final SiteConfigPreferences preferences, final XnatUserProvider primaryAdminUserProvider) { + super(primaryAdminUserProvider); + _preferences = preferences; + } + + @Override + public List<String> getHandledPreferences() { + return PREFERENCES; + } + + @Override + public void handlePreferences(final Map<String, String> values) { + if (values.containsKey(INITIALIZED)) { + handlePreference(INITIALIZED, values.get(INITIALIZED)); + } + } + + @Override + public void handlePreference(final String preference, final String value) { + if (PREFERENCES.contains(preference)) { + try { + initialize(); + } catch (InitializationException e) { + throw new NrgServiceRuntimeException(NrgServiceError.Unknown, "An error occurred attempting to complete system initialization", e); + } + } + } + + private void initialize() throws InitializationException { + final String adminEmail = _preferences.getAdminEmail(); + final String archivePath = _preferences.getArchivePath(); + final String buildPath = _preferences.getBuildPath(); + final String cachePath = _preferences.getCachePath(); + final boolean enableCsrfToken = _preferences.getEnableCsrfToken(); + final String ftpPath = _preferences.getFtpPath(); + final String pipelinePath = _preferences.getPipelinePath(); + final String prearchivePath = _preferences.getPrearchivePath(); + final boolean requireLogin = _preferences.getRequireLogin(); + final String siteId = _preferences.getSiteId(); + final String siteUrl = _preferences.getSiteUrl(); + final boolean userRegistration = _preferences.getUserRegistration(); + + // TODO: We may actually need to put a null check in here and make this a Future that circles back once everything is properly initialized. + final StringBuilder buffer = new StringBuilder("Preparing to complete system initialization with the final property settings of:").append(System.lineSeparator()); + buffer.append(" * adminEmail: ").append(adminEmail).append(System.lineSeparator()); + buffer.append(" * archivePath: ").append(archivePath).append(System.lineSeparator()); + buffer.append(" * buildPath: ").append(buildPath).append(System.lineSeparator()); + buffer.append(" * cachePath: ").append(cachePath).append(System.lineSeparator()); + buffer.append(" * enableCsrfToken: ").append(enableCsrfToken).append(System.lineSeparator()); + buffer.append(" * ftpPath: ").append(ftpPath).append(System.lineSeparator()); + buffer.append(" * pipelinePath: ").append(pipelinePath).append(System.lineSeparator()); + buffer.append(" * prearchivePath: ").append(prearchivePath).append(System.lineSeparator()); + buffer.append(" * requireLogin: ").append(requireLogin).append(System.lineSeparator()); + buffer.append(" * siteId: ").append(siteId).append(System.lineSeparator()); + buffer.append(" * siteUrl: ").append(siteUrl).append(System.lineSeparator()); + buffer.append(" * userRegistration: ").append(userRegistration).append(System.lineSeparator()); + + _log.info(buffer.toString()); + + // In the case where the application hasn't yet been initialized, this operation should mean that the system is + // being initialized from the set-up page. In that case, we need to propagate a few properties to the arc-spec + // persistence to support + try { + ArcSpecManager.initialize(getAdminUser()); + } catch (Exception e) { + throw new InitializationException(e); + } + } + + private static final Logger _log = LoggerFactory.getLogger(InitializedHandlerMethod.class); + + private static final String INITIALIZED = "initialized"; + private static final List<String> PREFERENCES = ImmutableList.copyOf(Collections.singletonList(INITIALIZED)); + + private final SiteConfigPreferences _preferences; +} diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/RequiredChannelHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/RequiredChannelHandlerMethod.java index 87950b79..287d41d7 100644 --- a/src/main/java/org/nrg/xnat/event/listeners/methods/RequiredChannelHandlerMethod.java +++ b/src/main/java/org/nrg/xnat/event/listeners/methods/RequiredChannelHandlerMethod.java @@ -50,7 +50,7 @@ public class RequiredChannelHandlerMethod extends AbstractSiteConfigPreferenceHa _filter.setRequiredChannel(_preferences.getSecurityChannel()); } - private static final List<String> PREFERENCES = ImmutableList.copyOf(Collections.singletonList("security.channel")); + private static final List<String> PREFERENCES = ImmutableList.copyOf(Collections.singletonList("securityChannel")); private final SiteConfigPreferences _preferences; private final TranslatingChannelProcessingFilter _filter; diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/RoleServicesHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/RoleServicesHandlerMethod.java index 2299b72f..0c503241 100644 --- a/src/main/java/org/nrg/xnat/event/listeners/methods/RoleServicesHandlerMethod.java +++ b/src/main/java/org/nrg/xnat/event/listeners/methods/RoleServicesHandlerMethod.java @@ -77,7 +77,7 @@ public class RoleServicesHandlerMethod extends AbstractSiteConfigPreferenceHandl } private static final Logger _log = LoggerFactory.getLogger(RoleServicesHandlerMethod.class); - private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("security.services.role.default", "security.services.roleRepository.default")); + private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("roleService", "roleRepositoryService")); private final SiteConfigPreferences _preferences; private final RoleHolder _roleHolder; diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/SmtpHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/SmtpHandlerMethod.java index 296967f0..e21fd61e 100644 --- a/src/main/java/org/nrg/xnat/event/listeners/methods/SmtpHandlerMethod.java +++ b/src/main/java/org/nrg/xnat/event/listeners/methods/SmtpHandlerMethod.java @@ -10,8 +10,9 @@ package org.nrg.xnat.event.listeners.methods; import com.google.common.collect.ImmutableList; -import org.nrg.mail.services.MailService; +import org.apache.commons.lang.StringUtils; import org.nrg.xdat.preferences.NotificationsPreferences; +import org.nrg.xdat.preferences.SmtpServer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.stereotype.Component; @@ -21,10 +22,9 @@ import java.util.*; @Component public class SmtpHandlerMethod extends AbstractNotificationsPreferenceHandlerMethod { @Autowired - public SmtpHandlerMethod(final NotificationsPreferences preferences, final JavaMailSenderImpl mailSender, final MailService mailService) { + public SmtpHandlerMethod(final NotificationsPreferences preferences, final JavaMailSenderImpl mailSender) { _preferences = preferences; - this._mailSender = mailSender; - _mailService = mailService; + _mailSender = mailSender; } @Override @@ -34,48 +34,44 @@ public class SmtpHandlerMethod extends AbstractNotificationsPreferenceHandlerMet @Override public void handlePreferences(final Map<String, String> values) { - if (!Collections.disjoint(PREFERENCES, values.keySet())) { - updateSmtp(); - } + updateSmtp(); } @Override public void handlePreference(final String preference, final String value) { - if (PREFERENCES.contains(preference)) { - updateSmtp(); - } + updateSmtp(); } private void updateSmtp() { - final Properties oldMailProperties = _mailSender.getJavaMailProperties(); - - final boolean smtpEnabled = _preferences.getSmtpEnabled(); - final boolean smtpAuth = _preferences.getSmtpAuth(); - final boolean startTls = _preferences.getSmtpStartTls(); - final String sslTrust = _preferences.getSmtpSSLTrust(); - - _mailSender.setHost(_preferences.getHostname()); - _mailSender.setPort(_preferences.getPort()); - _mailSender.setUsername(_preferences.getUsername()); - _mailSender.setPassword(_preferences.getPassword()); - _mailSender.setProtocol(_preferences.getProtocol()); - _mailService.setSmtpEnabled(smtpEnabled); - - oldMailProperties.setProperty("smtp.enabled", String.valueOf(smtpEnabled)); - oldMailProperties.setProperty("mail.smtp.auth", String.valueOf(smtpAuth)); - oldMailProperties.setProperty("mail.smtp.starttls.enable", String.valueOf(startTls)); - - if (sslTrust != null) { - oldMailProperties.setProperty("mail.smtp.ssl.trust", sslTrust); + final SmtpServer smtpServer = _preferences.getSmtpServer(); + + _mailSender.setHost(smtpServer.getHostname()); + _mailSender.setPort(smtpServer.getPort()); + _mailSender.setUsername(smtpServer.getUsername()); + _mailSender.setPassword(smtpServer.getPassword()); + _mailSender.setProtocol(smtpServer.getProtocol()); + + if (!smtpServer.getSmtpAuth()) { + _mailSender.setJavaMailProperties(SMTP_AUTH_DISABLED); + } else { + final Properties properties = new Properties(); + properties.setProperty(SmtpServer.SMTP_KEY_AUTH, "true"); + if (smtpServer.getSmtpStartTls()) { + properties.setProperty(SmtpServer.SMTP_KEY_STARTTLS_ENABLE, "true"); + } + if (StringUtils.isNotBlank(smtpServer.getSmtpSslTrust())) { + properties.setProperty(SmtpServer.SMTP_KEY_SSL_TRUST, smtpServer.getSmtpSslTrust()); + } + properties.putAll(smtpServer.getMailProperties()); + _mailSender.setJavaMailProperties(properties); } - - _mailSender.setJavaMailProperties(oldMailProperties); } - private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("smtp.enabled", "host", "port", "username", "password", "protocol", "smtp.enabled", "mail.smtp.auth", "mail.smtp.starttls.enable", "mail.smtp.ssl.trust")); + private static final List<String> PREFERENCES = ImmutableList.copyOf(Arrays.asList("smtpEnabled", "smtpHostname", "smtpPort", "smtpUsername", "smtpPassword", "smtpProtocol", "smtpAuth", "smtpStartTls", "smtpSslTrust")); + private static final Properties SMTP_AUTH_DISABLED = new Properties() {{ + setProperty(SmtpServer.SMTP_KEY_AUTH, "false"); + }}; private final NotificationsPreferences _preferences; private final JavaMailSenderImpl _mailSender; - private final MailService _mailService; - } diff --git a/src/main/java/org/nrg/xnat/event/listeners/methods/XnatUserProviderPreferenceHandlerMethod.java b/src/main/java/org/nrg/xnat/event/listeners/methods/XnatUserProviderPreferenceHandlerMethod.java new file mode 100644 index 00000000..91807ce7 --- /dev/null +++ b/src/main/java/org/nrg/xnat/event/listeners/methods/XnatUserProviderPreferenceHandlerMethod.java @@ -0,0 +1,52 @@ +/* + * web: org.nrg.xnat.event.listeners.methods.ReceivedFileUserPreferenceHandlerMethod + * XNAT http://www.xnat.org + * Copyright (c) 2016, Washington University School of Medicine + * All Rights Reserved + * + * Released under the Simplified BSD. + */ + +package org.nrg.xnat.event.listeners.methods; + +import com.google.common.collect.Maps; +import org.apache.commons.lang3.StringUtils; +import org.nrg.xnat.utils.XnatUserProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Component +public class XnatUserProviderPreferenceHandlerMethod extends AbstractSiteConfigPreferenceHandlerMethod { + @Autowired + public XnatUserProviderPreferenceHandlerMethod(final Map<String, XnatUserProvider> providers) { + _providers = Maps.newHashMap(providers); + } + + @Override + public List<String> getHandledPreferences() { + return new ArrayList<>(_providers.keySet()); + } + + @Override + public void handlePreferences(final Map<String, String> values) { + for (final String key : values.keySet()) { + handlePreference(key, values.get(key)); + } + } + + @Override + public void handlePreference(final String preference, final String value) { + if (_providers.containsKey(preference)) { + final XnatUserProvider provider = _providers.get(preference); + if (!StringUtils.equals(value, provider.getLogin())) { + provider.setLogin(value); + } + } + } + + private final Map<String, XnatUserProvider> _providers; +} diff --git a/src/main/java/org/nrg/xnat/helpers/prearchive/PrearcUtils.java b/src/main/java/org/nrg/xnat/helpers/prearchive/PrearcUtils.java index dd82e99f..2850af58 100644 --- a/src/main/java/org/nrg/xnat/helpers/prearchive/PrearcUtils.java +++ b/src/main/java/org/nrg/xnat/helpers/prearchive/PrearcUtils.java @@ -15,6 +15,7 @@ import org.apache.commons.io.filefilter.DirectoryFileFilter; import org.apache.commons.lang3.StringUtils; import org.nrg.config.entities.Configuration; import org.nrg.framework.constants.Scope; +import org.nrg.xapi.exceptions.InsufficientPrivilegesException; import org.nrg.xdat.XDAT; import org.nrg.xdat.model.ArcProjectI; import org.nrg.xdat.om.ArcProject; @@ -223,12 +224,11 @@ public class PrearcUtils { public static File getPrearcDir(final UserI user, final String project, final boolean allowUnassigned) throws Exception { String prearcPath; String prearchRootPref = XDAT.getSiteConfigPreferences().getPrearchivePath(); - String prearchRootArcSpec = ArcSpecManager.GetInstance().getGlobalPrearchivePath(); if (project == null || project.equals(COMMON)) { if (allowUnassigned || user == null || Roles.isSiteAdmin(user)) { prearcPath = prearchRootPref; } else { - throw new InvalidPermissionException("user " + user.getUsername() + " does not have permission to access the Unassigned directory "); + throw new InsufficientPrivilegesException(user.getUsername()); } } else { //Refactored to remove unnecessary database hits. It only needs to hit the xnat_projectdata table if the query is using a project alias rather than a project id. TO @@ -306,8 +306,8 @@ public class PrearcUtils { * @param project If the project is null, it is the unassigned project * project abbreviation or alias * @return true if the user has permissions to access the project, false otherwise - * @throws Exception - * @throws IOException + * @throws Exception When something goes wrong. + * @throws IOException When an error occurs reading or writing data. */ @SuppressWarnings("unused") public static boolean validUser(final UserI user, final String project, final boolean allowUnassigned) throws Exception { @@ -525,7 +525,7 @@ public class PrearcUtils { } public static String makeUri(final String urlBase, final String timestamp, final String folderName) { - return StringUtils.join(new String[]{urlBase, "/", timestamp, "/", folderName}); + return StringUtils.join(urlBase, "/", timestamp, "/", folderName); } public static Map<String, Object> parseURI(final String uri) throws MalformedURLException { @@ -533,7 +533,7 @@ public class PrearcUtils { } public static String buildURI(final String project, final String timestamp, final String folderName) { - return StringUtils.join(new String[]{"/prearchive/projects/", (project == null) ? PrearcUtils.COMMON : project, "/", timestamp, "/", folderName}); + return StringUtils.join("/prearchive/projects/", (project == null) ? PrearcUtils.COMMON : project, "/", timestamp, "/", folderName); } public static XFTTable convertArrayLtoTable(ArrayList<ArrayList<Object>> rows) { @@ -809,8 +809,8 @@ public class PrearcUtils { * @param session The session to be locked. * @param filename The filename to be locked. * @return PrearcFileLock - * @throws SessionFileLockException - * @throws IOException + * @throws SessionFileLockException When an attempt is made to access a locked file. + * @throws IOException When an error occurs reading or writing data. */ public static PrearcFileLock lockFile(final SessionDataTriple session, final String filename) throws SessionFileLockException, IOException { //putting these in a subdirectory of the cache space @@ -858,19 +858,26 @@ public class PrearcUtils { synchronized (syncLock) { //synchronized to prevent overlap with .lockFile() - if (name.exists() && (name.list() == null || name.list().length == 0)) { - try { - FileUtils.deleteDirectory(name); - - if (timestamp.exists() && (timestamp.list() == null || timestamp.list().length == 0)) { - FileUtils.deleteDirectory(timestamp); - - if (project.exists() && (project.list() == null || project.list().length == 0)) { - FileUtils.deleteDirectory(project); + if (name.exists()) { + final String[] names = name.list(); + if (names == null || names.length == 0) { + try { + FileUtils.deleteDirectory(name); + if (timestamp.exists()) { + final String[] timestamps = timestamp.list(); + if (timestamps == null || timestamps.length == 0) { + FileUtils.deleteDirectory(timestamp); + if (project.exists()) { + final String[] projects = project.list(); + if (projects == null || projects.length == 0) { + FileUtils.deleteDirectory(project); + } + } + } } + } catch (IOException e) { + logger.error("Couldn't clean temporary lock directories in the cache folder.", e); } - } catch (IOException e) { - logger.error("Couldn't clean temporary lock directories in the cache folder.", e); } } } diff --git a/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java b/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java index e3570b3b..a30abd94 100644 --- a/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java +++ b/src/main/java/org/nrg/xnat/restlet/actions/TriggerPipelines.java @@ -64,7 +64,7 @@ public class TriggerPipelines implements Callable<Boolean> { xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user)); xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); xnatPipelineLauncher.setParameter("sessionType", expt.getXSIType()); xnatPipelineLauncher.setParameter("xnat_project", expt.getProject()); diff --git a/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java b/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java index a3cf5b56..d2d064b1 100644 --- a/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java +++ b/src/main/java/org/nrg/xnat/restlet/resources/ProjtExptPipelineResource.java @@ -279,7 +279,7 @@ public class ProjtExptPipelineResource extends SecureResource { hasParams.add("userfullname"); xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); hasParams.add("adminemail"); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); hasParams.add("mailhost"); xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); hasParams.add("xnatserver"); @@ -394,7 +394,7 @@ public class ProjtExptPipelineResource extends SecureResource { xnatPipelineLauncher.setParameter("useremail", user.getEmail()); xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user)); xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); diff --git a/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java b/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java index 74253496..7dd6b042 100644 --- a/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java +++ b/src/main/java/org/nrg/xnat/turbine/modules/actions/ManagePipeline.java @@ -379,7 +379,7 @@ public class ManagePipeline extends SecureAction { xnatPipelineLauncher.setParameter("useremail", user.getEmail()); xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user)); xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); xnatPipelineLauncher.setPipelineName(pipeline_path); String exptLabel = item.getStringProperty("label"); diff --git a/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java b/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java index 46433009..208a02ea 100644 --- a/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java +++ b/src/main/java/org/nrg/xnat/turbine/modules/actions/PipelineActions.java @@ -204,7 +204,7 @@ public class PipelineActions extends SecureAction{ xnatPipelineLauncher.setParameter("userfullname", XnatPipelineLauncher.getUserName(user)); xnatPipelineLauncher.setParameter("adminemail", XDAT.getSiteConfigPreferences().getAdminEmail()); xnatPipelineLauncher.setParameter("xnatserver", TurbineUtils.GetSystemName()); - xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + xnatPipelineLauncher.setParameter("mailhost", XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); String emailsStr = ((String)org.nrg.xdat.turbine.utils.TurbineUtils.GetPassedParameter("emailField",data)); if (emailsStr != null) { diff --git a/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java b/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java index d753fc8f..0888c646 100644 --- a/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java +++ b/src/main/java/org/nrg/xnat/turbine/modules/actions/QDECAction.java @@ -208,7 +208,7 @@ public class QDECAction extends ListingAction{ param = parameters.addNewParameter(); param.setName("mailhost"); - param.addNewValues().setUnique( XDAT.getNotificationsPreferences().getSmtpServer().get("host")); + param.addNewValues().setUnique( XDAT.getNotificationsPreferences().getSmtpServer().getHostname()); return parameters; diff --git a/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java b/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java index a5a704ab..2f9bdc18 100644 --- a/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java +++ b/src/main/java/org/nrg/xnat/turbine/utils/ArcSpecManager.java @@ -15,6 +15,7 @@ import org.nrg.xdat.model.ArcProjectI; import org.nrg.xdat.om.ArcArchivespecification; import org.nrg.xdat.preferences.NotificationsPreferences; import org.nrg.xdat.preferences.SiteConfigPreferences; +import org.nrg.xdat.preferences.SmtpServer; import org.nrg.xft.event.EventDetails; import org.nrg.xft.event.EventUtils; import org.nrg.xft.security.UserI; @@ -31,7 +32,6 @@ import java.io.IOException; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import java.util.Map; /** * @author timo @@ -65,7 +65,9 @@ public class ArcSpecManager { String cachePath = arcSpec.getGlobalCachePath(); if (cachePath!=null){ File f = new File(cachePath,"archive_specification.xml"); - f.getParentFile().mkdirs(); + if (!f.getParentFile().mkdirs()) { + throw new RuntimeException("Failed to create working file " + f.getAbsolutePath() + ", please check permissions and file system."); + } FileWriter fw = new FileWriter(f); arcSpec.toXML(fw, true); @@ -120,12 +122,11 @@ public class ArcSpecManager { arcSpec.setSiteUrl(siteConfigPreferences.getSiteUrl()); } - final Map<String, String> smtpServer = notificationsPreferences.getSmtpServer(); - if (smtpServer != null && smtpServer.containsKey("host")) { - if (logger.isInfoEnabled()) { - logger.info("Setting SMTP host to: {}", smtpServer.get("host")); - } - arcSpec.setSmtpHost(smtpServer.get("host")); + final SmtpServer smtpServer = notificationsPreferences.getSmtpServer(); + if (smtpServer != null) { + final String hostname = smtpServer.getHostname(); + logger.info("Setting SMTP host to: {}", hostname); + arcSpec.setSmtpHost(hostname); } if (logger.isInfoEnabled()) { diff --git a/src/main/java/org/nrg/xnat/utils/XnatUserProvider.java b/src/main/java/org/nrg/xnat/utils/XnatUserProvider.java index 0314d6fa..ad38c9ab 100644 --- a/src/main/java/org/nrg/xnat/utils/XnatUserProvider.java +++ b/src/main/java/org/nrg/xnat/utils/XnatUserProvider.java @@ -9,6 +9,7 @@ package org.nrg.xnat.utils; +import org.apache.commons.lang3.StringUtils; import org.nrg.framework.exceptions.NrgServiceError; import org.nrg.framework.exceptions.NrgServiceRuntimeException; import org.nrg.xdat.security.helpers.Users; @@ -27,7 +28,8 @@ import javax.inject.Provider; @Component public class XnatUserProvider implements Provider<UserI> { public XnatUserProvider(final String login) { - _login = login; + _logger.debug("Initializing user provider with login {}", login); + setLogin(login); } /** @@ -35,16 +37,17 @@ public class XnatUserProvider implements Provider<UserI> { */ @Override public UserI get() { - if (null == user) { + if (null == _user) { try { - user = Users.getUser(_login); + _user = Users.getUser(_login); + _logger.debug("Retrieved user with login {}", _login); } catch (UserInitException e) { throw new NrgServiceRuntimeException(NrgServiceError.UserServiceError, "User object for name " + _login + " could not be initialized."); } catch (UserNotFoundException e) { throw new NrgServiceRuntimeException(NrgServiceError.UserNotFoundError, "User with name " + _login + " could not be found."); } } - return user; + return _user; } /** @@ -57,7 +60,20 @@ public class XnatUserProvider implements Provider<UserI> { return _login; } + /** + * Sets the configured login name for the default user. + * + * @param login The user login name to configure. + */ + public void setLogin(final String login) { + if (!StringUtils.equals(_login, login)) { + _login = login; + _user = null; + } + } + private final Logger _logger = LoggerFactory.getLogger(XnatUserProvider.class); - private final String _login; - private UserI user = null; + + private String _login; + private UserI _user = null; } diff --git a/src/main/resources/META-INF/xnat/preferences/site-config.properties b/src/main/resources/META-INF/xnat/preferences/site-config.properties deleted file mode 100644 index 0539c38c..00000000 --- a/src/main/resources/META-INF/xnat/preferences/site-config.properties +++ /dev/null @@ -1,62 +0,0 @@ -# -# web: site-config.properties -# XNAT http://www.xnat.org -# Copyright (c) 2016, Washington University School of Medicine and Howard Hughes Medical Institute -# All Rights Reserved -# -# Released under the Simplified BSD. -# - -# The XNAT siteConfiguration.properties is only used as the default site-wide configuration when a -# configuration is not already stored in the configuration service. After system initialization, the -# contents of this file can be used to add new properties to the system, but not to change the values -# of existing properties. For that, you should only modify site properties using the standard administrative -# interface. -checksums=true -#checksums.property.changed.listener=org.nrg.xnat.utils.ChecksumsSiteConfigurationListener -#showapplet=false -enableDicomReceiver=true -enableDicomReceiver.property.changed.listener=org.nrg.dcm.DicomSCPSiteConfigurationListener -emailVerification=true -enableProjectAppletScript=false -displayNameForGenericImageSession.singular=Session -displayNameForGenericImageSession.plural=Sessions -UI.debug-extension-points=false -UI.allow-advanced-search=true -UI.allow-new-user-comments=true -UI.allow-scan-addition=true -UI.show-left-bar=true -UI.show-left-bar-projects=true -UI.show-left-bar-favorites=true -UI.show-left-bar-search=true -UI.show-left-bar-browse=true -UI.show-manage-files=true -UI.allow-non-admin-project-creation=true -UI.login_failure_message=Your login attempt failed because the username and password combination you provided was invalid or your user already has the maximum number of user sessions open. After %d failed login attempts, your user account will be locked. If you believe your account is currently locked, you can:<ul><li>Unlock it by resetting your password</li><li>Wait one hour for it to unlock automatically</li></ul> - -# Indicates whether access to the list of system users should be restricted to site administrators only. -restrictUserListAccessToAdmins=false - -UI.allow-blocked-subject-assessor-view=false - -files.zip_extensions=zip,jar,rar,ear,gar,mrb - -emailAllowNonuserSubscribers=true - -requireSaltedPasswords=false - -siteDescriptionType=Page -siteDescriptionPage=/screens/site_description.vm -siteDescriptionText=SITE DESCRIPTION HERE: Go to Administer -> Configuration -> Site Information to change. -siteLoginLanding=/screens/QuickSearch.vm -siteLandingLayout=/Index.vm -siteHome=/screens/QuickSearch.vm -siteHomeLayout=/Index.vm - -scanTypeMapping=true - -passwordExpirationType=Interval -# Interval, in days, for expiring unchanged passwords (0 disables feature). Uses PostgreSQL interval notation: http://www.postgresql.org/docs/9.0/static/functions-datetime.html -passwordExpirationInterval=1 year -# Date for expiring passwords. Generally null by default. -passwordExpirationDate= \ No newline at end of file diff --git a/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml b/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml index ec8e5b88..81c14af4 100644 --- a/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml +++ b/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml @@ -308,7 +308,7 @@ generalSecuritySettings: contents: securityChannel: kind: panel.select.single - name: ":security.channel" + name: ":securityChannel" label: Security Channel options: any: Any @@ -332,7 +332,7 @@ generalSecuritySettings: description: "Should this site restrict access to the list of system users to site administrators only? If turned on, the site is more secure, but this restricts project owners from being able to administer users in their projects directly." uiAllowNonAdminProjectCreation: kind: panel.input.switchbox - name: ":UI.allow-non-admin-project-creation" + name: ":uiAllowNonAdminProjectCreation" label: "Allow non-administrators <br>to create projects?" onText: Allow offText: Do Not Allow @@ -384,17 +384,17 @@ userLoginsSessionControls: # description: Allow user to resume where they left off, if logging back in after a session timeout? maximumConcurrentSessions: kind: panel.input.number - name: ":sessions.concurrent_max" + name: ":concurrentMaxSessions" label: Maximum Concurrent Sessions validation: integer gte:1 onblur description: The maximum number of permitted sessions a user can have open simultaneously. You must restart Tomcat for changes to this to take effect. loginFailureMessage: kind: panel.textarea - name: ":UI.login_failure_message" + name: ":uiLoginFailureMessage" label: Login Failure Message code: html description: Text to show when a user fails to login -# value: "?? XNAT:data:siteConfig:UI.login_failure_message" +# value: "?? XNAT:data:siteConfig:uiLoginFailureMessage" maximumFailedLogins: kind: panel.input.number name: maxFailedLogins @@ -559,25 +559,25 @@ securityServices: securityServicesFeatureDefault: kind: panel.input.text # id: securityServicesFeatureDefault - name: ":security.services.feature.default" + name: ":featureService" label: Feature Default size: 50 securityServicesFeatureRepoDefault: kind: panel.input.text # id: securityServicesFeatureRepoDefault - name: ":security.services.featureRepository.default" + name: ":featureRepositoryService" label: Feature Repository Default size: 50 securityServicesRoleDefault: kind: panel.input.text # id: securityServicesRoleDefault - name: ":security.services.role.default" + name: ":roleService" label: Role Default size: 50 securityServicesRoleRepositoryDefault: kind: panel.input.text # id: securityServicesRoleRepositoryDefault - name: ":security.services.roleRepository.default" + name: ":roleRepositoryService" label: Role Repository Default size: 50 @@ -591,33 +591,33 @@ emailServerSettings: contents: smtpEnabled: kind: panel.input.switchbox - name: ":smtp.enabled" + name: ":smtpEnabled" label: "Enable SMTP?" onText: Enabled offText: Disabled hostname: kind: panel.input.text - name: host + name: smtpHostname label: Host placeholder: localhost port: kind: panel.input.number - name: port + name: smtpPort label: Port validation: allow-empty integer onblur placeholder: 587 username: kind: panel.input.text - name: username + name: smtpUsername label: Username placeholder: name@host.org password: kind: panel.input.password - name: password + name: smtpPassword label: Password protocol: kind: panel.input.text - name: protocol + name: smtpProtocol label: Protocol placeholder: smtp # subhead breaks up panel items @@ -627,19 +627,19 @@ emailServerSettings: label: Properties smtpAuth: kind: panel.input.switchbox - name: ":mail.smtp.auth" + name: ":smtpAuth" label: SMTP Auth? onText: Enabled offText: Disabled smtpStartTls: kind: panel.input.switchbox - name: ":mail.smtp.starttls.enable" + name: ":smtpStartTls" label: Start TLS? onText: Enabled offText: Disabled - smtpSSLTrust: + smtpSslTrust: kind: panel.input.text - name: ":mail.smtp.ssl.trust" + name: ":smtpSslTrust" label: SSL Trust placeholder: localhost emailPrefix: @@ -1000,7 +1000,7 @@ registrationOptions: when a user registers. uiAllowNewUserComments: kind: panel.input.switchbox - name: ":UI.allow-new-user-comments" + name: ":uiAllowNewUserComments" label: "Allow User Comments <br>on Registration?" onText: Allow offText: Do Not Allow @@ -1015,11 +1015,11 @@ manageDataTypes: contents: displayNameForGenericImageSessionSingular: kind: panel.input.text - name: ":displayNameForGenericImageSession.singular" + name: ":imageSessionDisplayNameSingular" label: "Singular Display Name For Generic Image Session Singular" displayNameForGenericImageSessionPlural: kind: panel.input.text - name: ":displayNameForGenericImageSession.plural" + name: ":imageSessionDisplayNamePlural" label: "Plural Display Name For Generic Image Session Singular" sessionBuilder: @@ -1030,6 +1030,15 @@ sessionBuilder: contentType: json url: /xapi/siteConfig contents: + receivedFileUser: + kind: panel.input.text + name: receivedFileUser + label: Received File User + validation: id-strict max-length:40 onblur + placeholder: User account for performing import and archiving operations + description: > + This should be the login name of an enabled and valid user. The specified user must be a site + administrator. sessionXmlRebuilderRepeat: kind: panel.input.number name: sessionXmlRebuilderRepeat diff --git a/src/main/webapp/WEB-INF/conf/services.properties b/src/main/webapp/WEB-INF/conf/services.properties deleted file mode 100644 index 429b50d9..00000000 --- a/src/main/webapp/WEB-INF/conf/services.properties +++ /dev/null @@ -1,91 +0,0 @@ -# -# D:/Development/XNAT/1.6/xnat_builder_1_6dev/plugin-resources/conf/services.properties -# XNAT http://www.xnat.org -# Copyright (c) 2014, Washington University School of Medicine -# All Rights Reserved -# -# Released under the Simplified BSD. -# -# Last modified 2/7/14 12:19 PM -# -site.title=XNAT - -datasource.name=xnat -datasource.driver=org.postgresql.Driver -datasource.url=jdbc:postgresql://localhost/xnat -datasource.username=xnat -datasource.password=xnat - -hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect -hibernate.hbm2ddl.auto=update -hibernate.show_sql=false -hibernate.cache.use_second_level_cache=true -hibernate.cache.use_query_cache=true - -mailserver.host=mail.server -mailserver.port=25 -mailserver.username= -mailserver.password= -mailserver.protocol=smtp -mailserver.admin=jrherrick@wustl.edu -mailserver.prefix=XNAT - -# Session XML rebuilder settings. interval is in minutes, repeat is in milliseconds. -services.rebuilder.interval=5 -services.rebuilder.repeat=60000 - -# Settings for the DICOM SCP Receiver. You can change the AE title and port here, as well as change the user that is -# used for operations on received files, e.g. archiving sessions in projects with auto-archiving. -services.dicom.scp.aetitle=XNAT -services.dicom.scp.port=8104 -services.dicom.scp.receivedfileuser=admin - -# Indicate the required security channel for the server. This can be http, https, or any. -security.channel=any - -# Number of failed login attempts before accounts are temporarily locked (-1 disables feature). -security.max_failed_logins=-1 -# Number of milliseconds to lock user accounts that have exceeded the max_failed_logins count (3600000 for 1 hour, 86400000 for 24 hours). -security.max_failed_logins_lockout_duration=86400000 -# Number of seconds of inactivity before an account is disabled (31556926 for 1 year). -security.inactivity_before_lockout=31556926 - -# Interval for timing out alias tokens. Uses PostgreSQL interval notation: http://www.postgresql.org/docs/9.0/static/functions-datetime.html -security.token_timeout=2 days - -# Java regular expression that new passwords must match. For no complexity checks, set this to ^.*$ -security.password_complexity=^.*$ -# Message that explains the password complexity requirements. This is displayed when user chooses a new password that fails to meet them. -security.password_complexity_message=Password is not sufficiently complex. - -# Number of days for which a password cannot be reused. -security.password_history=365 - -# The maximum number of permitted sessions a user can have open simultaneously. -security.sessions.concurrent_max=1000 - -# The following parameters are used to allow/force users to enter change justifications when modifying data. -audit.require_change_justification=false -audit.show_change_justification=false - -# Sets default values for the ActiveMQ configuration. -amq.usage.temp=128mb -amq.usage.mem=512mb -amq.usage.store=1gb - -# Comma-separated list of the providers that users will be able to use to authenticate. -provider.providers.enabled=db - -provider.db.name=Database -provider.db.id=localdb -provider.db.type=db - -# Add "ldap1" to the enabled provider list above and fill in the missing fields to enable LDAP authentication. -provider.ldap1.name=LDAP -provider.ldap1.id=ldap1 -provider.ldap1.type=ldap -provider.ldap1.address= -provider.ldap1.userdn= -provider.ldap1.password= -provider.ldap1.search.base= -provider.ldap1.search.filter= diff --git a/src/main/webapp/resources/samples/prefs-init.ini b/src/main/webapp/resources/samples/prefs-init.ini new file mode 100644 index 00000000..333765e7 --- /dev/null +++ b/src/main/webapp/resources/samples/prefs-init.ini @@ -0,0 +1,30 @@ +# +# prefs-init.ini +# XNAT http://www.xnat.org +# Copyright (c) 2016, Washington University School of Medicine +# All Rights Reserved +# +# Released under the Simplified BSD. +# + +[siteConfig] +siteUrl=http://xnat-centos.xnat.org +adminEmail=jrherrick@wustl.edu +archivePath=/data/xnat/archive +buildPath=/data/xnat/build +cachePath=/data/xnat/cache +ftpPath=/data/xnat/ftp +pipelinePath=/data/xnat/pipeline +prearchivePath=/data/xnat/prearchive +initialized=true + +[notifications] +hostname=smtp.gmail.com +username=foo@gmail.com +password=password1234 +port=587 +protocol=smtp +smtpAuth=true +smtpStartTls=true + + diff --git a/src/main/webapp/WEB-INF/conf/xnat-conf.properties b/src/main/webapp/resources/samples/xnat-conf.properties similarity index 100% rename from src/main/webapp/WEB-INF/conf/xnat-conf.properties rename to src/main/webapp/resources/samples/xnat-conf.properties diff --git a/src/main/webapp/scripts/project/settingsTabMgmt.js b/src/main/webapp/scripts/project/settingsTabMgmt.js index c13ccc0a..bbc6bd69 100644 --- a/src/main/webapp/scripts/project/settingsTabMgmt.js +++ b/src/main/webapp/scripts/project/settingsTabMgmt.js @@ -60,8 +60,8 @@ function fullConfigHandler() { }; var data = buildSettingsUpdateRequestBody([ - 'siteId','UI.debug-extension-points', 'siteDescriptionType', 'siteDescriptionText', 'siteDescriptionPage', 'siteUrl', 'siteAdminEmail', 'siteLoginLanding', 'siteLandingLayout', 'siteHome', 'siteHomeLayout' - , 'enableCsrfToken', 'enableCsrfEmail', 'restrictUserListAccessToAdmins', 'UI.allow-non-admin-project-creation', 'requireSaltedPasswords', 'passwordExpirationType', 'passwordExpirationInterval', 'passwordExpirationDate' + 'siteId','uiDebugExtensionPoints', 'siteDescriptionType', 'siteDescriptionText', 'siteDescriptionPage', 'siteUrl', 'siteAdminEmail', 'siteLoginLanding', 'siteLandingLayout', 'siteHome', 'siteHomeLayout' + , 'enableCsrfToken', 'enableCsrfEmail', 'restrictUserListAccessToAdmins', 'uiAllowNonAdminProjectCreation', 'requireSaltedPasswords', 'passwordExpirationType', 'passwordExpirationInterval', 'passwordExpirationDate' , 'archivePath', 'checksums', 'prearchivePath', 'cachePath', 'ftpPath', 'buildPath', 'pipelinePath' , 'requireLogin', 'enableNewRegistrations', 'emailVerification' , 'error', 'issue', 'newUser', 'update', 'emailAllowNonuserSubscribers', 'smt.enabled' diff --git a/src/main/webapp/setup/site-setup.yaml b/src/main/webapp/setup/site-setup.yaml index ea6d480c..516b6db2 100644 --- a/src/main/webapp/setup/site-setup.yaml +++ b/src/main/webapp/setup/site-setup.yaml @@ -175,31 +175,31 @@ siteSetup: host: kind: panel.input.text - name: host + name: smtpHostname label: Host placeholder: localhost validation: required port: kind: panel.input.number - name: port + name: smtpPort label: Port placeholder: 25 validation: required number username: kind: panel.input.text - name: username + name: smtpUsername label: Username password: kind: panel.input.password - name: password + name: smtpPassword label: Password protocol: kind: panel.input.text - name: protocol + name: smtpProtocol label: Protocol mailServerProperties: @@ -208,21 +208,21 @@ siteSetup: smtpAuth: kind: panel.input.switchbox - name: mail.smtp.auth + name: smtpAuth label: SMTP Auth? onText: Enabled offText: Disabled smtpStartTls: kind: panel.input.switchbox - name: mail.smtp.starttls.enable + name: smtpStartTls label: Start TLS? onText: Enabled offText: Disabled - smtpSSLTrust: + smtpSslTrust: kind: panel.input.text - name: mail.smtp.ssl.trust + name: smtpSslTrust label: SSL Trust # ========================= diff --git a/src/main/webapp/xdat-templates/layouts/Default.vm b/src/main/webapp/xdat-templates/layouts/Default.vm index e19a8139..a1ebfd21 100644 --- a/src/main/webapp/xdat-templates/layouts/Default.vm +++ b/src/main/webapp/xdat-templates/layouts/Default.vm @@ -8,7 +8,7 @@ $navigation.setTemplate("/bodyOpen.vm") <!-- path: xdat-templates/layouts/Default --> $navigation.setTemplate("/DefaultTop.vm") - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.show-left-bar","true"))) + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiShowLeftBarBrowse","true"))) $navigation.setTemplate("/DefaultLeft.vm") #end $navigation.setTemplate("/Breadcrumb.vm") diff --git a/src/main/webapp/xdat-templates/macros/TurbineMacros.vm b/src/main/webapp/xdat-templates/macros/TurbineMacros.vm index 221f0065..fd5d4c70 100644 --- a/src/main/webapp/xdat-templates/macros/TurbineMacros.vm +++ b/src/main/webapp/xdat-templates/macros/TurbineMacros.vm @@ -1636,7 +1636,7 @@ $!turbineUtils.escapeJS($s) ##Used to load globally scoped VM files and inject them into parent VMs. #macro(addGlobalCustomScreenJS $subFolder) - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.debug-extension-points","false")))document.write("<div class='extension_js'>/templates/screens/$subFolder</div>")#end + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiDebugExtensionPoints","false")))document.write("<div class='extension_js'>/templates/screens/$subFolder</div>")#end #foreach($screenProps in $turbineUtils.getTemplates($subFolder)) #set($templateFileName=$screenProps.getProperty("path")) #if($user.isGuest()) @@ -1655,7 +1655,7 @@ $!turbineUtils.escapeJS($s) ##Used to load VM files for specfic data-types and their extensions and inject them into parent VMs. #macro(addCustomScreenJS $dataType $subFolder) - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.debug-extension-points","false")))document.write("<div class='extension_js'>/templates/screens/$dataType/$subFolder</div>")#end + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiDebugExtensionPoints","false")))document.write("<div class='extension_js'>/templates/screens/$dataType/$subFolder</div>")#end #foreach($screenProps in $turbineUtils.getTemplates($dataType,$subFolder)) #set($templateFileName=$screenProps.getProperty("path")) #if($user.isGuest()) @@ -1674,7 +1674,7 @@ $!turbineUtils.escapeJS($s) ##Used to load globally scoped VM files and inject them into parent VMs. #macro(addGlobalCustomScreens $subFolder) - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.debug-extension-points","false")))<div class="extension">/templates/screens/$subFolder</div>#end + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiDebugExtensionPoints","false")))<div class="extension">/templates/screens/$subFolder</div>#end #foreach($screenProps in $turbineUtils.getTemplates($subFolder)) #set($templateFileName=$screenProps.getProperty("path")) #if($user.isGuest()) @@ -1693,7 +1693,7 @@ $!turbineUtils.escapeJS($s) ##Used to load VM files for specfic data-types and their extensions and inject them into parent VMs. #macro(addCustomScreens $dataType $subFolder) - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.debug-extension-points","false")))<div class="extension">/templates/screens/$dataType/$subFolder</div>#end + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiDebugExtensionPoints","false")))<div class="extension">/templates/screens/$dataType/$subFolder</div>#end #foreach($screenProps in $turbineUtils.getTemplates($dataType,$subFolder)) #set($templateFileName=$screenProps.getProperty("path")) #if($user.isGuest()) diff --git a/src/main/webapp/xnat-templates/layouts/Index.vm b/src/main/webapp/xnat-templates/layouts/Index.vm index d3f68965..32ca1920 100644 --- a/src/main/webapp/xnat-templates/layouts/Index.vm +++ b/src/main/webapp/xnat-templates/layouts/Index.vm @@ -9,7 +9,7 @@ $navigation.setTemplate("/bodyOpen.vm") $navigation.setTemplate("/DefaultTop.vm") - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.show-left-bar","true"))) + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiShowLeftBarBrowse","true"))) <!-- DefaultLeft --> $navigation.setTemplate("/DefaultLeft.vm") diff --git a/src/main/webapp/xnat-templates/navigations/HeaderIncludes.vm b/src/main/webapp/xnat-templates/navigations/HeaderIncludes.vm index e5e68f2b..38c56789 100755 --- a/src/main/webapp/xnat-templates/navigations/HeaderIncludes.vm +++ b/src/main/webapp/xnat-templates/navigations/HeaderIncludes.vm @@ -89,11 +89,11 @@ $navigation.setTemplate("/BaseJS.vm") // 'page' object is same as 'context' - easier to remember? XNAT.data.page = XNAT.data.context; - XNAT.app.showLeftBar = $turbineUtils.toBoolean($siteConfig.getProperty("UI.show-left-bar","true")); - XNAT.app.showLeftBarProjects = $turbineUtils.toBoolean($siteConfig.getProperty("UI.show-left-bar-projects","true")); - XNAT.app.showLeftBarFavorites = $turbineUtils.toBoolean($siteConfig.getProperty("UI.show-left-bar-favorites","true")); - XNAT.app.showLeftBarSearch = $turbineUtils.toBoolean($siteConfig.getProperty("UI.show-left-bar-search","true")); - XNAT.app.showLeftBarBrowse = $turbineUtils.toBoolean($siteConfig.getProperty("UI.show-left-bar-browse","true")); + XNAT.app.showLeftBar = $turbineUtils.toBoolean($siteConfig.getProperty("uiShowLeftBarBrowse","true")); + XNAT.app.showLeftBarProjects = $turbineUtils.toBoolean($siteConfig.getProperty("uiShowLeftBarProjects","true")); + XNAT.app.showLeftBarFavorites = $turbineUtils.toBoolean($siteConfig.getProperty("uiShowLeftBarFavorites","true")); + XNAT.app.showLeftBarSearch = $turbineUtils.toBoolean($siteConfig.getProperty("uiShowLeftBarSearch","true")); + XNAT.app.showLeftBarBrowse = $turbineUtils.toBoolean($siteConfig.getProperty("uiShowLeftBarBrowse","true")); window.available_elements = []; diff --git a/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm b/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm index 41babb23..7b4bb5e8 100755 --- a/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm +++ b/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm @@ -42,7 +42,7 @@ function submitQuickSearch(){ </select> <input id="searchValue" class="clean" name="searchValue" type="text" maxlength="40" size="20" value="$!field"/> <button type="button" id="search_btn" class="btn2" onclick="submitQuickSearch();">Go</button> -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-advanced-search","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowAdvancedSearch","true"))) <script> diff --git a/src/main/webapp/xnat-templates/screens/xnat_ctSessionData/edit/scans.vm b/src/main/webapp/xnat-templates/screens/xnat_ctSessionData/edit/scans.vm index 7e2e552f..9b9768c8 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_ctSessionData/edit/scans.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_ctSessionData/edit/scans.vm @@ -5,7 +5,7 @@ #* @vtlvariable name="om" type="org.nrg.xdat.om.XnatCtsessiondata" *# #* @vtlvariable name="scan" type="org.nrg.xdat.om.XnatImagescandata" *# <!-- BEGIN /xnat-templates/screens/xnat_ctSessionData/edit/scans.vm --> -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) <DIV class="edit_header1" style="margin-bottom:16px">Scans <input type="button" value="Add Scan" onclick="addScan(this)"/> </DIV> @@ -112,7 +112,7 @@ }); -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) if(window.scanSet.scans.length==0){ for(var newC=0;newC<5;newC++){ diff --git a/src/main/webapp/xnat-templates/screens/xnat_experimentData/actionsBox/ManageFiles.vm b/src/main/webapp/xnat-templates/screens/xnat_experimentData/actionsBox/ManageFiles.vm index c3b4e331..dc6f1c4b 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_experimentData/actionsBox/ManageFiles.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_experimentData/actionsBox/ManageFiles.vm @@ -1,5 +1,5 @@ <!-- Sequence: 5 --> -#if($user.checkFeature($om,"manage_files") && $turbineUtils.toBoolean($siteConfig.getProperty("UI.show-manage-files","true"))) +#if($user.checkFeature($om,"manage_files") && $turbineUtils.toBoolean($siteConfig.getProperty("uiShowManageFiles","true"))) <li class="yuimenuitem"> <A href="" ONCLICK="showFiles();return false;"><div class="ic">#if($actionObject.hasImage())<img border="0" src="$content.getURI("scripts/yui/build/treeview/assets/img/folders/cf.gif")"/>#else #end</div><div class="ic_spacer"> </div>Manage Files</A> </li> diff --git a/src/main/webapp/xnat-templates/screens/xnat_imageSessionData/edit/scans.vm b/src/main/webapp/xnat-templates/screens/xnat_imageSessionData/edit/scans.vm index 88cbb22a..1f5ffacd 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_imageSessionData/edit/scans.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_imageSessionData/edit/scans.vm @@ -6,7 +6,7 @@ XNAT.app.scans={}; </script> <DIV class="edit_header1" style="margin-bottom:16px">Scans -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) <input type="button" value="Add Scan" onclick="addScan(this)"/> #end </DIV> @@ -113,7 +113,7 @@ XNAT.app.scans={}; }); - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) if(window.scanSet.scans.length==0){ for(var newC=0;newC<5;newC++){ var tempScan = window.classMapping.newInstance(getDefaultScanXSIType()); diff --git a/src/main/webapp/xnat-templates/screens/xnat_mrSessionData/edit/scans.vm b/src/main/webapp/xnat-templates/screens/xnat_mrSessionData/edit/scans.vm index 81bfd64b..36029257 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_mrSessionData/edit/scans.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_mrSessionData/edit/scans.vm @@ -1,7 +1,7 @@ #* @vtlvariable name="scan" type="org.nrg.xdat.om.XnatImagescandata" *# #* @vtlvariable name="user" type="org.nrg.xdat.security.XDATUser" *# <!-- BEGIN /xnat-templates/screens/xnat_mrSessionData/edit/scans.vm --> -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) <DIV class="edit_header1" style="margin-bottom:16px">Scans <input type="button" value="Add Scan" onclick="addScan(this)"/> </DIV> @@ -116,7 +116,7 @@ }); -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) if(window.scanSet.scans.length==0){ for(var newC=0;newC<5;newC++){ diff --git a/src/main/webapp/xnat-templates/screens/xnat_petSessionData/edit/scans.vm b/src/main/webapp/xnat-templates/screens/xnat_petSessionData/edit/scans.vm index 4e34b816..257f365c 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_petSessionData/edit/scans.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_petSessionData/edit/scans.vm @@ -7,7 +7,7 @@ #end <DIV class="edit_header1" style="margin-bottom:16px">Scans -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) <input type="button" value="Add Scan" onclick="addScan(this)"/> #end </DIV> @@ -107,7 +107,7 @@ listing.render(); }); - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) if(window.scanSet.scans.length==0){ for(var newC=0;newC<2;newC++){ var tempScan = window.classMapping.newInstance("xnat:petScanData"); diff --git a/src/main/webapp/xnat-templates/screens/xnat_petmrSessionData/edit/scans.vm b/src/main/webapp/xnat-templates/screens/xnat_petmrSessionData/edit/scans.vm index 63de28f4..4621cf1f 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_petmrSessionData/edit/scans.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_petmrSessionData/edit/scans.vm @@ -6,7 +6,7 @@ #set($petscanTypes = $data.getSession().getAttribute("userHelper").getQueryResultsAsArrayList("select DISTINCT isd.type,isd.type from xnat_petscandata mr LEFT JOIN xnat_imagescandata isd ON mr.xnat_imagescandata_id=isd.xnat_imagescandata_id")) #end -#if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-scan-addition","true"))) +#if($turbineUtils.toBoolean($siteConfig.getProperty("uiAllowScanAddition","true"))) <DIV class="edit_header1" style="margin-bottom:16px">Scans <input type="button" value="Add Scan" onclick="addScan(this)"/> </DIV> diff --git a/src/main/webapp/xnat-templates/screens/xnat_subjectData/actionsBox/ManageFiles.vm b/src/main/webapp/xnat-templates/screens/xnat_subjectData/actionsBox/ManageFiles.vm index c3b4e331..dc6f1c4b 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_subjectData/actionsBox/ManageFiles.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_subjectData/actionsBox/ManageFiles.vm @@ -1,5 +1,5 @@ <!-- Sequence: 5 --> -#if($user.checkFeature($om,"manage_files") && $turbineUtils.toBoolean($siteConfig.getProperty("UI.show-manage-files","true"))) +#if($user.checkFeature($om,"manage_files") && $turbineUtils.toBoolean($siteConfig.getProperty("uiShowManageFiles","true"))) <li class="yuimenuitem"> <A href="" ONCLICK="showFiles();return false;"><div class="ic">#if($actionObject.hasImage())<img border="0" src="$content.getURI("scripts/yui/build/treeview/assets/img/folders/cf.gif")"/>#else #end</div><div class="ic_spacer"> </div>Manage Files</A> </li> diff --git a/src/main/webapp/xnat-templates/screens/xnat_subjectData/xnat_subjectData_assessor.vm b/src/main/webapp/xnat-templates/screens/xnat_subjectData/xnat_subjectData_assessor.vm index 667c20fc..e8a33334 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_subjectData/xnat_subjectData_assessor.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_subjectData/xnat_subjectData_assessor.vm @@ -2,8 +2,8 @@ ##handles data that is not viewable by this user. On some servers, users can see that these exist (but not view the actual data) ##on other servers, they shouldn't see that it exists at all. ##By default, the user shouldn't see these. -##To allow, site administrators should configure the UI.allow-blocked-subject-assessor-view peroprty in siteConfiguration.properties - #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-blocked-subject-assessor-view","false"))) +##To allow, site administrators should configure the uiLoginFailureMessage peroprty in siteConfiguration.properties + #if($turbineUtils.toBoolean($siteConfig.getProperty("uiLoginFailureMessage","false"))) #set($denied=true) <TR BGCOLOR="FF9999"> <TD>$!assessor.getProperty("date")</TD> -- GitLab