Skip to content

Commit

Permalink
Bug 575182 protect condition mining with Agreements consistency check
Browse files Browse the repository at this point in the history
convey global agreement to an end user in scope of examination
certificate's in agreement state and restriction set

Signed-off-by: eparovyshnaya <[email protected]>
  • Loading branch information
eparovyshnaya committed Aug 25, 2021
1 parent 7342f45 commit d1c9cde
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 24 deletions.
9 changes: 9 additions & 0 deletions bundles/org.eclipse.passage.lic.base/.settings/.api_filters
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/passage/lic/base/access/Restrictions.java" type="org.eclipse.passage.lic.base.access.Restrictions">
<filter id="643850349">
<message_arguments>
<message_argument value="AgreementAcceptanceService"/>
<message_argument value="Restrictions"/>
<message_argument value="Restrictions(LicensedProduct, Registry&lt;StringServiceId,PermissionsExaminationService&gt;, AgreementAcceptanceService, Collection&lt;Requirement&gt;, PermissionsAppliedLicenses)"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/passage/lic/base/restrictions/BasePermissionsExaminationService.java" type="org.eclipse.passage.lic.base.restrictions.BasePermissionsExaminationService">
<filter id="643850349">
<message_arguments>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand All @@ -23,11 +22,11 @@
import org.eclipse.passage.lic.api.Framework;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
import org.eclipse.passage.lic.api.conditions.ConditionPack;
import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
import org.eclipse.passage.lic.api.diagnostic.Diagnostic;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.ExaminationCertificate;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;
import org.eclipse.passage.lic.base.diagnostic.BaseDiagnostic;
import org.eclipse.passage.lic.base.diagnostic.SumOfDiagnostics;

Expand Down Expand Up @@ -64,7 +63,7 @@ protected Optional<String> feature() {
}

private T examine(Supplier<ServiceInvocationResult<Collection<Requirement>>> requirements, //
Supplier<ServiceInvocationResult<Collection<Permission>>> permissions) {
Supplier<ServiceInvocationResult<AppliedLicenses>> permissions) {
ServiceInvocationResult<Collection<Requirement>> reqs = requirements.get();
if (failed(reqs)) {
return stop();
Expand All @@ -74,7 +73,7 @@ private T examine(Supplier<ServiceInvocationResult<Collection<Requirement>>> req
// we just want to avoid heavy operations below
return freeWayOut();
}
ServiceInvocationResult<Collection<Permission>> perms = permissions.get();
ServiceInvocationResult<AppliedLicenses> perms = permissions.get();
if (failed(perms)) {
return stop();
}
Expand Down Expand Up @@ -141,11 +140,10 @@ private ServiceInvocationResult<Collection<ConditionPack>> conditions() {
filter.conditional()).get());
}

private ServiceInvocationResult<Collection<Permission>> permissions() {
private ServiceInvocationResult<Permissions.AppliedLicenses> permissions() {
ServiceInvocationResult<Collection<ConditionPack>> conditions = conditions();
if (failed(conditions) || empty(conditions)) {
return new BaseServiceInvocationResult<Collection<Permission>>(conditions.diagnostic(),
Collections.emptyList());
return new BaseServiceInvocationResult<AppliedLicenses>(conditions.diagnostic(), new AppliedLicenses());
}
return scan(new Permissions(//
framework.accessCycleConfiguration().permissionEmitters().get(), //
Expand All @@ -154,9 +152,11 @@ private ServiceInvocationResult<Collection<Permission>> permissions() {
}

private ServiceInvocationResult<ExaminationCertificate> restrictions(Collection<Requirement> requirements,
Collection<Permission> permissions) {
AppliedLicenses permissions) {
return scan(new Restrictions(//
framework.product(), //
framework.accessCycleConfiguration().examinators().get(), //
framework.accessCycleConfiguration().acceptance(), //
requirements, //
permissions).get());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.eclipse.passage.lic.api.LicensedProduct;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
import org.eclipse.passage.lic.api.agreements.GlobalAgreement;
import org.eclipse.passage.lic.api.conditions.ConditionPack;
import org.eclipse.passage.lic.api.conditions.evaluation.Emission;
import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
Expand All @@ -29,13 +31,14 @@
import org.eclipse.passage.lic.api.registry.StringServiceId;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
import org.eclipse.passage.lic.base.SumOfCollections;
import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;

/**
* FIXME: Has public visibility only for testing.
*
* @since 2.1
*/
public final class Permissions implements Supplier<ServiceInvocationResult<Collection<Permission>>> {
public final class Permissions implements Supplier<ServiceInvocationResult<AppliedLicenses>> {

private final Registry<StringServiceId, PermissionEmittingService> registry;
private final Collection<ConditionPack> conditions;
Expand All @@ -49,7 +52,17 @@ public Permissions(Registry<StringServiceId, PermissionEmittingService> registry
}

@Override
public ServiceInvocationResult<Collection<Permission>> get() {
public ServiceInvocationResult<AppliedLicenses> get() {
BaseServiceInvocationResult<Collection<Permission>> permissions = permissions();
return new BaseServiceInvocationResult<>(//
permissions.diagnostic(), //
new AppliedLicenses(//
permissions.data().get(), //
agreements())//
);
}

private BaseServiceInvocationResult<Collection<Permission>> permissions() {
return registry.services().stream() //
.map(service -> service.emit(conditions, product))//
.reduce(new BaseServiceInvocationResult.Sum<>(new SumOfCollections<Emission>()))//
Expand All @@ -70,6 +83,13 @@ private Collection<Permission> allPermissions(Optional<Collection<Emission>> emi
new SumOfCollections<Permission>());
}

private Collection<GlobalAgreement> agreements() {
return conditions.stream()//
.map(ConditionPack::agreements)//
.flatMap(Collection::stream)//
.collect(Collectors.toList());
}

/**
* Here we do not need `ConditionPack` granularity, thus unfold each one to
* amass all the permissions we have.
Expand All @@ -85,4 +105,27 @@ public Collection<Permission> apply(Collection<Permission> sum, Emission emissio

}

public static final class AppliedLicenses {

private final Collection<Permission> permissions;
private final Collection<GlobalAgreement> agreements;

AppliedLicenses() {
this(Collections.emptyList(), Collections.emptyList());
}

AppliedLicenses(Collection<Permission> permissions, Collection<GlobalAgreement> agreements) {
this.permissions = permissions;
this.agreements = agreements;
}

Collection<Permission> permissions() {
return permissions;
}

Collection<GlobalAgreement> agreements() {
return agreements;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,33 @@
package org.eclipse.passage.lic.base.access;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.eclipse.passage.lic.api.LicensedProduct;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
import org.eclipse.passage.lic.api.agreements.AgreementAcceptanceService;
import org.eclipse.passage.lic.api.agreements.AgreementState;
import org.eclipse.passage.lic.api.agreements.AgreementToAccept;
import org.eclipse.passage.lic.api.agreements.GlobalAgreement;
import org.eclipse.passage.lic.api.agreements.ResolvedAgreement;
import org.eclipse.passage.lic.api.diagnostic.Trouble;
import org.eclipse.passage.lic.api.registry.Registry;
import org.eclipse.passage.lic.api.registry.StringServiceId;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.ExaminationCertificate;
import org.eclipse.passage.lic.api.restrictions.PermissionsExaminationService;
import org.eclipse.passage.lic.api.restrictions.Restriction;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;
import org.eclipse.passage.lic.base.agreements.AgreementAcceptanceDemand;
import org.eclipse.passage.lic.base.agreements.BaseAgreementToAccept;
import org.eclipse.passage.lic.base.agreements.MinedAgreement;
import org.eclipse.passage.lic.base.agreements.UnacceptedAgreementRestriction;
import org.eclipse.passage.lic.base.diagnostic.code.NoServicesOfType;
import org.eclipse.passage.lic.base.restrictions.BaseExaminationCertificate;
import org.eclipse.passage.lic.internal.base.i18n.AccessCycleMessages;

/**
Expand All @@ -33,12 +48,16 @@
public final class Restrictions implements Supplier<ServiceInvocationResult<ExaminationCertificate>> {

private final Registry<StringServiceId, PermissionsExaminationService> registry;
private final AgreementAcceptanceService acceptance;
private final Collection<Requirement> requirements;
private final Collection<Permission> permissions;
private final AppliedLicenses permissions;
private final LicensedProduct product;

public Restrictions(Registry<StringServiceId, PermissionsExaminationService> registry,
Collection<Requirement> requirements, Collection<Permission> permissions) {
public Restrictions(LicensedProduct product, Registry<StringServiceId, PermissionsExaminationService> registry,
AgreementAcceptanceService acceptance, Collection<Requirement> requirements, AppliedLicenses permissions) {
this.product = product;
this.registry = registry;
this.acceptance = acceptance;
this.requirements = requirements;
this.permissions = permissions;
}
Expand All @@ -52,11 +71,43 @@ public ServiceInvocationResult<ExaminationCertificate> get() {
AccessCycleMessages.getString("Restrictions.no_services"))); //$NON-NLS-1$
}
return new BaseServiceInvocationResult<ExaminationCertificate>(//
registry.services().stream()//
.map(service -> service.examine(requirements, permissions)) //
.reduce(new SumOfCertificates())//
.get() // guaranteed to exist as there is at least one service
new SumOfCertificates().apply(//
permissionBasedCertificate(), //
agreementsBasedCertificate())//
);
}

private ExaminationCertificate permissionBasedCertificate() {
return registry.services().stream()//
.map(service -> service.examine(requirements, permissions.permissions())) //
.reduce(new SumOfCertificates())//
.get(); // guaranteed to exist as there is at least one service
}

private ExaminationCertificate agreementsBasedCertificate() {
List<AgreementToAccept> agreements = permissions.agreements().stream()//
.map(this::agreementToAccept)//
.collect(Collectors.toList());
return new BaseExaminationCertificate(Collections.emptyMap(), restrictions(agreements), agreements);
}

private AgreementToAccept agreementToAccept(GlobalAgreement agreement) {
ResolvedAgreement definition = new MinedAgreement(agreement);
return new BaseAgreementToAccept(//
new AgreementAcceptanceDemand(definition), //
definition, //
acceptanceState(agreement));
}

private AgreementState acceptanceState(GlobalAgreement agreement) {
return acceptance.accepted(agreement.content(), agreement.name());
}

private Collection<Restriction> restrictions(List<AgreementToAccept> agreements) {
return agreements.stream()//
.filter(agreement -> !agreement.acceptance().accepted())//
.map(agreement -> new UnacceptedAgreementRestriction(product, agreement).get())//
.collect(Collectors.toList());
}

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

import java.util.Collections;
import java.util.List;

import org.eclipse.passage.lic.api.agreements.ResolvedAgreement;
import org.eclipse.passage.lic.api.requirements.Feature;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.RestrictionLevel;

public final class AgreementAcceptanceDemand implements Requirement {

private final Feature feature;
private final List<ResolvedAgreement> agreement;

public AgreementAcceptanceDemand(ResolvedAgreement agreement) {
this.feature = new GlobalAgreementSupportFeature().get();
this.agreement = Collections.singletonList(agreement);
}

@Override
public Feature feature() {
return feature;
}

@Override
public RestrictionLevel restrictionLevel() {
return new RestrictionLevel.Fatal();
}

@Override
public List<ResolvedAgreement> agreements() {
return agreement;
}

@Override
public Object source() {
return "a license"; //$NON-NLS-1$
}

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

import java.util.function.Supplier;

import org.eclipse.passage.lic.api.requirements.Feature;
import org.eclipse.passage.lic.base.requirements.BaseFeature;

public final class GlobalAgreementSupportFeature implements Supplier<Feature> {

@Override
public Feature get() {
return new BaseFeature(//
"passage.global-agreement-support.feature", //$NON-NLS-1$
"0.0.0", //$NON-NLS-1$
"Global Agreements Support", //$NON-NLS-1$
"Eclipse Passage Runtime" //$NON-NLS-1$
);
}

}
Loading

0 comments on commit d1c9cde

Please sign in to comment.