mirror of
https://github.com/apache/struts.git
synced 2026-08-06 07:06:58 +00:00
fix(core): enforce class-level HTTP method annotations for wildcard-resolved unannotated methods (#1690)
The WW-5535 fix (commit 4d2eb93) corrected isMethodSpecified() for wildcard-resolved
methods but introduced a structural gap in HttpMethodInterceptor.intercept().
The if/else-if structure made the class-level annotation check unreachable whenever
isMethodSpecified()=true and the resolved method carries no method-level annotation:
if (isMethodSpecified()) {
if (isAnnotatedBy(method)) { ... }
// falls through silently
} else if (isAnnotatedBy(class)) { ... } // never reached
return invocation.invoke(); // no enforcement
Fix: convert else-if to standalone if so the class-level check is always evaluated
as a fallback when the method itself has no annotation. Method-level annotations
still take precedence (checked first).
Add two regression tests covering the wildcard-resolved unannotated method scenario.
Co-authored-by: g0w6y <g0w6y@users.noreply.github.com>
This commit is contained in:
+2
-1
@@ -90,7 +90,8 @@ public class HttpMethodInterceptor extends AbstractInterceptor {
|
||||
invocation.getProxy().getMethod(), AllowedHttpMethod.class.getSimpleName(), request.getMethod());
|
||||
return doIntercept(invocation, method);
|
||||
}
|
||||
} else if (AnnotationUtils.isAnnotatedBy(action.getClass(), HTTP_METHOD_ANNOTATIONS)) {
|
||||
}
|
||||
if (AnnotationUtils.isAnnotatedBy(action.getClass(), HTTP_METHOD_ANNOTATIONS)) {
|
||||
LOG.debug("Action: {} annotated with: {}, checking if request: {} meets allowed methods!",
|
||||
action, AllowedHttpMethod.class.getSimpleName(), request.getMethod());
|
||||
return doIntercept(invocation, action.getClass());
|
||||
|
||||
+45
@@ -273,6 +273,51 @@ public class HttpMethodInterceptorTest extends StrutsInternalTestCase {
|
||||
invocation.setProxy(actionProxy);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Regression: wildcard-resolved method with NO method-level annotation on a class
|
||||
* that has a class-level @AllowedHttpMethod(POST) — GET must be rejected.
|
||||
* The WW-5535 fix introduced an if/else-if that made the class-level check
|
||||
* unreachable when isMethodSpecified()=true and the method is unannotated.
|
||||
*/
|
||||
public void testWildcardResolvedUnannotatedMethodRespectsClassLevelAnnotation() throws Exception {
|
||||
// given — HttpMethodsTestAction has @AllowedHttpMethod(POST) at class level
|
||||
// execute() inherited from ActionSupport has no method-level HTTP annotation
|
||||
HttpMethodsTestAction action = new HttpMethodsTestAction();
|
||||
prepareActionInvocation(action);
|
||||
actionProxy.setMethod("execute");
|
||||
actionProxy.setMethodSpecified(true); // simulates wildcard-resolved, not default
|
||||
|
||||
prepareRequest("get");
|
||||
|
||||
// when
|
||||
String resultName = interceptor.intercept(invocation);
|
||||
|
||||
// then — class-level @AllowedHttpMethod(POST) must still be enforced
|
||||
assertEquals("bad-request", resultName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counterpart: POST on wildcard-resolved unannotated method must succeed
|
||||
* when the class allows POST via class-level annotation.
|
||||
*/
|
||||
public void testWildcardResolvedUnannotatedMethodAllowsPostWithClassLevelAnnotation() throws Exception {
|
||||
// given
|
||||
HttpMethodsTestAction action = new HttpMethodsTestAction();
|
||||
prepareActionInvocation(action);
|
||||
actionProxy.setMethod("execute");
|
||||
actionProxy.setMethodSpecified(true);
|
||||
invocation.setResultCode("success");
|
||||
|
||||
prepareRequest("post");
|
||||
|
||||
// when
|
||||
String resultName = interceptor.intercept(invocation);
|
||||
|
||||
// then
|
||||
assertEquals("success", resultName);
|
||||
}
|
||||
|
||||
private void prepareRequest(String httpMethod) {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(httpMethod, "/action");
|
||||
ActionContext.getContext().withServletRequest(request);
|
||||
|
||||
Reference in New Issue
Block a user