-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(FSADT1-1631): updating details api for legacy clients (#1356)
* feat(FSADT1-1631): removing unused code * chore: updating legacy api * feat(FSADT1-1631): added context propagator for roles - Reused the MDC for role context propagator. - Refactored the UserID filter - Extracted the context propagator filter * chore: small update on the DTO * chore: added the role mdc constant * feat(FSADT1-1631): updated principal util roles to set - Changed to SET from LIST to account for unique values * feat(FSADT1-1631): added client details obfuscator - This will obfuscate values based on roles and fields * feat(FSADT1-1631): added location and contact load * test(FSADT1-1631): added tests * chore: removed print * Doing code reviews * Doing code reviews * chore: fixing discrepancies * chore: fixing sonar issues * chore: fixing sonar issues * chore: fixing sonar issues * chore: fixing sonar issues * chore: fixing sonar issues * chore: fixing sonar issues * chore: fixing discrepancies * chore: fixing discrepancies * test: adding test --------- Co-authored-by: Maria Martinez <[email protected]>
- Loading branch information
1 parent
d162b23
commit 803f583
Showing
22 changed files
with
1,105 additions
and
372 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
backend/src/main/java/ca/bc/gov/app/controller/filters/ContextPropagatorWebFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package ca.bc.gov.app.controller.filters; | ||
|
||
import io.micrometer.context.ContextRegistry; | ||
import java.util.function.Function; | ||
import org.slf4j.MDC; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.ReactiveSecurityContextHolder; | ||
import org.springframework.security.core.context.SecurityContext; | ||
import org.springframework.web.server.ServerWebExchange; | ||
import org.springframework.web.server.WebFilter; | ||
import org.springframework.web.server.WebFilterChain; | ||
import reactor.core.publisher.Mono; | ||
import reactor.util.context.Context; | ||
|
||
/** | ||
* This class is a web filter that extracts a value from the security context and sets it in the MDC | ||
* (Mapped Diagnostic Context) for logging and tracing purposes. The value is then propagated down | ||
* the filter chain and set in the reactive context to ensure it is available for logging and | ||
* tracing in both reactive and non-reactive parts of the application. | ||
*/ | ||
public abstract class ContextPropagatorWebFilter implements WebFilter { | ||
|
||
protected abstract String getContextKey(); | ||
|
||
protected abstract Function<Authentication, String> getContextValueExtractor(); | ||
|
||
/** | ||
* Filters each incoming request to extract from the security context a {@link String} value using | ||
* {@link #getContextValueExtractor()} and set it in the MDC. The value is then propagated down | ||
* the filter chain and set in the reactive context to ensure it is available for logging and | ||
* tracing in both reactive and non-reactive parts of the application. | ||
* | ||
* @param exchange The current server web exchange that contains information about the request and | ||
* response. | ||
* @param chain The web filter chain that allows the filter to pass on the request to the next | ||
* entity in the chain. | ||
* @return A {@link Mono} of {@link Void} that indicates when request handling is complete. | ||
*/ | ||
@Override | ||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { | ||
// This is to be able to tackle non-reactive context | ||
contextLoad(); | ||
|
||
return | ||
// Here we are getting the user id from the security context | ||
ReactiveSecurityContextHolder | ||
.getContext() | ||
.map(SecurityContext::getAuthentication) | ||
.map(getContextValueExtractor()) | ||
// Then we set it to the MDC | ||
.doOnNext(userId -> MDC.put(getContextKey(), userId)) | ||
// Then we chain the filter, passing the context down | ||
.flatMap(userId -> chain | ||
.filter(exchange) | ||
.contextWrite(Context.of(getContextKey(), userId)) | ||
// While we are at it, we also set the context for the reactive part | ||
.doOnNext(v -> contextLoad()) | ||
); | ||
} | ||
|
||
/** | ||
* Initializes and registers a thread-local context for the current thread. This method configures | ||
* the {@link ContextRegistry} to handle the value within the MDC (Mapped Diagnostic Context), | ||
* allowing for the propagation of the value across different parts of the application that run on | ||
* the same thread. It specifically sets up accessors for getting, setting, and removing the value | ||
* from the MDC. This setup is crucial for maintaining state across the reactive and non-reactive | ||
* parts of the application. | ||
*/ | ||
private void contextLoad() { | ||
ContextRegistry | ||
.getInstance() | ||
.registerThreadLocalAccessor( | ||
getContextKey(), | ||
() -> MDC.get(getContextKey()), | ||
userId -> MDC.put(getContextKey(), userId), | ||
() -> MDC.remove(getContextKey()) | ||
); | ||
} | ||
|
||
} |
Oops, something went wrong.