rc3.org

Strong opinions, weakly held

Month: October 2007 (page 3 of 5)

How to get an innocent man to admit to being a terrorist

Lots of blogs are abuzz today with the story of an Egyptian Abdallah Higazy, who confessed to being involved with the 9/11 attacks even though he was completely innocent. You may remember the story, summarized as follows:

The long and the short of it was that an Egpytian national, Abdallah Higazy, was staying in a hotel in New York City on September 11 and the hotel emptied out when the planes hit the towers. The hotel later found in the closet of his room a device that allows you to communicate with airline pilots. Investigators thought this guy had something to do with 9/11 so they questioned him. According to Higazi, the investigators coerced him into confessing to a role in 9/11. Higazi first adamantly denied any involvement with 9/11 and could not believe what was happening to him. Then, he says, the investigator said his family would go through hell in Egypt, where they torture people like Saddam Hussein. Higazy then realized he had a choice: he could continue denying the radio was his and his family suffers ungodly torture in Egypt or he confesses and his family is spared. Of course, by confessing, Higazy’s life is worth garbage at that point, but … well, that’s why coerced confessions are outlawed in the United States.

So Higazy “confesses” and he’s processed by the criminal justice system. His future is quite bleak. Meanwhile, an airline pilot later shows up at the hotel and asks for his radio back. This is like something out of the movies. The radio belonged to the pilot, not Higazy, and Higazy was free to go, the victim of horrible timing. Higazi was innocent! He next sued the hotel and the FBI agent for coercing his confession. The bottom line in the Court of Appeals: Higazy has a case and may recover damages for this injustice.

Anyway, the appellate court released its decision, and then took it down, but not before some bloggers published it. Then the court asked the bloggers who posted it to take it down. The bloggers refused to do so, and you can still read the uncontested details of how the FBI agent threatened the suspect’s family to coerce his confession. (Those details are redacted from the official published version of the decision.)

I’ll leave it up to you to speculate whether things have gotten better or worse since December, 2001, when an FBI agent locked Higazy in a room and told him that the Egyptian government would make life very hard for his family if he didn’t admit to being a terrorist.

Recursion

New York Times columnist Paul Krugman blogs his rejection of New York Times book reviewer David Kennedy’s negative review of Krugman’s new book.

Update: To clarify, the reviewer doesn’t work for the Times, he’s a Stanford history professor.

Saving things in Ruby on Rails: the solution

I worked out the design issue that I mentioned yesterday, and learned a few things in the process. The most helpful thing I encountered were the three most recent screencasts from Railscasts, which Jason Perkins pointed me toward.

As an aside, if you’re not using screencasts to augment your learning, you’re really missing out. I think they’re probably the most information-dense way to learn development concepts that I’ve found — far more useful than book reading for example. I think that screencasts work well for two reasons. The first is that watching someone else do something is a very natural way to learn, and watching them work in a screencast is especially good because it’s as though you’re looking at their computer as they work, rather than watching them talk from a podium. The second is that they provide the opportunity to absorb other good habits through observation. I noticed three or four TextMate features I wasn’t already using while watching the screencasts that will certainly save me time down the road.

So back to my problem. To recap, I have a data model that looks like this:

users

id home_address_id business_address_id

addresses

id user_id

Both tables have other properties but they don’t really come into play here.

The problem is that I have one form that’s used to create a user, a home address, and a business address all at once, and the circular reference in the database makes it challenging to validate the user’s input and save everything.

After reading the comments on the previous entry and doing a lot of thinking, I considered changes to the data model and changes to the business logic, but would up fixing the whole thing by more cleverly using Ruby on Rails.

What’s validation for, anyway?

The first thing I figured out is that this line in Address.rb was a bad idea:

validates_presence_of user_id

You’d think it’s a good idea because an address that’s not associated with a user is an orphan, and you shouldn’t create orphaned addresses. However, the main purpose of validations in Ruby on Rails is not to prevent you from inserting bad data into the database but rather to validate user input and display errors in a clean and helpful way. The identity of the user associated with an address is not user input as that relationship is created behind the scenes. If that validation rule fails, there’s a bug in the code, not a user error, so you don’t need to use validation to handle it. I took that line out.

Handling the associations more intelligently

The next issue to tackle was validating the address before saving the user. Doing so was possible once I got rid of the unneeded validation rule, but the question was how best to do the validating. Fortunately, ActiveRecord provides the validates_associated method, which prevents a model from being saved if any of the associated objects specified are invalid.

Initially, my User class looked something like this:

class User < ActiveRecord::Base belongs_to :home_address, :class_name => “Address”, :foreign_key => “home_address_id” belongs_to :business_address, :class_name => “Address”, :foreign_key => “business_address_id” end

I was creating the addresses and assigning them to the home_address and business_address properties of the user, and using

validates_associated :home_address, :business_address

to make sure the addresses were valid before saving the user. That worked fine for validation, but user.save blew up due to a circular reference. I couldn’t save the user because the addresses didn’t have IDs yet and I couldn’t save the addresses because the user wasn’t saved. Whoops.

Here’s the solution:

class User < ActiveRecord::Base

validates_associated :addresses

has_many :addresses belongs_to :home_address, :class_name => “Address”, :foreign_key => “home_address_id” belongs_to :business_address, :class_name => “Address”, :foreign_key => “business_address_id” end

Adding the has_many allows the user to be saved before the addresses, and I reference that relationship with validates_associated so that validation works properly. So now the process is to create a user, create the addresses and associate them with the user. I can validate and save the user (automatically saving the associated addresses along the way) and then assign the newly created addresses to home_address and business_address and save the user again.

That gives me everything I need. I can directly access a user’s current home and business address, and I can keep all of a user’s old addresses on file. I can also validate user input in a clean and Rails-ish way.

Thanks to everyone who offered advice and on to the next thing.

Why root matters

John Gruber speculates on the forthcoming details of the iPhone SDK and makes the following remark with regard to security:

And the hysteria over the iPhone’s current “everything runs as root” situation is overblown. Applications on your Mac don’t run as the root; they run under your user account. But all of your data — your email, your address book, your documents, everything your apps can read or write without administrator authentication — is vulnerable to any sort of hypothetical buffer overflow exploit on the Mac, and would be on the iPhone, too, even if iPhone apps didn’t all run as root. Sure, root privileges allow an exploit to do anything, but the most important thing on your system is your personal data, and an exploit doesn’t need root privileges to access that.

Of course it’s true that an application running as the end user can access any of the end user’s data, but privilege separation remains really important, even for a device like the iPhone. The current iPhone is set up so that anyone can do anything, and Apple keeps things safe by providing a minimal interface to the phone’s features. You can use the applications provided, but unless you hack the phone, you can’t add applications or access the file system. This isn’t ideal, but the lack of privilege separation becomes much worse when there’s an interface available for loading arbitrary code onto the device.

For example, let’s say I’m a spy, and my goal is to record someone’s phone conversations. I decide that the best way to do this is to get a user to install an application that does one thing (pulls down sports scores, let’s say), but also secretly turns itself on anytime they make or receive a call and then stores the audio in an MP3 file that will be uploaded to a server when the phone is idle. Assume that I can get the user to install the Trojan horse onto their phone.

On iPhone of today (where the end user is root), once the Trojan horse is there, I can subvert the software that dials the phone in any way that I choose. I can replace the binary with one of my own creation that records the call, or I can replace the device driver for the audio system with one that accomplishes my goal, or I can alter how the phone software is called to use a wrapper that I created. The bottom line is that I have full access to modify the telephony features of the phone.

On a hypothetical iPhone where there’s privilege separation, all of the phone features are restricted to the “phone” user, and all of the third party applications are restricted to the “end user” user. So when “end user” installs a new application, it doesn’t have any access at all to the things “phone” can do, and so the Trojan horse can’t easily insert itself into the dialing process. That’s a pretty important security feature, don’t you think?

I imagine that the reason the iPhone doesn’t work this way already is that the developers were behind and that Apple chose to punt on the security question to get the phone out the door. Since third party applications are not currently allowed, the lack of privilege separation is tolerable. I’d imagine that by the time the SDK is released, we’ll see a new major release of the iPhone operating system with root locked down and separate privileges for the various functions of the phone. We’ll see.

Fun with saving things in Ruby on Rails

I’m running into a bit of a conundrum when it comes to designing objects in a Ruby on Rails application, and thought I’d toss it up here for discussion. I have an application with two persistent objects, User and Address. Address is a child of user, and user holds a pointer to their current address (so that a history of addresses can be maintained. So users has an ID column and a current address ID coumn, and addresses has an ID column and a user ID column. As you might imagine, this leads to a bit of a chicken and egg problem.

I have one “new user” form that enables someone to create a user. If everything goes well, when the user submits the form, a new User object will be created and a new Address object will be created. The question is, how do I design the method that saves the two objects? Here’s why this question is a little bit complicated:

  • I don’t want to save anything if there are problems with either of the objects. So if the address is invalid, I don’t want to save the user.
  • User ID is a required field for the address object, so in order to save the address, I have to save the user object first.
  • One purpose of this process is to save the objects to the database if they are valid. The other is to record the problems with the objects if they are not valid, so that they can be presented to the user for correction. One option would be to validate both objects before trying to save either of them and then save only if both are valid. Unfortunately, the address will always be treated as invalid if the user has not been saved.
  • Once the user and address have been saved, you have to go back and save the user again to populate he user’s current address ID with the newly assigned ID fof the address.

Currently the most straightforward to make this work is to instantiate and save the user object and then instantiate and save the address object. If you try to instantiate the address object and link it back to the user object, you get a stack error because ActiveRecord recurses through the circular relationships between the user and the address. The problem here is that once you’ve created the user object, if there’s an error in the address object, the user has already been saved. That breaks the expected experience in that the data will be partially saved.

So the question is, what’s the easiest and most idiomatic Rails way to handle this situation? Here are the options as I see them:

  1. Wrap all of the database operations in a transaction. If the save of the address fails, roll back the transaction and wipe out the newly created user.
  2. Muck around with the validation so that you can validate the address before you save the user. Then validate both the user and the address without attempting to save them.
  3. Split the form into two forms, one which creates the user and another which allows them to submit their address.
  4. If the address validation fails but the user validation succeeds, report to the user that the user object was saved but ask them to correct their address.

There are probably other options as well. I’m still trying to determine which makes the most sense. Any ideas?

Update: I’ve posted how I solved this problem.

iPhone and network neutrality

Why is the iPhone a closed platform? Even though Apple is going to allow third party applications next year, it’s apparent that they’re going to exercise some control over who’s allowed to deploy applications for the iPhone and what those applications will be allowed to do. The degree of control Apple will exercise remains unknown.

Steve Jobs has a reputation as a control freak, and a lot of people believe that he doesn’t want to allow third party iPhone applications because he doesn’t want crappy applications to ruin the experience that Apple has created. There’s also the argument that Apple is being forced by carriers to control which applications are deployed on the phone. That’s the argument that interests me, because I think it illustrates the importance of network neutrality.

Mobile carriers are pretty tight fisted in terms of how they allow their networks to be used, and ISPs would love to see the Internet governed more in that fashion. They see the ability to buy some bandwidth and use it in whatever fashion you see fit as a design flaw. The iPhone is a great little computer that can connect to the Internet from anywhere (other than my office, because AT&T’s coverage sucks), and the only thing that keeps us from taking full advantage of it is Apple and AT&T. AT&T, Time Warner, and the other ISPs would love to team up with computer makers and bring all of the frustrations of iPhone users to your desktop computing experience. That’s why network neutrality is worth fighting for.

iPhone SDK in February

Apple has announced that they’ll be releasing an SDK for the iPhone in February. There’s talk of digital signatures and no talk of how much the SDK will cost, so we still have no idea whether open source software for the iPhone will be legitimately allowed or will be for outlaws only. I’m sure you’ll be able to find a lot more details in the usual places.

Amazon.com one-click patent rejected

Blogger Peter Calveley petitioned the US Patent office to look at Amazon.com’s one-click patent again, and this time they rejected nearly all of its claims. That patent has always struck me as particularly egregious, but it also turned out to be tough to get rid of. It was awarded back in 1999, and a lot of people were deeply offended at the time. Here’s O’Reilly’s archive of articles about the patent.

The one-click patent was the driving force behind the creation of BountyQuest by Tim O’Reilly (and, oddly enough, Amazon.com CEO Jeff Bezos). BountyQuest was a site that enabled people to post bounties for prior art needed to invalidate specific patents, and Tim O’Reilly started by putting up a bounty for the one-click patent. In the end, BountyQuest died without collecting the prior art needed to invalidate, and Tim O’Reilly quit pursuing Amazon.com because they weren’t suing anyone for violating the patent.

Nonetheless, it’s nice to see the one-click patent get the treatment it deserves. The only downside is that the USPTO has eliminated one of the best symbols of the inapplicability of the patent system to software. Sadly, there are certainly hundreds more out there to take its place.

code.nytimes.com

The New York Times is releasing open source software. Their database abstraction package, DBSlayer looks innovative, clever, useful, and deceptively simple. One of the things I love most about the rise of open source is that it has given organizations a framework to show off the creativity that dwells inside their walls. Companies have always had the opportunity to do so, but not the justification or rationale.

Some thoughts on testing

I’m working on a couple of different Ruby on Rails applications which have me thinking about testing. One has an insufficient number of tests, and the other has no tests at all.

Why write unit tests?

The first thing I’ve come to realize is the degree to which I depend on unit tests in getting my job done. Implementing features is a whole lot faster when you get serious about testing. Let me give you a simple example. In a content management system, I added a field to hold a short description to a table that already had a description field. Because the new field is not populated for any existing records, I needed a method that would show the short description if it is populated, show the full long description if it’s small enough, or cleverly truncate the long description if it’s too long to be a short description.

This is the type of task where writing tests can cut down on development time. You set up a few mock objects to represent the possible scenarios, and then write some tests to make sure your code behaves correctly in all of them. Back in the day I would have written the code, used the Web interface to create records representing each possible state, and then tested each of those states by inspecting the results in the Web interface. It would have wound up taking forever (since I made several little mistakes while writing the method), and in the end I wouldn’t have had a test suite to test for bugs that creep in when the code is modified later.

Why Rails developers hate database constraints

In the one application that has no tests, I’ve seen why many Rails developers are not in favor of using foreign keys. They make using fixtures (the means that Rails provides for getting mock data into your test database) pretty darned difficult. Unit testing is great, but there’s nothing more frustrating than wasting your time debugging and fixing your testing environment. Maintaining application code is exhausting, burning time maintaining your tests is just exasperating.

The thing about fixtures is that they’re stupid (and I mean that as a compliment). You put some data in a file and Rails sticks it in the database. It doesn’t apply any of the validation in your application to it, and that’s great, because the only thing you really care about is whether your tests exercise the right parts of the application and get the results you need. If you’re using some mock user data to test a shopping cart, the fact that you didn’t populate all of the fields in the user table might not matter. Database constraints demand that you include data in your test environment that you may not really need, and generally slow down the test-writing process.

Foreign keys are even worse. Fixtures are inserted before each test and deleted after the test has run, but in some cases they can leave stale data in the database, causing subsequent tests to blow up, telling you nothing about the quality of your code and slowing down your development. Seeing a test work when run individually and then die when the full test suite is run is frustrating.

Configuring your database to defend itself from the insertion of bad data can be a good thing (and if you work with a DBA, they’ll probably demand it), but I’m not sure if the value overrides the added difficulty when it comes to writing tests. I’d rather have a well-tested application with a good suite of automated tests than a database with constraints. I’ve just seen too many working applications that are just fine without them.

Why unit tests are doubly important with scripting languages

Compiled languages (like Java) have an advantage over scripting languages like Ruby that unit tests can equalize. When you compile a Java program, the compiler will let you know about most of the typos you made, all of the times you referenced a variable by the wrong name, and all of the other easy to find errors. Any decent Java IDE will let you know about those kinds of errors before you even save the file you’re working on.

When you’re working with a scripting language, you don’t have the luxury of relying on the compiler to do this kind of work for you. That’s where unit tests come in. If nothing else, a suite of unit tests that opens and compiles every file in your project will save you testing time, even if those tests don’t actually exercise any of your logic.

I came to this realization when I started working on the Rails application that has no tests and realized that it contained a bunch of files that actually had syntax errors in them. (I found this out by trying to run all of the unit tests, which, of course where in the same state they were in when the Ruby on Rails code generator created them.) These kinds of mistakes are easy to make if you don’t have some mechanism to prevent them. I see it all the time, especially in the rarely used corners of PHP applications.

Older posts Newer posts

© 2024 rc3.org

Theme by Anders NorenUp ↑