Permalink
Browse files

Log in with google's openid.

  • Loading branch information...
spraints committed Nov 29, 2011
1 parent f47df1b commit 60dd54badee8bde2054fbeb8cc7244d1e96ff6f4
@@ -1,3 +1,21 @@
class ApplicationController < ActionController::Base
protect_from_forgery
+
+ def sign_in_from_omniauth omniauth
+ # only trust google's openid. We don't want no imposters!
+ if omniauth[:provider] == :open_id && omniauth[:uid] =~ %r{^https://www.google.com/accounts/o8/id}
+ session['email'] = omniauth[:info][:email]
+ elsif Rails.env.development?
+ raise omniauth[:provider].inspect unless omniauth[:provider] == 'open_id'
+ raise omniauth[:uid].inspect unless omniauth[:uid] =~ %r{^https://www.google.com/accounts/o8/id}
+ raise "huh?"
+ end
+ end
+
+ def self.signed_in? request
+ if email = request.session['email']
+ return true if email =~ /@crankapps.com$/
+ end
+ return false
+ end
end
@@ -0,0 +1,6 @@
+class SessionsController < ApplicationController
+ def create
+ sign_in_from_omniauth request.env['omniauth.auth']
+ redirect_to root_path
+ end
+end
@@ -0,0 +1,7 @@
+require 'openid/association'
+
+class OpenIdAssociation < ActiveRecord::Base
+ def to_assoc
+ OpenID::Association.new(handle, secret, Time.at(issued), lifetime, assoc_type)
+ end
+end
@@ -0,0 +1,2 @@
+class OpenIdNonce < ActiveRecord::Base
+end
@@ -0,0 +1,2 @@
+class ProjectMapping < ActiveRecord::Base
+end
@@ -8,6 +8,8 @@
</head>
<body>
+ You are <%= session[:email] %>.
+
<%= yield %>
</body>
@@ -0,0 +1,8 @@
+- if params[:message]
+ %p{style: 'color: red'}
+ = params[:message].titleize
+%p
+ You must sign in with a crankapps.com email address.
+%form{action: '/auth/open_id', method: 'post'}
+ = hidden_field_tag 'openid_url', 'https://www.google.com/accounts/o8/id'
+ = submit_tag 'Sign in with google'
View
@@ -16,7 +16,7 @@ class Application < Rails::Application
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
- # config.autoload_paths += %W(#{config.root}/extras)
+ config.autoload_paths << config.root.join('lib')
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
@@ -0,0 +1 @@
+Rails.application.config.middleware.use OmniAuth::Strategies::OpenID, :store => OpenID::Store::ActiveRecord.new
View
@@ -1,58 +1,16 @@
Kanbfire::Application.routes.draw do
- # The priority is based upon order of creation:
- # first created -> highest priority.
+ resources :project_mappings
- # Sample of regular route:
- # match 'products/:id' => 'catalog#view'
- # Keep in mind you can assign values other than :controller and :action
+ match 'auth/open_id/callback' => 'sessions#create'
+ match 'auth/failure' => 'sessions#new'
- # Sample of named route:
- # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
- # This route can be invoked with purchase_url(:id => product.id)
+ logged_in = lambda do |request|
+ ApplicationController.signed_in? request
+ end
- # Sample resource route (maps HTTP verbs to controller actions automatically):
- # resources :products
+ constraints logged_in do
+ root :to => 'dashboards#show'
+ end
- # Sample resource route with options:
- # resources :products do
- # member do
- # get 'short'
- # post 'toggle'
- # end
- #
- # collection do
- # get 'sold'
- # end
- # end
-
- # Sample resource route with sub-resources:
- # resources :products do
- # resources :comments, :sales
- # resource :seller
- # end
-
- # Sample resource route with more complex sub-resources
- # resources :products do
- # resources :comments
- # resources :sales do
- # get 'recent', :on => :collection
- # end
- # end
-
- # Sample resource route within a namespace:
- # namespace :admin do
- # # Directs /admin/products/* to Admin::ProductsController
- # # (app/controllers/admin/products_controller.rb)
- # resources :products
- # end
-
- # You can have the root of your site routed with "root"
- # just remember to delete public/index.html.
- # root :to => 'welcome#index'
-
- # See how all your routes lay out with "rake routes"
-
- # This is a legacy wild controller route that's not recommended for RESTful applications.
- # Note: This route will make all actions in every controller accessible via GET requests.
- # match ':controller(/:action(/:id(.:format)))'
+ root :to => 'sessions#new'
end
@@ -0,0 +1,19 @@
+# Use this migration to create the tables for the ActiveRecord store
+class AddOpenIdStoreToDb < ActiveRecord::Migration
+ def change
+ create_table "open_id_associations", :force => true do |t|
+ t.column "server_url", :binary, :null => false
+ t.column "handle", :string, :null => false
+ t.column "secret", :binary, :null => false
+ t.column "issued", :integer, :null => false
+ t.column "lifetime", :integer, :null => false
+ t.column "assoc_type", :string, :null => false
+ end
+
+ create_table "open_id_nonces", :force => true do |t|
+ t.column :server_url, :string, :null => false
+ t.column :timestamp, :integer, :null => false
+ t.column :salt, :string, :null => false
+ end
+ end
+end
View
@@ -0,0 +1,31 @@
+# encoding: UTF-8
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# Note that this schema.rb definition is the authoritative source for your
+# database schema. If you need to create the application database on another
+# system, you should be using db:schema:load, not running all the migrations
+# from scratch. The latter is a flawed and unsustainable approach (the more migrations
+# you'll amass, the slower it'll run and the greater likelihood for issues).
+#
+# It's strongly recommended to check this file into your version control system.
+
+ActiveRecord::Schema.define(:version => 20111129164804) do
+
+ create_table "open_id_associations", :force => true do |t|
+ t.binary "server_url", :null => false
+ t.string "handle", :null => false
+ t.binary "secret", :null => false
+ t.integer "issued", :null => false
+ t.integer "lifetime", :null => false
+ t.string "assoc_type", :null => false
+ end
+
+ create_table "open_id_nonces", :force => true do |t|
+ t.string "server_url", :null => false
+ t.integer "timestamp", :null => false
+ t.string "salt", :null => false
+ end
+
+end
@@ -0,0 +1,54 @@
+require 'openid/store/interface'
+
+module OpenID
+ module Store
+ class ActiveRecord < OpenID::Store::Interface
+ def store_association server_url, assoc
+ remove_association server_url, assoc.handle
+ OpenIdAssociation.create!(
+ :server_url => server_url,
+ :handle => assoc.handle,
+ :secret => assoc.secret,
+ :issued => assoc.issued.to_i,
+ :lifetime => assoc.lifetime,
+ :assoc_type => assoc.assoc_type
+ )
+ end
+
+ def get_association server_url, handle=nil
+ scope = OpenIdAssociation.where :server_url => server_url
+ scope = scope.where :handle => handle unless handle.blank?
+ scope.each do |stored_assoc|
+ assoc = stored_assoc.to_assoc
+ if assoc.expires_in == 0
+ stored_assoc.destroy
+ else
+ return assoc
+ end
+ end
+ nil
+ end
+
+ def remove_association server_url, handle
+ OpenIdAssociation.delete_all(:server_url => server_url, :handle => handle)
+ end
+
+ def use_nonce server_url, timestamp, salt
+ scope = OpenIdNonce.where(:server_url => server_url, :timestamp => timestamp, :salt => salt)
+ return false if scope.any?
+ return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew
+ scope.create!
+ return true
+ end
+
+ def cleanup_nonces
+ now = Time.now.to_i
+ Nonce.delete_all(['timestamp > ? OR timestamp < ?', now - OpenID::Nonce.skew, now + OpenID::Nonce.skew])
+ end
+
+ def cleanup_associations
+ Association.delete_all(['issues + lifetime > ?', Time.now.to_i])
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit 60dd54b

Please sign in to comment.