Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sdk): fixed error show api use case in seller api server module #155

Merged
merged 6 commits into from
Nov 15, 2024
Merged
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());
}
}
Loading