Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

572833 protect the product with common-use license #742

Merged
merged 2 commits into from
Apr 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
Expand All @@ -39,10 +40,12 @@
import org.eclipse.passage.lic.licenses.model.api.FloatingLicensePack;
import org.eclipse.passage.lic.licenses.model.api.LicenseRequisites;
import org.eclipse.passage.lic.licenses.model.api.ProductRef;
import org.eclipse.passage.lic.licenses.model.api.UserGrant;
import org.eclipse.passage.loc.internal.api.IssuedFloatingLicense;
import org.eclipse.passage.loc.internal.api.OperatorProductService;
import org.eclipse.passage.loc.internal.licenses.LicenseRegistry;
import org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages;
import org.eclipse.passage.loc.internal.licenses.core.issue.FloatingLicenseIssuingProtection;
import org.eclipse.passage.loc.internal.licenses.trouble.code.LicenseIssuingFailed;
import org.eclipse.passage.loc.internal.licenses.trouble.code.LicenseValidationFailed;
import org.eclipse.passage.loc.internal.products.ProductRegistry;
Expand All @@ -62,13 +65,25 @@ final class IssueFloatingLicense {

ServiceInvocationResult<IssuedFloatingLicense> issue(FloatingLicensePack pack,
Collection<FloatingLicenseAccess> configs) {
FloatingLicensePack license = shielded(EcoreUtil.copy(pack), configs);
try {
new UpdateLicensePlan(licenses).withFloating(EcoreUtil.copy(pack));
new UpdateLicensePlan(licenses).withFloating(license);
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved
} catch (IOException e) {
return new BaseServiceInvocationResult<>(new Trouble(new LicenseIssuingFailed(),
LicensesCoreMessages.LicenseOperatorServiceImpl_error_io, e));
}
return persistLicenseFiles(EcoreUtil.copy(pack), configs);
return persistLicenseFiles(EcoreUtil.copy(license), configs);
}

private FloatingLicensePack shielded(FloatingLicensePack pack, Collection<FloatingLicenseAccess> configs) {
new FloatingLicenseIssuingProtection().accept(pack);
Collection<String> users = pack.getUsers().stream()//
.map(UserGrant::getUser)//
.collect(Collectors.toSet());
Collection<FloatingLicenseAccess> redundant = configs.stream()//
.filter(c -> !users.contains(c.getUser())).collect(Collectors.toSet());
configs.removeAll(redundant);
return pack;
}

private ServiceInvocationResult<IssuedFloatingLicense> persistLicenseFiles(FloatingLicensePack pack,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.eclipse.passage.loc.internal.api.OperatorProductService;
import org.eclipse.passage.loc.internal.licenses.LicenseRegistry;
import org.eclipse.passage.loc.internal.licenses.core.i18n.LicensesCoreMessages;
import org.eclipse.passage.loc.internal.licenses.core.issue.PersonalLicenseIssuingProtection;
import org.eclipse.passage.loc.internal.licenses.trouble.code.LicenseIssuingFailed;
import org.eclipse.passage.loc.internal.licenses.trouble.code.LicenseValidationFailed;
import org.eclipse.passage.loc.internal.products.ProductRegistry;
Expand Down Expand Up @@ -70,6 +71,7 @@ ServiceInvocationResult<IssuedLicense> issue(Supplier<LicensePack> template) {
}
LicensedProduct product = new BaseLicensedProduct(license.getProductIdentifier(), license.getProductVersion());
Path path = new UserHomeProductResidence(product).get();

Path decrypted;
try {
decrypted = new PersistedDecoded(path, license)//
Expand Down Expand Up @@ -97,6 +99,7 @@ private LicensePack adjsut(LicensePack license) {
license.setIdentifier(UUID.randomUUID().toString());
license.setIssueDate(issueDate);
new AssignGrantIdentifiers().accept(license);
new PersonalLicenseIssuingProtection().accept(license);
return license;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*******************************************************************************
* 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.issue;

import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;

import org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed;
import org.eclipse.passage.lic.internal.base.conditions.BaseValidityPeriodClosed;

final class ClosedValidityPeriodReduction<L> implements Reduction<L> {

private final Function<L, Optional<ValidityPeriodClosed>> get;
private final BiConsumer<L, ValidityPeriodClosed> set;
private final int length = 1;

ClosedValidityPeriodReduction(Function<L, Optional<ValidityPeriodClosed>> get, BiConsumer<L, ValidityPeriodClosed> set) {
this.get = get;
this.set = set;
}

@Override
public void accept(L license) {
Optional<ValidityPeriodClosed> valid = get.apply(license);
if (!valid.isPresent()) {
return;
}
ZonedDateTime allowed = allowed(valid.get().from());
if (allowed.isBefore(valid.get().to())) {
set.accept(license, new BaseValidityPeriodClosed(valid.get().from(), allowed));
}
}

private ZonedDateTime allowed(ZonedDateTime from) {
return from.plus(length, ChronoUnit.MONTHS);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* 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.issue;

import org.eclipse.passage.lic.licenses.model.api.FeatureGrant;

@SuppressWarnings("restriction")
final class FeatureGrantCapacityReduction implements Reduction<FeatureGrant> {

private final int capacity = 3;

@Override
public void accept(FeatureGrant grant) {
grant.setCapacity(Math.min(capacity, grant.getCapacity()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*******************************************************************************
* 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.issue;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

import org.eclipse.passage.lic.internal.base.conditions.BaseValidityPeriodClosed;
import org.eclipse.passage.lic.internal.equinox.EquinoxPassage;
import org.eclipse.passage.lic.licenses.model.api.FeatureGrant;
import org.eclipse.passage.lic.licenses.model.api.FloatingLicensePack;
import org.eclipse.passage.lic.licenses.model.api.ValidityPeriod;
import org.eclipse.passage.lic.licenses.model.api.ValidityPeriodClosed;
import org.eclipse.passage.lic.licenses.model.meta.LicensesFactory;

@SuppressWarnings("restriction")
public final class FloatingLicenseIssuingProtection implements Consumer<FloatingLicensePack> {

private final String feature = "org.eclipse.passage.loc.operator.issue.floating.full"; //$NON-NLS-1$
private final List<Reduction<FeatureGrant>> featureReductions;
private final List<Reduction<FloatingLicensePack>> licReductions;

public FloatingLicenseIssuingProtection() {
this.featureReductions = Arrays.asList(//
new ClosedValidityPeriodReduction<FeatureGrant>(this::validGet, this::validSet), //
new FeatureGrantCapacityReduction()//
);
this.licReductions = Arrays.asList(//
new ClosedValidityPeriodReduction<FloatingLicensePack>(this::validGet, this::validSet), //
new UserGrantsAmountReduction()//
);
}

@Override
public void accept(FloatingLicensePack license) {
if (new EquinoxPassage().canUse(feature)) {
return;
}
// TODO: log diminishing
diminish(license);
}

private void diminish(FloatingLicensePack license) {
diminishFeatureGrants(license);
diminishLicense(license);
}

private void diminishFeatureGrants(FloatingLicensePack license) {
license.getFeatures().forEach(this::diminishGrant);
}

private void diminishLicense(FloatingLicensePack lic) {
licReductions.forEach(r -> r.accept(lic));
}

private void diminishGrant(FeatureGrant grant) {
featureReductions.forEach(r -> r.accept(grant));
}

private Optional<org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed> validGet(
FloatingLicensePack lic) {
return validGet(lic.getLicense().getValid());
}

private Optional<org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed> validGet(
FeatureGrant grant) {
return validGet(grant.getValid());
}

private Optional<org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed> validGet(
ValidityPeriod period) {
if (!(period instanceof ValidityPeriodClosed)) {
return Optional.empty(); // nothing we can reduce for now
}
ValidityPeriodClosed closed = (ValidityPeriodClosed) period;
return Optional.of(new BaseValidityPeriodClosed(date(closed.getFrom()), date(closed.getUntil())));
}

private void validSet(FloatingLicensePack lic,
org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed period) {
lic.getLicense().setValid(convert(period));
}

private void validSet(FeatureGrant grant,
org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed period) {
grant.setValid(convert(period));
}

private ValidityPeriodClosed convert(org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed period) {
org.eclipse.passage.lic.licenses.model.api.ValidityPeriodClosed valid = LicensesFactory.eINSTANCE
.createValidityPeriodClosed();
valid.setFrom(Date.from(period.from().toInstant()));
valid.setUntil(Date.from(period.to().toInstant()));
return valid;
}

private ZonedDateTime date(Date date) {
return ZonedDateTime.from(date.toInstant().atZone(ZoneId.systemDefault()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*******************************************************************************
* 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.issue;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

import org.eclipse.passage.lic.internal.api.conditions.ValidityPeriodClosed;
import org.eclipse.passage.lic.internal.base.conditions.BaseValidityPeriodClosed;
import org.eclipse.passage.lic.internal.equinox.EquinoxPassage;
import org.eclipse.passage.lic.licenses.model.api.LicenseGrant;
import org.eclipse.passage.lic.licenses.model.api.LicensePack;

@SuppressWarnings("restriction")
public final class PersonalLicenseIssuingProtection implements Consumer<LicensePack> {

private final String feature = "org.eclipse.passage.loc.operator.issue.personal.full"; //$NON-NLS-1$
private final List<Reduction<LicenseGrant>> reductions;

public PersonalLicenseIssuingProtection() {
this.reductions = Arrays.asList(//
new ClosedValidityPeriodReduction<LicenseGrant>(this::validGet, this::validSet)//
);
}

@Override
public void accept(LicensePack license) {
if (new EquinoxPassage().canUse(feature)) {
return;
}
diminish(license);
}

private void diminish(LicensePack license) {
license.getLicenseGrants().forEach(this::diminishGrant);
}

private void diminishGrant(LicenseGrant grant) {
reductions.forEach(r -> r.accept(grant));
}

private Optional<ValidityPeriodClosed> validGet(LicenseGrant grant) {
return Optional.of(new BaseValidityPeriodClosed(date(grant.getValidFrom()), date(grant.getValidUntil())));
}

private void validSet(LicenseGrant grant, ValidityPeriodClosed period) {
grant.setValidFrom(Date.from(period.from().toInstant()));
grant.setValidUntil(Date.from(period.to().toInstant()));
}

private ZonedDateTime date(Date date) {
return ZonedDateTime.from(date.toInstant().atZone(ZoneId.systemDefault()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*******************************************************************************
* 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.issue;

import java.util.function.Consumer;

interface Reduction<L> extends Consumer<L> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*******************************************************************************
* 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.issue;

import org.eclipse.emf.common.util.EList;
import org.eclipse.passage.lic.licenses.model.api.FloatingLicensePack;
import org.eclipse.passage.lic.licenses.model.api.UserGrant;

@SuppressWarnings("restriction")
final class UserGrantsAmountReduction implements Reduction<FloatingLicensePack> {

private final int amount = 1;

@Override
public void accept(FloatingLicensePack license) {
EList<UserGrant> users = license.getUsers();
if (users.size() > amount) {
for (int i = users.size() - 1; i >= amount; i--) {
users.remove(i);
}
}
}

}