lukaszlenart opened a new pull request, #1940:
URL: https://github.com/apache/struts/pull/1940

   Fixes [WW-5715](https://issues.apache.org/jira/browse/WW-5715)
   
   ## Problem
   
   `AuthorizingSettableBeanProperty` derived the `@StrutsParameter` 
authorization path from `getName()` — Jackson's *external* property name — 
while `StrutsParameterAuthorizer` resolves that path against the *Java member*. 
The two names are identical until the application renames a property 
(`@JsonProperty`, `@JsonAlias`, a `PropertyNamingStrategy`); once they diverge, 
the authorization decision is made about one member while the value is assigned 
to another:
   
   - **Wrongly denied** — `@StrutsParameter setUserName` arriving as 
`user_name` is dropped, and the WARN names a property the developer never wrote.
   - **Wrongly allowed** — an unannotated `@JsonProperty("name") setAdmin` next 
to an annotated `setName` is authorized as `name` and receives the value.
   
   ## Change
   
   `ParameterAuthorizingModule` now keys each wrapper by the member Jackson 
invokes for the property (`SettableBeanProperty#getMember()`): the field name, 
or the bean property a one-argument `set` / no-argument `get`/`is` accessor is 
named after — the name `StrutsParameterAuthorizer` resolves back to that 
member. The wrapper threads the name through `withDelegate` and into 
`AuthorizingValueDeserializer`, so nested path prefixes are built from member 
names as well.
   
   Things that deliberately keep the external name:
   - creator parameters — they only occur nested (the root is always populated 
via `readerForUpdating`), where the authorizer counts depth alone;
   - mutators outside the bean convention (`settings(...)`, a one-argument 
`getName(...)`), which resolve to no member and fail closed as before.
   
   `BeanPropertyDefinition#getInternalName()` was tried first and rejected: it 
names the merged property, not the mutator. Jackson merges an accessor renamed 
with `@JsonProperty` into whatever property already owns that external name and 
then invokes the explicitly named accessor, so the ticket's literal 
`@JsonProperty("name") setAdmin` + `@StrutsParameter setName` case kept the 
internal name `name` and still landed in `setAdmin`. That case is now a 
regression test.
   
   The one-arg `AuthorizingSettableBeanProperty` constructor stays as a 
deprecated shim; its removal is 
[WW-5744](https://issues.apache.org/jira/browse/WW-5744) at 8.0.0.
   
   ## Tests
   
   - `ContentTypeInterceptorIntegrationTest` (real `StrutsParameterAuthorizer` 
+ `JacksonJsonHandler`): renamed annotated member binds; unannotated member 
renamed onto an annotated member's name is rejected; unannotated member 
*merged* into an annotated member's property is rejected.
   - `ParameterAuthorizingModuleTest`: `SNAKE_CASE` naming strategy yields 
Java-member paths at every nesting level; non-convention and one-argument 
getter-named mutators keep the external name.
   
   `mvn test -DskipAssembly -pl plugins/rest`: 179 tests, 0 failures.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to