Showing posts with label Rails. Show all posts
Showing posts with label Rails. Show all posts

Tuesday, 22 March 2011

Ruby on Rails 3 - Installing Devise authentication on Heroku

A few days ago I decided to add authentication to my Rails 3 app. I came across a few alternatives but in the end opted for Devise as this seems to be the newest and from the documents I found apparently the easiest to implement.
I needed users to be able to register new users, sign in and out and to have special admin users who could access restricted areas of the site, Devise hit all these requirements.

So I found a couple of good tutorials including https://github.com/plataformatec/devise and associated wiki https://github.com/plataformatec/devise/wiki/_pages and found these really good at getting me up and going quickly.

I got everything working locally but then when I pushed my git repo to Heroku I got the error when using the register page: We're sorry, but something went wrong. We've been notified about this issue and we'll take a look at it shortly.


so to the command line 'Heroku logs' revealed this error:
2011-03-21T14:03:09-07:00 app[web.1]: NameError (uninitialized constant Devise::Encryptors::Bcrypt):

It took me a while but after searching around any trying all sorts of things i hit the answer. and as usual it was simple, if you are deploying to heroku you need to add bcrypt-ruby to your gemfile like so:

gem 'devise', '1.1.8'
gem 'bcrypt-ruby', '2.1.4'


Also remember to generate and commit your new gemfile.lock into git and send this to heroku as well as the new gemfile or you will get the following error, as i did:

You have modified your Gemfile in development but did not check
the resulting snapshot (Gemfile.lock) into version control
You have added to the Gemfile:
* bcrypt-ruby (= 2.1.4)
FAILED: http://docs.heroku.com/bundler
Heroku push rejected, failed to install gems via Bundler


My Devise Authentication Implementation
I've added the following to the top of all my admin controller classes to ensure that only administrators can access them

before_filter :authenticate_user!
before_filter :authorise_user!


The method :authenticate_user! is a helper method built into Devise
The method :authorise_user! is my own declared in ApplicationController as follows:

def authorise_user!
  if ! current_user.try(:admin?)
    flash[:alert] = "Unauthorised"
    redirect_to ''
  end
end


where admin is a boolean field on the devise created user table. (I used option 2 from this wiki page)

For controllers which none admin users have access to I want to restrict them so that they can only see resources that they created. So for example, bob created an order-x, you don't want James to be able to access that order-x it belongs to bob not James.

For this I've created methods similar to:

def authorise_as_owner!
  order = Order.find(params[:id])
  unless current_user.try(:admin?) || order.user_id == current_user.id
    flash[:alert]  = "Not your order!"
    redirect_to ''
  end
end

Thursday, 3 March 2011

Heroku - Installing your app and sqlite3

So ive just installed a dummy rails app to Heroku to test it out, its very very similar to appharbor, unsupprising since appharbor was inspired by heroku.

all went well untll i added a scaffold for my first admin page, when i tried to deploy this i got he error:


Application Error

An error occurred in the application and your page could not be served. Please try again in a few moments.
If you are the application owner, check your logs for details.


so i did check the logs 'heroku logs' (you need the logging add-on instaled for your app) and this is what i saw:

2011-03-03T01:24:00-08:00 heroku[web.1]: State changed from crashed to created
2011-03-03T01:24:00-08:00 heroku[web.1]: State changed from created to starting
2011-03-03T01:24:01-08:00 heroku[web.1]: State changed from crashed to created
2011-03-03T01:24:01-08:00 heroku[web.1]: State changed from created to starting
2011-03-03T01:24:08-08:00 app[web.1]: /usr/ruby1.8.7/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/runtime.rb:64:in `require': no such file to load
-- sqlite3 (LoadError)
2011-03-03T01:24:08-08:00 app[web.1]: from /usr/ruby1.8.7/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/runtime.rb:64:in `require'
2011-03-03T01:24:08-08:00 app[web.1]: from /usr/ruby1.8.7/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/runtime.rb:62:in `each'

...
...
2011-03-03T01:24:08-08:00 app[web.1]: from /home/heroku_rack/heroku.ru:1:in `new'
2011-03-03T01:24:08-08:00 app[web.1]: from /home/heroku_rack/heroku.ru:1
2011-03-03T01:24:08-08:00 heroku[web.1]: State changed from starting to crashed

so what went wrong? well looked like it was a problem loading sqlite3
stackoverflow to the rescue :-)

just make sure the references to sqlite3 are wrapped up as per the following line of code in your gemfile

group :development do
   gem 'sqlite3-ruby', :require => 'sqlite3'
end


and that is it, just do a 'heroku rake db:migrate' to get your database on heroku and your should be good to go.