Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 71115834e694baa7f9f48fc026abf4d3647c9069 @lancejpollard committed May 18, 2010
Showing with 1,674 additions and 0 deletions.
  1. +3 −0 .gems
  2. +6 −0 .gitignore
  3. +3 −0 Capfile
  4. +109 −0 README.rdoc
  5. +10 −0 Rakefile
  6. +60 −0 app/controllers/application_controller.rb
  7. +28 −0 app/controllers/user_sessions_controller.rb
  8. +49 −0 app/controllers/users_controller.rb
  9. +2 −0 app/helpers/application_helper.rb
  10. +61 −0 app/models/profile.rb
  11. +5 −0 app/models/user.rb
  12. +3 −0 app/models/user_session.rb
  13. +20 −0 app/views/layouts/application.html.haml
  14. +3 −0 app/views/shared/_github.haml
  15. +20 −0 app/views/shared/_head.haml
  16. +3 −0 app/views/shared/_logo.haml
  17. +17 −0 app/views/user_sessions/new.html.haml
  18. +4 −0 app/views/users/_form.html.haml
  19. +17 −0 app/views/users/_new.html.haml
  20. +18 −0 app/views/users/edit.html.haml
  21. +17 −0 app/views/users/new.html.haml
  22. +8 −0 app/views/users/show.html.haml
  23. +17 −0 config/authlogic.example.yml
  24. +110 −0 config/boot.rb
  25. +22 −0 config/database.yml
  26. +74 −0 config/environment.rb
  27. +17 −0 config/environments/development.rb
  28. +21 −0 config/environments/production.rb
  29. +22 −0 config/environments/test.rb
  30. +36 −0 config/initializers/authlogic_connect_config.rb
  31. +10 −0 config/initializers/inflections.rb
  32. +5 −0 config/initializers/mime_types.rb
  33. +17 −0 config/initializers/new_rails_defaults.rb
  34. +14 −0 config/routes.rb
  35. +8 −0 console
  36. +30 −0 db/migrate/20100506020514_create_users.rb
  37. +16 −0 db/migrate/20100506020518_create_sessions.rb
  38. +18 −0 db/migrate/20100506020520_create_tokens.rb
  39. +58 −0 db/schema.rb
  40. +2 −0 doc/README_FOR_APP
  41. +30 −0 public/404.html
  42. +30 −0 public/422.html
  43. +30 −0 public/500.html
  44. +10 −0 public/dispatch.cgi
  45. +24 −0 public/dispatch.fcgi
  46. +10 −0 public/dispatch.rb
  47. 0 public/favicon.ico
  48. BIN public/images/bg.jpg
  49. BIN public/images/bird.png
  50. BIN public/images/blue-arrow.png
  51. BIN public/images/blue-arrow2.png
  52. BIN public/images/blue-bg.jpg
  53. BIN public/images/blue-email.png
  54. BIN public/images/blue-pattern.jpg
  55. BIN public/images/blue-send.png
  56. BIN public/images/blue-submit.png
  57. BIN public/images/countbg.png
  58. BIN public/images/icon-del.png
  59. BIN public/images/icon-fb.png
  60. BIN public/images/icon-ff.png
  61. BIN public/images/icon-fl.png
  62. BIN public/images/icon-fm.png
  63. BIN public/images/icon-su.png
  64. BIN public/images/icon-tu.png
  65. BIN public/images/icons/bebo.png
  66. BIN public/images/icons/blinklist.png
  67. BIN public/images/icons/blogger.png
  68. BIN public/images/icons/delicious.png
  69. BIN public/images/icons/digg.png
  70. BIN public/images/icons/facebook.png
  71. BIN public/images/icons/flickr.png
  72. BIN public/images/icons/friendfeed.png
  73. BIN public/images/icons/furl.png
  74. BIN public/images/icons/google.png
  75. BIN public/images/icons/lastfm.png
  76. BIN public/images/icons/linkedin.png
  77. BIN public/images/icons/myspace.png
  78. BIN public/images/icons/netvibes.png
  79. BIN public/images/icons/newsvine.png
  80. BIN public/images/icons/reddit.png
  81. BIN public/images/icons/rss.png
  82. BIN public/images/icons/stumbleupon.png
  83. BIN public/images/icons/technorati.png
  84. BIN public/images/icons/tumbrl.png
  85. BIN public/images/icons/twitter.png
  86. BIN public/images/icons/vimeo.png
  87. BIN public/images/icons/yahoo.png
  88. BIN public/images/icons/youtube.png
  89. BIN public/images/inputbg.png
  90. BIN public/images/loading.gif
  91. BIN public/images/logo.png
  92. BIN public/images/page.png
  93. BIN public/images/shadow2.png
  94. BIN public/images/textarea.png
  95. BIN public/images/twitterbg.png
  96. +31 −0 public/javascripts/application.js
  97. +7 −0 public/javascripts/cufon.yui.js
  98. +15 −0 public/javascripts/jquery.jcarousel.pack.js
  99. +22 −0 public/javascripts/kievit.js
  100. +5 −0 public/robots.txt
  101. 0 public/stylesheets/.gitkeep
  102. +300 −0 public/stylesheets/application.css
  103. +19 −0 public/stylesheets/reset.css
  104. +4 −0 script/about
  105. +3 −0 script/console
  106. +3 −0 script/dbconsole
  107. +3 −0 script/destroy
  108. +3 −0 script/generate
  109. +3 −0 script/performance/benchmarker
  110. +3 −0 script/performance/profiler
  111. +3 −0 script/performance/request
  112. +3 −0 script/plugin
  113. +3 −0 script/process/inspector
  114. +3 −0 script/process/reaper
  115. +3 −0 script/process/spawner
  116. +3 −0 script/runner
  117. +3 −0 script/server
  118. +5 −0 test/fixtures/users.yml
  119. +8 −0 test/functional/password_resets_controller_test.rb
  120. +21 −0 test/functional/user_sessions_controller_test.rb
  121. +34 −0 test/functional/users_controller_test.rb
  122. +41 −0 test/test_helper.rb
  123. +8 −0 test/unit/user_test.rb
  124. +18 −0 vendor/plugins/haml/init.rb
3 .gems
@@ -0,0 +1,3 @@
+authlogic
+oauth
+json
@@ -0,0 +1,6 @@
+.DS_Store
+.bundle
+db/*.sqlite3
+log/*.log
+tmp/**/*
+config/authlogic.yml
@@ -0,0 +1,3 @@
+load 'deploy' if respond_to?(:namespace) # cap2 differentiator
+Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
+load 'config/deploy'
@@ -0,0 +1,109 @@
+= Authlogic OAuth Example App
+
+This is an example of how to use Authlogic to enable OAuth authentication in a rails app.
+
+<b>Please note that there are multiple branches for this example app that show how to do different things in Authlogic.</b>
+
+* This application live: http://authlogic-oauth.heroku.com
+* Authlogic OAuth: http://github.com/jrallison/authlogic_oauth
+* Authlogic: http://github.com/binarylogic/authlogic
+
+== What does this example app contain?
+
+1. User registration with Twitter credentials using OAuth.
+1. User login with Twitter credentials using OAuth.
+
+== Tutorial on how to create this app and easily setup Authlogic OAuth
+
+=== 1. Setup and use Authlogic
+
+* Authlogic Example: http://github.com/binarylogic/authlogic_example
+
+=== 2. Install OAuth and Authlogic_Oauth
+
+ $ sudo gem install oauth
+ $ sudo gem install authlogic-oauth
+
+Now add the gem dependencies in your config:
+
+ config.gem "oauth"
+ config.gem "authlogic-oauth", :lib => "authlogic_oauth"
+
+Or for older version of rails, install it as a plugin:
+
+ $ script/plugin install git://github.com/jrallison/authlogic_oauth.git
+
+=== 3. Make some simple changes to your database:
+
+ class AddUsersOauthFields < ActiveRecord::Migration
+ def self.up
+ add_column :users, :oauth_token, :string
+ add_column :users, :oauth_secret, :string
+ add_index :users, :oauth_token
+
+ change_column :users, :login, :string, :default => nil, :null => true
+ change_column :users, :crypted_password, :string, :default => nil, :null => true
+ change_column :users, :password_salt, :string, :default => nil, :null => true
+ end
+
+ def self.down
+ remove_column :users, :oauth_token
+ remove_column :users, :oauth_secret
+
+ [:login, :crypted_password, :password_salt].each do |field|
+ User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
+ change_column :users, field, :string, :default => "", :null => false
+ end
+ end
+ end
+
+=== 4. Make sure you save your objects properly
+
+You only need to save your objects this way if you want the user to authenticate with their OAuth provider.
+
+That being said, you probably want to do this in your controllers. You should do this for BOTH your User objects and UserSession objects (assuming you are authenticating users). It should look something like this:
+
+ @user_session.save do |result|
+ if result
+ flash[:notice] = "Login successful!"
+ redirect_back_or_default account_url
+ else
+ render :action => :new
+ end
+ end
+
+You should save your @user objects this way as well, because you also want the user to authenticate with OAuth.
+
+Notice we are saving with a block. Why? Because we need to redirect the user to their OAuth provider so that they can authenticate. When we do this, we don't want to execute that block of code, because if we do, we will get a DoubleRender error. This lets us skip that entire block and send the user along their way without any problems.
+
+=== 5. Define the oauth_consumer class method on your UserSession model
+
+The oauth_consumer should return an OAuth::Consumer which is configured for your OAuth provider. Here's an example for Twitter:
+
+ class UserSession < Authlogic::Session::Base
+
+ def self.oauth_consumer
+ OAuth::Consumer.new("TOKEN", "SECRET",
+ { :site=>"http://twitter.com",
+ :authorize_url => "http://twitter.com/oauth/authenticate" })
+ end
+
+ end
+
+=== 6. Add login and register buttons to your views
+
+ <%= oauth_register_button :value => "Register with Twitter" %>
+ <%= oauth_login_button :value => "Login with Twitter" %>
+
+=== 7. Next Steps
+
+Here are some next steps for the plugin.
+
+1. Safe OAuth error handling.
+2. Remove oauth request from the Rails request cycle.
+
+== Improving this tutorial
+
+If you find something confusing or encounter a problem with this tutorial please fork this project, make the changes, and send me a pull request. I would really appreciate this and so would successive Authlogic users.
+
+Copyright (c) 2009 John Allison, released under the MIT license
@@ -0,0 +1,10 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require(File.join(File.dirname(__FILE__), 'config', 'boot'))
+
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+require 'tasks/rails'
@@ -0,0 +1,60 @@
+class ApplicationController < ActionController::Base
+ #protect_from_forgery
+ layout 'application'
+ helper :all
+ helper_method :current_user_session, :current_user
+
+ def login_required
+ if current_user.nil?
+ redirect_to new_user_url
+ true
+ end
+ false
+ end
+
+ private
+ def admin_only
+ if Rails.env == "production"
+ authenticate_or_request_with_http_basic do |id, password|
+ id == ENV["USER"] && password == ENV["PASSWORD"]
+ end
+ end
+ end
+
+ def current_user_session
+ return @current_user_session if defined?(@current_user_session)
+ @current_user_session = UserSession.find
+ end
+
+ def current_user
+ return @current_user if defined?(@current_user)
+ @current_user = current_user_session && current_user_session.record
+ end
+
+ def require_user
+ unless current_user
+ store_location
+ flash[:notice] = "You must be logged in to access this page"
+ redirect_to new_user_session_url
+ return false
+ end
+ end
+
+ def require_no_user
+ if current_user
+ store_location
+ flash[:notice] = "You must be logged out to access this page"
+ redirect_to profile_url(current_user)
+ return false
+ end
+ end
+
+ def store_location
+ session[:return_to] = request.fullpath
+ end
+
+ def redirect_back_or_default(default)
+ redirect_to(session[:return_to] || default)
+ session[:return_to] = nil
+ end
+end
@@ -0,0 +1,28 @@
+class UserSessionsController < ApplicationController
+ before_filter :require_no_user, :only => [:new, :create]
+ before_filter :require_user, :only => :destroy
+
+ def new
+ @user_session = UserSession.new
+ end
+
+ def create
+ @user_session = UserSession.new(params[:user_session])
+ # uses a block to prevent double render error...
+ # because oauth and openid use redirects
+ @user_session.save do |result|
+ if result
+ flash[:notice] = "Login successful!"
+ redirect_to current_user ? profile_url(current_user) : login_url
+ else
+ render :action => :new
+ end
+ end
+ end
+
+ def destroy
+ current_user_session.destroy
+ flash[:notice] = "Logout successful!"
+ redirect_to login_url
+ end
+end
@@ -0,0 +1,49 @@
+class UsersController < ApplicationController
+ before_filter :require_no_user, :only => [:new, :create]
+ before_filter :require_user, :only => [:show, :edit, :update]
+ before_filter :admin_only, :only => :detonate
+
+ def new
+ @user = User.new
+ end
+
+ def create
+ @user = User.new(params[:user])
+ # block! see user_sessions_controller.rb for description
+ @user.save do |result|
+ if result
+ flash[:notice] = "Account registered!"
+ redirect_back_or_default profile_url(@user)
+ else
+ render :action => :new
+ end
+ end
+ end
+
+ def show
+ @user = @current_user
+ @profile = @user.profile
+ end
+
+ def edit
+ @user = @current_user
+ end
+
+ def update
+ @user = @current_user # makes our views "cleaner" and more consistent
+ @user.update_attributes(params[:user]) do |result|
+ if result
+ flash[:notice] = "Account updated!"
+ redirect_to profile_url(@user)
+ else
+ render :action => :edit
+ end
+ end
+ end
+
+ # for debugging...
+ def detonate
+ User.all.collect(&:destroy)
+ redirect_to signup_url
+ end
+end
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
@@ -0,0 +1,61 @@
+module Profile
+ def self.included(base)
+ base.class_eval do
+ include InstanceMethods
+ end
+ end
+
+ module InstanceMethods
+
+ def facebook
+ if token = authenticated_with?(:facebook)
+ @facebook ||= JSON.parse(token.get("/me"))
+ end
+ end
+
+ def twitter
+ if token = authenticated_with?(:twitter)
+ @twitter ||= JSON.parse(token.get("/account/verify_credentials.json").body)
+ end
+ end
+
+ def google
+ @google ||= "" # todo
+ end
+
+ # primitive profile to show what's possible
+ def profile
+ unless @profile
+ @profile = if facebook
+ {
+ :id => facebook["id"],
+ :name => facebook["name"],
+ :photo => "https://graph.facebook.com/#{facebook["id"]}/picture",
+ :link => facebook["link"],
+ :title => "Facebook"
+ }
+ elsif twitter
+ {
+ :id => twitter["id"],
+ :name => twitter["name"],
+ :photo => twitter["profile_image_url"],
+ :link => "http://twitter.com/#{twitter["screen_name"]}",
+ :title => "Twitter"
+ }
+ else
+ {
+ :id => "unknown",
+ :name => "User",
+ :photo => "/images/icons/google.png",
+ :link => "/images/icons/google.png",
+ :title => "Google"
+ }
+ end
+ end
+
+ @profile
+ end
+
+ end
+
+end
@@ -0,0 +1,5 @@
+class User < ActiveRecord::Base
+ acts_as_authentic
+
+ include Profile
+end
@@ -0,0 +1,3 @@
+class UserSession < Authlogic::Session::Base
+
+end
@@ -0,0 +1,20 @@
+!!!
+%html{:dir => "ltr", :lang => "en-US", :xmlns => "http://www.w3.org/1999/xhtml"}
+ %head{:profile => "http://gmpg.org/xfn/11"}
+ %title Authlogic Connect Example
+ = render :partial => "shared/head"
+ %body
+ #wrapper
+ = render :partial => "shared/logo"
+ #page-container
+ %ul#page.container
+ %li
+ .content
+ = yield
+ .shadow
+ - if current_user
+ .actions
+ %a.nice{:href => edit_user_path(@user)} Edit
+ %a.nice{:href => logout_path} Logout
+
+ = render :partial => "shared/github"
@@ -0,0 +1,3 @@
+/ footer
+%a{:href => "http://github.com/viatropos/authlogic-connect-example", :target => "_blank"}
+ %img#fork_me{:src => "http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png", :alt => "Fork me on GitHub"}
Oops, something went wrong.

0 comments on commit 7111583

Please sign in to comment.