From a19844031c62fc820e72fba96228410baee21cf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Mon, 3 Oct 2022 12:11:25 -0500 Subject: [PATCH 01/12] enable Reproducible Builds --- client/pom.xml | 1 - pom.xml | 5 ++--- tools/checkstyle/pom.xml | 6 ++++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index 9394180848b..39fe824ff3a 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -781,7 +781,6 @@ org.apache.maven.plugins maven-shade-plugin - 3.0.0 rebuild-war diff --git a/pom.xml b/pom.xml index ff4de809cf0..5693c95bf8b 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ org.apache apache - 11 + 27 @@ -47,6 +47,7 @@ + 10 UTF-8 UTF-8 4.17.0.0 @@ -73,7 +74,6 @@ 3.12.0 3.0.0 5.3.0 - 2.5.3 3.1.0 3.8.2 2.22.2 @@ -883,7 +883,6 @@ org.apache.maven.plugins maven-release-plugin - ${cs.release-plugin.version} default diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index 5bcd3eaf2ac..6769945dbe4 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -25,12 +25,18 @@ 4.18.0.0-SNAPSHOT + 10 UTF-8 UTF-8 + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + org.apache.maven.plugins maven-site-plugin From 7cfbcf4b4f1b3e36ea496cbdbf17d1c49d8a8d1b Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Sat, 3 Aug 2024 02:00:04 +0530 Subject: [PATCH 02/12] [4.19] server, api, ui: access improvements and assorted fixes (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * server, api, ui: access improvements and assorted fixes Fixes domain-admin access check to prevent unauthorized access. Co-authored-by: Fabricio Duarte Co-authored-by: nvazquez Co-authored-by: Abhishek Kumar * Revert "server: refactor listNetworks api database retrievals (#9184)" This reverts commit c7f1ba5b8eec03d51bfe0f1432e46c9101b0f940. * Fix snapshot chain being deleted on XenServer (#9447) Using XenServer as the hypervisor, when deleting a snapshot that has a parent, that parent will also get erased on storage, causing data loss. This behavior was introduced with #7873, where the list of snapshot states that can be deleted was changed to add BackedUp snapshots. This PR changes the states list back to the original list, and swaps the while loop for a do while loop to account for the changes in #7873. Fixes #9446 * UI: Display Firewall, LB and Port Forwading rules tab for CKS clusters deployed on isolated networks (#9458) --------- Co-authored-by: nvazquez Co-authored-by: Fabricio Duarte Co-authored-by: João Jandre <48719461+JoaoJandre@users.noreply.github.com> Co-authored-by: Pearl Dsilva --- .github/workflows/ci.yml | 1 + .../snapshot/DefaultSnapshotStrategy.java | 7 +- .../java/com/cloud/acl/DomainChecker.java | 70 ++++-- .../com/cloud/network/NetworkServiceImpl.java | 209 ++++++++---------- .../com/cloud/user/AccountManagerImpl.java | 18 +- .../java/com/cloud/acl/DomainCheckerTest.java | 166 ++++++++++++++ .../cloud/user/AccountManagerImplTest.java | 58 +++++ test/integration/smoke/test_account_access.py | 198 +++++++++++++++++ ui/src/views/compute/KubernetesServiceTab.vue | 1 + 9 files changed, 590 insertions(+), 138 deletions(-) create mode 100644 server/src/test/java/com/cloud/acl/DomainCheckerTest.java create mode 100644 test/integration/smoke/test_account_access.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42407a48b9b..d369916f712 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,7 @@ jobs: fail-fast: false matrix: tests: [ "smoke/test_accounts + smoke/test_account_access smoke/test_affinity_groups smoke/test_affinity_groups_projects smoke/test_annotations diff --git a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java index f1f073db170..333272113bd 100644 --- a/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java +++ b/engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/snapshot/DefaultSnapshotStrategy.java @@ -102,6 +102,8 @@ public class DefaultSnapshotStrategy extends SnapshotStrategyBase { @Inject SnapshotZoneDao snapshotZoneDao; + private final List snapshotStatesAbleToDeleteSnapshot = Arrays.asList(Snapshot.State.Destroying, Snapshot.State.Destroyed, Snapshot.State.Error); + public SnapshotDataStoreVO getSnapshotImageStoreRef(long snapshotId, long zoneId) { List snaps = snapshotStoreDao.listReadyBySnapshot(snapshotId, DataStoreRole.Image); for (SnapshotDataStoreVO ref : snaps) { @@ -199,9 +201,8 @@ public class DefaultSnapshotStrategy extends SnapshotStrategyBase { boolean result = false; boolean resultIsSet = false; - final List snapshotStatesAbleToDeleteSnapshot = Arrays.asList(Snapshot.State.BackedUp, Snapshot.State.Destroying, Snapshot.State.Destroyed, Snapshot.State.Error); try { - while (snapshot != null && snapshotStatesAbleToDeleteSnapshot.contains(snapshot.getState())) { + do { SnapshotInfo child = snapshot.getChild(); if (child != null) { @@ -247,7 +248,7 @@ public class DefaultSnapshotStrategy extends SnapshotStrategyBase { } snapshot = parent; - } + } while (snapshot != null && snapshotStatesAbleToDeleteSnapshot.contains(snapshot.getState())); } catch (Exception e) { s_logger.error(String.format("Failed to delete snapshot [%s] on storage [%s] due to [%s].", snapshotTo, storageToString, e.getMessage()), e); } diff --git a/server/src/main/java/com/cloud/acl/DomainChecker.java b/server/src/main/java/com/cloud/acl/DomainChecker.java index a8c9ab84f7e..7930be49ec1 100644 --- a/server/src/main/java/com/cloud/acl/DomainChecker.java +++ b/server/src/main/java/com/cloud/acl/DomainChecker.java @@ -208,7 +208,7 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { return true; } else if (entity instanceof Network && accessType != null && accessType == AccessType.UseEntry) { - _networkMgr.checkNetworkPermissions(caller, (Network)entity); + _networkMgr.checkNetworkPermissions(caller, (Network) entity); } else if (entity instanceof Network && accessType != null && accessType == AccessType.OperateEntry) { _networkMgr.checkNetworkOperatePermissions(caller, (Network)entity); } else if (entity instanceof VirtualRouter) { @@ -216,30 +216,58 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { } else if (entity instanceof AffinityGroup) { return false; } else { - if (_accountService.isNormalUser(caller.getId())) { - Account account = _accountDao.findById(entity.getAccountId()); - String errorMessage = String.format("%s does not have permission to operate with resource", caller); - if (account != null && account.getType() == Account.Type.PROJECT) { - //only project owner can delete/modify the project - if (accessType != null && accessType == AccessType.ModifyProject) { - if (!_projectMgr.canModifyProjectAccount(caller, account.getId())) { - throw new PermissionDeniedException(errorMessage); - } - } else if (!_projectMgr.canAccessProjectAccount(caller, account.getId())) { - throw new PermissionDeniedException(errorMessage); - } - checkOperationPermitted(caller, entity); - } else { - if (caller.getId() != entity.getAccountId()) { - throw new PermissionDeniedException(errorMessage); - } - } - } + validateCallerHasAccessToEntityOwner(caller, entity, accessType); } return true; } - private boolean checkOperationPermitted(Account caller, ControlledEntity entity) { + protected void validateCallerHasAccessToEntityOwner(Account caller, ControlledEntity entity, AccessType accessType) { + PermissionDeniedException exception = new PermissionDeniedException("Caller does not have permission to operate with provided resource."); + String entityLog = String.format("entity [owner ID: %d, type: %s]", entity.getAccountId(), + entity.getEntityType().getSimpleName()); + + if (_accountService.isRootAdmin(caller.getId())) { + return; + } + + if (caller.getId() == entity.getAccountId()) { + return; + } + + Account owner = _accountDao.findById(entity.getAccountId()); + if (owner == null) { + s_logger.error(String.format("Owner not found for %s", entityLog)); + throw exception; + } + + Account.Type callerAccountType = caller.getType(); + if ((callerAccountType == Account.Type.DOMAIN_ADMIN || callerAccountType == Account.Type.RESOURCE_DOMAIN_ADMIN) && + _domainDao.isChildDomain(caller.getDomainId(), owner.getDomainId())) { + return; + } + + if (owner.getType() == Account.Type.PROJECT) { + // only project owner can delete/modify the project + if (accessType == AccessType.ModifyProject) { + if (!_projectMgr.canModifyProjectAccount(caller, owner.getId())) { + s_logger.error(String.format("Caller ID: %d does not have permission to modify project with " + + "owner ID: %d", caller.getId(), owner.getId())); + throw exception; + } + } else if (!_projectMgr.canAccessProjectAccount(caller, owner.getId())) { + s_logger.error(String.format("Caller ID: %d does not have permission to access project with " + + "owner ID: %d", caller.getId(), owner.getId())); + throw exception; + } + checkOperationPermitted(caller, entity); + return; + } + + s_logger.error(String.format("Caller ID: %d does not have permission to access %s", caller.getId(), entityLog)); + throw exception; + } + + protected boolean checkOperationPermitted(Account caller, ControlledEntity entity) { User user = CallContext.current().getCallingUser(); Project project = projectDao.findByProjectAccountId(entity.getAccountId()); if (project == null) { diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 83ef8b1b213..c58463ac708 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -36,6 +36,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -2196,9 +2197,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C Long associatedNetworkId = cmd.getAssociatedNetworkId(); String networkFilterStr = cmd.getNetworkFilter(); - boolean applyManualPagination = CollectionUtils.isNotEmpty(supportedServicesStr) || - Boolean.TRUE.equals(canUseForDeploy); - String vlanId = null; if (cmd instanceof ListNetworksCmdByAdmin) { vlanId = ((ListNetworksCmdByAdmin)cmd).getVlan(); @@ -2284,13 +2282,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C isRecursive = true; } - Long offset = cmd.getStartIndex(); - Long limit = cmd.getPageSizeVal(); - if (applyManualPagination) { - offset = null; - limit = null; - } - Filter searchFilter = new Filter(NetworkVO.class, "id", false, offset, limit); + Filter searchFilter = new Filter(NetworkVO.class, "id", false, null, null); SearchBuilder sb = _networksDao.createSearchBuilder(); if (forVpc != null) { @@ -2345,123 +2337,113 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C sb.join("associatedNetworkSearch", associatedNetworkSearch, sb.entity().getId(), associatedNetworkSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); } - SearchCriteria mainSearchCriteria = createNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, - guestIpType, trafficType, physicalNetworkId, networkOfferingId, aclType, restartRequired, - specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId); - SearchCriteria additionalSearchCriteria = _networksDao.createSearchCriteria(); + List networksToReturn = new ArrayList(); if (isSystem == null || !isSystem) { if (!permittedAccounts.isEmpty()) { if (Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //get account level networks - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, - getAccountSpecificNetworksSearchCriteria(sb, permittedAccounts, skipProjectNetworks)); + networksToReturn.addAll(listAccountSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, permittedAccounts)); } if (domainId != null && Arrays.asList(Network.NetworkFilter.Domain, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //get domain level networks - SearchCriteria domainLevelSC = getDomainLevelNetworksSearchCriteria(sb, domainId, false); - if (domainLevelSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, domainLevelSC); - } + networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, domainId, false)); } if (Arrays.asList(Network.NetworkFilter.Shared, Network.NetworkFilter.All).contains(networkFilter)) { // get shared networks - SearchCriteria sharedNetworksSC = getSharedNetworksSearchCriteria(sb, permittedAccounts); - if (sharedNetworksSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, sharedNetworksSC); - } + List sharedNetworks = listSharedNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, permittedAccounts); + addNetworksToReturnIfNotExist(networksToReturn, sharedNetworks); + } } else { if (Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //add account specific networks - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, - getAccountSpecificNetworksByDomainPathSearchCriteria(sb, path, isRecursive, - skipProjectNetworks)); + networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive)); } if (Arrays.asList(Network.NetworkFilter.Domain, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //add domain specific networks of domain + parent domains - SearchCriteria domainSpecificNetworksByDomainPathSC = - getDomainSpecificNetworksByDomainPathSearchCriteria(sb, path, isRecursive); - if (domainSpecificNetworksByDomainPathSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, domainSpecificNetworksByDomainPathSC); - } + networksToReturn.addAll(listDomainSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive)); //add networks of subdomains if (domainId == null) { - SearchCriteria domainLevelSC = getDomainLevelNetworksSearchCriteria(sb, caller.getDomainId(), true); - if (domainLevelSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, domainLevelSC); - } + networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, caller.getDomainId(), true)); } } if (Arrays.asList(Network.NetworkFilter.Shared, Network.NetworkFilter.All).contains(networkFilter)) { // get shared networks - SearchCriteria sharedNetworksSC = getSharedNetworksByDomainPathSearchCriteria(sb, path, isRecursive); - if (sharedNetworksSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, sharedNetworksSC); - } + List sharedNetworks = listSharedNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive); + addNetworksToReturnIfNotExist(networksToReturn, sharedNetworks); } } - if (CollectionUtils.isNotEmpty(additionalSearchCriteria.getValues())) { - mainSearchCriteria.addAnd("id", SearchCriteria.Op.SC, additionalSearchCriteria); - } } else { - if (skipProjectNetworks) { - mainSearchCriteria.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); - } else { - mainSearchCriteria.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); - } + networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + null, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter); } - Pair, Integer> result = _networksDao.searchAndCount(mainSearchCriteria, searchFilter); - List networksToReturn = result.first(); if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) { - List supportedNetworks = new ArrayList<>(); - Service[] supportedServices = new Service[supportedServicesStr.size()]; + List supportedNetworks = new ArrayList(); + Service[] suppportedServices = new Service[supportedServicesStr.size()]; int i = 0; for (String supportedServiceStr : supportedServicesStr) { Service service = Service.getService(supportedServiceStr); if (service == null) { throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr); } else { - supportedServices[i] = service; + suppportedServices[i] = service; } i++; } + for (NetworkVO network : networksToReturn) { - if (areServicesSupportedInNetwork(network.getId(), supportedServices)) { + if (areServicesSupportedInNetwork(network.getId(), suppportedServices)) { supportedNetworks.add(network); } } + networksToReturn = supportedNetworks; } if (canUseForDeploy != null) { - List networksForDeploy = new ArrayList<>(); + List networksForDeploy = new ArrayList(); for (NetworkVO network : networksToReturn) { if (_networkModel.canUseForDeploy(network) == canUseForDeploy) { networksForDeploy.add(network); } } + networksToReturn = networksForDeploy; } - if (applyManualPagination) { - //Now apply pagination - List wPagination = com.cloud.utils.StringUtils.applyPagination(networksToReturn, cmd.getStartIndex(), cmd.getPageSizeVal()); - if (wPagination != null) { - Pair, Integer> listWPagination = new Pair<>(wPagination, networksToReturn.size()); - return listWPagination; - } - return new Pair<>(networksToReturn, networksToReturn.size()); + //Now apply pagination + List wPagination = com.cloud.utils.StringUtils.applyPagination(networksToReturn, cmd.getStartIndex(), cmd.getPageSizeVal()); + if (wPagination != null) { + Pair, Integer> listWPagination = new Pair, Integer>(wPagination, networksToReturn.size()); + return listWPagination; } - return new Pair<>(result.first(), result.second()); + return new Pair, Integer>(networksToReturn, networksToReturn.size()); } - private SearchCriteria createNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, - Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - Long networkOfferingId, String aclType, Boolean restartRequired, - Boolean specifyIpRanges, Long vpcId, Map tags, Boolean display, String vlanId, Long associatedNetworkId) { + private void addNetworksToReturnIfNotExist(final List networksToReturn, final List sharedNetworks) { + Set networkIds = networksToReturn.stream() + .map(NetworkVO::getId) + .collect(Collectors.toSet()); + List sharedNetworksToReturn = sharedNetworks.stream() + .filter(network -> ! networkIds.contains(network.getId())) + .collect(Collectors.toList()); + networksToReturn.addAll(sharedNetworksToReturn); + } + + private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, + Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, + Long networkOfferingId, String aclType, boolean skipProjectNetworks, Boolean restartRequired, + Boolean specifyIpRanges, Long vpcId, Map tags, Boolean display, String vlanId, Long associatedNetworkId) { SearchCriteria sc = sb.create(); @@ -2503,6 +2485,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C sc.addAnd("physicalNetworkId", SearchCriteria.Op.EQ, physicalNetworkId); } + if (skipProjectNetworks) { + sc.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + } else { + sc.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); + } + if (restartRequired != null) { sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired); } @@ -2543,8 +2531,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C return sc; } - private SearchCriteria getDomainLevelNetworksSearchCriteria(SearchBuilder sb, long domainId, boolean parentDomainsOnly) { - List networkIds = new ArrayList<>(); + private List listDomainLevelNetworks(SearchCriteria sc, Filter searchFilter, long domainId, boolean parentDomainsOnly) { + List networkIds = new ArrayList(); Set allowedDomains = _domainMgr.getDomainParentIds(domainId); List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); @@ -2559,55 +2547,48 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } if (!networkIds.isEmpty()) { - SearchCriteria domainSC = sb.create(); - domainSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria domainSC = _networksDao.createSearchCriteria(); domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray()); domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString()); - return domainSC; + + sc.addAnd("id", SearchCriteria.Op.SC, domainSC); + return _networksDao.search(sc, searchFilter); + } else { + return new ArrayList(); } - return null; } - private SearchCriteria getAccountSpecificNetworksSearchCriteria(SearchBuilder sb, - List permittedAccounts, boolean skipProjectNetworks) { - SearchCriteria accountSC = sb.create(); - if (skipProjectNetworks) { - accountSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); - } else { - accountSC.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); - } + private List listAccountSpecificNetworks(SearchCriteria sc, Filter searchFilter, List permittedAccounts) { + SearchCriteria accountSC = _networksDao.createSearchCriteria(); if (!permittedAccounts.isEmpty()) { accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray()); } + accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString()); - return accountSC; + + sc.addAnd("id", SearchCriteria.Op.SC, accountSC); + return _networksDao.search(sc, searchFilter); } - private SearchCriteria getAccountSpecificNetworksByDomainPathSearchCriteria(SearchBuilder sb, - String path, boolean isRecursive, boolean skipProjectNetworks) { - SearchCriteria accountSC = sb.create(); - if (skipProjectNetworks) { - accountSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); - } else { - accountSC.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); - } + private List listAccountSpecificNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { + SearchCriteria accountSC = _networksDao.createSearchCriteria(); accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString()); if (path != null) { if (isRecursive) { - accountSC.setJoinParameters("domainSearch", "path", path + "%"); + sc.setJoinParameters("domainSearch", "path", path + "%"); } else { - accountSC.setJoinParameters("domainSearch", "path", path); + sc.setJoinParameters("domainSearch", "path", path); } } - return accountSC; + sc.addAnd("id", SearchCriteria.Op.SC, accountSC); + return _networksDao.search(sc, searchFilter); } - private SearchCriteria getDomainSpecificNetworksByDomainPathSearchCriteria(SearchBuilder sb, - String path, boolean isRecursive) { + private List listDomainSpecificNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { - Set allowedDomains = new HashSet<>(); + Set allowedDomains = new HashSet(); if (path != null) { if (isRecursive) { allowedDomains = _domainMgr.getDomainChildrenIds(path); @@ -2617,7 +2598,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } } - List networkIds = new ArrayList<>(); + List networkIds = new ArrayList(); List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); @@ -2626,28 +2607,30 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } if (!networkIds.isEmpty()) { - SearchCriteria domainSC = sb.create(); - domainSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria domainSC = _networksDao.createSearchCriteria(); domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray()); domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString()); - return domainSC; + + sc.addAnd("id", SearchCriteria.Op.SC, domainSC); + return _networksDao.search(sc, searchFilter); + } else { + return new ArrayList(); } - return null; } - private SearchCriteria getSharedNetworksSearchCriteria(SearchBuilder sb, List permittedAccounts) { + private List listSharedNetworks(SearchCriteria sc, Filter searchFilter, List permittedAccounts) { List sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(permittedAccounts); if (!sharedNetworkIds.isEmpty()) { - SearchCriteria ssc = sb.create(); - ssc.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria ssc = _networksDao.createSearchCriteria(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - return ssc; + sc.addAnd("id", SearchCriteria.Op.SC, ssc); + return _networksDao.search(sc, searchFilter); } - return null; + return new ArrayList(); } - private SearchCriteria getSharedNetworksByDomainPathSearchCriteria(SearchBuilder sb, String path, boolean isRecursive) { - Set allowedDomains = new HashSet<>(); + private List listSharedNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { + Set allowedDomains = new HashSet(); if (path != null) { if (isRecursive) { allowedDomains = _domainMgr.getDomainChildrenIds(path); @@ -2669,13 +2652,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C List sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(allowedAccountsList); if (!sharedNetworkIds.isEmpty()) { - SearchCriteria ssc = sb.create(); - ssc.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria ssc = _networksDao.createSearchCriteria(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - return ssc; + sc.addAnd("id", SearchCriteria.Op.SC, ssc); + return _networksDao.search(sc, searchFilter); } } - return null; + return new ArrayList(); } @Override diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index 3eed429ed21..0a0d9265ac4 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -2744,7 +2744,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new InvalidParameterValueException("Unable to find user by id"); } final ControlledEntity account = getAccount(getUserAccountById(userId).getAccountId()); //Extracting the Account from the userID of the requested user. - checkAccess(CallContext.current().getCallingUser(), account); + User caller = CallContext.current().getCallingUser(); + preventRootDomainAdminAccessToRootAdminKeys(caller, account); + checkAccess(caller, account); Map keys = new HashMap(); keys.put("apikey", user.getApiKey()); @@ -2753,6 +2755,19 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M return keys; } + protected void preventRootDomainAdminAccessToRootAdminKeys(User caller, ControlledEntity account) { + if (isDomainAdminForRootDomain(caller) && isRootAdmin(account.getAccountId())) { + String msg = String.format("Caller Username %s does not have access to root admin keys", caller.getUsername()); + s_logger.error(msg); + throw new PermissionDeniedException(msg); + } + } + + protected boolean isDomainAdminForRootDomain(User callingUser) { + AccountVO caller = _accountDao.findById(callingUser.getAccountId()); + return caller.getType() == Account.Type.DOMAIN_ADMIN && caller.getDomainId() == Domain.ROOT_DOMAIN; + } + @Override public List listUserTwoFactorAuthenticationProviders() { return userTwoFactorAuthenticationProviders; @@ -2787,6 +2802,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } Account account = _accountDao.findById(user.getAccountId()); + preventRootDomainAdminAccessToRootAdminKeys(user, account); checkAccess(caller, null, true, account); // don't allow updating system user diff --git a/server/src/test/java/com/cloud/acl/DomainCheckerTest.java b/server/src/test/java/com/cloud/acl/DomainCheckerTest.java new file mode 100644 index 00000000000..a5ec41306d8 --- /dev/null +++ b/server/src/test/java/com/cloud/acl/DomainCheckerTest.java @@ -0,0 +1,166 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. +package com.cloud.acl; + +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.SecurityChecker; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.projects.ProjectManager; +import com.cloud.user.Account; +import com.cloud.user.AccountService; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.Ternary; + +@RunWith(MockitoJUnitRunner.class) +public class DomainCheckerTest { + + @Mock + AccountService _accountService; + @Mock + AccountDao _accountDao; + @Mock + DomainDao _domainDao; + @Mock + ProjectManager _projectMgr; + + @Spy + @InjectMocks + DomainChecker domainChecker; + + private ControlledEntity getMockedEntity(long accountId) { + ControlledEntity entity = Mockito.mock(Account.class); + Mockito.when(entity.getAccountId()).thenReturn(accountId); + Mockito.when(entity.getEntityType()).thenReturn((Class)Account.class); + return entity; + } + + @Test + public void testRootAdminHasAccess() { + Account rootAdmin = Mockito.mock(Account.class); + Mockito.when(rootAdmin.getId()).thenReturn(1L); + ControlledEntity entity = getMockedEntity(2L); + Mockito.when(_accountService.isRootAdmin(rootAdmin.getId())).thenReturn(true); + + domainChecker.validateCallerHasAccessToEntityOwner(rootAdmin, entity, SecurityChecker.AccessType.ModifyProject); + } + + @Test + public void testCallerIsOwner() { + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getId()).thenReturn(1L); + ControlledEntity entity = getMockedEntity(1L); + + domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ModifyProject); + } + + @Test(expected = PermissionDeniedException.class) + public void testOwnerNotFound() { + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getId()).thenReturn(1L); + ControlledEntity entity = getMockedEntity(2L); + Mockito.when(_accountDao.findById(entity.getAccountId())).thenReturn(null); + + domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ModifyProject); + } + + @Test + public void testDomainAdminHasAccess() { + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getId()).thenReturn(1L); + Mockito.when(caller.getDomainId()).thenReturn(100L); + Mockito.when(caller.getType()).thenReturn(Account.Type.DOMAIN_ADMIN); + ControlledEntity entity = getMockedEntity(2L); + AccountVO owner = Mockito.mock(AccountVO.class); + Mockito.when(owner.getDomainId()).thenReturn(101L); + Mockito.when(_accountDao.findById(entity.getAccountId())).thenReturn(owner); + Mockito.when(_domainDao.isChildDomain(100L, 101L)).thenReturn(true); + + domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ModifyProject); + } + + private Ternary getProjectAccessCheckResources() { + Account caller = Mockito.mock(Account.class); + Mockito.when(caller.getId()).thenReturn(100L); + Mockito.when(caller.getType()).thenReturn(Account.Type.PROJECT); + ControlledEntity entity = getMockedEntity(2L); + AccountVO projectAccount = Mockito.mock(AccountVO.class); + Mockito.when(projectAccount.getId()).thenReturn(2L); + Mockito.when(projectAccount.getType()).thenReturn(Account.Type.PROJECT); + return new Ternary<>(caller, entity, projectAccount); + } + + @Test + public void testProjectOwnerCanModify() { + Ternary resources = getProjectAccessCheckResources(); + Account caller = resources.first(); + ControlledEntity entity = resources.second(); + AccountVO projectAccount = resources.third(); + Mockito.when(_accountDao.findById(entity.getAccountId())).thenReturn(projectAccount); + Mockito.when(_projectMgr.canModifyProjectAccount(caller, projectAccount.getId())).thenReturn(true); + Mockito.doReturn(true).when(domainChecker).checkOperationPermitted(caller, entity); + + domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ModifyProject); + } + + @Test(expected = PermissionDeniedException.class) + public void testProjectOwnerCannotModify() { + Ternary resources = getProjectAccessCheckResources(); + Account caller = resources.first(); + ControlledEntity entity = resources.second(); + AccountVO projectAccount = resources.third(); + Mockito.when(_accountDao.findById(entity.getAccountId())).thenReturn(projectAccount); + Mockito.when(_projectMgr.canModifyProjectAccount(caller, projectAccount.getId())).thenReturn(false); + + domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ModifyProject); + } + + @Test + public void testProjectOwnerCanAccess() { + Ternary resources = getProjectAccessCheckResources(); + Account caller = resources.first(); + ControlledEntity entity = resources.second(); + AccountVO projectAccount = resources.third(); + Mockito.when(_accountDao.findById(entity.getAccountId())).thenReturn(projectAccount); + Mockito.when(_projectMgr.canAccessProjectAccount(caller, projectAccount.getId())).thenReturn(true); + Mockito.doReturn(true).when(domainChecker).checkOperationPermitted(caller, entity); + + domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ListEntry); + } + + @Test(expected = PermissionDeniedException.class) + public void testProjectOwnerCannotAccess() { + Ternary resources = getProjectAccessCheckResources(); + Account caller = resources.first(); + ControlledEntity entity = resources.second(); + AccountVO projectAccount = resources.third(); + Mockito.when(_accountDao.findById(entity.getAccountId())).thenReturn(projectAccount); + Mockito.when(_projectMgr.canAccessProjectAccount(caller, projectAccount.getId())).thenReturn(false); + + domainChecker.validateCallerHasAccessToEntityOwner(caller, entity, SecurityChecker.AccessType.ListEntry); + } + +} diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java index 9014af523fd..36fb1ca518a 100644 --- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java +++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java @@ -33,6 +33,7 @@ import com.cloud.vm.UserVmManagerImpl; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.snapshot.VMSnapshotVO; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; @@ -241,6 +242,63 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase { accountManagerImpl.getKeys(_listkeyscmd); } + @Test(expected = PermissionDeniedException.class) + public void testGetUserKeysCmdDomainAdminRootAdminUser() { + CallContext.register(callingUser, callingAccount); + Mockito.when(_listkeyscmd.getID()).thenReturn(2L); + Mockito.when(accountManagerImpl.getActiveUser(2L)).thenReturn(userVoMock); + Mockito.when(userAccountDaoMock.findById(2L)).thenReturn(userAccountVO); + Mockito.when(userAccountVO.getAccountId()).thenReturn(2L); + Mockito.when(userDetailsDaoMock.listDetailsKeyPairs(Mockito.anyLong())).thenReturn(null); + + // Queried account - admin account + AccountVO adminAccountMock = Mockito.mock(AccountVO.class); + Mockito.when(adminAccountMock.getAccountId()).thenReturn(2L); + Mockito.when(_accountDao.findByIdIncludingRemoved(2L)).thenReturn(adminAccountMock); + Mockito.lenient().when(accountService.isRootAdmin(2L)).thenReturn(true); + Mockito.lenient().when(securityChecker.checkAccess(Mockito.any(Account.class), + Mockito.nullable(ControlledEntity.class), Mockito.nullable(AccessType.class), Mockito.anyString())).thenReturn(true); + + // Calling account is domain admin of the ROOT domain + Mockito.lenient().when(callingAccount.getType()).thenReturn(Account.Type.DOMAIN_ADMIN); + Mockito.lenient().when(callingAccount.getDomainId()).thenReturn(Domain.ROOT_DOMAIN); + + Mockito.lenient().when(callingUser.getAccountId()).thenReturn(2L); + Mockito.lenient().when(_accountDao.findById(2L)).thenReturn(callingAccount); + + Mockito.lenient().when(accountService.isDomainAdmin(Mockito.anyLong())).thenReturn(Boolean.TRUE); + Mockito.lenient().when(accountMock.getAccountId()).thenReturn(2L); + + accountManagerImpl.getKeys(_listkeyscmd); + } + + @Test + public void testPreventRootDomainAdminAccessToRootAdminKeysNormalUser() { + User user = Mockito.mock(User.class); + ControlledEntity entity = Mockito.mock(ControlledEntity.class); + Mockito.when(user.getAccountId()).thenReturn(1L); + AccountVO account = Mockito.mock(AccountVO.class); + Mockito.when(account.getType()).thenReturn(Account.Type.NORMAL); + Mockito.when(_accountDao.findById(1L)).thenReturn(account); + accountManagerImpl.preventRootDomainAdminAccessToRootAdminKeys(user, entity); + Mockito.verify(accountManagerImpl, Mockito.never()).isRootAdmin(Mockito.anyLong()); + } + + @Test(expected = PermissionDeniedException.class) + public void testPreventRootDomainAdminAccessToRootAdminKeysRootDomainAdminUser() { + User user = Mockito.mock(User.class); + ControlledEntity entity = Mockito.mock(ControlledEntity.class); + Mockito.when(user.getAccountId()).thenReturn(1L); + AccountVO account = Mockito.mock(AccountVO.class); + Mockito.when(account.getType()).thenReturn(Account.Type.DOMAIN_ADMIN); + Mockito.when(account.getDomainId()).thenReturn(Domain.ROOT_DOMAIN); + Mockito.when(_accountDao.findById(1L)).thenReturn(account); + Mockito.when(entity.getAccountId()).thenReturn(1L); + Mockito.lenient().when(securityChecker.checkAccess(Mockito.any(Account.class), + Mockito.nullable(ControlledEntity.class), Mockito.nullable(AccessType.class), Mockito.anyString())).thenReturn(true); + accountManagerImpl.preventRootDomainAdminAccessToRootAdminKeys(user, entity); + } + @Test public void updateUserTestTimeZoneAndEmailNull() { prepareMockAndExecuteUpdateUserTest(0); diff --git a/test/integration/smoke/test_account_access.py b/test/integration/smoke/test_account_access.py new file mode 100644 index 00000000000..97eeced6386 --- /dev/null +++ b/test/integration/smoke/test_account_access.py @@ -0,0 +1,198 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +""" BVT tests for Account User Access +""" +# Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import * +from marvin.lib.base import (Account, + User, + Domain) +from marvin.lib.common import (get_domain) +from marvin.cloudstackAPI import (getUserKeys) +from marvin.cloudstackException import CloudstackAPIException +from nose.plugins.attrib import attr + +_multiprocess_shared_ = True + +class TestAccountAccess(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + testClient = super(TestAccountAccess, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + cls.hypervisor = testClient.getHypervisorInfo() + cls._cleanup = [] + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.apiclient) + + cls.domains = [] + cls.domain_admins = {} + cls.domain_users = {} + cls.account_users = {} + + domain_data = { + "name": "domain_1" + } + cls.domain_1 = Domain.create( + cls.apiclient, + domain_data, + ) + cls._cleanup.append(cls.domain_1) + cls.domains.append(cls.domain_1) + domain_data["name"] = "domain_11" + cls.domain_11 = Domain.create( + cls.apiclient, + domain_data, + parentdomainid=cls.domain_1.id + ) + cls._cleanup.append(cls.domain_11) + cls.domains.append(cls.domain_11) + domain_data["name"] = "domain_12" + cls.domain_12 = Domain.create( + cls.apiclient, + domain_data, + parentdomainid=cls.domain_1.id + ) + cls._cleanup.append(cls.domain_12) + cls.domains.append(cls.domain_12) + domain_data["name"] = "domain_2" + cls.domain_2 = Domain.create( + cls.apiclient, + domain_data, + ) + cls._cleanup.append(cls.domain_2) + cls.domains.append(cls.domain_2) + + + for d in cls.domains: + cls.create_domainadmin_and_user(d) + + @classmethod + def tearDownClass(cls): + super(TestAccountAccess, cls).tearDownClass() + + @classmethod + def create_account(cls, domain, is_admin): + cls.debug(f"Creating account for domain {domain.name}, admin: {is_admin}") + data = { + "email": "admin-" + domain.name + "@test.com", + "firstname": "Admin", + "lastname": domain.name, + "username": "admin-" + domain.name, + "password": "password" + } + if is_admin == False: + data["email"] = "user-" + domain.name + "@test.com" + data["firstname"] = "User" + data["username"] = "user-" + domain.name + account = Account.create( + cls.apiclient, + data, + admin=is_admin, + domainid=domain.id + ) + cls._cleanup.append(account) + if is_admin == True: + cls.domain_admins[domain.id] = account + else: + cls.domain_users[domain.id] = account + + user = User.create( + cls.apiclient, + data, + account=account.name, + domainid=account.domainid) + cls._cleanup.append(user) + cls.account_users[account.id] = user + + @classmethod + def create_domainadmin_and_user(cls, domain): + cls.debug(f"Creating accounts for domain #{domain.id} {domain.name}") + cls.create_account(domain, True) + cls.create_account(domain, False) + + def get_user_keys(self, api_client, user_id): + getUserKeysCmd = getUserKeys.getUserKeysCmd() + getUserKeysCmd.id = user_id + return api_client.getUserKeys(getUserKeysCmd) + + def is_child_domain(self, parent_domain, child_domain): + if not parent_domain or not child_domain: + return False + parent_domain_prefix = parent_domain.split('-')[0] + child_domain_prefix = child_domain.split('-')[0] + if not parent_domain_prefix or not child_domain_prefix: + return False + return child_domain_prefix.startswith(parent_domain_prefix) + + + @attr(tags=["advanced", "advancedns", "smoke", "sg"], required_hardware="false") + def test_01_user_access(self): + """ + Test user account is not accessing any other account + """ + + domain_user_accounts = [value for value in self.domain_users.values()] + all_account_users = [value for value in self.account_users.values()] + for user_account in domain_user_accounts: + current_account_user = self.account_users[user_account.id] + self.debug(f"Check for account {user_account.name} with user {current_account_user.username}") + user_api_client = self.testClient.getUserApiClient( + UserName=user_account.name, + DomainName=user_account.domain + ) + for user in all_account_users: + self.debug(f"Checking access for user {user.username} associated with account {user.account}") + try: + self.get_user_keys(user_api_client, user.id) + self.debug(f"API successful") + if user.id != current_account_user.id: + self.fail(f"User account #{user_account.id} was able to access another account #{user.id}") + except CloudstackAPIException as e: + self.debug(f"Exception occurred: {e}") + if user.id == current_account_user.id: + self.fail(f"User account #{user_account.id} not able to access own account") + + @attr(tags=["advanced", "advancedns", "smoke", "sg"], required_hardware="false") + def test_02_domain_admin_access(self): + """ + Test domain admin account is not accessing any other account from unauthorized domain + """ + + domain_admin_accounts = [value for value in self.domain_admins.values()] + all_account_users = [value for value in self.account_users.values()] + for admin_account in domain_admin_accounts: + current_account_user = self.account_users[admin_account.id] + self.debug(f"Check for domain admin {admin_account.name} with user {current_account_user.username}, {current_account_user.domain}") + admin_api_client = self.testClient.getUserApiClient( + UserName=admin_account.name, + DomainName=admin_account.domain + ) + for user in all_account_users: + self.debug(f"Checking access for user {user.username}, {user.domain} associated with account {user.account}") + try: + self.get_user_keys(admin_api_client, user.id) + self.debug(f"API successful") + if self.is_child_domain(current_account_user.domain, user.domain) == False: + self.fail(f"User account #{admin_account.id} was able to access another account #{user.id}") + except CloudstackAPIException as e: + self.debug(f"Exception occurred: {e}") + if self.is_child_domain(current_account_user.domain, user.domain) == True: + self.fail(f"User account #{admin_account.id} not able to access own account") diff --git a/ui/src/views/compute/KubernetesServiceTab.vue b/ui/src/views/compute/KubernetesServiceTab.vue index bdaa2eefde6..9bc80afae08 100644 --- a/ui/src/views/compute/KubernetesServiceTab.vue +++ b/ui/src/views/compute/KubernetesServiceTab.vue @@ -402,6 +402,7 @@ export default { if (this.arrayHasItems(networks)) { this.network = networks[0] } + resolve(this.network) }) this.networkLoading = false }) From 4ea342cad3db3bb6cf4758000c9575d1675105bf Mon Sep 17 00:00:00 2001 From: nvazquez Date: Fri, 2 Aug 2024 17:31:16 -0300 Subject: [PATCH 03/12] Updating pom.xml version numbers for release 4.19.1.1 Signed-off-by: nvazquez --- agent/pom.xml | 2 +- api/pom.xml | 2 +- client/pom.xml | 2 +- core/pom.xml | 2 +- debian/changelog | 6 ++++++ developer/pom.xml | 2 +- engine/api/pom.xml | 2 +- engine/components-api/pom.xml | 2 +- engine/orchestration/pom.xml | 2 +- engine/pom.xml | 2 +- engine/schema/pom.xml | 2 +- engine/service/pom.xml | 2 +- engine/storage/cache/pom.xml | 2 +- engine/storage/configdrive/pom.xml | 2 +- engine/storage/datamotion/pom.xml | 2 +- engine/storage/image/pom.xml | 2 +- engine/storage/integration-test/pom.xml | 2 +- engine/storage/object/pom.xml | 2 +- engine/storage/pom.xml | 2 +- engine/storage/snapshot/pom.xml | 2 +- engine/storage/volume/pom.xml | 2 +- engine/userdata/cloud-init/pom.xml | 2 +- engine/userdata/pom.xml | 2 +- framework/agent-lb/pom.xml | 2 +- framework/ca/pom.xml | 2 +- framework/cluster/pom.xml | 2 +- framework/config/pom.xml | 2 +- framework/db/pom.xml | 2 +- framework/direct-download/pom.xml | 2 +- framework/events/pom.xml | 2 +- framework/ipc/pom.xml | 2 +- framework/jobs/pom.xml | 2 +- framework/managed-context/pom.xml | 2 +- framework/pom.xml | 2 +- framework/quota/pom.xml | 2 +- framework/rest/pom.xml | 2 +- framework/security/pom.xml | 2 +- framework/spring/lifecycle/pom.xml | 2 +- framework/spring/module/pom.xml | 2 +- plugins/acl/dynamic-role-based/pom.xml | 2 +- plugins/acl/project-role-based/pom.xml | 2 +- plugins/acl/static-role-based/pom.xml | 2 +- .../affinity-group-processors/explicit-dedication/pom.xml | 2 +- plugins/affinity-group-processors/host-affinity/pom.xml | 2 +- .../affinity-group-processors/host-anti-affinity/pom.xml | 2 +- .../non-strict-host-affinity/pom.xml | 2 +- .../non-strict-host-anti-affinity/pom.xml | 2 +- plugins/alert-handlers/snmp-alerts/pom.xml | 2 +- plugins/alert-handlers/syslog-alerts/pom.xml | 2 +- plugins/api/discovery/pom.xml | 2 +- plugins/api/rate-limit/pom.xml | 2 +- plugins/api/solidfire-intg-test/pom.xml | 2 +- plugins/api/vmware-sioc/pom.xml | 2 +- plugins/backup/dummy/pom.xml | 2 +- plugins/backup/networker/pom.xml | 2 +- plugins/backup/veeam/pom.xml | 2 +- plugins/ca/root-ca/pom.xml | 2 +- plugins/database/mysql-ha/pom.xml | 2 +- plugins/database/quota/pom.xml | 2 +- plugins/dedicated-resources/pom.xml | 2 +- plugins/deployment-planners/implicit-dedication/pom.xml | 2 +- plugins/deployment-planners/user-concentrated-pod/pom.xml | 2 +- plugins/deployment-planners/user-dispersing/pom.xml | 2 +- plugins/drs/cluster/balanced/pom.xml | 2 +- plugins/drs/cluster/condensed/pom.xml | 2 +- plugins/event-bus/inmemory/pom.xml | 2 +- plugins/event-bus/kafka/pom.xml | 2 +- plugins/event-bus/rabbitmq/pom.xml | 2 +- plugins/ha-planners/skip-heurestics/pom.xml | 2 +- plugins/host-allocators/random/pom.xml | 2 +- plugins/hypervisors/baremetal/pom.xml | 2 +- plugins/hypervisors/hyperv/pom.xml | 2 +- plugins/hypervisors/kvm/pom.xml | 2 +- plugins/hypervisors/ovm/pom.xml | 2 +- plugins/hypervisors/ovm3/pom.xml | 2 +- plugins/hypervisors/simulator/pom.xml | 2 +- plugins/hypervisors/ucs/pom.xml | 2 +- plugins/hypervisors/vmware/pom.xml | 2 +- plugins/hypervisors/xenserver/pom.xml | 2 +- plugins/integrations/cloudian/pom.xml | 2 +- plugins/integrations/kubernetes-service/pom.xml | 2 +- plugins/integrations/prometheus/pom.xml | 2 +- plugins/metrics/pom.xml | 2 +- plugins/network-elements/bigswitch/pom.xml | 2 +- plugins/network-elements/brocade-vcs/pom.xml | 2 +- plugins/network-elements/cisco-vnmc/pom.xml | 2 +- plugins/network-elements/dns-notifier/pom.xml | 2 +- plugins/network-elements/elastic-loadbalancer/pom.xml | 2 +- plugins/network-elements/globodns/pom.xml | 2 +- plugins/network-elements/internal-loadbalancer/pom.xml | 2 +- plugins/network-elements/juniper-contrail/pom.xml | 2 +- plugins/network-elements/netscaler/pom.xml | 2 +- plugins/network-elements/nicira-nvp/pom.xml | 2 +- plugins/network-elements/opendaylight/pom.xml | 2 +- plugins/network-elements/ovs/pom.xml | 2 +- plugins/network-elements/palo-alto/pom.xml | 2 +- plugins/network-elements/stratosphere-ssp/pom.xml | 2 +- plugins/network-elements/tungsten/pom.xml | 2 +- plugins/network-elements/vxlan/pom.xml | 2 +- plugins/outofbandmanagement-drivers/ipmitool/pom.xml | 2 +- .../outofbandmanagement-drivers/nested-cloudstack/pom.xml | 2 +- plugins/outofbandmanagement-drivers/redfish/pom.xml | 2 +- plugins/pom.xml | 2 +- plugins/shutdown/pom.xml | 2 +- plugins/storage-allocators/random/pom.xml | 2 +- plugins/storage/image/default/pom.xml | 2 +- plugins/storage/image/s3/pom.xml | 2 +- plugins/storage/image/sample/pom.xml | 2 +- plugins/storage/image/swift/pom.xml | 2 +- plugins/storage/object/minio/pom.xml | 2 +- plugins/storage/object/simulator/pom.xml | 2 +- plugins/storage/volume/adaptive/pom.xml | 2 +- plugins/storage/volume/cloudbyte/pom.xml | 2 +- plugins/storage/volume/datera/pom.xml | 2 +- plugins/storage/volume/default/pom.xml | 2 +- plugins/storage/volume/flasharray/pom.xml | 2 +- plugins/storage/volume/linstor/pom.xml | 2 +- plugins/storage/volume/nexenta/pom.xml | 2 +- plugins/storage/volume/primera/pom.xml | 2 +- plugins/storage/volume/sample/pom.xml | 2 +- plugins/storage/volume/scaleio/pom.xml | 2 +- plugins/storage/volume/solidfire/pom.xml | 2 +- plugins/storage/volume/storpool/pom.xml | 2 +- plugins/user-authenticators/ldap/pom.xml | 2 +- plugins/user-authenticators/md5/pom.xml | 2 +- plugins/user-authenticators/oauth2/pom.xml | 2 +- plugins/user-authenticators/pbkdf2/pom.xml | 2 +- plugins/user-authenticators/plain-text/pom.xml | 2 +- plugins/user-authenticators/saml2/pom.xml | 2 +- plugins/user-authenticators/sha256salted/pom.xml | 2 +- plugins/user-two-factor-authenticators/static-pin/pom.xml | 2 +- plugins/user-two-factor-authenticators/totp/pom.xml | 2 +- pom.xml | 2 +- quickcloud/pom.xml | 2 +- server/pom.xml | 2 +- services/console-proxy/pom.xml | 2 +- services/console-proxy/rdpconsole/pom.xml | 2 +- services/console-proxy/server/pom.xml | 2 +- services/pom.xml | 2 +- services/secondary-storage/controller/pom.xml | 2 +- services/secondary-storage/pom.xml | 2 +- services/secondary-storage/server/pom.xml | 2 +- systemvm/pom.xml | 2 +- test/pom.xml | 2 +- tools/apidoc/pom.xml | 2 +- tools/checkstyle/pom.xml | 2 +- tools/devcloud-kvm/pom.xml | 2 +- tools/devcloud4/pom.xml | 2 +- tools/marvin/pom.xml | 2 +- tools/pom.xml | 2 +- usage/pom.xml | 2 +- utils/pom.xml | 2 +- vmware-base/pom.xml | 2 +- 153 files changed, 158 insertions(+), 152 deletions(-) diff --git a/agent/pom.xml b/agent/pom.xml index ec478bad269..25c032abf14 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/api/pom.xml b/api/pom.xml index 13c0d269dc0..cdb4e802c2b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/client/pom.xml b/client/pom.xml index 59c419f93b7..b50a5197bd9 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/core/pom.xml b/core/pom.xml index 06b33a55ae4..31200bcadcd 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/debian/changelog b/debian/changelog index b04c2cb351b..d6ac588cba6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cloudstack (4.19.1.1) unstable; urgency=low + + * Update the version to 4.19.1.1 + + -- the Apache CloudStack project Fri, 02 Aug 2024 17:31:16 -0300 + cloudstack (4.19.1.0) unstable; urgency=low * Update the version to 4.19.1.0 diff --git a/developer/pom.xml b/developer/pom.xml index 687d11e093c..6cb64ff1fea 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/engine/api/pom.xml b/engine/api/pom.xml index 2e3893d8578..4ebed0e00be 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml index e4427ef0cca..de5afd58ff0 100644 --- a/engine/components-api/pom.xml +++ b/engine/components-api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml index e1d6056c1bb..f0ab03017d3 100755 --- a/engine/orchestration/pom.xml +++ b/engine/orchestration/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/engine/pom.xml b/engine/pom.xml index dc738bd0074..eeb19798ec1 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml index 46cdc12a017..4d144ae8d91 100644 --- a/engine/schema/pom.xml +++ b/engine/schema/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/engine/service/pom.xml b/engine/service/pom.xml index fd8f34d9961..acfedb5bd06 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 cloud-engine-service war diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml index c78f09004bd..be1131d3bfe 100644 --- a/engine/storage/cache/pom.xml +++ b/engine/storage/cache/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/storage/configdrive/pom.xml b/engine/storage/configdrive/pom.xml index d7a5a8695c0..1071fe5ea1a 100644 --- a/engine/storage/configdrive/pom.xml +++ b/engine/storage/configdrive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml index 8ae90347b89..cbb9c66f6e8 100644 --- a/engine/storage/datamotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml index f6d97b46fca..ff4afad2295 100644 --- a/engine/storage/image/pom.xml +++ b/engine/storage/image/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 47da53aa050..1e1d5297488 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/storage/object/pom.xml b/engine/storage/object/pom.xml index e76c9c1fbd1..9d4982af506 100644 --- a/engine/storage/object/pom.xml +++ b/engine/storage/object/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index 39a141d057d..c98cfe4d297 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index ce1e14d4a41..d56fc91c85d 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml index fe9699aafa3..25f81e9f926 100644 --- a/engine/storage/volume/pom.xml +++ b/engine/storage/volume/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/userdata/cloud-init/pom.xml b/engine/userdata/cloud-init/pom.xml index ff598bd6555..9c2f92d411a 100644 --- a/engine/userdata/cloud-init/pom.xml +++ b/engine/userdata/cloud-init/pom.xml @@ -23,7 +23,7 @@ cloud-engine org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/engine/userdata/pom.xml b/engine/userdata/pom.xml index 2babb354c14..352a68738b7 100644 --- a/engine/userdata/pom.xml +++ b/engine/userdata/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/agent-lb/pom.xml b/framework/agent-lb/pom.xml index a5d9639d788..a65e24e2280 100644 --- a/framework/agent-lb/pom.xml +++ b/framework/agent-lb/pom.xml @@ -24,7 +24,7 @@ cloudstack-framework org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/ca/pom.xml b/framework/ca/pom.xml index a0458eaa604..e05c55ee65c 100644 --- a/framework/ca/pom.xml +++ b/framework/ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index 20f3069d27d..1dc046cd63f 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/config/pom.xml b/framework/config/pom.xml index 1c90c9fd104..4f30a6ed2ba 100644 --- a/framework/config/pom.xml +++ b/framework/config/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/db/pom.xml b/framework/db/pom.xml index 5199eca03e5..cc6b82787f3 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/direct-download/pom.xml b/framework/direct-download/pom.xml index 51c2ed4dde3..0bdefa91a4d 100644 --- a/framework/direct-download/pom.xml +++ b/framework/direct-download/pom.xml @@ -32,7 +32,7 @@ cloudstack-framework org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/events/pom.xml b/framework/events/pom.xml index def0f189ddd..73219ac1ec2 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index 9e34bf0bc6d..b9010371438 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index c74a0a72394..93690fd1505 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml index 3be67ecf0a1..d40ed883df1 100644 --- a/framework/managed-context/pom.xml +++ b/framework/managed-context/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/framework/pom.xml b/framework/pom.xml index 792872efb46..7b8bf9f72ec 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml index 84e119a4489..d4a325e94bc 100644 --- a/framework/quota/pom.xml +++ b/framework/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml index 1429a46098a..0119e20a2fd 100644 --- a/framework/rest/pom.xml +++ b/framework/rest/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml cloud-framework-rest diff --git a/framework/security/pom.xml b/framework/security/pom.xml index c18bfaeb3b1..80d596d7407 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml index 5b614a87158..673d9318907 100644 --- a/framework/spring/lifecycle/pom.xml +++ b/framework/spring/lifecycle/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index 00e8a29b4dc..2174116feb7 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml index 5f78c31e388..1bad1036409 100644 --- a/plugins/acl/dynamic-role-based/pom.xml +++ b/plugins/acl/dynamic-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/acl/project-role-based/pom.xml b/plugins/acl/project-role-based/pom.xml index 49d2ecd47b5..3313467ac29 100644 --- a/plugins/acl/project-role-based/pom.xml +++ b/plugins/acl/project-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml index fd0727f55ea..93f80b7c6dc 100644 --- a/plugins/acl/static-role-based/pom.xml +++ b/plugins/acl/static-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml index 497a5810baf..aaea68314a1 100644 --- a/plugins/affinity-group-processors/explicit-dedication/pom.xml +++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/affinity-group-processors/host-affinity/pom.xml b/plugins/affinity-group-processors/host-affinity/pom.xml index 25f57d9f424..fd4dc621395 100644 --- a/plugins/affinity-group-processors/host-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml index ab51fd598e5..fe586e3eeff 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml b/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml index 9a9494bdc61..344d57f9a4d 100644 --- a/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml +++ b/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml b/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml index 261cf12fc3f..cd86ae88117 100644 --- a/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml @@ -32,7 +32,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml index e2124a12e9e..b1353e743b6 100644 --- a/plugins/alert-handlers/snmp-alerts/pom.xml +++ b/plugins/alert-handlers/snmp-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml index d0f3ff57a69..0c3976cc811 100644 --- a/plugins/alert-handlers/syslog-alerts/pom.xml +++ b/plugins/alert-handlers/syslog-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml index fdb95168d1b..088acb6523d 100644 --- a/plugins/api/discovery/pom.xml +++ b/plugins/api/discovery/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index 5abe676abf9..4bddd771c0a 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml index 8e088c1b6fa..c7e8cb677f5 100644 --- a/plugins/api/solidfire-intg-test/pom.xml +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/api/vmware-sioc/pom.xml b/plugins/api/vmware-sioc/pom.xml index 4a63912c847..1138903aea5 100644 --- a/plugins/api/vmware-sioc/pom.xml +++ b/plugins/api/vmware-sioc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/backup/dummy/pom.xml b/plugins/backup/dummy/pom.xml index 1315504ee8b..9c0f783f65a 100644 --- a/plugins/backup/dummy/pom.xml +++ b/plugins/backup/dummy/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/backup/networker/pom.xml b/plugins/backup/networker/pom.xml index df947ce6471..43a229a0cc2 100644 --- a/plugins/backup/networker/pom.xml +++ b/plugins/backup/networker/pom.xml @@ -25,7 +25,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/backup/veeam/pom.xml b/plugins/backup/veeam/pom.xml index 20c346fdde1..6e3484e447e 100644 --- a/plugins/backup/veeam/pom.xml +++ b/plugins/backup/veeam/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/ca/root-ca/pom.xml b/plugins/ca/root-ca/pom.xml index 44df2ffa6f0..749da5566ea 100644 --- a/plugins/ca/root-ca/pom.xml +++ b/plugins/ca/root-ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index 3481a9db9d1..875a44fc542 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml index 24b8cd36a58..2f3410af2f7 100644 --- a/plugins/database/quota/pom.xml +++ b/plugins/database/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml index 7d802a9c2d8..4a917c4a7f1 100644 --- a/plugins/dedicated-resources/pom.xml +++ b/plugins/dedicated-resources/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml index c963f014941..cbd530a15da 100644 --- a/plugins/deployment-planners/implicit-dedication/pom.xml +++ b/plugins/deployment-planners/implicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index ef1afbae837..065fe546b06 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index d042b3d39c5..deb6b51231a 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/drs/cluster/balanced/pom.xml b/plugins/drs/cluster/balanced/pom.xml index cbd2c1ac89c..3aa5ed0467f 100644 --- a/plugins/drs/cluster/balanced/pom.xml +++ b/plugins/drs/cluster/balanced/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/drs/cluster/condensed/pom.xml b/plugins/drs/cluster/condensed/pom.xml index dc55dc9ac72..094f75058d7 100644 --- a/plugins/drs/cluster/condensed/pom.xml +++ b/plugins/drs/cluster/condensed/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml index 1cffb07a662..7b107eef601 100644 --- a/plugins/event-bus/inmemory/pom.xml +++ b/plugins/event-bus/inmemory/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml index 9b39552a518..f76693d2702 100644 --- a/plugins/event-bus/kafka/pom.xml +++ b/plugins/event-bus/kafka/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml index 6e9a8fc9da5..e3e2d22f506 100644 --- a/plugins/event-bus/rabbitmq/pom.xml +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml index 9c47f69005f..54f753e19d1 100644 --- a/plugins/ha-planners/skip-heurestics/pom.xml +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index d8a1b0d74a6..71cecd96250 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index b4c769423ba..7e595ee8fbd 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index 0622aa0335a..e458f42002f 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 5089a574cca..8772e2067f7 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index e570e3105d9..071da377e8f 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml index d02126585b5..93bed50f557 100644 --- a/plugins/hypervisors/ovm3/pom.xml +++ b/plugins/hypervisors/ovm3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml index 8e32681db49..fb6d76360c7 100644 --- a/plugins/hypervisors/simulator/pom.xml +++ b/plugins/hypervisors/simulator/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml cloud-plugin-hypervisor-simulator diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index 05fa4cfdf46..715ff0badff 100644 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml cloud-plugin-hypervisor-ucs diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index 3c528d96935..b8889cbffec 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index be15709cb8d..5e200620338 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/integrations/cloudian/pom.xml b/plugins/integrations/cloudian/pom.xml index 088e6ef306f..901acb7abc7 100644 --- a/plugins/integrations/cloudian/pom.xml +++ b/plugins/integrations/cloudian/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/integrations/kubernetes-service/pom.xml b/plugins/integrations/kubernetes-service/pom.xml index faf96bdc240..bc6d3adfdfb 100644 --- a/plugins/integrations/kubernetes-service/pom.xml +++ b/plugins/integrations/kubernetes-service/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/integrations/prometheus/pom.xml b/plugins/integrations/prometheus/pom.xml index e409958190e..f9cad05ac6e 100644 --- a/plugins/integrations/prometheus/pom.xml +++ b/plugins/integrations/prometheus/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml index 52867a0ae80..ac8fbe9e815 100644 --- a/plugins/metrics/pom.xml +++ b/plugins/metrics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml index 2ca87b951d0..88c661a906d 100644 --- a/plugins/network-elements/bigswitch/pom.xml +++ b/plugins/network-elements/bigswitch/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml index 2547b26e633..96193a10575 100644 --- a/plugins/network-elements/brocade-vcs/pom.xml +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml index b5ca98a6438..87b8bb5a581 100644 --- a/plugins/network-elements/cisco-vnmc/pom.xml +++ b/plugins/network-elements/cisco-vnmc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml index bcf08ce151b..0e0f8fe374c 100644 --- a/plugins/network-elements/dns-notifier/pom.xml +++ b/plugins/network-elements/dns-notifier/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml cloud-plugin-example-dns-notifier diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index 7956e428ef9..dec208cb8d8 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index eaeb93fdeb0..2d4e2e766a4 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml index f9952efb3c5..6dafbb44b05 100644 --- a/plugins/network-elements/internal-loadbalancer/pom.xml +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 9efe981137b..7b623f1df82 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index 3329e6e3e68..8e87e3336ea 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 1aac01bbc37..2c6e4e7544f 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index 15e0b73170e..16567f3fb18 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index c2c8862de12..1ba739869e4 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml index 1c5cf968bc1..43cf93ad043 100644 --- a/plugins/network-elements/palo-alto/pom.xml +++ b/plugins/network-elements/palo-alto/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml index b91dfaecbe5..852591c771c 100644 --- a/plugins/network-elements/stratosphere-ssp/pom.xml +++ b/plugins/network-elements/stratosphere-ssp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/tungsten/pom.xml b/plugins/network-elements/tungsten/pom.xml index a1fe498792c..907063ca987 100644 --- a/plugins/network-elements/tungsten/pom.xml +++ b/plugins/network-elements/tungsten/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml index b9319b1daf2..b106aad623e 100644 --- a/plugins/network-elements/vxlan/pom.xml +++ b/plugins/network-elements/vxlan/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml index efc7c0dfd0c..26a191a279e 100644 --- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml +++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml index a81b94ce5b9..d90643d331d 100644 --- a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml +++ b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/redfish/pom.xml b/plugins/outofbandmanagement-drivers/redfish/pom.xml index 8e6ba9ba8b1..d4d1145d24e 100644 --- a/plugins/outofbandmanagement-drivers/redfish/pom.xml +++ b/plugins/outofbandmanagement-drivers/redfish/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/pom.xml b/plugins/pom.xml index 6232e897569..48f79588eb5 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/plugins/shutdown/pom.xml b/plugins/shutdown/pom.xml index 6665707fae1..b7ca2e40bac 100644 --- a/plugins/shutdown/pom.xml +++ b/plugins/shutdown/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index 4af469ad3bb..2b62c6e5d3f 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index 8ce7a58f366..1925c870dfe 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index 9be978209a6..50c42978b1b 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index 7669c371d77..ef728bf7c43 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index 57dff558189..f8124f5ed9d 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/object/minio/pom.xml b/plugins/storage/object/minio/pom.xml index 3b992f151e2..a0c803d2e70 100644 --- a/plugins/storage/object/minio/pom.xml +++ b/plugins/storage/object/minio/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/object/simulator/pom.xml b/plugins/storage/object/simulator/pom.xml index 9a33cb4934d..a8d83ee547e 100644 --- a/plugins/storage/object/simulator/pom.xml +++ b/plugins/storage/object/simulator/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/adaptive/pom.xml b/plugins/storage/volume/adaptive/pom.xml index 5eb500561ab..e170a730c00 100644 --- a/plugins/storage/volume/adaptive/pom.xml +++ b/plugins/storage/volume/adaptive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index cbf8b030fe7..1a2a667e0cf 100644 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/datera/pom.xml b/plugins/storage/volume/datera/pom.xml index e78f959b18c..f8563f9a8ee 100644 --- a/plugins/storage/volume/datera/pom.xml +++ b/plugins/storage/volume/datera/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml index fca704cf7ce..c5a7e5561b1 100644 --- a/plugins/storage/volume/default/pom.xml +++ b/plugins/storage/volume/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/flasharray/pom.xml b/plugins/storage/volume/flasharray/pom.xml index 94de5cb04b9..56f034a954e 100644 --- a/plugins/storage/volume/flasharray/pom.xml +++ b/plugins/storage/volume/flasharray/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/linstor/pom.xml b/plugins/storage/volume/linstor/pom.xml index c96bed7a2e0..7d1c157dc5e 100644 --- a/plugins/storage/volume/linstor/pom.xml +++ b/plugins/storage/volume/linstor/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml index 1d9b68f6abb..5b44b7087e3 100644 --- a/plugins/storage/volume/nexenta/pom.xml +++ b/plugins/storage/volume/nexenta/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/primera/pom.xml b/plugins/storage/volume/primera/pom.xml index e0241905d6d..cb137fd7480 100644 --- a/plugins/storage/volume/primera/pom.xml +++ b/plugins/storage/volume/primera/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml index e9294cc8910..7208076858b 100644 --- a/plugins/storage/volume/sample/pom.xml +++ b/plugins/storage/volume/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/scaleio/pom.xml b/plugins/storage/volume/scaleio/pom.xml index 28151354cb9..96264a2e91f 100644 --- a/plugins/storage/volume/scaleio/pom.xml +++ b/plugins/storage/volume/scaleio/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml index 1dc282a4c47..80f0d3aed3a 100644 --- a/plugins/storage/volume/solidfire/pom.xml +++ b/plugins/storage/volume/solidfire/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/storage/volume/storpool/pom.xml b/plugins/storage/volume/storpool/pom.xml index 339af6f2529..ef2cc3eba70 100644 --- a/plugins/storage/volume/storpool/pom.xml +++ b/plugins/storage/volume/storpool/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../../pom.xml diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index 18dc3df0867..fcffb84c9e7 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index 795959d31b2..69d39f1050a 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-authenticators/oauth2/pom.xml b/plugins/user-authenticators/oauth2/pom.xml index 9971a631fe1..18f594166ed 100644 --- a/plugins/user-authenticators/oauth2/pom.xml +++ b/plugins/user-authenticators/oauth2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml index eae26486f4b..663f7eead60 100644 --- a/plugins/user-authenticators/pbkdf2/pom.xml +++ b/plugins/user-authenticators/pbkdf2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index 2c5b605458b..81a07c47de1 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml index 5e70fc4730c..8742800328a 100644 --- a/plugins/user-authenticators/saml2/pom.xml +++ b/plugins/user-authenticators/saml2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml index 6987f844200..21d11ebb988 100644 --- a/plugins/user-authenticators/sha256salted/pom.xml +++ b/plugins/user-authenticators/sha256salted/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-two-factor-authenticators/static-pin/pom.xml b/plugins/user-two-factor-authenticators/static-pin/pom.xml index e8a69d258a9..f494d3898e3 100644 --- a/plugins/user-two-factor-authenticators/static-pin/pom.xml +++ b/plugins/user-two-factor-authenticators/static-pin/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/plugins/user-two-factor-authenticators/totp/pom.xml b/plugins/user-two-factor-authenticators/totp/pom.xml index 1ceaff1efb6..b9093d6afab 100644 --- a/plugins/user-two-factor-authenticators/totp/pom.xml +++ b/plugins/user-two-factor-authenticators/totp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.0 + 4.19.1.1 ../../pom.xml diff --git a/pom.xml b/pom.xml index e308180ef63..e3228e574a9 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 pom Apache CloudStack Apache CloudStack is an IaaS ("Infrastructure as a Service") cloud orchestration platform. diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml index 1e59f8c6b09..7f81244db09 100644 --- a/quickcloud/pom.xml +++ b/quickcloud/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/server/pom.xml b/server/pom.xml index dc8dcf112d2..09d8ee309c9 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index df449c4a708..02ee2921d2a 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/services/console-proxy/rdpconsole/pom.xml b/services/console-proxy/rdpconsole/pom.xml index a6c1be7e2bb..0d74b451474 100644 --- a/services/console-proxy/rdpconsole/pom.xml +++ b/services/console-proxy/rdpconsole/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index 76a836b2c29..48024431a8d 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/services/pom.xml b/services/pom.xml index 16622d9dec8..24169e8778d 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml index 758d28e2d8f..c0dfb9e79ca 100644 --- a/services/secondary-storage/controller/pom.xml +++ b/services/secondary-storage/controller/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index a7f501efa5f..a5a35c63c88 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml index f9095fd7213..fa6d40782a3 100644 --- a/services/secondary-storage/server/pom.xml +++ b/services/secondary-storage/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/systemvm/pom.xml b/systemvm/pom.xml index e3db354dd79..4d742ad7a00 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/test/pom.xml b/test/pom.xml index 976afc90ebc..7a68fcdcef1 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml index 11af6486f4c..20196a42614 100644 --- a/tools/apidoc/pom.xml +++ b/tools/apidoc/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index 727fbee89bd..fa4122d0391 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -22,7 +22,7 @@ Apache CloudStack Developer Tools - Checkstyle Configuration org.apache.cloudstack checkstyle - 4.19.1.0 + 4.19.1.1 UTF-8 diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml index 42794d03504..1fbb630eff8 100644 --- a/tools/devcloud-kvm/pom.xml +++ b/tools/devcloud-kvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml index 3b0e1e5031f..d6ccfa14245 100644 --- a/tools/devcloud4/pom.xml +++ b/tools/devcloud4/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 2efc4c3f373..94adc211b51 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/tools/pom.xml b/tools/pom.xml index 53ebb83c3d1..67ab345b527 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/usage/pom.xml b/usage/pom.xml index d33d2d7e92a..cca3c59d49f 100644 --- a/usage/pom.xml +++ b/usage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 diff --git a/utils/pom.xml b/utils/pom.xml index 2505fa3593b..8d3b6863c22 100755 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 ../pom.xml diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index f37057d804f..958a461ee40 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.0 + 4.19.1.1 From 8a2f6528f1ebfc3fd4b8fddcf06628f4f5a45126 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 28 Aug 2024 15:22:29 +0200 Subject: [PATCH 04/12] Session Token Invalidation on Logout --- .../main/java/com/cloud/api/ApiServlet.java | 27 ++++++++++--------- ui/src/api/index.js | 1 - ui/src/store/modules/user.js | 11 ++++---- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/server/src/main/java/com/cloud/api/ApiServlet.java b/server/src/main/java/com/cloud/api/ApiServlet.java index f6f46419c04..e719238afef 100644 --- a/server/src/main/java/com/cloud/api/ApiServlet.java +++ b/server/src/main/java/com/cloud/api/ApiServlet.java @@ -260,19 +260,22 @@ public class ApiServlet extends HttpServlet { } if (apiAuthenticator.getAPIType() == APIAuthenticationType.LOGOUT_API) { - if (session != null) { - final Long userId = (Long) session.getAttribute("userid"); - final Account account = (Account) session.getAttribute("accountobj"); - Long accountId = null; - if (account != null) { - accountId = account.getId(); - } - auditTrailSb.insert(0, "(userId=" + userId + " accountId=" + accountId + " sessionId=" + session.getId() + ")"); - if (userId != null) { - apiServer.logoutUser(userId); - } - invalidateHttpSession(session, "invalidating session after logout call"); + if (session == null) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Session not found for the logout process."); } + + final Long userId = (Long) session.getAttribute("userid"); + final Account account = (Account) session.getAttribute("accountobj"); + Long accountId = null; + if (account != null) { + accountId = account.getId(); + } + auditTrailSb.insert(0, "(userId=" + userId + " accountId=" + accountId + " sessionId=" + session.getId() + ")"); + if (userId != null) { + apiServer.logoutUser(userId); + } + invalidateHttpSession(session, "invalidating session after logout call"); + final Cookie[] cookies = req.getCookies(); if (cookies != null) { for (final Cookie cookie : cookies) { diff --git a/ui/src/api/index.js b/ui/src/api/index.js index 1db41661276..14432010738 100644 --- a/ui/src/api/index.js +++ b/ui/src/api/index.js @@ -65,7 +65,6 @@ export function login (arg) { } export function logout () { - sourceToken.cancel() message.destroy() notification.destroy() return api('logout') diff --git a/ui/src/store/modules/user.js b/ui/src/store/modules/user.js index fb5b6ff5e0b..08a0c340c64 100644 --- a/ui/src/store/modules/user.js +++ b/ui/src/store/modules/user.js @@ -24,6 +24,7 @@ import router from '@/router' import store from '@/store' import { oauthlogin, login, logout, api } from '@/api' import { i18n } from '@/locales' +import { sourceToken } from '@/utils/request' import { ACCESS_TOKEN, @@ -374,11 +375,6 @@ const user = { cloudianUrl = state.cloudian.url + 'logout.htm?redirect=' + encodeURIComponent(window.location.href) } - Object.keys(Cookies.get()).forEach(cookieName => { - Cookies.remove(cookieName) - Cookies.remove(cookieName, { path: '/client' }) - }) - commit('SET_TOKEN', '') commit('SET_APIS', {}) commit('SET_PROJECT', {}) @@ -406,6 +402,11 @@ const user = { } }).catch(() => { resolve() + }).finally(() => { + Object.keys(Cookies.get()).forEach(cookieName => { + Cookies.remove(cookieName) + Cookies.remove(cookieName, { path: '/client' }) + }) }) }) }, From 123b426c16cf4fcadc30f55e8b7fd1a5d60bd09b Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 20 Aug 2024 15:12:54 +0200 Subject: [PATCH 05/12] fix quota resource access validation --- .../java/com/cloud/user/AccountService.java | 2 + .../api/command/QuotaBalanceCmd.java | 13 +- .../api/command/QuotaCreditsCmd.java | 6 + .../api/command/QuotaStatementCmd.java | 6 + .../management/MockAccountManager.java | 5 + .../api/dispatch/ParamProcessWorker.java | 59 ++++---- .../com/cloud/user/AccountManagerImpl.java | 14 ++ .../api/dispatch/ParamProcessWorkerTest.java | 131 +++++++++++++++--- .../cloud/user/MockAccountManagerImpl.java | 5 + 9 files changed, 189 insertions(+), 52 deletions(-) diff --git a/api/src/main/java/com/cloud/user/AccountService.java b/api/src/main/java/com/cloud/user/AccountService.java index 63f5455cfd0..60db7abb734 100644 --- a/api/src/main/java/com/cloud/user/AccountService.java +++ b/api/src/main/java/com/cloud/user/AccountService.java @@ -116,6 +116,8 @@ public interface AccountService { void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException; + void validateAccountHasAccessToResource(Account account, AccessType accessType, Object resource); + Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly); /** diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java index f4e248855fd..ecb6531d0cf 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaBalanceCmd.java @@ -21,6 +21,8 @@ import java.util.List; import javax.inject.Inject; +import com.cloud.user.Account; +import org.apache.cloudstack.api.ACL; import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -42,6 +44,7 @@ public class QuotaBalanceCmd extends BaseCmd { @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Account Id for which statement needs to be generated") private String accountName; + @ACL @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "If domain Id is given and the caller is domain admin then the statement is generated for domain.") private Long domainId; @@ -51,6 +54,7 @@ public class QuotaBalanceCmd extends BaseCmd { @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "Start date range quota query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-01.") private Date startDate; + @ACL @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account") private Long accountId; @@ -104,7 +108,14 @@ public class QuotaBalanceCmd extends BaseCmd { @Override public long getEntityOwnerId() { - return _accountService.getActiveAccountByName(accountName, domainId).getAccountId(); + if (accountId != null) { + return accountId; + } + Account account = _accountService.getActiveAccountByName(accountName, domainId); + if (account != null) { + return account.getAccountId(); + } + return Account.ACCOUNT_ID_SYSTEM; } @Override diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaCreditsCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaCreditsCmd.java index c47c0ad2d76..e83d52f94f4 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaCreditsCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaCreditsCmd.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command; import com.cloud.user.Account; +import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiErrorCode; @@ -48,6 +49,7 @@ public class QuotaCreditsCmd extends BaseCmd { @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Account Id for which quota credits need to be added") private String accountName; + @ACL @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Domain for which quota credits need to be added") private Long domainId; @@ -132,6 +134,10 @@ public class QuotaCreditsCmd extends BaseCmd { @Override public long getEntityOwnerId() { + Account account = _accountService.getActiveAccountByName(accountName, domainId); + if (account != null) { + return account.getAccountId(); + } return Account.ACCOUNT_ID_SYSTEM; } diff --git a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java index 4d1c233c37a..3219ba1448f 100644 --- a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java +++ b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/command/QuotaStatementCmd.java @@ -21,6 +21,7 @@ import java.util.List; import javax.inject.Inject; +import org.apache.cloudstack.api.ACL; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseCmd; @@ -44,6 +45,7 @@ public class QuotaStatementCmd extends BaseCmd { @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Optional, Account Id for which statement needs to be generated") private String accountName; + @ACL @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.") private Long domainId; @@ -56,6 +58,7 @@ public class QuotaStatementCmd extends BaseCmd { @Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "List quota usage records for the specified usage type") private Integer usageType; + @ACL @Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account") private Long accountId; @@ -112,6 +115,9 @@ public class QuotaStatementCmd extends BaseCmd { @Override public long getEntityOwnerId() { + if (accountId != null) { + return accountId; + } Account activeAccountByName = _accountService.getActiveAccountByName(accountName, domainId); if (activeAccountByName != null) { return activeAccountByName.getAccountId(); diff --git a/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index 67cfe1df3e1..a3fac2c8be9 100644 --- a/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/src/test/java/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -451,6 +451,11 @@ public class MockAccountManager extends ManagerBase implements AccountManager { // TODO Auto-generated method stub } + @Override + public void validateAccountHasAccessToResource(Account account, AccessType accessType, Object resource) { + // TODO Auto-generated method stub + } + @Override public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { // TODO Auto-generated method stub diff --git a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java index 9f07db4b033..b11a5282e62 100644 --- a/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java +++ b/server/src/main/java/com/cloud/api/dispatch/ParamProcessWorker.java @@ -32,8 +32,6 @@ import java.util.regex.Matcher; import javax.inject.Inject; -import org.apache.cloudstack.acl.ControlledEntity; -import org.apache.cloudstack.acl.InfrastructureEntity; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ACL; @@ -288,41 +286,44 @@ public class ParamProcessWorker implements DispatchWorker { doAccessChecks(cmd, entitiesToAccess); } - private void doAccessChecks(BaseCmd cmd, Map entitiesToAccess) { - Account caller = CallContext.current().getCallingAccount(); - List entityOwners = cmd.getEntityOwnerIds(); - Account[] owners = null; - if (entityOwners != null) { - owners = entityOwners.stream().map(id -> _accountMgr.getAccount(id)).toArray(Account[]::new); - } else { - if (cmd.getEntityOwnerId() == Account.ACCOUNT_ID_SYSTEM && cmd instanceof BaseAsyncCmd && ((BaseAsyncCmd)cmd).getApiResourceType() == ApiCommandResourceType.Network) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Skipping access check on the network owner if the owner is ROOT/system."); - } - owners = new Account[]{}; - } else { - owners = new Account[]{_accountMgr.getAccount(cmd.getEntityOwnerId())}; - } - } + protected void doAccessChecks(BaseCmd cmd, Map entitiesToAccess) { + Account[] owners = getEntityOwners(cmd); + Account caller = CallContext.current().getCallingAccount(); if (cmd instanceof BaseAsyncCreateCmd) { // check that caller can access the owner account. _accountMgr.checkAccess(caller, null, false, owners); } - if (!entitiesToAccess.isEmpty()) { - // check that caller can access the owner account. - _accountMgr.checkAccess(caller, null, false, owners); - for (Map.Entryentry : entitiesToAccess.entrySet()) { - Object entity = entry.getKey(); - if (entity instanceof ControlledEntity) { - _accountMgr.checkAccess(caller, entry.getValue(), true, (ControlledEntity) entity); - } else if (entity instanceof InfrastructureEntity) { - // FIXME: Move this code in adapter, remove code from - // Account manager - } + checkCallerAccessToEntities(caller, owners, entitiesToAccess); + } + + protected Account[] getEntityOwners(BaseCmd cmd) { + List entityOwners = cmd.getEntityOwnerIds(); + if (entityOwners != null) { + return entityOwners.stream().map(id -> _accountMgr.getAccount(id)).toArray(Account[]::new); + } + + if (cmd.getEntityOwnerId() == Account.ACCOUNT_ID_SYSTEM && cmd instanceof BaseAsyncCmd && cmd.getApiResourceType() == ApiCommandResourceType.Network) { + s_logger.debug("Skipping access check on the network owner if the owner is ROOT/system."); + } else { + Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); + if (owner != null) { + return new Account[]{owner}; } } + return new Account[]{}; + } + + protected void checkCallerAccessToEntities(Account caller, Account[] owners, Map entitiesToAccess) { + if (entitiesToAccess.isEmpty()) { + return; + } + _accountMgr.checkAccess(caller, null, false, owners); + for (Map.Entry entry : entitiesToAccess.entrySet()) { + Object entity = entry.getKey(); + _accountMgr.validateAccountHasAccessToResource(caller, entry.getValue(), entity); + } } @SuppressWarnings({"unchecked", "rawtypes"}) diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index 0a0d9265ac4..c7ceb00cb57 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -43,6 +43,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.APIChecker; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.InfrastructureEntity; import org.apache.cloudstack.acl.QuerySelector; import org.apache.cloudstack.acl.Role; import org.apache.cloudstack.acl.RoleService; @@ -722,6 +723,19 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M } + @Override + public void validateAccountHasAccessToResource(Account account, AccessType accessType, Object resource) { + Class resourceClass = resource.getClass(); + if (ControlledEntity.class.isAssignableFrom(resourceClass)) { + checkAccess(account, accessType, true, (ControlledEntity) resource); + } else if (Domain.class.isAssignableFrom(resourceClass)) { + checkAccess(account, (Domain) resource); + } else if (InfrastructureEntity.class.isAssignableFrom(resourceClass)) { + s_logger.trace("Validation of access to infrastructure entity has been disabled in CloudStack version 4.4."); + } + s_logger.debug(String.format("Account [%s] has access to resource.", account.getUuid())); + } + @Override public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) { // We just care for resource domain admins for now, and they should be permitted to see only their zone. diff --git a/server/src/test/java/com/cloud/api/dispatch/ParamProcessWorkerTest.java b/server/src/test/java/com/cloud/api/dispatch/ParamProcessWorkerTest.java index cf2a43eceda..0604405f4a5 100644 --- a/server/src/test/java/com/cloud/api/dispatch/ParamProcessWorkerTest.java +++ b/server/src/test/java/com/cloud/api/dispatch/ParamProcessWorkerTest.java @@ -18,6 +18,29 @@ */ package com.cloud.api.dispatch; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.InjectMocks; +import org.mockito.Spy; + +import org.mockito.junit.MockitoJUnitRunner; + +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd; +import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.context.CallContext; + import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.NetworkRuleConflictException; @@ -26,28 +49,33 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; -import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.context.CallContext; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; - -import java.util.HashMap; +import com.cloud.vm.VMInstanceVO; @RunWith(MockitoJUnitRunner.class) public class ParamProcessWorkerTest { - @Mock - protected AccountManager accountManager; + @Spy + @InjectMocks + private ParamProcessWorker paramProcessWorkerSpy; - protected ParamProcessWorker paramProcessWorker; + @Mock + private AccountManager accountManagerMock; + + @Mock + private Account callingAccountMock; + + @Mock + private User callingUserMock; + + @Mock + private Account ownerAccountMock; + + @Mock + BaseCmd baseCmdMock; + + private Account[] owners = new Account[]{ownerAccountMock}; + + private Map entities = new HashMap<>(); public static class TestCmd extends BaseCmd { @@ -65,7 +93,7 @@ public class ParamProcessWorkerTest { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, - ResourceAllocationException, NetworkRuleConflictException { + ResourceAllocationException, NetworkRuleConflictException { // well documented nothing } @@ -83,9 +111,7 @@ public class ParamProcessWorkerTest { @Before public void setup() { - CallContext.register(Mockito.mock(User.class), Mockito.mock(Account.class)); - paramProcessWorker = new ParamProcessWorker(); - paramProcessWorker._accountMgr = accountManager; + CallContext.register(callingUserMock, callingAccountMock); } @After @@ -101,10 +127,71 @@ public class ParamProcessWorkerTest { params.put("boolparam1", "true"); params.put("doubleparam1", "11.89"); final TestCmd cmd = new TestCmd(); - paramProcessWorker.processParameters(cmd, params); + paramProcessWorkerSpy.processParameters(cmd, params); Assert.assertEquals("foo", cmd.strparam1); Assert.assertEquals(100, cmd.intparam1); Assert.assertTrue(Double.compare(cmd.doubleparam1, 11.89) == 0); + Mockito.verify(paramProcessWorkerSpy).doAccessChecks(Mockito.any(), Mockito.any()); } + @Test + public void doAccessChecksTestChecksCallerAccessToOwnerWhenCmdExtendsBaseAsyncCreateCmd() { + Mockito.doReturn(owners).when(paramProcessWorkerSpy).getEntityOwners(Mockito.any()); + Mockito.doNothing().when(paramProcessWorkerSpy).checkCallerAccessToEntities(Mockito.any(), Mockito.any(), Mockito.any()); + + paramProcessWorkerSpy.doAccessChecks(new AssociateIPAddrCmd(), entities); + + Mockito.verify(accountManagerMock).checkAccess(callingAccountMock, null, false, owners); + } + + @Test + public void doAccessChecksTestChecksCallerAccessToEntities() { + Mockito.doReturn(owners).when(paramProcessWorkerSpy).getEntityOwners(Mockito.any()); + Mockito.doNothing().when(paramProcessWorkerSpy).checkCallerAccessToEntities(Mockito.any(), Mockito.any(), Mockito.any()); + + paramProcessWorkerSpy.doAccessChecks(new AssociateIPAddrCmd(), entities); + + Mockito.verify(paramProcessWorkerSpy).checkCallerAccessToEntities(callingAccountMock, owners, entities); + } + + @Test + public void getEntityOwnersTestReturnsAccountsWhenCmdHasMultipleEntityOwners() { + Mockito.when(baseCmdMock.getEntityOwnerIds()).thenReturn(List.of(1L, 2L)); + Mockito.doReturn(callingAccountMock).when(accountManagerMock).getAccount(1L); + Mockito.doReturn(ownerAccountMock).when(accountManagerMock).getAccount(2L); + + List result = List.of(paramProcessWorkerSpy.getEntityOwners(baseCmdMock)); + + Assert.assertEquals(List.of(callingAccountMock, ownerAccountMock), result); + } + + @Test + public void getEntityOwnersTestReturnsAccountWhenCmdHasOneEntityOwner() { + Mockito.when(baseCmdMock.getEntityOwnerId()).thenReturn(1L); + Mockito.when(baseCmdMock.getEntityOwnerIds()).thenReturn(null); + Mockito.doReturn(ownerAccountMock).when(accountManagerMock).getAccount(1L); + + List result = List.of(paramProcessWorkerSpy.getEntityOwners(baseCmdMock)); + + Assert.assertEquals(List.of(ownerAccountMock), result); + } + + @Test + public void checkCallerAccessToEntitiesTestChecksCallerAccessToOwners() { + entities.put(ownerAccountMock, SecurityChecker.AccessType.UseEntry); + + paramProcessWorkerSpy.checkCallerAccessToEntities(callingAccountMock, owners, entities); + + Mockito.verify(accountManagerMock).checkAccess(callingAccountMock, null, false, owners); + } + + @Test + public void checkCallerAccessToEntitiesTestChecksCallerAccessToResource() { + VMInstanceVO vmInstanceVo = new VMInstanceVO(); + entities.put(vmInstanceVo, SecurityChecker.AccessType.UseEntry); + + paramProcessWorkerSpy.checkCallerAccessToEntities(callingAccountMock, owners, entities); + + Mockito.verify(accountManagerMock).validateAccountHasAccessToResource(callingAccountMock, SecurityChecker.AccessType.UseEntry, vmInstanceVo); + } } diff --git a/server/src/test/java/com/cloud/user/MockAccountManagerImpl.java b/server/src/test/java/com/cloud/user/MockAccountManagerImpl.java index fe7748b8581..f8558992440 100644 --- a/server/src/test/java/com/cloud/user/MockAccountManagerImpl.java +++ b/server/src/test/java/com/cloud/user/MockAccountManagerImpl.java @@ -438,6 +438,11 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco // TODO Auto-generated method stub } + @Override + public void validateAccountHasAccessToResource(Account account, AccessType accessType, Object resource) { + // TODO Auto-generated method stub + } + @Override public Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly) { // TODO Auto-generated method stub From 4fa22f4d5881406353d3dfeadb68050e2242fdb8 Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador Date: Fri, 30 Aug 2024 19:03:28 -0300 Subject: [PATCH 06/12] Validate QCOW2 on upload and register --- .../formatinspector/Qcow2HeaderField.java | 51 ++++ .../formatinspector/Qcow2Inspector.java | 267 ++++++++++++++++++ .../resource/NfsSecondaryStorageResource.java | 14 +- .../storage/template/DownloadManagerImpl.java | 39 ++- 4 files changed, 360 insertions(+), 11 deletions(-) create mode 100644 services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2HeaderField.java create mode 100644 services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2Inspector.java diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2HeaderField.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2HeaderField.java new file mode 100644 index 00000000000..4a8e8b51a47 --- /dev/null +++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2HeaderField.java @@ -0,0 +1,51 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +package org.apache.cloudstack.storage.formatinspector; + +public enum Qcow2HeaderField { + MAGIC(0, 4), + VERSION(4, 4), + BACKING_FILE_OFFSET(8, 8), + BACKING_FILE_NAME_LENGTH(16, 4), + CLUSTER_BITS(20, 4), + SIZE(24, 8), + CRYPT_METHOD(32, 4), + L1_SIZE(36, 4), + LI_TABLE_OFFSET(40, 8), + REFCOUNT_TABLE_OFFSET(48, 8), + REFCOUNT_TABLE_CLUSTERS(56, 4), + NB_SNAPSHOTS(60, 4), + SNAPSHOTS_OFFSET(64, 8), + INCOMPATIBLE_FEATURES(72, 8); + + private final int offset; + private final int length; + + Qcow2HeaderField(int offset, int length) { + this.offset = offset; + this.length = length; + } + + public int getLength() { + return length; + } + + public int getOffset() { + return offset; + } +} diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2Inspector.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2Inspector.java new file mode 100644 index 00000000000..1ad2076a12d --- /dev/null +++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/formatinspector/Qcow2Inspector.java @@ -0,0 +1,267 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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. + +package org.apache.cloudstack.storage.formatinspector; + +import com.cloud.utils.NumbersUtil; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.log4j.Logger; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Class to inspect QCOW2 files/objects. In our context, a QCOW2 might be a threat to the environment if it meets one of the following criteria when coming from external sources + * (like registering or uploading volumes and templates): + *
    + *
  • has a backing file reference;
  • + *
  • has an external data file reference;
  • + *
  • has unknown incompatible features.
  • + *
+ * + * The implementation was done based on the QEMU's official interoperability documentation + * and on the OpenStack's Cinder implementation for Python. + */ +public class Qcow2Inspector { + protected static Logger LOGGER = Logger.getLogger(Qcow2Inspector.class); + + private static final byte[] QCOW_MAGIC_STRING = ArrayUtils.add("QFI".getBytes(), (byte) 0xfb); + private static final int INCOMPATIBLE_FEATURES_MAX_KNOWN_BIT = 4; + private static final int INCOMPATIBLE_FEATURES_MAX_KNOWN_BYTE = 0; + private static final int EXTERNAL_DATA_FILE_BYTE_POSITION = 7; + private static final int EXTERNAL_DATA_FILE_BIT = 2; + private static final byte EXTERNAL_DATA_FILE_BITMASK = (byte) (1 << EXTERNAL_DATA_FILE_BIT); + + private static final Set SET_OF_HEADER_FIELDS_TO_READ = Set.of(Qcow2HeaderField.MAGIC, + Qcow2HeaderField.VERSION, + Qcow2HeaderField.SIZE, + Qcow2HeaderField.BACKING_FILE_OFFSET, + Qcow2HeaderField.INCOMPATIBLE_FEATURES); + + /** + * Validates if the file is a valid and allowed QCOW2 (i.e.: does not contain external references). + * @param filePath Path of the file to be validated. + * @throws RuntimeException If the QCOW2 file meets one of the following criteria: + *
    + *
  • has a backing file reference;
  • + *
  • has an external data file reference;
  • + *
  • has unknown incompatible features.
  • + *
+ */ + public static void validateQcow2File(String filePath) throws RuntimeException { + LOGGER.info(String.format("Verifying if [%s] is a valid and allowed QCOW2 file .", filePath)); + + Map headerFieldsAndValues; + try (InputStream inputStream = new FileInputStream(filePath)) { + headerFieldsAndValues = unravelQcow2Header(inputStream, filePath); + } catch (IOException ex) { + throw new RuntimeException(String.format("Unable to validate file [%s] due to: ", filePath), ex); + } + + validateQcow2HeaderFields(headerFieldsAndValues, filePath); + + LOGGER.info(String.format("[%s] is a valid and allowed QCOW2 file.", filePath)); + } + + /** + * Unravels the QCOW2 header in a serial fashion, iterating through the {@link Qcow2HeaderField}, reading the fields specified in + * {@link Qcow2Inspector#SET_OF_HEADER_FIELDS_TO_READ} and skipping the others. + * @param qcow2InputStream InputStream of the QCOW2 being unraveled. + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @return A map of the header fields and their values according to the {@link Qcow2Inspector#SET_OF_HEADER_FIELDS_TO_READ}. + * @throws IOException If the field cannot be read or skipped. + */ + public static Map unravelQcow2Header(InputStream qcow2InputStream, String qcow2LogReference) throws IOException { + Map result = new HashMap<>(); + + LOGGER.debug(String.format("Unraveling QCOW2 [%s] headers.", qcow2LogReference)); + for (Qcow2HeaderField qcow2Header : Qcow2HeaderField.values()) { + if (!SET_OF_HEADER_FIELDS_TO_READ.contains(qcow2Header)) { + skipHeader(qcow2InputStream, qcow2Header, qcow2LogReference); + continue; + } + + byte[] headerValue = readHeader(qcow2InputStream, qcow2Header, qcow2LogReference); + result.put(qcow2Header.name(), headerValue); + } + + return result; + } + + /** + * Skips the field's length in the InputStream. + * @param qcow2InputStream InputStream of the QCOW2 being unraveled. + * @param field Field being skipped (name and length). + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws IOException If the bytes skipped do not match the field length. + */ + protected static void skipHeader(InputStream qcow2InputStream, Qcow2HeaderField field, String qcow2LogReference) throws IOException { + LOGGER.trace(String.format("Skipping field [%s] of QCOW2 [%s].", field, qcow2LogReference)); + + if (qcow2InputStream.skip(field.getLength()) != field.getLength()) { + throw new IOException(String.format("Unable to skip field [%s] of QCOW2 [%s].", field, qcow2LogReference)); + } + } + + /** + * Reads the field's length in the InputStream. + * @param qcow2InputStream InputStream of the QCOW2 being unraveled. + * @param field Field being read (name and length). + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws IOException If the bytes read do not match the field length. + */ + protected static byte[] readHeader(InputStream qcow2InputStream, Qcow2HeaderField field, String qcow2LogReference) throws IOException { + byte[] readBytes = new byte[field.getLength()]; + + LOGGER.trace(String.format("Reading field [%s] of QCOW2 [%s].", field, qcow2LogReference)); + if (qcow2InputStream.read(readBytes) != field.getLength()) { + throw new IOException(String.format("Unable to read field [%s] of QCOW2 [%s].", field, qcow2LogReference)); + } + + LOGGER.trace(String.format("Read %s as field [%s] of QCOW2 [%s].", ArrayUtils.toString(readBytes), field, qcow2LogReference)); + return readBytes; + } + + /** + * Validates the values of the header fields {@link Qcow2HeaderField#MAGIC}, {@link Qcow2HeaderField#BACKING_FILE_OFFSET}, and {@link Qcow2HeaderField#INCOMPATIBLE_FEATURES}. + * @param headerFieldsAndValues A map of the header fields and their values. + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws SecurityException If the QCOW2 does not contain the QCOW magic string or contains a backing file reference or incompatible features. + */ + public static void validateQcow2HeaderFields(Map headerFieldsAndValues, String qcow2LogReference) throws SecurityException{ + byte[] fieldValue = headerFieldsAndValues.get(Qcow2HeaderField.MAGIC.name()); + validateQcowMagicString(fieldValue, qcow2LogReference); + + fieldValue = headerFieldsAndValues.get(Qcow2HeaderField.BACKING_FILE_OFFSET.name()); + validateAbsenceOfBackingFileReference(NumbersUtil.bytesToLong(fieldValue), qcow2LogReference); + + fieldValue = headerFieldsAndValues.get(Qcow2HeaderField.INCOMPATIBLE_FEATURES.name()); + validateAbsenceOfIncompatibleFeatures(fieldValue, qcow2LogReference); + } + + /** + * Verifies if the first 4 bytes of the header are the QCOW magic string. Throws an exception if not. + * @param headerMagicString The first 4 bytes of the header. + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws SecurityException If the header's magic string is not the QCOW magic string. + */ + private static void validateQcowMagicString(byte[] headerMagicString, String qcow2LogReference) throws SecurityException { + LOGGER.debug(String.format("Verifying if [%s] has a valid QCOW magic string.", qcow2LogReference)); + + if (!Arrays.equals(QCOW_MAGIC_STRING, headerMagicString)) { + throw new SecurityException(String.format("[%s] is not a valid QCOW2 because its first 4 bytes are not the QCOW magic string.", qcow2LogReference)); + } + + LOGGER.debug(String.format("[%s] has a valid QCOW magic string.", qcow2LogReference)); + } + + /** + * Verifies if the QCOW2 has a backing file and throws an exception if so. + * @param backingFileOffset The backing file offset value of the QCOW2 header. + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws SecurityException If the QCOW2 has a backing file reference. + */ + private static void validateAbsenceOfBackingFileReference(long backingFileOffset, String qcow2LogReference) throws SecurityException { + LOGGER.debug(String.format("Verifying if [%s] has a backing file reference.", qcow2LogReference)); + + if (backingFileOffset != 0) { + throw new SecurityException(String.format("[%s] has a backing file reference. This can be an attack to the infrastructure; therefore, we will not accept" + + " this QCOW2.", qcow2LogReference)); + } + + LOGGER.debug(String.format("[%s] does not have a backing file reference.", qcow2LogReference)); + } + + /** + * Verifies if the QCOW2 has incompatible features and throw an exception if it has an external data file reference or unknown incompatible features. + * @param incompatibleFeatures The incompatible features bytes of the QCOW2 header. + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws SecurityException If the QCOW2 has an external data file reference or unknown incompatible features. + */ + private static void validateAbsenceOfIncompatibleFeatures(byte[] incompatibleFeatures, String qcow2LogReference) throws SecurityException { + LOGGER.debug(String.format("Verifying if [%s] has incompatible features.", qcow2LogReference)); + + if (NumbersUtil.bytesToLong(incompatibleFeatures) == 0) { + LOGGER.debug(String.format("[%s] does not have incompatible features.", qcow2LogReference)); + return; + } + + LOGGER.debug(String.format("[%s] has incompatible features.", qcow2LogReference)); + + validateAbsenceOfExternalDataFileReference(incompatibleFeatures, qcow2LogReference); + validateAbsenceOfUnknownIncompatibleFeatures(incompatibleFeatures, qcow2LogReference); + } + + /** + * Verifies if the QCOW2 has an external data file reference and throw an exception if so. + * @param incompatibleFeatures The incompatible features bytes of the QCOW2 header. + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws SecurityException If the QCOW2 has an external data file reference. + */ + private static void validateAbsenceOfExternalDataFileReference(byte[] incompatibleFeatures, String qcow2LogReference) throws SecurityException { + LOGGER.debug(String.format("Verifying if [%s] has an external data file reference.", qcow2LogReference)); + + if ((incompatibleFeatures[EXTERNAL_DATA_FILE_BYTE_POSITION] & EXTERNAL_DATA_FILE_BITMASK) != 0) { + throw new SecurityException(String.format("[%s] has an external data file reference. This can be an attack to the infrastructure; therefore, we will discard" + + " this file.", qcow2LogReference)); + } + + LOGGER.info(String.format("[%s] does not have an external data file reference.", qcow2LogReference)); + } + + /** + * Verifies if the QCOW2 has unknown incompatible features and throw an exception if so. + *

+ * Unknown incompatible features are those with bit greater than + * {@link Qcow2Inspector#INCOMPATIBLE_FEATURES_MAX_KNOWN_BIT}, which will be the represented by bytes in positions greater than + * {@link Qcow2Inspector#INCOMPATIBLE_FEATURES_MAX_KNOWN_BYTE} (in Big Endian order). Therefore, we expect that those bytes are always zero. If not, an exception is thrown. + * @param incompatibleFeatures The incompatible features bytes of the QCOW2 header. + * @param qcow2LogReference A reference (like the filename) of the QCOW2 being unraveled to print in the logs and exceptions. + * @throws SecurityException If the QCOW2 has unknown incompatible features. + */ + private static void validateAbsenceOfUnknownIncompatibleFeatures(byte[] incompatibleFeatures, String qcow2LogReference) throws SecurityException { + LOGGER.debug(String.format("Verifying if [%s] has unknown incompatible features [%s].", qcow2LogReference, ArrayUtils.toString(incompatibleFeatures))); + + for (int byteNum = incompatibleFeatures.length - 1; byteNum >= 0; byteNum--) { + int bytePosition = incompatibleFeatures.length - 1 - byteNum; + LOGGER.trace(String.format("Looking for unknown incompatible feature bit in position [%s].", bytePosition)); + + byte bitmask = 0; + if (byteNum == INCOMPATIBLE_FEATURES_MAX_KNOWN_BYTE) { + bitmask = ((1 << INCOMPATIBLE_FEATURES_MAX_KNOWN_BIT) - 1); + } + + LOGGER.trace(String.format("Bitmask for byte in position [%s] is [%s].", bytePosition, Integer.toBinaryString(bitmask))); + + int featureBit = incompatibleFeatures[bytePosition] & ~bitmask; + if (featureBit != 0) { + throw new SecurityException(String.format("Found unknown incompatible feature bit [%s] in byte [%s] of [%s]. This can be an attack to the infrastructure; " + + "therefore, we will discard this QCOW2.", featureBit, bytePosition + Qcow2HeaderField.INCOMPATIBLE_FEATURES.getOffset(), qcow2LogReference)); + } + + LOGGER.trace(String.format("Did not find unknown incompatible feature in position [%s].", bytePosition)); + } + + LOGGER.info(String.format("[%s] does not have unknown incompatible features.", qcow2LogReference)); + } + +} diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 41cf11025a1..ceaa37926e9 100644 --- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -71,6 +71,7 @@ import org.apache.cloudstack.storage.command.UploadStatusCommand; import org.apache.cloudstack.storage.command.browser.ListDataStoreObjectsCommand; import org.apache.cloudstack.storage.configdrive.ConfigDrive; import org.apache.cloudstack.storage.configdrive.ConfigDriveBuilder; +import org.apache.cloudstack.storage.formatinspector.Qcow2Inspector; import org.apache.cloudstack.storage.template.DownloadManager; import org.apache.cloudstack.storage.template.DownloadManagerImpl; import org.apache.cloudstack.storage.template.UploadEntity; @@ -3482,8 +3483,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return result; } + String finalFilename = resourcePath + "/" + templateFilename; + + if (ImageStoreUtil.isCorrectExtension(finalFilename, "qcow2")) { + try { + Qcow2Inspector.validateQcow2File(finalFilename); + } catch (RuntimeException e) { + s_logger.error(String.format("Uploaded file [%s] is not a valid QCOW2.", finalFilename), e); + return "The uploaded file is not a valid QCOW2. Ask the administrator to check the logs for more details."; + } + } + // Set permissions for the downloaded template - File downloadedTemplate = new File(resourcePath + "/" + templateFilename); + File downloadedTemplate = new File(finalFilename); _storage.setWorldReadableAndWriteable(downloadedTemplate); // Set permissions for template/volume.properties diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index 11878ae6400..c946614934b 100644 --- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -16,8 +16,6 @@ // under the License. package org.apache.cloudstack.storage.template; -import static com.cloud.utils.NumbersUtil.toHumanReadableSize; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -51,9 +49,11 @@ import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType import org.apache.cloudstack.storage.resource.IpTablesHelper; import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource; import org.apache.cloudstack.storage.resource.SecondaryStorageResource; +import org.apache.cloudstack.storage.formatinspector.Qcow2HeaderField; +import org.apache.cloudstack.storage.formatinspector.Qcow2Inspector; import org.apache.cloudstack.utils.security.ChecksumValue; import org.apache.cloudstack.utils.security.DigestHelper; -import org.apache.commons.lang3.StringUtils; + import org.apache.log4j.Logger; import com.cloud.agent.api.storage.DownloadAnswer; @@ -91,7 +91,9 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Proxy; import com.cloud.utils.script.Script; -import com.cloud.utils.storage.QCOW2Utils; +import com.cloud.utils.StringUtils; + +import static com.cloud.utils.NumbersUtil.toHumanReadableSize; public class DownloadManagerImpl extends ManagerBase implements DownloadManager { private String _name; @@ -365,11 +367,17 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager // The QCOW2 is the only format with a header, // and as such can be easily read. - try (InputStream inputStream = td.getS3ObjectInputStream();) { - dnld.setTemplatesize(QCOW2Utils.getVirtualSize(inputStream, false)); - } - catch (IOException e) { - result = "Couldn't read QCOW2 virtual size. Error: " + e.getMessage(); + try (InputStream inputStream = td.getS3ObjectInputStream()) { + Map qcow2HeaderFieldsAndValues = Qcow2Inspector.unravelQcow2Header(inputStream, td.getDownloadUrl()); + Qcow2Inspector.validateQcow2HeaderFields(qcow2HeaderFieldsAndValues, td.getDownloadUrl()); + + dnld.setTemplatesize(NumbersUtil.bytesToLong(qcow2HeaderFieldsAndValues.get(Qcow2HeaderField.SIZE.name()))); + } catch (IOException ex) { + result = String.format("Unable to read QCOW2 metadata. Error: %s", ex.getMessage()); + LOGGER.error(result, ex); + } catch (SecurityException ex) { + result = String.format("[%s] is not a valid QCOW2:", td.getDownloadUrl()); + LOGGER.error(result, ex); } } @@ -515,8 +523,19 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return result; } + String finalFilename = resourcePath + "/" + templateFilename; + + if (ImageFormat.QCOW2.equals(dnld.getFormat())) { + try { + Qcow2Inspector.validateQcow2File(finalFilename); + } catch (RuntimeException e) { + LOGGER.error(String.format("The downloaded file [%s] is not a valid QCOW2.", finalFilename), e); + return "The downloaded file is not a valid QCOW2. Ask the administrator to check the logs for more details."; + } + } + // Set permissions for the downloaded template - File downloadedTemplate = new File(resourcePath + "/" + templateFilename); + File downloadedTemplate = new File(finalFilename); _storage.setWorldReadableAndWriteable(downloadedTemplate); setPermissionsForTheDownloadedTemplate(resourcePath, resourceType); From 13dd6983428a535a5d401bce106dd5da9a1b802a Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Tue, 10 Sep 2024 18:25:36 +0200 Subject: [PATCH 07/12] util: check JSESSIONID in cookies if user is passed --- .../command/ListAndSwitchSAMLAccountCmd.java | 7 +- .../cloudstack/saml/SAML2AuthManager.java | 3 + .../cloudstack/saml/SAML2AuthManagerImpl.java | 3 +- .../org/apache/cloudstack/saml/SAMLUtils.java | 25 ++++- .../ListAndSwitchSAMLAccountCmdTest.java | 25 ++++- .../main/java/com/cloud/api/ApiServer.java | 26 ++++- .../main/java/com/cloud/api/ApiServlet.java | 102 +++++++++++------- test/integration/smoke/test_login.py | 1 + ui/src/api/index.js | 10 ++ ui/src/store/modules/user.js | 1 - .../main/java/com/cloud/utils/HttpUtils.java | 42 ++++++-- .../java/com/cloud/utils/HttpUtilsTest.java | 86 ++++++++++++--- 12 files changed, 266 insertions(+), 65 deletions(-) diff --git a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java index 25f056adf68..c2f81cd3356 100644 --- a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java +++ b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmd.java @@ -48,6 +48,7 @@ import org.apache.cloudstack.saml.SAML2AuthManager; import org.apache.cloudstack.saml.SAMLUtils; import org.apache.log4j.Logger; +import com.cloud.api.ApiServer; import com.cloud.api.response.ApiResponseSerializer; import com.cloud.domain.Domain; import com.cloud.domain.dao.DomainDao; @@ -60,6 +61,8 @@ import com.cloud.user.dao.UserAccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.HttpUtils; +import org.apache.commons.lang3.EnumUtils; + @APICommand(name = "listAndSwitchSamlAccount", description = "Lists and switches to other SAML accounts owned by the SAML user", responseObject = SuccessResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListAndSwitchSAMLAccountCmd extends BaseCmd implements APIAuthenticator { public static final Logger s_logger = Logger.getLogger(ListAndSwitchSAMLAccountCmd.class.getName()); @@ -104,7 +107,9 @@ public class ListAndSwitchSAMLAccountCmd extends BaseCmd implements APIAuthentic params, responseType)); } - if (!HttpUtils.validateSessionKey(session, params, req.getCookies(), ApiConstants.SESSIONKEY)) { + HttpUtils.ApiSessionKeyCheckOption sessionKeyCheckOption = EnumUtils.getEnumIgnoreCase(HttpUtils.ApiSessionKeyCheckOption.class, + ApiServer.ApiSessionKeyCheckLocations.value(), HttpUtils.ApiSessionKeyCheckOption.CookieAndParameter); + if (!HttpUtils.validateSessionKey(session, params, req.getCookies(), ApiConstants.SESSIONKEY, sessionKeyCheckOption)) { throw new ServerApiException(ApiErrorCode.UNAUTHORIZED, _apiServer.getSerializedApiError(ApiErrorCode.UNAUTHORIZED.getHttpCode(), "Unauthorized session, please re-login", params, responseType)); diff --git a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManager.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManager.java index 3a4030f9c0d..e10ea08012f 100644 --- a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManager.java +++ b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManager.java @@ -73,6 +73,9 @@ public interface SAML2AuthManager extends PluggableAPIAuthenticator, PluggableSe ConfigKey SAMLCheckSignature = new ConfigKey("Advanced", Boolean.class, "saml2.check.signature", "true", "When enabled (default and recommended), SAML2 signature checks are enforced and lack of signature in the SAML SSO response will cause login exception. Disabling this is not advisable but provided for backward compatibility for users who are able to accept the risks.", false); + ConfigKey SAMLUserSessionKeyPathAttribute = new ConfigKey("Advanced", String.class, "saml2.user.sessionkey.path", "", + "The Path attribute of sessionkey cookie when SAML users have logged in. If not set, it will be set to the path of SAML redirection URL (saml2.redirect.url).", true); + SAMLProviderMetadata getSPMetadata(); SAMLProviderMetadata getIdPMetadata(String entityId); Collection getAllIdPMetadata(); diff --git a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java index dfa76414fb7..aa1e0be91c7 100644 --- a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java +++ b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java @@ -542,6 +542,7 @@ public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManage SAMLServiceProviderSingleSignOnURL, SAMLServiceProviderSingleLogOutURL, SAMLCloudStackRedirectionUrl, SAMLUserAttributeName, SAMLIdentityProviderMetadataURL, SAMLDefaultIdentityProviderId, - SAMLSignatureAlgorithm, SAMLAppendDomainSuffix, SAMLTimeout, SAMLCheckSignature}; + SAMLSignatureAlgorithm, SAMLAppendDomainSuffix, SAMLTimeout, SAMLCheckSignature, + SAMLUserSessionKeyPathAttribute}; } } diff --git a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLUtils.java b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLUtils.java index f10bc891368..bb94c8af4c2 100644 --- a/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLUtils.java +++ b/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/saml/SAMLUtils.java @@ -25,6 +25,8 @@ import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.math.BigInteger; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URLEncoder; import java.nio.charset.Charset; import java.security.InvalidKeyException; @@ -101,7 +103,9 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; +import com.cloud.api.ApiServlet; import com.cloud.utils.HttpUtils; +import com.cloud.utils.exception.CloudRuntimeException; public class SAMLUtils { public static final Logger s_logger = Logger.getLogger(SAMLUtils.class); @@ -296,7 +300,26 @@ public class SAMLUtils { resp.addCookie(new Cookie("timezone", URLEncoder.encode(timezone, HttpUtils.UTF_8))); } resp.addCookie(new Cookie("userfullname", URLEncoder.encode(loginResponse.getFirstName() + " " + loginResponse.getLastName(), HttpUtils.UTF_8).replace("+", "%20"))); - resp.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly;Path=/client/api", ApiConstants.SESSIONKEY, loginResponse.getSessionKey())); + + String redirectUrl = SAML2AuthManager.SAMLCloudStackRedirectionUrl.value(); + String path = SAML2AuthManager.SAMLUserSessionKeyPathAttribute.value(); + String domain = null; + try { + URI redirectUri = new URI(redirectUrl); + domain = redirectUri.getHost(); + if (StringUtils.isBlank(path)) { + path = redirectUri.getPath(); + } + if (StringUtils.isBlank(path)) { + path = "/"; + } + } catch (URISyntaxException ex) { + throw new CloudRuntimeException("Invalid URI: " + redirectUrl); + } + String sameSite = ApiServlet.getApiSessionKeySameSite(); + String sessionKeyCookie = String.format("%s=%s;Domain=%s;Path=%s;%s", ApiConstants.SESSIONKEY, loginResponse.getSessionKey(), domain, path, sameSite); + s_logger.debug("Adding sessionkey cookie to response: " + sessionKeyCookie); + resp.addHeader("SET-COOKIE", sessionKeyCookie); } /** diff --git a/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java index b4d230e3cd6..729334d22ce 100644 --- a/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java +++ b/plugins/user-authenticators/saml2/src/test/java/org/apache/cloudstack/api/command/ListAndSwitchSAMLAccountCmdTest.java @@ -27,6 +27,7 @@ import java.net.InetAddress; import java.util.HashMap; import java.util.Map; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -88,6 +89,9 @@ public class ListAndSwitchSAMLAccountCmdTest extends TestCase { @Mock HttpServletRequest req; + final String sessionId = "node0xxxxxxxxxxxxx"; + Cookie[] cookies; + @Test public void testListAndSwitchSAMLAccountCmd() throws Exception { // Setup @@ -95,6 +99,7 @@ public class ListAndSwitchSAMLAccountCmdTest extends TestCase { final String sessionKeyValue = "someSessionIDValue"; Mockito.when(session.getAttribute(ApiConstants.SESSIONKEY)).thenReturn(sessionKeyValue); Mockito.when(session.getAttribute("userid")).thenReturn(2L); + Mockito.when(session.getId()).thenReturn(sessionId); params.put(ApiConstants.USER_ID, new String[]{"2"}); params.put(ApiConstants.DOMAIN_ID, new String[]{"1"}); Mockito.when(userDao.findByUuid(anyString())).thenReturn(new UserVO(2L)); @@ -146,7 +151,25 @@ public class ListAndSwitchSAMLAccountCmdTest extends TestCase { Mockito.verify(accountService, Mockito.times(0)).getUserAccountById(Mockito.anyLong()); } - // valid sessionkey value test + // valid sessionkey value and invalid JSESSIONID test + cookies = new Cookie[2]; + cookies[0] = new Cookie(ApiConstants.SESSIONKEY, sessionKeyValue); + cookies[1] = new Cookie("JSESSIONID", "invalid-JSESSIONID"); + Mockito.when(req.getCookies()).thenReturn(cookies); + params.put(ApiConstants.SESSIONKEY, new String[]{sessionKeyValue}); + try { + cmd.authenticate("command", params, session, null, HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp); + } catch (ServerApiException exception) { + assertEquals(exception.getErrorCode(), ApiErrorCode.UNAUTHORIZED); + } finally { + Mockito.verify(accountService, Mockito.times(0)).getUserAccountById(Mockito.anyLong()); + } + + // valid sessionkey value and valid JSESSIONID test + cookies = new Cookie[2]; + cookies[0] = new Cookie(ApiConstants.SESSIONKEY, sessionKeyValue); + cookies[1] = new Cookie("JSESSIONID", sessionId + ".node0"); + Mockito.when(req.getCookies()).thenReturn(cookies); params.put(ApiConstants.SESSIONKEY, new String[]{sessionKeyValue}); try { cmd.authenticate("command", params, session, null, HttpUtils.RESPONSE_TYPE_JSON, new StringBuilder(), req, resp); diff --git a/server/src/main/java/com/cloud/api/ApiServer.java b/server/src/main/java/com/cloud/api/ApiServer.java index b1a04932cf9..d68f42470d5 100644 --- a/server/src/main/java/com/cloud/api/ApiServer.java +++ b/server/src/main/java/com/cloud/api/ApiServer.java @@ -33,6 +33,7 @@ import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; +import java.util.EnumSet; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; @@ -47,6 +48,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; @@ -168,6 +170,8 @@ import com.cloud.user.UserVO; import com.cloud.utils.ConstantTimeComparator; import com.cloud.utils.DateUtil; import com.cloud.utils.HttpUtils; +import com.cloud.utils.HttpUtils.ApiSessionKeySameSite; +import com.cloud.utils.HttpUtils.ApiSessionKeyCheckOption; import com.cloud.utils.Pair; import com.cloud.utils.ReflectUtil; import com.cloud.utils.StringUtils; @@ -306,6 +310,24 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer , true , ConfigKey.Scope.Global); + static final ConfigKey ApiSessionKeyCookieSameSiteSetting = new ConfigKey<>(String.class + , "api.sessionkey.cookie.samesite" + , ConfigKey.CATEGORY_ADVANCED + , ApiSessionKeySameSite.Lax.name() + , "The SameSite attribute of cookie 'sessionkey'. Valid options are: Lax (default), Strict, NoneAndSecure and Null." + , true + , ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.Select, + EnumSet.allOf(ApiSessionKeySameSite.class).stream().map(Enum::toString).collect(Collectors.joining(", "))); + + public static final ConfigKey ApiSessionKeyCheckLocations = new ConfigKey<>(String.class + , "api.sessionkey.check.locations" + , ConfigKey.CATEGORY_ADVANCED + , ApiSessionKeyCheckOption.CookieAndParameter.name() + , "The locations of 'sessionkey' during the validation of the API requests. Valid options are: CookieOrParameter, ParameterOnly, CookieAndParameter (default)." + , true + , ConfigKey.Scope.Global, null, null, null, null, null, ConfigKey.Kind.Select, + EnumSet.allOf(ApiSessionKeyCheckOption.class).stream().map(Enum::toString).collect(Collectors.joining(", "))); + @Override public boolean configure(final String name, final Map params) throws ConfigurationException { messageBus.subscribe(AsyncJob.Topics.JOB_EVENT_PUBLISH, MessageDispatcher.getDispatcher(this)); @@ -1531,7 +1553,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer JSONDefaultContentType, proxyForwardList, useForwardHeader, - listOfForwardHeaders + listOfForwardHeaders, + ApiSessionKeyCookieSameSiteSetting, + ApiSessionKeyCheckLocations }; } } diff --git a/server/src/main/java/com/cloud/api/ApiServlet.java b/server/src/main/java/com/cloud/api/ApiServlet.java index e719238afef..d9654f03916 100644 --- a/server/src/main/java/com/cloud/api/ApiServlet.java +++ b/server/src/main/java/com/cloud/api/ApiServlet.java @@ -47,6 +47,7 @@ import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.managed.context.ManagedContext; import org.apache.cloudstack.utils.consoleproxy.ConsoleAccessUtils; import org.apache.log4j.Logger; +import org.apache.commons.lang3.EnumUtils; import org.jetbrains.annotations.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.context.support.SpringBeanAutowiringSupport; @@ -63,13 +64,15 @@ import com.cloud.user.User; import com.cloud.user.UserAccount; import com.cloud.utils.HttpUtils; +import com.cloud.utils.HttpUtils.ApiSessionKeySameSite; +import com.cloud.utils.HttpUtils.ApiSessionKeyCheckOption; import com.cloud.utils.StringUtils; import com.cloud.utils.db.EntityManager; import com.cloud.utils.net.NetUtils; @Component("apiServlet") public class ApiServlet extends HttpServlet { - public static final Logger s_logger = Logger.getLogger(ApiServlet.class.getName()); + public static final Logger LOGGER = Logger.getLogger(ApiServlet.class.getName()); private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServlet.class.getName()); private static final String REPLACEMENT = "_"; private static final String LOG_REPLACEMENTS = "[\n\r\t]"; @@ -127,7 +130,7 @@ public class ApiServlet extends HttpServlet { String value = decodeUtf8(paramTokens[1]); params.put(name, new String[] {value}); } else { - s_logger.debug("Invalid parameter in URL found. param: " + param); + LOGGER.debug("Invalid parameter in URL found. param: " + param); } } } @@ -156,7 +159,7 @@ public class ApiServlet extends HttpServlet { if (v.length > 1) { String message = String.format("Query parameter '%s' has multiple values %s. Only the last value will be respected." + "It is advised to pass only a single parameter", k, Arrays.toString(v)); - s_logger.warn(message); + LOGGER.warn(message); } }); @@ -167,7 +170,7 @@ public class ApiServlet extends HttpServlet { try { remoteAddress = getClientAddress(req); } catch (UnknownHostException e) { - s_logger.warn("UnknownHostException when trying to lookup remote IP-Address. This should never happen. Blocking request.", e); + LOGGER.warn("UnknownHostException when trying to lookup remote IP-Address. This should never happen. Blocking request.", e); final String response = apiServer.getSerializedApiError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "UnknownHostException when trying to lookup remote IP-Address", null, HttpUtils.RESPONSE_TYPE_XML); @@ -191,17 +194,17 @@ public class ApiServlet extends HttpServlet { // logging the request start and end in management log for easy debugging String reqStr = ""; String cleanQueryString = StringUtils.cleanString(req.getQueryString()); - if (s_logger.isDebugEnabled()) { + if (LOGGER.isDebugEnabled()) { reqStr = auditTrailSb.toString() + " " + cleanQueryString; - s_logger.debug("===START=== " + reqStr); + LOGGER.debug("===START=== " + reqStr); } try { resp.setContentType(HttpUtils.XML_CONTENT_TYPE); HttpSession session = req.getSession(false); - if (s_logger.isTraceEnabled()) { - s_logger.trace(String.format("session found: %s", session)); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("session found: %s", session)); } final Object[] responseTypeParam = params.get(ApiConstants.RESPONSE); if (responseTypeParam != null) { @@ -212,10 +215,10 @@ public class ApiServlet extends HttpServlet { final String command = commandObj == null ? null : (String) commandObj[0]; final Object[] userObj = params.get(ApiConstants.USERNAME); String username = userObj == null ? null : (String)userObj[0]; - if (s_logger.isTraceEnabled()) { + if (LOGGER.isTraceEnabled()) { String logCommand = saveLogString(command); String logName = saveLogString(username); - s_logger.trace(String.format("command %s processing for user \"%s\"", + LOGGER.trace(String.format("command %s processing for user \"%s\"", logCommand, logName)); } @@ -238,25 +241,26 @@ public class ApiServlet extends HttpServlet { if (ApiServer.EnableSecureSessionCookie.value()) { resp.setHeader("SET-COOKIE", String.format("JSESSIONID=%s;Secure;HttpOnly;Path=/client", session.getId())); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Session cookie is marked secure!"); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Session cookie is marked secure!"); } } } try { - if (s_logger.isTraceEnabled()) { - s_logger.trace(String.format("apiAuthenticator.authenticate(%s, params[%d], %s, %s, %s, %s, %s,%s)", + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("apiAuthenticator.authenticate(%s, params[%d], %s, %s, %s, %s, %s,%s)", saveLogString(command), params.size(), session.getId(), remoteAddress.getHostAddress(), saveLogString(responseType), "auditTrailSb", "req", "resp")); } responseString = apiAuthenticator.authenticate(command, params, session, remoteAddress, responseType, auditTrailSb, req, resp); if (session != null && session.getAttribute(ApiConstants.SESSIONKEY) != null) { - resp.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly", ApiConstants.SESSIONKEY, session.getAttribute(ApiConstants.SESSIONKEY))); + String sameSite = getApiSessionKeySameSite(); + resp.addHeader("SET-COOKIE", String.format("%s=%s;HttpOnly;%s", ApiConstants.SESSIONKEY, session.getAttribute(ApiConstants.SESSIONKEY), sameSite)); } } catch (ServerApiException e) { httpResponseCode = e.getErrorCode().getHttpCode(); responseString = e.getMessage(); - s_logger.debug("Authentication failure: " + e.getMessage()); + LOGGER.debug("Authentication failure: " + e.getMessage()); } if (apiAuthenticator.getAPIType() == APIAuthenticationType.LOGOUT_API) { @@ -289,7 +293,7 @@ public class ApiServlet extends HttpServlet { return; } } else { - s_logger.trace("no command available"); + LOGGER.trace("no command available"); } auditTrailSb.append(cleanQueryString); final boolean isNew = ((session == null) ? true : session.isNew()); @@ -298,15 +302,15 @@ public class ApiServlet extends HttpServlet { // we no longer rely on web-session here, verifyRequest will populate user/account information // if a API key exists - if (isNew && s_logger.isTraceEnabled()) { - s_logger.trace(String.format("new session: %s", session)); + if (isNew && LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("new session: %s", session)); } if (!isNew && (command.equalsIgnoreCase(ValidateUserTwoFactorAuthenticationCodeCmd.APINAME) || (!skip2FAcheckForAPIs(command) && !skip2FAcheckForUser(session)))) { - s_logger.debug("Verifying two factor authentication"); + LOGGER.debug("Verifying two factor authentication"); boolean success = verify2FA(session, command, auditTrailSb, params, remoteAddress, responseType, req, resp); if (!success) { - s_logger.debug("Verification of two factor authentication failed"); + LOGGER.debug("Verification of two factor authentication failed"); return; } } @@ -319,8 +323,8 @@ public class ApiServlet extends HttpServlet { if (account != null) { if (invalidateHttpSessionIfNeeded(req, resp, auditTrailSb, responseType, params, session, account)) return; } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("no account, this request will be validated through apikey(%s)/signature"); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("no account, this request will be validated through apikey(%s)/signature"); } } @@ -330,8 +334,8 @@ public class ApiServlet extends HttpServlet { CallContext.register(accountMgr.getSystemUser(), accountMgr.getSystemAccount()); } setProjectContext(params); - if (s_logger.isTraceEnabled()) { - s_logger.trace(String.format("verifying request for user %s from %s with %d parameters", + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("verifying request for user %s from %s with %d parameters", userId, remoteAddress.getHostAddress(), params.size())); } if (apiServer.verifyRequest(params, userId, remoteAddress)) { @@ -362,18 +366,34 @@ public class ApiServlet extends HttpServlet { HttpUtils.writeHttpResponse(resp, serializedResponseText, se.getErrorCode().getHttpCode(), responseType, ApiServer.JSONcontentType.value()); auditTrailSb.append(" " + se.getErrorCode() + " " + se.getDescription()); } catch (final Exception ex) { - s_logger.error("unknown exception writing api response", ex); + LOGGER.error("unknown exception writing api response", ex); auditTrailSb.append(" unknown exception writing api response"); } finally { s_accessLogger.info(auditTrailSb.toString()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("===END=== " + reqStr); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("===END=== " + reqStr); } // cleanup user context to prevent from being peeked in other request context CallContext.unregister(); } } + public static String getApiSessionKeySameSite() { + ApiSessionKeySameSite sameSite = EnumUtils.getEnumIgnoreCase(ApiSessionKeySameSite.class, + ApiServer.ApiSessionKeyCookieSameSiteSetting.value(), ApiSessionKeySameSite.Lax); + switch (sameSite) { + case Strict: + return "SameSite=Strict"; + case NoneAndSecure: + return "SameSite=None;Secure"; + case Null: + return ""; + case Lax: + default: + return "SameSite=Lax"; + } + } + private boolean checkIfAuthenticatorIsOf2FA(String command) { boolean verify2FA = false; APIAuthenticator apiAuthenticator = authManager.getAPIAuthenticator(command); @@ -402,7 +422,7 @@ public class ApiServlet extends HttpServlet { Long userId = (Long) session.getAttribute("userid"); boolean is2FAverified = (boolean) session.getAttribute(ApiConstants.IS_2FA_VERIFIED); if (is2FAverified) { - s_logger.debug(String.format("Two factor authentication is already verified for the user %d, so skipping", userId)); + LOGGER.debug(String.format("Two factor authentication is already verified for the user %d, so skipping", userId)); skip2FAcheck = true; } else { UserAccount userAccount = accountMgr.getUserAccountById(userId); @@ -433,7 +453,7 @@ public class ApiServlet extends HttpServlet { HttpUtils.writeHttpResponse(resp, responseString, HttpServletResponse.SC_OK, responseType, ApiServer.JSONcontentType.value()); verify2FA = true; } else { - s_logger.error("Cannot find API authenticator while verifying 2FA"); + LOGGER.error("Cannot find API authenticator while verifying 2FA"); auditTrailSb.append(" Cannot find API authenticator while verifying 2FA"); verify2FA = false; } @@ -457,7 +477,7 @@ public class ApiServlet extends HttpServlet { errorMsg = "Two factor authentication is mandated by admin, user needs to setup 2FA using setupUserTwoFactorAuthentication API and" + " then verify 2FA using validateUserTwoFactorAuthenticationCode API before calling other APIs. Existing session is invalidated."; } - s_logger.error(errorMsg); + LOGGER.error(errorMsg); invalidateHttpSession(session, String.format("Unable to process the API request for %s from %s due to %s", userId, remoteAddress.getHostAddress(), errorMsg)); auditTrailSb.append(" " + ApiErrorCode.UNAUTHORIZED2FA + " " + errorMsg); @@ -488,7 +508,7 @@ public class ApiServlet extends HttpServlet { private boolean requestChecksoutAsSane(HttpServletResponse resp, StringBuilder auditTrailSb, String responseType, Map params, HttpSession session, String command, Long userId, String account, Object accountObj) { if ((userId != null) && (account != null) && (accountObj != null) && apiServer.verifyUser(userId)) { if (command == null) { - s_logger.info("missing command, ignoring request..."); + LOGGER.info("missing command, ignoring request..."); auditTrailSb.append(" " + HttpServletResponse.SC_BAD_REQUEST + " " + "no command specified"); final String serializedResponse = apiServer.getSerializedApiError(HttpServletResponse.SC_BAD_REQUEST, "no command specified", params, responseType); HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_BAD_REQUEST, responseType, ApiServer.JSONcontentType.value()); @@ -509,7 +529,9 @@ public class ApiServlet extends HttpServlet { } private boolean invalidateHttpSessionIfNeeded(HttpServletRequest req, HttpServletResponse resp, StringBuilder auditTrailSb, String responseType, Map params, HttpSession session, String account) { - if (!HttpUtils.validateSessionKey(session, params, req.getCookies(), ApiConstants.SESSIONKEY)) { + ApiSessionKeyCheckOption sessionKeyCheckOption = EnumUtils.getEnumIgnoreCase(ApiSessionKeyCheckOption.class, + ApiServer.ApiSessionKeyCheckLocations.value(), ApiSessionKeyCheckOption.CookieAndParameter); + if (!HttpUtils.validateSessionKey(session, params, req.getCookies(), ApiConstants.SESSIONKEY, sessionKeyCheckOption)) { String msg = String.format("invalidating session %s for account %s", session.getId(), account); invalidateHttpSession(session, msg); auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials"); @@ -523,13 +545,13 @@ public class ApiServlet extends HttpServlet { public static void invalidateHttpSession(HttpSession session, String msg) { try { - if (s_logger.isTraceEnabled()) { - s_logger.trace(msg); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(msg); } session.invalidate(); } catch (final IllegalStateException ise) { - if (s_logger.isTraceEnabled()) { - s_logger.trace(String.format("failed to invalidate session %s", session.getId())); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("failed to invalidate session %s", session.getId())); } } } @@ -537,7 +559,7 @@ public class ApiServlet extends HttpServlet { private void setProjectContext(Map requestParameters) { final String[] command = (String[])requestParameters.get(ApiConstants.COMMAND); if (command == null) { - s_logger.info("missing command, ignoring request..."); + LOGGER.info("missing command, ignoring request..."); return; } @@ -585,14 +607,14 @@ public class ApiServlet extends HttpServlet { header = header.trim(); ip = getCorrectIPAddress(request.getHeader(header)); if (StringUtils.isNotBlank(ip)) { - s_logger.debug(String.format("found ip %s in header %s ", ip, header)); + LOGGER.debug(String.format("found ip %s in header %s ", ip, header)); break; } } // no address found in header so ip is blank and use remote addr } // else not an allowed proxy address, ip is blank and use remote addr } if (StringUtils.isBlank(ip)) { - s_logger.trace(String.format("no ip found in headers, returning remote address %s.", pretender.getHostAddress())); + LOGGER.trace(String.format("no ip found in headers, returning remote address %s.", pretender.getHostAddress())); return pretender; } diff --git a/test/integration/smoke/test_login.py b/test/integration/smoke/test_login.py index 40d8349a13d..acd6c4334ac 100644 --- a/test/integration/smoke/test_login.py +++ b/test/integration/smoke/test_login.py @@ -133,6 +133,7 @@ class TestLogin(cloudstackTestCase): args["command"] = 'listUsers' args["listall"] = 'true' args["response"] = "json" + args["sessionkey"] = response.json()['loginresponse']['sessionkey'] response = session.get(self.server_url, params=args) self.assertEqual( response.status_code, diff --git a/ui/src/api/index.js b/ui/src/api/index.js index 14432010738..7ab87780a9d 100644 --- a/ui/src/api/index.js +++ b/ui/src/api/index.js @@ -15,8 +15,13 @@ // specific language governing permissions and limitations // under the License. +import Cookies from 'js-cookie' import { axios, sourceToken } from '@/utils/request' import { message, notification } from 'ant-design-vue' +import { vueProps } from '@/vue-app' +import { + ACCESS_TOKEN +} from '@/store/mutation-types' export function api (command, args = {}, method = 'GET', data = {}) { let params = {} @@ -30,6 +35,11 @@ export function api (command, args = {}, method = 'GET', data = {}) { }) } + const sessionkey = vueProps.$localStorage.get(ACCESS_TOKEN) || Cookies.get('sessionkey') + if (sessionkey) { + args.sessionkey = sessionkey + } + return axios({ params: { ...args diff --git a/ui/src/store/modules/user.js b/ui/src/store/modules/user.js index 08a0c340c64..46a1905619f 100644 --- a/ui/src/store/modules/user.js +++ b/ui/src/store/modules/user.js @@ -24,7 +24,6 @@ import router from '@/router' import store from '@/store' import { oauthlogin, login, logout, api } from '@/api' import { i18n } from '@/locales' -import { sourceToken } from '@/utils/request' import { ACCESS_TOKEN, diff --git a/utils/src/main/java/com/cloud/utils/HttpUtils.java b/utils/src/main/java/com/cloud/utils/HttpUtils.java index a5d9f6a16b6..cc97bf4ba15 100644 --- a/utils/src/main/java/com/cloud/utils/HttpUtils.java +++ b/utils/src/main/java/com/cloud/utils/HttpUtils.java @@ -37,6 +37,14 @@ public class HttpUtils { public static final String JSON_CONTENT_TYPE = "application/json; charset=UTF-8"; public static final String XML_CONTENT_TYPE = "text/xml; charset=UTF-8"; + public enum ApiSessionKeySameSite { + Lax, Strict, NoneAndSecure, Null + } + + public enum ApiSessionKeyCheckOption { + CookieOrParameter, ParameterOnly, CookieAndParameter + } + public static void addSecurityHeaders(final HttpServletResponse resp) { if (resp.containsHeader("X-Content-Type-Options")) { resp.setHeader("X-Content-Type-Options", "nosniff"); @@ -103,23 +111,43 @@ public class HttpUtils { return null; } - public static boolean validateSessionKey(final HttpSession session, final Map params, final Cookie[] cookies, final String sessionKeyString) { + public static boolean validateSessionKey(final HttpSession session, final Map params, final Cookie[] cookies, final String sessionKeyString, final ApiSessionKeyCheckOption apiSessionKeyCheckLocations) { if (session == null || sessionKeyString == null) { return false; } + final String jsessionidFromCookie = HttpUtils.findCookie(cookies, "JSESSIONID"); + if (jsessionidFromCookie == null + || !(jsessionidFromCookie.startsWith(session.getId() + '.'))) { + s_logger.error("JSESSIONID from cookie is invalid."); + return false; + } final String sessionKey = (String) session.getAttribute(sessionKeyString); + if (sessionKey == null) { + s_logger.error("sessionkey attribute of the session is null."); + return false; + } final String sessionKeyFromCookie = HttpUtils.findCookie(cookies, sessionKeyString); + boolean isSessionKeyFromCookieValid = sessionKeyFromCookie != null && sessionKey.equals(sessionKeyFromCookie); + String[] sessionKeyFromParams = null; if (params != null) { sessionKeyFromParams = (String[]) params.get(sessionKeyString); } - if ((sessionKey == null) - || (sessionKeyFromParams == null && sessionKeyFromCookie == null) - || (sessionKeyFromParams != null && !sessionKey.equals(sessionKeyFromParams[0])) - || (sessionKeyFromCookie != null && !sessionKey.equals(sessionKeyFromCookie))) { - return false; + boolean isSessionKeyFromParamsValid = sessionKeyFromParams != null && sessionKey.equals(sessionKeyFromParams[0]); + + switch (apiSessionKeyCheckLocations) { + case CookieOrParameter: + return (sessionKeyFromCookie != null || sessionKeyFromParams != null) + && (sessionKeyFromCookie == null || isSessionKeyFromCookieValid) + && (sessionKeyFromParams == null || isSessionKeyFromParamsValid); + case ParameterOnly: + return sessionKeyFromParams != null && isSessionKeyFromParamsValid + && (sessionKeyFromCookie == null || isSessionKeyFromCookieValid); + case CookieAndParameter: + default: + return sessionKeyFromCookie != null && isSessionKeyFromCookieValid + && sessionKeyFromParams != null && isSessionKeyFromParamsValid; } - return true; } } diff --git a/utils/src/test/java/com/cloud/utils/HttpUtilsTest.java b/utils/src/test/java/com/cloud/utils/HttpUtilsTest.java index e10a5a36b27..e94724ce3d6 100644 --- a/utils/src/test/java/com/cloud/utils/HttpUtilsTest.java +++ b/utils/src/test/java/com/cloud/utils/HttpUtilsTest.java @@ -60,35 +60,97 @@ public class HttpUtilsTest { final String sessionKeyValue = "randomUniqueSessionID"; // session and sessionKeyString null test - assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); sessionKeyString = "sessionkey"; - assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); // param and cookie null test session = new MockHttpSession(); + final String sessionId = session.getId(); session.setAttribute(sessionKeyString, sessionKeyValue); - assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); - // param null, cookies not null test + // param null, cookies not null test (JSESSIONID is null) params = null; cookies = new Cookie[]{new Cookie(sessionKeyString, sessionKeyValue)}; - assertFalse(HttpUtils.validateSessionKey(session, params, cookies, "randomString")); - assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, "randomString", HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + + // param null, cookies not null test (JSESSIONID is not null and matches) + cookies = new Cookie[2]; + cookies[0] = new Cookie(sessionKeyString, sessionKeyValue); + cookies[1] = new Cookie("JSESSIONID", sessionId + ".node0"); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, "randomString", HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + + // param null, cookies not null test (JSESSIONID is not null but mismatches) + cookies = new Cookie[2]; + cookies[0] = new Cookie(sessionKeyString, sessionKeyValue); + cookies[1] = new Cookie("JSESSIONID", "node0xxxxxxxxxxxxx.node0"); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, "randomString", HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); // param not null, cookies null test params = new HashMap(); params.put(sessionKeyString, new String[]{"randomString"}); cookies = null; - assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); params.put(sessionKeyString, new String[]{sessionKeyValue}); - assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); - // both param and cookies not null test + // both param and cookies not null test (JSESSIONID is null) params = new HashMap(); - cookies = new Cookie[]{new Cookie(sessionKeyString, sessionKeyValue)}; + cookies = new Cookie[2]; + cookies[0] = new Cookie(sessionKeyString, sessionKeyValue); params.put(sessionKeyString, new String[]{"incorrectValue"}); - assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); params.put(sessionKeyString, new String[]{sessionKeyValue}); - assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + + // both param and cookies not null test (JSESSIONID is not null but mismatches) + params = new HashMap(); + cookies = new Cookie[2]; + cookies[0] = new Cookie(sessionKeyString, sessionKeyValue); + cookies[1] = new Cookie("JSESSIONID", "node0xxxxxxxxxxxxx.node0"); + params.put(sessionKeyString, new String[]{"incorrectValue"}); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + params.put(sessionKeyString, new String[]{sessionKeyValue}); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + + // both param and cookies not null test (JSESSIONID is not null amd matches) + params = new HashMap(); + cookies = new Cookie[2]; + cookies[0] = new Cookie(sessionKeyString, sessionKeyValue); + cookies[1] = new Cookie("JSESSIONID", sessionId + ".node0"); + params.put(sessionKeyString, new String[]{"incorrectValue"}); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + params.put(sessionKeyString, new String[]{sessionKeyValue}); + assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + + // param not null, cookies null test (JSESSIONID is not null amd matches) + params = new HashMap(); + cookies = new Cookie[1]; + cookies[0] = new Cookie("JSESSIONID", sessionId + ".node0"); + params.put(sessionKeyString, new String[]{"incorrectValue"}); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.ParameterOnly)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieAndParameter)); + params.put(sessionKeyString, new String[]{sessionKeyValue}); + assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.ParameterOnly)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieAndParameter)); + + // param not null (correct), cookies not null test (correct) + cookies = new Cookie[2]; + cookies[0] = new Cookie(sessionKeyString, sessionKeyValue); + cookies[1] = new Cookie("JSESSIONID", sessionId + ".node0"); + assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.ParameterOnly)); + assertTrue(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieAndParameter)); + + // param not null (correct), cookies not null test (wrong) + cookies = new Cookie[2]; + cookies[0] = new Cookie(sessionKeyString, "incorrectValue"); + cookies[1] = new Cookie("JSESSIONID", sessionId + ".node0"); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieOrParameter)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.ParameterOnly)); + assertFalse(HttpUtils.validateSessionKey(session, params, cookies, sessionKeyString, HttpUtils.ApiSessionKeyCheckOption.CookieAndParameter)); } } From b3f9824be1efffd12ca648748dc59e37f2a0e60f Mon Sep 17 00:00:00 2001 From: Daniel Augusto Veronezi Salvador Date: Tue, 17 Sep 2024 16:08:23 -0300 Subject: [PATCH 08/12] Fix Vue devServer after CSRF fix --- ui/vue.config.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/vue.config.js b/ui/vue.config.js index c74218b4bcf..9cae2ff66fb 100644 --- a/ui/vue.config.js +++ b/ui/vue.config.js @@ -142,7 +142,11 @@ const vueConfig = { secure: false, ws: false, changeOrigin: true, - proxyTimeout: 10 * 60 * 1000 // 10 minutes + proxyTimeout: 10 * 60 * 1000, // 10 minutes + cookieDomainRewrite: '*', + cookiePathRewrite: { + '/client': '/' + } } }, https: process.env.HTTPS_KEY ? { From 18fe4226cecc930ec0b39c43e5b63a48c17c2ad4 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Fri, 4 Oct 2024 11:18:01 +0200 Subject: [PATCH 09/12] Updating pom.xml version numbers for release 4.19.1.2 Signed-off-by: Daan Hoogland --- agent/pom.xml | 2 +- api/pom.xml | 2 +- client/pom.xml | 2 +- core/pom.xml | 2 +- debian/changelog | 6 ++++++ developer/pom.xml | 2 +- engine/api/pom.xml | 2 +- engine/components-api/pom.xml | 2 +- engine/orchestration/pom.xml | 2 +- engine/pom.xml | 2 +- engine/schema/pom.xml | 2 +- engine/service/pom.xml | 2 +- engine/storage/cache/pom.xml | 2 +- engine/storage/configdrive/pom.xml | 2 +- engine/storage/datamotion/pom.xml | 2 +- engine/storage/image/pom.xml | 2 +- engine/storage/integration-test/pom.xml | 2 +- engine/storage/object/pom.xml | 2 +- engine/storage/pom.xml | 2 +- engine/storage/snapshot/pom.xml | 2 +- engine/storage/volume/pom.xml | 2 +- engine/userdata/cloud-init/pom.xml | 2 +- engine/userdata/pom.xml | 2 +- framework/agent-lb/pom.xml | 2 +- framework/ca/pom.xml | 2 +- framework/cluster/pom.xml | 2 +- framework/config/pom.xml | 2 +- framework/db/pom.xml | 2 +- framework/direct-download/pom.xml | 2 +- framework/events/pom.xml | 2 +- framework/ipc/pom.xml | 2 +- framework/jobs/pom.xml | 2 +- framework/managed-context/pom.xml | 2 +- framework/pom.xml | 2 +- framework/quota/pom.xml | 2 +- framework/rest/pom.xml | 2 +- framework/security/pom.xml | 2 +- framework/spring/lifecycle/pom.xml | 2 +- framework/spring/module/pom.xml | 2 +- plugins/acl/dynamic-role-based/pom.xml | 2 +- plugins/acl/project-role-based/pom.xml | 2 +- plugins/acl/static-role-based/pom.xml | 2 +- .../affinity-group-processors/explicit-dedication/pom.xml | 2 +- plugins/affinity-group-processors/host-affinity/pom.xml | 2 +- .../affinity-group-processors/host-anti-affinity/pom.xml | 2 +- .../non-strict-host-affinity/pom.xml | 2 +- .../non-strict-host-anti-affinity/pom.xml | 2 +- plugins/alert-handlers/snmp-alerts/pom.xml | 2 +- plugins/alert-handlers/syslog-alerts/pom.xml | 2 +- plugins/api/discovery/pom.xml | 2 +- plugins/api/rate-limit/pom.xml | 2 +- plugins/api/solidfire-intg-test/pom.xml | 2 +- plugins/api/vmware-sioc/pom.xml | 2 +- plugins/backup/dummy/pom.xml | 2 +- plugins/backup/networker/pom.xml | 2 +- plugins/backup/veeam/pom.xml | 2 +- plugins/ca/root-ca/pom.xml | 2 +- plugins/database/mysql-ha/pom.xml | 2 +- plugins/database/quota/pom.xml | 2 +- plugins/dedicated-resources/pom.xml | 2 +- plugins/deployment-planners/implicit-dedication/pom.xml | 2 +- plugins/deployment-planners/user-concentrated-pod/pom.xml | 2 +- plugins/deployment-planners/user-dispersing/pom.xml | 2 +- plugins/drs/cluster/balanced/pom.xml | 2 +- plugins/drs/cluster/condensed/pom.xml | 2 +- plugins/event-bus/inmemory/pom.xml | 2 +- plugins/event-bus/kafka/pom.xml | 2 +- plugins/event-bus/rabbitmq/pom.xml | 2 +- plugins/ha-planners/skip-heurestics/pom.xml | 2 +- plugins/host-allocators/random/pom.xml | 2 +- plugins/hypervisors/baremetal/pom.xml | 2 +- plugins/hypervisors/hyperv/pom.xml | 2 +- plugins/hypervisors/kvm/pom.xml | 2 +- plugins/hypervisors/ovm/pom.xml | 2 +- plugins/hypervisors/ovm3/pom.xml | 2 +- plugins/hypervisors/simulator/pom.xml | 2 +- plugins/hypervisors/ucs/pom.xml | 2 +- plugins/hypervisors/vmware/pom.xml | 2 +- plugins/hypervisors/xenserver/pom.xml | 2 +- plugins/integrations/cloudian/pom.xml | 2 +- plugins/integrations/kubernetes-service/pom.xml | 2 +- plugins/integrations/prometheus/pom.xml | 2 +- plugins/metrics/pom.xml | 2 +- plugins/network-elements/bigswitch/pom.xml | 2 +- plugins/network-elements/brocade-vcs/pom.xml | 2 +- plugins/network-elements/cisco-vnmc/pom.xml | 2 +- plugins/network-elements/dns-notifier/pom.xml | 2 +- plugins/network-elements/elastic-loadbalancer/pom.xml | 2 +- plugins/network-elements/globodns/pom.xml | 2 +- plugins/network-elements/internal-loadbalancer/pom.xml | 2 +- plugins/network-elements/juniper-contrail/pom.xml | 2 +- plugins/network-elements/netscaler/pom.xml | 2 +- plugins/network-elements/nicira-nvp/pom.xml | 2 +- plugins/network-elements/opendaylight/pom.xml | 2 +- plugins/network-elements/ovs/pom.xml | 2 +- plugins/network-elements/palo-alto/pom.xml | 2 +- plugins/network-elements/stratosphere-ssp/pom.xml | 2 +- plugins/network-elements/tungsten/pom.xml | 2 +- plugins/network-elements/vxlan/pom.xml | 2 +- plugins/outofbandmanagement-drivers/ipmitool/pom.xml | 2 +- .../outofbandmanagement-drivers/nested-cloudstack/pom.xml | 2 +- plugins/outofbandmanagement-drivers/redfish/pom.xml | 2 +- plugins/pom.xml | 2 +- plugins/shutdown/pom.xml | 2 +- plugins/storage-allocators/random/pom.xml | 2 +- plugins/storage/image/default/pom.xml | 2 +- plugins/storage/image/s3/pom.xml | 2 +- plugins/storage/image/sample/pom.xml | 2 +- plugins/storage/image/swift/pom.xml | 2 +- plugins/storage/object/minio/pom.xml | 2 +- plugins/storage/object/simulator/pom.xml | 2 +- plugins/storage/volume/adaptive/pom.xml | 2 +- plugins/storage/volume/cloudbyte/pom.xml | 2 +- plugins/storage/volume/datera/pom.xml | 2 +- plugins/storage/volume/default/pom.xml | 2 +- plugins/storage/volume/flasharray/pom.xml | 2 +- plugins/storage/volume/linstor/pom.xml | 2 +- plugins/storage/volume/nexenta/pom.xml | 2 +- plugins/storage/volume/primera/pom.xml | 2 +- plugins/storage/volume/sample/pom.xml | 2 +- plugins/storage/volume/scaleio/pom.xml | 2 +- plugins/storage/volume/solidfire/pom.xml | 2 +- plugins/storage/volume/storpool/pom.xml | 2 +- plugins/user-authenticators/ldap/pom.xml | 2 +- plugins/user-authenticators/md5/pom.xml | 2 +- plugins/user-authenticators/oauth2/pom.xml | 2 +- plugins/user-authenticators/pbkdf2/pom.xml | 2 +- plugins/user-authenticators/plain-text/pom.xml | 2 +- plugins/user-authenticators/saml2/pom.xml | 2 +- plugins/user-authenticators/sha256salted/pom.xml | 2 +- plugins/user-two-factor-authenticators/static-pin/pom.xml | 2 +- plugins/user-two-factor-authenticators/totp/pom.xml | 2 +- pom.xml | 2 +- quickcloud/pom.xml | 2 +- server/pom.xml | 2 +- services/console-proxy/pom.xml | 2 +- services/console-proxy/rdpconsole/pom.xml | 2 +- services/console-proxy/server/pom.xml | 2 +- services/pom.xml | 2 +- services/secondary-storage/controller/pom.xml | 2 +- services/secondary-storage/pom.xml | 2 +- services/secondary-storage/server/pom.xml | 2 +- systemvm/pom.xml | 2 +- test/pom.xml | 2 +- tools/apidoc/pom.xml | 2 +- tools/checkstyle/pom.xml | 2 +- tools/devcloud-kvm/pom.xml | 2 +- tools/devcloud4/pom.xml | 2 +- tools/marvin/pom.xml | 2 +- tools/pom.xml | 2 +- usage/pom.xml | 2 +- utils/pom.xml | 2 +- vmware-base/pom.xml | 2 +- 153 files changed, 158 insertions(+), 152 deletions(-) diff --git a/agent/pom.xml b/agent/pom.xml index 25c032abf14..b25d246bd91 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/api/pom.xml b/api/pom.xml index cdb4e802c2b..2daba5d2057 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/client/pom.xml b/client/pom.xml index b50a5197bd9..0a098c00fbb 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/core/pom.xml b/core/pom.xml index 31200bcadcd..e3b514e2770 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/debian/changelog b/debian/changelog index d6ac588cba6..524c3891091 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cloudstack (4.19.1.2) unstable; urgency=low + + * Update the version to 4.19.1.2 + + -- the Apache CloudStack project Fri, 04 Oct 2024 11:18:01 +0200 + cloudstack (4.19.1.1) unstable; urgency=low * Update the version to 4.19.1.1 diff --git a/developer/pom.xml b/developer/pom.xml index 6cb64ff1fea..25174bfeb25 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/engine/api/pom.xml b/engine/api/pom.xml index 4ebed0e00be..2654a2ed8d7 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml index de5afd58ff0..651b789dc98 100644 --- a/engine/components-api/pom.xml +++ b/engine/components-api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml index f0ab03017d3..dd4bc8aa510 100755 --- a/engine/orchestration/pom.xml +++ b/engine/orchestration/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/engine/pom.xml b/engine/pom.xml index eeb19798ec1..3720b4d08b6 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml index 4d144ae8d91..04de8a07f88 100644 --- a/engine/schema/pom.xml +++ b/engine/schema/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/engine/service/pom.xml b/engine/service/pom.xml index acfedb5bd06..ba090f2c5b9 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 cloud-engine-service war diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml index be1131d3bfe..773fca373af 100644 --- a/engine/storage/cache/pom.xml +++ b/engine/storage/cache/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/storage/configdrive/pom.xml b/engine/storage/configdrive/pom.xml index 1071fe5ea1a..ddf2bffc183 100644 --- a/engine/storage/configdrive/pom.xml +++ b/engine/storage/configdrive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml index cbb9c66f6e8..6f4a06473f3 100644 --- a/engine/storage/datamotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml index ff4afad2295..0658effcd50 100644 --- a/engine/storage/image/pom.xml +++ b/engine/storage/image/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 1e1d5297488..21a24397985 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/storage/object/pom.xml b/engine/storage/object/pom.xml index 9d4982af506..15e0639b031 100644 --- a/engine/storage/object/pom.xml +++ b/engine/storage/object/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index c98cfe4d297..ae5883aa68d 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index d56fc91c85d..baa581bfc1f 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml index 25f81e9f926..4d1b634461c 100644 --- a/engine/storage/volume/pom.xml +++ b/engine/storage/volume/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/userdata/cloud-init/pom.xml b/engine/userdata/cloud-init/pom.xml index 9c2f92d411a..ece4cad7bf7 100644 --- a/engine/userdata/cloud-init/pom.xml +++ b/engine/userdata/cloud-init/pom.xml @@ -23,7 +23,7 @@ cloud-engine org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/engine/userdata/pom.xml b/engine/userdata/pom.xml index 352a68738b7..77a24f3aa66 100644 --- a/engine/userdata/pom.xml +++ b/engine/userdata/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/agent-lb/pom.xml b/framework/agent-lb/pom.xml index a65e24e2280..c728ccf6e2e 100644 --- a/framework/agent-lb/pom.xml +++ b/framework/agent-lb/pom.xml @@ -24,7 +24,7 @@ cloudstack-framework org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/ca/pom.xml b/framework/ca/pom.xml index e05c55ee65c..7799d1ff262 100644 --- a/framework/ca/pom.xml +++ b/framework/ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index 1dc046cd63f..b3dbc32eda1 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/config/pom.xml b/framework/config/pom.xml index 4f30a6ed2ba..e1da4732f7f 100644 --- a/framework/config/pom.xml +++ b/framework/config/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/db/pom.xml b/framework/db/pom.xml index cc6b82787f3..2dbe24352e7 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/direct-download/pom.xml b/framework/direct-download/pom.xml index 0bdefa91a4d..a21e3e99b6f 100644 --- a/framework/direct-download/pom.xml +++ b/framework/direct-download/pom.xml @@ -32,7 +32,7 @@ cloudstack-framework org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/events/pom.xml b/framework/events/pom.xml index 73219ac1ec2..58b68cf4fb7 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index b9010371438..bc8cf2501e6 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index 93690fd1505..de1cd1e79a4 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml index d40ed883df1..9d14e7aa53e 100644 --- a/framework/managed-context/pom.xml +++ b/framework/managed-context/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/framework/pom.xml b/framework/pom.xml index 7b8bf9f72ec..ab7935d2898 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml index d4a325e94bc..cbc01880426 100644 --- a/framework/quota/pom.xml +++ b/framework/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml index 0119e20a2fd..ca5d9c39beb 100644 --- a/framework/rest/pom.xml +++ b/framework/rest/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml cloud-framework-rest diff --git a/framework/security/pom.xml b/framework/security/pom.xml index 80d596d7407..d565e153e5e 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-framework - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml index 673d9318907..27e6940a77b 100644 --- a/framework/spring/lifecycle/pom.xml +++ b/framework/spring/lifecycle/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index 2174116feb7..ed3668a4b9e 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml index 1bad1036409..3e454a680a4 100644 --- a/plugins/acl/dynamic-role-based/pom.xml +++ b/plugins/acl/dynamic-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/acl/project-role-based/pom.xml b/plugins/acl/project-role-based/pom.xml index 3313467ac29..29160f41d21 100644 --- a/plugins/acl/project-role-based/pom.xml +++ b/plugins/acl/project-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml index 93f80b7c6dc..75f9e3d44c7 100644 --- a/plugins/acl/static-role-based/pom.xml +++ b/plugins/acl/static-role-based/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml index aaea68314a1..364552748e1 100644 --- a/plugins/affinity-group-processors/explicit-dedication/pom.xml +++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/affinity-group-processors/host-affinity/pom.xml b/plugins/affinity-group-processors/host-affinity/pom.xml index fd4dc621395..8ffc7757589 100644 --- a/plugins/affinity-group-processors/host-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml index fe586e3eeff..e2fd7007030 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml b/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml index 344d57f9a4d..1ac2b32d0c8 100644 --- a/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml +++ b/plugins/affinity-group-processors/non-strict-host-affinity/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml b/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml index cd86ae88117..87a53f5b82a 100644 --- a/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/non-strict-host-anti-affinity/pom.xml @@ -32,7 +32,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml index b1353e743b6..da2ff6e7759 100644 --- a/plugins/alert-handlers/snmp-alerts/pom.xml +++ b/plugins/alert-handlers/snmp-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml index 0c3976cc811..f6214e0e8c8 100644 --- a/plugins/alert-handlers/syslog-alerts/pom.xml +++ b/plugins/alert-handlers/syslog-alerts/pom.xml @@ -24,7 +24,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml index 088acb6523d..3d5db00370d 100644 --- a/plugins/api/discovery/pom.xml +++ b/plugins/api/discovery/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index 4bddd771c0a..74651b9cc02 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml index c7e8cb677f5..ef86ad28aa4 100644 --- a/plugins/api/solidfire-intg-test/pom.xml +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/api/vmware-sioc/pom.xml b/plugins/api/vmware-sioc/pom.xml index 1138903aea5..a9c4f5b2fbf 100644 --- a/plugins/api/vmware-sioc/pom.xml +++ b/plugins/api/vmware-sioc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/backup/dummy/pom.xml b/plugins/backup/dummy/pom.xml index 9c0f783f65a..37e23578a8e 100644 --- a/plugins/backup/dummy/pom.xml +++ b/plugins/backup/dummy/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/backup/networker/pom.xml b/plugins/backup/networker/pom.xml index 43a229a0cc2..bef73c3b113 100644 --- a/plugins/backup/networker/pom.xml +++ b/plugins/backup/networker/pom.xml @@ -25,7 +25,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/backup/veeam/pom.xml b/plugins/backup/veeam/pom.xml index 6e3484e447e..50af6e2a8f2 100644 --- a/plugins/backup/veeam/pom.xml +++ b/plugins/backup/veeam/pom.xml @@ -23,7 +23,7 @@ cloudstack-plugins org.apache.cloudstack - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/ca/root-ca/pom.xml b/plugins/ca/root-ca/pom.xml index 749da5566ea..ed848716370 100644 --- a/plugins/ca/root-ca/pom.xml +++ b/plugins/ca/root-ca/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index 875a44fc542..f092b09ce1a 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml index 2f3410af2f7..d5bc0d67f41 100644 --- a/plugins/database/quota/pom.xml +++ b/plugins/database/quota/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml index 4a917c4a7f1..3932a619af5 100644 --- a/plugins/dedicated-resources/pom.xml +++ b/plugins/dedicated-resources/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml index cbd530a15da..d99e8baec99 100644 --- a/plugins/deployment-planners/implicit-dedication/pom.xml +++ b/plugins/deployment-planners/implicit-dedication/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index 065fe546b06..231591a9dac 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index deb6b51231a..cafc155acad 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/drs/cluster/balanced/pom.xml b/plugins/drs/cluster/balanced/pom.xml index 3aa5ed0467f..18970478c8b 100644 --- a/plugins/drs/cluster/balanced/pom.xml +++ b/plugins/drs/cluster/balanced/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/drs/cluster/condensed/pom.xml b/plugins/drs/cluster/condensed/pom.xml index 094f75058d7..b353db228f6 100644 --- a/plugins/drs/cluster/condensed/pom.xml +++ b/plugins/drs/cluster/condensed/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml index 7b107eef601..58d84ea1a20 100644 --- a/plugins/event-bus/inmemory/pom.xml +++ b/plugins/event-bus/inmemory/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml index f76693d2702..05a5a1f8c3d 100644 --- a/plugins/event-bus/kafka/pom.xml +++ b/plugins/event-bus/kafka/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml index e3e2d22f506..9306626672e 100644 --- a/plugins/event-bus/rabbitmq/pom.xml +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml index 54f753e19d1..1286be1092d 100644 --- a/plugins/ha-planners/skip-heurestics/pom.xml +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index 71cecd96250..1aff16f0c4c 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index 7e595ee8fbd..dc121da0b7e 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index e458f42002f..642c5a202f7 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 8772e2067f7..7db4f6e10ef 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index 071da377e8f..4afc662c391 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml index 93bed50f557..cd78cbea4a0 100644 --- a/plugins/hypervisors/ovm3/pom.xml +++ b/plugins/hypervisors/ovm3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml index fb6d76360c7..5d5f0f706ed 100644 --- a/plugins/hypervisors/simulator/pom.xml +++ b/plugins/hypervisors/simulator/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml cloud-plugin-hypervisor-simulator diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index 715ff0badff..13a7cb2f01f 100644 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml cloud-plugin-hypervisor-ucs diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index b8889cbffec..7afb2890682 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index 5e200620338..cd63fc3a018 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/integrations/cloudian/pom.xml b/plugins/integrations/cloudian/pom.xml index 901acb7abc7..812aa06034e 100644 --- a/plugins/integrations/cloudian/pom.xml +++ b/plugins/integrations/cloudian/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/integrations/kubernetes-service/pom.xml b/plugins/integrations/kubernetes-service/pom.xml index bc6d3adfdfb..41afdcc1448 100644 --- a/plugins/integrations/kubernetes-service/pom.xml +++ b/plugins/integrations/kubernetes-service/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/integrations/prometheus/pom.xml b/plugins/integrations/prometheus/pom.xml index f9cad05ac6e..edf42a1ec89 100644 --- a/plugins/integrations/prometheus/pom.xml +++ b/plugins/integrations/prometheus/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml index ac8fbe9e815..690820fa401 100644 --- a/plugins/metrics/pom.xml +++ b/plugins/metrics/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml index 88c661a906d..9cb94602f8a 100644 --- a/plugins/network-elements/bigswitch/pom.xml +++ b/plugins/network-elements/bigswitch/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml index 96193a10575..54a66d00759 100644 --- a/plugins/network-elements/brocade-vcs/pom.xml +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml index 87b8bb5a581..3d7c4ab5e1d 100644 --- a/plugins/network-elements/cisco-vnmc/pom.xml +++ b/plugins/network-elements/cisco-vnmc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml index 0e0f8fe374c..a451da887b8 100644 --- a/plugins/network-elements/dns-notifier/pom.xml +++ b/plugins/network-elements/dns-notifier/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml cloud-plugin-example-dns-notifier diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index dec208cb8d8..cae1d558403 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index 2d4e2e766a4..5ff56fcbcc7 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml index 6dafbb44b05..8a6a1c47b02 100644 --- a/plugins/network-elements/internal-loadbalancer/pom.xml +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 7b623f1df82..76e0a88ba60 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index 8e87e3336ea..9a5d1179a40 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 2c6e4e7544f..17477536062 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index 16567f3fb18..a1e48697a04 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index 1ba739869e4..0e0238a1f3b 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml index 43cf93ad043..e78f6fcfd6a 100644 --- a/plugins/network-elements/palo-alto/pom.xml +++ b/plugins/network-elements/palo-alto/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml index 852591c771c..dd8ef92b24f 100644 --- a/plugins/network-elements/stratosphere-ssp/pom.xml +++ b/plugins/network-elements/stratosphere-ssp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/tungsten/pom.xml b/plugins/network-elements/tungsten/pom.xml index 907063ca987..cdfd5381475 100644 --- a/plugins/network-elements/tungsten/pom.xml +++ b/plugins/network-elements/tungsten/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml index b106aad623e..c255e9f6a71 100644 --- a/plugins/network-elements/vxlan/pom.xml +++ b/plugins/network-elements/vxlan/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml index 26a191a279e..0d662d34609 100644 --- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml +++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml index d90643d331d..3a2451ebd9d 100644 --- a/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml +++ b/plugins/outofbandmanagement-drivers/nested-cloudstack/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/redfish/pom.xml b/plugins/outofbandmanagement-drivers/redfish/pom.xml index d4d1145d24e..5c6d594d51b 100644 --- a/plugins/outofbandmanagement-drivers/redfish/pom.xml +++ b/plugins/outofbandmanagement-drivers/redfish/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/pom.xml b/plugins/pom.xml index 48f79588eb5..3cfaf7569bf 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/plugins/shutdown/pom.xml b/plugins/shutdown/pom.xml index b7ca2e40bac..833fb7b3a60 100644 --- a/plugins/shutdown/pom.xml +++ b/plugins/shutdown/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index 2b62c6e5d3f..a151cf22e54 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index 1925c870dfe..d9ff818c1ca 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index 50c42978b1b..f705f19bded 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index ef728bf7c43..63eb932a209 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index f8124f5ed9d..df8a77b2886 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/object/minio/pom.xml b/plugins/storage/object/minio/pom.xml index a0c803d2e70..5f384406995 100644 --- a/plugins/storage/object/minio/pom.xml +++ b/plugins/storage/object/minio/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/object/simulator/pom.xml b/plugins/storage/object/simulator/pom.xml index a8d83ee547e..f8fa5040db6 100644 --- a/plugins/storage/object/simulator/pom.xml +++ b/plugins/storage/object/simulator/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/adaptive/pom.xml b/plugins/storage/volume/adaptive/pom.xml index e170a730c00..6dd4d340e7b 100644 --- a/plugins/storage/volume/adaptive/pom.xml +++ b/plugins/storage/volume/adaptive/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index 1a2a667e0cf..3d24826fdbd 100644 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/datera/pom.xml b/plugins/storage/volume/datera/pom.xml index f8563f9a8ee..107017e052c 100644 --- a/plugins/storage/volume/datera/pom.xml +++ b/plugins/storage/volume/datera/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml index c5a7e5561b1..b749ccb0f08 100644 --- a/plugins/storage/volume/default/pom.xml +++ b/plugins/storage/volume/default/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/flasharray/pom.xml b/plugins/storage/volume/flasharray/pom.xml index 56f034a954e..f0abeb9a623 100644 --- a/plugins/storage/volume/flasharray/pom.xml +++ b/plugins/storage/volume/flasharray/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/linstor/pom.xml b/plugins/storage/volume/linstor/pom.xml index 7d1c157dc5e..5dcfa1e311c 100644 --- a/plugins/storage/volume/linstor/pom.xml +++ b/plugins/storage/volume/linstor/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml index 5b44b7087e3..93bab1b08ee 100644 --- a/plugins/storage/volume/nexenta/pom.xml +++ b/plugins/storage/volume/nexenta/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/primera/pom.xml b/plugins/storage/volume/primera/pom.xml index cb137fd7480..c088270e788 100644 --- a/plugins/storage/volume/primera/pom.xml +++ b/plugins/storage/volume/primera/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml index 7208076858b..4a2bfe651eb 100644 --- a/plugins/storage/volume/sample/pom.xml +++ b/plugins/storage/volume/sample/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/scaleio/pom.xml b/plugins/storage/volume/scaleio/pom.xml index 96264a2e91f..581d8737c02 100644 --- a/plugins/storage/volume/scaleio/pom.xml +++ b/plugins/storage/volume/scaleio/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml index 80f0d3aed3a..186991de98b 100644 --- a/plugins/storage/volume/solidfire/pom.xml +++ b/plugins/storage/volume/solidfire/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/storage/volume/storpool/pom.xml b/plugins/storage/volume/storpool/pom.xml index ef2cc3eba70..8d7dcde2c19 100644 --- a/plugins/storage/volume/storpool/pom.xml +++ b/plugins/storage/volume/storpool/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../../pom.xml diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index fcffb84c9e7..672856a04fa 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index 69d39f1050a..52ce473916b 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-authenticators/oauth2/pom.xml b/plugins/user-authenticators/oauth2/pom.xml index 18f594166ed..f28425ede94 100644 --- a/plugins/user-authenticators/oauth2/pom.xml +++ b/plugins/user-authenticators/oauth2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml index 663f7eead60..e90b9d9de28 100644 --- a/plugins/user-authenticators/pbkdf2/pom.xml +++ b/plugins/user-authenticators/pbkdf2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index 81a07c47de1..b22c806ba04 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml index 8742800328a..c019af8d629 100644 --- a/plugins/user-authenticators/saml2/pom.xml +++ b/plugins/user-authenticators/saml2/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml index 21d11ebb988..24aac411b10 100644 --- a/plugins/user-authenticators/sha256salted/pom.xml +++ b/plugins/user-authenticators/sha256salted/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-two-factor-authenticators/static-pin/pom.xml b/plugins/user-two-factor-authenticators/static-pin/pom.xml index f494d3898e3..ddbcdc422b0 100644 --- a/plugins/user-two-factor-authenticators/static-pin/pom.xml +++ b/plugins/user-two-factor-authenticators/static-pin/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/plugins/user-two-factor-authenticators/totp/pom.xml b/plugins/user-two-factor-authenticators/totp/pom.xml index b9093d6afab..bc38e002e2b 100644 --- a/plugins/user-two-factor-authenticators/totp/pom.xml +++ b/plugins/user-two-factor-authenticators/totp/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.19.1.1 + 4.19.1.2 ../../pom.xml diff --git a/pom.xml b/pom.xml index e3228e574a9..0d7151527cb 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 pom Apache CloudStack Apache CloudStack is an IaaS ("Infrastructure as a Service") cloud orchestration platform. diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml index 7f81244db09..325fb7ff85a 100644 --- a/quickcloud/pom.xml +++ b/quickcloud/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/server/pom.xml b/server/pom.xml index 09d8ee309c9..a1187b426aa 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index 02ee2921d2a..2fa22292d6f 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/services/console-proxy/rdpconsole/pom.xml b/services/console-proxy/rdpconsole/pom.xml index 0d74b451474..3858a78d460 100644 --- a/services/console-proxy/rdpconsole/pom.xml +++ b/services/console-proxy/rdpconsole/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index 48024431a8d..99b9fea1bf7 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/services/pom.xml b/services/pom.xml index 24169e8778d..ffa61f12cb2 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml index c0dfb9e79ca..393e3604784 100644 --- a/services/secondary-storage/controller/pom.xml +++ b/services/secondary-storage/controller/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index a5a35c63c88..22db68a7983 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-services - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml index fa6d40782a3..30fd233cd5f 100644 --- a/services/secondary-storage/server/pom.xml +++ b/services/secondary-storage/server/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/systemvm/pom.xml b/systemvm/pom.xml index 4d742ad7a00..f0b330643c1 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/test/pom.xml b/test/pom.xml index 7a68fcdcef1..eff245bc38a 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml index 20196a42614..afefac3a74b 100644 --- a/tools/apidoc/pom.xml +++ b/tools/apidoc/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index fa4122d0391..d4a7743e9c6 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -22,7 +22,7 @@ Apache CloudStack Developer Tools - Checkstyle Configuration org.apache.cloudstack checkstyle - 4.19.1.1 + 4.19.1.2 UTF-8 diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml index 1fbb630eff8..2bb84f2ba38 100644 --- a/tools/devcloud-kvm/pom.xml +++ b/tools/devcloud-kvm/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml index d6ccfa14245..b7f3a39be22 100644 --- a/tools/devcloud4/pom.xml +++ b/tools/devcloud4/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 94adc211b51..94ded408c9b 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloud-tools - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/tools/pom.xml b/tools/pom.xml index 67ab345b527..2923919b4dd 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/usage/pom.xml b/usage/pom.xml index cca3c59d49f..36dee654a93 100644 --- a/usage/pom.xml +++ b/usage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 diff --git a/utils/pom.xml b/utils/pom.xml index 8d3b6863c22..c585d586056 100755 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 ../pom.xml diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index 958a461ee40..27bf264c364 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.19.1.1 + 4.19.1.2 From d6181d542108d02cca31daa758234bb29e1b317a Mon Sep 17 00:00:00 2001 From: Lucas Martins <56271185+lucas-a-martins@users.noreply.github.com> Date: Fri, 4 Oct 2024 16:41:30 -0300 Subject: [PATCH 10/12] Fix `updateTemplatePermission` when the UI is set to a language other than English (#9766) * Fix updateTemplatePermission UI in non-english language * Improve fix --------- Co-authored-by: Lucas Martins --- ui/public/locales/pt_BR.json | 4 ++-- .../image/UpdateTemplateIsoPermissions.vue | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index f02aee747eb..6955d83a510 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -1482,8 +1482,8 @@ "label.setting": "Configura\u00e7\u00e3o", "label.settings": "Configura\u00e7\u00f5es", "label.setup": "Configura\u00e7\u00e3o", -"label.shared": "Compatilhado", -"label.sharedexecutable": "Compatilhado", +"label.shared": "Compartilhado", +"label.sharedexecutable": "Compartilhado", "label.sharedmountpoint": "SharedMountPoint", "label.sharedrouterip": "Endere\u00e7os IPv4 para o roteador dentro da rede compartilhada", "label.sharedrouteripv6": "Endere\u00e7os IPv6 para o roteador dentro da rede compartilhada", diff --git a/ui/src/views/image/UpdateTemplateIsoPermissions.vue b/ui/src/views/image/UpdateTemplateIsoPermissions.vue index c7b0f9e5cf1..557574156b1 100644 --- a/ui/src/views/image/UpdateTemplateIsoPermissions.vue +++ b/ui/src/views/image/UpdateTemplateIsoPermissions.vue @@ -25,7 +25,7 @@

{{ $t('label.operation') }}

- {{ $t('label.add') }} - {{ $t('label.remove') }} - {{ $t('label.reset') }} + {{ $t('label.add') }} + {{ $t('label.remove') }} + {{ $t('label.reset') }} -