Skip to content

Commit

Permalink
Merge pull request #770 from eclipse-passage/573171
Browse files Browse the repository at this point in the history
Bug 573171  support old way of storing keys in 2.0.0
  • Loading branch information
eparovyshnaya authored May 11, 2021
2 parents 06fd54a + 2578ae3 commit 4e9f1cb
Show file tree
Hide file tree
Showing 10 changed files with 422 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ private PGPKeyRingGenerator keyRing(String username, String password) throws Lic
private void persist(PGPKeyRing key, OutputStream target, String error) throws LicensingException {
try (ArmoredOutputStream output = new ArmoredOutputStream(new BufferedOutputStream(target))) {
key.encode(output);
output.flush();
} catch (IOException e) {
throw new LicensingException(BcMessages.getString(error), e); // $NON-NLS-1$
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*******************************************************************************
* 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.products.core;

import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import org.eclipse.passage.loc.internal.products.core.i18n.ConverterMessages;

public final class ConvertKeysReport {

private final List<Record> records;

ConvertKeysReport(List<Record> records) {
this.records = records;
}

ConvertKeysReport(Record record) {
this(Collections.singletonList(record));
}

public List<Record> records() {
return records;
}

public static abstract class Record {

private final Path directory;
private final String message;

protected Record(Path directory, String message) {
this.directory = directory;
this.message = message;
}

public final Path origin() {
return directory;
}

public final String message() {
return message;
}

}

static final class ErrorOnScan extends Record {

ErrorOnScan(Path directory, Throwable thro) {
super(directory, String.format(//
ConverterMessages.ConvertKeysReport_e_scan, //
thro.getClass().getName(), //
thro.getMessage()));
}

}

static final class NoProduct extends Record {

NoProduct(Path pub) {
super(pub.getParent(), String.format(//
ConverterMessages.ConvertKeysReport_e_product, //
pub));
}

}

static final class ScrNotFound extends Record {

ScrNotFound(Path pub) {
super(pub.getParent(), String.format(//
ConverterMessages.ConvertKeysReport_e_pair, //
pub.getFileName()));
}

}

static final class ErrorOnKeyReading extends Record {

ErrorOnKeyReading(Path directory, String key, Throwable thro) {
super(directory, String.format(//
ConverterMessages.ConvertKeysReport_e_reading, //
key, //
thro.getClass().getName(), //
thro.getMessage()));
}

}

static final class ErrorOnKeyStoring extends Record {

ErrorOnKeyStoring(Path directory, String key, Throwable thro) {
super(directory, String.format(//
ConverterMessages.ConvertKeysReport_e_storing, //
key, //
thro.getClass().getName(), //
thro.getMessage()));
}

}

static final class Success extends Record {

Success(Path origin, String name, Optional<String> locator) {
super(origin, String.format(//
ConverterMessages.ConvertKeysReport_success, //
name, //
locator.orElse(ConverterMessages.ConvertKeysReport_no_locator)));
}

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

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.passage.lic.internal.api.LicensedProduct;
import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.base.BaseLicensedProduct;
import org.eclipse.passage.lic.internal.base.io.LicensingFolder;
import org.eclipse.passage.lic.internal.base.io.PassageFileExtension;
import org.eclipse.passage.lic.internal.base.io.UserHomePath;
import org.eclipse.passage.lic.keys.model.api.KeyPair;

public final class ConvertedKeys {

private final String ext = new PassageFileExtension.PublicKey().get();
private final Consumer<ConvertKeysReport> exposure;

public ConvertedKeys(Consumer<ConvertKeysReport> exposure) {
this.exposure = exposure;
}

public ConvertedKeys() {
this(new ToLog());
}

@SuppressWarnings("resource")
public void persist() {
Path root = new LicensingFolder(new UserHomePath().get()).get();
Stream<Path> files;
try {
files = Files.walk(root); // resource leak never happens
} catch (IOException e) {
exposure.accept(failedToScan(root, e));
return;
}
exposure.accept(//
new ConvertKeysReport(files//
.filter(Files::isRegularFile)//
.filter(this::isPublicKey)//
.map(this::convert)//
.collect(Collectors.toList())//
));
}

private boolean isPublicKey(Path file) {
return file.toString().endsWith(ext);
}

private ConvertKeysReport.Record convert(Path pub) {
Optional<LicensedProduct> product = product(pub);
if (product.isEmpty()) {
return noProduct(pub);
}
Optional<Path> scr = scr(pub);
if (scr.isEmpty()) {
return noPair(pub);
}
KeyPair pair;
try {
pair = new KeyPairUpgraded(product.get(), pub, scr.get()).get();
} catch (IOException e) {
return new ConvertKeysReport.ErrorOnKeyReading(pub.getParent(), keyName(pub), e);
}
Optional<String> locator;
try {
locator = new KeyPairStored(pair).store();
} catch (LicensingException e) {
return new ConvertKeysReport.ErrorOnKeyStoring(pub.getParent(), keyName(pub), e);
}
return new ConvertKeysReport.Success(pub.getParent(), keyName(pub), locator);
}

private String keyName(Path pub) {
String path = pub.getFileName().toString();
return path.substring(0, path.length() - ext.length());
}

private ConvertKeysReport failedToScan(Path dir, IOException e) {
return new ConvertKeysReport(new ConvertKeysReport.ErrorOnScan(dir, e));
}

private ConvertKeysReport.Record noProduct(Path pub) {
return new ConvertKeysReport.NoProduct(pub);
}

private ConvertKeysReport.Record noPair(Path pub) {
return new ConvertKeysReport.ScrNotFound(pub);
}

private Optional<Path> scr(Path pub) {
Path scr = pub.getParent().resolve(keyName(pub) + new PassageFileExtension.PrivateKey().get());
return Files.exists(scr) && Files.isRegularFile(scr) //
? Optional.of(scr) //
: Optional.empty();
}

private Optional<LicensedProduct> product(Path pub) {
String name = keyName(pub);
int separator = name.lastIndexOf('_');
if (separator < 0 || separator >= name.length()) {
return productFromFolders(pub);
}
return Optional.of(new BaseLicensedProduct(//
name.substring(0, separator), //
name.substring(separator + 1)));
}

private Optional<LicensedProduct> productFromFolders(Path pub) {
if (pub.getParent().getParent() == null) { // nio null
return Optional.empty();
}
return Optional.of(new BaseLicensedProduct(//
pub.getParent().getParent().getFileName().toString(), //
pub.getParent().getFileName().toString()));
}

static final class ToLog implements Consumer<ConvertKeysReport> {

private final Logger log = LogManager.getLogger(ConvertedKeys.class);

@Override
public void accept(ConvertKeysReport report) {
report.records().forEach(this::print);
}

private void print(ConvertKeysReport.Record record) {
log.info(String.format(//
"%s || %s", //$NON-NLS-1$
record.origin().toAbsolutePath(), //
record.message()));
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
import org.eclipse.passage.loc.internal.equinox.OperatorGearAware;

@SuppressWarnings("restriction")
final class KeyPairStored {
public final class KeyPairStored {

private final KeyPair pair;

KeyPairStored(KeyPair pair) {
public KeyPairStored(KeyPair pair) {
this.pair = pair;
}

public Optional<String> get() throws LicensingException {
public Optional<String> store() throws LicensingException {
return new OperatorGearAware().withGear(gear -> store(gear.workspace().keys()));
}

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

import java.io.IOException;
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.io.EncryptionAlgorithm;
import org.eclipse.passage.lic.internal.api.io.EncryptionKeySize;
import org.eclipse.passage.lic.keys.model.api.KeyPair;
import org.eclipse.passage.lic.keys.model.api.ProductRef;
import org.eclipse.passage.lic.keys.model.meta.KeysFactory;

public final class KeyPairUpgraded {

private final LicensedProduct product;
private final Path pub;
private final Path scr;

public KeyPairUpgraded(LicensedProduct product, Path pub, Path scr) {
this.product = product;
this.pub = pub;
this.scr = scr;
}

public KeyPair get() throws IOException {
KeyPair pair = KeysFactory.eINSTANCE.createKeyPair();
pair.setProduct(product());
pair.setAlgorithm(new EncryptionAlgorithm.Default().name());
pair.setKey(new EncryptionKeySize.Default().size());
pair.setPub(fileContent(pub));
pair.setScr(fileContent(scr));
return pair;
}

private ProductRef product() {
ProductRef ref = KeysFactory.eINSTANCE.createProductRef();
ref.setIdentifier(product.identifier());
ref.setVersion(product.version());
return ref;
}

private String fileContent(Path file) throws IOException {
return new String(Files.readAllBytes(file));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,14 @@ private IStatus createKeyPair(ProductVersionDescriptor target, LicensedProduct p
}

private Optional<String> store(KeyPair pair) throws LicensingException {
return new KeyPairStored(pair).get();
return new KeyPairStored(pair).store();
}

private KeyPair generate(ProductVersionDescriptor target, LicensedProduct product, StreamCodec codec)
throws LicensingException {
try (ByteArrayOutputStream open = new ByteArrayOutputStream();
ByteArrayOutputStream secret = new ByteArrayOutputStream()) {
codec.createKeyPair(open, secret, product.identifier(), new ProductVersionPassword(target).get());
open.flush();
secret.flush();
return new KeyPairGeneraged(codec, open.toByteArray(), secret.toByteArray()).get();
} catch (Exception e) {
throw new LicensingException("failed to generate keys", e); //$NON-NLS-1$ // TODO: l10n
Expand Down
Loading

0 comments on commit 4e9f1cb

Please sign in to comment.