Toaster Lovin'

A journal of technical matters, by Rico Jones

Ruby on Rails: Testing for Insecure Admin Routes

I have a Ruby on Rails app with an admin section, as is common for a lot of apps. The admin section is namespaced, so all of the controllers are named something like Admin::WidgetsController and the routes all start with /admin.

Now, there is no reason, ever, for a non-admin user to do anything in the admin section, so I created an Admin::ApplicationController and put a before_filter in it to redirect requests from non-admin users to the admin login page. Then, I had all of my Admin:: controllers inherit from it.

So I’m all set, right?

Ruby on Rails: Testing for Orphaned Routes

Over time, one of my large Ruby on Rails apps has accumulated a lot of cruft in it’s routes file. In addition to the normal entropy that accumulates in any large app, I didn’t really have a solid grasp of how routes worked when I started on this app, so it was looking pretty bad.

Well, I recently went through routes.rb and did some major housekeeping. But this app has a bunch of models, with controllers for most of them in both the default namespace and an admin namespace.

How to Configure Asterisk for Your Home Office

I work from home. Along with work comes frequent work-related phone calls. For a while I was taking work calls on my mobile phone, but having work spill over into my personal life was driving me nuts. I also tried a Skype phone number, but managing calls from my computer also drove me nuts.

About a year ago, I determined that the right thing for me was a dedicated phone number that rang an actual telephone on my desk. It would have a decent speakerphone, a dedicated voicemail light, and actual hardware buttons for dialing – all of those glorious things.

And then I did a dumb thing.

Leveling Up

I recently read a blog post by Jason Rudolph about leveling up as a software developer. To paraphrase him, the idea is to:

  1. Identify the experiences that advance a person as a developer.
  2. Select a particular experience to pursue.
  3. Pursue that experience to completion. (Achievement unlocked!)
  4. Reflect on that experience. Really soak it in.
  5. Return to Step 2, this time selecting a new experience.

Is the Attribute Actually Optional?

Ruby on Rails model attributes are optional by default. That is, unless you specify otherwise, an attribute is not required for a model instance to be valid. I like to test that this is, in fact, the case.

test "weight is not required" do
  assert @product.valid?, "product should be valid to begin with"
  @product.weight = nil
  assert @product.valid?, "product should still be valid"

This might seem too trivial to test, or like we’re testing core Rails functionality, but an optional attribute is a feature of your application. In other words, it’s easy for parts of your app to depend on an attribute being optional, which means it’s easy to break something by making that attribute required down the road.

Are the Fixtures Valid?

A common pattern in my Ruby on Rails unit tests is to start with a valid instance of a model, make a change to the attribute I’m testing, then assert that the model instance is no longer valid.

test "weight is required" do
  @prod_one = products(:one)
  @prod_one.weight = nil
  assert !@prod_one.valid?

Simple enough; I don’t think we’re treading new ground here. The problem is that this test assumes the fixture is valid. If the fixture isn’t valid, the test will still pass, but it won’t actually be testing anything. Yikes! Better to assert that the fixture is valid.

Returning to Computation

Way back in the day, when I was in college, I took a class on basic programming with C++. I only did okay in that class, but the concepts really stuck. There was something about decomposing work into it’s fundamental units – variables, conditionals and loops – that struck me as true.

It was one of those things, a Fundamental Truth About The Universe, like that genes, not organisms, are the basic units of reproduction; or that evolution, not the id, is what explains human behaviour. One of those “Aha!” moments when the haze of confusion is swept away and suddenly everything makes sense.

And so my eyes were opened a little wider.