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

Bug 573171 support old way of storing keys in 2.0.0 #770

Merged
merged 1 commit into from
May 11, 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 @@ -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