“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay...”

Rob Lacey (contact@robl.me)
Senior Software Engineer, Brighton, UK

Facebook Development with Adobe AIR

http://wiki.developers.facebook.com/index.php/Facebook_for_Adobe_AIR

Skip all filters

I found some code recently for a client that skips (or should at least) skip all filters in a controller. I haven’t seen this done before and a quick google clarified someone else has put it to use somewhere, as I wasn’t sure if this should ever have worked.

class FooController < ApplicationController
  skip_filter filter_chain
end

http://markmcb.com/2008/10/14/skip-all-rails-filters/

It was actually implemented with a little more functionality to set options for all the filters that are being skipped. e.g only for particular actions in a controller.

class ApplicationController

  def self.skip_all_filters(options = {})
    skip_filter filter_chain, options
  end

end

However, this doesn’t appear to work in post Rails 2.1 applications. So I found myself using the following instead.

class ApplicationController
 
  def self.skip_all_filters(options = {})
    filter_chain.map(&:method).each do |filter|
      skip_filter filter, options
    end
  end

end

class FooController < ApplicationController
  
  before_filter :do_something
  skip_all_filters :only => [:blah, :blah2]

end

htpasswd files and basic Apache authetication

Its been a long time since I needed to do any kind of basic Apache authetication so a quick reminder to myself more than anything.

Its easy to generate a new file with the username and password. Don’t use ‘-c’ the next time as you’ll lose the contents of your original file.

htpasswd -b -c /var/www/websitething/.htpasswd username password

Adding this to my basic VirtualHost config now restricts access to the site with my username/password. woo.

<VirtualHost *:80>
  ServerName
  DocumentRoot /var/www/websitething/public

  <Directory /var/www/websitething/public>
    AuthType Basic
    AuthName MyPrivateFile
    AuthUserFile /var/www/websitething/.htpasswd
    Satisfy All
    Require valid-user
  </Directory>

</VirtualHost>

RSpec 1.2.7 and Spork

I just updated the RSpec gem today since seeing from The RSpec book update that there is a new release.

rl@bloodandguts:~/project$ ./script/spec_server 
Loading Rails environment

*****************************************************************
DEPRECATION WARNING: you are using deprecated behaviour that will
be removed from a future version of RSpec.

/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'

* spec_server is deprecated.
* please use spork (gem install spork) instead.
*****************************************************************

So…here we go.

rl@bloodandguts:~/project$ sudo gem install spork
Successfully installed spork-0.5.7
1 gem installed
Installing ri documentation for spork-0.5.7...
Updating ri class cache with 7915 classes...
Installing RDoc documentation for spork-0.5.7...

Update the spec helper with the bootstrap command

rl@bloodandguts:~/project$ spork --bootstrap
Using RSpec
Bootstrapping /home/rl/project/spec/spec_helper.rb.
Done. Edit /home/rl/project/spec/spec_helper.rb now with your favorite text editor and follow the instructions.

The spec_helper will have instructions on how to edit the file although I mostly took the previous contents of the file and placed it in the ‘Spork.prefork’ block.

require 'rubygems'
require 'spork'

Spork.prefork do
  # Loading more in this block will cause your tests to run faster. However, 
  # if you change any configuration or code from libraries loaded here, you'll
  # need to restart spork for it take effect.
end

Spork.each_run do
  # This code will be run each time you run your specs.

end

# --- Instructions ---
# - Sort through your spec_helper file. Place as much environment loading 
#   code that you don't normally modify during development in the 
#   Spork.prefork block.
# - Place the rest under Spork.each_run block
# - Any code that is left outside of the blocks will be ran during preforking
#   and during each_run!
# - These instructions should self-destruct in 10 seconds.  If they don't,
#   feel free to delete them.
#

# This file is copied to ~/spec when you run 'ruby script/generate rspec'
# from the project root directory.

Starting the server with just ‘spork’

rl@bloodandguts:~/project$ spork
Using RSpec
Preloading Rails environment
Loading Spork.prefork block...
Spork is ready and listening on 8989!

And run your spec for good measure.

rl@bloodandguts:~/project$ spec --drb spec/models/user_spec.rb 
.....

Finished in 6.806868 seconds

5 examples, 0 failures, 0 pending

Installing new fonts on Ubuntu

Normally I do all of my image manipulation on Windows with Photoshop as I am not a big fan of GIMP, so I’ve never had to install a new font before. Not immediately obvious but you can do it like so.

rl@bloodandguts:~$ sudo mkdir /usr/share/fonts/truetype/robl/
rl@bloodandguts:~$ sudo cp /home/rl/Desktop/HorsePuke.ttf /usr/share/fonts/truetype/robl/
rl@bloodandguts:~$ sudo fc-cache -fv
/usr/share/fonts: caching, new cache contents: 0 fonts, 3 dirs
/usr/share/fonts/X11: caching, new cache contents: 0 fonts, 6 dirs
.......
/usr/share/fonts/truetype/robl: caching, new cache contents: 1 fonts, 0 dirs
.......
fc-cache: succeeded

A solution to the pain of FBJS

I’ve been trying to develop a small Facebook application and FBJS is getting in the way somewhat. We have an existing application which we can easily plug in to Facebook with a few tweaks but sadly most if not all of our jQuery is completely useless.

Facebook add security re-jig all of your javascript into its own namespace by prefixing ‘applicationid_’ to each function and variable and then only allow limited access to javascript by means of implementing their own slightly modified version FBJS.

Unfortunately this means our jQuery flounders and we have to rewrite to get the same functionality. One potential saving grace is this little script that someone has come up with

http://forum.developers.facebook.com/viewtopic.php?id=33519

Its a re-write of basic jQuery functionality in FBJS, so in theory you can just plugin your existing jQuery and it will just work. It hasn’t worked for me but I think I was being a little optomistic that everything would just magically work still I am going to keep on working with it to see what more I can get out of it.

ActiveRecord and getting the timing right

Have you ever with returning record that are depedndent on time based criteria. One of my last projects had a token based logging in system. A user clicked a login button, it created a token on a remote site and redirected the user away to the other site if the token matched and wasn’t out of date (more than 30 seconds old) then the user was logged in.

So we’d employ something like

Token.create(:token => 'something random', :expires_at => 30.seconds.from_now)

On the remote server we’d then attempt to recover the token

Token.find(:first, :conditions => ["token = ? AND expires_at < now()",  'something random'])

We then started to get problems with people just not being able to login. It didn’t take 30 seconds to redirect and recover the token from the database so what was going on.

The database server was on a different server to the web server which hosted both the Main site and the one that allowed token access. However the database server time was about 10mins behind the time on the webserver so Ruby’s Time.now and SQL’s now() or CURRENT_TIME() were returning the incorrect results.

At that point running ‘ntpdate’ to update the server time on the database server worked. But going back and fixing every instance of ‘now()’ was probably the smart move.

Token.find(:first, :conditions => ["token = ? AND expires_at < ?",  'something random', Time.now])

There’s a lesson to be learned from that, if you’re going to trust the time then it should be the same across all the servers you are using. But also if we are using an ORM to encapsulate SQL logic then stray into SQL at your peril as you may get unexpected results.

Development on a local machine whilst being publicly visible on the net

Just read a nice little tip in the “Developing Facebook Platform Applications with Rails”. If you’re working off a laptop in an office or at home and you want your app to be viewable on the public internet you don’t have to develop on a remote server. You can however use ssh to forward requests from a remote server (if you have one) over an ssh tunnel to your local machine.

Once minor addition to your /etc/ssh/sshdconfig

GatewayPorts clientspecified

and reload the config. Be very careful here, there’s nothing worse than changing your config and accidentally locking yourself out of your remote machine.

root@li38-149:~# /etc/init.d/ssh reload
 * Reloading OpenBSD Secure Shell server's configuration sshd

Now trying the following from your local command line.

rl@bloodandguts:~/project$ ssh user@yourserver.com -R :9000:127.0.0.1:9000 sleep 99999

Accessing http://yourserver.com:9000 will now serve the application over the tunnel. Obivously your provider will need to allow the port you are trying to access available. Some ports are locked down by firewalls and so a little extra running around may be required.

Model.find_or_create_by_attribute

I was under the impression that find_or_create_by worked like so…

Model.find_or_create_by_attribute('attribute, :other => '1', :stuff => '2')

But it seems its actually like….hmmzzz….when did that happen or am I going crazy.

Model.find_or_create_by_attribute(:attribute => 'attribute', :other => '1', :stuff => '2')

rspec and parameter filtering

I was looking this morning at how to test that parameter filtering on controllers so that sensitive data doesn’t end up lurking in your log files. ie. credit card numbers, passwords. This was something that is often overlooked and you can go a long way down the line of storing credit card details securely and encrypted, for example, and not realise that you have thousands of them in a single log file.

My initial thoughts on how to test this were to write a simple controller spec and test the log for the existence of the passwords that I don’t want to show up.

post :create, :user => { :pasword => 'kj123ert', :password_confirmation => 'kjl123ert' }

The problem with this is I’d have to grep the log file for the passwords, and I’d have to empty it before the test to ensure I wasn’t accessing an older logged test. Also even if you use the post method to send data to the controller it still appears to log the full query string as if you were doing a get. Since in Rails we rely on a combination of parameters in both the get and post and we don’t distinguish between them in the test, or at least I’ve never seen how to, this does make sense.

Processing FooController#index (for 0.0.0.0 at 2009-05-18 08:48:20) [POST]
  Parameters: {"password_confirmation"=>"[FILTERED]", "action"=>"index", "controller"=>"foo", "password"=>"[FILTERED]"}
Completed in 8ms (View: 1, DB: 30) | 200 OK [http://test.host/foo?password=kj123ert&password_confirmation=kj123ert]

So another solution presents itself. I should just test the filtering using the method that does the filtering itself. Fortunately it wasn’t that difficult to track down.

Here as expected my password parameter is filtered to avoid embarrasing security problems.

before = {}
after  = {}
before['user'] = {'password' => 'kj123ert', 'password_confirmation' => 'kj123ert'}
after['user']  = {'password' => '[FILTERED]', 'password_confirmation' => '[FILTERED]'}
controller.__send__(:filter_parameters, before).should == after