RickBacci
12/1/2010 - 1:56 AM

OmniAuth strategy for a custom provider

OmniAuth strategy for a custom provider

# lib/pixelation_strategy.rb
require 'omniauth/core'
module OmniAuth
  module Strategies
    class Pixelation
      include OmniAuth::Strategy

      # receive parameters from the strategy declaration and save them
      def initialize(app, secret, auth_redirect, options = {})
        @secret = secret
        @auth_redirect = auth_redirect
        super(app, :pixelation, options)
      end

      # redirect to the Pixelation website
      def request_phase
        r = Rack::Response.new
        r.redirect @auth_redirect
        r.finish
      end

      def callback_phase
        uid, username, avatar, token = request.params["uid"], request.params["username"], request.params["avatar"], request.params["token"]
        sha1 = Digest::SHA1.hexdigest("a mix of  #{@secret}, #{uid}, #{username}, #{avatar}")

        # check if the request comes from Pixelation or not
	if sha1 == token
          @uid, @username, @avatar = uid, username, avatar
          # OmniAuth takes care of the rest
	  super
        else
	  # OmniAuth takes care of the rest
          fail!(:invalid_credentials)
        end
      end

      # normalize user's data according to http://github.com/intridea/omniauth/wiki/Auth-Hash-Schema
      def auth_hash
        OmniAuth::Utils.deep_merge(super(), {
          'uid' => @uid,
          'user_info' => {
            'name'     => @username,
            'nickname' => @username,
            'image'    => @avatar
          }
        })
      end
    end
  end
end
# config/initializers/omniauth.rb
module OmniAuth
  module Strategies
    # tell OmniAuth to load our strategy
    autoload :Pixelation, 'lib/pixelation_strategy'
  end
end

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, "app_name", "secret"
  provider :facebook, "app_name", "secret", :scope => ''
  # pass the 2 parameters to the constructor
  provider :pixelation, "secret", "redirect URL"
end