package com.tyndalehouse.step.core.service.jsword.impl;
import com.tyndalehouse.step.core.utils.StringUtils;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.sword.ConfigEntryType;
import org.crosswire.jsword.book.sword.ConfigValueInterceptor;
import org.jasypt.util.text.BasicTextEncryptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Config value interceptor, to decrypt STEP cipher keys
*/
@Singleton
public class StepConfigValueInterceptor implements ConfigValueInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(StepConfigValueInterceptor.class);
private final BasicTextEncryptor encryptor;
private final Map<String, String> decryptions = new HashMap<>();
@Inject
public StepConfigValueInterceptor(@Named("app.internal.key") String key) {
final BasicTextEncryptor encryptor = new BasicTextEncryptor();
final String sysKey = System.getProperty("app.internal.key");
if(sysKey != null) {
//then use this one instead
encryptor.setPassword(sysKey);
} else {
encryptor.setPassword(key);
}
this.encryptor = encryptor;
// this.books = new HashSet(Arrays.asList(StringUtils.split(lockedBooks)));
}
@Override
public Object intercept(final String bookName, final ConfigEntryType configEntryType, final Object value) {
if (value != null && ConfigEntryType.CIPHER_KEY.equals(configEntryType) && isSTEPBook(bookName.toLowerCase())) {
try {
String decryptedResult = decryptions.get(value);
if(decryptedResult != null) {
return decryptedResult;
}
final String valueAsString = (String) value;
final String decrypt = this.encryptor.decrypt(valueAsString);
synchronized (this) {
decryptions.put(valueAsString, decrypt);
}
return decrypt;
} catch (Exception ex) {
//unable to decrypt
LOGGER.error(ex.getMessage());
LOGGER.debug(ex.getMessage(), ex);
}
}
return value;
}
private boolean isSTEPBook(final String initials) {
Book b = Books.installed().getBook(initials);
if(b == null) {
return false;
}
final Object stepLocked = b.getBookMetaData().getProperty("STEPLocked");
return Boolean.parseBoolean((String) stepLocked);
}
}