<bean id="transferObjectInjector" class="coldspring.transfer.TDOBeanInjectorObserver">
<constructor-arg name="transfer"><ref bean="transfer" /></constructor-arg>
<constructor-arg name="suffixList"><value>service,datasource</value></constructor-arg>
<constructor-arg name="debugMode"><value>true</value></constructor-arg>
</bean>
Normally you would declare it non-lazy but we already do other non-lazy initialization so in our ColdSpring factory initialization code, we do this:
<constructor-arg name="transfer"><ref bean="transfer" /></constructor-arg>
<constructor-arg name="suffixList"><value>service,datasource</value></constructor-arg>
<constructor-arg name="debugMode"><value>true</value></constructor-arg>
</bean>
<cfset bf.getBean("transferObjectInjector") />
to force the bean injector to be initialized which, in turn, registers itself as a Transfer event listener (so that it can intercept object creation). The suffixList specifies that any set*Service() method or set*Datasource() method on the business objects managed by Transfer should be matched to beans defined in ColdSpring and injected.
So how do we add the on-demand encryption to our business object's data?First, we add a setter to the Transfer object decorator (our business object) to match our encryption service:
function setEncryptionService(encryptionService) {
variables.encryptionService = encryptionService;
}
(Yes, I use cfscript a lot these days)
Then we override the setter for the data we need to encrypt:
variables.encryptionService = encryptionService;
}
function setSFPassword(password) {
getTransferObject().setSFPassword( variables.encryptionService.encryptStr(password) );
}
This uses the (injected) encryption service to encrypt the (user-submitted) password and then pass it to the underlying setter (generated by Transfer). That was easy. But what about the getter? That has to handle unencrypted data as well as encrypted data.
Here's the matching setter:
getTransferObject().setSFPassword( variables.encryptionService.encryptStr(password) );
}
function getSFPassword() {
var password = getTransferObject().getSFPassword();
var decrypted = "";
try {
decrypted = variables.encryptionService.decryptStr(password);
if (decrypted == "") decrypted = password;
return decrypted;
} catch (any ex) {
// must be unencrypted already return password;
}
}
We use the underlying getter to retrieve the value from the database and then we try to decrypt it. If decryption fails, we assume the data is currently unencrypted and return it as-is. Note that decryption can fail in two ways: it can throw an exception or it can return an empty string!
This allows us to encrypt data upon any user updates while still handled unencrypted legacy data during the migration period.var password = getTransferObject().getSFPassword();
var decrypted = "";
try {
decrypted = variables.encryptionService.decryptStr(password);
if (decrypted == "") decrypted = password;
return decrypted;
} catch (any ex) {
// must be unencrypted already return password;
}
}

0 responses so far ↓
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment