Skip to content

Commit

Permalink
Bug 567032 issue floating license configuration wizard
Browse files Browse the repository at this point in the history
 Rework existing LicenseOperatorService to extend it with floating
license issuing.

Signed-off-by: eparovyshnaya <[email protected]>
  • Loading branch information
eparovyshnaya committed Oct 27, 2020
1 parent 60fb58e commit ef49998
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 ef49998

Please sign in to comment.