Skip to content

Commit

Permalink
fixed buyer with wrong env
Browse files Browse the repository at this point in the history
  • Loading branch information
kuangxiang20240501 committed Nov 15, 2024
1 parent cb5d021 commit 0a89c2d
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public static class ResourceServer {
private String bearerTokenHeaderName = "Authorization";
private String userId = "x-kraken-userId";
private SecurityFilter securityFilter = new SecurityFilter();
private Verifier verifier = new Verifier();
}

@Data
Expand Down Expand Up @@ -130,4 +131,9 @@ public static class FilterConfig {
private List<String> paths = List.of();
private String filterName;
}

@Data
public static class Verifier {
private String env;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class BuyerService extends AssetStatusManager {
private static final String BUYER_KEY_PREFIX = "mef.sonata.buyer";
private static final String BUYER_NAME = "Buyer";
private static final String BUYER_DESC = "Onboard buyer information";
public static final String ENV = "env";

@Getter private final UnifiedAssetService unifiedAssetService;
private final UnifiedAssetRepository unifiedAssetRepository;
Expand Down Expand Up @@ -166,7 +167,7 @@ private BuyerAssetDto.BuyerToken generateBuyerToken(
if (StringUtils.isNotBlank(envId)) {
Environment environment = environmentService.findOne(envId);
log.info("generateBuyerToken, envId:{}, envName:{}", envId, environment.getName());
claims.put("env", environment.getName());
claims.put(ENV, environment.getName());
}
if (authServer.isEnabled()) {
String token =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ private Constants() {}
public static final String COMMA = ",";
public static final String MAPPER_SIGN = "-mapper";
public static final String INIT_VERSION = "1.0";
public static final String ENV = "env";

public static String formatVersion(String version) {
return version.replaceFirst("[V|v]", "");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.consoleconnect.kraken.operator.gateway.service;

import com.consoleconnect.kraken.operator.auth.model.AuthDataProperty;
import com.consoleconnect.kraken.operator.auth.security.SecurityChecker;
import com.consoleconnect.kraken.operator.core.dto.Tuple2;
import com.consoleconnect.kraken.operator.core.dto.UnifiedAssetDto;
Expand All @@ -8,70 +9,91 @@
import com.consoleconnect.kraken.operator.core.exception.KrakenException;
import com.consoleconnect.kraken.operator.core.service.UnifiedAssetService;
import com.consoleconnect.kraken.operator.core.toolkit.AssetsConstants;
import com.consoleconnect.kraken.operator.core.toolkit.Constants;
import com.consoleconnect.kraken.operator.core.toolkit.LabelConstants;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.core.publisher.SynchronousSink;

@Component(value = "securityBuyerChecker")
@AllArgsConstructor
public class BuyerCheckerService implements SecurityChecker {

public static final int INTERVAL = 60;
private UnifiedAssetService unifiedAssetService;
private AuthDataProperty.ResourceServer resourceServer;

@Override
public Mono<Object> internalRun(ServerWebExchange exchange) {
return ReactiveSecurityContextHolder.getContext()
.handle(
(securityContext, sink) -> {
Authentication authentication = securityContext.getAuthentication();
List<UnifiedAssetDto> list =
unifiedAssetService
.findBySpecification(
Tuple2.ofList(
AssetsConstants.FIELD_KIND, AssetKindEnum.PRODUCT_BUYER.getKind()),
Tuple2.ofList(LabelConstants.LABEL_BUYER_ID, authentication.getName()),
null,
PageRequest.ofSize(1),
null)
.getData();
if (CollectionUtils.isEmpty(list)) {
sink.error(KrakenException.badRequest("buyer not found"));
return;
}
UnifiedAssetDto unifiedAssetDto = list.get(0);
if (AssetStatusEnum.DEACTIVATED
.getKind()
.equalsIgnoreCase(unifiedAssetDto.getMetadata().getStatus())) {
sink.error(KrakenException.badRequest("buyer deactivated"));
return;
}
Map<String, String> labels = unifiedAssetDto.getMetadata().getLabels();
Instant dbGeneratedAt =
Optional.ofNullable(labels.get(LabelConstants.LABEL_ISSUE_AT))
.map(DateTimeFormatter.ISO_INSTANT::parse)
.map(Instant::from)
.orElse(Instant.MIN);
Jwt principal = (Jwt) authentication.getPrincipal();
Instant issuedAt = principal.getIssuedAt();
if (issuedAt.isBefore(dbGeneratedAt.minusSeconds(INTERVAL))) {
sink.error(KrakenException.badRequest("Token expired "));
return;
}
sink.next(new Object());
});
.handle(getSecurityContextSynchronousSinkBiConsumer());
}

public BiConsumer<SecurityContext, SynchronousSink<Object>>
getSecurityContextSynchronousSinkBiConsumer() {
return (securityContext, sink) -> {
Authentication authentication = securityContext.getAuthentication();
List<UnifiedAssetDto> list =
unifiedAssetService
.findBySpecification(
Tuple2.ofList(AssetsConstants.FIELD_KIND, AssetKindEnum.PRODUCT_BUYER.getKind()),
Tuple2.ofList(LabelConstants.LABEL_BUYER_ID, authentication.getName()),
null,
PageRequest.ofSize(1),
null)
.getData();
if (CollectionUtils.isEmpty(list)) {
sink.error(KrakenException.badRequest("buyer not found"));
return;
}
UnifiedAssetDto unifiedAssetDto = list.get(0);
if (AssetStatusEnum.DEACTIVATED
.getKind()
.equalsIgnoreCase(unifiedAssetDto.getMetadata().getStatus())) {
sink.error(KrakenException.badRequest("buyer deactivated"));
return;
}
Map<String, String> labels = unifiedAssetDto.getMetadata().getLabels();
Instant dbGeneratedAt =
Optional.ofNullable(labels.get(LabelConstants.LABEL_ISSUE_AT))
.map(DateTimeFormatter.ISO_INSTANT::parse)
.map(Instant::from)
.orElse(Instant.MIN);
Jwt principal = (Jwt) authentication.getPrincipal();
String signEnv =
Optional.ofNullable(principal.getClaims())
.map(map -> map.get(Constants.ENV))
.map(Object::toString)
.orElse("");
if (!StringUtils.equalsIgnoreCase(resourceServer.getVerifier().getEnv(), signEnv)) {
sink.error(
KrakenException.badRequest(
"Invalid buyer: invalid environment identity env:" + signEnv));
return;
}
Instant issuedAt = principal.getIssuedAt();
if (Objects.requireNonNull(issuedAt).isBefore(dbGeneratedAt.minusSeconds(INTERVAL))) {
sink.error(KrakenException.badRequest("Token expired "));
return;
}
sink.next(new Object());
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.consoleconnect.kraken.operator.gateway.service;

import static org.mockito.Mockito.when;

import com.consoleconnect.kraken.operator.auth.model.AuthDataProperty;
import com.consoleconnect.kraken.operator.core.enums.AssetKindEnum;
import com.consoleconnect.kraken.operator.core.enums.AssetStatusEnum;
Expand All @@ -12,15 +14,19 @@
import com.consoleconnect.kraken.operator.gateway.CustomConfig;
import com.consoleconnect.kraken.operator.test.AbstractIntegrationTest;
import com.consoleconnect.kraken.operator.test.MockIntegrationTest;
import com.nimbusds.jwt.JWTParser;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import lombok.SneakyThrows;
import org.junit.jupiter.api.*;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.SynchronousSink;

@MockIntegrationTest
@ContextConfiguration(classes = CustomConfig.class)
Expand All @@ -32,6 +38,8 @@ public class BuyerCheckServiceTest extends AbstractIntegrationTest {
@Autowired BuyerCheckerService buyerCheckerService;
@Autowired WebTestClient webTestClient;
@Autowired AuthDataProperty.ResourceServer resourceServer;
@Mock private Authentication principal;
@Mock SynchronousSink<Object> sink;
private final String xKrakenKeyToken =
"eyJhbGciOiJIUzI1NiIsImtpZCI6ImtyYWtlbiIsInR5cCI6IkpXVCJ9.eyJleHAiOjQ0Mzg1Mzc5NDIsImlhdCI6MTcyNzMyODM0MiwiaXNzIjoiaHR0cHM6Ly9rcmFrZW4uY29uc29sZWNvbm5lY3QuY29tL2lzc3VlciIsInN1YiI6ImJ1eWVyMDIifQ.9FL7_ph6-NtJg5hNSOqt8HaxwMg66gnEjpb_XCMsXrY";

Expand All @@ -42,8 +50,19 @@ void givenBuyer_whenInit_thenReturnData() {
UnifiedAsset unifiedAsset =
UnifiedAsset.of(AssetKindEnum.PRODUCT_BUYER.getKind(), "buyer02", "buyer02");
unifiedAsset.getMetadata().setStatus(AssetStatusEnum.ACTIVATED.getKind());
Jwt jwt =
Jwt.withTokenValue(xKrakenKeyToken)
.headers(
map -> {
map.put("alg", "HS256");
map.put("typ", "JWT");
})
.issuedAt(Instant.now().minusSeconds(60))
.claim("env", "stage")
.build();
;

Instant instant = JWTParser.parse(xKrakenKeyToken).getJWTClaimsSet().getIssueTime().toInstant();
Instant instant = jwt.getIssuedAt();
unifiedAsset
.getMetadata()
.getLabels()
Expand All @@ -57,6 +76,10 @@ void givenBuyer_whenInit_thenReturnData() {
unifiedAsset,
new SyncMetadata("", "", DateTime.nowInUTCString(), ""),
true);
when(principal.getName()).thenReturn("buyer02");
when(principal.getPrincipal()).thenReturn(jwt);
SecurityContextImpl context = new SecurityContextImpl(this.principal);
buyerCheckerService.getSecurityContextSynchronousSinkBiConsumer().accept(context, sink);
Assertions.assertEquals(200, ingestionDataResult.getCode());
}
}

0 comments on commit 0a89c2d

Please sign in to comment.