Skip to content

Commit 71380e0

Browse files
committed
Polish
1 parent ba1a780 commit 71380e0

File tree

10 files changed

+105
-89
lines changed

10 files changed

+105
-89
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAccessOperationFilter.java

Lines changed: 0 additions & 52 deletions
This file was deleted.

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/PropertiesEndpointAccessResolver.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private static Access determineDefaultAccess(PropertyResolver properties) {
8080
@Override
8181
public Access accessFor(EndpointId endpointId, Access defaultAccess) {
8282
return this.accessCache.computeIfAbsent(endpointId,
83-
(key) -> capAccess(resolveAccess(endpointId, defaultAccess)));
83+
(key) -> resolveAccess(endpointId, defaultAccess).cap(this.maxPermittedAccess));
8484
}
8585

8686
private Access resolveAccess(EndpointId endpointId, Access defaultAccess) {
@@ -101,8 +101,4 @@ private Access resolveAccess(EndpointId endpointId, Access defaultAccess) {
101101
return (this.endpointsDefaultAccess != null) ? this.endpointsDefaultAccess : defaultAccess;
102102
}
103103

104-
private Access capAccess(Access access) {
105-
return Access.values()[Math.min(access.ordinal(), this.maxPermittedAccess.ordinal())];
106-
}
107-
108104
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/jmx/JmxEndpointAutoConfiguration.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
import org.springframework.beans.factory.ObjectProvider;
2424
import org.springframework.boot.LazyInitializationExcludeFilter;
25-
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAccessOperationFilter;
2625
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
2726
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;
2827
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.IncludeExcludeEndpointFilter;
@@ -123,9 +122,8 @@ static LazyInitializationExcludeFilter eagerlyInitializeJmxEndpointExporter() {
123122
}
124123

125124
@Bean
126-
EndpointAccessOperationFilter<JmxOperation> jmxAccessPropertiesOperationFilter(
127-
EndpointAccessResolver endpointAccessResolver) {
128-
return new EndpointAccessOperationFilter<>(endpointAccessResolver);
125+
OperationFilter<JmxOperation> jmxAccessPropertiesOperationFilter(EndpointAccessResolver endpointAccessResolver) {
126+
return OperationFilter.byAccess(endpointAccessResolver);
129127
}
130128

131129
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointAutoConfiguration.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.Collections;
2121

2222
import org.springframework.beans.factory.ObjectProvider;
23-
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAccessOperationFilter;
2423
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
2524
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure;
2625
import org.springframework.boot.actuate.autoconfigure.endpoint.expose.IncludeExcludeEndpointFilter;
@@ -130,9 +129,8 @@ public IncludeExcludeEndpointFilter<org.springframework.boot.actuate.endpoint.we
130129
}
131130

132131
@Bean
133-
EndpointAccessOperationFilter<WebOperation> webAccessPropertiesOperationFilter(
134-
EndpointAccessResolver endpointAccessResolver) {
135-
return new EndpointAccessOperationFilter<>(endpointAccessResolver);
132+
OperationFilter<WebOperation> webAccessPropertiesOperationFilter(EndpointAccessResolver endpointAccessResolver) {
133+
return OperationFilter.byAccess(endpointAccessResolver);
136134
}
137135

138136
@Configuration(proxyBeanMethods = false)

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/Access.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot.actuate.endpoint;
1818

19+
import org.springframework.util.Assert;
20+
1921
/**
2022
* Permitted level of access to an endpoint and its operations.
2123
*
@@ -37,6 +39,16 @@ public enum Access {
3739
/**
3840
* Unrestricted access to the endpoint is permitted.
3941
*/
40-
UNRESTRICTED
42+
UNRESTRICTED;
43+
44+
/**
45+
* Cap access to a maximum permitted.
46+
* @param maxPermitted the maximum permitted access
47+
* @return this access if less than the maximum or the maximum permitted
48+
*/
49+
public Access cap(Access maxPermitted) {
50+
Assert.notNull(maxPermitted, "'maxPermittedAccess' must not be null");
51+
return (ordinal() <= maxPermitted.ordinal()) ? this : maxPermitted;
52+
}
4153

4254
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/OperationFilter.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,22 @@ public interface OperationFilter<O extends Operation> {
3535
*/
3636
boolean match(O operation, EndpointId endpointId, Access defaultAccess);
3737

38+
/**
39+
* Return an {@link OperationFilter} that filters based on the allowed {@link Access
40+
* access} as determined by an {@link EndpointAccessResolver access resolver}.
41+
* @param <O> the operation type
42+
* @param accessResolver the access resolver
43+
* @return a new {@link OperationFilter}
44+
*/
45+
static <O extends Operation> OperationFilter<O> byAccess(EndpointAccessResolver accessResolver) {
46+
return (operation, endpointId, defaultAccess) -> {
47+
Access access = accessResolver.accessFor(endpointId, defaultAccess);
48+
return switch (access) {
49+
case NONE -> false;
50+
case READ_ONLY -> operation.getType() == OperationType.READ;
51+
case UNRESTRICTED -> true;
52+
};
53+
};
54+
}
55+
3856
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/ServletEndpointRegistrar.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,27 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
117117
throws IOException, ServletException {
118118
if (request instanceof HttpServletRequest httpRequest
119119
&& response instanceof HttpServletResponse httpResponse) {
120-
if (READ_ONLY_ACCESS_REQUEST_METHODS.contains(httpRequest.getMethod().toUpperCase(Locale.ROOT))) {
121-
chain.doFilter(httpRequest, response);
122-
}
123-
else {
124-
httpResponse.sendError(METHOD_NOT_ALLOWED);
125-
}
120+
doFilter(httpRequest, httpResponse, chain);
126121
}
127122
else {
128123
throw new ServletException();
129124
}
130125
}
131126

127+
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
128+
throws IOException, ServletException {
129+
if (isReadOnlyAccessMethod(request)) {
130+
chain.doFilter(request, response);
131+
}
132+
else {
133+
response.sendError(METHOD_NOT_ALLOWED);
134+
}
135+
}
136+
137+
private boolean isReadOnlyAccessMethod(HttpServletRequest request) {
138+
return READ_ONLY_ACCESS_REQUEST_METHODS.contains(request.getMethod().toUpperCase(Locale.ROOT));
139+
}
140+
132141
}
133142

134143
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/ControllerEndpointHandlerMapping.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,14 @@ protected void registerHandlerMethod(Object handler, Method method, RequestMappi
125125
}
126126

127127
private RequestMappingInfo withReadOnlyAccess(Access access, RequestMappingInfo mapping) {
128-
Set<RequestMethod> methods = mapping.getMethodsCondition().getMethods();
129-
Set<RequestMethod> modifiedMethods = new HashSet<>(methods);
130-
if (modifiedMethods.isEmpty()) {
131-
modifiedMethods.addAll(READ_ONLY_ACCESS_REQUEST_METHODS);
128+
Set<RequestMethod> methods = new HashSet<>(mapping.getMethodsCondition().getMethods());
129+
if (methods.isEmpty()) {
130+
methods.addAll(READ_ONLY_ACCESS_REQUEST_METHODS);
132131
}
133132
else {
134-
modifiedMethods.retainAll(READ_ONLY_ACCESS_REQUEST_METHODS);
133+
methods.retainAll(READ_ONLY_ACCESS_REQUEST_METHODS);
135134
}
136-
return mapping.mutate().methods(modifiedMethods.toArray(new RequestMethod[0])).build();
135+
return mapping.mutate().methods(methods.toArray(new RequestMethod[0])).build();
137136
}
138137

139138
private RequestMappingInfo withEndpointMappedPatterns(ExposableControllerEndpoint endpoint,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.actuate.endpoint;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
23+
/**
24+
* Tests for {@link Access}.
25+
*
26+
* @author Phillip Webb
27+
*/
28+
class AccessTests {
29+
30+
@Test
31+
void capWhenAboveMaximum() {
32+
assertThat(Access.UNRESTRICTED.cap(Access.READ_ONLY)).isEqualTo(Access.READ_ONLY);
33+
}
34+
35+
@Test
36+
void capWhenAtMaximum() {
37+
assertThat(Access.READ_ONLY.cap(Access.READ_ONLY)).isEqualTo(Access.READ_ONLY);
38+
}
39+
40+
@Test
41+
void capWhenBelowMaximum() {
42+
assertThat(Access.NONE.cap(Access.READ_ONLY)).isEqualTo(Access.NONE);
43+
}
44+
45+
}
Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,26 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.actuate.autoconfigure.endpoint;
17+
package org.springframework.boot.actuate.endpoint;
1818

1919
import org.junit.jupiter.api.Test;
2020

21-
import org.springframework.boot.actuate.endpoint.Access;
22-
import org.springframework.boot.actuate.endpoint.EndpointAccessResolver;
23-
import org.springframework.boot.actuate.endpoint.EndpointId;
24-
import org.springframework.boot.actuate.endpoint.Operation;
25-
import org.springframework.boot.actuate.endpoint.OperationType;
26-
2721
import static org.assertj.core.api.Assertions.assertThat;
2822
import static org.mockito.BDDMockito.given;
2923
import static org.mockito.Mockito.mock;
3024

3125
/**
32-
* Tests for {@link EndpointAccessOperationFilter}.
26+
* Tests for {@link OperationFilter}.
3327
*
3428
* @author Andy Wilkinson
3529
*/
36-
class EndpointAccessOperationFilterTests {
30+
class OperationFilterTests {
3731

3832
private final EndpointAccessResolver accessResolver = mock(EndpointAccessResolver.class);
3933

4034
private final Operation operation = mock(Operation.class);
4135

42-
private final EndpointAccessOperationFilter<Operation> filter = new EndpointAccessOperationFilter<>(
43-
this.accessResolver);
36+
private final OperationFilter<Operation> filter = OperationFilter.byAccess(this.accessResolver);
4437

4538
@Test
4639
void whenAccessIsUnrestrictedThenMatchReturnsTrue() {

0 commit comments

Comments
 (0)