Skip to content

Commit

Permalink
Merge pull request #552 from bcgov/hotfix/GRAD2-3012
Browse files Browse the repository at this point in the history
GRAD2-3012: task is complete.
  • Loading branch information
infstar authored Nov 25, 2024
2 parents 6098c94 + bc1d150 commit f4a3a96
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package ca.bc.gov.educ.api.graduation.config;

import ca.bc.gov.educ.api.graduation.util.EducGraduationApiConstants;
import ca.bc.gov.educ.api.graduation.util.GradValidation;
import ca.bc.gov.educ.api.graduation.util.LogHelper;
import ca.bc.gov.educ.api.graduation.util.ThreadLocalStateUtil;
import ca.bc.gov.educ.api.graduation.util.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

Expand Down Expand Up @@ -42,6 +43,14 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
if (correlationID != null) {
ThreadLocalStateUtil.setCorrelationID(correlationID);
}

// username
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof JwtAuthenticationToken authenticationToken) {
Jwt jwt = (Jwt) authenticationToken.getCredentials();
String username = JwtUtil.getName(jwt, request);
ThreadLocalStateUtil.setCurrentUser(username);
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ public <T> T get(String url, Class<T> clazz) {
obj = graduationServiceWebClient
.get()
.uri(url)
.headers(h -> h.set(EducGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID()))
.headers(h -> {
h.set(EducGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID());
h.set(EducGraduationApiConstants.USERNAME, ThreadLocalStateUtil.getCurrentUser());
})
.retrieve()
// if 5xx errors, throw Service error
.onStatus(HttpStatusCode::is5xxServerError,
Expand Down Expand Up @@ -141,7 +144,10 @@ public <T> T post(String url, Object body, Class<T> clazz) {
try {
obj = graduationServiceWebClient.post()
.uri(url)
.headers(h -> h.set(EducGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID()))
.headers(h -> {
h.set(EducGraduationApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID());
h.set(EducGraduationApiConstants.USERNAME, ThreadLocalStateUtil.getCurrentUser());
})
.body(BodyInserters.fromValue(body))
.retrieve()
.onStatus(HttpStatusCode::is5xxServerError,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public class EducGraduationApiConstants {

public static final String CORRELATION_ID = "correlationID";
public static final String USERNAME = "username";

//API end-point Mapping constants
public static final String API_ROOT_MAPPING = "";
Expand Down
94 changes: 94 additions & 0 deletions api/src/main/java/ca/bc/gov/educ/api/graduation/util/JwtUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package ca.bc.gov.educ.api.graduation.util;

import jakarta.servlet.http.HttpServletRequest;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.oauth2.jwt.Jwt;

import java.util.Map;

/**
* The type JWT util.
*/
public class JwtUtil {

private JwtUtil() {
}

/**
* Gets username string from object.
*
* @param jwt the JWT
* @return the username string from jwt
*/
public static String getUsername(Jwt jwt) {
return (String) jwt.getClaims().get("preferred_username");
}

/**
* Gets email string from object.
*
* @param jwt the JWT
* @return the username string from jwt
*/
public static String getEmail(Jwt jwt) {
return (String) jwt.getClaims().get("email");
}

/**
* Gets name string from object.
*
* @param jwt the JWT
* @return the username string from jwt
*/
public static String getName(Jwt jwt) {
StringBuilder sb = new StringBuilder();
if (isServiceAccount(jwt.getClaims())) {
sb.append("Batch Process");
} else {
String givenName = (String) jwt.getClaims().get("given_name");
if (StringUtils.isNotBlank(givenName)) {
sb.append(givenName.charAt(0));
}
String familyName = (String) jwt.getClaims().get("family_name");
sb.append(familyName);
}
return sb.toString();
}

/**
* Gets name string
* => If it is service account, get it from request header. Otherwise, get username from jwt
*
* @param jwt the JWT
* @param request the Request Header
* @return the username string
*/
public static String getName(Jwt jwt, HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
if (isServiceAccount(jwt.getClaims())) {
sb.append(getUserNameString(request));
} else {
String givenName = (String) jwt.getClaims().get("given_name");
if (StringUtils.isNotBlank(givenName)) {
sb.append(givenName.charAt(0));
}
String familyName = (String) jwt.getClaims().get("family_name");
sb.append(familyName);
}
return sb.toString();
}

private static String getUserNameString(HttpServletRequest request) {
val username = request.getHeader(EducGraduationApiConstants.USERNAME);
if (StringUtils.isNotBlank(username)) {
return username;
} else {
return "Batch Process";
}
}

public static boolean isServiceAccount(Map<String, Object> claims) {
return !claims.containsKey("family_name");
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package ca.bc.gov.educ.api.graduation.util;

import java.util.Objects;

public class ThreadLocalStateUtil {
private static ThreadLocal<String> transaction = new ThreadLocal<>();

private static ThreadLocal<String> user = new ThreadLocal<>();

/**
* Set the current correlationID for this thread
*
Expand All @@ -21,7 +25,26 @@ public static String getCorrelationID() {
return transaction.get();
}

/**
* Set the current user for this thread
*
* @param currentUser
*/
public static void setCurrentUser(String currentUser){
user.set(currentUser);
}

/**
* Get the current user for this thread
*
* @return the username of the current user, or null if it is unknown.
*/
public static String getCurrentUser() {
return Objects.requireNonNullElse(user.get(), "GRAD");
}

public static void clear() {
transaction.remove();
user.remove();
}
}

0 comments on commit f4a3a96

Please sign in to comment.