diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java index 73ff74fd3d..f05cda4430 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/configuration/AppConfiguration.java @@ -16,17 +16,20 @@ */ package org.apache.dolphinscheduler.api.configuration; +import org.apache.dolphinscheduler.api.interceptor.LocaleChangeInterceptor; import org.apache.dolphinscheduler.api.interceptor.LoginHandlerInterceptor; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.*; import org.springframework.web.servlet.i18n.CookieLocaleResolver; -import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import java.util.Locale; - /** * application configuration */ @@ -37,15 +40,23 @@ public class AppConfiguration implements WebMvcConfigurer { public static final String LOGIN_PATH_PATTERN = "/login"; public static final String PATH_PATTERN = "/**"; public static final String LOCALE_LANGUAGE_COOKIE = "language"; - public static final int COOKIE_MAX_AGE = 3600; + @Bean + public CorsFilter corsFilter() { + CorsConfiguration config = new CorsConfiguration(); + config.addAllowedOrigin("*"); + config.addAllowedMethod("*"); + config.addAllowedHeader("*"); + UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); + configSource.registerCorsConfiguration(PATH_PATTERN, config); + return new CorsFilter(configSource); + } @Bean public LoginHandlerInterceptor loginInterceptor() { return new LoginHandlerInterceptor(); } - /** * Cookie * @return local resolver @@ -56,30 +67,24 @@ public class AppConfiguration implements WebMvcConfigurer { localeResolver.setCookieName(LOCALE_LANGUAGE_COOKIE); /** set default locale **/ localeResolver.setDefaultLocale(Locale.US); - /** set cookie max age **/ - localeResolver.setCookieMaxAge(COOKIE_MAX_AGE); + /** set language tag compliant **/ + localeResolver.setLanguageTagCompliant(false); return localeResolver; } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { - LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); - /** **/ - lci.setParamName("language"); - - return lci; + return new LocaleChangeInterceptor(); } - @Override public void addInterceptors(InterceptorRegistry registry) { - //i18n + // i18n registry.addInterceptor(localeChangeInterceptor()); - + // login registry.addInterceptor(loginInterceptor()).addPathPatterns(LOGIN_INTERCEPTOR_PATH_PATTERN).excludePathPatterns(LOGIN_PATH_PATTERN,"/swagger-resources/**", "/webjars/**", "/v2/**", "/doc.html", "*.html", "/ui/**"); } - @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); @@ -94,12 +99,6 @@ public class AppConfiguration implements WebMvcConfigurer { registry.addViewController("/").setViewName("forward:/ui/index.html"); } - @Override - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping(PATH_PATTERN).allowedOrigins("*").allowedMethods("*"); - } - - /** * Turn off suffix-based content negotiation * @@ -110,7 +109,4 @@ public class AppConfiguration implements WebMvcConfigurer { configurer.favorPathExtension(false); } - - - } diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptor.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptor.java new file mode 100644 index 0000000000..3fe236e065 --- /dev/null +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptor.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.api.interceptor; + +import org.apache.dolphinscheduler.api.service.BaseService; +import org.apache.dolphinscheduler.common.Constants; + +import java.util.Locale; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +public class LocaleChangeInterceptor extends HandlerInterceptorAdapter { + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + Cookie cookie = BaseService.getCookie(request, Constants.LOCALE_LANGUAGE); + if (cookie != null) { + // Proceed in cookie + return true; + } + // Proceed in header + String newLocale = request.getHeader(Constants.LOCALE_LANGUAGE); + if (newLocale != null) { + LocaleContextHolder.setLocale(parseLocaleValue(newLocale)); + } + return true; + } + + @Nullable + protected Locale parseLocaleValue(String localeValue) { + return StringUtils.parseLocale(localeValue); + } + +} diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptorTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptorTest.java new file mode 100644 index 0000000000..7a7506fda5 --- /dev/null +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/interceptor/LocaleChangeInterceptorTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.api.interceptor; + +import org.apache.dolphinscheduler.api.ApiApplicationServer; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ApiApplicationServer.class) +public class LocaleChangeInterceptorTest { + + @Autowired + LocaleChangeInterceptor interceptor; + + @Test + public void testPreHandle() { + HttpServletRequest request = Mockito.mock(HttpServletRequest.class); + HttpServletResponse response = Mockito.mock(HttpServletResponse.class); + // test no language + Assert.assertTrue(interceptor.preHandle(request, response, null)); + } + +} diff --git a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java index ebe5a60ee5..9932219e9e 100644 --- a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java +++ b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java @@ -890,6 +890,11 @@ public final class Constants { public static final String PASSWORD_DEFAULT = "******"; + /** + * locale + */ + public static final String LOCALE_LANGUAGE = "language"; + /** * driver */ diff --git a/dolphinscheduler-ui/package.json b/dolphinscheduler-ui/package.json index ad08a14896..74a305781b 100644 --- a/dolphinscheduler-ui/package.json +++ b/dolphinscheduler-ui/package.json @@ -36,6 +36,7 @@ "vuex-router-sync": "^5.0.0" }, "devDependencies": { + "acorn": "^7.4.1", "autoprefixer": "^9.1.0", "babel-core": "^6.25.0", "babel-helper-vue-jsx-merge-props": "^2.0.2", diff --git a/dolphinscheduler-ui/src/js/module/io/index.js b/dolphinscheduler-ui/src/js/module/io/index.js index 79e2eb543d..d1b6a1af62 100644 --- a/dolphinscheduler-ui/src/js/module/io/index.js +++ b/dolphinscheduler-ui/src/js/module/io/index.js @@ -84,6 +84,10 @@ io.interceptors.request.use( _t: Math.random() }) } + config.headers = config.headers || {} + const language = cookies.get('language') + if (language) config.headers.language = language + if (sIdCookie) config.headers.sessionId = sIdCookie return config } }, error => { diff --git a/pom.xml b/pom.xml index e240910ecd..238c82a759 100644 --- a/pom.xml +++ b/pom.xml @@ -704,6 +704,7 @@ **/api/enums/StatusTest.java **/api/exceptions/ApiExceptionHandlerTest.java **/api/exceptions/ServiceExceptionTest.java + **/api/interceptor/LocaleChangeInterceptorTest.java **/api/interceptor/LoginHandlerInterceptorTest.java **/api/security/PasswordAuthenticatorTest.java **/api/security/SecurityConfigTest.java