mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Remaining commits for ALF-9510:
o re-encryptor o secret key keystore creation Removed secret key keystores from Solr Added pcks12 secret key keystore for use in browsers git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@30208 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Binary file not shown.
@@ -1013,7 +1013,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="solrHttpClientFactory" class="org.alfresco.httpclient.HttpClientFactory">
|
<bean id="solrHttpClientFactory" class="org.alfresco.httpclient.HttpClientFactory" init-method="init">
|
||||||
<property name="secureCommsType" value="${solr.secureComms}"/>
|
<property name="secureCommsType" value="${solr.secureComms}"/>
|
||||||
<property name="sSLEncryptionParameters" ref="sslEncryptionParameters"/>
|
<property name="sSLEncryptionParameters" ref="sslEncryptionParameters"/>
|
||||||
<property name="keyResourceLoader" ref="springKeyResourceLoader"/>
|
<property name="keyResourceLoader" ref="springKeyResourceLoader"/>
|
||||||
|
@@ -11,7 +11,9 @@
|
|||||||
|
|
||||||
<!-- Beans to initilize encryption -->
|
<!-- Beans to initilize encryption -->
|
||||||
|
|
||||||
|
<!-- TODO i18n for key store names -->
|
||||||
<bean id="sslKeyStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
<bean id="sslKeyStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
||||||
|
<property name="name" value="SSL Key Store"/>
|
||||||
<property name="location" value="${encryption.ssl.keystore.location}"/>
|
<property name="location" value="${encryption.ssl.keystore.location}"/>
|
||||||
<property name="type" value="${encryption.ssl.keystore.type}"/>
|
<property name="type" value="${encryption.ssl.keystore.type}"/>
|
||||||
<property name="provider" value="${encryption.ssl.keystore.provider}"/>
|
<property name="provider" value="${encryption.ssl.keystore.provider}"/>
|
||||||
@@ -19,6 +21,7 @@
|
|||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="sslTrustStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
<bean id="sslTrustStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
||||||
|
<property name="name" value="SSL Trust Store"/>
|
||||||
<property name="location" value="${encryption.ssl.truststore.location}"/>
|
<property name="location" value="${encryption.ssl.truststore.location}"/>
|
||||||
<property name="type" value="${encryption.ssl.truststore.type}"/>
|
<property name="type" value="${encryption.ssl.truststore.type}"/>
|
||||||
<property name="provider" value="${encryption.ssl.truststore.provider}"/>
|
<property name="provider" value="${encryption.ssl.truststore.provider}"/>
|
||||||
@@ -30,6 +33,21 @@
|
|||||||
<property name="trustStoreParameters" ref="sslTrustStoreParameters"/>
|
<property name="trustStoreParameters" ref="sslTrustStoreParameters"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ssl.keyStore" class="org.alfresco.encryption.AlfrescoKeyStoreImpl" init-method="init">
|
||||||
|
<property name="keyStoreParameters" ref="sslKeyStoreParameters"/>
|
||||||
|
<property name="keyResourceLoader" ref="springKeyResourceLoader"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ssl.trustStore" class="org.alfresco.encryption.AlfrescoKeyStoreImpl" init-method="init">
|
||||||
|
<property name="keyStoreParameters" ref="sslTrustStoreParameters"/>
|
||||||
|
<property name="keyResourceLoader" ref="springKeyResourceLoader"/>
|
||||||
|
</bean>
|
||||||
|
<!--
|
||||||
|
<bean id="authSSLProtocolSocketFactory" class="org.alfresco.encryption.ssl.AuthSSLProtocolSocketFactory">
|
||||||
|
<property name="keyStore" ref="ssl.keyStore"/>
|
||||||
|
<property name="trustStore" ref="ssl.trustStore"/>
|
||||||
|
</bean>
|
||||||
|
-->
|
||||||
<bean id="md5EncryptionParameters" class="org.alfresco.httpclient.MD5EncryptionParameters">
|
<bean id="md5EncryptionParameters" class="org.alfresco.httpclient.MD5EncryptionParameters">
|
||||||
<property name="cipherAlgorithm" value="${encryption.cipherAlgorithm}"/>
|
<property name="cipherAlgorithm" value="${encryption.cipherAlgorithm}"/>
|
||||||
<property name="messageTimeout" value="${encryption.mac.messageTimeout}"/>
|
<property name="messageTimeout" value="${encryption.mac.messageTimeout}"/>
|
||||||
@@ -40,6 +58,7 @@
|
|||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="keyStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
<bean id="keyStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
||||||
|
<property name="name" value="Key Store"/>
|
||||||
<property name="location" value="${encryption.keystore.location}"/>
|
<property name="location" value="${encryption.keystore.location}"/>
|
||||||
<property name="provider" value="${encryption.keystore.provider}"/>
|
<property name="provider" value="${encryption.keystore.provider}"/>
|
||||||
<property name="type" value="${encryption.keystore.type}"/>
|
<property name="type" value="${encryption.keystore.type}"/>
|
||||||
@@ -56,6 +75,7 @@
|
|||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="backupKeyStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
<bean id="backupKeyStoreParameters" class="org.alfresco.encryption.KeyStoreParameters">
|
||||||
|
<property name="name" value="Backup Key Store"/>
|
||||||
<property name="location" value="${encryption.keystore.backup.location}"/>
|
<property name="location" value="${encryption.keystore.backup.location}"/>
|
||||||
<property name="provider" value="${encryption.keystore.backup.provider}"/>
|
<property name="provider" value="${encryption.keystore.backup.provider}"/>
|
||||||
<property name="type" value="${encryption.keystore.backup.type}"/>
|
<property name="type" value="${encryption.keystore.backup.type}"/>
|
||||||
@@ -86,20 +106,6 @@
|
|||||||
<property name="fallback" ref="backupEncryptor" />
|
<property name="fallback" ref="backupEncryptor" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="reEncryptor" class="org.alfresco.encryption.ReEncryptor">
|
|
||||||
<property name="chunkSize" value="${encryption.reencryptor.chunkSize}"/>
|
|
||||||
<property name="backupKeyStore" ref="backupKeyStore"/>
|
|
||||||
<property name="keyStore" ref="keyStore"/>
|
|
||||||
<property name="backupKeyProvider" ref="backupKeyProvider"/>
|
|
||||||
<property name="keyProvider" ref="keyProvider"/>
|
|
||||||
<property name="transactionService" ref="transactionService"/>
|
|
||||||
<property name="dictionaryService" ref="dictionaryService"/>
|
|
||||||
<property name="nodeDAO" ref="nodeDAO"/>
|
|
||||||
<property name="dictionaryDAO" ref="dictionaryDAO"/>
|
|
||||||
<property name="qnameDAO" ref="qnameDAO"/>
|
|
||||||
<property name="cipherAlgorithm" value="${encryption.cipherAlgorithm}"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="encryptionKeysRegistry" class="org.alfresco.encryption.EncryptionKeysRegistryImpl">
|
<bean id="encryptionKeysRegistry" class="org.alfresco.encryption.EncryptionKeysRegistryImpl">
|
||||||
<property name="transactionService" ref="transactionService"/>
|
<property name="transactionService" ref="transactionService"/>
|
||||||
<property name="attributeService" ref="attributeService"/>
|
<property name="attributeService" ref="attributeService"/>
|
||||||
|
BIN
config/alfresco/keystore/browser.p12
Normal file
BIN
config/alfresco/keystore/browser.p12
Normal file
Binary file not shown.
Binary file not shown.
@@ -5,7 +5,3 @@ keystore.password=mp6yc0UD9e
|
|||||||
metadata.keyData=
|
metadata.keyData=
|
||||||
metadata.algorithm=DESede
|
metadata.algorithm=DESede
|
||||||
metadata.password=oKIWzVdEdA
|
metadata.password=oKIWzVdEdA
|
||||||
# The password protecting the alias: solr
|
|
||||||
#solr.keyData=
|
|
||||||
#solr.algorithm=DESede
|
|
||||||
#solr.password=TxHTtOnrwQ
|
|
@@ -37,6 +37,9 @@ system.mt.warn.upgrade_mt_admin_context=Please update your alfresco/extension/mt
|
|||||||
system.usage.err.no_txn=RepoUsageComponent must be called in a transaction.
|
system.usage.err.no_txn=RepoUsageComponent must be called in a transaction.
|
||||||
system.usage.err.no_txn_readwrite=RepoUsageComponent must be called in a read-write transaction.
|
system.usage.err.no_txn_readwrite=RepoUsageComponent must be called in a read-write transaction.
|
||||||
|
|
||||||
|
# Re-encryptor
|
||||||
|
reencryptor.batchprocessor.name=Reencryptor
|
||||||
|
|
||||||
# START TRANSLATION
|
# START TRANSLATION
|
||||||
system.usage.warn.limit_users_approached=The allowable user limit of {0} is being approached. There are {1} users in the system.
|
system.usage.warn.limit_users_approached=The allowable user limit of {0} is being approached. There are {1} users in the system.
|
||||||
system.usage.warn.limit_users_reached=The allowable user limit of {0} has been reached. There are {1} users in the system.
|
system.usage.warn.limit_users_reached=The allowable user limit of {0} has been reached. There are {1} users in the system.
|
||||||
|
@@ -250,4 +250,15 @@
|
|||||||
<property name="encryptor" ref="fallbackEncryptor" />
|
<property name="encryptor" ref="fallbackEncryptor" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="reEncryptor" class="org.alfresco.encryption.ReEncryptor">
|
||||||
|
<property name="chunkSize" value="${encryption.reencryptor.chunkSize}"/>
|
||||||
|
<property name="backupKeyProvider" ref="backupKeyProvider"/>
|
||||||
|
<property name="keyProvider" ref="keyProvider"/>
|
||||||
|
<property name="transactionService" ref="transactionService"/>
|
||||||
|
<property name="nodeDAO" ref="nodeDAO"/>
|
||||||
|
<property name="dictionaryDAO" ref="dictionaryDAO"/>
|
||||||
|
<property name="qnameDAO" ref="qnameDAO"/>
|
||||||
|
<property name="metadataEncryptor" ref="metadataEncryptor"/>
|
||||||
|
<property name="jobLockService" ref="jobLockService"/>
|
||||||
|
</bean>
|
||||||
</beans>
|
</beans>
|
||||||
|
@@ -56,7 +56,6 @@ import org.springframework.context.ApplicationContext;
|
|||||||
public class EncryptionTests extends TestCase
|
public class EncryptionTests extends TestCase
|
||||||
{
|
{
|
||||||
private static final String TEST_MODEL = "org/alfresco/encryption/reencryption_model.xml";
|
private static final String TEST_MODEL = "org/alfresco/encryption/reencryption_model.xml";
|
||||||
// private static final String TEST_BUNDLE = "org/alfresco/encryption/encryptiontest_model";
|
|
||||||
|
|
||||||
private static int NUM_PROPERTIES = 500;
|
private static int NUM_PROPERTIES = 500;
|
||||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||||
@@ -72,11 +71,13 @@ public class EncryptionTests extends TestCase
|
|||||||
private MetadataEncryptor metadataEncryptor;
|
private MetadataEncryptor metadataEncryptor;
|
||||||
private ReEncryptor reEncryptor;
|
private ReEncryptor reEncryptor;
|
||||||
private String cipherAlgorithm = "DESede/CBC/PKCS5Padding";
|
private String cipherAlgorithm = "DESede/CBC/PKCS5Padding";
|
||||||
private KeyStoreParameters keyStoreParameters;
|
|
||||||
private KeyStoreParameters backupKeyStoreParameters;
|
private KeyStoreParameters backupKeyStoreParameters;
|
||||||
|
private AlfrescoKeyStoreImpl backupKeyStore;
|
||||||
private KeyResourceLoader keyResourceLoader;
|
private KeyResourceLoader keyResourceLoader;
|
||||||
private EncryptionKeysRegistryImpl encryptionKeysRegistry;
|
private EncryptionKeysRegistryImpl encryptionKeysRegistry;
|
||||||
private KeyStoreChecker keyStoreChecker;
|
private KeyStoreChecker keyStoreChecker;
|
||||||
|
private DefaultEncryptor mainEncryptor;
|
||||||
|
private DefaultEncryptor backupEncryptor;
|
||||||
|
|
||||||
private AuthenticationComponent authenticationComponent;
|
private AuthenticationComponent authenticationComponent;
|
||||||
private DictionaryDAO dictionaryDAO;
|
private DictionaryDAO dictionaryDAO;
|
||||||
@@ -102,8 +103,10 @@ public class EncryptionTests extends TestCase
|
|||||||
reEncryptor = (ReEncryptor)ctx.getBean("reEncryptor");
|
reEncryptor = (ReEncryptor)ctx.getBean("reEncryptor");
|
||||||
backupKeyStoreParameters = (KeyStoreParameters)ctx.getBean("backupKeyStoreParameters");
|
backupKeyStoreParameters = (KeyStoreParameters)ctx.getBean("backupKeyStoreParameters");
|
||||||
keyStoreChecker = (KeyStoreChecker)ctx.getBean("keyStoreChecker");
|
keyStoreChecker = (KeyStoreChecker)ctx.getBean("keyStoreChecker");
|
||||||
keyStoreParameters = (KeyStoreParameters)ctx.getBean("keyStoreParameters");
|
|
||||||
encryptionKeysRegistry = (EncryptionKeysRegistryImpl)ctx.getBean("encryptionKeysRegistry");
|
encryptionKeysRegistry = (EncryptionKeysRegistryImpl)ctx.getBean("encryptionKeysRegistry");
|
||||||
|
backupKeyStore = (AlfrescoKeyStoreImpl)ctx.getBean("backupKeyStore");
|
||||||
|
mainEncryptor = (DefaultEncryptor)ctx.getBean("encryptor");
|
||||||
|
backupEncryptor = (DefaultEncryptor)ctx.getBean("backupEncryptor");
|
||||||
|
|
||||||
// reencrypt in one txn (since we don't commit the model, the qnames won't be available across transactions)
|
// reencrypt in one txn (since we don't commit the model, the qnames won't be available across transactions)
|
||||||
reEncryptor.setSplitTxns(false);
|
reEncryptor.setSplitTxns(false);
|
||||||
@@ -162,18 +165,26 @@ public class EncryptionTests extends TestCase
|
|||||||
{
|
{
|
||||||
return keys.get(keyAlias);
|
return keys.get(keyAlias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refresh()
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return keyProvider;
|
return keyProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Encryptor getEncryptor(KeyProvider keyProvider)
|
protected Encryptor getFallbackEncryptor(KeyProvider keyProvider)
|
||||||
{
|
{
|
||||||
DefaultEncryptor encryptor = new DefaultEncryptor();
|
DefaultEncryptor encryptor = new DefaultEncryptor();
|
||||||
encryptor.setCipherAlgorithm(cipherAlgorithm);
|
encryptor.setCipherAlgorithm(cipherAlgorithm);
|
||||||
encryptor.setCipherProvider(null);
|
encryptor.setCipherProvider(null);
|
||||||
encryptor.setKeyProvider(keyProvider);
|
encryptor.setKeyProvider(keyProvider);
|
||||||
|
|
||||||
return encryptor;
|
DefaultFallbackEncryptor fallbackEncryptor = new DefaultFallbackEncryptor(encryptor, mainEncryptor);
|
||||||
|
|
||||||
|
return fallbackEncryptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MetadataEncryptor getMetadataEncryptor(Encryptor encryptor)
|
protected MetadataEncryptor getMetadataEncryptor(Encryptor encryptor)
|
||||||
@@ -185,7 +196,7 @@ public class EncryptionTests extends TestCase
|
|||||||
return metadataEncryptor;
|
return metadataEncryptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createEncryptedProperties(List<NodeRef> nodes, MetadataEncryptor metadataEncryptor)
|
protected void createEncryptedProperties(List<NodeRef> nodes)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < NUM_PROPERTIES; i++)
|
for(int i = 0; i < NUM_PROPERTIES; i++)
|
||||||
{
|
{
|
||||||
@@ -218,20 +229,26 @@ public class EncryptionTests extends TestCase
|
|||||||
|
|
||||||
public void testReEncrypt()
|
public void testReEncrypt()
|
||||||
{
|
{
|
||||||
|
KeyProvider backupKeyProvider = backupEncryptor.getKeyProvider();
|
||||||
|
KeyProvider mainKeyProvider = mainEncryptor.getKeyProvider();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Create encrypted properties using the configured encryptor and key provider
|
// Create encrypted properties using the configured encryptor and key provider
|
||||||
createEncryptedProperties(before, metadataEncryptor);
|
createEncryptedProperties(before);
|
||||||
|
|
||||||
// Create encrypted properties using the new encryptor and key provider
|
// Create encrypted properties using the new encryptor and key provider
|
||||||
KeyProvider newKeyProvider = getKeyProvider(newKeys);
|
KeyProvider newKeyProvider = getKeyProvider(newKeys);
|
||||||
Encryptor newEncryptor = getEncryptor(newKeyProvider);
|
|
||||||
MetadataEncryptor newMetadataEncryptor = getMetadataEncryptor(newEncryptor);
|
// set backup encryptor key provider to main encryptor key provider and drop in
|
||||||
createEncryptedProperties(after, newMetadataEncryptor);
|
// new key provider for main encryptor
|
||||||
|
backupEncryptor.setKeyProvider(mainEncryptor.getKeyProvider());
|
||||||
|
mainEncryptor.setKeyProvider(newKeyProvider);
|
||||||
|
|
||||||
|
createEncryptedProperties(after);
|
||||||
|
|
||||||
// re-encrypt
|
// re-encrypt
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
reEncryptor.reEncrypt(newKeyProvider);
|
System.out.println(reEncryptor.reEncrypt() + " properties re-encrypted");
|
||||||
System.out.println("Re-encrypted " + NUM_PROPERTIES*2 + " properties in " + (System.currentTimeMillis() - start) + "ms");
|
System.out.println("Re-encrypted " + NUM_PROPERTIES*2 + " properties in " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
|
||||||
// check that the nodes have been re-encrypted properly i.e. check that the properties
|
// check that the nodes have been re-encrypted properly i.e. check that the properties
|
||||||
@@ -239,7 +256,7 @@ public class EncryptionTests extends TestCase
|
|||||||
for(NodeRef nodeRef : before)
|
for(NodeRef nodeRef : before)
|
||||||
{
|
{
|
||||||
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
|
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
|
||||||
props = newMetadataEncryptor.decrypt(props);
|
props = metadataEncryptor.decrypt(props);
|
||||||
assertNotNull("", props.get(PROP));
|
assertNotNull("", props.get(PROP));
|
||||||
assertEquals("", nodeRef.toString(), props.get(PROP));
|
assertEquals("", nodeRef.toString(), props.get(PROP));
|
||||||
}
|
}
|
||||||
@@ -247,11 +264,15 @@ public class EncryptionTests extends TestCase
|
|||||||
for(NodeRef nodeRef : after)
|
for(NodeRef nodeRef : after)
|
||||||
{
|
{
|
||||||
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
|
Map<QName, Serializable> props = nodeService.getProperties(nodeRef);
|
||||||
props = newMetadataEncryptor.decrypt(props);
|
props = metadataEncryptor.decrypt(props);
|
||||||
assertNotNull("", props.get(PROP));
|
assertNotNull("", props.get(PROP));
|
||||||
assertEquals("", nodeRef.toString(), props.get(PROP));
|
assertEquals("", nodeRef.toString(), props.get(PROP));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(MissingKeyStoreException e)
|
||||||
|
{
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
catch(AlfrescoRuntimeException e)
|
catch(AlfrescoRuntimeException e)
|
||||||
{
|
{
|
||||||
if(e.getCause() instanceof InvalidKeyException)
|
if(e.getCause() instanceof InvalidKeyException)
|
||||||
@@ -260,12 +281,21 @@ public class EncryptionTests extends TestCase
|
|||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
backupEncryptor.setKeyProvider(backupKeyProvider);
|
||||||
|
mainEncryptor.setKeyProvider(mainKeyProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBootstrapReEncrypt()
|
public void testBootstrapReEncrypt()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// ensure that the backup key store is not available
|
||||||
|
backupKeyStoreParameters.setLocation("");
|
||||||
|
backupKeyStore.reload();
|
||||||
|
|
||||||
reEncryptor.bootstrapReEncrypt();
|
reEncryptor.bootstrapReEncrypt();
|
||||||
fail("Should have caught missing backup key store");
|
fail("Should have caught missing backup key store");
|
||||||
}
|
}
|
||||||
|
@@ -61,7 +61,7 @@ public class KeyStoreKeyProviderTest extends TestCase
|
|||||||
passwords.put(AlfrescoKeyStore.KEY_KEYSTORE_PASSWORD, "ksPwd2");
|
passwords.put(AlfrescoKeyStore.KEY_KEYSTORE_PASSWORD, "ksPwd2");
|
||||||
passwords.put(ALIAS_ONE, "aliasPwd1");
|
passwords.put(ALIAS_ONE, "aliasPwd1");
|
||||||
passwords.put(ALIAS_TWO, "aliasPwd2");
|
passwords.put(ALIAS_TWO, "aliasPwd2");
|
||||||
KeyStoreParameters encryptionParameters = new KeyStoreParameters("JCEKS", "SunJCE", null, FILE_TWO);
|
KeyStoreParameters encryptionParameters = new KeyStoreParameters("test", "JCEKS", "SunJCE", null, FILE_TWO);
|
||||||
KeystoreKeyProvider keyProvider = new KeystoreKeyProvider(encryptionParameters, getKeyStoreLoader(passwords));
|
KeystoreKeyProvider keyProvider = new KeystoreKeyProvider(encryptionParameters, getKeyStoreLoader(passwords));
|
||||||
// FILE_TWO,
|
// FILE_TWO,
|
||||||
// getKeyStoreLoader(),
|
// getKeyStoreLoader(),
|
||||||
@@ -77,7 +77,7 @@ public class KeyStoreKeyProviderTest extends TestCase
|
|||||||
// passwords.put(KeyStoreManager.KEY_KEYSTORE_PASSWORD, "ksPwd2");
|
// passwords.put(KeyStoreManager.KEY_KEYSTORE_PASSWORD, "ksPwd2");
|
||||||
// passwords.put(ALIAS_ONE, "aliasPwd1");
|
// passwords.put(ALIAS_ONE, "aliasPwd1");
|
||||||
// passwords.put(ALIAS_TWO, "aliasPwd2");
|
// passwords.put(ALIAS_TWO, "aliasPwd2");
|
||||||
KeyStoreParameters encryptionParameters = new KeyStoreParameters("JCEKS", "SunJCE", null, keyStoreLocation);
|
KeyStoreParameters encryptionParameters = new KeyStoreParameters("test", "JCEKS", "SunJCE", null, keyStoreLocation);
|
||||||
KeystoreKeyProvider keyProvider = new KeystoreKeyProvider(encryptionParameters, getKeyStoreLoader(passwords));
|
KeystoreKeyProvider keyProvider = new KeystoreKeyProvider(encryptionParameters, getKeyStoreLoader(passwords));
|
||||||
// FILE_TWO,
|
// FILE_TWO,
|
||||||
// getKeyStoreLoader(),
|
// getKeyStoreLoader(),
|
||||||
|
@@ -35,11 +35,14 @@ import org.alfresco.repo.domain.node.NodePropertyEntity;
|
|||||||
import org.alfresco.repo.domain.node.NodePropertyKey;
|
import org.alfresco.repo.domain.node.NodePropertyKey;
|
||||||
import org.alfresco.repo.domain.node.NodePropertyValue;
|
import org.alfresco.repo.domain.node.NodePropertyValue;
|
||||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||||
|
import org.alfresco.repo.lock.JobLockService;
|
||||||
|
import org.alfresco.repo.lock.LockAcquisitionException;
|
||||||
import org.alfresco.repo.node.encryption.MetadataEncryptor;
|
import org.alfresco.repo.node.encryption.MetadataEncryptor;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|
||||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -49,7 +52,6 @@ import org.springframework.context.ApplicationContext;
|
|||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.extensions.surf.util.I18NUtil;
|
import org.springframework.extensions.surf.util.I18NUtil;
|
||||||
|
|
||||||
// TODO lock so that only one encryptor can run at a time
|
|
||||||
/**
|
/**
|
||||||
* Re-encrypts encryptable repository properties using a new set of encryption keys.
|
* Re-encrypts encryptable repository properties using a new set of encryption keys.
|
||||||
* Decrypts the repository properties using the default encryptor, falling back to
|
* Decrypts the repository properties using the default encryptor, falling back to
|
||||||
@@ -59,8 +61,8 @@ import org.springframework.extensions.surf.util.I18NUtil;
|
|||||||
* Can run in one of two ways:
|
* Can run in one of two ways:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li> during bootstrap (used by the community edition of the software)
|
* <li> during bootstrap.
|
||||||
* <li> by using JMX. In this case, the system can stay running while the re-encryption takes place.
|
* <li> by using JMX (available only to Enterprise). In this case, the system can stay running while the re-encryption takes place.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
@@ -71,26 +73,22 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
|
|
||||||
private NodeDAO nodeDAO;
|
private NodeDAO nodeDAO;
|
||||||
private DictionaryDAO dictionaryDAO;
|
private DictionaryDAO dictionaryDAO;
|
||||||
private DictionaryService dictionaryService;
|
|
||||||
private TransactionService transactionService;
|
|
||||||
private QNameDAO qnameDAO;
|
private QNameDAO qnameDAO;
|
||||||
|
|
||||||
private MetadataEncryptor metadataEncryptor;
|
private MetadataEncryptor metadataEncryptor;
|
||||||
// private KeyStoreParameters keyStoreParameters;
|
|
||||||
// private KeyStoreParameters backupKeyStoreParameters;
|
|
||||||
private AlfrescoKeyStore backupKeyStore;
|
|
||||||
private AlfrescoKeyStore keyStore;
|
|
||||||
private KeyProvider backupKeyProvider;
|
private KeyProvider backupKeyProvider;
|
||||||
private KeyProvider keyProvider;
|
private KeyProvider keyProvider;
|
||||||
// private KeyResourceLoader keyResourceLoader;
|
|
||||||
|
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
private TransactionService transactionService;
|
||||||
private RetryingTransactionHelper transactionHelper;
|
private RetryingTransactionHelper transactionHelper;
|
||||||
private String cipherAlgorithm;
|
|
||||||
|
|
||||||
private int chunkSize;
|
private int chunkSize;
|
||||||
private boolean splitTxns = true;
|
private boolean splitTxns = true;
|
||||||
|
|
||||||
|
private static final QName LOCK = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "OrphanReaper");
|
||||||
|
private JobLockService jobLockService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the transaction provider so that each execution can be performed within a transaction
|
* Set the transaction provider so that each execution can be performed within a transaction
|
||||||
*/
|
*/
|
||||||
@@ -106,6 +104,16 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
this.metadataEncryptor = metadataEncryptor;
|
this.metadataEncryptor = metadataEncryptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MetadataEncryptor getMetadataEncryptor()
|
||||||
|
{
|
||||||
|
return metadataEncryptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJobLockService(JobLockService jobLockService)
|
||||||
|
{
|
||||||
|
this.jobLockService = jobLockService;
|
||||||
|
}
|
||||||
|
|
||||||
public void setChunkSize(int chunkSize)
|
public void setChunkSize(int chunkSize)
|
||||||
{
|
{
|
||||||
this.chunkSize = chunkSize;
|
this.chunkSize = chunkSize;
|
||||||
@@ -126,47 +134,11 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
this.dictionaryDAO = dictionaryDAO;
|
this.dictionaryDAO = dictionaryDAO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDictionaryService(DictionaryService dictionaryService)
|
|
||||||
{
|
|
||||||
this.dictionaryService = dictionaryService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQnameDAO(QNameDAO qnameDAO)
|
public void setQnameDAO(QNameDAO qnameDAO)
|
||||||
{
|
{
|
||||||
this.qnameDAO = qnameDAO;
|
this.qnameDAO = qnameDAO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCipherAlgorithm(String cipherAlgorithm)
|
|
||||||
{
|
|
||||||
this.cipherAlgorithm = cipherAlgorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void setKeyStoreParameters(KeyStoreParameters keyStoreParameters)
|
|
||||||
// {
|
|
||||||
// this.keyStoreParameters = keyStoreParameters;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void setBackupKeyStoreParameters(KeyStoreParameters backupKeyStoreParameters)
|
|
||||||
// {
|
|
||||||
// this.backupKeyStoreParameters = backupKeyStoreParameters;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// protected KeyProvider getKeyProvider(AlfrescoKeyStore keyStore)
|
|
||||||
// {
|
|
||||||
// KeyProvider keyProvider = new KeystoreKeyProvider(keyStore);
|
|
||||||
// return keyProvider;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void setBackupKeyStore(AlfrescoKeyStore backupKeyStore)
|
|
||||||
{
|
|
||||||
this.backupKeyStore = backupKeyStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeyStore(AlfrescoKeyStore keyStore)
|
|
||||||
{
|
|
||||||
this.keyStore = keyStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBackupKeyProvider(KeyProvider backupKeyProvider)
|
public void setBackupKeyProvider(KeyProvider backupKeyProvider)
|
||||||
{
|
{
|
||||||
this.backupKeyProvider = backupKeyProvider;
|
this.backupKeyProvider = backupKeyProvider;
|
||||||
@@ -177,86 +149,43 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
this.keyProvider = keyProvider;
|
this.keyProvider = keyProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void setKeyResourceLoader(KeyResourceLoader keyResourceLoader)
|
/**
|
||||||
// {
|
* Attempts to get the lock. If the lock couldn't be taken, then <tt>null</tt> is returned.
|
||||||
// this.keyResourceLoader = keyResourceLoader;
|
*
|
||||||
// }
|
* @return Returns the lock token or <tt>null</tt>
|
||||||
|
*/
|
||||||
// public MetadataEncryptor getMetadataEncryptor()
|
private String getLock(long time)
|
||||||
// {
|
|
||||||
// DefaultEncryptor backupEncryptor = new DefaultEncryptor();
|
|
||||||
// backupEncryptor.setCipherProvider(null); // TODO parameterize
|
|
||||||
// backupEncryptor.setCipherAlgorithm(cipherAlgorithm);
|
|
||||||
// backupEncryptor.setKeyProvider(backupKeyProvider);
|
|
||||||
//
|
|
||||||
// DefaultEncryptor encryptor = new DefaultEncryptor();
|
|
||||||
// encryptor.setCipherProvider(null); // TODO parameterize
|
|
||||||
// encryptor.setCipherAlgorithm(cipherAlgorithm);
|
|
||||||
// encryptor.setKeyProvider(keyProvider);
|
|
||||||
//
|
|
||||||
// DefaultFallbackEncryptor fallbackEncryptor = new DefaultFallbackEncryptor(encryptor, backupEncryptor);
|
|
||||||
// MetadataEncryptor metadataEncryptor = new MetadataEncryptor();
|
|
||||||
// metadataEncryptor.setEncryptor(fallbackEncryptor);
|
|
||||||
// metadataEncryptor.setDictionaryService(dictionaryService);
|
|
||||||
// return metadataEncryptor;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public MetadataEncryptor getMetadataEncryptor(KeyProvider backupKeyProvider, KeyProvider newKeyProvider)
|
|
||||||
// {
|
|
||||||
// DefaultEncryptor backupEncryptor = new DefaultEncryptor();
|
|
||||||
// backupEncryptor.setCipherProvider(null); // TODO parameterize
|
|
||||||
// backupEncryptor.setCipherAlgorithm(cipherAlgorithm);
|
|
||||||
// backupEncryptor.setKeyProvider(backupKeyProvider);
|
|
||||||
//
|
|
||||||
// DefaultEncryptor encryptor = new DefaultEncryptor();
|
|
||||||
// encryptor.setCipherProvider(null); // TODO parameterize
|
|
||||||
// encryptor.setCipherAlgorithm(cipherAlgorithm);
|
|
||||||
// encryptor.setKeyProvider(newKeyProvider);
|
|
||||||
//
|
|
||||||
// DefaultFallbackEncryptor fallbackEncryptor = new DefaultFallbackEncryptor(encryptor, backupEncryptor);
|
|
||||||
// MetadataEncryptor metadataEncryptor = new MetadataEncryptor();
|
|
||||||
// metadataEncryptor.setEncryptor(fallbackEncryptor);
|
|
||||||
// metadataEncryptor.setDictionaryService(dictionaryService);
|
|
||||||
// return metadataEncryptor;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// protected KeyProvider getKeyProvider(final Map<String, Key> keys)
|
|
||||||
// {
|
|
||||||
// KeyProvider keyProvider = new KeyProvider()
|
|
||||||
// {
|
|
||||||
// @Override
|
|
||||||
// public Key getKey(String keyAlias)
|
|
||||||
// {
|
|
||||||
// return keys.get(keyAlias);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// return keyProvider;
|
|
||||||
// }
|
|
||||||
|
|
||||||
protected Encryptor getEncryptor(KeyProvider keyProvider)
|
|
||||||
{
|
{
|
||||||
DefaultEncryptor encryptor = new DefaultEncryptor();
|
try
|
||||||
encryptor.setCipherProvider(null); // TODO parameterize
|
{
|
||||||
encryptor.setCipherAlgorithm(cipherAlgorithm);
|
return jobLockService.getLock(LOCK, time);
|
||||||
encryptor.setKeyProvider(keyProvider);
|
}
|
||||||
|
catch (LockAcquisitionException e)
|
||||||
return encryptor;
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For testing use.
|
* Attempts to get the lock. If it fails, the current transaction is marked for rollback.
|
||||||
*
|
*
|
||||||
* @param keyProvider
|
* @return Returns the lock token
|
||||||
*/
|
*/
|
||||||
void reEncrypt(KeyProvider keyProvider)
|
private void refreshLock(String lockToken, long time)
|
||||||
{
|
{
|
||||||
metadataEncryptor.setEncryptor(getEncryptor(keyProvider));
|
if (lockToken == null)
|
||||||
reEncryptImpl();
|
{
|
||||||
|
throw new IllegalArgumentException("Must provide existing lockToken");
|
||||||
|
}
|
||||||
|
jobLockService.refreshLock(lockToken, LOCK, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void reEncrypt(final MetadataEncryptor metadataEncryptor, final List<NodePropertyEntity> properties)
|
protected void reEncryptProperties(final List<NodePropertyEntity> properties, final String lockToken)
|
||||||
{
|
{
|
||||||
final Iterator<NodePropertyEntity> it = properties.iterator();
|
final Iterator<NodePropertyEntity> it = properties.iterator();
|
||||||
|
|
||||||
|
// TODO use BatchProcessWorkerAdaptor?
|
||||||
|
|
||||||
BatchProcessor.BatchProcessWorker<NodePropertyEntity> worker = new BatchProcessor.BatchProcessWorker<NodePropertyEntity>()
|
BatchProcessor.BatchProcessWorker<NodePropertyEntity> worker = new BatchProcessor.BatchProcessWorker<NodePropertyEntity>()
|
||||||
{
|
{
|
||||||
public String getIdentifier(NodePropertyEntity entity)
|
public String getIdentifier(NodePropertyEntity entity)
|
||||||
@@ -266,6 +195,7 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
|
|
||||||
public void beforeProcess() throws Throwable
|
public void beforeProcess() throws Throwable
|
||||||
{
|
{
|
||||||
|
refreshLock(lockToken, chunkSize * 100L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterProcess() throws Throwable
|
public void afterProcess() throws Throwable
|
||||||
@@ -287,7 +217,7 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
// decrypt...
|
// decrypt...
|
||||||
Serializable decrypted = metadataEncryptor.decrypt(propertyQName, sealed);
|
Serializable decrypted = metadataEncryptor.decrypt(propertyQName, sealed);
|
||||||
|
|
||||||
// ...and then re-encrypt. The new keys will be used.
|
// ...and then re-encrypt. The new key will be used.
|
||||||
Serializable resealed = metadataEncryptor.encrypt(propertyQName, decrypted);
|
Serializable resealed = metadataEncryptor.encrypt(propertyQName, decrypted);
|
||||||
|
|
||||||
// TODO update resealed using batch update?
|
// TODO update resealed using batch update?
|
||||||
@@ -315,13 +245,17 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
@Override
|
@Override
|
||||||
public Collection<NodePropertyEntity> getNextWork()
|
public Collection<NodePropertyEntity> getNextWork()
|
||||||
{
|
{
|
||||||
int count = 0;
|
|
||||||
List<NodePropertyEntity> sublist = new ArrayList<NodePropertyEntity>(chunkSize);
|
List<NodePropertyEntity> sublist = new ArrayList<NodePropertyEntity>(chunkSize);
|
||||||
|
|
||||||
|
synchronized(it)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
while(it.hasNext() && count < chunkSize)
|
while(it.hasNext() && count < chunkSize)
|
||||||
{
|
{
|
||||||
sublist.add(it.next());
|
sublist.add(it.next());
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sublist;
|
return sublist;
|
||||||
}
|
}
|
||||||
@@ -329,12 +263,12 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
|
|
||||||
// TODO, "propertize" these numbers
|
// TODO, "propertize" these numbers
|
||||||
new BatchProcessor<NodePropertyEntity>(
|
new BatchProcessor<NodePropertyEntity>(
|
||||||
I18NUtil.getMessage(""),
|
I18NUtil.getMessage("reencryptor.batchprocessor.name"), // TODO i18n name
|
||||||
transactionHelper,
|
transactionHelper,
|
||||||
provider,
|
provider,
|
||||||
2, 20,
|
2, 100,
|
||||||
applicationContext,
|
applicationContext,
|
||||||
logger, 20).process(worker, splitTxns);
|
logger, 100).process(worker, splitTxns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,7 +276,7 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
*/
|
*/
|
||||||
public int bootstrapReEncrypt() throws MissingKeyStoreException
|
public int bootstrapReEncrypt() throws MissingKeyStoreException
|
||||||
{
|
{
|
||||||
if(backupKeyStore.getKey(KeyProvider.ALIAS_METADATA) == null)
|
if(backupKeyProvider.getKey(KeyProvider.ALIAS_METADATA) == null)
|
||||||
{
|
{
|
||||||
throw new MissingKeyStoreException("Backup key store is either not present or does not contain a metadata encryption key");
|
throw new MissingKeyStoreException("Backup key store is either not present or does not contain a metadata encryption key");
|
||||||
}
|
}
|
||||||
@@ -353,30 +287,50 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
* Re-encrypt by decrypting using the configured keystore and encrypting using a keystore configured using the provided new key store parameters.
|
* Re-encrypt by decrypting using the configured keystore and encrypting using a keystore configured using the provided new key store parameters.
|
||||||
* Called from e.g. JMX.
|
* Called from e.g. JMX.
|
||||||
*
|
*
|
||||||
* Note: it is the responsibility of the end user to ensure that the keystore configured by newKeyStoreParameters is
|
* Note: it is the responsibility of the end user to ensure that the underlying keystores have been set up appropriately
|
||||||
* placed in the repository keystore directory. This can be done while the repository is running and it will be picked
|
* i.e. the old key store is backed up to the location defined by the property '${dir.keystore}/backup-keystore' and the new
|
||||||
* up automatically the next time the repository restarts.
|
* key store replaces it. This can be done while the repository is running.
|
||||||
*/
|
*/
|
||||||
public int reEncrypt() throws MissingKeyStoreException
|
public int reEncrypt() throws MissingKeyStoreException
|
||||||
{
|
{
|
||||||
backupKeyStore.reload();
|
// refresh the key providers to pick up changes made
|
||||||
keyStore.reload();
|
backupKeyProvider.refresh();
|
||||||
if(keyStore.getKey(KeyProvider.ALIAS_METADATA) == null)
|
keyProvider.refresh();
|
||||||
|
|
||||||
|
if(keyProvider.getKey(KeyProvider.ALIAS_METADATA) == null)
|
||||||
{
|
{
|
||||||
throw new MissingKeyStoreException("Main key store is either not present or does not contain a metadata encryption key");
|
throw new MissingKeyStoreException("Main key store is either not present or does not contain a metadata encryption key");
|
||||||
}
|
}
|
||||||
if(backupKeyStore.getKey(KeyProvider.ALIAS_METADATA) == null)
|
if(backupKeyProvider.getKey(KeyProvider.ALIAS_METADATA) == null)
|
||||||
{
|
{
|
||||||
throw new MissingKeyStoreException("Backup key store is either not present or does not contain a metadata encryption key");
|
throw new MissingKeyStoreException("Backup key store is either not present or does not contain a metadata encryption key");
|
||||||
}
|
}
|
||||||
return reEncryptImpl();
|
|
||||||
|
int numProps = reEncryptImpl();
|
||||||
|
return numProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int reEncryptImpl()
|
protected int reEncryptImpl()
|
||||||
{
|
{
|
||||||
// get properties that are encrypted
|
RetryingTransactionCallback<String> txnWork = new RetryingTransactionCallback<String>()
|
||||||
|
{
|
||||||
|
public String execute() throws Exception
|
||||||
|
{
|
||||||
|
String lockToken = getLock(20000L);
|
||||||
|
return lockToken;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
String lockToken = transactionService.getRetryingTransactionHelper().doInTransaction(txnWork, false, true);
|
||||||
|
if(lockToken == null)
|
||||||
|
{
|
||||||
|
logger.warn("Can't get lock. Assume multiple re-encryptors ...");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get encrypted properties
|
||||||
Collection<PropertyDefinition> propertyDefs = dictionaryDAO.getPropertiesOfDataType(DataTypeDefinition.ENCRYPTED);
|
Collection<PropertyDefinition> propertyDefs = dictionaryDAO.getPropertiesOfDataType(DataTypeDefinition.ENCRYPTED);
|
||||||
// TODO use callback mechanism
|
// TODO use callback mechanism, or select based on set of nodes?
|
||||||
List<NodePropertyEntity> properties = nodeDAO.selectProperties(propertyDefs);
|
List<NodePropertyEntity> properties = nodeDAO.selectProperties(propertyDefs);
|
||||||
|
|
||||||
if(logger.isDebugEnabled())
|
if(logger.isDebugEnabled())
|
||||||
@@ -384,8 +338,8 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
logger.debug("Found " + properties.size() + " properties to re-encrypt...");
|
logger.debug("Found " + properties.size() + " properties to re-encrypt...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// reencrypt these properties
|
// reencrypt these properties TODO don't call if num props == 0
|
||||||
reEncrypt(metadataEncryptor, properties);
|
reEncryptProperties(properties, lockToken);
|
||||||
|
|
||||||
if(logger.isDebugEnabled())
|
if(logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -396,8 +350,7 @@ public class ReEncryptor implements ApplicationContextAware
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setApplicationContext(ApplicationContext applicationContext)
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||||
throws BeansException
|
|
||||||
{
|
{
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<imports>
|
<imports>
|
||||||
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
|
||||||
|
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
|
||||||
</imports>
|
</imports>
|
||||||
|
|
||||||
<namespaces>
|
<namespaces>
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
<type name="test:base">
|
<type name="test:base">
|
||||||
<title>Base</title>
|
<title>Base</title>
|
||||||
<description>The Base Type</description>
|
<description>The Base Type</description>
|
||||||
<parent></parent>
|
<parent>cm:content</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<property name="test:prop1">
|
<property name="test:prop1">
|
||||||
|
@@ -42,8 +42,11 @@ import org.alfresco.service.cmr.search.SearchParameters.FieldFacetSort;
|
|||||||
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition;
|
import org.alfresco.service.cmr.search.SearchParameters.SortDefinition;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.apache.commons.codec.net.URLCodec;
|
import org.apache.commons.codec.net.URLCodec;
|
||||||
|
import org.apache.commons.httpclient.Header;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
import org.apache.commons.httpclient.HttpException;
|
import org.apache.commons.httpclient.HttpException;
|
||||||
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
|
import org.apache.commons.httpclient.URI;
|
||||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
||||||
import org.apache.commons.httpclient.auth.AuthScope;
|
import org.apache.commons.httpclient.auth.AuthScope;
|
||||||
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
|
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
|
||||||
@@ -303,13 +306,23 @@ public class SolrQueryHTTPClient
|
|||||||
body.put("textAttributes", textAttributes);
|
body.put("textAttributes", textAttributes);
|
||||||
|
|
||||||
PostMethod post = new PostMethod(url.toString());
|
PostMethod post = new PostMethod(url.toString());
|
||||||
// TOOD deal with redirects for SSL
|
|
||||||
post.setRequestEntity(new ByteArrayRequestEntity(body.toString().getBytes("UTF-8"), "application/json"));
|
post.setRequestEntity(new ByteArrayRequestEntity(body.toString().getBytes("UTF-8"), "application/json"));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
httpClient.executeMethod(post);
|
httpClient.executeMethod(post);
|
||||||
|
|
||||||
|
if(post.getStatusCode() == HttpStatus.SC_MOVED_PERMANENTLY || post.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY)
|
||||||
|
{
|
||||||
|
Header locationHeader = post.getResponseHeader("location");
|
||||||
|
if (locationHeader != null)
|
||||||
|
{
|
||||||
|
String redirectLocation = locationHeader.getValue();
|
||||||
|
post.setURI(new URI(redirectLocation, true));
|
||||||
|
httpClient.executeMethod(post);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (post.getStatusCode() != HttpServletResponse.SC_OK)
|
if (post.getStatusCode() != HttpServletResponse.SC_OK)
|
||||||
{
|
{
|
||||||
throw new LuceneQueryParserException("Request failed " + post.getStatusCode() + " " + url.toString());
|
throw new LuceneQueryParserException("Request failed " + post.getStatusCode() + " " + url.toString());
|
||||||
|
Reference in New Issue
Block a user