Wednesday, December 29, 2010

Grails and Spring Security

I'm developing a personal 'cloud browser' application for iRODS based on my Jargon libraries. Previously, I had started looking at a set of Spring Security libraries that could be used in web apps, such that authentication and gathering of roles could be done against the iRODS security, using iRODS user groups for role based access.

My Spring Security library has a custom AuthenticationManager as well as a custom AuthenticationFilter and AuthenticationToken, as iRODS security uses not only user and password, but also zone, resource, host, and port. Because of the differences, I did not find the Spring Security Grails plug-in to be suitable. Besides, since I am already testing a set of custom libraries, I wanted to take advantage of the library and the XML wiring I had already created.

First, here's what my XML wiring looks like:


I had started to re-create this using Spring DSL in my resources.groovy file, but I was finding it difficult to translate (I'm still very new at Spring DSL, and it had more to do with just getting this done).

I added my mappings to the resources.xml file in my Grails app, and started things up just to see if Spring could wire this together. Knock me over with a feather but that worked! The one issue I had was a complaint about the Spring Security namespace, which was corrected by adding these items to my BuildConfig.groovy:


dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
compile 'org.irods:jargon-core:0.0.3-SNAPSHOT'
compile 'org.irods:jargon-security:0.0.1-SNAPSHOT'
compile 'org.springframework.security:spring-security-core:3.0.5.RELEASE'
compile 'org.springframework.security:spring-security-web:3.0.5.RELEASE'
compile 'org.springframework.security:spring-security-config:3.0.5.RELEASE'

//test 'org.irods:jargon-test:0.0.1-SNAPSHOT'
// runtime 'mysql:mysql-connector-java:5.1.5'
}
The key was actually the spring-security-config dependency.

Next, I started testing with a browser, only to find that the security was not being enforced. The missing step was to add the delegating filter proxy to my web.xml file. Well...what web.xml file? Like I said, I'm very new to Grails. It turns out that I needed to fire up the grails console and do a

grails install-templates


command. This adds templates for various artifacts to my project. Then it's a simple matter of editing the template web.xml file to add my delegating filter proxy mapping like so:


Now, I have not completed all the testing, but it does seem like I'm on the right path. I'll let you all know how it's going, but I think it'll work out.

Tuesday, December 28, 2010

Fedora 14 running full-screen on Virtual Box for Mac

A big shout-out to www.sysprobs.com for this entry:


http://www.sysprobs.com/install-fedora-14-virtualbox-working-guest-additions

As I was having endless headaches mining the Google for tips on getting Fedora Linux 14 to run in full-screen mode on my Mac using VirtualBox. The missing pieces were some yum updates that had to be run, it's now running beautifully.

As is typical, I had to wade through several pages of hits that didn't solve the problem, hopefully this will boost the real solution.

Sunday, December 12, 2010

Testing Groovy/Grails with Jargon

I'm having a great time looking at Groovy and Grails as a rapid development environment for iRODS web interfaces via the new Jargon API I am developing.

Jargon is a pure Java API that encapsulates the iRODS server protocol. I am developing a new version, and one of the goals is to make it more usable in Spring-based apps. I have web projects to develop, and at the same time, I need to kick the tires on how Jargon works with dynamic scripting languages. So far, so good. I'm able to wire together some simple things, and utilize the Jargon libraries quite smoothly. Here's a little bit of wiring together of IRODSFileSystem using Spring DSL:

beans = {

irodsFileSystem(org.irods.jargon.core.pub.IRODSFileSystem) {
bean ->
bean.factoryMethod = "instance"
bean.singleton = true
}


irodsFileServiceWrapperService(mydrop.IrodsFileServiceWrapperService) {
irodsFileSystem = ref("irodsFileSystem")
}

irodsAuthenticationHelperService(mydrop.IRODSAuthenticationHelperService) {
irodsFileServiceWrapperService = ref("irodsFileServiceWrapperService")
}

}





Here's a bit of my hacked auth code (I need to see how to more formally wire in Spring Security with Grails:

IrodsFileServiceWrapperService irodsFileServiceWrapperService

/**
* Validate the user by logging into iRODS under the given credentials. Also retrieve the iRODS user groups for
* use in role-based access
* @param host
* @param port
* @param zone
* @param userName
* @param password
* @param resource
* @return
*/
def authenticate(String host, int port, String zone, String userName, String password, String resource) throws AuthenticationException {
def irodsAccount = IRODSAccount.instance(host, port, userName, password, resource, zone, "")
def irodsFileSystem = irodsFileServiceWrapperService.getIrodsFileSystem()
def irodsAccountAuthenticationManager = new IRODSAccountAuthenticationManager()
irodsAccountAuthenticationManager.setIrodsAccessObjectFactory irodsFileSystem.getIRODSAccessObjectFactory()
def irodsAuthentication = new IRODSAuthenticationToken(irodsAccount)
def irodsAuthenticationToken = irodsAccountAuthenticationManager.authenticate(irodsAuthentication)
SecurityContextHolder.getContext().setAuthentication(irodsAuthenticationToken);
}



I'm certain that this is not the most beautiful Grails code, but it's promising nevertheless.

Saturday, November 13, 2010

Ruby on Rails on OSX 10.6

A bit of frustration picking up Rails again on Mac. It seemed that I could not install rails via the

>gem install rails


command. I kept getting an exception like this:

ERROR: http://gems.rubyforge.org/ does not appear to be a repository


Well, I kept messing with gems.rubyforge.org, when it appear that the gems install on the mac was actually the problem. So I tried gem udpate --system, which, of course, failed because it tries to talk to gems.rubyforge.org.

Solution...go to http://rubygems.org/pages/download and manually download an updated gems..once I did this, gems, now properly configured with the gem repository, seems to work fine.

Back to Rails and Ruby after something of hiatus, delayed for several hours messing with gems. Tolerating frustration is a vital part of the developer's tool-set.

Tuesday, October 26, 2010

Peeking at iRODS XML packing instructions using icommands

In working on the Jargon API, I'm often comparing the protocol operations with icommands. A helpful tip to turn on XML logging of the icommands you are executing:

type this at the command prompt before issuing your commands to set some environment variables:

export irodsProt=1; export irodsLogLevel=9;

Wednesday, October 20, 2010

Hover highlighting for drag and drop in a Swing JTree

This was a pain in the butt. I am working on a file browser for iRODS that allows easy movement of data from local file system to iRODS resources. I'm implementing drag-and-drop gestures of all sorts, and the Swing JTree is pretty bare-bones, and lacked hover highlighting when dragging.

I found a very helpful thread here, pertaining to Swing JTables, but I found it easily adaptable to JTree, adding an alpha background color to the original code. In my subclass of JTree, in which I implement DropTargetListener, I added this


class {

private int highlightedRow = -1;
private Rectangle dirtyRegion = null;
private Color highlightColor = new Color(Color.BLUE.getRed(), Color.BLUE.getGreen(), Color.BLUE.getBlue(), 100);


...


@Override
public void dragOver(DropTargetDragEvent dtde) {

Point location = dtde.getLocation();
int closestRow = this.getClosestRowForLocation((int) location.getX(), (int) location.getY());
boolean highlighted = false;

Graphics g = getGraphics();

// row changed

if (highlightedRow != closestRow) {
if (null != dirtyRegion) {
paintImmediately(dirtyRegion);
}

for (int j = 0; j
if (closestRow == j) {

Rectangle firstRowRect = getRowBounds(closestRow);
this.dirtyRegion = firstRowRect;
g.setColor(highlightColor);

g.fillRect((int) dirtyRegion.getX(), (int) dirtyRegion.getY(), (int) dirtyRegion.getWidth(), (int) dirtyRegion.getHeight());
highlightedRow = closestRow;
}
}

}


...

@Override
public void dragExit(DropTargetEvent dte) {
if (null != dirtyRegion) {
paintImmediately(dirtyRegion);
}
}


}

}