diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssueFloatingLicense.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssueFloatingLicense.java index 80d3276d1..c56e3143a 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssueFloatingLicense.java +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/IssueFloatingLicense.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 ArSysOp + * Copyright (c) 2020, 2021 ArSysOp * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -12,11 +12,15 @@ *******************************************************************************/ package org.eclipse.passage.loc.internal.licenses.core; +import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.BinaryOperator; import org.eclipse.emf.ecore.EObject; import org.eclipse.passage.lic.emf.ecore.LicensingEcore; @@ -57,13 +61,16 @@ ServiceInvocationResult issue(FloatingLicensePack pack, Path residence = residence(pack.getLicense()); ServiceInvocationResult> license = // persist(pack, product, residence, decryptedFile(pack), encryptedFile(pack)); - ServiceInvocationResult> files = configs.stream()// + BinaryOperator>> sum = new BaseServiceInvocationResult.Sum<>( + new SumOfLists()); + ServiceInvocationResult> withConfigs = configs.stream()// .map(access -> persist(access, product, residence, decryptedFile(access), encryptedFile(access)))// - .reduce(license, new BaseServiceInvocationResult.Sum<>(new SumOfLists())); - if (!new NoSevereErrors().test(files.diagnostic())) { - return new BaseServiceInvocationResult<>(files.diagnostic()); + .reduce(license, sum); + ServiceInvocationResult> withKey = sum.apply(withConfigs, replicateKey(product, residence)); + if (!new NoSevereErrors().test(withKey.diagnostic())) { + return new BaseServiceInvocationResult<>(withKey.diagnostic()); } - return new BaseServiceInvocationResult<>(new BaseIssuedFloatingLicense(residence, files.data().get())); + return new BaseServiceInvocationResult<>(new BaseIssuedFloatingLicense(residence, withKey.data().get())); } private ServiceInvocationResult> persist(EObject target, LicensedProduct product, // @@ -87,11 +94,23 @@ private ServiceInvocationResult> persist(EObject target, LicensedProd licen = new PersistedEncoded(product, lic, new ProductPassword(products, operator)).write(encrypted); } catch (LicensingException e) { return new BaseServiceInvocationResult<>(new Trouble(new LicenseIssuingFailed(), // - LicensesCoreMessages.LicenseOperatorServiceImpl_floating_save_decoded_failed, e)); + LicensesCoreMessages.LicenseOperatorServiceImpl_floating_save_encoded_failed, e)); } return new BaseServiceInvocationResult<>(Arrays.asList(lic, licen)); } + private ServiceInvocationResult> replicateKey(LicensedProduct product, Path folder) { + // copy product public key + Path key; + try { + key = copyPlainFile(new ProductKeyFile(product).pub(), folder); + } catch (Exception e) { + return new BaseServiceInvocationResult<>(new Trouble(new LicenseIssuingFailed(), // + LicensesCoreMessages.LicenseOperatorServiceImpl_floating_save_product_key, e)); + } + return new BaseServiceInvocationResult<>(Collections.singletonList(key)); + } + private Path residence(LicenseRequisites license) { return new UserHomeProductResidence(// license.getProduct().getProduct(), // @@ -100,9 +119,14 @@ private Path residence(LicenseRequisites license) { .resolve(license.getIdentifier()); } + private Path copyPlainFile(Path origin, Path folder) throws IOException { + Path destination = folder.resolve(origin.getFileName().toString()); + Files.copy(origin, destination); + return destination; + } + private LicensedProduct product(ProductRef ref) { return new BaseLicensedProduct(ref.getProduct(), ref.getVersion()); - } private String decryptedFile(FloatingLicensePack pack) { diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/PersistedEncoded.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/PersistedEncoded.java index 3dfba7dea..b5211058d 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/PersistedEncoded.java +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/PersistedEncoded.java @@ -15,7 +15,6 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; import java.util.function.Function; @@ -23,9 +22,6 @@ import org.eclipse.passage.lic.internal.api.LicensedProduct; import org.eclipse.passage.lic.internal.api.LicensingException; import org.eclipse.passage.lic.internal.api.io.StreamCodec; -import org.eclipse.passage.lic.internal.base.io.FileNameFromLicensedProduct; -import org.eclipse.passage.lic.internal.base.io.PassageFileExtension; -import org.eclipse.passage.lic.internal.base.io.UserHomeProductResidence; import org.eclipse.passage.loc.internal.equinox.OperatorGearAware; import org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages; @@ -57,14 +53,7 @@ Path write(String file) throws LicensingException { } private Path key() throws LicensingException { - Path key = new UserHomeProductResidence(product).get() - .resolve(new FileNameFromLicensedProduct(product, new PassageFileExtension.PrivateKey()).get()); - if (!Files.exists(key)) { - throw new LicensingException(String.format(// - LicensesCoreMessages.LicenseOperatorServiceImpl_private_key_not_found, key.toAbsolutePath())); - } - return key; - + return new ProductKeyFile(product).scr(); } private StreamCodec codec() throws LicensingException { diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/ProductKeyFile.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/ProductKeyFile.java new file mode 100644 index 000000000..98f181a03 --- /dev/null +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/ProductKeyFile.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2021 ArSysOp + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0/. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * ArSysOp - initial API and implementation + *******************************************************************************/ +package org.eclipse.passage.loc.internal.licenses.core; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.passage.lic.internal.api.LicensedProduct; +import org.eclipse.passage.lic.internal.api.LicensingException; +import org.eclipse.passage.lic.internal.base.io.FileNameFromLicensedProduct; +import org.eclipse.passage.lic.internal.base.io.PassageFileExtension; +import org.eclipse.passage.lic.internal.base.io.UserHomeProductResidence; +import org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages; + +final class ProductKeyFile { + + private final LicensedProduct product; + + ProductKeyFile(LicensedProduct product) { + this.product = product; + } + + Path scr() throws LicensingException { + return get(// + new PassageFileExtension.PrivateKey(), // + LicensesCoreMessages.LicenseOperatorServiceImpl_private_key_not_found); + } + + Path pub() throws LicensingException { + return get(// + new PassageFileExtension.PublicKey(), // + LicensesCoreMessages.LicenseOperatorServiceImpl_public_key_not_found); + } + + private Path get(PassageFileExtension ext, String error) throws LicensingException { + Path key = new UserHomeProductResidence(product).get() + .resolve(new FileNameFromLicensedProduct(product, ext).get()); + if (!Files.exists(key)) { + throw new LicensingException(String.format(error, key.toAbsolutePath())); + } + return key; + } + +} diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java index 559ea97df..09c50a18b 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2020 ArSysOp and others + * Copyright (c) 2019, 2021 ArSysOp and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -15,14 +15,17 @@ import org.eclipse.osgi.util.NLS; -public class LicensesCoreMessages extends NLS { +public final class LicensesCoreMessages extends NLS { + private static final String BUNDLE_NAME = "org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages"; //$NON-NLS-1$ + public static String EmfObjectPersisted_failed; public static String LicenseOperatorServiceImpl_error_io; public static String LicenseOperatorServiceImpl_export_error; public static String LicenseOperatorServiceImpl_export_success; public static String LicenseOperatorServiceImpl_failed_to_save_decoded; public static String LicenseOperatorServiceImpl_private_key_not_found; + public static String LicenseOperatorServiceImpl_public_key_not_found; public static String LicenseOperatorServiceImpl_status_invalid_licensing_request; public static String LicenseOperatorServiceImpl_w_no_encoding; public static String LicensesSelectionCommandAdvisor_select_lic_plan; @@ -45,7 +48,9 @@ public class LicensesCoreMessages extends NLS { public static String LicenseOperatorServiceImpl_floating_no_codec; public static String LicenseOperatorServiceImpl_floating_save_decoded_failed; public static String LicenseOperatorServiceImpl_floating_save_encoded_failed; + public static String LicenseOperatorServiceImpl_floating_save_product_key; public static String LicenseOperatorServiceImpl_floating_save_encoded_file_error; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, LicensesCoreMessages.class); diff --git a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties index 5dd4ac850..46237662e 100644 --- a/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties +++ b/bundles/org.eclipse.passage.loc.licenses.core/src/org/eclipse/passage/loc/internal/licenses/core/i18n/LicensesCoreMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2019, 2020 ArSysOp and others +# Copyright (c) 2019, 2021 ArSysOp and others # # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at @@ -18,6 +18,7 @@ LicenseOperatorServiceImpl_export_error=License Pack export error LicenseOperatorServiceImpl_export_success=License pack exported successfully: \n\n %s \n LicenseOperatorServiceImpl_failed_to_save_decoded=Failed on decoded license file saving LicenseOperatorServiceImpl_private_key_not_found=Product private key not found: \n %s +LicenseOperatorServiceImpl_public_key_not_found=Product public key not found: \n %s LicenseOperatorServiceImpl_status_invalid_licensing_request=Invalid Licensing Request LicenseOperatorServiceImpl_w_no_encoding=License Pack has been exported without encoding: \n\n %s \n LicensesSelectionCommandAdvisor_select_lic_plan=Select License Plan @@ -40,4 +41,5 @@ LicenseRequest_error_attachment_not_exist=The mail attachment does not exist LicenseOperatorServiceImpl_floating_no_codec=Failed to issue floating license pack as there is no codec found for the product %s LicenseOperatorServiceImpl_floating_save_decoded_failed=Failed to persist decoded floating license / access file LicenseOperatorServiceImpl_floating_save_encoded_failed=Failed to persist encoded floating license / access file +LicenseOperatorServiceImpl_floating_save_product_key=Failed to deliver product public key LicenseOperatorServiceImpl_floating_save_encoded_file_error=Failed to persist encoded file %s