Skip to content

Commit e4321af

Browse files
authored
Merge pull request #27 from wwan13/feature/resolve
Configurations
2 parents 15eed4d + 58a0fed commit e4321af

File tree

8 files changed

+118
-135
lines changed

8 files changed

+118
-135
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 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+
* http://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 io.wwan13.wintersecurity.config;
18+
19+
import io.wwan13.wintersecurity.resolve.RolesResolver;
20+
import io.wwan13.wintersecurity.resolve.SubjectResolver;
21+
import io.wwan13.wintersecurity.resolve.TargetAnnotations;
22+
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
23+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
24+
25+
import java.util.List;
26+
27+
public class ArgumentResolversRegistrar implements WebMvcConfigurer {
28+
29+
private final TargetAnnotations targetAnnotations;
30+
31+
public ArgumentResolversRegistrar(TargetAnnotations targetAnnotations) {
32+
this.targetAnnotations = targetAnnotations;
33+
}
34+
35+
@Override
36+
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
37+
SubjectResolver subjectResolver = new SubjectResolver(targetAnnotations);
38+
resolvers.add(subjectResolver);
39+
40+
RolesResolver rolesResolver = new RolesResolver(targetAnnotations);
41+
resolvers.add(rolesResolver);
42+
}
43+
}

src/main/java/io/wwan13/wintersecurity/config/EnableSecureRequest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
AuthConfiguration.class,
3333
AuthProcessorRegistrar.class,
3434
TargetAnnotationsRegistrar.class,
35+
ArgumentResolversRegistrar.class,
3536
SecretKeyRegistrar.class
3637
})
3738
public @interface EnableSecureRequest {

src/main/java/io/wwan13/wintersecurity/resolve/RolesResolver.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
package io.wwan13.wintersecurity.resolve;
1818

19-
import io.wwan13.wintersecurity.jwt.PayloadAnalysis;
2019
import io.wwan13.wintersecurity.jwt.TokenClaims;
2120
import io.wwan13.wintersecurity.resolve.util.AttributeExtractor;
22-
import io.wwan13.wintersecurity.util.TypeConverter;
21+
import io.wwan13.wintersecurity.resolve.util.ResolveTypeConverter;
2322
import org.springframework.core.MethodParameter;
2423
import org.springframework.web.bind.support.WebDataBinderFactory;
2524
import org.springframework.web.context.request.NativeWebRequest;
@@ -32,24 +31,15 @@
3231
public class RolesResolver implements HandlerMethodArgumentResolver {
3332

3433
private final TargetAnnotations targetAnnotations;
35-
private final PayloadAnalysis payloadAnalysis;
3634

37-
public RolesResolver(
38-
TargetAnnotations targetAnnotations,
39-
PayloadAnalysis payloadAnalysis
40-
) {
35+
public RolesResolver(TargetAnnotations targetAnnotations) {
4136
this.targetAnnotations = targetAnnotations;
42-
this.payloadAnalysis = payloadAnalysis;
4337
}
4438

4539
@Override
4640
public boolean supportsParameter(MethodParameter parameter) {
47-
boolean hasAnnotation = targetAnnotations.forRoles().stream()
41+
return targetAnnotations.forRoles().stream()
4842
.anyMatch(parameter::hasParameterAnnotation);
49-
boolean isValidType = payloadAnalysis.roles().getType()
50-
.isAssignableFrom(parameter.getParameterType());
51-
52-
return hasAnnotation && isValidType;
5343
}
5444

5545
@Override
@@ -69,9 +59,9 @@ public Object resolveArgument(
6959
.findFirst()
7060
.orElseThrow(() -> new IllegalArgumentException("Empty role entered"));
7161

72-
return TypeConverter.convertTo(role, parameter.getParameterType());
62+
return ResolveTypeConverter.convertTo(role, parameter.getParameterType());
7363
}
7464

75-
return TypeConverter.convertTo(claims.getRoles(), parameter.getParameterType());
65+
return ResolveTypeConverter.convertTo(claims.getRoles(), parameter.getParameterType());
7666
}
7767
}

src/main/java/io/wwan13/wintersecurity/resolve/SubjectResolver.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
package io.wwan13.wintersecurity.resolve;
1818

19-
import io.wwan13.wintersecurity.jwt.PayloadAnalysis;
2019
import io.wwan13.wintersecurity.jwt.TokenClaims;
2120
import io.wwan13.wintersecurity.resolve.util.AttributeExtractor;
22-
import io.wwan13.wintersecurity.util.TypeConverter;
21+
import io.wwan13.wintersecurity.resolve.util.ResolveTypeConverter;
2322
import org.springframework.core.MethodParameter;
2423
import org.springframework.web.bind.support.WebDataBinderFactory;
2524
import org.springframework.web.context.request.NativeWebRequest;
@@ -31,24 +30,17 @@
3130
public class SubjectResolver implements HandlerMethodArgumentResolver {
3231

3332
private final TargetAnnotations targetAnnotations;
34-
private final PayloadAnalysis payloadAnalysis;
3533

3634
public SubjectResolver(
37-
TargetAnnotations targetAnnotations,
38-
PayloadAnalysis payloadAnalysis
35+
TargetAnnotations targetAnnotations
3936
) {
4037
this.targetAnnotations = targetAnnotations;
41-
this.payloadAnalysis = payloadAnalysis;
4238
}
4339

4440
@Override
4541
public boolean supportsParameter(MethodParameter parameter) {
46-
boolean hasAnnotation = targetAnnotations.forSubject().stream()
42+
return targetAnnotations.forSubject().stream()
4743
.anyMatch(parameter::hasParameterAnnotation);
48-
boolean isValidType = payloadAnalysis.subject().getType()
49-
.isAssignableFrom(parameter.getParameterType());
50-
51-
return hasAnnotation && isValidType;
5244
}
5345

5446
@Override
@@ -61,7 +53,7 @@ public Object resolveArgument(
6153
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
6254
TokenClaims claims = AttributeExtractor.extractClaims(request);
6355

64-
return TypeConverter.convertTo(
56+
return ResolveTypeConverter.convertTo(
6557
claims.getSubject(),
6658
parameter.getParameterType()
6759
);

src/main/java/io/wwan13/wintersecurity/util/TypeConverter.java renamed to src/main/java/io/wwan13/wintersecurity/resolve/util/ResolveTypeConverter.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,29 @@
1414
* limitations under the License.
1515
*/
1616

17-
package io.wwan13.wintersecurity.util;
17+
package io.wwan13.wintersecurity.resolve.util;
1818

1919
import com.fasterxml.jackson.databind.DeserializationFeature;
2020
import com.fasterxml.jackson.databind.ObjectMapper;
2121

22-
public class TypeConverter {
22+
public class ResolveTypeConverter {
2323

2424
private static final ObjectMapper objectMapper = new ObjectMapper()
2525
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
26+
private static final String ERROR_MESSAGE_FORMAT =
27+
"'%s' cannot be converted to declared type '%s'";
2628

27-
private TypeConverter() {
29+
private ResolveTypeConverter() {
2830
throw new IllegalStateException("Cannot instantiate a utility class!");
2931
}
3032

3133
public static Object convertTo(Object originValue, Class<?> targetClazz) {
32-
return objectMapper.convertValue(originValue, targetClazz);
34+
try {
35+
return objectMapper.convertValue(originValue, targetClazz);
36+
} catch (IllegalArgumentException e) {
37+
throw new IllegalStateException(
38+
String.format(ERROR_MESSAGE_FORMAT, originValue, targetClazz.getSimpleName())
39+
);
40+
}
3341
}
3442
}

src/test/java/io/wwan13/wintersecurity/resolve/ResolveTestContainer.java

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,7 @@
1616

1717
package io.wwan13.wintersecurity.resolve;
1818

19-
import io.wwan13.wintersecurity.jwt.PayloadAnalysis;
20-
import io.wwan13.wintersecurity.jwt.PayloadAnalyst;
2119
import io.wwan13.wintersecurity.jwt.TokenClaims;
22-
import io.wwan13.wintersecurity.jwt.payload.annotation.Roles;
23-
import io.wwan13.wintersecurity.jwt.payload.annotation.Subject;
24-
import io.wwan13.wintersecurity.jwt.payload.support.DefaultPayloadAnalyst;
2520

2621
import java.util.Map;
2722
import java.util.Set;
@@ -33,31 +28,10 @@ public class ResolveTestContainer {
3328
Set.of(RequestUserRoles.class)
3429
);
3530

36-
public static PayloadAnalysis payloadAnalysis;
37-
38-
static {
39-
PayloadAnalyst payloadAnalyst = new DefaultPayloadAnalyst();
40-
payloadAnalysis = payloadAnalyst.analyze(ResolveTestPayload.class);
41-
}
42-
4331
public static TokenClaims defaultTestClaims = new TokenClaims(
4432
Map.of(
4533
"sub", "1",
4634
"roles", "ROLE_USER"
4735
)
4836
);
49-
50-
public static class ResolveTestPayload {
51-
@Subject
52-
Long subject;
53-
@Roles
54-
Set<String> roles;
55-
}
56-
57-
public static class ResolveTestPayloadWithStringRole {
58-
@Subject
59-
Long subject;
60-
@Roles
61-
String role;
62-
}
6337
}

src/test/java/io/wwan13/wintersecurity/resolve/RolesResolverTest.java

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616

1717
package io.wwan13.wintersecurity.resolve;
1818

19-
import io.wwan13.wintersecurity.jwt.PayloadAnalysis;
20-
import io.wwan13.wintersecurity.jwt.PayloadAnalyst;
2119
import io.wwan13.wintersecurity.jwt.TokenClaims;
22-
import io.wwan13.wintersecurity.jwt.payload.support.DefaultPayloadAnalyst;
2320
import io.wwan13.wintersecurity.resolve.stub.StubMethodParameter;
2421
import io.wwan13.wintersecurity.resolve.stub.StubModerAndViesContainer;
2522
import io.wwan13.wintersecurity.resolve.stub.StubNativeWebRequest;
@@ -31,21 +28,20 @@
3128
import java.util.Set;
3229

3330
import static org.assertj.core.api.Assertions.assertThat;
31+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3432

3533
class RolesResolverTest {
3634

3735
static RolesResolver rolesResolver = new RolesResolver(
38-
ResolveTestContainer.targetAnnotations,
39-
ResolveTestContainer.payloadAnalysis
36+
ResolveTestContainer.targetAnnotations
4037
);
4138

4239
@Test
43-
void should_ReturnTrue_when_AnnotationDeclaredWithValidParameterType() {
40+
void should_ReturnTrue_when_AnnotationDeclared() {
4441
// given
4542
final StubMethodParameter methodParameter = new StubMethodParameter();
4643

4744
methodParameter.declaredAnnotationsWillBe(RequestUserRoles.class);
48-
methodParameter.parameterTypeWillBe(Set.class);
4945

5046
// when
5147
boolean result = rolesResolver.supportsParameter(methodParameter);
@@ -54,43 +50,12 @@ void should_ReturnTrue_when_AnnotationDeclaredWithValidParameterType() {
5450
assertThat(result).isTrue();
5551
}
5652

57-
@Test
58-
void should_ReturnFalse_when_InValidParameterType() {
59-
// given
60-
final StubMethodParameter methodParameter = new StubMethodParameter();
61-
62-
methodParameter.declaredAnnotationsWillBe(RequestUserRoles.class);
63-
methodParameter.parameterTypeWillBe(Long.class);
64-
65-
// when
66-
boolean result = rolesResolver.supportsParameter(methodParameter);
67-
68-
// then
69-
assertThat(result).isFalse();
70-
}
71-
7253
@Test
7354
void should_ReturnFalse_when_AnnotationNotDeclared() {
7455
// given
7556
final StubMethodParameter methodParameter = new StubMethodParameter();
7657

7758
methodParameter.declaredAnnotationsWillBe(Set.of());
78-
methodParameter.parameterTypeWillBe(Set.class);
79-
80-
// when
81-
boolean result = rolesResolver.supportsParameter(methodParameter);
82-
83-
// then
84-
assertThat(result).isFalse();
85-
}
86-
87-
@Test
88-
void should_ReturnFalse_when_InValidParameterTypeIsDataType() {
89-
// given
90-
final StubMethodParameter methodParameter = new StubMethodParameter();
91-
92-
methodParameter.declaredAnnotationsWillBe(RequestUserRoles.class);
93-
methodParameter.parameterTypeWillBe(Long.class);
9459

9560
// when
9661
boolean result = rolesResolver.supportsParameter(methodParameter);
@@ -131,16 +96,11 @@ void should_ResolveStringRole_when_NoneCollectionTypeRoleEntered() {
13196
final StubNativeWebRequest nativeWebRequest = new StubNativeWebRequest();
13297
final StubWebDataBinderFactory webDataBinderFactory = new StubWebDataBinderFactory();
13398

134-
final PayloadAnalyst payloadAnalyst = new DefaultPayloadAnalyst();
135-
final PayloadAnalysis payloadAnalysis =
136-
payloadAnalyst.analyze(ResolveTestContainer.ResolveTestPayloadWithStringRole.class);
137-
13899
nativeWebRequest.requestAttributesWillBe(new TokenClaims(Map.of("roles", "ROLE_USER")));
139100
methodParameter.parameterTypeWillBe(String.class);
140101

141102
final RolesResolver rolesResolver = new RolesResolver(
142-
ResolveTestContainer.targetAnnotations,
143-
payloadAnalysis
103+
ResolveTestContainer.targetAnnotations
144104
);
145105

146106
// when
@@ -155,4 +115,27 @@ void should_ResolveStringRole_when_NoneCollectionTypeRoleEntered() {
155115
assertThat(value.getClass()).isAssignableFrom(String.class);
156116
assertThat((String) value).isEqualTo("ROLE_USER");
157117
}
118+
119+
120+
@Test
121+
void should_ThrowException_when_InValidParameterTypeDeclared() {
122+
// given
123+
final StubMethodParameter methodParameter = new StubMethodParameter();
124+
final StubModerAndViesContainer modelAndViewContainer = new StubModerAndViesContainer();
125+
final StubNativeWebRequest nativeWebRequest = new StubNativeWebRequest();
126+
final StubWebDataBinderFactory webDataBinderFactory = new StubWebDataBinderFactory();
127+
128+
nativeWebRequest.requestAttributesWillBe(ResolveTestContainer.defaultTestClaims);
129+
methodParameter.parameterTypeWillBe(Long.class);
130+
131+
// when
132+
assertThatThrownBy(() ->
133+
rolesResolver.resolveArgument(
134+
methodParameter,
135+
modelAndViewContainer,
136+
nativeWebRequest,
137+
webDataBinderFactory
138+
)
139+
).isInstanceOf(IllegalStateException.class);
140+
}
158141
}

0 commit comments

Comments
 (0)