Skip to content

Commit

Permalink
Merge branch 'main' into grad-release
Browse files Browse the repository at this point in the history
  • Loading branch information
cditcher committed Dec 13, 2024
2 parents 5130620 + 03e032e commit eaf45af
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 10 deletions.
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ updates:
schedule:
interval: "daily"
target-branch: "grad-release"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,6 @@ jobs:
# now hit it with a zap scan
- name: ZAP Scan
uses: zaproxy/action-api-scan@v0.7.0
uses: zaproxy/action-api-scan@v0.9.0
with:
target: 'https://${{ env.REPO_NAME }}-${{ env.OPENSHIFT_NAMESPACE }}.apps.silver.devops.gov.bc.ca/api/v1/api-docs'
2 changes: 1 addition & 1 deletion .github/workflows/build.from.main.branch.deploy.to.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,6 @@ jobs:
# now hit it with a zap scan
- name: ZAP Scan
uses: zaproxy/action-api-scan@v0.7.0
uses: zaproxy/action-api-scan@v0.9.0
with:
target: 'https://${{ env.REPO_NAME }}-${{ env.OPENSHIFT_NAMESPACE }}.apps.silver.devops.gov.bc.ca/api/v1/api-docs'
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,6 @@ jobs:
# now hit it with a zap scan
- name: ZAP Scan
uses: zaproxy/action-api-scan@v0.7.0
uses: zaproxy/action-api-scan@v0.9.0
with:
target: 'https://${{ env.REPO_NAME }}-${{ env.OPENSHIFT_NAMESPACE }}.apps.silver.devops.gov.bc.ca/api/v1/api-docs'
2 changes: 1 addition & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>ca.bc.gov.educ</groupId>
<artifactId>educ-grad-graduation-api</artifactId>

<version>1.8.65</version>
<version>1.8.66</version>
<name>educ-grad-graduation-api</name>
<description>Ministry of Education GRAD GRADUATION API</description>

Expand Down
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 eaf45af

Please sign in to comment.