Skip to content

Commit e392279

Browse files
committed
Added request headers to all EE event details payload
1 parent c42c0e0 commit e392279

File tree

7 files changed

+77
-38
lines changed

7 files changed

+77
-38
lines changed

server/api-service/lowcoder-dependencies/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<dependency>
2727
<groupId>org.lowcoder.plugin</groupId>
2828
<artifactId>lowcoder-plugin-api</artifactId>
29-
<version>2.3.0</version>
29+
<version>2.3.1</version>
3030
</dependency>
3131

3232
<dependency>

server/api-service/lowcoder-infra/src/main/java/org/lowcoder/infra/event/AbstractEvent.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import lombok.Setter;
55
import lombok.experimental.SuperBuilder;
66
import org.lowcoder.plugin.api.event.LowcoderEvent;
7+
import org.lowcoder.sdk.constants.GlobalContext;
8+
import reactor.util.context.ContextView;
79

810
import java.lang.reflect.Field;
911
import java.util.HashMap;
@@ -19,6 +21,7 @@ public abstract class AbstractEvent implements LowcoderEvent
1921
protected final Boolean isAnonymous;
2022
private final String ipAddress;
2123
protected Map<String, Object> details;
24+
protected Map<String, String> eventHeaders;
2225
@Setter
2326
private static String environmentID;
2427

@@ -42,7 +45,10 @@ public B detail(String name, String value)
4245
}
4346
}
4447

45-
public void populateDetails() {
48+
public void populateDetails(ContextView contextView) {
49+
//populate eventHeaders field
50+
eventHeaders = contextView.get(GlobalContext.HEADERS);
51+
4652
if (details == null) {
4753
details = new HashMap<>();
4854
}
@@ -57,5 +63,8 @@ public void populateDetails() {
5763

5864
}
5965
details.put("environmentId", environmentID);
66+
if(!details.containsKey("headers")) {
67+
details.put("headers", eventHeaders);
68+
}
6069
}
6170
}

server/api-service/lowcoder-sdk/src/main/java/org/lowcoder/sdk/constants/GlobalContext.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ public class GlobalContext {
1616

1717
public static final String CURRENT_ORG_MEMBER = "currentOrgMember";
1818
public static final String DOMAIN = "domain";
19+
public static final String HEADERS = "headers";
1920
}

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/filter/ApiEventFilter.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.springframework.web.server.WebFilterChain;
1818
import reactor.core.publisher.Mono;
1919
import reactor.core.scheduler.Schedulers;
20+
import reactor.util.context.ContextView;
2021

2122
import java.nio.charset.StandardCharsets;
2223
import java.util.Optional;
@@ -40,7 +41,7 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
4041
String token = contextView.get(VISITOR_TOKEN);
4142
((Mono<OrgMember>) contextView.get(CURRENT_ORG_MEMBER))
4243
.flatMap(orgMember -> {
43-
emitEvent(exchange.getRequest(), token, orgMember);
44+
emitEvent(exchange.getRequest(), token, orgMember, contextView);
4445
return Mono.empty();
4546
})
4647
.subscribeOn(Schedulers.boundedElastic())
@@ -51,7 +52,7 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
5152
);
5253
}
5354

54-
private void emitEvent(ServerHttpRequest request, String token, OrgMember orgMember) {
55+
private void emitEvent(ServerHttpRequest request, String token, OrgMember orgMember, ContextView contextView) {
5556
MultiValueMap<String, String> headers = writableHttpHeaders(request.getHeaders());
5657
headers.remove("Cookie");
5758
Optional<String> ipAddressOptional = headers.remove("X-Real-IP").stream().findFirst();
@@ -69,7 +70,7 @@ private void emitEvent(ServerHttpRequest request, String token, OrgMember orgMem
6970
.queryParams(request.getQueryParams())
7071
.ipAddress(ipAddress)
7172
.build();
72-
event.populateDetails();
73+
event.populateDetails(contextView);
7374

7475
log.debug("API call event emitted for '{}' from org '{}' on URI: {}", orgMember.getUserId(), orgMember.getUserId(), request.getURI().getPath());
7576
applicationEventPublisher.publishEvent(event);

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/filter/GlobalContextFilter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.springframework.http.HttpMethod;
1717
import org.springframework.http.server.reactive.ServerHttpRequest;
1818
import org.springframework.stereotype.Component;
19+
import org.springframework.util.MultiValueMap;
1920
import org.springframework.web.server.ServerWebExchange;
2021
import org.springframework.web.server.WebFilter;
2122
import org.springframework.web.server.WebFilterChain;
@@ -32,6 +33,7 @@
3233
import static org.lowcoder.sdk.constants.Authentication.isAnonymousUser;
3334
import static org.lowcoder.sdk.constants.GlobalContext.*;
3435
import static org.lowcoder.sdk.util.IDUtils.generate;
36+
import static org.springframework.http.HttpHeaders.writableHttpHeaders;
3537

3638
@Component
3739
@RequiredArgsConstructor
@@ -107,6 +109,11 @@ private Map<String, Object> buildContextMap(ServerWebExchange serverWebExchange,
107109
contextMap.put(CURRENT_ORG_MEMBER, orgMemberService.getCurrentOrgMember(visitorId).cache());
108110
contextMap.put(VISITOR_TOKEN, cookieHelper.getCookieToken(serverWebExchange));
109111
contextMap.put(DOMAIN, UriUtils.getRefererDomainFromRequest(serverWebExchange));
112+
113+
//Analytics related fields
114+
MultiValueMap<String, String> headers = writableHttpHeaders(request.getHeaders());
115+
headers.remove("Cookie");
116+
contextMap.put(HEADERS, headers);
110117
return contextMap;
111118
}
112119

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/ApiCallEventPublisher.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ public Object handleAPICallEvent(ProceedingJoinPoint joinPoint) throws Throwable
5454
return sessionUserService.getVisitorToken()
5555
.zipWith(sessionUserService.getVisitorOrgMemberCacheSilent().defaultIfEmpty(OrgMember.NOT_EXIST))
5656
.zipWith(ReactiveRequestContextHolder.getRequest())
57-
.doOnNext(
57+
.delayUntil(
5858
tuple -> {
5959
String token = tuple.getT1().getT1();
6060
OrgMember orgMember = tuple.getT1().getT2();
6161
ServerHttpRequest request = tuple.getT2();
6262
if (orgMember == OrgMember.NOT_EXIST) {
63-
return;
63+
return Mono.empty();
6464
}
6565
MultiValueMap<String, String> headers = writableHttpHeaders(request.getHeaders());
6666
headers.remove("Cookie");
@@ -77,8 +77,11 @@ public Object handleAPICallEvent(ProceedingJoinPoint joinPoint) throws Throwable
7777
.queryParams(request.getQueryParams())
7878
.ipAddress(ipAddress)
7979
.build();
80-
event.populateDetails();
81-
applicationEventPublisher.publishEvent(event);
80+
return Mono.deferContextual(contextView -> {
81+
event.populateDetails(contextView);
82+
applicationEventPublisher.publishEvent(event);
83+
return Mono.empty();
84+
});
8285
})
8386
.onErrorResume(throwable -> {
8487
log.error("handleAPICallEvent error {} for: {} ", joinPoint.getSignature().getName(), EventType.API_CALL_EVENT, throwable);

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/util/BusinessEventPublisher.java

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public Mono<Void> publishFolderCommonEvent(String folderId, String folderName, E
7474

7575
return sessionUserService.getVisitorToken()
7676
.zipWith(sessionUserService.getVisitorOrgMemberCache())
77-
.doOnNext(
77+
.delayUntil(
7878
tuple -> {
7979
String token = tuple.getT1();
8080
OrgMember orgMember = tuple.getT2();
@@ -87,8 +87,11 @@ public Mono<Void> publishFolderCommonEvent(String folderId, String folderName, E
8787
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
8888
.sessionHash(Hashing.sha512().hashString(token, StandardCharsets.UTF_8).toString())
8989
.build();
90-
event.populateDetails();
91-
applicationEventPublisher.publishEvent(event);
90+
return Mono.deferContextual(contextView -> {
91+
event.populateDetails(contextView);
92+
applicationEventPublisher.publishEvent(event);
93+
return Mono.empty();
94+
});
9295
})
9396
.then()
9497
.onErrorResume(throwable -> {
@@ -151,7 +154,7 @@ public Mono<Void> publishApplicationCommonEvent(ApplicationView applicationView,
151154
return Pair.of(category, description);
152155
});
153156
}), TupleUtils::merge)
154-
.doOnNext(tuple -> {
157+
.delayUntil(tuple -> {
155158
OrgMember orgMember = tuple.getT1().getT1();
156159
Optional<Folder> optional = tuple.getT1().getT2();
157160
Optional<Folder> optionalFrom = tuple.getT1().getT3();
@@ -175,8 +178,11 @@ public Mono<Void> publishApplicationCommonEvent(ApplicationView applicationView,
175178
.isAnonymous(anonymous)
176179
.sessionHash(Hashing.sha512().hashString(token, StandardCharsets.UTF_8).toString())
177180
.build();
178-
event.populateDetails();
179-
applicationEventPublisher.publishEvent(event);
181+
return Mono.deferContextual(contextView -> {
182+
event.populateDetails(contextView);
183+
applicationEventPublisher.publishEvent(event);
184+
return Mono.empty();
185+
});
180186
})
181187
.then()
182188
.onErrorResume(throwable -> {
@@ -188,7 +194,7 @@ public Mono<Void> publishApplicationCommonEvent(ApplicationView applicationView,
188194

189195
public Mono<Void> publishUserLoginEvent(String source) {
190196
return sessionUserService.getVisitorOrgMember().zipWith(sessionUserService.getVisitorToken())
191-
.doOnNext(tuple -> {
197+
.delayUntil(tuple -> {
192198
OrgMember orgMember = tuple.getT1();
193199
String token = tuple.getT2();
194200
UserLoginEvent event = UserLoginEvent.builder()
@@ -198,8 +204,11 @@ public Mono<Void> publishUserLoginEvent(String source) {
198204
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
199205
.sessionHash(Hashing.sha512().hashString(token, StandardCharsets.UTF_8).toString())
200206
.build();
201-
event.populateDetails();
202-
applicationEventPublisher.publishEvent(event);
207+
return Mono.deferContextual(contextView -> {
208+
event.populateDetails(contextView);
209+
applicationEventPublisher.publishEvent(event);
210+
return Mono.empty();
211+
});
203212
})
204213
.then()
205214
.onErrorResume(throwable -> {
@@ -211,7 +220,7 @@ public Mono<Void> publishUserLoginEvent(String source) {
211220
public Mono<Void> publishUserLogoutEvent() {
212221
return sessionUserService.getVisitorOrgMemberCache()
213222
.zipWith(sessionUserService.getVisitorToken())
214-
.doOnNext(tuple -> {
223+
.delayUntil(tuple -> {
215224
OrgMember orgMember = tuple.getT1();
216225
String token = tuple.getT2();
217226
UserLogoutEvent event = UserLogoutEvent.builder()
@@ -220,8 +229,11 @@ public Mono<Void> publishUserLogoutEvent() {
220229
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
221230
.sessionHash(Hashing.sha512().hashString(token, StandardCharsets.UTF_8).toString())
222231
.build();
223-
event.populateDetails();
224-
applicationEventPublisher.publishEvent(event);
232+
return Mono.deferContextual(contextView -> {
233+
event.populateDetails(contextView);
234+
applicationEventPublisher.publishEvent(event);
235+
return Mono.empty();
236+
});
225237
})
226238
.then()
227239
.onErrorResume(throwable -> {
@@ -244,7 +256,7 @@ public Mono<Void> publishGroupCreateEvent(Group group) {
244256
.isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId()))
245257
.sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString())
246258
.build();
247-
event.populateDetails();
259+
event.populateDetails(contextView);
248260
applicationEventPublisher.publishEvent(event);
249261
return Mono.empty();
250262
}))
@@ -272,7 +284,7 @@ public Mono<Void> publishGroupUpdateEvent(boolean publish, Group previousGroup,
272284
.isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId()))
273285
.sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString())
274286
.build();
275-
event.populateDetails();
287+
event.populateDetails(contextView);
276288
applicationEventPublisher.publishEvent(event);
277289
return Mono.empty();
278290
}))
@@ -300,7 +312,7 @@ public Mono<Void> publishGroupDeleteEvent(boolean publish, Group previousGroup)
300312
.isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId()))
301313
.sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString())
302314
.build();
303-
event.populateDetails();
315+
event.populateDetails(contextView);
304316
applicationEventPublisher.publishEvent(event);
305317
return Mono.empty();
306318
}))
@@ -337,7 +349,7 @@ public Mono<Void> publishGroupMemberAddEvent(boolean publish, String groupId, Ad
337349
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
338350
.sessionHash(Hashing.sha512().hashString(token, StandardCharsets.UTF_8).toString())
339351
.build();
340-
event.populateDetails();
352+
event.populateDetails(contextView);
341353
applicationEventPublisher.publishEvent(event);
342354
return Mono.empty();
343355
}))
@@ -374,7 +386,7 @@ public Mono<Void> publishGroupMemberRoleUpdateEvent(boolean publish, String grou
374386
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
375387
.sessionHash(Hashing.sha512().hashString(tuple.getT4(), StandardCharsets.UTF_8).toString())
376388
.build();
377-
event.populateDetails();
389+
event.populateDetails(contextView);
378390
applicationEventPublisher.publishEvent(event);
379391
return Mono.empty();
380392
}))
@@ -410,7 +422,7 @@ public Mono<Void> publishGroupMemberLeaveEvent(boolean publish, GroupMember grou
410422
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
411423
.sessionHash(Hashing.sha512().hashString(tuple.getT4(), StandardCharsets.UTF_8).toString())
412424
.build();
413-
event.populateDetails();
425+
event.populateDetails(contextView);
414426
applicationEventPublisher.publishEvent(event);
415427
return Mono.empty();
416428
}))
@@ -446,7 +458,7 @@ public Mono<Void> publishGroupMemberRemoveEvent(boolean publish, GroupMember pre
446458
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
447459
.sessionHash(Hashing.sha512().hashString(tuple.getT4(), StandardCharsets.UTF_8).toString())
448460
.build();
449-
event.populateDetails();
461+
event.populateDetails(contextView);
450462
applicationEventPublisher.publishEvent(event);
451463
return Mono.empty();
452464
}))
@@ -484,9 +496,11 @@ public Mono<Void> publishDatasourceEvent(Datasource datasource, EventType eventT
484496
.isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId()))
485497
.sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString())
486498
.build();
487-
event.populateDetails();
488-
applicationEventPublisher.publishEvent(event);
489-
return Mono.<Void> empty();
499+
return Mono.deferContextual(contextView -> {
500+
event.populateDetails(contextView);
501+
applicationEventPublisher.publishEvent(event);
502+
return Mono.<Void>empty();
503+
});
490504
})
491505
.onErrorResume(throwable -> {
492506
log.error("publishDatasourceEvent error.", throwable);
@@ -535,9 +549,11 @@ public Mono<Void> publishDatasourcePermissionEvent(String datasourceId,
535549
.isAnonymous(Authentication.isAnonymousUser(orgMember.getUserId()))
536550
.sessionHash(Hashing.sha512().hashString(tuple.getT3(), StandardCharsets.UTF_8).toString())
537551
.build();
538-
datasourcePermissionEvent.populateDetails();
539-
applicationEventPublisher.publishEvent(datasourcePermissionEvent);
540-
return Mono.<Void> empty();
552+
return Mono.deferContextual(contextView -> {
553+
datasourcePermissionEvent.populateDetails(contextView);
554+
applicationEventPublisher.publishEvent(datasourcePermissionEvent);
555+
return Mono.<Void>empty();
556+
});
541557
})
542558
.onErrorResume(throwable -> {
543559
log.error("publishDatasourcePermissionEvent error.", throwable);
@@ -552,7 +568,7 @@ public Mono<Void> publishLibraryQuery(LibraryQuery libraryQuery, EventType event
552568
public Mono<Void> publishLibraryQueryEvent(String id, String name, EventType eventType) {
553569
return sessionUserService.getVisitorOrgMemberCache()
554570
.zipWith(sessionUserService.getVisitorToken())
555-
.map(tuple -> {
571+
.flatMap(tuple -> {
556572
LibraryQueryEvent event = LibraryQueryEvent.builder()
557573
.userId(tuple.getT1().getUserId())
558574
.orgId(tuple.getT1().getOrgId())
@@ -562,10 +578,12 @@ public Mono<Void> publishLibraryQueryEvent(String id, String name, EventType eve
562578
.isAnonymous(Authentication.isAnonymousUser(tuple.getT1().getUserId()))
563579
.sessionHash(Hashing.sha512().hashString(tuple.getT2(), StandardCharsets.UTF_8).toString())
564580
.build();
565-
event.populateDetails();
566-
return event;
581+
return Mono.deferContextual(contextView -> {
582+
event.populateDetails(contextView);
583+
applicationEventPublisher.publishEvent(event);
584+
return Mono.<Void>empty();
585+
});
567586
})
568-
.doOnNext(applicationEventPublisher::publishEvent)
569587
.then()
570588
.onErrorResume(throwable -> {
571589
log.error("publishLibraryQueryEvent error.", throwable);

0 commit comments

Comments
 (0)