Skip to content

Commit

Permalink
fix(sdk): fixed error show api use case in seller api server module (#…
Browse files Browse the repository at this point in the history
…155)

* fixed error show api use case in  seller api server module

* fixed buyer with wrong env

* fix  control plane api use case display error
  • Loading branch information
kuangxiang20240501 authored Nov 15, 2024
1 parent 54f2813 commit 76e4b3d
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 73 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 @@ -11,6 +11,8 @@
import com.fasterxml.jackson.core.type.TypeReference;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
Expand Down Expand Up @@ -38,30 +40,31 @@ public HttpResponse<Void> onEvent(String envId, String userId, ClientEvent event
if (CollectionUtils.isEmpty(serverAPIDtos)) {
return HttpResponse.ok(null);
}
serverAPIDtos.forEach(
serverAPIDto -> {
EnvironmentClientEntity environmentClientEntity =
environmentClientRepository
.findOneByEnvIdAndClientKeyAndKind(
envId,
serverAPIDto.getServerKey(),
ClientReportTypeEnum.CLIENT_SERVER_API.name())
.orElseGet(
() -> {
EnvironmentClientEntity entity = new EnvironmentClientEntity();
entity.setEnvId(envId);
entity.setKind(ClientReportTypeEnum.CLIENT_SERVER_API.name());
entity.setClientKey(serverAPIDto.getServerKey());
entity.setCreatedAt(ZonedDateTime.now());
entity.setCreatedBy(userId);
return entity;
});
environmentClientEntity.setUpdatedAt(ZonedDateTime.now());
environmentClientEntity.setUpdatedBy(userId);
environmentClientEntity.setPayload(serverAPIDto);
environmentClientRepository.save(environmentClientEntity);
});

Map<String, List<ServerAPIDto>> serverKeyMap =
serverAPIDtos.stream().collect(Collectors.groupingBy(ServerAPIDto::getServerKey));
serverKeyMap
.entrySet()
.forEach(
entry -> {
EnvironmentClientEntity environmentClientEntity =
environmentClientRepository
.findOneByEnvIdAndClientKeyAndKind(
envId, entry.getKey(), ClientReportTypeEnum.CLIENT_SERVER_API.name())
.orElseGet(
() -> {
EnvironmentClientEntity entity = new EnvironmentClientEntity();
entity.setEnvId(envId);
entity.setKind(ClientReportTypeEnum.CLIENT_SERVER_API.name());
entity.setClientKey(entry.getKey());
entity.setCreatedAt(ZonedDateTime.now());
entity.setCreatedBy(userId);
return entity;
});
environmentClientEntity.setUpdatedAt(ZonedDateTime.now());
environmentClientEntity.setUpdatedBy(userId);
environmentClientEntity.setPayload(entry.getValue());
environmentClientRepository.save(environmentClientEntity);
});
return HttpResponse.ok(null);
}
}
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 @@ -94,9 +94,10 @@ default void calculateDataPlane(
return;
}
String json = JsonToolkit.toJson(environmentClientEntity.getPayload());
ServerAPIDto serverAPIDto =
JsonToolkit.fromJson(json, new TypeReference<ServerAPIDto>() {});
List<String> mapperKeys = List.of(serverAPIDto.getMapperKey());
List<ServerAPIDto> serverAPIDtos =
JsonToolkit.fromJson(json, new TypeReference<List<ServerAPIDto>>() {});
List<String> mapperKeys =
serverAPIDtos.stream().map(ServerAPIDto::getMapperKey).toList();
List<UnifiedAssetDto> list =
getUnifiedAssetService().findByAllKeysIn(mapperKeys, true);
list.forEach(this::hiddenMappers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
import com.consoleconnect.kraken.operator.core.event.IngestionDataResult;
import com.consoleconnect.kraken.operator.core.exception.KrakenException;
import com.consoleconnect.kraken.operator.core.ingestion.DataIngestionJob;
import com.consoleconnect.kraken.operator.core.model.AssetLink;
import com.consoleconnect.kraken.operator.core.model.Metadata;
import com.consoleconnect.kraken.operator.core.model.SyncMetadata;
import com.consoleconnect.kraken.operator.core.model.UnifiedAsset;
import com.consoleconnect.kraken.operator.core.model.*;
import com.consoleconnect.kraken.operator.core.model.facet.ComponentAPITargetFacets;
import com.consoleconnect.kraken.operator.core.repo.UnifiedAssetRepository;
import com.consoleconnect.kraken.operator.core.service.CompatibilityCheckService;
Expand Down Expand Up @@ -73,6 +70,7 @@ public class TemplateUpgradeService {
private final TransactionService transactionService;
private final CompatibilityCheckService compatibilityCheckService;
private final EventSinkService eventSinkService;
private final AppProperty appProperty;

protected String deployProduction(
String templateUpgradeId, String stageEnvId, String productionEnvId, String userId) {
Expand Down Expand Up @@ -332,6 +330,7 @@ public Paging<TemplateUpgradeDeploymentVO> listTemplateDeployment(
public List<MapperTagVO> templateDeploymentDetailsFromControlDeployment(
UnifiedAssetDto templateDeployment) {
Map<String, List<Tuple2>> apiUseCases = apiComponentService.findApiUseCase();
log.info("apiUseCases : {}", JsonToolkit.toJson(apiUseCases));
ControlDeploymentFacet controlDeploymentFacet =
UnifiedAsset.getFacets(templateDeployment, ControlDeploymentFacet.class);
UpgradeTuple upgradeTuple = controlDeploymentFacet.getUpgradeTuple();
Expand All @@ -347,6 +346,7 @@ public List<MapperTagVO> templateDeploymentDetailsFromControlDeployment(
.filter(Optional::isPresent)
.map(Optional::get)
.map(ApiUseCaseDto::getMapperKey)
.filter(t -> !appProperty.getQueryExcludeAssetKeys().contains(t))
.distinct()
.map(this::getMapperTagVOFromDraft)
.toList();
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,17 @@ void givenBuyer_whenInit_thenReturnData() {
UnifiedAsset unifiedAsset =
UnifiedAsset.of(AssetKindEnum.PRODUCT_BUYER.getKind(), "buyer02", "buyer02");
unifiedAsset.getMetadata().setStatus(AssetStatusEnum.ACTIVATED.getKind());

Instant instant = JWTParser.parse(xKrakenKeyToken).getJWTClaimsSet().getIssueTime().toInstant();
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 = jwt.getIssuedAt();
unifiedAsset
.getMetadata()
.getLabels()
Expand All @@ -57,6 +74,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 76e4b3d

Please sign in to comment.