Skip to content

Commit

Permalink
Merge pull request #499 from eclipse-passage/567032-4
Browse files Browse the repository at this point in the history
Bug 567032 issue floating license configuration wizard
  • Loading branch information
eparovyshnaya authored Oct 27, 2020
2 parents 60fb58e + 4565dc2 commit aa1d87c
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 209 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,10 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="0.0.0";x-installation:=
org.eclipse.emf.ecore;bundle-version="0.0.0";visibility:=reexport,
org.eclipse.passage.lic.emf.meta;bundle-version="0.6.0",
org.eclipse.passage.lic.floating;bundle-version="0.0.0";visibility:=reexport
Export-Package: org.eclipse.passage.lic.floating.model.api;
x-friends:="org.eclipse.passage.lic.floating.edit",
Export-Package: org.eclipse.passage.lic.floating.model.api;x-friends:="org.eclipse.passage.lic.floating.edit,org.eclipse.passage.loc.dashboard.ui,org.eclipse.passage.loc.api",
org.eclipse.passage.lic.floating.model.impl;x-internal:=true,
org.eclipse.passage.lic.floating.model.meta;
x-friends:="org.eclipse.passage.lic.floating.e4.ui,
org.eclipse.passage.lic.floating.edit",
org.eclipse.passage.lic.floating.model.util;
x-friends:="org.eclipse.passage.lic.floating.edit",
org.eclipse.passage.lic.internal.floating.model;
x-friends:="org.eclipse.passage.loc.dashboard.ui"
org.eclipse.passage.lic.floating.model.meta;x-friends:="org.eclipse.passage.lic.floating.e4.ui,org.eclipse.passage.lic.floating.edit",
org.eclipse.passage.lic.floating.model.util;x-friends:="org.eclipse.passage.lic.floating.edit",
org.eclipse.passage.lic.internal.floating.model;x-friends:="org.eclipse.passage.loc.dashboard.ui"
Bundle-ClassPath: .
Bundle-ActivationPolicy: lazy
3 changes: 2 additions & 1 deletion bundles/org.eclipse.passage.loc.api/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ Require-Bundle: org.eclipse.e4.core.services;bundle-version="0.0.0",
org.eclipse.passage.lic.licenses;bundle-version="1.0.0";visibility:=reexport,
org.eclipse.passage.lic.products;bundle-version="1.0.0";visibility:=reexport,
org.eclipse.passage.lic.users;bundle-version="1.0.0";visibility:=reexport,
org.eclipse.passage.lic.users.model;bundle-version="1.0.0"
org.eclipse.passage.lic.users.model;bundle-version="1.0.0",
org.eclipse.passage.lic.floating.model;bundle-version="0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*******************************************************************************
* Copyright (c) 2020 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.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Supplier;

import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.passage.lic.emf.ecore.LicensingEcore;
import org.eclipse.passage.lic.internal.api.LicensedProduct;
import org.eclipse.passage.lic.internal.api.ServiceInvocationResult;
import org.eclipse.passage.lic.internal.api.diagnostic.Trouble;
import org.eclipse.passage.lic.internal.api.io.StreamCodec;
import org.eclipse.passage.lic.internal.base.BaseLicensedProduct;
import org.eclipse.passage.lic.internal.base.BaseServiceInvocationResult;
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.lic.internal.licenses.model.AssignGrantIdentifiers;
import org.eclipse.passage.lic.licenses.model.api.LicensePack;
import org.eclipse.passage.lic.licenses.model.meta.LicensesPackage;
import org.eclipse.passage.lic.products.ProductVersionDescriptor;
import org.eclipse.passage.lic.users.UserDescriptor;
import org.eclipse.passage.lic.users.model.api.User;
import org.eclipse.passage.lic.users.model.api.UserLicense;
import org.eclipse.passage.lic.users.model.meta.UsersFactory;
import org.eclipse.passage.lic.users.model.meta.UsersPackage;
import org.eclipse.passage.loc.internal.api.CodecSupplier;
import org.eclipse.passage.loc.internal.api.IssuedLicense;
import org.eclipse.passage.loc.internal.api.OperatorEvents;
import org.eclipse.passage.loc.internal.api.OperatorLicenseEvents;
import org.eclipse.passage.loc.internal.api.OperatorProductService;
import org.eclipse.passage.loc.internal.api.PersonalLicenseRequest;
import org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages;
import org.eclipse.passage.loc.internal.licenses.trouble.code.LicenseIssuingFailed;
import org.eclipse.passage.loc.internal.licenses.trouble.code.LicenseIssuingIsPartial;
import org.eclipse.passage.loc.internal.licenses.trouble.code.LicenseValidationFailed;
import org.eclipse.passage.loc.internal.products.ProductRegistry;
import org.eclipse.passage.loc.internal.users.UserRegistry;
import org.eclipse.passage.loc.internal.users.UserRegistryEvents;
import org.osgi.service.event.EventAdmin;

@SuppressWarnings("restriction")
final class IssuePersonalLicense {

private final UserRegistry users;
private final ProductRegistry products;
private final OperatorProductService operator;
private final EventAdmin events;

IssuePersonalLicense(UserRegistry users, ProductRegistry products, OperatorProductService operator,
EventAdmin events) {
this.users = users;
this.products = products;
this.operator = operator;
this.events = events;
}

ServiceInvocationResult<IssuedLicense> issue(PersonalLicenseRequest request, Supplier<LicensePack> template) {
LicensePack license = EcoreUtil.copy(template.get());
String errors = LicensingEcore.extractValidationError(license);
if (errors != null) {
return new BaseServiceInvocationResult<>(new Trouble(new LicenseValidationFailed(), errors));
}
LicensedProduct product = new BaseLicensedProduct(license.getProductIdentifier(), license.getProductVersion());
Date issueDate = new Date();
license.setIdentifier(UUID.randomUUID().toString());
license.setIssueDate(issueDate);
new AssignGrantIdentifiers().accept(license);
String userIdentifier = license.getUserIdentifier();
UserDescriptor userDescriptor = users.getUser(userIdentifier);
Map<String, Object> attachments = new HashMap<String, Object>();
UserLicense userLicense = null;
if (userDescriptor instanceof User) {
User user = (User) userDescriptor;
String conditionType = userDescriptor.getPreferredConditionType();
String expression = userDescriptor.getPreferredConditionExpression();
userLicense = UsersFactory.eINSTANCE.createUserLicense();
userLicense.setPackIdentifier(license.getIdentifier());
userLicense.setIssueDate(issueDate);
userLicense.setPlanIdentifier(request.plan());
userLicense.setValidFrom(request.validFrom());
userLicense.setValidUntil(request.validUntil());
userLicense.setConditionExpression(expression);
userLicense.setConditionType(conditionType);
userLicense.setProductIdentifier(product.identifier());
userLicense.setProductVersion(product.version());
if (users instanceof IEditingDomainProvider) {
IEditingDomainProvider edp = (IEditingDomainProvider) users;
EditingDomain editingDomain = edp.getEditingDomain();
EReference structured = UsersPackage.eINSTANCE.getUser_UserLicenses();
CommandStack stack = editingDomain.getCommandStack();
stack.execute(AddCommand.create(editingDomain, user, structured, userLicense));
} else {
user.getUserLicenses().add(userLicense);
}
events.postEvent(OperatorEvents.create(UserRegistryEvents.USER_LICENSE_CREATE, userLicense));
try {
// FIXME: define parameters
user.eResource().save(null);
attachments.put(userLicense.eClass().getName(), userLicense);
} catch (IOException e) {
return new BaseServiceInvocationResult<>(new Trouble(new LicenseIssuingFailed(),
LicensesCoreMessages.LicenseOperatorServiceImpl_error_io, e));
}
}
Path path = new UserHomeProductResidence(product).get();
Path decrypted = path.resolve(license.getIdentifier() + new PassageFileExtension.LicenseDecrypted().get());
URI uri = URI.createFileURI(decrypted.toString());
ResourceSet resourceSet = new ResourceSetImpl();
Resource resource = resourceSet.createResource(uri);
resource.getContents().add(license);
try {
resource.save(null);
events.postEvent(OperatorLicenseEvents.decodedIssued(decrypted.toString()));
} catch (IOException e) {
return new BaseServiceInvocationResult<>(new Trouble(new LicenseIssuingFailed(),
LicensesCoreMessages.LicenseOperatorServiceImpl_failed_to_save_decoded, e));
}

Optional<StreamCodec> codec = codec(product);
if (!codec.isPresent()) {
return new BaseServiceInvocationResult<>(new Trouble(new LicenseIssuingIsPartial(), //
String.format(LicensesCoreMessages.LicenseOperatorServiceImpl_w_no_encoding, decrypted)));
}

Path privateKeyPath = path.resolve(//
new FileNameFromLicensedProduct(product, new PassageFileExtension.PrivateKey()).get());
File privateProductToken = privateKeyPath.toFile();
if (!privateProductToken.exists()) {
String pattern = LicensesCoreMessages.LicenseOperatorServiceImpl_private_key_not_found;
String message = String.format(pattern, privateProductToken.getAbsolutePath());
return new BaseServiceInvocationResult<>(new Trouble(new LicenseIssuingFailed(), message));
}

Path encrypted = path.resolve(license.getIdentifier() + new PassageFileExtension.LicenseEncrypted().get());
File licenseEncoded = encrypted.toFile();
try (FileInputStream licenseInput = new FileInputStream(decrypted.toFile());
FileOutputStream licenseOutput = new FileOutputStream(licenseEncoded);
FileInputStream keyStream = new FileInputStream(privateProductToken)) {
String username = product.identifier();
ProductVersionDescriptor pvd = products.getProductVersion(product.identifier(), product.version());
String password = operator.createPassword(pvd);
codec.get().encode(licenseInput, licenseOutput, keyStream, username, password);
events.postEvent(OperatorLicenseEvents.encodedIssued(encrypted.toString()));
attachments.put(LicensesPackage.eNAME, encrypted);
return new BaseServiceInvocationResult<>(new BaseIssuedLicense(userLicense, encrypted, decrypted));
} catch (Exception e) {
return new BaseServiceInvocationResult<>(//
new Trouble(//
new LicenseIssuingFailed(), //
LicensesCoreMessages.LicenseOperatorServiceImpl_export_error, e));
}
}

private Optional<StreamCodec> codec(LicensedProduct product) {
return new CodecSupplier(product).get();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2020 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.util.function.Supplier;

import org.eclipse.passage.lic.licenses.LicensePlanFeatureDescriptor;
import org.eclipse.passage.lic.licenses.model.api.LicenseGrant;
import org.eclipse.passage.lic.licenses.model.meta.LicensesFactory;
import org.eclipse.passage.loc.internal.api.PersonalLicenseRequest;

final class LicenseGrantFromRequest implements Supplier<LicenseGrant> {

private final LicensePlanFeatureDescriptor feature;
private final PersonalLicenseRequest request;

public LicenseGrantFromRequest(LicensePlanFeatureDescriptor feature, PersonalLicenseRequest request) {
this.feature = feature;
this.request = request;
}

@Override
public LicenseGrant get() {
LicensesFactory licenseFactory = LicensesFactory.eINSTANCE;
LicenseGrant grant = licenseFactory.createLicenseGrant();
grant.setFeatureIdentifier(feature.getFeatureIdentifier());
grant.setMatchVersion(feature.getMatchVersion());
grant.setMatchRule(feature.getMatchRule());
grant.setCapacity(1);
grant.setConditionExpression(request.conditionExpression());
grant.setConditionType(request.conditionType());
grant.setValidFrom(request.validFrom());
grant.setValidUntil(request.validUntil());
return grant;
}

}
Loading

0 comments on commit aa1d87c

Please sign in to comment.