From a5da48159316bebb412c80cd4f33b5989560d3e8 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 12 Mar 2019 10:44:58 +0100 Subject: [PATCH 1/4] fix german locale for DateFromNow --- scm-plugins/scm-git-plugin/package.json | 2 +- scm-plugins/scm-git-plugin/yarn.lock | 6 +++--- scm-plugins/scm-hg-plugin/package.json | 2 +- scm-plugins/scm-hg-plugin/yarn.lock | 6 +++--- scm-plugins/scm-svn-plugin/package.json | 2 +- scm-plugins/scm-svn-plugin/yarn.lock | 6 +++--- scm-ui-components/packages/ui-components/package.json | 2 +- scm-ui-components/packages/ui-components/src/DateFromNow.js | 4 ++++ scm-ui-components/packages/ui-components/yarn.lock | 6 +++--- scm-ui-components/packages/ui-types/package.json | 2 +- scm-ui-components/packages/ui-types/yarn.lock | 6 +++--- scm-ui/package.json | 2 +- scm-ui/yarn.lock | 6 +++--- 13 files changed, 28 insertions(+), 24 deletions(-) diff --git a/scm-plugins/scm-git-plugin/package.json b/scm-plugins/scm-git-plugin/package.json index 8d5ac3165b..3b66c4f2c1 100644 --- a/scm-plugins/scm-git-plugin/package.json +++ b/scm-plugins/scm-git-plugin/package.json @@ -12,6 +12,6 @@ "@scm-manager/ui-extensions": "^0.1.2" }, "devDependencies": { - "@scm-manager/ui-bundler": "^0.0.25" + "@scm-manager/ui-bundler": "^0.0.26" } } diff --git a/scm-plugins/scm-git-plugin/yarn.lock b/scm-plugins/scm-git-plugin/yarn.lock index 6438262437..a45145d157 100644 --- a/scm-plugins/scm-git-plugin/yarn.lock +++ b/scm-plugins/scm-git-plugin/yarn.lock @@ -707,9 +707,9 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" -"@scm-manager/ui-bundler@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166" +"@scm-manager/ui-bundler@^0.0.26": + version "0.0.26" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66" dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" diff --git a/scm-plugins/scm-hg-plugin/package.json b/scm-plugins/scm-hg-plugin/package.json index 8d3926f0dd..d723751912 100644 --- a/scm-plugins/scm-hg-plugin/package.json +++ b/scm-plugins/scm-hg-plugin/package.json @@ -9,6 +9,6 @@ "@scm-manager/ui-extensions": "^0.1.2" }, "devDependencies": { - "@scm-manager/ui-bundler": "^0.0.25" + "@scm-manager/ui-bundler": "^0.0.26" } } diff --git a/scm-plugins/scm-hg-plugin/yarn.lock b/scm-plugins/scm-hg-plugin/yarn.lock index 47334b6e36..c1e19efede 100644 --- a/scm-plugins/scm-hg-plugin/yarn.lock +++ b/scm-plugins/scm-hg-plugin/yarn.lock @@ -641,9 +641,9 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" -"@scm-manager/ui-bundler@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166" +"@scm-manager/ui-bundler@^0.0.26": + version "0.0.26" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66" dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" diff --git a/scm-plugins/scm-svn-plugin/package.json b/scm-plugins/scm-svn-plugin/package.json index 8bbf204e2f..10439dba66 100644 --- a/scm-plugins/scm-svn-plugin/package.json +++ b/scm-plugins/scm-svn-plugin/package.json @@ -9,6 +9,6 @@ "@scm-manager/ui-extensions": "^0.1.2" }, "devDependencies": { - "@scm-manager/ui-bundler": "^0.0.25" + "@scm-manager/ui-bundler": "^0.0.26" } } diff --git a/scm-plugins/scm-svn-plugin/yarn.lock b/scm-plugins/scm-svn-plugin/yarn.lock index 47334b6e36..c1e19efede 100644 --- a/scm-plugins/scm-svn-plugin/yarn.lock +++ b/scm-plugins/scm-svn-plugin/yarn.lock @@ -641,9 +641,9 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" -"@scm-manager/ui-bundler@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166" +"@scm-manager/ui-bundler@^0.0.26": + version "0.0.26" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66" dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" diff --git a/scm-ui-components/packages/ui-components/package.json b/scm-ui-components/packages/ui-components/package.json index 80b83b0265..8eaebe3632 100644 --- a/scm-ui-components/packages/ui-components/package.json +++ b/scm-ui-components/packages/ui-components/package.json @@ -14,7 +14,7 @@ "eslint-fix": "eslint src --fix" }, "devDependencies": { - "@scm-manager/ui-bundler": "^0.0.25", + "@scm-manager/ui-bundler": "^0.0.26", "create-index": "^2.3.0", "enzyme": "^3.5.0", "enzyme-adapter-react-16": "^1.3.1", diff --git a/scm-ui-components/packages/ui-components/src/DateFromNow.js b/scm-ui-components/packages/ui-components/src/DateFromNow.js index be15bcdad2..3c14f02d0c 100644 --- a/scm-ui-components/packages/ui-components/src/DateFromNow.js +++ b/scm-ui-components/packages/ui-components/src/DateFromNow.js @@ -4,6 +4,10 @@ import moment from "moment"; import { translate } from "react-i18next"; import injectSheet from "react-jss"; +// fix german locale +// https://momentjscom.readthedocs.io/en/latest/moment/00-use-it/07-browserify/ +import "moment/locale/de"; + const styles = { date: { borderBottom: "1px dotted rgba(219, 219, 219)", diff --git a/scm-ui-components/packages/ui-components/yarn.lock b/scm-ui-components/packages/ui-components/yarn.lock index 1a4c28c9c2..9736de8a78 100644 --- a/scm-ui-components/packages/ui-components/yarn.lock +++ b/scm-ui-components/packages/ui-components/yarn.lock @@ -687,9 +687,9 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" -"@scm-manager/ui-bundler@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166" +"@scm-manager/ui-bundler@^0.0.26": + version "0.0.26" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66" dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" diff --git a/scm-ui-components/packages/ui-types/package.json b/scm-ui-components/packages/ui-types/package.json index 11029490bb..c6a7c880dc 100644 --- a/scm-ui-components/packages/ui-types/package.json +++ b/scm-ui-components/packages/ui-types/package.json @@ -14,7 +14,7 @@ "check": "flow check" }, "devDependencies": { - "@scm-manager/ui-bundler": "^0.0.25" + "@scm-manager/ui-bundler": "^0.0.26" }, "browserify": { "transform": [ diff --git a/scm-ui-components/packages/ui-types/yarn.lock b/scm-ui-components/packages/ui-types/yarn.lock index d0ef9f7a86..2d47639005 100644 --- a/scm-ui-components/packages/ui-types/yarn.lock +++ b/scm-ui-components/packages/ui-types/yarn.lock @@ -707,9 +707,9 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" -"@scm-manager/ui-bundler@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166" +"@scm-manager/ui-bundler@^0.0.26": + version "0.0.26" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66" dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" diff --git a/scm-ui/package.json b/scm-ui/package.json index 531b3400a9..6844ea3ec7 100644 --- a/scm-ui/package.json +++ b/scm-ui/package.json @@ -52,7 +52,7 @@ "pre-commit": "jest && flow && eslint src" }, "devDependencies": { - "@scm-manager/ui-bundler": "^0.0.25", + "@scm-manager/ui-bundler": "^0.0.26", "concat": "^1.0.3", "copyfiles": "^2.0.0", "enzyme": "^3.3.0", diff --git a/scm-ui/yarn.lock b/scm-ui/yarn.lock index 5c38cb2dba..5b6ec89ef3 100644 --- a/scm-ui/yarn.lock +++ b/scm-ui/yarn.lock @@ -698,9 +698,9 @@ version "0.0.2" resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" -"@scm-manager/ui-bundler@^0.0.25": - version "0.0.25" - resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.25.tgz#1f65b3ff0ae81559a114c6a8d8cf43856cc6e166" +"@scm-manager/ui-bundler@^0.0.26": + version "0.0.26" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.26.tgz#4676a7079b781b33fa1989c6643205c3559b1f66" dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" From 251459671accc01a28e890cac4a0636b3994ecfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Tue, 12 Mar 2019 10:11:41 +0000 Subject: [PATCH 2/4] Close branch bugfix/momentjs_german_locale From d54b5360e2efc140378658f41a47b1da3a62317f Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 12 Mar 2019 13:55:34 +0100 Subject: [PATCH 3/4] identify ui requests as ajax requests --- scm-ui-components/packages/ui-components/src/apiclient.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scm-ui-components/packages/ui-components/src/apiclient.js b/scm-ui-components/packages/ui-components/src/apiclient.js index 77ebe8cf4e..551bb3e2eb 100644 --- a/scm-ui-components/packages/ui-components/src/apiclient.js +++ b/scm-ui-components/packages/ui-components/src/apiclient.js @@ -6,7 +6,9 @@ import type { BackendErrorContent } from "./errors"; const fetchOptions: RequestOptions = { credentials: "same-origin", headers: { - Cache: "no-cache" + Cache: "no-cache", + // identify the request as ajax request + "X-Requested-With": "XMLHttpRequest" } }; From cd302a376894927bc01925b9dc1a7d12bc7dbaa9 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 12 Mar 2019 13:58:46 +0100 Subject: [PATCH 4/4] fix handling of post authentication filters for protocol request do not call PushStateDispatcher in the HttpProtocolServletAuthenticationFilter, because the HttpProtocolServlet already does this. --- ...tpProtocolServletAuthenticationFilter.java | 11 ++- ...otocolServletAuthenticationFilterTest.java | 72 +++++++++++++++++++ 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java diff --git a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java index e58945a346..973b3af4cb 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java @@ -1,7 +1,6 @@ package sonia.scm.web.filter; import sonia.scm.Priority; -import sonia.scm.PushStateDispatcher; import sonia.scm.config.ScmConfiguration; import sonia.scm.filter.Filters; import sonia.scm.filter.WebElement; @@ -12,6 +11,8 @@ import sonia.scm.web.WebTokenGenerator; import sonia.scm.web.protocol.HttpProtocolServlet; import javax.inject.Inject; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -21,25 +22,23 @@ import java.util.Set; @WebElement(value = HttpProtocolServlet.PATTERN) public class HttpProtocolServletAuthenticationFilter extends AuthenticationFilter { - private final PushStateDispatcher dispatcher; private final UserAgentParser userAgentParser; @Inject public HttpProtocolServletAuthenticationFilter( ScmConfiguration configuration, Set tokenGenerators, - PushStateDispatcher dispatcher, UserAgentParser userAgentParser) { super(configuration, tokenGenerators); - this.dispatcher = dispatcher; this.userAgentParser = userAgentParser; } @Override - protected void sendUnauthorizedError(HttpServletRequest request, HttpServletResponse response) throws IOException { + protected void handleUnauthorized(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { UserAgent userAgent = userAgentParser.parse(request); if (userAgent.isBrowser()) { - dispatcher.dispatch(request, response, request.getRequestURI()); + // we can proceed the filter chain because the HttpProtocolServlet will render the ui if the client is a browser + chain.doFilter(request, response); } else { HttpUtil.sendUnauthorized(request, response); } diff --git a/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java b/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java new file mode 100644 index 0000000000..ff493e2b84 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java @@ -0,0 +1,72 @@ +package sonia.scm.web.filter; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import sonia.scm.config.ScmConfiguration; +import sonia.scm.util.HttpUtil; +import sonia.scm.web.UserAgent; +import sonia.scm.web.UserAgentParser; +import sonia.scm.web.WebTokenGenerator; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class HttpProtocolServletAuthenticationFilterTest { + + private ScmConfiguration configuration = new ScmConfiguration(); + + private Set tokenGenerators = Collections.emptySet(); + + @Mock + private UserAgentParser userAgentParser; + + private HttpProtocolServletAuthenticationFilter authenticationFilter; + + @Mock + private HttpServletRequest request; + + @Mock + private HttpServletResponse response; + + @Mock + private FilterChain filterChain; + + private UserAgent nonBrowser = UserAgent.builder("i'm not a browser").browser(false).build(); + private UserAgent browser = UserAgent.builder("i am a browser").browser(true).build(); + + @BeforeEach + void setUpObjectUnderTest() { + authenticationFilter = new HttpProtocolServletAuthenticationFilter(configuration, tokenGenerators, userAgentParser); + } + + @Test + void shouldSendUnauthorized() throws IOException, ServletException { + when(userAgentParser.parse(request)).thenReturn(nonBrowser); + + authenticationFilter.handleUnauthorized(request, response, filterChain); + + verify(response).sendError(HttpServletResponse.SC_UNAUTHORIZED, HttpUtil.STATUS_UNAUTHORIZED_MESSAGE); + } + + @Test + void shouldCallFilterChain() throws IOException, ServletException { + when(userAgentParser.parse(request)).thenReturn(browser); + + authenticationFilter.handleUnauthorized(request, response, filterChain); + + verify(filterChain).doFilter(request, response); + } + +}