Skip to content

Commit

Permalink
chore(release): 1.0.0-develop.3 [skip ci]
Browse files Browse the repository at this point in the history
# [1.0.0-develop.3](v1.0.0-develop.2...v1.0.0-develop.3) (2024-07-29)

### Features

* remove BaseController, change Principal to Authenticationand unit test cases added ([15425be](15425be))
* test cases added, file header updated and detail log added for security events ([a4fa6cc](a4fa6cc))

Signed-off-by: Dominik Pinsel <dominik.pinsel@mercedes-benz.com>
  • Loading branch information
nitin-vavdiya authored and DominikPinsel committed Aug 5, 2024
1 parent ae2710f commit d470f86
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 97 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@
import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;

import java.util.List;

import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
Expand Down Expand Up @@ -127,8 +130,11 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestMatchers(new AntPathRequestMatcher("/error")).permitAll()
).oauth2ResourceServer(resourceServer -> resourceServer.jwt(jwt ->
jwt.jwtAuthenticationConverter(new CustomAuthenticationConverter(securityConfigProperties.clientId())))
.authenticationEntryPoint(new CustomAuthenticationEntryPoint()))
.addFilterAfter(new PresentationIatpFilter(validationService), BasicAuthenticationFilter.class);
.authenticationEntryPoint(new CustomAuthenticationEntryPoint()))
.securityMatcher(new NegatedRequestMatcher(new OrRequestMatcher(
List.of(
new AntPathRequestMatcher(RestURI.API_PRESENTATIONS_IATP),
new AntPathRequestMatcher(RestURI.API_PRESENTATIONS_IATP_WORKAROUND)))));

return http.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import com.nimbusds.jwt.SignedJWT;
import io.swagger.v3.oas.annotations.Parameter;
import liquibase.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -33,6 +34,7 @@
import org.eclipse.tractusx.managedidentitywallets.dto.PresentationResponseMessage;
import org.eclipse.tractusx.managedidentitywallets.reader.TractusXPresentationRequestReader;
import org.eclipse.tractusx.managedidentitywallets.service.PresentationService;
import org.eclipse.tractusx.managedidentitywallets.service.STSTokenValidationService;
import org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils;
import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -63,6 +65,8 @@ public class PresentationController {

private final TractusXPresentationRequestReader presentationRequestReader;

private final STSTokenValidationService validationService;

/**
* Create presentation response entity.
*
Expand Down Expand Up @@ -114,17 +118,37 @@ public ResponseEntity<Map<String, Object>> validatePresentation(@RequestBody Map
@PostMapping(path = { RestURI.API_PRESENTATIONS_IATP, RestURI.API_PRESENTATIONS_IATP_WORKAROUND }, produces = { MediaType.APPLICATION_JSON_VALUE })
@GetVerifiablePresentationIATPApiDocs
@SneakyThrows
public ResponseEntity<PresentationResponseMessage> createPresentation(@Parameter(hidden = true) @RequestHeader(name = "Authorization") String stsToken,
@RequestParam(name = "asJwt", required = false, defaultValue = "false") boolean asJwt,
InputStream is) {
public ResponseEntity<PresentationResponseMessage> createPresentation(
/* As filters are disabled for this endpoint set required to false and handle missing token manually */
@Parameter(hidden = true) @RequestHeader(name = "Authorization", required = false) String stsToken,
@RequestParam(name = "asJwt", required = false, defaultValue = "false") boolean asJwt,
InputStream is) {
try {

if(stsToken == null){
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

if (stsToken.startsWith("Bearer ")) {
stsToken = stsToken.substring("Bearer ".length());
}

var validationResult = validationService.validateToken(stsToken);
if (!validationResult.isValid()) {
log.atDebug().log("Unauthorized request. Errors: '%s'".formatted(
StringUtil.join(validationResult.getErrors().stream()
.map(Enum::name)
.toList(),
", ")));
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

// requested scopes are ignored for now
final List<String> requestedScopes = presentationRequestReader.readVerifiableCredentialScopes(is);
// requested scopes are ignored until the documentation is better refined

SignedJWT accessToken = getAccessToken(stsToken);
Map<String, Object> map = presentationService.createVpWithRequiredScopes(accessToken, asJwt);
VerifiablePresentation verifiablePresentation = new VerifiablePresentation((Map)map.get("vp"));
VerifiablePresentation verifiablePresentation = new VerifiablePresentation((Map) map.get("vp"));
PresentationResponseMessage message = new PresentationResponseMessage(verifiablePresentation);
return ResponseEntity.ok(message);
} catch (TractusXPresentationRequestReader.InvalidPresentationQueryMessageResource e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void createPresentationFailure401Test() {
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<Map<String, Object>> response = testTemplate.exchange(
RestURI.API_PRESENTATIONS_IATP,
HttpMethod.GET,
HttpMethod.POST,
entity,
new ParameterizedTypeReference<>() {
}
Expand All @@ -94,15 +94,12 @@ void createPresentationFailure401WithErrorsTest() {

ResponseEntity<String> response = testTemplate.exchange(
RestURI.API_PRESENTATIONS_IATP,
HttpMethod.GET,
HttpMethod.POST,
entity,
new ParameterizedTypeReference<>() {
}
);

String expectedBody = TOKEN_ALREADY_EXPIRED.name() + StringPool.COMA_SEPARATOR + NONCE_MISSING.name();

Assertions.assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
Assertions.assertEquals(expectedBody, response.getBody());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void testPresentationQueryWithToken() {
final Map<String, Object> data2 = MAPPER.readValue(message2, Map.class);

final HttpHeaders headers2 = new HttpHeaders();
headers2.set(HttpHeaders.AUTHORIZATION, jwt);
headers2.set(HttpHeaders.AUTHORIZATION, "Bearer " + jwt);
final HttpEntity<Map<String, Object>> entity2 = new HttpEntity<>(data2, headers2);
var result2 = restTemplate
.postForEntity(RestURI.API_PRESENTATIONS_IATP, entity2, String.class);
Expand Down

0 comments on commit d470f86

Please sign in to comment.