Site Network: Personal | Professional | Photography

Technical Blog

This blog will contain content related to Java, Seam, Security, my sites and projects, as well as other technical subjects I am interested in.

Comments and questions are welcome!

Archive for the ‘ATG’ Category

Updates to the ATG RSS Feed Module

Sunday, May 4th, 2008

Thanks to Doug Henderson sending me some code updates I have released a new version of the RSS Feed Droplet (first mentioned in this post) which supports configurable character encodings. This can be very useful if you have "interesting" characters in the content you are publishing.

I have also rolled the code into my ATG Open Source Module Pack, so that I can maintain everything in one location.

Also: please note that you cannot reformat the JSP code, or introduce any spaces as it will break the feed. I've made note of that in the module's Readme as well.

Enjoy!

Adding the “Upload Image” Button in the ACC

Monday, April 14th, 2008

If you have your own content repository items defined, and you'd like the ACC to provide the Upload Image functionality for your internal binary properties, Russell Moore has figured it out:

In /atg/devtools/ create a local version of admins.xml:

 
<repository-admins>
  <default-admin id="YourRepository">
    <display-name>Your Content</display-name>
    <repository-name>YourRepository</repository-name>
    <create-bean-displays>
      <bean-display type="media" class="atg.ui.repository.MediaInternalBinaryEditor">
<property name="internalBinaryExcludedTableProperties" value="path, version, mimeType,data, length,url"/>
      </bean-display>
    </create-bean-displays>
    <standard-bean-displays>
      <bean-display type="media" class="atg.ui.repository.MediaInternalBinaryEditor">
<property name="internalBinaryExcludedTableProperties" value="version, mimeType, data, length, url"/>
<property name="internalBinaryTableReadOnlyProperties" value="path"/>
      </bean-display>
    </standard-bean-displays>
  </default-admin>
</repository-admins>
 

Thanks Russell!

Getting the Real IP Address from a Proxied Request in ATG

Tuesday, April 8th, 2008

Many things can obscure the real IP address of the end user when they visit your site: a load balancer in front of your ATG cluster, Akamai, the user's ISP or office network, and more. This makes correlating logging events, or using the ATG session IP validation security option, and more, very difficult. In light of that challange I've added a new mini-module to my Open Source ATG Modules called the ProxyIPFixer. It uses a simple ATG pipeline Servlet to examine the X-FORWARDED-FOR request header, and if it finds one, parse through the IP addresses to find the originating IP address of the user, and puts that value into the ATG Request object's remoteAddr property.

This allows downstream pipeline servlets, code, and pages to see the real user's IP address.

The caveat is that the header can be faked, and that some ISPs/companies, such as AOL, do not set the true end point of the user, and you can only see back to their outgoing proxy server. In AOL's case in particular, they can also route subsequent requests by the same AOL user through different AOL proxy points, which will make it appear that someone is hijacking a session (if you're using the ATG session security mechanism). So be aware of the limitations. However it can be very useful.

For those who don't want to download the whole module package, I have attached the Java source and the ATG properties file to this post.

Enjoy! (and as always feel free to contact me with questions, issues, improvements, etc...)

ProxyIPFixerServlet Java Source

ProxyIPFixer ATG Properties File

ATG Project Templates and Open Source Modules

Tuesday, February 26th, 2008

I have just added a new page to my site:

ATG Technologies

This page currently has ATG Project templates, with ant build files, for ATG 7.1 and ATG 2006.3 and 2007.1 available for download. It also has a collection of small handy ATG Modules which I have created and released as open source, using the Apache License.

These modules provide everything from Cache Header control, to Captcha, to Encryption, etc... I will be enhancing them and adding new modules as time goes on.

Check them out, and e-mail me with any comments, questions, bugs, requests, code updates, or contributions.

Oracle PL/SQL Loop to Update Fields with Periodic Commits

Tuesday, February 5th, 2008

Have you ever had one of those moments where you've just completed importing 1.7 million user records from flat files into an normalized set of ATG Personalization tables, plus some custom tables, and you only then realize that the passwords from the old system, while in the compatible md5sum format, are all UPPERCASE, while ATG uses all lowercase hashes?

It's not a great moment.

Initially I was stuck in an ATG specific mind-set. I figured the two possible solutions were as follows:

  1. Use the already sub-classed ProfileFormHandler to override the out of the box password comparison and do an uppercase on the hash value before checking it against the database. Also update the create and update related methods as well to uppercase the hash.
  2. Drop the 1.7 million records. Update the importer tool to lowercase the incoming md5 hash before persisting it.

The issue with option 1 is that it means overriding the perfectly good out of the box behavior of ATG Profiles for the life of the application due to a set of awkward initial data. I'm happy to override ATG behavior when I should, but this just felt wrong.

The issue with option 2 is that it would take approx 2-3 days. The import process was slow and had to be done in small chunks for reasons I won't get into now.

It wasn't until after sleeping on it that I realized I had put myself into the ATG box unnecessarily. Let's just fix the data in situ. I didn't know much PL/SQL but some Googling (I love how that's a common verb now, btw) led me to write up this:

 
declare i number := 0;
begin
  FOR r IN (SELECT id FROM dps_user)
  loop
    UPDATE dps_user
       SET password = lower(password)
     WHERE id = r.id;
  	i := i+1;
	IF mod(i, 10000) = 0 THEN    -- Commit every 10000 records
	      COMMIT;
	end IF;
  end loop;
commit;
end;
 

I'm no Oracle DBA, but it works!

Essentially it loops through every row in the dps_user table, and replaces the password with an all-lowercase version of itself. Every 10,000 records it does a commit as the full 1.7 million records would overwhelm the undo tablespace.

Enjoy!