From b35b024cfe141a451d82ae62111a5e1c96f0bfc2 Mon Sep 17 00:00:00 2001
From: Tucker Siegel <tgsiegel@terpmail.umd.edu>
Date: Wed, 12 Apr 2023 14:20:22 -0400
Subject: [PATCH] add userId

---
 .../interceptor/RequestInterceptor.java       |  8 +++
 .../umd/dawn/common/logging/RequestLog.java   |  2 +
 .../DawnHttpServletRequestWrapper.java        | 59 +++++++++++++++++++
 3 files changed, 69 insertions(+)
 create mode 100644 src/main/java/edu/umd/dawn/common/wrappers/DawnHttpServletRequestWrapper.java

diff --git a/src/main/java/edu/umd/dawn/common/interceptor/RequestInterceptor.java b/src/main/java/edu/umd/dawn/common/interceptor/RequestInterceptor.java
index 9f4c329..bfcad47 100644
--- a/src/main/java/edu/umd/dawn/common/interceptor/RequestInterceptor.java
+++ b/src/main/java/edu/umd/dawn/common/interceptor/RequestInterceptor.java
@@ -1,7 +1,9 @@
 package edu.umd.dawn.common.interceptor;
 
+import edu.umd.dawn.common.jwt.Claims;
 import edu.umd.dawn.common.logging.RequestLog;
 import edu.umd.dawn.common.services.UserAgentService;
+import edu.umd.dawn.common.wrappers.DawnHttpServletRequestWrapper;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import java.util.Enumeration;
@@ -25,6 +27,9 @@ public class RequestInterceptor implements HandlerInterceptor {
     
     @Value("${config.serviceName:dawn-service}")
     private String serviceName;
+    
+    @Value("${config.accessSecret:empty}")
+    private String accessSecret;
 
     @Autowired
     private UserAgentService userAgentService;
@@ -97,6 +102,8 @@ public class RequestInterceptor implements HandlerInterceptor {
 
         Map<String, String> headers = getRequestHeaders(request);
 
+        Claims claims = new DawnHttpServletRequestWrapper(request, accessSecret).getClaims();
+
         RequestLog requestLog = RequestLog.builder()
                 .path(path)
                 .method(request.getMethod())
@@ -105,6 +112,7 @@ public class RequestInterceptor implements HandlerInterceptor {
                 .parameters(getParemeters(request))
                 .duration(executeTime)
                 .userAgent(userAgentService.parse(headers))
+                .userId(claims.getUserId())
                 .build();
 
         log.log(Level.forName("REQUEST", 10), requestLog);
diff --git a/src/main/java/edu/umd/dawn/common/logging/RequestLog.java b/src/main/java/edu/umd/dawn/common/logging/RequestLog.java
index e570cf6..60088d0 100644
--- a/src/main/java/edu/umd/dawn/common/logging/RequestLog.java
+++ b/src/main/java/edu/umd/dawn/common/logging/RequestLog.java
@@ -18,6 +18,8 @@ public class RequestLog extends Log {
     @Builder.Default
     private String type = "request";
 
+    private String userId;
+
     private double duration;
     private int statusCode;
     private String method;
diff --git a/src/main/java/edu/umd/dawn/common/wrappers/DawnHttpServletRequestWrapper.java b/src/main/java/edu/umd/dawn/common/wrappers/DawnHttpServletRequestWrapper.java
new file mode 100644
index 0000000..f2e21ba
--- /dev/null
+++ b/src/main/java/edu/umd/dawn/common/wrappers/DawnHttpServletRequestWrapper.java
@@ -0,0 +1,59 @@
+package edu.umd.dawn.common.wrappers;
+
+import edu.umd.dawn.common.jwt.Claims;
+import edu.umd.dawn.common.jwt.JWTUtil;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+public class DawnHttpServletRequestWrapper extends HttpServletRequestWrapper {
+
+    private String accessSecret;
+
+    public DawnHttpServletRequestWrapper(HttpServletRequest request) {
+        super(request);
+    }
+
+    public DawnHttpServletRequestWrapper(HttpServletRequest request, String accessSecret) {
+        super(request);
+        this.accessSecret = accessSecret;
+    }
+
+    /**
+     * try everything possible to get the claims
+     * @return
+     */
+    public Claims getClaims() {
+        Claims claims = (Claims) getAttribute("claims");
+        if (claims != null) {
+            return claims;
+        }
+
+        if (accessSecret.equals("empty")) {
+            log.warn("This service has not been provided the configuration value for `config.accessSecret` in the application.properties configuration. Since it uses the JWTInterceptor, this is a required value for proper functionality.");
+        }
+
+        String token = (String) getAttribute("token");
+        if (token != null) {
+            try {
+                return JWTUtil.parse(accessSecret, token).getClaims();
+            } catch (Exception e) {
+            }
+        }
+
+        String jwtHeader = (String) getHeader("Authorization");
+        if (jwtHeader.startsWith("Bearer ")) {
+            jwtHeader.replace("Bearer ", "");
+        }
+
+        try {
+            return JWTUtil.parse(accessSecret, jwtHeader).getClaims();
+        } catch (Exception e) {
+        }
+
+        return null;
+
+    }
+    
+}
-- 
GitLab