=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/configuration/Configuration.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/configuration/Configuration.java 2015-10-06 14:23:01 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/configuration/Configuration.java 2015-10-09 10:49:19 +0000 @@ -29,11 +29,13 @@ */ import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; -import org.hisp.dhis.indicator.IndicatorGroup; import org.hisp.dhis.common.BaseIdentifiableObject; import org.hisp.dhis.common.DxfNamespaces; import org.hisp.dhis.dataelement.DataElementGroup; +import org.hisp.dhis.indicator.IndicatorGroup; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitLevel; import org.hisp.dhis.period.PeriodType; @@ -44,10 +46,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; /** * @author Lars Helge Overland */ +@JacksonXmlRootElement( localName = "configuration", namespace = DxfNamespaces.DXF_2_0 ) public class Configuration implements Serializable { @@ -79,6 +83,8 @@ private UserAuthorityGroup selfRegistrationRole; private OrganisationUnit selfRegistrationOrgUnit; + + private Set corsWhitelist = new HashSet<>(); // ------------------------------------------------------------------------- // Remote synch @@ -283,4 +289,16 @@ { this.smtpPassword = smtpPassword; } + + @JsonProperty + @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) + public Set getCorsWhitelist() + { + return corsWhitelist; + } + + public void setCorsWhitelist( Set corsWhitelist ) + { + this.corsWhitelist = corsWhitelist; + } } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/Setting.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/Setting.java 2015-10-07 09:31:10 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/Setting.java 2015-10-09 10:49:19 +0000 @@ -92,7 +92,7 @@ ACCEPTANCE_REQUIRED_FOR_APPROVAL( "keyAcceptanceRequiredForApproval", Boolean.FALSE, Boolean.class ), SYSTEM_NOTIFICATIONS_EMAIL( "keySystemNotificationsEmail" ), ANALYSIS_RELATIVE_PERIOD( "keyAnalysisRelativePeriod", "LAST_12_MONTHS", String.class ), - CORS_WHITELIST( "keyCorsWhitelist", List.class ), + CORS_WHITELIST2( "keyCorsWhitelist", List.class ), REQUIRE_ADD_TO_VIEW( "keyRequireAddToView", Boolean.FALSE, Boolean.class ), ALLOW_OBJECT_ASSIGNMENT( "keyAllowObjectAssignment", Boolean.FALSE, Boolean.class ), USE_CUSTOM_LOGO_FRONT( "keyUseCustomLogoFront", Boolean.FALSE, Boolean.class ), === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/SystemSettingManager.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/SystemSettingManager.java 2015-10-06 22:23:53 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/setting/SystemSettingManager.java 2015-10-09 10:49:19 +0000 @@ -176,6 +176,4 @@ String googleAnalyticsUA(); Integer credentialsExpires(); - - List getCorsWhitelist(); } === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/setting/DefaultSystemSettingManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/setting/DefaultSystemSettingManager.java 2015-10-06 22:23:53 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/setting/DefaultSystemSettingManager.java 2015-10-09 10:49:19 +0000 @@ -302,13 +302,4 @@ { return (Integer) getSystemSetting( Setting.CREDENTIALS_EXPIRES ); } - - @Override - @SuppressWarnings( "unchecked" ) - public List getCorsWhitelist() - { - Serializable value = getSystemSetting( Setting.CORS_WHITELIST ); - - return value != null ? (List) value : Collections.emptyList(); - } } === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/configuration/hibernate/Configuration.hbm.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/configuration/hibernate/Configuration.hbm.xml 2014-11-26 12:22:29 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/configuration/hibernate/Configuration.hbm.xml 2015-10-09 10:49:19 +0000 @@ -43,5 +43,11 @@ + + + + + + === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/ConfigurationController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/ConfigurationController.java 2015-10-08 22:27:07 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/ConfigurationController.java 2015-10-09 10:49:19 +0000 @@ -28,6 +28,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import java.io.IOException; +import java.util.Set; + import javax.servlet.http.HttpServletRequest; import org.hisp.dhis.common.BaseIdentifiableObject; @@ -35,6 +38,7 @@ import org.hisp.dhis.configuration.Configuration; import org.hisp.dhis.configuration.ConfigurationService; import org.hisp.dhis.dataelement.DataElementGroup; +import org.hisp.dhis.dxf2.render.RenderService; import org.hisp.dhis.indicator.IndicatorGroup; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitLevel; @@ -49,6 +53,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; @@ -69,6 +74,9 @@ @Autowired private PeriodService periodService; + @Autowired + private RenderService renderService; + // ------------------------------------------------------------------------- // Resources // ------------------------------------------------------------------------- @@ -345,6 +353,28 @@ configurationService.setConfiguration( config ); } + @RequestMapping( value = "/corsWhitelist", method = RequestMethod.GET, produces = "application/json" ) + public String getCorsWhitelist( Model model, HttpServletRequest request ) + { + return setModel( model, configurationService.getConfiguration().getCorsWhitelist() ); + } + + @SuppressWarnings("unchecked") + @PreAuthorize( "hasRole('ALL') or hasRole('F_SYSTEM_SETTING')" ) + @ResponseStatus( value = HttpStatus.OK ) + @RequestMapping( value = "/corsWhitelist", method = RequestMethod.POST, consumes = "application/json" ) + public void setCorsWhitelist( @RequestBody String input ) + throws IOException + { + Set corsWhitelist = renderService.fromJson( input, Set.class ); + + Configuration config = configurationService.getConfiguration(); + + config.setCorsWhitelist( corsWhitelist ); + + configurationService.setConfiguration( config ); + } + // ------------------------------------------------------------------------- // Supportive methods // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/StaticContentController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/StaticContentController.java 2015-10-07 08:36:33 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/StaticContentController.java 2015-10-09 10:49:19 +0000 @@ -100,7 +100,7 @@ Boolean useCustomFile = Boolean.parseBoolean( (String) systemSettingManager.getSystemSetting( KEY_WHITELIST_MAP.get( key ) ) ); - if ( !useCustomFile ) // Serve the default + if ( !useCustomFile ) // Serve default { try { @@ -111,7 +111,7 @@ throw new WebMessageException( WebMessageUtils.error( "Can't read the file." ) ); } } - else // Serve the custom + else // Serve custom { InputStream in = null; @@ -159,7 +159,8 @@ throw new WebMessageException( WebMessageUtils.badRequest( "Missing parameter 'file'" ) ); } - // Only PNG is accepted at the current time. Ensure file is a PNG image. + // Only PNG is accepted at the current time + MimeType mimeType = MimeTypeUtils.parseMimeType( file.getContentType() ); if( !mimeType.isCompatibleWith( MimeTypeUtils.IMAGE_PNG )) @@ -168,13 +169,14 @@ } // Only keys in the white list are accepted at the current time + if ( !KEY_WHITELIST_MAP.containsKey( key ) ) { throw new WebMessageException( WebMessageUtils.badRequest( "This key is not supported." ) ); } - File out; + File out = null; try { === modified file 'dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/CorsFilter.java' --- dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/CorsFilter.java 2015-01-17 07:41:26 +0000 +++ dhis-2/dhis-web/dhis-web-commons/src/main/java/org/hisp/dhis/security/filter/CorsFilter.java 2015-10-09 10:49:19 +0000 @@ -28,13 +28,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hisp.dhis.setting.SystemSettingManager; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import java.io.IOException; +import java.util.Set; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -44,32 +39,31 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hisp.dhis.configuration.ConfigurationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; /** * @author Morten Olav Hansen */ -public class CorsFilter implements Filter +public class CorsFilter + implements Filter { private static final Log log = LogFactory.getLog( CorsFilter.class ); public static final String CORS_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"; - public static final String CORS_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; - public static final String CORS_MAX_AGE = "Access-Control-Max-Age"; - public static final String CORS_ALLOW_HEADERS = "Access-Control-Allow-Headers"; - public static final String CORS_EXPOSE_HEADERS = "Access-Control-Expose-Headers"; - public static final String CORS_REQUEST_HEADERS = "Access-Control-Request-Headers"; - public static final String CORS_ALLOW_METHODS = "Access-Control-Allow-Methods"; - public static final String CORS_REQUEST_METHOD = "Access-Control-Request-Method"; - public static final String CORS_ORIGIN = "Origin"; private static final String EXPOSED_HEADERS = "ETag"; @@ -77,7 +71,7 @@ private static final Integer MAX_AGE = 60 * 60; // 1hr max-age @Autowired - private SystemSettingManager systemSettingManager; + private ConfigurationService configurationService; @Override public void doFilter( ServletRequest req, ServletResponse res, FilterChain filterChain ) throws IOException, ServletException @@ -88,6 +82,7 @@ String origin = request.getHeader( CORS_ORIGIN ); // Origin header is required for CORS requests + if ( StringUtils.isEmpty( origin ) ) { filterChain.doFilter( request, response ); @@ -115,7 +110,10 @@ response.addHeader( CORS_MAX_AGE, String.valueOf( MAX_AGE ) ); response.setStatus( HttpServletResponse.SC_NO_CONTENT ); - return; // CORS preflight requires a 2xx status code, so we need to short-circuit the filter chain here + + // CORS preflight requires a 2xx status code, so short-circuit the filter chain + + return; } else { @@ -147,7 +145,8 @@ .scheme( forwardedProto ).build().toUriString(); } - List whitelist = systemSettingManager.getCorsWhitelist(); + Set whitelist = configurationService.getConfiguration().getCorsWhitelist(); + return !StringUtils.isEmpty( origin ) && (localUrl.equals( origin ) || whitelist.contains( origin )); } === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/GetAccessSettingsAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/GetAccessSettingsAction.java 2015-06-15 13:44:20 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/GetAccessSettingsAction.java 2015-10-09 10:49:19 +0000 @@ -30,14 +30,16 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator; +import org.hisp.dhis.commons.filter.FilterUtils; +import org.hisp.dhis.configuration.ConfigurationService; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitService; -import org.hisp.dhis.setting.SystemSettingManager; import org.hisp.dhis.system.filter.NonCriticalUserAuthorityGroupFilter; -import org.hisp.dhis.commons.filter.FilterUtils; import org.hisp.dhis.user.UserAuthorityGroup; import org.hisp.dhis.user.UserService; import org.springframework.beans.factory.annotation.Autowired; @@ -57,7 +59,7 @@ private OrganisationUnitService organisationUnitService; @Autowired - private SystemSettingManager systemSettingManager; + private ConfigurationService configurationService; // ------------------------------------------------------------------------- // Output @@ -77,9 +79,9 @@ return selfRegistrationOrgUnits; } - private List corsWhitelist = new ArrayList<>(); + private Set corsWhitelist = new HashSet<>(); - public List getCorsWhitelist() + public Set getCorsWhitelist() { return corsWhitelist; } @@ -99,7 +101,7 @@ selfRegistrationOrgUnits.addAll( organisationUnitService.getOrganisationUnitsAtLevel( 1 ) ); selfRegistrationOrgUnits.addAll( organisationUnitService.getOrganisationUnitsAtLevel( 2 ) ); - corsWhitelist = systemSettingManager.getCorsWhitelist(); + corsWhitelist = configurationService.getConfiguration().getCorsWhitelist(); return SUCCESS; } === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/SetAccessSettingsAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/SetAccessSettingsAction.java 2015-06-17 13:37:50 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-settings/src/main/java/org/hisp/dhis/settings/action/system/SetAccessSettingsAction.java 2015-10-09 10:49:19 +0000 @@ -29,16 +29,15 @@ */ import static org.hisp.dhis.setting.SystemSettingManager.KEY_ACCOUNT_RECOVERY; +import static org.hisp.dhis.setting.SystemSettingManager.KEY_ALLOW_OBJECT_ASSIGNMENT; import static org.hisp.dhis.setting.SystemSettingManager.KEY_CAN_GRANT_OWN_USER_AUTHORITY_GROUPS; import static org.hisp.dhis.setting.SystemSettingManager.KEY_CREDENTIALS_EXPIRES; import static org.hisp.dhis.setting.SystemSettingManager.KEY_OPENID_PROVIDER; import static org.hisp.dhis.setting.SystemSettingManager.KEY_OPENID_PROVIDER_LABEL; import static org.hisp.dhis.setting.SystemSettingManager.KEY_SELF_REGISTRATION_NO_RECAPTCHA; -import static org.hisp.dhis.setting.SystemSettingManager.KEY_ALLOW_OBJECT_ASSIGNMENT; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.hisp.dhis.configuration.Configuration; @@ -138,9 +137,9 @@ this.openIdProviderLabel = openIdProviderLabel; } - private List corsWhitelist = new ArrayList<>(); + private Set corsWhitelist = new HashSet<>(); - public void setCorsWhitelist( ArrayList corsWhitelist ) + public void setCorsWhitelist( Set corsWhitelist ) { this.corsWhitelist = corsWhitelist; } @@ -186,6 +185,7 @@ Configuration config = configurationService.getConfiguration(); config.setSelfRegistrationRole( group ); config.setSelfRegistrationOrgUnit( unit ); + config.setCorsWhitelist( corsWhitelist ); configurationService.setConfiguration( config ); systemSettingManager.saveSystemSetting( KEY_ACCOUNT_RECOVERY, accountRecovery ); @@ -204,8 +204,6 @@ systemSettingManager.saveSystemSetting( KEY_CREDENTIALS_EXPIRES, credentialsExpires ); } - systemSettingManager.saveSystemSetting( SystemSettingManager.KEY_CORS_WHITELIST, (Serializable) corsWhitelist ); - message = i18n.getString( "settings_updated" ); return SUCCESS;