diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/CourseConfiguration.java b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/CourseConfiguration.java index 7c3a964ac..e36bde1df 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/lessons/CourseConfiguration.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/lessons/CourseConfiguration.java @@ -27,8 +27,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentHints; import org.owasp.webgoat.assignments.AttackResult; -import org.owasp.webgoat.lessons.Lesson; -import org.owasp.webgoat.lessons.Assignment; import org.owasp.webgoat.session.Course; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,6 +37,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import java.util.*; import static java.util.stream.Collectors.groupingBy; @@ -75,16 +74,26 @@ public class CourseConfiguration { private String getPath(Class e) { for (Method m : e.getMethods()) { - if (m.getReturnType() == AttackResult.class) { + if (methodReturnTypeIsOfTypeAttackResult(m)) { var mapping = getMapping(m); - if (mapping == null) { - log.error("AttackResult method found without mapping in: {}", e.getSimpleName()); - } else { + if (mapping != null) { return mapping; } } } - return "none"; + throw new IllegalStateException("Assignment endpoint: " + e + " has no mapping like @GetMapping/@PostMapping etc," + + "with return type 'AttackResult' or 'ResponseEntity' please consider adding one"); + } + + private boolean methodReturnTypeIsOfTypeAttackResult(Method m) { + if (m.getReturnType() == AttackResult.class) { + return true; + } + var genericType = m.getGenericReturnType(); + if (genericType instanceof ParameterizedType) { + return ((ParameterizedType) m.getGenericReturnType()).getActualTypeArguments()[0] == AttackResult.class; + } + return false; } private String getMapping(Method m) { @@ -100,9 +109,9 @@ public class CourseConfiguration { paths = ArrayUtils.addAll(m.getAnnotation(PutMapping.class).value(), m.getAnnotation(PutMapping.class).path()); } if (paths == null) { - return ""; + return null; } else { - return Arrays.stream(paths).filter(path -> !"".equals(path)).findFirst().orElseGet(() -> ""); + return Arrays.stream(paths).filter(path -> !"".equals(path)).findFirst().orElse(""); } } diff --git a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTRefreshEndpoint.java b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTRefreshEndpoint.java index ce7c90cc0..39b63c326 100644 --- a/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTRefreshEndpoint.java +++ b/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/jwt/JWTRefreshEndpoint.java @@ -26,6 +26,7 @@ import io.jsonwebtoken.*; import org.apache.commons.lang3.RandomStringUtils; import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AttackResult; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -82,7 +83,7 @@ public class JWTRefreshEndpoint extends AssignmentEndpoint { @PostMapping("/JWT/refresh/checkout") @ResponseBody - public ResponseEntity checkout(@RequestHeader(value = "Authorization", required = false) String token) { + public ResponseEntity checkout(@RequestHeader(value = "Authorization", required = false) String token) { if (token == null) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); }