Tag Archives: Rails

Authenticate using Office 365

This is a extension to a previous post about creating a Rails web site that uses external OAuth providers to authenticate users. Until now the Rails template supported Facebook, Twitter, LinkedIn and Google OAuth providers. Lately I have added Office 365 support to the template available on Github. This could be useful for e.g. companies that want to develop web sites for internal applications and allow their internal users to log on using their standard accounts.

Azure portal

  1. Go to portal.azure.com & log in
  2. Expand “more services” and select “active directory”
  3. Choose “applications” and click “add” at the bottom (or click on ”
    Add an application you’re developing” if you are viewing the domain overview)
  4. Give your web application a name
  5. Enter a Sign-On URL and an App ID URL (e.g. http://example.com/users/sign_in). It is not obvious what the App ID URI should be but it seems to work fine to use the same as the Sign-On URL
  6. Configure the app and modify the reply URL to be e.g. http://example.com/users/auth/office365/callback/
  7. Copy the Client ID and add it to the Rails template
  8. Select duration under “keys”, press save and then copy the generated key to the Rails template

Finally, deploy your web site and hopefully it should work.

Create a web site in 53 seconds

N.B. Make sure to read the follow-up to this article that explains how to support Office 365 authentication.

Do you want to create a responsive web site built on Bootstrap with support for Facebook, Twitter, Linkedin and Google+ login in less than a minute? Read on!

I have been a fan of Ruby on Rails since 2007. For those who are not familiar with the framework, Ruby on Rails, or just Rails, is a platform that makes it possible to build web sites in no time at all. But what is even more important is that the focus on convention over configuration, one of the pillars of Rails, makes it simple to extend upon a site later on, even by someone not involved in the original development. Other platforms I have had experience with do not necessarily share the level of adherence to conventions that allow this with the same ease. Or at all.

Most of the web sites I build these days are based on Rails, whether they are small simple concept sites or big complex sites. I create private sites as well as solutions for my work. And most of the time I find myself adding the same set of features to every site. They are responsive and based on Bootstrap, they allow users to log on with OAuth using Devise and they include role based permissions based on CanCan. I got tired to redoing the same steps for every single site and created a template. You can check out a demo version of the output of the template by looking at http://railyard.spotwise.net – please note that due to inactivity the site may need a few seconds to spin up. The purpose of this article is to share this template and how it is used.

To follow the instructions below you need to register at various sites:

  • A git repository. I recommend Bitbucket since creating private repositories is free for personal use. Github is a popular alternative but without an paid account the code will be open. That may or may not be acceptable by you depending on your project.
  • The OAuth providers you want to use (Facebook, Twitter, Linkedin, Google+). My guess is that most already have an account with these. Note that for Google+ the email address of the account will be visible to users logging in so you may want to consider creating an account specifically for your app.
  • Somewhere to host the site. I use Heroku and the example below is based on that. Heroku provides a free tier for small web sites that can then scale with the load. It is certainly possible to host this elsewhere, including on a server of your own. That may be a topic for another article some other time.

Walkthrough

Create Heroku site, DNS name and code repository

First, log onto Heroku and create a new app. You have a choice of hosting the site in the US or in Europe. You can also define a name for the site if you don’t want Heroku to create a name for you. I normally define a name as that makes it easier to tell them apart later on and I also add a suffix to the hostname to identify the location where the site is hosted.

For this walkthrough I will use the name “myweb” as the name of the app. A possible name in Heroku would then be myweb-eu.herokuapp.com. The herokuapp.com part is added by Heroku and is common to all sites hosted there.

If you want to use a custom DNS name now is the time to go into the configuration settings for your domain(s) and create an alias hostname that points to the name provided by Heroku. Please note that the Heroku hostname may not resolve to a static IP address so you want to create an alias for the Heroku hostname, not an A record for the IP address currently used by Heroku for the site.

Again, continuing with the example a record in the DNS zone could be

@example.com
myweb IN CNAME myweb-eu.herokuapp.com.

If you add a custom DNS name you also need to go back into the Heroku settings and add that alias to the list of names for the site. Otherwise, Heroku will not be able to associate incoming requests to the correct site. In Heroku there would thus be both the myweb-eu.herokuapp.com name as well as myweb.example.com.

Finally, you should create a repository for the code. For Bitbucket this is quickly done by clicking on “Create” and giving the repository a name (e.g. myweb). The rest of the information there is optional and pretty self-explanatory.

Create apps within the various OAuth providers

Next step is to select which OAuth providers you want to use. The template currently supports Facebook, Twitter, Linkedin and Google+ and they are selectively enabled by setting the variable at the top of the script to true for the services you want to use. Within the template there are also links to the developer portals of each of the four supported OAuth providers. In addition to these it supports local users. It is easy to configure the script to use any combination of these. You may want to include all of them or perhaps just one. The choice is yours. One thing to keep in mind is that currently the template does not support associating users with one another. If an individual user logs on using different OAuth providers those will be different local accounts. A special caveat is that if those accounts use the same email address it most likely will not work. For this reason you may want to use all of the providers but instead pick based on your app. Twitter does not provide the email address of the user and can safely be combined with any of the others.

For all of the providers you need to provide the URL of the site. This would be the myweb.example.com or, if you do not use a custom hostname, myweb-eu.herokuapp.com. In many cases you can also provide an application icon that is shown to the end user when logging on. Some specific things to keep in mind for each provider are:

  • Facebook: Copy the “app ID” & “app secret” values to the template. Do not forget to publish the app. If you do not do this only yourself (or other developers you designate) will be able to log on. It will work fine for you but when you ask others to try it out they will not be able to log on. In order to publish the app you need to provide a contact email address.
  • Twitter: Copy the “API key” & “API secret” values to the template. Twitter also requires the callback URL to be specified – http://myweb.example.com/users/auth/twitter/callback.
  • Linkedin: Copy the “API key” & “secret key” values to the template. Enable the r_emailaddress and r_basicprofile scopes.
  • Google+: Copy the “client ID” & “client secret” values to the template. Turn on the two APIs “Contact API” and “Google+ API”

Note: The template makes a differentiation between development and production mode. The keys and secrets for the production site must be unique for the individual application. However, if you plan to use this template for multiple apps you can share the development amongst them, that is how I do it. The development keys and secrets needs to be created separately. They would be very similar to the production site but the hostname would be localhost:3000 instead of myweb.example.com.

Create the actual site

OK, so I lied slightly. This has taken way more than 53 seconds. That time was for the actual creation of the site from the template, which is what we are getting to now.

Download the latest template from https://github.com/spotwise/railyard, currently fourteen-twelve.rb. In theory you could use the template directly from GitHub as described in the readme file but you should adapt it to your needs so I recommend you make a local copy, either by cloning the entire project or by downloading just the template.

Then edit the local template file with your favourite editor. If you use a Mac for your development I would personally recommend Textmate.

Some things you want to edit in the file are:

  • The choice of authentication providers
  • The keys and secrets to the OAuth providers used
  • The choice of Bootswatch theme
  • The data model
  • In general, search for the text TODO in the template file and follow the instructions.

    When you have finished updated the template it is time to actually create the site. Just run the command:

    rails new myweb -m

    Depending on your computer and your Internet connection this will take around a minute (or more). If everything worked you should be able to do:

    cd myweb
    rails s

    After that you should be able to open your browser and access http://localhost:3000.

    If you intend to deploy the code to Heroku you should add the gem rails_12factor. You do this by adding this to the file Gemfile in your application root and then run “bundle install”:

    gem 'rails_12factor'

    Deploy

    Now it is time to push the code to the repository as well as to Heroku. First Bitbucket (other repositories would be similar):

    git remote add origin git@bitbucket.org:[username]/myweb.git
    git push -u origin --all
    git push -u origin --tags

    Where [username] is your Bitbucket username. The above commands can be found in the repository web page.

    Then push the code to Heroku to deploy:

    heroku git:remote -a myweb-eu
    git push heroku master

    Finally, with the code on Heroku you need to migrate your database. To do so run the following command from the root folder of your application:

    heroku run rake db:migrate

    Good luck! If you run into problems or need help, please send a tweet to @spotwise.

Convert Rails 3 project to use jQuery

Rails 3 supports unobtrusive javascript to decouple the content from the logic in a way similar to how CSS has helped web designers to decouple the content from the layout.

By default Rails 3 comes with Prototype. But more and more people are switching to jQuery. The project Rails-3-jQuery on Github simplifies the process of switching out the Prototype support to jQuery. It includes jRails that provides drop-in replacements for Prototype and Scriptaculous helper methods to make it a seamless transition.

To update a project, just issue the following command in the project root

rake rails:template 
   LOCATION=http://github.com/lleger/Rails-3-jQuery/raw/master/jquery.rb

For more information on the project, check the project page on Github.

Simple localisation of Rails validation messages

Rails scaffolding can be good to get up running quickly but it can also be a problem. This is for instance true when it comes to localising the error messages presented by Rails (e.g. “X errors prohibited this <object> from being saved”). The issue is caused by two things:

  1. Rails includes English default message headers for the error box without being apparent how to change them.
  2. Each individual error is prefixed by the capitalised field name. Regardless of GUI language these will probably be in English.

The first of these issues can easily be solved by replacing the default <%= f.error_messages %> with something like:

<%= error_messages_for :item,
:header_message => "Försök igen",
:message => "Några av värdena du har angivit är inte giltiga:" %>

The second is a little harder but can be solved by realising that Rails calls the method human_attribute_name on the model object, passing the column name. While it would be possible to do a switch statement or a lookup array to translate the column name, I have found it easier to just return an empty string and to provide the exact error message as part of the validation instead.

validates_presence_of :name, "Namnet måste anges"


def self.human_attribute_name(attr)
return ""
end

Boolean portability under Rails

Booleans should be so simple. They can only have two values. As a former colleague used to say – How hard can it be? With all the variants of “0/1”, “Y/N”, “t/f” the answer seems to be – Apparently quite so.

Rails 2.0 switched the default database engine to sqlite3 and this has now caused me two issues. The first I wrote about some time back. The last one I just stumbled upon was related to booleans.

This works in MySQL:

@guests = Guest.find(:all, :conditions => 'accept = 1')

But it fails in sqlite3 since Rails stores booleans as ‘t’ or ‘f’ on that database engine. The portable way to write the condition in Rails is to make Rails itself select the proper value depending on the underlying database by writing it like this:

@guests = Guest.find(:all, :conditions => ['accept = ?', true])

Problem installing MySQL Ruby bindings

In a previous article I outlined the installation of a Rails environment on Ubuntu 8.04. That article fails when the target system is a clean installation of Ubuntu 8.04 since it would then be lacking the essential build environment. This is manifested when installing the native extensions for MySQL using “gem install mysql” and the error message shown is:

root@hobbit:~# gem install mysql
Building native extensions. This could take a while...
ERROR: Error installing mysql:
ERROR: Failed to build gem native extension.


/usr/bin/ruby1.8 extconf.rb install mysql
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... no
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

To fix this, just install build-essential, i.e. “apt-get install build-essential”.