Posts tagged as ColdFusion

Validate new passwords with ORM and ValidateThis

My new project is using CF9’s ORM, FW/1 and ValidateThis, all for the first time – so naturally I’m having to work a few things out. There will probably be a few posts like this one over the next few weeks…

I have a user edit page, on which you can edit your personal details and change your password. It’s set up something like this:

user.cfc

component output="false" persistent="true"
{
	// identifier
	property name="userid" fieldtype="id"; 
	
	// properties
	property name="firstname";
	property name="lastname";
	property name="uuid";
	property name="password";
}

user.xml (ValidateThis rules)

<?xml version="1.0" encoding="UTF-8"?>
<validateThis xsi:noNamespaceSchemaLocation="http://www.validatethis.org/validateThis.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<objectProperties>
		<property name="firstname" desc="First name">
			<rule type="required" />
		</property>
		<property name="lastname" desc="Last name">
			<rule type="required" />
		</property>
	</objectProperties>
</validateThis>

…and the (simplified) code to run the validation:

user = variables.userService.get( rc.userID );
user.setFirstName( rc.firstname );
user.setLastName( rc.lastname );

result = application.ValidateThis.validate( user );
		
if ( result.hasErrors() ) {
	// show error messages		
} else {
	// save user
}

Which is all well and good, but the problem comes with the password. My user object has a password field which stores a hash of the user’s password and uuid. The update form has two fields, newpassword1 and newpassword2, which have to match in order to set the password. But these are not persisted values; they are only used to set the actual persisted password value. So how to make them part of the user object so it can be validated in one easy command using ValidateThis?

The answer is simple, and will apply to other situations as well. All the persisted values in the user object are set up using properties, and so also get the auto-generated getters and setters. But if we add a couple of explicit getters and setters for our non-persisted values, ValidateThis will be able to access the values from the object, but they will not be a part of the persisted data. So our new user.cfc object will look like this:

component output="false" persistent="true"
{
	// identifier
	property name="userid" fieldtype="id"; 
	
	// properties
	property name="firstname";
	property name="lastname";
	property name="uuid";
	property name="password";
	
	variables.newpassword1 = "";
	variables.newpassword2 = "";
	
	function getVariables() {
		return variables;
	}
	
	function setNewPassword1(string newpassword1) {
		variables.newpassword1 = newpassword1;
	}
	function getNewPassword1() {
		return variables.newpassword1;
	}
	function setNewPassword2(string newpassword2) {
		variables.newpassword2 = newpassword2;
	}
	function getNewPassword2() {
		return variables.newpassword2;
	}
	function updatePassword() {
		setPassword( hash( getNewPassword1() & getUUID() ) );
	}
}

And we can add the following rules to our user.xml (in the real code we would probably make newpassword1 required only under certain contexts, such as the initial user creation):

<property name="newpassword1" desc="New password">
	<rule type="required" />
</property>
<property name="newpassword2" desc="New password confirmation">
	<rule type="equalTo" failureMessage="Please make sure your passwords match">
		<param DependentPropertyName="newpassword1" />
		<param ComparePropertyName="newpassword1" />
	</rule>
</property>

And then, when the user validates successfully, we simply call the updatePassword() method before persisting the object, and it will be updated with the new hashed password:

user = variables.userService.get( rc.userID );
user.setFirstName( rc.firstname );
user.setLastName( rc.lastname );
user.setNewPassword1( rc.newpassword1 );
user.setNewPassword2( rc.newpassword2 );

result = application.ValidateThis.validate( user );
		
if ( result.hasErrors() ) {
	// show error messages		
} else {
	user.updatePassword();
	// save user
}

I hope this is useful to others who are just starting to use these technologies…

4 comments Posted on 15 August, 2010, in ColdFusion, ORM, ValidateThis

ORM gotcha: Hibernate reserved words

Typically, the very first time I tried to use CF9’s ORM, I ran into a bizarre problem which had me scratching my head for hours…

The setup was this: a table in my SQL database called “member”. A member.cfc object with the following code:

component  output="false" persistent="true"
{
	property name="memberid" fieldtype="id"; 
	property name="firstname";
	property name="lastname";  
}

And a test page which called it:

<cfscript>
members = EntityLoad("member");
writedump(members);
</cfscript>

Running this page always gave the following error:

unexpected token: member near line 1, column 6 [from member]

However, if I gave the EntityLoad() function more arguments, for instance:

members = EntityLoad("member", {});

…it worked perfectly.

After a lot of head-scratching and seeking of help on Twitter (thanks @aliaspooryorik) and Stack Overflow (thanks Henry), I had the idea that “member” might be some sort of reserved word in Hibernate. So I changed the table and component names to “user” – and everything worked exactly as it should.

My guess is that it works fine if in the generated HQL query there’s a WHERE clause following the “SELECT FROM member”; but if you just have the basic EntityLoad(”member”) then it doesn’t have this WHERE clause, and so the reserved word “member” gets seen as an HQL keyword.

I guess I was just unlucky that my very first attempt at ORM ran into this problem; does anyone know of any other table/object names I should steer clear of?

3 comments Posted on 13 August, 2010, in ColdFusion, ORM

Mura plugin: Impersonate User

One feature that is missing from Mura’s site member tools is the ability for an administrator to log in to the site as a particular user.

So I hacked together a very quick tool which will allow you to do just that.

Once installed, go to the plugins page for your site, and click on the name of the Impersonate User plugin.

You’ll then get a form in which you can enter either a UserID (a UUID) or a username. Click the button, and you’ll be immediately logged out of the admin, logged in as the requested user, and directed to the site’s home page.

You can now see the site exactly as that user would, even though you don’t know what their password is…

You can find the source code on the plugin’s github repository, and you can download the plugin here.

No comments Posted on 15 April, 2010, in ColdFusion, Mura CMS

Username Restrictions - my first Mura plugin

One of the great things about Mura - much like Mango - is its extensibility via its plugin architecture.

The basic user validation in Mura doesn't do much in the way of checking a username. It's required, and it cannot be the same as an existing username. That's as far as it goes.

If you have forums, or other public displays of usernames, you probably don't want users registering with a name containing "admin" or your company or product name. And one-letter usernames aren't great, either.

So, wanting a bit more, I set about writing a plugin - and just a few hours later, here it is, ready for release into the wild.

Read more »

1 comment Posted on 2 April, 2010, in ColdFusion, Mura CMS

Learning Mura CMS

A few weeks ago, I was landed with an emergency web project - due to a number of factors, I needed to design and build a fully functional product launch site with site membership, CMS facilities, integrated forums and a free trial signup process. In two and a half weeks.

I'd looked briefly at Mura CMS a while back, but didn't have a use for it at the time. This seemed the ideal project to implement Mura, if only the learning curve would be easy enough. So I took a day or two to install Mura, play with it, get to grips with the structure and conventions, and see if it fitted the task. A bit of a gamble, as if it wasn't a good fit then I'd have wasted two precious days, but well worth the effort.

Read more »

10 comments Posted on 2 April, 2010, in ColdFusion, Mura CMS