Be Genius

me

Bo Jeanes

I am an software engineer who has lived and worked in New York, Brisbane, Chicago, San Francisco, and now Melbourne. I primarily work in Ruby though am a functional programmer at heart and a fan of programming languages in general. In particular, I love Rust and Clojure but keep my eye on many langauges all the time.

Using Apache as a BasicAuth proxy to an internal resource

This article isn’t named ideally so if you have a better title, tell me.

This is the scenario: we have a simple HTTP resource on the internal network at Mocra. This resource is a closed source tool which is great except that it has one drawback — there are only two security modes: basic authentication on, or basic authentication off. There is only one username/password and you can’t control when or by whom it is required.

Now, my preferred behaviour here is to be able to give out multiple login/passwords and also to only require authentication outside of our local network. I set out to get this working.

I devised this solution a few months ago (which is why it’s using Apache at all) but I thought it might be of some use to someone. I created an Apache VirtualHost to act as a proxy between this resource and its clients. It looks like this:

<VirtualHost *:80>
  # This virtual host proxies requests for the internal resource
  ServerName external.resource.com

  # Set auth header to base64 encoded 'username:password' 
  # where username and password are the credentials for internal resource
  RequestHeader set Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ="

  ProxyPass /resource_path/ http://192.168.1.123:1337/resource_path/
  ProxyPassReverse /resource_path/ http://192.168.1.123:1337/resource_path/

  <Location />
    Order allow,deny
    Allow from 192.168.1.0/24 # our local subnet
    Allow from 127.0.0.1 # duh
    Allow from 1.3.3.7 # our external router IP

    AuthType basic
    AuthName "Our Internal Resource"
    # where all the external login/passwords are
    AuthUserFile /var/www/.htpasswd 
    Require valid-user

    # this is the secret sauce that allows EITHER
    # local access or Basic Auth access
    Satisfy Any 
  </Location>

  RewriteEngine on
  RewriteRule ^/?$ http://external.resource.com:80/resource_path/ [R]
</VirtualHost>

Ultraviolet Tools

A few weeks ago, I was modifying my clone of Enki (my blogging platform) to use Ultraviolet instead of CodeRay, as it supports using both TextMate themes and syntaxes. This means I can extend it fairly limitlessly and use TextMate itself to modify the themes an syntaxes.

However, Ultraviolet doesn’t come with the best tools to turn the TextMate syntax and theme files into files Ultraviolet can use, and the ones that it does provide puts those translated files INTO the gem on your system. This means that you can’t easily deploy or share them.

So, to remedy this I made a small gem Ultraviolet Tools that provides two command line tools: uv-create-syntax and uv-create-theme.

They aren’t very complicated, nor very documented, but they are straight-forward to use:

Install

Install Ultraviolet Tools with sudo gem install bjeanes-ultraviolet-tools -s http://gems.github.com.

Usage

Themes

Run uv-create-theme path/to/theme.tmTheme

Syntaxes

Run uv-create_syntax path/to/syntax.plist or uv-create_syntax path/to/bundle/with/syntaxes.tmBundle

Using the resulting files

Use my fork of ultraviolet as it has an option to change the load path for themes and syntaxes so that you can load them out of your application files.

Using fields_for can generate invalid HTML

Just a quick post so show you how fields_for form helper can cause invalid HTML when used in combination with accepts_nested_attributes_for in your views.

If you are for any reason editing/creating your child objects in a tabular form, your view might look something like this:

<% form_for(@todo_list) do |f| %>
  <%= f.label      :name %>
  <%= f.text_field :name %>

  <h3>To Do Items:</h3>
  <table>
    <thead>
      <tr>
        <th>To Do Item</th>
        <th>Due Date</th>
        <th>Done?</th>
      </tr>
    </thead>
    <tbody>
      <% f.fields_for :items do |item| %>
        <tr>
          <td><%= item.text_field :content %></td>
          <td><%= item.text_field :due_date %></td>
          <td><%= item.check_box  :done %></td>
        </tr>
      <% end %>
    </tbody>
  </table>

  <%= f.submit 'Save' %>
<% end %>

At first glance this looks fine. However, when the ToDoList model has accepts_nested_attributes_for :items, the fields_for helper also outputs a hidden field for each existing Item instance with it’s ID.

This means that we get the following HTML:

<form action="/to_do_lists/1" class="edit_to_do_list" id="edit_to_do_list_1" method="post">
  <div style="margin:0;padding:0;display:inline">
    <input name="_method" type="hidden" value="put" />
    <input name="authenticity_token" type="hidden" value="CE2jyRoewbwsqu4eX8AFWFqsgrMfCN35Jzy6b43MhsA=" />
  </div>
  <label for="to_do_list_name">Name</label>
  <input id="to_do_list_name" name="to_do_list[name]" size="30" type="text" value="Sup" />

  <h3>To Do Items:</h3>
  <table>
    <thead>
      <tr>
        <th>To Do Item</th>
        <th>Due Date</th>
        <th>Done?</th>
      </tr>
    </thead>
    <tbody>
      <input id="to_do_list_items_attributes_0_id" name="to_do_list[items_attributes][0][id]" type="hidden" value="1" />
        <tr>
          <td><input id="to_do_list_items_attributes_0_content" name="to_do_list[items_attributes][0][content]" size="30" type="text" value="arst" /></td>
          <td><input id="to_do_list_items_attributes_0_due_date" name="to_do_list[items_attributes][0][due_date]" size="30" type="text" value="2009-07-30" /></td>
          <td><input name="to_do_list[items_attributes][0][done]" type="hidden" value="0" /><input id="to_do_list_items_attributes_0_done" name="to_do_list[items_attributes][0][done]" type="checkbox" value="1" /></td>
        </tr>
      <input id="to_do_list_items_attributes_1_id" name="to_do_list[items_attributes][1][id]" type="hidden" value="2" />
        <tr>
          <td><input id="to_do_list_items_attributes_1_content" name="to_do_list[items_attributes][1][content]" size="30" type="text" value="arst" /></td>
          <td><input id="to_do_list_items_attributes_1_due_date" name="to_do_list[items_attributes][1][due_date]" size="30" type="text" value="2009-07-30" /></td>
          <td><input name="to_do_list[items_attributes][1][done]" type="hidden" value="0" /><input id="to_do_list_items_attributes_1_done" name="to_do_list[items_attributes][1][done]" type="checkbox" value="1" /></td>
        </tr>
    </tbody>
  </table>

  <input id="to_do_list_submit" name="commit" type="submit" value="Save" />
</form>

The keen eye will notice the hidden <input> tags that are direct children of the tbody:

<tbody>
  <input id="to_do_list_items_attributes_0_id" name="to_do_list[items_attributes][0][id]" type="hidden" value="1" />
    <tr><!-- clip! --></tr>
  <input id="to_do_list_items_attributes_1_id" name="to_do_list[items_attributes][1][id]" type="hidden" value="2" />
    <tr><!-- clip! --></tr>
</tbody>

This is not a valid place for an <input> tag.

I’ve put an example project demonstrating this on my GitHub

Creating new Postgres User and DB

This post is mostly a reminder for me in the future. However, others may find it useful also.

I love Postgres but more often than not I get frustrated and confused trying to get authentication working with a new database. By looking through the Deprec source code, I pulled out these two lines of code and so far they haven’t failed me:

su - postgres -c "createuser -P -D -A -E $DBUSER"
su - postgres -c "createdb -O $DBUSER $DBNAME"

Of course, replace $DBUSER and $DBNAME with your desired username and database name, or define them as shell variables. The $DBUSER creates that user as the owner of the database (so it has permission to read/write etc).

Fix for "dynamic_pager: cannot open swap directory /private/var/vm" in OS X (possibly just Snow Leopard)

Today my Snow Leopard install was going so slow it felt like I was trying to swim through molasses. The system was literally so slow that typing text into some text fields (especially TextMate) lagged at about a rate of 1 character per second, and opening files (or even running touch on them) took a couple of seconds.

After a few fruitless restarts and a keen eye on my logs I started noticing these errors in Console.app:

9/07/09 3:01:37 PM com.apple.launchd[1] (com.apple.dynamic*pager) Exited
with exit code: 1\
9/07/09 3:01:37 PM com.apple.launchd Throttling respawn: Will start in
10 seconds\
9/07/09 3:01:47 PM com.apple.dynamic*pager[2481] dynamic*pager: cannot
open swap directory /private/var/vm\
9/07/09 3:01:47 PM com.apple.launchd Exited with exit code: 1\
9/07/09 3:01:47 PM com.apple.launchd Throttling respawn: Will start in
10 seconds\
9/07/09 3:01:57 PM com.apple.dynamic*pager[2546] dynamic*pager: cannot
open swap directory /private/var/vm\
9/07/09 3:01:57 PM com.apple.launchd Exited with exit code: 1\
9/07/09 3:01:57 PM com.apple.launchd Throttling respawn: Will start in
10 seconds\
9/07/09 3:02:07 PM com.apple.dynamic*pager[2547] dynamic\_pager: cannot
open swap directory /private/var/vm\
9/07/09 3:02:07 PM com.apple.launchd[1] (com.apple.dynamic\_pager[2547])
Exited with exit code: 1\
9/07/09 3:02:07 PM com.apple.launchd[1] (com.apple.dynamic\_pager)
Throttling respawn: Will start in 10 seconds\

I don’t know how or why they started but I was able to fix it by simply running sudo mkdir /private/var/vm in Terminal. Within a few seconds of creating the directory, the errors ceased and I could see a swapfile created inside the directory.

I have no idea what caused the directory to be deleted in the first place or why OS X isn’t smart enough to try creating it, but the fix is simple and instantly effective.

Note: I am not sure if this is a Snow Leopard specific issue or not, but it very well might be. Also, these started right after installing Adobe CS4, so I feel pretty confident blaming that for now.

Using accepts_nested_attributes_for When the Child Object validates_presence_of Parent

I came across an interesting dilemma today in Rails 2.3 whilst trying to use accepts_nested_attributes_for.

The models I have were:

class Organization < ActiveRecord::Base
  has_many :users
  accepts_nested_attributes_for :users
end

class User < ActiveRecord::Base
  belongs_to :organization
  validates_presence_of :organization
end

I had an “Organization” creation form which allowed an administrator to create an Organization and an initial user for it. However, even though I had filled in all the required fields to pass the validations I was constantly getting the following error: Organization can not be blank.

Digging deeper I found that when an object is added to an association via the association.build method, the parent object isn’t actually set:

>> o = Organization.new(:name => "Test")
=> #<Organization id: nil, name: "Test">
>> u = o.users.build(:name => "Test User")  
=> #<User id: nil, organization_id: nil, name: "Test User">
>> u.organization
=> nil

Apparently this flaw also applies to accepts_nested_attributes_for. When I send through the User params through from my form normally with the Organization params, it creates the User object in the users association as you’d expect, but raises a validation error because the User instance doesn’t recognise that it is has a parent Organization

My quick 5 minute fix was to modify the Organization model thusly:

class Organization < ActiveRecord::Base
  has_many :users
  accepts_nested_attributes_for :users

  def users_attributes_with_self_assignment=(attributes)
    self.users_attributes_without_self_assignment = attributes
    users.each { |u| u.organization = self }
  end
  alias_method_chain :users_attributes=, :self_assignment
end

Related Rails bugs seem to be here and here. This patch will also solve the problem and is currently in edge, but didn’t make it in time for Rails 2.3.

Fish Shell version of __git_ps1 Function That is Bundled with Git

Today at ActionHack, I was showing off Fish Shell to "`geoffreyd":http://twitter.com/geoffreyd. I was showing off all the cool fish prompt features I had, but pointed out that my git branch portion needed some beefing up, as it didn't show the current mode nor commit shas when not in a branch.

Knowing that git came with a `_*git*ps1 ()@ function for Bash that achieves this, I decided to port it to Fish tonight. My shell scripting fu is pretty weak but as far as I can tell it works great and I am now using it in my shell.

Here is the Fish function (I’ve kept the function name the same as the bash one):

function __git_ps1
  set -l g (git rev-parse --git-dir ^/dev/null)
  if [ -n "$g" ]
    set -l r ""
    set -l b ""

    if [ -d "$g/../.dotest" ]
      if [ -f "$g/../.dotest/rebasing" ]
        set r "|REBASE"
      elseif [ -f "$g/../.dotest/applying" ]
        set r "|AM"
      else
        set r "|AM/REBASE"
      end

      set b (git symbolic-ref HEAD ^/dev/null)
    elseif [ -f "$g/.dotest-merge/interactive" ]
      set r "|REBASE-i"
      set b (cat "$g/.dotest-merge/head-name")
    elseif [ -d "$g/.dotest-merge" ]
      set r "|REBASE-m"
      set b (cat "$g/.dotest-merge/head-name")
    elseif [ -f "$g/MERGE_HEAD" ]
      set r "|MERGING"
      set b (git symbolic-ref HEAD ^/dev/null)
    else
      if [ -f "$g/BISECT_LOG" ]
        set r "|BISECTING"
      end

      set b (git symbolic-ref HEAD ^/dev/null)
      if [ -z $b ]
        set b (git describe --exact-match HEAD ^/dev/null)
        if [ -z $b ]
          set b (cut -c1-7 "$g/HEAD")
          set b "$b..."
        end
      end
    end

    if not test $argv
        set argv " (%s)"
    end

    set b (echo $b | sed -e 's|^refs/heads/||')

    printf $argv "$b$r" ^/dev/null
  end
end

I have also pushed it to my dot-files repository here.

Enjoy :)

UPDATE: Here it is in action:

__git_ps1 for Fish

Using fields_for with Nested Attributes, Calling it Multiple Times

There has been quite an annoying problem that has been bugging @chendo and I today.

In short, fields_for when used with accepts_nested_attributes_fordoes not reset it’s index when it’s called multiple times for the same attribute.

Our scenario was the following:

We had a 3 levels of hierarchical data that we had to display in a <table>. Because of the nature of the data we were displaying one level as columns and the other level as rows. Unfortunately, HTML mandates that we group everything by rows — each column is really just a single cell. This means that we have to iterate over the “column” values not just once, but once for every row.

Now, fields_for takes care of naming your <input> tags magically with the correct indexes so that your models can accept the params directly and magic happens. However, evidently calling fields_for multiple times was not part of the original intention, and it seems resetting the index after each call was neglected.

`chendo couldn't see a cleaner way of doing this so we added our own option to reset the index. We didn't just override the behaviour in case there is a good reason to leave it, but here is our code:

class ActionView::Helpers::FormBuilder
  def fields_for_with_nested_attributes_with_index_reset(association_name, args, block)
    if args.last.is_a?(Hash) && args.last[:reset_index]
      @nested_child_index = nil
    end

    fields_for_without_nested_attributes_without_index_reset(association_name, args, block)
  end

  alias_method_change :fields_for_with_nested_attributes, :index_reset
end

Using AlterEgo with ActiveRecord

Today after finding the gem AlterEgo and falling in love with the API, @chendo and I came to a sad realisation that its beauty was skin-deep. It seems it is not ActiveRecord-aware and overrides #state and #state= on your models. This means that your state column goes untouched and your models are always in the default state.

To get around this, @chendo and I hacked together this little monkey patch which does two things:

  1. It adds question methods for each of your defined states. So if you have states: active, inactive, and banned on your User model, your instances will have #active?, #inactive?, and #banned?
  2. It properly sets and gets the state of the row and loads it into AlterEgo.

Here is the code:

module AlterEgo
  def self.included(base)
    base.instance_eval do

      # This will allow us to define a question method for each state in a class
      # For instance if user has states :active and :inactive, methods active? and inactive?
      # will be defined when first called
      def method_missing_with_states(method, *args, &block)
        begin
          method_missing_without_states(method, *args, &block)
        rescue NoMethodError => e
          state_found = false
          result = nil

          base.states.keys.each do |state|
            if method.to_s == "#{state}?" && !state_found
              self.class.send :define_method, "#{state}?" do
                self.state == state
              end
              state_found = true
              result = self.__send__(method)
            end
          end
          raise(e) unless state_found
          result
        end
      end
      alias_method_chain :method_missing, :states

      # state setter to write to database
      define_method :state= do |value|
        write_attribute(:state, value.to_s)
      end

      # state getter to read from database
      define_method :state_with_active_record do
        (read_attribute(:state) || (self.state = state_without_active_record)).to_sym
      end
      alias_method_chain :state, :active_record
    end
  end
end

How to Prepare Your Mac for Resale

First thing is first: you want to re-install Mac OS X (this guide requires Leopard). Insert your OS X disk and boot off it. Make sure you do a “Clean Install” so as not to leave any of your files on the system.

When the install is finished, your computer will restart and you’ll see the traditional OS X welcome screen and the setup assistant. Go through all the settings, choosing anything just to get the system booted up. However, make sure you take note of the user account login you use. For this guide, I will assume login of temp, and if you don’t have a good reason not to, you should do the same.

At this point you want to download any Apple updates and install them, as well as install any bundled software you plan to advertise the machine coming with. When all your installs are finished and the machine is as you want it for the customer/recipient, shut down the machine.

Next, turn the machine back on but as soon as you hear the Mac chime noise, press and hold ⌘S until you are taken to a console (white text on black screen — looks real nerdy and sci-fi).

The next step is to run all the commands in the code block below

NOTE: If you didn’t use temp as your username you created in the setup assistant, make sure you replace all instances of temp with your actual username.

# Mount the file system so we can modify it
/sbin/fsck -fy
/sbin/mount -uw /

# Activate directory services
/bin/launchctl load /System/Library/LaunchDaemons/com.apple.DirectoryServices.plist &

# Delete all traces of the temporary account
/usr/bin/dscl . -delete /Users/temp
/usr/bin/dscl . -delete /Groups/admin GroupMembership temp
/bin/rm -rf /Users/temp

# Get rid of a few other files
/bin/rm -R /Library/Preferences
/bin/rm -f /root/.bash_history

# Now we make it appear as though the initial setup assistant
# still needs to run
/bin/rm /var/db/.AppleSetupDone

# Reboot and check that it seems like
# it is a new mac, then turn off your computer
# and sell it!
/sbin/reboot