Merge with 2.0.0-m3

This commit is contained in:
René Pfeuffer
2019-03-12 15:20:03 +01:00
16 changed files with 108 additions and 31 deletions

View File

@@ -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"
}
}

View File

@@ -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"

View File

@@ -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"
}
}

View File

@@ -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"

View File

@@ -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"
}
}

View File

@@ -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"

View File

@@ -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",

View File

@@ -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)",

View File

@@ -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"
}
};

View File

@@ -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"

View File

@@ -14,7 +14,7 @@
"check": "flow check"
},
"devDependencies": {
"@scm-manager/ui-bundler": "^0.0.25"
"@scm-manager/ui-bundler": "^0.0.26"
},
"browserify": {
"transform": [

View File

@@ -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"

View File

@@ -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",

View File

@@ -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"

View File

@@ -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<WebTokenGenerator> 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);
}

View File

@@ -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<WebTokenGenerator> 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);
}
}