From cf04a1a714ef4a1df973929dc750232b4d67d7b4 Mon Sep 17 00:00:00 2001 From: Kartik Hegde Date: Sat, 12 Nov 2022 14:29:11 +0530 Subject: Multitenancy in SDC Issue-ID: SDC-4215 Change-Id: Ie24ba38acc9f1998d4a7e722e8f98456dab9201d Signed-off-by: Kartik Hegde --- .../org/openecomp/sdcrests/item/rest/Items.java | 4 +- .../sdcrests/item/rest/mapping/MapItemToDto.java | 1 + .../sdcrests/item/rest/services/ItemsImpl.java | 25 +- .../sdcrests/item/rest/services/ItemsImplTest.java | 84 +++++- .../org/openecomp/sdcrests/item/types/ItemDto.java | 8 + .../server/filters/MultitenancyKeycloakFilter.java | 286 +++++++++++++++++++++ .../src/main/webapp/WEB-INF/keycloak.json | 11 + .../src/main/webapp/WEB-INF/web.xml | 14 + .../vendorlicense/rest/VendorLicenseModels.java | 8 +- .../mapping/MapVendorLicenseModelEntityToDto.java | 3 + ...eModelRequestDtoToVendorLicenseModelEntity.java | 1 + .../rest/services/VendorLicenseModelsImpl.java | 114 ++++++-- .../types/VendorLicenseModelEntityDto.java | 6 + .../types/VendorLicenseModelRequestDto.java | 10 + .../sdcrests/vsp/rest/VendorSoftwareProducts.java | 15 +- .../vsp/rest/mapping/MapItemToVspDetailsDto.java | 1 + .../rest/mapping/MapVspDescriptionDtoToItem.java | 1 + .../mapping/MapVspDescriptionDtoToVspDetails.java | 3 + .../vsp/rest/mapping/MapVspDetailsToDto.java | 1 + .../rest/services/VendorSoftwareProductsImpl.java | 127 ++++++--- .../types/VspDescriptionDto.java | 8 + .../types/VspDetailsDto.java | 1 + 22 files changed, 654 insertions(+), 78 deletions(-) create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/java/org/openecomp/server/filters/MultitenancyKeycloakFilter.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/keycloak.json (limited to 'openecomp-be/api/openecomp-sdc-rest-webapp') diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/Items.java b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/Items.java index 066acb9370..a2c0e39e8f 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/Items.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/Items.java @@ -26,6 +26,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; +import javax.servlet.http.HttpServletRequest; import javax.validation.constraints.NotNull; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -35,6 +36,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.openecomp.sdc.versioning.types.Item; @@ -61,7 +63,7 @@ public interface Items { @QueryParam("permission") String permissionFilter, @Parameter(description = "Filter by onboarding method", schema = @Schema(type = "string", allowableValues = {"NetworkPackage", "manual"})) @QueryParam("onboardingMethod") String onboardingMethodFilter, - @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user); + @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user, @Context HttpServletRequest hreq); @GET @Path("/{itemId}") diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/mapping/MapItemToDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/mapping/MapItemToDto.java index 3bd8a7fe9f..0eb74a03b6 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/mapping/MapItemToDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/mapping/MapItemToDto.java @@ -34,5 +34,6 @@ public class MapItemToDto extends MappingBase { target.setOwner(source.getOwner()); target.setStatus(source.getStatus().name()); target.setProperties(source.getProperties()); + target.setTenant(source.getTenant()); } } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/services/ItemsImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/services/ItemsImpl.java index 9fb6ebd8b8..af3568cd2a 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/services/ItemsImpl.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/main/java/org/openecomp/sdcrests/item/rest/services/ItemsImpl.java @@ -35,12 +35,15 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import javax.annotation.PostConstruct; import javax.inject.Named; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; +import org.keycloak.representations.AccessToken; import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity; import org.openecomp.sdc.activitylog.dao.type.ActivityType; import org.openecomp.sdc.be.csar.storage.StorageFactory; import org.openecomp.sdc.common.errors.ErrorCode.ErrorCodeBuilder; import org.openecomp.sdc.common.errors.ErrorCodeAndMessage; +import org.openecomp.sdc.common.util.Multitenancy; import org.openecomp.sdc.datatypes.model.ItemType; import org.openecomp.sdc.itempermissions.impl.types.PermissionTypes; import org.openecomp.sdc.logging.api.Logger; @@ -116,15 +119,27 @@ public class ItemsImpl implements Items { @Override public Response list(String itemStatusFilter, String versionStatusFilter, String itemTypeFilter, String permissionFilter, - String onboardingMethodFilter, String user) { + String onboardingMethodFilter, String user, HttpServletRequest hreq) { Predicate itemPredicate = createItemPredicate(itemStatusFilter, versionStatusFilter, itemTypeFilter, onboardingMethodFilter, permissionFilter, user); GenericCollectionWrapper results = new GenericCollectionWrapper<>(); MapItemToDto mapper = new MapItemToDto(); - getManagersProvider().getItemManager().list(itemPredicate).stream() - .sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime())) - .forEach(item -> results.add(mapper.applyMapping(item, ItemDto.class))); - return Response.ok(results).build(); + Multitenancy keyaccess= new Multitenancy(); + if (keyaccess.multiTenancyCheck()) { + AccessToken.Access realmAccess = keyaccess.getAccessToken(hreq).getRealmAccess(); + Set realmroles = realmAccess.getRoles(); + realmroles.stream().forEach(role -> getManagersProvider().getItemManager().list(itemPredicate).stream() + .sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime())) + .filter(item -> item.getTenant().contains(role)) + .forEach(item -> results.add(mapper.applyMapping(item, ItemDto.class)))); + return Response.ok(results).build(); + } + else{ + getManagersProvider().getItemManager().list(itemPredicate).stream() + .sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime())) + .forEach(item -> results.add(mapper.applyMapping(item, ItemDto.class))); + return Response.ok(results).build(); + } } @Override diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/test/java/org/openecomp/sdcrests/item/rest/services/ItemsImplTest.java b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/test/java/org/openecomp/sdcrests/item/rest/services/ItemsImplTest.java index 25de08304b..da3e6f3297 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/test/java/org/openecomp/sdcrests/item/rest/services/ItemsImplTest.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-services/src/test/java/org/openecomp/sdcrests/item/rest/services/ItemsImplTest.java @@ -22,6 +22,7 @@ package org.openecomp.sdcrests.item.rest.services; import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -39,7 +40,11 @@ import io.minio.MinioClient; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.HashSet; +import java.util.Set; import javax.ws.rs.core.Response; + +import org.junit.Assert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -58,6 +63,7 @@ import org.openecomp.sdc.versioning.ItemManager; import org.openecomp.sdc.versioning.VersioningManager; import org.openecomp.sdc.versioning.dao.types.Version; import org.openecomp.sdc.versioning.types.Item; +import org.openecomp.sdc.versioning.types.ItemStatus; import org.openecomp.sdcrests.item.types.ItemActionRequestDto; @ExtendWith(MockitoExtension.class) @@ -71,6 +77,8 @@ class ItemsImplTest { private static final String CREDENTIALS = "credentials"; private static final String TEMP_PATH = "tempPath"; private static final String UPLOAD_PARTSIZE = "uploadPartSize"; + private static final boolean MULTITENANCY_ENABLED = true; + private static final String TEST_TENANT = "test_tenant"; @Mock private ManagersProvider managersProvider; @@ -190,7 +198,7 @@ class ItemsImplTest { items.initActionSideAffectsMap(); items.setManagersProvider(managersProvider); when(managersProvider.getItemManager()).thenReturn(itemManager); - Response response = items.list(null, null, null, null, null, USER); + Response response = items.list(null, null, null, null, null, USER, null); assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -201,4 +209,78 @@ class ItemsImplTest { versions.add(new Version("3")); return versions; } + + @Test + void getItemList_withMultitenancyValidTenant_ReturnSuccessList() { + Assert.assertTrue(MULTITENANCY_ENABLED); + Assert.assertNotNull(getTestRoles()); + items.initActionSideAffectsMap(); + items.setManagersProvider(managersProvider); + when(managersProvider.getItemManager()).thenReturn(itemManager); + Response response = items.list(null, null, null, null, null, USER, null); + assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + List expectedItems=new ArrayList<>(); + List actualItems=getAllItems(); + getTestRoles().stream().forEach(role -> getAllItems().stream() + .filter(item -> item.getTenant()!=null) + .filter(item -> item.getTenant().contains(role)) + .forEach(item -> expectedItems.add(item))); + assertNotSame(expectedItems.size(), actualItems.size()); + } + + + @Test + void getItemList_withMultitenancyInvalidTenant_ReturnsEmptylList() { + Assert.assertTrue(MULTITENANCY_ENABLED); + + Assert.assertNotNull(getTestRoles()); + String tenant= "invalid tenant"; + items.initActionSideAffectsMap(); + items.setManagersProvider(managersProvider); + when(managersProvider.getItemManager()).thenReturn(itemManager); + Response response = items.list(null, null, null, null, null, USER, null); + assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + List expectedItems=new ArrayList<>(); + List actualItems=getAllItems(); + assertNotNull(tenant); + getTestRoles().stream().forEach(role -> getAllItems().stream() + .filter(item -> item.getTenant()!=null) + .filter(item -> item.getTenant().contains(tenant)) + .forEach(item -> expectedItems.add(item))); + Assert.assertEquals(expectedItems.size(), 0); + Assert.assertNotEquals(expectedItems.containsAll(actualItems), actualItems.containsAll(expectedItems)); + } + + + private List getAllItems(){ + List items=new ArrayList<>(); + + Item itemOne = new Item(); + itemOne.setType(ItemType.vlm.name()); + itemOne.setOwner(USER); + itemOne.setStatus(ItemStatus.ACTIVE); + itemOne.setName("TEST_VENDOR_ONE"); + itemOne.setDescription("TEST_DESCRIPTION"); + itemOne.setTenant(TEST_TENANT); + + Item itemTwo = new Item(); + itemTwo.setType(ItemType.vsp.name()); + itemTwo.setOwner(USER); + itemTwo.setStatus(ItemStatus.ACTIVE); + itemTwo.setName("TEST_VSP_ONE"); + itemTwo.setDescription("TEST_DESCRIPTION"); + itemTwo.setTenant("admin_tenant"); + + items.add(itemOne); + items.add(itemTwo); + return items; + } + + + private Set getTestRoles(){ + Set roles = new HashSet<>(); + roles.add("test_admin"); + roles.add("test_tenant"); + return roles; + } } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-types/src/main/java/org/openecomp/sdcrests/item/types/ItemDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-types/src/main/java/org/openecomp/sdcrests/item/types/ItemDto.java index 34ad19fa7c..5e2810cc9e 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-types/src/main/java/org/openecomp/sdcrests/item/types/ItemDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/item-rest/item-rest-types/src/main/java/org/openecomp/sdcrests/item/types/ItemDto.java @@ -32,6 +32,7 @@ public class ItemDto { private String description; private String owner; private String status; + private String tenant; private Map properties; public void setId(final String id) { @@ -58,4 +59,11 @@ public class ItemDto { this.status = ValidationUtils.sanitizeInputString(status); } + public void setTenant(final String tenant) { + if(tenant != null) { + this.tenant = ValidationUtils.sanitizeInputString(tenant); + } + else this.tenant=tenant; + } + } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/java/org/openecomp/server/filters/MultitenancyKeycloakFilter.java b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/java/org/openecomp/server/filters/MultitenancyKeycloakFilter.java new file mode 100644 index 0000000000..8cb87e3e33 --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/java/org/openecomp/server/filters/MultitenancyKeycloakFilter.java @@ -0,0 +1,286 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2022 Tech-Mahindra Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.server.filters; + +import org.keycloak.adapters.AdapterDeploymentContext; +import org.keycloak.adapters.AuthenticatedActionsHandler; +import org.keycloak.adapters.KeycloakConfigResolver; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.KeycloakDeploymentBuilder; +import org.keycloak.adapters.NodesRegistrationManagement; +import org.keycloak.adapters.PreAuthActionsHandler; +import org.keycloak.adapters.servlet.FilterRequestAuthenticator; +import org.keycloak.adapters.servlet.OIDCFilterSessionStore; +import org.keycloak.adapters.servlet.OIDCServletHttpFacade; +import org.keycloak.adapters.spi.AuthChallenge; +import org.keycloak.adapters.spi.AuthOutcome; +import org.keycloak.adapters.spi.InMemorySessionIdMapper; +import org.keycloak.adapters.spi.SessionIdMapper; +import org.keycloak.adapters.spi.UserSessionManagement; +import org.openecomp.sdc.common.util.Multitenancy; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + + + +public class MultitenancyKeycloakFilter implements Filter { + + private static final Logger log = Logger.getLogger("" + MultitenancyKeycloakFilter.class); + + public static final String SKIP_PATTERN_PARAM = "keycloak.config.skipPattern"; + + public static final String ID_MAPPER_PARAM = "keycloak.config.idMapper"; + + public static final String CONFIG_RESOLVER_PARAM = "keycloak.config.resolver"; + + public static final String CONFIG_FILE_PARAM = "keycloak.config.file"; + + public static final String CONFIG_PATH_PARAM = "keycloak.config.path"; + + protected AdapterDeploymentContext deploymentContext; + + protected SessionIdMapper idMapper = new InMemorySessionIdMapper(); + + protected NodesRegistrationManagement nodesRegistrationManagement; + + protected Pattern skipPattern; + + private final KeycloakConfigResolver definedconfigResolver; + + boolean keycloak; + + /** + * Constructor that can be used to define a {@code KeycloakConfigResolver} that will be used at initialization to + * provide the {@code KeycloakDeployment}. + * @param definedconfigResolver the resolver + */ + public MultitenancyKeycloakFilter(KeycloakConfigResolver definedconfigResolver) { + this.definedconfigResolver = definedconfigResolver; + } + + public MultitenancyKeycloakFilter() { + this(null); + } + + @Override + public void init(final FilterConfig filterConfig) throws ServletException { + String skipPatternDefinition = filterConfig.getInitParameter(SKIP_PATTERN_PARAM); + if (skipPatternDefinition != null) { + skipPattern = Pattern.compile(skipPatternDefinition, Pattern.DOTALL); + } + + String idMapperClassName = filterConfig.getInitParameter(ID_MAPPER_PARAM); + if (idMapperClassName != null) { + try { + final Class idMapperClass = getClass().getClassLoader().loadClass(idMapperClassName); + final Constructor idMapperConstructor = idMapperClass.getDeclaredConstructor(); + Object idMapperInstance = null; + // for KEYCLOAK-13745 test + if (idMapperConstructor.getModifiers() == Modifier.PRIVATE) { + idMapperInstance = idMapperClass.getMethod("getInstance").invoke(null); + } else { + idMapperInstance = idMapperConstructor.newInstance(); + } + if(idMapperInstance instanceof SessionIdMapper) { + this.idMapper = (SessionIdMapper) idMapperInstance; + } else { + log.log(Level.WARNING, "SessionIdMapper class {0} is not instance of org.keycloak.adapters.spi.SessionIdMapper", idMapperClassName); + } + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + log.log(Level.WARNING, "SessionIdMapper class could not be instanced", e); + } + } + + if (definedconfigResolver != null) { + deploymentContext = new AdapterDeploymentContext(definedconfigResolver); + log.log(Level.INFO, "Using {0} to resolve Keycloak configuration on a per-request basis.", definedconfigResolver.getClass()); + } else { + String configResolverClass = filterConfig.getInitParameter(CONFIG_RESOLVER_PARAM); + if (configResolverClass != null) { + try { + KeycloakConfigResolver configResolver = (KeycloakConfigResolver) getClass().getClassLoader().loadClass(configResolverClass).getDeclaredConstructor().newInstance(); + deploymentContext = new AdapterDeploymentContext(configResolver); + log.log(Level.INFO, "Using {0} to resolve Keycloak configuration on a per-request basis.", configResolverClass); + } catch (Exception ex) { + log.log(Level.FINE, "The specified resolver {0} could NOT be loaded. Keycloak is unconfigured and will deny all requests. Reason: {1}", new Object[]{configResolverClass, ex.getMessage()}); + deploymentContext = new AdapterDeploymentContext(new KeycloakDeployment()); + } + } else { + String fp = filterConfig.getInitParameter(CONFIG_FILE_PARAM); + InputStream is = null; + if (fp != null) { + try { + is = new FileInputStream(fp); + } catch (FileNotFoundException e) { + log.log(Level.FINE, "config file is empty",e); + } + } else { + String path = "/WEB-INF/keycloak.json"; + String pathParam = filterConfig.getInitParameter(CONFIG_PATH_PARAM); + if (pathParam != null) path = pathParam; + is = filterConfig.getServletContext().getResourceAsStream(path); + } + KeycloakDeployment kd = createKeycloakDeploymentFrom(is); + deploymentContext = new AdapterDeploymentContext(kd); + log.fine("Keycloak is using a per-deployment configuration."); + } + } + filterConfig.getServletContext().setAttribute(AdapterDeploymentContext.class.getName(), deploymentContext); + nodesRegistrationManagement = new NodesRegistrationManagement(); + } + + private KeycloakDeployment createKeycloakDeploymentFrom(InputStream is) { + if (is == null) { + log.fine("No adapter configuration. Keycloak is unconfigured and will deny all requests."); + return new KeycloakDeployment(); + } + return KeycloakDeploymentBuilder.build(is); + } + + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + log.fine("Keycloak OIDC Filter"); + Multitenancy keyaccess= new Multitenancy(); + keycloak= keyaccess.multiTenancyCheck(); + + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + + if (!keycloak) { + chain.doFilter(req, res); + return; + } + + if (shouldSkip(request)) { + chain.doFilter(req, res); + return; + } + + OIDCServletHttpFacade facade = new OIDCServletHttpFacade(request, response); + KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade); + if (deployment == null || !deployment.isConfigured()) { + response.sendError(403); + log.fine("deployment not configured"); + return; + } + + PreAuthActionsHandler preActions = new PreAuthActionsHandler(new org.openecomp.server.filters.MultitenancyKeycloakFilter.IdMapperUserSessionManagement(), deploymentContext, facade); + + if (preActions.handleRequest()) { + return; + } + + + nodesRegistrationManagement.tryRegister(deployment); + OIDCFilterSessionStore tokenStore = new OIDCFilterSessionStore(request, facade, 100000, deployment, idMapper); + tokenStore.checkCurrentToken(); + + + FilterRequestAuthenticator authenticator = new FilterRequestAuthenticator(deployment, tokenStore, facade, request, 8443); + AuthOutcome outcome = authenticator.authenticate(); + if (outcome == AuthOutcome.AUTHENTICATED) { + log.fine("AUTHENTICATED"); + if (facade.isEnded()) { + return; + } + AuthenticatedActionsHandler actions = new AuthenticatedActionsHandler(deployment, facade); + if (actions.handledRequest()) { + return; + } else { + HttpServletRequestWrapper wrapper = tokenStore.buildWrapper(); + chain.doFilter(wrapper, res); + return; + } + } + AuthChallenge challenge = authenticator.getChallenge(); + if (challenge != null) { + log.fine("challenge"); + challenge.challenge(facade); + return; + } + response.sendError(403); + + } + + /** + * Decides whether this {@link Filter} should skip the given {@link HttpServletRequest} based on the configured {@link org.keycloak.adapters.servlet.KeycloakOIDCFilter#skipPattern}. + * Patterns are matched against the {@link HttpServletRequest#getRequestURI() requestURI} of a request without the context-path. + * A request for {@code /myapp/index.html} would be tested with {@code /index.html} against the skip pattern. + * Skipped requests will not be processed further by {@link org.keycloak.adapters.servlet.KeycloakOIDCFilter} and immediately delegated to the {@link FilterChain}. + * + * @param request the request to check + * @return {@code true} if the request should not be handled, + * {@code false} otherwise. + */ + private boolean shouldSkip(HttpServletRequest request) { + + if (skipPattern == null) { + return false; + } + + String requestPath = request.getRequestURI().substring(request.getContextPath().length()); + return skipPattern.matcher(requestPath).matches(); + } + + @Override + public void destroy() { + + } + + private class IdMapperUserSessionManagement implements UserSessionManagement { + @Override + public void logoutAll() { + if (idMapper != null) { + idMapper.clear(); + } + } + + @Override + public void logoutHttpSessions(List ids) { + log.fine("**************** logoutHttpSessions"); + for (String id : ids) { + log.finest(id); + idMapper.removeSession(id); + } + + } + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/keycloak.json b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/keycloak.json new file mode 100644 index 0000000000..d037661aec --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/keycloak.json @@ -0,0 +1,11 @@ +{ +"realm": "sdc", +"auth-server-url": "http://10.32.243.37:31613/", +"ssl-required": "external", +"resource": "sdc-app", +"public-client":true, +"bearer-only":true, +"use-resource-role-mappings": true, +"principal-attribute":"preferred_username", +"confidential-port": 0 +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/web.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/web.xml index 31400f878e..7d2edf4994 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/web.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/web.xml @@ -24,6 +24,20 @@ org.openecomp.server.listeners.OnboardingAppStartupListener + + + Keycloak Filter + org.openecomp.server.filters.MultitenancyKeycloakFilter + + + Keycloak Filter + /keycloak/* + /v1.0/vendor-license-models/* + /v1.0/vendor-software-products + */actions + /v1.0/items/* + + dataValidatorFilter org.openecomp.sdc.common.filters.DataValidatorFilter diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/VendorLicenseModels.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/VendorLicenseModels.java index 0636b6e599..1c942d46c5 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/VendorLicenseModels.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/VendorLicenseModels.java @@ -45,6 +45,8 @@ import org.openecomp.sdcrests.vendorlicense.types.VendorLicenseModelActionReques import org.openecomp.sdcrests.vendorlicense.types.VendorLicenseModelEntityDto; import org.openecomp.sdcrests.vendorlicense.types.VendorLicenseModelRequestDto; import org.springframework.validation.annotation.Validated; +import javax.ws.rs.core.Context; +import javax.servlet.http.HttpServletRequest; @Path("/v1.0/vendor-license-models") @Produces(MediaType.APPLICATION_JSON) @@ -61,13 +63,13 @@ public interface VendorLicenseModels { @Parameter(description = "Filter to only return Vendor License Models at this status." + "Currently supported values: 'ACTIVE' , 'ARCHIVED'." + "Default value = 'ACTIVE'.") @QueryParam("Status") String itemStatus, - @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(RestConstants.USER_ID_HEADER_PARAM) String user); + @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(RestConstants.USER_ID_HEADER_PARAM) String user , @Context HttpServletRequest req); @POST @Path("/") - @Operation(description = "Create vendor license model") + @Operation(description = "Create vendor license model", responses = @ApiResponse(responseCode = "401", description = "Unauthorized Tenant")) Response createLicenseModel(@Valid VendorLicenseModelRequestDto request, - @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(RestConstants.USER_ID_HEADER_PARAM) String user); + @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(RestConstants.USER_ID_HEADER_PARAM) String user, @Context HttpServletRequest req); @DELETE @Path("/{vlmId}") diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/mapping/MapVendorLicenseModelEntityToDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/mapping/MapVendorLicenseModelEntityToDto.java index 5b0bfb7d73..9a099b83cc 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/mapping/MapVendorLicenseModelEntityToDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-services/src/main/java/org/openecomp/sdcrests/vendorlicense/rest/mapping/MapVendorLicenseModelEntityToDto.java @@ -31,5 +31,8 @@ public class MapVendorLicenseModelEntityToDto extends MappingBase itemPredicate = createItemPredicate(versionStatus, itemStatus, user); GenericCollectionWrapper results = new GenericCollectionWrapper<>(); MapItemToDto mapper = new MapItemToDto(); - asdcItemManager.list(itemPredicate).stream().sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime())) - .forEach(item -> results.add(mapper.applyMapping(item, ItemDto.class))); - return Response.ok(results).build(); + Multitenancy keyaccess= new Multitenancy(); + if (keyaccess.multiTenancyCheck()) { + AccessToken.Access realmAccess = keyaccess.getAccessToken(hreq).getRealmAccess(); + Set realmroles = realmAccess.getRoles(); + realmroles.stream().forEach(role -> asdcItemManager.list(itemPredicate).stream().sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime())) + .filter(item -> item.getTenant().contains(role)) + .forEach(item -> results.add(mapper.applyMapping(item, ItemDto.class)))); + return Response.ok(results).build(); + } + else + { + asdcItemManager.list(itemPredicate).stream().sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime())) + .forEach(item -> results.add(mapper.applyMapping(item, ItemDto.class))); + return Response.ok(results).build(); + } } @Override - public Response createLicenseModel(VendorLicenseModelRequestDto request, String user) { - Item item = new Item(); - item.setType(ItemType.vlm.name()); - item.setOwner(user); - item.setStatus(ItemStatus.ACTIVE); - item.setName(request.getVendorName()); - item.setDescription(request.getDescription()); - uniqueValueUtil.validateUniqueValue(VendorLicenseConstants.UniqueValues.VENDOR_NAME, item.getName()); - item = asdcItemManager.create(item); - uniqueValueUtil.createUniqueValue(VendorLicenseConstants.UniqueValues.VENDOR_NAME, item.getName()); - Version version = versioningManager.create(item.getId(), new Version(), null); - VendorLicenseModelEntity vlm = new MapVendorLicenseModelRequestDtoToVendorLicenseModelEntity() - .applyMapping(request, VendorLicenseModelEntity.class); - vlm.setId(item.getId()); - vlm.setVersion(version); - vendorLicenseManager.createVendorLicenseModel(vlm); - versioningManager.publish(item.getId(), version, "Initial vlm:" + vlm.getVendorName()); - ItemCreationDto itemCreationDto = new ItemCreationDto(); - itemCreationDto.setItemId(item.getId()); - itemCreationDto.setVersion(new MapVersionToDto().applyMapping(version, VersionDto.class)); - activityLogManager.logActivity(new ActivityLogEntity(vlm.getId(), version, ActivityType.Create, user, true, "", "")); - return Response.ok(itemCreationDto).build(); + public Response createLicenseModel(VendorLicenseModelRequestDto request, String user, HttpServletRequest hreq) { + Multitenancy keyaccess= new Multitenancy(); + if (keyaccess.multiTenancyCheck()) { + AccessToken.Access realmAccess = keyaccess.getAccessToken(hreq).getRealmAccess(); + Set realmroles = realmAccess.getRoles(); + boolean match = realmroles.contains(request.getTenant()); + if (match) { + Item item = new Item(); + item.setType(ItemType.vlm.name()); + item.setOwner(user); + item.setStatus(ItemStatus.ACTIVE); + item.setName(request.getVendorName()); + item.setDescription(request.getDescription()); + item.setTenant(request.getTenant()); + uniqueValueUtil.validateUniqueValue(VendorLicenseConstants.UniqueValues.VENDOR_NAME, item.getName()); + item = asdcItemManager.create(item); + uniqueValueUtil.createUniqueValue(VendorLicenseConstants.UniqueValues.VENDOR_NAME, item.getName()); + Version version = versioningManager.create(item.getId(), new Version(), null); + VendorLicenseModelEntity vlm = new MapVendorLicenseModelRequestDtoToVendorLicenseModelEntity() + .applyMapping(request, VendorLicenseModelEntity.class); + vlm.setId(item.getId()); + vlm.setVersion(version); + vendorLicenseManager.createVendorLicenseModel(vlm); + versioningManager.publish(item.getId(), version, "Initial vlm:" + vlm.getVendorName()); + ItemCreationDto itemCreationDto = new ItemCreationDto(); + itemCreationDto.setItemId(item.getId()); + itemCreationDto.setVersion(new MapVersionToDto().applyMapping(version, VersionDto.class)); + activityLogManager.logActivity(new ActivityLogEntity(vlm.getId(), version, ActivityType.Create, user, true, "", "")); + return Response.ok(itemCreationDto).build(); + } + else { + LOGGER.error("Unauthorized tenant"); + return Response.status(401, "Unauthorized tenant").build(); + } + } + else + { + Item item = new Item(); + item.setType(ItemType.vlm.name()); + item.setOwner(user); + item.setStatus(ItemStatus.ACTIVE); + item.setName(request.getVendorName()); + item.setDescription(request.getDescription()); + uniqueValueUtil.validateUniqueValue(VendorLicenseConstants.UniqueValues.VENDOR_NAME, item.getName()); + item = asdcItemManager.create(item); + uniqueValueUtil.createUniqueValue(VendorLicenseConstants.UniqueValues.VENDOR_NAME, item.getName()); + Version version = versioningManager.create(item.getId(), new Version(), null); + VendorLicenseModelEntity vlm = new MapVendorLicenseModelRequestDtoToVendorLicenseModelEntity() + .applyMapping(request, VendorLicenseModelEntity.class); + vlm.setId(item.getId()); + vlm.setVersion(version); + vendorLicenseManager.createVendorLicenseModel(vlm); + versioningManager.publish(item.getId(), version, "Initial vlm:" + vlm.getVendorName()); + ItemCreationDto itemCreationDto = new ItemCreationDto(); + itemCreationDto.setItemId(item.getId()); + itemCreationDto.setVersion(new MapVersionToDto().applyMapping(version, VersionDto.class)); + activityLogManager.logActivity(new ActivityLogEntity(vlm.getId(), version, ActivityType.Create, user, true, "", "")); + return Response.ok(itemCreationDto).build(); + } } @Override diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelEntityDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelEntityDto.java index 2c647647d8..020539ad86 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelEntityDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelEntityDto.java @@ -20,7 +20,11 @@ package org.openecomp.sdcrests.vendorlicense.types; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +@Getter +@Setter @Schema(description = "VendorLicenseModelEntity") public class VendorLicenseModelEntityDto extends VendorLicenseModelRequestDto { @@ -33,4 +37,6 @@ public class VendorLicenseModelEntityDto extends VendorLicenseModelRequestDto { public void setId(String id) { this.id = id; } + + private String tenant; } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelRequestDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelRequestDto.java index ba8fd96e6e..bb93a219a8 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelRequestDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-license-rest/vendor-license-rest-types/src/main/java/org/openecomp/sdcrests/vendorlicense/types/VendorLicenseModelRequestDto.java @@ -38,6 +38,9 @@ public class VendorLicenseModelRequestDto { @NotNull private String iconRef; + @Size(max = 25) + private String tenant; + public void setVendorName(final String vendorName) { this.vendorName = ValidationUtils.sanitizeInputString(vendorName); } @@ -45,4 +48,11 @@ public class VendorLicenseModelRequestDto { public void setDescription(final String description) { this.description = ValidationUtils.sanitizeInputString(description); } + + public void setTenant(final String tenant) { + if(tenant != null){ + this.tenant = ValidationUtils.sanitizeInputString(tenant); + } + else this.tenant=tenant; + } } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/VendorSoftwareProducts.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/VendorSoftwareProducts.java index fbe7d371ca..347cc4b15b 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/VendorSoftwareProducts.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/VendorSoftwareProducts.java @@ -28,6 +28,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; import java.io.File; import java.io.IOException; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.ws.rs.Consumes; @@ -40,6 +41,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.openecomp.sdcrests.item.types.ItemCreationDto; @@ -62,8 +64,9 @@ public interface VendorSoftwareProducts extends VspEntities { @POST @Path("/") - @Operation(description = "Create a new vendor software product", responses = @ApiResponse(content = @Content(schema = @Schema(implementation = ItemCreationDto.class)))) - Response createVsp(@Valid VspRequestDto vspRequestDto, @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user); + @Operation(description = "Create a new vendor software product", responses = {@ApiResponse(content = @Content(schema = @Schema(implementation = ItemCreationDto.class))) + , @ApiResponse(responseCode = "401", description = "Unauthorized Tenant")}) + Response createVsp(@Valid VspRequestDto vspRequestDto, @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user, @Context HttpServletRequest req); @GET @Path("/") @@ -71,9 +74,9 @@ public interface VendorSoftwareProducts extends VspEntities { Response listVsps(@Parameter(description = "Filter to return only Vendor Software Products with at" + " least one version at this status. Currently supported values: 'Certified' , 'Draft'") @QueryParam("versionFilter") String versionStatus, @Parameter(description = "Filter to only return Vendor Software Products at this status." - + "Currently supported values: 'ACTIVE' , 'ARCHIVED'." - + "Default value = 'ACTIVE'.") @QueryParam("Status") String itemStatus, - @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user); + + "Currently supported values: 'ACTIVE' , 'ARCHIVED'." + + "Default value = 'ACTIVE'.") @QueryParam("Status") String itemStatus, + @NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user, @Context HttpServletRequest req); @GET @Path("/{vspId}") @@ -116,7 +119,7 @@ public interface VendorSoftwareProducts extends VspEntities { @GET @Path("/validation-vsp") - Response getValidationVsp(@NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user) throws Exception; + Response getValidationVsp(@NotNull(message = USER_MISSING_ERROR_MSG) @HeaderParam(USER_ID_HEADER_PARAM) String user, @Context HttpServletRequest hreq) throws Exception; @PUT @Path("/{vspId}/versions/{versionId}/actions") diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapItemToVspDetailsDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapItemToVspDetailsDto.java index e0966e8350..1ec3d8fc8a 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapItemToVspDetailsDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapItemToVspDetailsDto.java @@ -36,5 +36,6 @@ public class MapItemToVspDetailsDto extends MappingBase { target.setOnboardingMethod((String) source.getProperties().get(VspItemProperty.ONBOARDING_METHOD)); target.setOwner(source.getOwner()); target.setStatus(source.getStatus().name()); + target.setTenant(source.getTenant()); } } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapVspDescriptionDtoToItem.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapVspDescriptionDtoToItem.java index 0543c20298..d833a1bd8c 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapVspDescriptionDtoToItem.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/mapping/MapVspDescriptionDtoToItem.java @@ -29,6 +29,7 @@ public class MapVspDescriptionDtoToItem extends MappingBase { target.setSubCategory(source.getSubCategory()); target.setVendorId(source.getVendorId()); target.setVendorName(source.getVendorName()); + target.setTenant(source.getTenant()); target.setLicensingVersion(source.getVlmVersion() == null ? null : source.getVlmVersion().getId()); if (StringUtils.isNotBlank(source.getLicenseType())) { target.setLicenseType(LicenseType.valueOf(source.getLicenseType())); diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java index b424db9b42..c859414112 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java @@ -42,6 +42,7 @@ import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Collectors; import javax.inject.Named; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; import org.apache.commons.collections4.MapUtils; import org.openecomp.core.dao.UniqueValueDaoFactory; @@ -55,6 +56,7 @@ import org.openecomp.sdc.be.csar.storage.StorageFactory; import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.common.errors.ErrorCode; import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.common.util.Multitenancy; import org.openecomp.sdc.datatypes.error.ErrorMessage; import org.openecomp.sdc.datatypes.model.ItemType; import org.openecomp.sdc.healing.factory.HealingManagerFactory; @@ -116,6 +118,7 @@ import org.openecomp.sdcrests.vsp.rest.mapping.MapVspDetailsToDto; import org.openecomp.sdcrests.wrappers.GenericCollectionWrapper; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import org.keycloak.representations.AccessToken; @Named @Service("vendorSoftwareProducts") @@ -173,12 +176,15 @@ public class VendorSoftwareProductsImpl implements VendorSoftwareProducts { } @Override - public Response createVsp(VspRequestDto vspRequestDto, String user) { - ItemCreationDto vspCreationDto = createVspItem(vspRequestDto, user); - return Response.ok(vspCreationDto).build(); - } + public Response createVsp(VspRequestDto vspRequestDto, String user, HttpServletRequest hreq) { + ItemCreationDto vspCreationDto = createVspItem(vspRequestDto, user, hreq); + if (vspCreationDto != null) { + return Response.ok(vspCreationDto).build(); + } + else return Response.status(401, "Unauthorized Tenant").build(); + } - private ItemCreationDto createVspItem(VspRequestDto vspRequestDto, String user) { + private ItemCreationDto createVspItem(VspRequestDto vspRequestDto, String user, HttpServletRequest hreq) { OnboardingMethod onboardingMethod = null; try { onboardingMethod = OnboardingMethod.valueOf(vspRequestDto.getOnboardingMethod()); @@ -188,34 +194,69 @@ public class VendorSoftwareProductsImpl implements VendorSoftwareProducts { } ItemCreationDto itemCreationDto = null; if (onboardingMethod == NetworkPackage || onboardingMethod == OnboardingMethod.Manual) { - itemCreationDto = createItem(vspRequestDto, user, onboardingMethod); + itemCreationDto = createItem(vspRequestDto, user, onboardingMethod, hreq); } else { throwUnknownOnboardingMethodException(new IllegalArgumentException("Wrong parameter Onboarding Method")); } return itemCreationDto; } - private ItemCreationDto createItem(VspRequestDto vspRequestDto, String user, OnboardingMethod onboardingMethod) { - Item item = new MapVspDescriptionDtoToItem().applyMapping(vspRequestDto, Item.class); - item.setType(ItemType.vsp.name()); - item.setOwner(user); - item.setStatus(ItemStatus.ACTIVE); - item.addProperty(VspItemProperty.ONBOARDING_METHOD, onboardingMethod.name()); - uniqueValueUtil.validateUniqueValue(VENDOR_SOFTWARE_PRODUCT_NAME, item.getName()); - item = itemManager.create(item); - uniqueValueUtil.createUniqueValue(VENDOR_SOFTWARE_PRODUCT_NAME, item.getName()); - Version version = versioningManager.create(item.getId(), new Version(), null); - VspDetails vspDetails = new MapVspDescriptionDtoToVspDetails().applyMapping(vspRequestDto, VspDetails.class); - vspDetails.setId(item.getId()); - vspDetails.setVersion(version); - vspDetails.setOnboardingMethod(vspRequestDto.getOnboardingMethod()); - vendorSoftwareProductManager.createVsp(vspDetails); - versioningManager.publish(item.getId(), version, "Initial vsp:" + vspDetails.getName()); - ItemCreationDto itemCreationDto = new ItemCreationDto(); - itemCreationDto.setItemId(item.getId()); - itemCreationDto.setVersion(new MapVersionToDto().applyMapping(version, VersionDto.class)); - activityLogManager.logActivity(new ActivityLogEntity(vspDetails.getId(), version, ActivityType.Create, user, true, "", "")); - return itemCreationDto; + private ItemCreationDto createItem(VspRequestDto vspRequestDto, String user, OnboardingMethod onboardingMethod , HttpServletRequest hreq) { + Multitenancy keyaccess= new Multitenancy(); + if (keyaccess.multiTenancyCheck()) { + AccessToken.Access realmAccess = keyaccess.getAccessToken(hreq).getRealmAccess(); + Set realmroles = realmAccess.getRoles(); + boolean match = realmroles.contains(vspRequestDto.getTenant()); + if (match) { + Item item = new MapVspDescriptionDtoToItem().applyMapping(vspRequestDto, Item.class); + item.setType(ItemType.vsp.name()); + item.setOwner(user); + item.setTenant(item.getTenant()); + item.setStatus(ItemStatus.ACTIVE); + item.addProperty(VspItemProperty.ONBOARDING_METHOD, onboardingMethod.name()); + uniqueValueUtil.validateUniqueValue(VENDOR_SOFTWARE_PRODUCT_NAME, item.getName()); + item = itemManager.create(item); + uniqueValueUtil.createUniqueValue(VENDOR_SOFTWARE_PRODUCT_NAME, item.getName()); + Version version = versioningManager.create(item.getId(), new Version(), null); + VspDetails vspDetails = new MapVspDescriptionDtoToVspDetails().applyMapping(vspRequestDto, VspDetails.class); + vspDetails.setId(item.getId()); + vspDetails.setVersion(version); + vspDetails.setOnboardingMethod(vspRequestDto.getOnboardingMethod()); + vendorSoftwareProductManager.createVsp(vspDetails); + versioningManager.publish(item.getId(), version, "Initial vsp:" + vspDetails.getName()); + ItemCreationDto itemCreationDto = new ItemCreationDto(); + itemCreationDto.setItemId(item.getId()); + itemCreationDto.setVersion(new MapVersionToDto().applyMapping(version, VersionDto.class)); + activityLogManager.logActivity(new ActivityLogEntity(vspDetails.getId(), version, ActivityType.Create, user, true, "", "")); + return itemCreationDto; + } + else { + LOGGER.error("Unauthorized tenant"); + return null; + } + } + else { + Item item = new MapVspDescriptionDtoToItem().applyMapping(vspRequestDto, Item.class); + item.setType(ItemType.vsp.name()); + item.setOwner(user); + item.setStatus(ItemStatus.ACTIVE); + item.addProperty(VspItemProperty.ONBOARDING_METHOD, onboardingMethod.name()); + uniqueValueUtil.validateUniqueValue(VENDOR_SOFTWARE_PRODUCT_NAME, item.getName()); + item = itemManager.create(item); + uniqueValueUtil.createUniqueValue(VENDOR_SOFTWARE_PRODUCT_NAME, item.getName()); + Version version = versioningManager.create(item.getId(), new Version(), null); + VspDetails vspDetails = new MapVspDescriptionDtoToVspDetails().applyMapping(vspRequestDto, VspDetails.class); + vspDetails.setId(item.getId()); + vspDetails.setVersion(version); + vspDetails.setOnboardingMethod(vspRequestDto.getOnboardingMethod()); + vendorSoftwareProductManager.createVsp(vspDetails); + versioningManager.publish(item.getId(), version, "Initial vsp:" + vspDetails.getName()); + ItemCreationDto itemCreationDto = new ItemCreationDto(); + itemCreationDto.setItemId(item.getId()); + itemCreationDto.setVersion(new MapVersionToDto().applyMapping(version, VersionDto.class)); + activityLogManager.logActivity(new ActivityLogEntity(vspDetails.getId(), version, ActivityType.Create, user, true, "", "")); + return itemCreationDto; + } } private void throwUnknownOnboardingMethodException(IllegalArgumentException e) { @@ -224,11 +265,25 @@ public class VendorSoftwareProductsImpl implements VendorSoftwareProducts { } @Override - public Response listVsps(String versionStatus, String itemStatus, String user) { - GenericCollectionWrapper results = new GenericCollectionWrapper<>(); - MapItemToVspDetailsDto mapper = new MapItemToVspDetailsDto(); - getVspList(versionStatus, itemStatus, user).forEach(vspItem -> results.add(mapper.applyMapping(vspItem, VspDetailsDto.class))); - return Response.ok(results).build(); + public Response listVsps(String versionStatus, String itemStatus, String user, HttpServletRequest hreq ) { + Multitenancy keyaccess = new Multitenancy(); + if (keyaccess.multiTenancyCheck()) { + AccessToken.Access realmAccess = keyaccess.getAccessToken(hreq).getRealmAccess(); + Set realmroles = realmAccess.getRoles(); + Predicate itemPredicate = createItemPredicate(versionStatus, itemStatus, user); + GenericCollectionWrapper results = new GenericCollectionWrapper<>(); + MapItemToVspDetailsDto mapper = new MapItemToVspDetailsDto(); + realmroles.stream().forEach(role -> itemManager.list(itemPredicate).stream().sorted((o1, o2) -> o2.getModificationTime().compareTo(o1.getModificationTime())) + .filter(vspItem -> vspItem.getTenant().contains(role)) + .forEach(vspItem -> results.add(mapper.applyMapping(vspItem, VspDetailsDto.class)))); + return Response.ok(results).build(); + } + else { + GenericCollectionWrapper results = new GenericCollectionWrapper<>(); + MapItemToVspDetailsDto mapper = new MapItemToVspDetailsDto(); + getVspList(versionStatus, itemStatus, user).forEach(vspItem -> results.add(mapper.applyMapping(vspItem, VspDetailsDto.class))); + return Response.ok(results).build(); + } } @Override @@ -427,12 +482,12 @@ public class VendorSoftwareProductsImpl implements VendorSoftwareProducts { } @Override - public Response getValidationVsp(String user) { - ItemCreationDto validationVsp = retrieveValidationVsp(); + public Response getValidationVsp(String user, HttpServletRequest hreq) { + ItemCreationDto validationVsp = retrieveValidationVsp(hreq); return Response.ok(validationVsp).build(); } - private ItemCreationDto retrieveValidationVsp() { + private ItemCreationDto retrieveValidationVsp(HttpServletRequest req) { synchronized (VALIDATION_VSP_CACHE_LOCK) { if (cachedValidationVsp != null) { return cachedValidationVsp; @@ -441,7 +496,7 @@ public class VendorSoftwareProductsImpl implements VendorSoftwareProducts { validationVspRequest.setOnboardingMethod(NetworkPackage.toString()); validationVspRequest.setName(VALIDATION_VSP_NAME); try { - cachedValidationVsp = createVspItem(validationVspRequest, VALIDATION_VSP_USER); + cachedValidationVsp = createVspItem(validationVspRequest, VALIDATION_VSP_USER, req); return cachedValidationVsp; } catch (CoreException vspCreateException) { LOGGER.debug("Failed to create validation VSP", vspCreateException); diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDescriptionDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDescriptionDto.java index e5f4ae0426..c194c4f357 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDescriptionDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDescriptionDto.java @@ -51,6 +51,7 @@ public class VspDescriptionDto { private LicenseType licenseType; private LicensingData licensingData; private List selectedModelList; + private String tenant; public void setName(final String name) { this.name = ValidationUtils.sanitizeInputString(name); @@ -64,6 +65,13 @@ public class VspDescriptionDto { this.description = ValidationUtils.sanitizeInputString(description); } + public void setTenant(final String tenant) { + if( tenant != null) { + this.tenant = ValidationUtils.sanitizeInputString(tenant); + } + else this.tenant=tenant; + } + public void setSelectedModelList(final List selectedModelList) { if (CollectionUtils.isEmpty(selectedModelList)) { this.selectedModelList = new ArrayList<>(); diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDetailsDto.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDetailsDto.java index 973d8ea577..25986cb109 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDetailsDto.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-types/src/main/java/org/openecomp/sdcrests/vendorsoftwareproducts/types/VspDetailsDto.java @@ -38,4 +38,5 @@ public class VspDetailsDto extends VspRequestDto { private String networkPackageName; private String owner; private String status; + private String tenant; } -- cgit 1.2.3-korg