Skip to content

Commit adf8a6a

Browse files
author
Daniel Heid
committed
Read user ID from remote user servlet attribute (#161)
1 parent 1d72d89 commit adf8a6a

10 files changed

Lines changed: 86 additions & 47 deletions

File tree

core/src/main/java/org/matomo/java/tracking/servlet/HttpServletRequestWrapper.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@
1616
@Value
1717
public class HttpServletRequestWrapper {
1818

19+
@Nullable
1920
StringBuffer requestURL;
2021

22+
@Nullable
2123
String remoteAddr;
2224

25+
@Nullable
26+
String remoteUser;
27+
28+
@Nullable
2329
Map<String, String> headers;
2430

31+
@Nullable
2532
CookieWrapper[] cookies;
2633

2734
/**

core/src/main/java/org/matomo/java/tracking/servlet/ServletMatomoRequest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public static MatomoRequest.MatomoRequestBuilder addServletRequestHeaders(
7777
.actionUrl(request.getRequestURL() == null ? null : request.getRequestURL().toString())
7878
.headers(collectHeaders(request))
7979
.visitorIp(determineVisitorIp(request))
80+
.userId(request.getRemoteUser())
8081
.cookies(processCookies(builder, request));
8182
}
8283

core/src/test/java/org/matomo/java/tracking/servlet/ServletMatomoRequestTest.java

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,61 +11,62 @@
1111

1212
class ServletMatomoRequestTest {
1313

14+
private MatomoRequest.MatomoRequestBuilder requestBuilder;
15+
16+
private HttpServletRequestWrapper.HttpServletRequestWrapperBuilder wrapperBuilder =
17+
HttpServletRequestWrapper.builder();
18+
1419
@Test
1520
void addsServletRequestHeaders() {
1621

17-
HttpServletRequestWrapper request = HttpServletRequestWrapper
18-
.builder()
22+
wrapperBuilder
1923
.headers(singletonMap("headername", "headerValue"))
2024
.build();
2125

22-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
26+
whenBuildsRequest();
2327

24-
MatomoRequest matomoRequest = builder.build();
28+
MatomoRequest matomoRequest = requestBuilder.build();
2529
assertThat(matomoRequest.getHeaders()).hasSize(1).containsEntry("headername", "headerValue");
2630
}
2731

2832
@Test
2933
void skipsEmptyHeaderNames() {
3034

31-
HttpServletRequestWrapper request = HttpServletRequestWrapper
32-
.builder()
35+
wrapperBuilder
3336
.headers(singletonMap("", "headerValue"))
3437
.build();
3538

36-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
39+
whenBuildsRequest();
3740

38-
MatomoRequest matomoRequest = builder.build();
41+
MatomoRequest matomoRequest = requestBuilder.build();
3942
assertThat(matomoRequest.getHeaders()).isEmpty();
4043

4144
}
4245

4346
@Test
4447
void skipsBlankHeaderNames() {
4548

46-
HttpServletRequestWrapper request = HttpServletRequestWrapper
47-
.builder()
49+
wrapperBuilder
4850
.headers(singletonMap(" ", "headerValue"))
4951
.build();
5052

51-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
53+
whenBuildsRequest();
5254

53-
MatomoRequest matomoRequest = builder.build();
55+
MatomoRequest matomoRequest = requestBuilder.build();
5456
assertThat(matomoRequest.getHeaders()).isEmpty();
5557

5658
}
5759

5860
@ParameterizedTest
5961
@ValueSource(strings = {"connection", "content-length", "expect", "host", "upgrade"})
6062
void doesNotAddRestrictedHeaders(String restrictedHeader) {
61-
HttpServletRequestWrapper request = HttpServletRequestWrapper
62-
.builder()
63+
wrapperBuilder
6364
.headers(singletonMap(restrictedHeader, "headerValue"))
6465
.build();
6566

66-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
67+
whenBuildsRequest();
6768

68-
MatomoRequest matomoRequest = builder.build();
69+
MatomoRequest matomoRequest = requestBuilder.build();
6970
assertThat(matomoRequest.getHeaders()).isEmpty();
7071
}
7172

@@ -88,16 +89,15 @@ void failsIfBuilderIsNull() {
8889

8990
@Test
9091
void extractsVisitorIdFromCookie() {
91-
HttpServletRequestWrapper request = HttpServletRequestWrapper
92-
.builder()
92+
wrapperBuilder
9393
.cookies(new CookieWrapper[] {
9494
new CookieWrapper("_pk_id.1.1fff", "be40d677d6c7270b.1699801331.")
9595
})
9696
.build();
9797

98-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
98+
whenBuildsRequest();
9999

100-
MatomoRequest matomoRequest = builder.build();
100+
MatomoRequest matomoRequest = requestBuilder.build();
101101
assertThat(matomoRequest.getVisitorId()).hasToString("be40d677d6c7270b");
102102
assertThat(matomoRequest.getCookies())
103103
.hasSize(1)
@@ -109,21 +109,19 @@ void extractsVisitorIdFromCookie() {
109109
strings = {"_pk_ses.1.1fff", "_pk_ref.1.1fff", "_pk_hsr.1.1fff"}
110110
)
111111
void extractsMatomoCookies(String cookieName) {
112-
HttpServletRequestWrapper request = HttpServletRequestWrapper
113-
.builder()
112+
wrapperBuilder
114113
.cookies(new CookieWrapper[] {new CookieWrapper(cookieName, "anything")})
115114
.build();
116115

117-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
116+
whenBuildsRequest();
118117

119-
MatomoRequest matomoRequest = builder.build();
118+
MatomoRequest matomoRequest = requestBuilder.build();
120119
assertThat(matomoRequest.getCookies()).hasSize(1).containsEntry(cookieName, "anything");
121120
}
122121

123122
@Test
124123
void extractsSessionIdFromMatomoSessIdCookie() {
125-
HttpServletRequestWrapper request = HttpServletRequestWrapper
126-
.builder()
124+
wrapperBuilder
127125
.cookies(new CookieWrapper[] {
128126
new CookieWrapper(
129127
"MATOMO_SESSID",
@@ -132,16 +130,15 @@ void extractsSessionIdFromMatomoSessIdCookie() {
132130
})
133131
.build();
134132

135-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
133+
whenBuildsRequest();
136134

137-
MatomoRequest matomoRequest = builder.build();
135+
MatomoRequest matomoRequest = requestBuilder.build();
138136
assertThat(matomoRequest.getSessionId()).isEqualTo("2cbf8b5ba00fbf9ba70853308cd0944a");
139137
}
140138

141139
@Test
142140
void parsesVisitCustomVariablesFromCookie() {
143-
HttpServletRequestWrapper request = HttpServletRequestWrapper
144-
.builder()
141+
wrapperBuilder
145142
.cookies(new CookieWrapper[] {
146143
new CookieWrapper(
147144
"_pk_cvar.1.1fff",
@@ -150,9 +147,9 @@ void parsesVisitCustomVariablesFromCookie() {
150147
})
151148
.build();
152149

153-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
150+
whenBuildsRequest();
154151

155-
MatomoRequest matomoRequest = builder.build();
152+
MatomoRequest matomoRequest = requestBuilder.build();
156153
assertThat(matomoRequest.getVisitCustomVariables().get(1).getKey()).isEqualTo(
157154
"VAR 1 set, var 2 not set");
158155
assertThat(matomoRequest.getVisitCustomVariables().get(1).getValue()).isEqualTo("yes");
@@ -163,15 +160,42 @@ void parsesVisitCustomVariablesFromCookie() {
163160

164161
@Test
165162
void determinerVisitorIpFromXForwardedForHeader() {
166-
HttpServletRequestWrapper request = HttpServletRequestWrapper
167-
.builder()
163+
wrapperBuilder
168164
.headers(singletonMap("x-forwarded-for", "44.55.66.77"))
169165
.build();
170166

171-
MatomoRequest.MatomoRequestBuilder builder = ServletMatomoRequest.fromServletRequest(request);
167+
whenBuildsRequest();
172168

173-
MatomoRequest matomoRequest = builder.build();
169+
MatomoRequest matomoRequest = requestBuilder.build();
174170
assertThat(matomoRequest.getVisitorIp()).isEqualTo("44.55.66.77");
175171
}
176172

173+
@Test
174+
void setsActionUrlFromRequestURL() {
175+
wrapperBuilder
176+
.requestURL(new StringBuffer("https://localhost/test"))
177+
.build();
178+
179+
whenBuildsRequest();
180+
181+
MatomoRequest matomoRequest = requestBuilder.build();
182+
assertThat(matomoRequest.getActionUrl()).isEqualTo("https://localhost/test");
183+
}
184+
185+
@Test
186+
void setsUserIdFromRemoteUser() {
187+
wrapperBuilder
188+
.remoteUser("remote-user")
189+
.build();
190+
191+
whenBuildsRequest();
192+
193+
MatomoRequest matomoRequest = requestBuilder.build();
194+
assertThat(matomoRequest.getUserId()).isEqualTo("remote-user");
195+
}
196+
197+
private void whenBuildsRequest() {
198+
requestBuilder = ServletMatomoRequest.fromServletRequest(wrapperBuilder.build());
199+
}
200+
177201
}

servlet-jakarta/src/main/java/org/matomo/java/tracking/servlet/JakartaHttpServletWrapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static HttpServletRequestWrapper fromHttpServletRequest(@NonNull HttpServ
4141
.builder()
4242
.requestURL(request.getRequestURL())
4343
.remoteAddr(request.getRemoteAddr())
44+
.remoteUser(request.getRemoteUser())
4445
.headers(headers)
4546
.cookies(cookies == null ? null : cookies.toArray(new CookieWrapper[0]))
4647
.build();

servlet-jakarta/src/test/java/org/matomo/java/tracking/servlet/JakartaHttpServletWrapperTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ void wrapsHttpServletRequest() {
1414

1515
MockHttpServletRequest servlet = new MockHttpServletRequest();
1616
servlet.setRequestURL(new StringBuffer("http://localhost"));
17+
servlet.setRemoteUser("remote-user");
1718
servlet.setHeaders(singletonMap("Accept-Language", "en-US,en;q=0.9,de;q=0.8"));
1819
servlet.setCookies(List.of(new Cookie("foo", "bar")));
1920

2021
HttpServletRequestWrapper httpServletRequestWrapper =
2122
JakartaHttpServletWrapper.fromHttpServletRequest(servlet);
2223

2324
assertThat(httpServletRequestWrapper.getRequestURL()).hasToString("http://localhost");
25+
assertThat(httpServletRequestWrapper.getRemoteUser()).hasToString("remote-user");
2426
assertThat(httpServletRequestWrapper.getHeaders())
2527
.containsEntry("accept-language", "en-US,en;q=0.9,de;q=0.8");
2628
assertThat(httpServletRequestWrapper.getCookies())

servlet-jakarta/src/test/java/org/matomo/java/tracking/servlet/MockHttpServletRequest.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class MockHttpServletRequest implements HttpServletRequest {
3434

3535
private StringBuffer requestURL;
3636

37+
private String remoteUser;
38+
3739
private Map<String, String> headers = new LinkedHashMap<>();
3840

3941
private Collection<Cookie> cookies;
@@ -98,11 +100,6 @@ public String getQueryString() {
98100
return null;
99101
}
100102

101-
@Override
102-
public String getRemoteUser() {
103-
return null;
104-
}
105-
106103
@Override
107104
public boolean isUserInRole(String role) {
108105
return false;

servlet-javax/src/main/java/org/matomo/java/tracking/servlet/JavaxHttpServletWrapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static HttpServletRequestWrapper fromHttpServletRequest(@NonNull HttpServ
4141
.builder()
4242
.requestURL(request.getRequestURL())
4343
.remoteAddr(request.getRemoteAddr())
44+
.remoteUser(request.getRemoteUser())
4445
.headers(headers)
4546
.cookies(cookies == null ? null : cookies.toArray(new CookieWrapper[0]))
4647
.build();

servlet-javax/src/test/java/org/matomo/java/tracking/servlet/JavaxHttpServletWrapperTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.matomo.java.tracking.servlet;
22

3+
import static java.util.Collections.singleton;
34
import static java.util.Collections.singletonMap;
45
import static org.assertj.core.api.Assertions.assertThat;
56

@@ -14,13 +15,15 @@ void wrapsHttpServletRequest() {
1415

1516
MockHttpServletRequest servlet = new MockHttpServletRequest();
1617
servlet.setRequestURL(new StringBuffer("http://localhost"));
18+
servlet.setRemoteUser("remote-user");
1719
servlet.setHeaders(singletonMap("Accept-Language", "en-US,en;q=0.9,de;q=0.8"));
18-
servlet.setCookies(List.of(new Cookie("foo", "bar")));
20+
servlet.setCookies(singleton(new Cookie("foo", "bar")));
1921

2022
HttpServletRequestWrapper httpServletRequestWrapper =
2123
JavaxHttpServletWrapper.fromHttpServletRequest(servlet);
2224

2325
assertThat(httpServletRequestWrapper.getRequestURL()).hasToString("http://localhost");
26+
assertThat(httpServletRequestWrapper.getRemoteUser()).hasToString("remote-user");
2427
assertThat(httpServletRequestWrapper.getHeaders())
2528
.containsEntry("accept-language", "en-US,en;q=0.9,de;q=0.8");
2629
assertThat(httpServletRequestWrapper.getCookies())

servlet-javax/src/test/java/org/matomo/java/tracking/servlet/MockHttpServletRequest.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class MockHttpServletRequest implements HttpServletRequest {
3333

3434
private StringBuffer requestURL;
3535

36+
private String remoteUser;
37+
3638
private Map<String, String> headers = new LinkedHashMap<>();
3739

3840
private Collection<Cookie> cookies;
@@ -97,11 +99,6 @@ public String getQueryString() {
9799
return null;
98100
}
99101

100-
@Override
101-
public String getRemoteUser() {
102-
return null;
103-
}
104-
105102
@Override
106103
public boolean isUserInRole(String role) {
107104
return false;

test/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
<properties>
1717
<maven.compiler.source>11</maven.compiler.source>
1818
<maven.compiler.target>11</maven.compiler.target>
19+
<maven.surefire.skip>true</maven.surefire.skip>
20+
<maven.jar.skip>true</maven.jar.skip>
21+
<maven.source.skip>true</maven.source.skip>
22+
<maven.javadoc.skip>true</maven.javadoc.skip>
23+
<maven.failsafe.skip>true</maven.failsafe.skip>
24+
<maven.jacoco.skip>true</maven.jacoco.skip>
1925
<maven.install.skip>true</maven.install.skip>
2026
<maven.release.skip>true</maven.release.skip>
2127
<maven.deploy.skip>true</maven.deploy.skip>

0 commit comments

Comments
 (0)