My coworker (and all around good egg) Scott Stroz and I hit an interesting memory problem recently in one of our applications. The fix, and our story, is now documented, with pretty pictures.
Enjoy.
--marc
My coworker (and all around good egg) Scott Stroz and I hit an interesting memory problem recently in one of our applications. The fix, and our story, is now documented, with pretty pictures.
Enjoy.
--marc
I’ve been thinking more about security lately; specifically, password safety. For a fine explanation of why you want to hash passwords instead of storing them plaintext, read Billy’s post from a while back. He’s got a good list of references as well, including NIST’s approved hashing algorithms. In addition, check out OWASP’s thorough treatment.
Now, then…
This weekend I re-read Coda Hale’s admonition about why MD5, SHA512, etc aren’t the right choice for a hashing algorithm. His point: use bcrypt, which “uses a variant of the Blowfish encryption algorithm’s keying schedule, and introduces a work factor, which allows you to determine how expensive the hash function will be” (Coda Hale’s words).
As of this writing, bcrypt does not ship with ColdFusion. Fortunately, it’s quite easy to use within CF. One thing that quite appeals to me about bcrypt is that the salt is essentially stored with the hash, and so you don’t need to store/use/remember the salt used to hash a password. Think about that.
In code, it means you can hash and check a password as easily as this:
//hash it pw = "happy1.!gIlm0re"; hashed = bcrypt.hashpw(pw, bcrypt.gensalt()); //check it match = bcrypt.checkpw(pw, hashed);
Compare that with any password hashing code you've written before. I bet it's simpler and at the same time more secure.
What’s the catch? Time… in my tests, with the default “work load”, it takes about 200-300 ms to hash and check a single password. This is also, not ironically, why it’s such an effective technique for hashing passwords, as Coda Hale describes.
Here’s how to do it in ColdFusion:
Using javaloader, you’ll do the following. I’m leaving my timers in here so you can easily compare the difference between the default workload and a higher workload of, say, 12.
<cfscript> pw = "happy1.!gIlm0re"; jbClass = expandPath("jBCrypt-0.3"); javaloader = createObject('component','javaloader.javaloader'); javaloader.init([jbClass]); bcrypt = javaloader.create("BCrypt"); startts = getTickCount(); hashed = bcrypt.hashpw(pw, bcrypt.gensalt()); writeoutput("created pw " & hashed & " in " & getTickCount() - startts & " ms <br>"); startts = getTickCount(); match = bcrypt.checkpw(pw, hashed); writeoutput("checked pw match (#match#) in " & getTickCount() - startts & " ms <br>"); startts = getTickCount(); hashed = bcrypt.hashpw(pw, bcrypt.gensalt(12)); writeoutput("created pw " & hashed & " in " & getTickCount() - startts & " ms <br>"); startts = getTickCount(); match = bcrypt.checkpw(pw, hashed); writeoutput("checked pw match (#match#) in " & getTickCount() - startts & " ms <br>"); </cfscript>
Using the code below, here’s sample output:
The ability to hash and check passwords without having to manage salts, combined with the high degree of difficulty it would require to actually crack a bcrypted password, makes this an appealing solution for me. The fact that it’s so easy to use in ColdFusion is gravy.
Long title, I know. Short post.
I thought that you needed cascade=”all-delete-orphan” any time you wanted to ensure an element in a one-to-many property was removed from the join table. For example, blog.removeComment( comment ) should remove the row from BlogComments. Turns out, it’s not always required.
I still think you should use it all the time, however.
This is one of those “I learned something new but it doesn’t change anything” type of posts.
When removing elements from a one-to-many collection, you typically specify cascade=”all-delete-orphan” on that property. Then, when you remove the item and re-save the entity, it’ll remove that item from the join table. Here’s an example, using a typical “linktable”, which you use when you have a simple 2-key join table. Given an entity named “Event.cfc”, with a property named “attendees” which maps to an Attendee.cfc:
property name="attendees" fieldtype="one-to-many" cfc="Attendee" linktable="J_Events_Attendees" fkcolumn="EventID" inversejoincolumn="AttendeeID" singularname="attendee" cascade="all-delete-orphan";
With a relationship like this, if you call event.removeAttendee( someAttendee ), then ORM will remove the link from that linktable for you, thanks to the cascade.
Here’s what I learned… cascade=”all-delete-orphan” doesn’t matter in the case of a simple linktable. If you set it to cascade=”all”, it’ll do exactly what you want.
BUT: it absolutely matters when you have a property that is not a simple link table but is instead an entity in itself, representing a link in addition to other data.
Consider this… an Event entity mapping to an “EventComment” entity. EventComment comprises more than a simple “eventid,commentid” relationship; instead, it has a comment string, and also an Attendee and a date and who knows what else. These “joins with additional data” are more common than simple joins in my experience, if for no other reason than everyone seems to *need* CreatedBy, CreatedOn, ModifiedBy, and ModifiedOn fields even though you never use them.
That mapping looks like:
property name="eventComments" fieldtype="one-to-many" cfc="EventComment" fkcolumn="EventID" singularname="eventComment" inverse="true" cascade="all-delete-orphan";
Now check this out. If you call event.removeEventComment( someComment ), it’ll remove it from EventComment’s table as expected. But unlike the earlier example, if you change it to cascade=”all”, it will not behave the same way. In fact, the behavior I observed, using MySQL, is this:
Bottom line: no deletion, though it *looks* like it’s deleted. These ORM headfakes’ll drive a dude to drink (More).
This is perhaps completely obvious that it should behave this way. I so rarely work with 2-column join tables, and while futzing about tonight with some examples I stumbled onto this difference in behavior accidentally.
You don’t need all-delete-orphan when working with simply a linktable. However, I strongly suggest using it, since it doesn’t cause damage and more clearly expresses intent. And in the event that your simple join turns into a multi-column affair requiring an intermediary entity, you save yourself one fewer “now why in the hell isn’t this deleting anymore?” moment.
--Ommmmmm….
--Marc
Lately, the frameworks I’ve been using have been configured with XML files – ColdSpring, ModelGlue, and ValidateThis. If you’re coding XML, and use either the basic XML editor in Eclipse or the Aptana XML editor in ColdFusion Builder, you’re potentially missing out on some slick code completion offered by another Eclipse plugin… the WebTools project, which contains my free XML Editor of choice.
Use the normal “Help -- Install new software” process in Eclipse, using http://download.eclipse.org/webtools/updates/ as the update site.
The WTP XML editor has two must-have features:
Check it:
This is me editing a ModelGlue xml config file. Note that the file has this attribute on the modelglue element: xsi:noNamespaceSchemaLocation="http://www.model-glue.com/schema/gesture/ModelGlue.xsd"
Yes, that’s a valid URL.
This means that if your framework of choice makes an XSD schema available, then you can add the appropriate URI to your XML file and voila, the editor will start providing code assist.
One other small-but-useful feature is automatic element shorthand. Let me explain:
Imagine you type this: <param name=”regex” value=”(?i)password”></param>
Or, rather, imagine the editor auto-closed that tag. Now, if you put your cursor right after password” and before the closing angle bracket, and enter the backslash, the editor will automatically remove the closing element. Small, but the little things in life matter.
A best practice for the XML files is to suffix them with a .cfm extension, i.e. ModelGlue.xml.cfm if those files are web-accessible. This way, you can put an Application.cfm in that directory, with a CFABORT, and those xml config files are no longer readable (assuming you don’t lock them down with your webserver). The problem here is that once they have a .cfm extension, they don’t play nicely with the XML editor.
Fortunately, this is an easy fix.
Here’s what that looks like:
That’s step 1. Step 2 is actually opening a .cfm file in the WTP XML Editor.
That dialog looks like this:
This is a one time thing! Once you open a particular .xml.cfm file in the XML editor, it’ll always open in that editor until you instruct it otherwise.
You may have a .xml.cfm file that, when you open with the xml editor via right click – open with, continues to give you the “invalid content type” popup. This is most likely because the file does not have the xml declaration at the top. For example, if you have a Coldspring beans.xml.cfm file and it starts with <beans>, you’ll probably get this error. The fix is to add <?xml version="1.0" encoding="UTF-8"?> to the top of your file.
If you want code assist on your XML files, both .xml and .xml.cfm, then take 5 minutes to install the WTP XML Editor. Give it a go, and see if it’s right for you.
java.lang.String
, a classic immutable object. Once a String is created, it cannot be changed. Period. With software that does a lot of String manipulation, you can end up with a lot of string objects in need of garbage collecting. To answer this problem, StringBuilder
was implemented (StringBuffer is the predecessor). So, you may need to create a mutable version of your object that should be used with specific intent.(2*4) + (5^2) * 10
. The main thing we do is control the default constructor, init
. By requiring a string expression as a parameter, we’ve controlled how instances are created.component name="ImmutableExpression" { rawExpression=''; evaluatedExpression=''; public ImmutableExpression function init(required String expression) { rawExpression = expression; try{ evaluatedExpression = evaluate(expression); } catch(Expression e){ throw( type="InvalidExpressionException", message="This doesn't look like a valid expression: " & expression); } return this; } ... }
init
by requiring a single argument. component extends=“mxunit.framework.TestCase” { function twoExpressionsShouldNotBeTheSame(){ exp1 = new ImmutableExpression( “3^3” ); exp2 = new ImmutableExpression( “4*2” ); assertNotSame( exp1, exp2 ); } /** * @expectedException InvalidExpressionException */ function badExpressionShouldBeKickedOut(){ exp1 = new ImmutableExpression( “1*b” ); } }
exp1 = new ImmutableExpression( “3^3” ); exp2 = new ImmutableExpression( “4*2” ); exp3 = exp1.add(exp2) ;
exp3.getExpression()
will return (3^3) + (4*2)
and exp3.value()
will return 35
... public ImmutableExpression function add (ImmutableExpression exp){ return new ImmutableExpression( “(” & rawExpression & “) + (” & exp.getExpression() & “)” ); } ...
add(...)
. This is in the style if functional programmingfinal
, so you have to check the type being instantiated at runtime to prevent it from being extended. Why? If a component can be extended its methods can be overridden and possibly break your immutable intention.... myComponentType = “sandbox.mutability.ImmutableExpression”; private void function ensureInstanceType(){ if ( getMetaData(this).fullName != myComponentType ) throw ( type=“InheritanceViolationException”, message=“This component is not intended to be extended.” ); } ...
add(1,1)
function, it will guarantee to return something, hopefully 2
, and it will guarantee not to change either of the parameters (1 or 1). With respect to programming, we’re usually passing in variables that are evaluated at runtime to some value. In a functional style, you do not change the state of the variables being passed in. In some functional languages, this constraint is a feature, but in many languages it is not. So, you need to do this yourself by cloning.Blogger Theme: Garland by Steven Wittens and Stefan Nagtegaal. Blogger Templates by Blog Forum