Reset Access Datasources Without Resetting ColdFusion

I am “stuck” with a few web applications that provide web front-ends to Access databases. I am not the owner of these databases, and for various reasons, the database owner will not upgrade it to SQL Server. Alas, this sometimes causes headaches like the following.

The Access databases are on a network fileserver. Occasionally, this server goes down or resets, and ColdFusion’s datasource connection to the database gets stuck in a disrupted state. I’ve come to learn two things you can try to get ColdFusion’s connection to the Access datasource working again without resetting the entire ColdFusion Application Server service, which is obviously disruptive to your entire site and all of its applications.

  1. Reset the ODBC services. The ColdFusion ODBC services (such as “ColdFusion 8 ODBC Agent” and “ColdFusion 8 ODBC Server”) actually handle the ODBC connections to DataDirect driver databases such as Microsoft Access databases. This is handy. Just reset these services and often connectivity is restored.
  2. Use the “Disable Connections” option in the datasource configuration. If you are using JDBC drivers (for instance, perhaps to connect to Microsoft Access 2007 databases), resetting the ColdFusion 8 ODBC Server service won’t help. Darn. However, if you go into the datasource’s configuration in ColdFusion Administrator, you can check the “Disable Connections” checkbox and submit the change. This will force ColdFusion to disconnect from the database. Immediately go back in and uncheck the checkbox and submit again. Your datasource will now have connectivity reestablished without a ColdFusion restart!

Happy days! The second option won’t be helpful to you if you have many, many datasources. However, this is better than a ColdFusion reset that would disrupt all of your apps.

CFExecute Output Not Going in Your Variable?

I’m blogging this because it’s a little tidbit I always waste about 30 minutes figuring out before I remember it.

The <cfexecute> tag can return the output of the execution into a variable if you supply one with the variable=”" attribute. However, I will try to do this, and (a) the script returns too quickly, and (b) there is no output when there should be.

There is an easy solution! <cfexecute> is expecting the timeout=”" attribute. Supply it a timeout value in seconds, and it will then wait for the script to finish executing and thus have output to store in your variable.

You may be wondering why this is necessary, because even without the timeout=”" attribute, the execution still occurs. <cfexecute> just doesn’t return any output. That’s because <cfexecute> is indeed running, it is just immediately timing out–effectively giving up on the executed process–and thus not returning the output. By supplying a timeout, ColdFusion hangs around waiting for the process to complete before returning its output.

Generating a Decrypted Memento for a Transfer Decorator

In my last blog post, I discussed how to efficiently handle multiple encrypted fields while using Transfer. The key was using onMissingMethod in the Transfer decorator. However, what about when we use the memento with Transfer's getMemento() method? This approach can be especially handy to quickly transfer an object's properties when using web services to Flex or AJAX front ends.

For reference, here was the object definition we were using in our sample Transfer configuration.

XML:
  1. <object name="Reg" table="Regs" decorator="MyProj.com.Reg">
  2.   <id name="ID" column="RegID" type="numeric" />
  3.   <property name="FName" type="string" column="RegFName" />
  4.   <property name="LName" type="string" column="RegLName" />
  5.   <property name="LastMod" type="date" column="RegLastMod" />
  6.   <property name="Expires" type="date" column="RegExpires" nullable="true" />
  7.   <property name="EncHome" type="string" column="regHome" />
  8.   <property name="EncWork" type="string" column="regWork" />
  9.   <property name="EncMobile" type="string" column="regMobile" />
  10.   <property name="EncSMS" type="string" column="regSMS" />
  11. </object>

The process is very simple. Recall that we prefixed our Transfer properties with "Enc" to know which fields are encrypted. Let's create a getDecryptedMemento() method. It will loop through all of the keys in the memento, which is just a struct, and decrypt any of the encrypted fields, saving them as new keys in the struct (i.e. "EncHome" is decrypted as "Home" in the struct).

Something like this will do the trick:

CFM:
  1. <cffunction name="getDecryptedMemento" access="public" returntype="struct" output="false">
  2.   <cfset var memento=getMemento()>
  3.   <cfset var key="">
  4.   <cfset var newkey="">
  5.   <cfloop index="key" list="#StructKeyList(memento)#">
  6.     <cfif Left(key,3) is "Enc">
  7.       <cfset newkey=RemoveChars(key,1,3)>
  8.       <cfset memento[newkey]=decryptValue(memento[key])>
  9.     </cfif>
  10.   </cfloop>
  11.   <cfreturn memento>
  12. </cffunction>

Not much to it. Note that we would use the same decryption function as we are using in onMissingMethod for the dynamic accessors. I'm calling it decryptValue() for this sample.

In the end, our getDecryptedMemento() method returns a memento that looks just like the Transfer-generated getMemento() output, with decrypted versions of the encrypted fields!

Handling Multiple Encrypted Fields in a Transfer Decorator

I had a recent project that had multiple fields in a particular table that needed to be encrypted for privacy and security considerations. I was using Transfer for the project. The typical way to handle the encryption is to create custom accessor methods in a decorator component. The Transfer wiki has a decent explanation of this concept on a page entitled How to Encrypt User Passwords Using a Decorator. However, it is intentionally simple, demonstrating a single property. Multiply your getter/setter methods by how many properties you will be working with, and the lines of code can add up. This framework stuff is supposed to prevent that kind of repetition! Well, utilizing onMissingMethod() and the core concept on the Transfer decorator example, we can handle this scenario efficiently.

First, let's consider the object definition in our sample Transfer configuration file.

XML:
  1. <object name="Reg" table="Regs" decorator="MyProj.com.Reg">
  2.   <id name="ID" column="RegID" type="numeric" />
  3.   <property name="FName" type="string" column="RegFName" />
  4.   <property name="LName" type="string" column="RegLName" />
  5.   <property name="LastMod" type="date" column="RegLastMod" />
  6.   <property name="Expires" type="date" column="RegExpires" nullable="true" />
  7.   <property name="EncHome" type="string" column="regHome" />
  8.   <property name="EncWork" type="string" column="regWork" />
  9.   <property name="EncMobile" type="string" column="regMobile" />
  10.   <property name="EncSMS" type="string" column="regSMS" />
  11. </object>

Note that I have prefixed the Transfer properties with "Enc". This isn't required, but will simplify our processing later on. So in this sample, we have 4 properties: Home, Work, Mobile, and SMS. The concept is that these are client phone numbers that we want to protect with encryption. So, Transfer will generate getEncHome(), getEncWork(), getEncMobile(), getEncSMS(), and corresponding setters. However, we want to provide getHome(), getWork(), getMobile(), getSMS(), and corresponding setters, that get and set the properties after encryption/decryption.

Use onMissingMethod()

To accomplish this, we might have an onMissingMethod() function in the decorator like this:

CFM:
  1. <cffunction name="onMissingMethod" access="public" returntype="any" output="false">
  2.   <cfargument name="missingMethodName" type="string" required="true">
  3.   <cfargument name="missingMethodArguments" type="struct" required="true">
  4.   <cfscript>
  5.     var func="";
  6.     var encList="Home,Mobile,SMS,Work";
  7.     var method=Arguments.missingMethodName;
  8.     var args=Arguments.missingMethodArguments;
  9.     var firstArg=args[ListFirst(StructKeyList(args))];
  10.     var prop=RemoveChars(method,1,3);
  11.     // Handle encryption/decryption of encrypted values:
  12.     if( ListFindNoCase("get,set",Left(method,3)) and
  13.         ListFindNoCase(encList,prop) )
  14.     {
  15.       func=variables[Insert("Enc",method,3)];
  16.       if( Left(method,3) is "get")
  17.         return decryptValue(func());
  18.       else
  19.         func(encryptValue(firstArg));
  20.     }
  21.   </cfscript>
  22. </cffunction>

As a good security measure, we use an "encList" string to check that only proper methods can be called. Then we examine the method name. If it starts with "get" or "set" and ends with one of the list items, we proceed. Thus, we'll process a method like getHome(), but not a method like getFoo(). We then call getEncHome() and decrypt it for getters, encrypt and call setEncHome() for setters.

Dynamic Method Calling

But alas, how do we do this dynamically without a long if-then-else chain? We call the proper method by referencing it from the component's variables scope. Terrence Ryan describes this in his blog post Cheap and Easy Dynamic Method Calling in CFScript. We construct the method name, in our case, by inserting "Enc" after the "get" or "set" prefix of the method name passed into onMissingMethod (thus "getHome" becomes the Transfer method "getEncHome"). Assign the function to the local "func" variable, then call it as if "func" was the function. Finally, handle any encryption or decryption that you will be doing. For this sample, I have encryptValue() and decryptValue() methods handling the details of that work.

Summary

We've used two solutions to handle multiple encrypted fields in the decorator. First, we used onMissingMethod() to handle processing of all of the properties in a single method. Then, we used dynamic method calling to call the Transfer-generated accessors within onMissingMethod().

The end result is being able to use setHome(), getHome(), etc. with the encryption and decryption being handled automatically. Great!

In addition to accessors, we may sometimes want to use the object's memento with the Transfer method getMemento(). In my next blog post, I'll demonstrate how that process can also be done very efficiently.

  Theme Brought to you by Directory Journal and Elegant Directory.