Securing a Rails app on Passenger with SSL

Posted by Brian in Howto, Rails, tips, web (July 24th, 2012)

Configuring a site for SSL is simple once you understand the process. Unfortunately I don’t set these up all that often so I forget. In my book Web Development Recipes I cover how to set up the certificates on the Apache server, but I don’t explicitly show how to make it work with a Rails application. So here’s how I usually set things up.

Assume we have a Linux-based server running Ubuntu (either 10.04 or 12.04), we keep our sites in /var/www and we will define our virtual host in the file /etc/apache2/sites-available/mysite

We want to make sure all HTTP requests go to HTTPS. To do that, we need to set up security for the site *and* add a redirect, either at the application level or at the server level. Many folks will recommend using Rack:SSL, but I’m just going to let Apache take care of it for me.

To make all this work we’ll need to enable two Apache modules; ssl and rewrite. The rewrite mod may already be enabled so you should scan your /etc/apache2.conf or your other configs for it.

To enable the mods, we use the a2enmod command:

$ sudo a2enmod ssl
$ sudo a2enmod rewrite

Next we need to modify the site definition in /etc/apache2/sites-available/mysite so it uses SSL and our certificates. First we’ll change the host for HTTP on port 80 so it redirects traffic to the secure site, like this:


  ServerName myapp.example.com
  RewriteEngine On
  RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=permanent]

I’m using named virtual hosts here, so this rewrite only applies to myapp.example.com and none of the other sites I may have set up.

In the same file, we add the definition for the secure site on port 443, the default SSH port. This contains all the info that Passgener needs to spawn the site.


  ServerName myapp.example.com
  DocumentRoot /var/www/myapp/current/public
  
    AllowOverride all
    Options -MultiViews
  

  SSLEngine on 
  SSLOptions +StrictRequire 
  SSLCertificateFile /etc/apache2/certs/myapp.example.com.crt 
  SSLCertificateKeyFile /etc/apache2/certs/myapp.example.com.key 

To make this work, we have to generate the certificate and the key.

We do that by creating the /etc/apache2/certs folder and changing into it:

$ sudo mkdir /etc/apache2/certs
$ cd /etc/apache2/certs

Then we generate our Certificate request which also generates a key.

$ sudo openssl req -new -newkey rsa:2048 -nodes -keyout myapp.example.com.key -out myapp.example.com.csr 

Then we take the csr file and get it signed by the cert admin. Or if we need things secured temporarily, we could
sign it ourselves, knowing that our users will get a nasty warning about unknown certs.

$ openssl x509 -req  -in myapp.example.com.csr \
 -signkey myapp.example.com.key -out myapp.example.com.crt

You really don’t want to go to production with a self-signed certificate though.

Once these files are in the certs directory, we can restart the web server and everything should work as expected.

Installing Oracle Client on Ubuntu.

Posted by Brian in Rails, tips (May 31st, 2011)

Ubuntu isn’t one of the supported operating systems from Oracle, so we have do to some manual work to get things set up.

First, we need to create a home for the files we’ll be downloading.


sudo mkdir -p /opt/oracle/11_2
sudo apt-get install libaio1

Then we need to visit Oracle’s download page and grab these three files for the Instant Client for Linux:

Instant Client Basic-Lite
Instant Client SDK
Instant Client SQLPlus*

We’ll want the ZIP files, not the RPM files, for each one. You will need an Oracle account to download these files.

Then, once we get those zip files over to our Ubuntu server, we need to unzip them all. We should end up with a folder called

instantclient_11_2

Now let’s move that folder into the /opt/oracle/11_2 structure we made.

mv instantclient_11_2 /opt/oracle/11_2/instantclient

Next, we need to open /etc/environment and add this line:


LD_LIBRARY_PATH=/opt/oracle/11_2/instantclient

The LD_LIBRARY_PATH is a variable used by lots of programs that talk to Oracle.

At this point, you will want to estart your terminal session so the environment variable will be available. You could set it manually, but this is a good place to test to make sure that the variable is actually loading into the environment.

Next, we’ll fire up sqlplus to make sure that the Oracle stuff is installed properly.

sqlplus

If it comes up without any errors, we’re good to go. We can exit with CTRL+C.

Next, let’s install the Ruby Oracle adapter. We’ll need to symlink a file since we’re using the InstantClient.


cd /opt/oracle/11_2/instantclient
ln -s libclntsh.so.11.1 libclntsh.so

Next, we need to copy over all the development header files into the instantclient root folder so RubyGems can find them when it needs to compile the native extensions.


cd /opt/oracle/11_2/instantclient/
cp sdk/include/*.h .

Finally, we can install the gem. If you’re using sudo, then the environment won’t have the variables you need so you’ll need to pass them with the command.

sudo env LD_LIBRARY_PATH=/opt/oracle/11_2/instantclient gem install ruby-oci8

That should be it. If you run into other problems, don’t fight with Oracle – just remove the /opt/oracle/11_2/instantclient folder and start over.

How to Survive a Live Coding Demo Without a Projector

Posted by Brian in Accessibility, Howto, Public Speaking, tips (October 10th, 2010)

I love to turn bad situations into opportunities to help others learn. This morning I gave a talk at Twin Cities Code Camp on “Building Mobile Apps with HTML5 and Web Standards”. The talk had a slide deck, but was mostly designed to be a follow-along live demo. When I went in to give the talk, the projector system was locked down. According to my feedback, the talk still worked very well, thanks to the preparation I did beforehand to accommodate for things like this. Hopefully this advice will help you if you’re preparing for a talk in the future.

My slides for the talk are online here. The code is on Github.

Practice Writing and Drawing

I have horrible handwriting when I write fast, and when I’m nervous. I teach a lot though and have learned to slow down and think carefully as I write. Having clear handwriting on a whiteboard is really important because you’re going to have to give people URLs to your content. They need to be able to read it at the back of the room, too, so be sure to write big.

Learn to carefully draw simple shapes that resemble things you’d show on-screen. In my talk, I drew the interface elements we’d be creating and was able to show how they’d look.

Have a live copy people can see

Make the finished product available on your website so people can play with it. If you’re building a web site, provide the URL to the demo version. If you’re demoing an iPhone or Android app, have a link to a video that people can watch that shows the app in action if you can’t get access to put the app on the App store. This helps people see what’s in your head (and on your screen.)

Make a PDF of your slide deck!

If you use Keynote or PowerPoint, or even SlideDown, convert your slides to PDFs. Include presenter notes in your export so that people will have more context as they’re reading along. If you don’t make use of presenter notes, you should start. They can help you when you present, but they can also help jog memories later when people look at your slides at work.

Protip: Presentation Remote for iPhone will let you see the presentation notes in your hand. You can control the slideshow with it as well.

Use Git and Github for your examples

Lately I’ve been using Git branches to stage my code examples. For my talk on HTML5 mobile apps, I started out with a new branch like this:

git init
git checkout -b 01_simple_form

Then I’ll do all the work for the first stage, commit it, and make a new branch for the second stage. In this talk, the first branch was just the HTML for the user interface. The second branch then covered the JavaScript we used to create the database on the client machine.

git add .  
git commit -m "Web form"
git checkout -b 02_create_database

By the time I’m done, I have several branches in the repository that I can use to track the stages of my live demo. At the end, I merge my last branch into the Master branch.

git checkout master
git merge 09_offline

Protip: If I realize that I made a mistake, I can check out the earlier branch, fix the code, commit the code, and merge that fixed branch forward into the branches that followed.

git stash      # puts your in-progress work aside
git checkout 01_simple_form
# fix changes
git commit -am "fixed the form"
git checkout 02_create_database
git merge 01_simple_form
git checkout 03_add_note
git merge 01_simple_form 
git stash apply # put your stuff back

Once I’m ready, I create the new Git repository and push my code. I have to push the master branch and the other branches too.

git remote add origin git@github.com:napcs/html5_offline_notes.git
git push origin master
git push origin 01_simple_form
git push origin 02_create_database
git push origin 03_add_note
..

So how does this help me during a talk? I can direct people to the Github page and they can use the Select branch section to see each branch. The Github web interface lets them follow along as I talk about the code. That’s what I did here.

Git advantages
Uploaded with Skitch!

Be ready offline

As a last resort, take this git repository and your PDF presentation and make it available on a thumb drive, or fire up a local wifi hotspot and run a server. An iPad, iPhone, or iPod Touch with Air Sharing can help with this.

Wrapping Up

So, that’s how I’ve done preparation for my talks and managed to make it through a code-centric talk with just a whiteboard. Do you have any suggestions on what you would do?

Connecting to SQL Server from a Mac (Again)

Posted by Brian in Rails, tips (September 20th, 2010)

Connecting to SQL Server is one task I have to do regularly when I work on Rails applications for clients that use Microsoft technologies. I usually set my machine up and don’t really worry too much about how it all comes together.

Recently I had to do the installation completely from scratch. I followed Ken Collins’ comprehensive walkthrough, but I ran into a problem – I wanted to use RVM. Ken’s tutorial uses MacPorts to install the Ruby ODBC bindings, and I wasn’t using Ruby via MacPorts.

Everything out there wasn’t working for me even when I followed Ken’s article on RVM.

Here’s what ended up working for me.

First, I used MacPorts. Then I installed the ports I needed:

sudo port install unixodbc
sudo port install freetds +odbc

I modified /opt/local/etc/freetds/freetds.conf to look like this:

[my_dev_server]
  host = 192.168.1.58
  port = 1433
  tds version = 8.0

Then I modified /opt/local/odbcinst.ini to point to my FreeTDS configuration:

[FreeTDS]
Decscription = FreeTDS driver for SQLServer
Driver = /opt/local/lib/libtdsodbc.so
Setup = /opt/local/lib/libtdsodbc.so
FileUsage = 1

Finally I modified /opt/local/odbc.ini and created my ODBC DSN.

[my_dev_server_dsn]
Driver=FreeTDS
Description=My Server Connection
Servername=my_dev_server
Server=my_dev_server
Port=1433
Database=killer_app

Note that the servername matches the servername defined in the FreeTDS configuration file.

Then I went and installed the gems I needed for my project

gem install ruby-odbc
gem install dbi  -v=0.4.1
gem install dbd-odbc -v=0.2.4
gem install activerecord-sqlserver-adapter -v=2.3.9

But when I ran my Rails application, attempts to connect to models failed.

ODBC::Error: IM002 (0) [iODBC][Driver Manager]Data source name not found and no default driver specified. Driver could not be loaded

It’s using iODBC which comes with OSX. It wasn’t using UnixODBC at all!

To fix that, I had to reinstall the ruby-odbc gem and instruct it to use the unixodbc path. This is what ultimately fixed things for me:

gem install ruby-odbc -- --with-odbc-dir=/opt/local

After that, everything worked again!

Making “as_string” Attribute Readers for ActiveRecord

Posted by Brian in Howto, Metaprogramming, Rails, tips (March 15th, 2010)

Occasionally, I need to transform boolean model attributes like “active” to display “active” or “inactive” instead of “true” or “false” when making reports or views. A lot of times this means writing some kind of helper method like this:

def active_or_inactive(object, true_message, false_message)
  object.active ? true_message : false_message
end

and calling it like this:

  <%= active_or_inactive(@project, "Active", "Inactive" %>

That’s not a bad approach, and it helps keep the views slightly cleaner by keeping the logic out, but it ends up being more characters than simply using a ternary operator in the view. I’ve used a slightly different approach in some of my more recent projects and I thought I should share it with you.

Move It To The Model

That’s right, I’m advocating pushing that helper into the model itself. I can hear you now, yelling something about “this guy doesn’t know what he’s talking about! How dare he put display logic in his models!” But before you close your browser, allow me to explain.

It just so happens that I need this logic not only in my views, but in my text-based reports that I run outside of the web server. I could mix the module with the helpers in when I needed it, but there’s also something un-object-oriented that bugs me about helpers. They remind me of PHP a bit. I feel like I should be calling object.active_as_string("Active", "Inactive") instead. So that’s what I’m going to do.

First, a unit test, because we’re all good professionals that write tests first. I want to call a method called active_as_string which takes two parameters – the string to print when it’s true and the string to print when it’s
false. Here are my tests:

require 'test_helper'

class ProjectTest < ActiveSupport::TestCase

  test "should display 'Active' if active" do
    p = Project.new(:active => true)
    assert_equal p.active_as_string("Active", "Inactive"), "Active"
  end

  test "should display 'Inactive' if not active" do
    p = Project.new(:active => false)
    assert_equal p.active_as_string("Active", "Inactive"), "Inactive"
  end
end

Tests help me design the method’s use up front. With two failing tests as my guide, I can now take my first stab at making the method work:

class Project < ActiveRecord::Base
   def active_as_string(true_message, false_message)
      self.active ? true_message : false_message
   end
end

With that implemented, my tests pass. However, I also have a "closed" boolean I need to handle, and it would also be nice if I could display "No description" if a project's description was blank. I could write my own _as_string methods like I've done already, but instead, I'll do a little metaprogramming to generate what I need.

Let's add four more test cases - to test the "closed" and the "description" fields.

  test "should display 'Closed' if closed" do
    p = Project.new(:closed => true)
    assert_equal p.closed_as_string("Closed", "Open"), "Closed"
  end

  test "should display 'Open ' if not closed" do
    p = Project.new(:active => false)
    assert_equal p.closed_as_string("Closed", "Open"), "Open"
  end
  
  test "should display 'No Description' if description is nil" do
    p = Project.new(:description => nil)
    assert_equal p.description_as_string("No Description"), "No Description"
  end

  test "should display the description if it exists" do
    p = Project.new(:description => "Hi there!")
    assert_equal p.description_as_string("No Description"), "Hi there!"
  end

Now, let's build some methods!

ActiveRecord::Base.columns

Every ActiveRecord class has a class method called columns that returns a collection of column objects. The Column object describes each database column and lets you determine its type and its name. We can use that and class_eval to generate a whole bunch of methods at runtime.


class Project < ActiveRecord::Base
  self.columns.each do |column|

    if column.type == :boolean

      class_eval <<-EOF

        def #{column.name}_as_string(t,f)
          value = self.#{column.name}
          value ? t : f
        end

      EOF

    end
  end
end

In this example, we're creating the _as_string method for each boolean column. It takes two parameters and is basically the same code we already used in our original method earlier. Notice how class_eval can do string interpolation using Ruby's #{} syntax. That makes it easy to build up the method names.

We can use that same concept to do the same for any other methods - we'll just cast them to strings and check to see if they are blank.

  class_eval <<-EOF

    def #{column.name}_as_string(default_value)
     value = self.#{column.name}.to_s
     value.blank? ? default_value : value
    end

  EOF

We throw that into the else block and our whole example looks like this:

  class Project < ActiveRecord::Base
  
    self.columns.each do |column|
    
      if column.type == :boolean
      
        class_eval <<-EOF
        
          def #{column.name}_as_string(t,f)
            value = self.#{column.name}
            value ? t : f
          end
          
        EOF
        
      else
      
      class_eval <<-EOF
      
          def #{column.name}_as_string(default_value)
           value = self.#{column.name}.to_s
           value.blank? ? default_value : value
          end
          
        EOF
        
      end
      
    end
  end

If you run your tests now, they all pass. But our work isn't done - this isn't very DRY. We may want to use this in another class too.

Modules!

Create a new module and mix the behavior into your models. Create the file lib/active_record/as_string_reader_methods.rb (create the active_recordfolder if it doesn't exist already) and put this code in the file:

  module ActiveRecord
    module AsStringReaderMethods
     def self.included(base)
       create_string_readers(base)
     end

     def self.create_string_readers(base)
      base.columns.each do |column|

         if column.type == :boolean

           class_eval <<-EOF

             def #{column.name}_as_string(t,f)
               value = self.#{column.name}
               value ? t : f
             end

           EOF
         else

           class_eval <<-EOF

             def #{column.name}_as_string(default_value)
               value = self.#{column.name}.to_s
               value.blank? ? default_value : value
             end

           EOF
         end
       end
     end
    end
  end

It's mostly the same code we had before, but in this case we're using the self.included method to trigger the method creation on the model that includes the module.

Now, remove the code from your Project mode and replace it with

include AsStringReaderMethods

Run your tests, and everything should pass. You now have a module you can drop into your projects and you'll have this functionality yourself. Now it's up to you to expand upon this, and use this pattern in your own work if you find it useful.

Good luck!

Rails and SQL Server – “There is no text for object”

Posted by Brian in Howto, Rails, tips (February 23rd, 2010)

I recently moved a Rails application to a new SQL Server 2005 server on a recent project and everything seemed to go smoothly, but when I tried to fire up a connection to the database from my Rails application, I was greeted with

ActiveRecord::StatementInvalid: DBI::DatabaseError: 42000 (15197) [FreeTDS][SQL Server]There is no text for object 'people'.: EXEC sp_helptext people

The “people” table here is actually a view that gets used all over the place in multiple applications. The DBA had moved the databases from an older SQL Server 2000 database previously.

The solution was to ensure that the application’s user account had the “view definition” permission on the view in question as well as the “select” permission. On the view, in the SQL Server Management Studio, right click and choose “Properties”. Then choose Permissions select your user account, and then select the “View definition” permission. Checking the box under the “Grant” column was enough for me to make it work.

Interestingly enough, the production server (which was upgraded months ago from SQL Server 2000 to 2005), does not have the permission set, but still works fine.

Hopefully someone else finds this useful.

Moving from Prototype to JQuery

Posted by Brian in tips, web (November 15th, 2009)

On a recent project, I converted a ton of Javascript from Prototype to jQuery in order to take advantage of many of the nice UI elements available. As I did the conversion, I took down some notes that I wanted to share with you about the differences between the two libraries. In some cases, the differences are insignificant, and in a couple of others, the differences merely come down to a difference of opinion among the developers and supporters of the libraries.

Here are the notes:

Getting Ready

Before you can work with elements on the page, those elements must be loaded.

Prototype uses

document.observe("dom:loaded", function() {
  // your functions
})

jQuery uses this:

$(document).ready(function(){
  // your functions
})

Finding things

In Prototype, you use $() or $$() to locate elements. With $() you use the ID, whereas with $$() you use a CSS selector.

  var header = $("header");  // a single element, 

With JQuery, you do almost all of your element location using $(), which works very much like $$() in Prototype.

  var header = $("#header");  // a single element, 

Binding events

Prototype’s Element class has an Observe method. It’s very easy to use and easy on the eyes.

  $("header").observe("click", function(event){
    alert("Hi there");
  });

In jQuery, it’s nearly identical, except that click is a method on the JQuery object.

  $("#header").click(function(event){
    alert("Hi there");
  });

At first, the differences look marginal, but let’s look at a more complicated example:

In Prototype, to find all links on the page with the class “Popup” and make them open in a new window, you have to do this:

function new_window_links(){
  links = $$("a.popup");
  links.each(function(link){
    link.observe("click", function(event){
      window.open(link.href);
      event.stop();
    });
  });
}

The Prototype version makes us find all of the elements, loop over them, and then apply the observer to each one.

jQuery can hide the iteration from you, which results in somewhat cleaner code.

function new_window_links(){
  links = $("a.popup").click(function(event){
      window.open($(this).attr('href'));
      event.preventDefault();
  });
}

Adding Classes

Prototype:

   $(".foo").addClassName("ninja");
  $(".foo").addClass("ninja");

Traversing the DOM

Prototype:

  parent_of_foo = $("foo").up();

jQuery

  parent_of_foo = $("#foo").parent();

Working with HTML attributes

This one was the most difficult to get used to. In Prototype, many of the HTML attributes are available as methods on the Element class.

  window.open(link.href);

In jQuery, you use the attr method to get and set the attributes.

  window.open(link.attr("http");

This illustrates only a few of the differences between the libraries, but as you can see, the differences don’t realy amount to anything substantial. Both of these libraries greatly simplify cross-browser JavaScript development, so no matter which you choose, you’ll be in good shape.

Mongodb and Macports

Posted by Brian in tips (October 20th, 2009)

I just hit a bump in the road with installing MongoDB via Macports 1.8.1.

sudo port install boost pcre++ spidermonkey
sudo port install mongodb

When I ran

mongodb

I was greeted with

dyld: Library not loaded: /opt/local/lib/libnspr4.dylib
  Referenced from: /opt/local/lib/nspr/libplds4.dylib
  Reason: image not found
Trace/BPT trap

To fix, I simply copied the missing file from its origin to where Mongodb was looking.

 sudo  cp /opt/local/lib/nspr/libnspr4.dylib /opt/local/lib

And all was right.

Saving without callbacks

Posted by Brian in Howto, Rails, tips (August 19th, 2009)

Occasionally, you need to do something to a model without invoking callbacks. This is especially necessary for instances where you need to modify the record you just saved in an after_save callback. For example, say you want to create a hash based on the record’s ID. You won’t have the ID until after it’s been saved, and if you call self.save in an after_save callback, you’re going to end up in an endless loop.

It turns out that ActiveRecord has two private methods.

create_without_callbacks

and

update_without_callbacks

Remember that private in Ruby is less about keeping you from calling the methods and more about letting you know that you shouldn’t depend on them. With Ruby’s send method, using either of these in your application is easy.

Note that in Ruby 1.9, send doesn’t allow calling private methods, but send! does.

  class Project < ActiveRecord::Base
    after_save :create_hash_from_name_and_id

    private
      def create_hash_from_name_and_id
        self.hash = Digest::SHA1.hexdigest("#{self.id}#{Time.now.to_s}#{self.name}")
        self.send :update_without_callbacks
      end
  end

It's my opinion that these methods should not be private. If I can skip validations with save(false), then I should be able to skip callbacks as well.

There are other patterns you can use to skip callbacks.

  class Project < ActiveRecord::Base
    attr_accessor :skip_callbacks

    with_options :unless => :skip_callbacks do |project|
      project.after_save :create_hash_from_name_and_id
      project.after_save :do_more_stuff
    end

    private
      def create_hash_from_name_and_id
        self.skip_callbacks = true
        self.hash = Digest::SHA1.hexdigest("#{self.id}#{Time.now.to_s}#{self.name}")
        self.save
      end
  end

So there you go. Go forth and skip callbacks at will.

Geokit and named_scope

Posted by Brian in Rails, tips (August 11th, 2009)

I discovered that the geokit_rails plugin doesn’t support named_scope. For those unfamiliar, named_scope methods can be chained to narrow down a query while only performing one query. Here’s an example:

class Business < ActiveRecord::Base
  acts_as_mappable 
  named_scope :active, :conditions => {:active => true}
  named_scope :nonprofit, :conditions => {:nonprofit => true}
end

@active_businesses = Business.active
@nonprofits = Business.nonprofit
@active_nonprofits = Business.active.nonprofit

Geokit has a really nice syntax for locating businesses within a certain distance.

@businesses = Business.find :all, :origin => "742 Evergreen Terrace, Springfield IL", :within => 10

However, you simply cannot, out of the box, use this with named_scopes. So I cannot do

@businesses = Business.active :origin => "742 Evergreen Terrace, Springfield IL", :within => 10

The way Geokit exposes itself to ActiveRecord is just not compatible.

RailsCasts to the Rescue!

Ryan Bates, Railscasts producer and all-around awesome guy, has posted a solution in which you can build your own dynamic named scopes. We can create our own scope for Geokit, because the Geokit-Rails plugin provides a public method to retrieve the distance SQL fragment.

First, we add a new named scope to our model

   named_scope :map_conditions, lambda { |*args| {:conditions => args} }

Next, we add our own method to handle the scopes.

    def self.by_location(options ={})
      scope = self.scoped({})
      scope = scope.map_conditions "#{distance_sql(options[:origin])} <= #{options[:within]}"
      scope
    end

We use this method to append our own conditions to the anonymous scope. we use the distance_sql method which takes whatever we pass in via our :origin option, and we concatonate the equality. In this case, we want distance less than or equal to our distance.

We can now do exactly what we wanted, although with modified syntax.

@businesses = Business.active.nonprofit.by_location :origin => "742 Evergreen Terrace, Springfield IL", :within => 10

Pretty amazing stuff.

Next Page »