Permalink
Browse files

made it work with rails 2.3.5 and rails 3, cleaned up some of the cod…

…e so you include less in the application
  • Loading branch information...
1 parent 32a0c6c commit cd57ce16c8ffb03e919f512a9335485a4326e1fb @lancejpollard committed May 18, 2010
Showing with 397 additions and 75 deletions.
  1. +3 −3 Gemfile
  2. 0 MIT-LICENSE
  3. +63 −26 README.markdown
  4. +6 −4 Rakefile
  5. 0 init.rb
  6. +12 −21 lib/authlogic-connect.rb
  7. +6 −2 lib/authlogic_connect/callback_filter.rb
  8. +1 −0 lib/authlogic_connect/common.rb
  9. +55 −0 lib/authlogic_connect/common/ext.rb
  10. 0 lib/authlogic_connect/common/session.rb
  11. 0 lib/authlogic_connect/common/user.rb
  12. 0 lib/authlogic_connect/common/variables.rb
  13. +15 −0 lib/authlogic_connect/engine.rb
  14. 0 lib/authlogic_connect/oauth.rb
  15. 0 lib/authlogic_connect/oauth/helper.rb
  16. +2 −1 lib/authlogic_connect/oauth/process.rb
  17. 0 lib/authlogic_connect/oauth/session.rb
  18. 0 lib/authlogic_connect/oauth/tokens/facebook_token.rb
  19. 0 lib/authlogic_connect/oauth/tokens/get_satisfaction_token.rb
  20. 0 lib/authlogic_connect/oauth/tokens/google_token.rb
  21. 0 lib/authlogic_connect/oauth/tokens/linked_in_token.rb
  22. 0 lib/authlogic_connect/oauth/tokens/myspace_token.rb
  23. 0 lib/authlogic_connect/oauth/tokens/oauth_token.rb
  24. 0 lib/authlogic_connect/oauth/tokens/opensocial_token.rb
  25. 0 lib/authlogic_connect/oauth/tokens/twitter_token.rb
  26. 0 lib/authlogic_connect/oauth/tokens/vimeo_token.rb
  27. 0 lib/authlogic_connect/oauth/tokens/yahoo_token.rb
  28. +7 −3 lib/authlogic_connect/oauth/user.rb
  29. 0 lib/authlogic_connect/oauth/variables.rb
  30. 0 lib/authlogic_connect/openid.rb
  31. 0 lib/authlogic_connect/openid/session.rb
  32. 0 lib/authlogic_connect/openid/tokens/aol_token.rb
  33. 0 lib/authlogic_connect/openid/tokens/blogger_token.rb
  34. 0 lib/authlogic_connect/openid/tokens/flickr_token.rb
  35. 0 lib/authlogic_connect/openid/tokens/my_openid_token.rb
  36. 0 lib/authlogic_connect/openid/tokens/openid_token.rb
  37. +10 −11 lib/authlogic_connect/openid/user.rb
  38. 0 lib/authlogic_connect/openid/variables.rb
  39. 0 lib/authlogic_connect/token.rb
  40. +129 −0 lib/open_id_authentication.rb
  41. +3 −3 pkg/authlogic-connect.gemspec
  42. +19 −1 rails/init.rb
  43. +13 −0 test/test_authlogic_connect.rb
  44. +53 −0 test/test_helper.rb
View
@@ -1,9 +1,9 @@
source 'http://rubygems.org'
gem 'rails', '3.0.0.beta3'
-gem "json"
+
gem "ruby-openid"
+gem 'rack-openid', '>=0.2.1', :require => 'rack/openid'
gem "authlogic", :git => "git://github.com/odorcicd/authlogic.git", :branch => "rails3"
gem "oauth"
-gem "oauth2" # facebook only
-gem "authlogic-connect"
+gem "oauth2"
View
0 MIT-LICENSE 100644 → 100755
No changes.
View
89 README.markdown 100644 → 100755
@@ -15,6 +15,8 @@ All of that is easier than creating a new account and password.
* <b>Authlogic:</b> [http://github.com/binarylogic/authlogic](http://github.com/binarylogic/authlogic)
* <b>Authlogic Connect Example Project:</b> [http://github.com/viatropos/authlogic-connect-example](http://github.com/viatropos/authlogic-connect-example)
* <b>Live example with Twitter and Facebook using Rails 3:</b> [http://authlogic-connect.heroku.com](http://authlogic-connect.heroku.com)
+* <b>Rails 2.3.5 Example:</b> [http://github.com/viatropos/authlogic-connect-example-rails2](http://github.com/viatropos/authlogic-connect-example-rails2)]
+* **Rubygems Repository:** [http://rubygems.org/search?query=authlogic-connect](http://rubygems.org/search?query=authlogic-connect)
## Supported Providers
@@ -35,40 +37,40 @@ Lists of all known providers here:
## Install and use
-### 1. Install Authlogic and setup your application
+### 1. Install Authlogic Connect (it will install the dependencies)
- sudo gem install authlogic
-
-### 2. Install OAuth and Authlogic Connect
-
- sudo gem install oauth
sudo gem install authlogic-connect
Now add the gem dependencies in your config:
+Rails 2.3.x: `config/environment.rb`
+
config.gem "json"
config.gem "authlogic"
config.gem "oauth"
config.gem "oauth2"
- config.gem "authlogic-connect", :lib => "authlogic_connect"
+ config.gem "authlogic-connect"
-### 3. Add the Migrations
+Rails 3: `Gemfile`
-If you are starting from scratch (and you don't even have a User model yet), create the migrations using this command.
+ gem "ruby-openid"
+ gem "rack-openid", ">=0.2.1", :require => "rack/openid"
+ gem "authlogic", :git => "git://github.com/odorcicd/authlogic.git", :branch => "rails3"
+ gem "oauth"
+ gem "oauth2"
+ gem "authlogic-connect"
- script/generate authlogic_connect_migration
+### 3. Add the Migrations
-Otherwise, add this migration
+See the [Rails 2 Example](http://github.com/viatropos/authlogic-connect-example-rails2) and [Rails 3 Example](http://github.com/viatropos/authlogic-connect-example) projects to see what you need. Will add a generator sometime.
- class AddAuthlogicConnectMigration < ActiveRecord::Migration
- def self.up
- # TODO
- end
+Files needed are:
- def self.down
- # TODO
- end
- end
+- models: User, UserSession
+- controllers: UsersController, UserSessionsController, ApplicationController
+- migrations: create\_users, create\_sessions, create\_tokens
+- initializers: config/authlogic.example.yml, config/initializers/authlogic_connect_config.rb
+- routes
### 4. Configure your keys
@@ -124,15 +126,23 @@ If we don't use the block, we will get a DoubleRender error. This lets us skip t
Here's an example of the FacebookToken for Oauth
class FacebookToken < OauthToken
-
+
+ version 2.0 # oauth 2.0
+
+ settings "https://graph.facebook.com",
+ :authorize_url => "https://graph.facebook.com/oauth/authorize",
+ :scope => "email, offline_access"
+
end
+
+If there is an Oauth/OpenID service you need, let me know, or fork/add/push and I will integrate it into the project and add you to the list.
-### 6. Add login and register buttons to your views
+### 7. Add login and register buttons to your views
<%# oauth_register_button :value => "Register with Twitter" %>
<%# oauth_login_button :value => "Login with Twitter" %>
-That's it! The rest is taken care of for you.
+Check out the example projects to see exactly what's required. These aren't totally useful yet. Their job is to just send the right parameters to authlogic-connect.
## The Flow
@@ -160,19 +170,46 @@ That's it! The rest is taken care of for you.
- Save user
- Finish block, render page
-## Tests
+### Note about the redirect process
+
+When you make a request to one of these services, it responds with a GET request. But assuming we have made the request through a `create` method (`UsersController#create` for `/register`, `UserSessionsController#create` for `/login`), we want that GET to be a POST.
+
+This is accomplished by adding a property called `auth_callback_method` to the session when the original request is made. It says "POST", or whatever the translation is from the controller method that was called.
-This has no tests! I had to build this in a weekend and am not fluent with Shoulda, which I'd like to use. One of these days when I can breathe.
+Then a Rack Middleware filter converts the GET return request from the authentication service into POST. This forces it to run back through the `create` method. Check out [`AuthlogicConnect::CallbackFilter`](http://github.com/viatropos/authlogic-connect/blob/master/lib/authlogic_connect/callback_filter.rb) for details. Or search "Rack Middleware".
-## Goals
+## Project Goals
1. It should require the end user ONE CLICK to create an account with your site.
2. It should not depend on Javascript
3. It should be enhanced by Javascript
4. You should never have to touch the User/Session model/controller/migration if you are a just looking to get up and running quickly.
5. You should be able to plugin ruby libraries that wrap an api, such as TwitterAuth via `@user.twitter`, and LinkedIn via `@user.linked_in`. Just because it's that easy.
+### Tests
+
+This has no tests! I had to build this in a day and am not fluent with Shoulda, which I'd like to use. It should have lots of tests to make sure all permutations of login and account association work perfectly.
+
+Goal:
+
+- Test Framework: [Shoulda](http://github.com/thoughtbot/shoulda)
+- Autotest with Shoulda
+- Testing style like [Paperclip Tests](http://github.com/thoughtbot/paperclip/tree/master/test/)
+- Rails 2.3+ and Rails 3 Compatability
+
+I have no idea how to get up and running with Autotest and Shoulda right now. If you know, I'd love to get the answer on Stack Overflow:
+
+[http://stackoverflow.com/questions/2823224/what-test-environment-setup-do-committers-use-in-the-ruby-community](http://stackoverflow.com/questions/2823224/what-test-environment-setup-do-committers-use-in-the-ruby-community)
+
## TODO
- Change `register_with_oauth` and related to `register_method` and `login_method`: oauth, openid, traditional
-- Build view helpers
+- Build view helpers
+
+## Helpful References for Rails 3
+
+- [Rails 3 Initialization Process](http://ryanbigg.com/guides/initialization.html)
+- [Rails 3 Plugins - Part 1, Big Picture](http://www.themodestrubyist.com/2010/03/01/rails-3-plugins---part-1---the-big-picture/)
+- [Rails 3 Plugins - Part 2, Writing an Engine](http://www.themodestrubyist.com/2010/03/05/rails-3-plugins---part-2---writing-an-engine/)
+- [Rails 3 Plugins - Part 3, Initializers](http://www.themodestrubyist.com/2010/03/16/rails-3-plugins---part-3---rake-tasks-generators-initializers-oh-my/)
+- [Using Gemspecs as Intended](http://yehudakatz.com/2010/04/02/using-gemspecs-as-intended/)
View
10 Rakefile 100644 → 100755
@@ -6,7 +6,7 @@ require 'rake/gempackagetask'
spec = Gem::Specification.new do |s|
s.name = "authlogic-connect"
s.author = "Lance Pollard"
- s.version = "0.0.3.2"
+ s.version = "0.0.3.4"
s.summary = "Authlogic Connect: Let your app use all of Oauth and OpenID"
s.homepage = "http://github.com/viatropos/authlogic-connect"
s.email = "lancejpollard@gmail.com"
@@ -18,10 +18,12 @@ spec = Gem::Specification.new do |s|
s.require_path = "lib"
s.add_dependency("activesupport", ">= 2.1.2")
s.add_dependency("activerecord", ">= 2.1.2")
- s.add_dependency("authlogic")
- s.add_dependency("oauth")
s.add_dependency("json")
- s.add_dependency("oauth2") # facebook only
+ s.add_dependency("ruby-openid")
+ s.add_dependency("rack-openid", ">=0.2.1")
+ s.add_dependency("oauth")
+ s.add_dependency("oauth2")
+ s.add_dependency("authlogic")
end
desc "Create .gemspec file (useful for github)"
View
0 init.rb 100644 → 100755
No changes.
View
33 lib/authlogic-connect.rb 100644 → 100755
@@ -1,20 +1,9 @@
require 'active_record'
+require "rubygems"
require 'authlogic'
require 'oauth'
require 'oauth2'
-
-# Throw callback rack app into the middleware stack
-# TODO: Somehow do this for Rails 3?
-# For now it is in the sample Rails 3 app
-=begin
-ActionController::Dispatcher.middleware = ActionController::MiddlewareStack.new do |m|
- ActionController::Dispatcher.middleware.each do |klass|
- m.use klass
- end
- m.use AuthlogicConnect::CallbackFilter
-end
-=end
this = File.dirname(__FILE__)
library = "#{this}/authlogic_connect"
@@ -45,33 +34,33 @@ def recursively_symbolize_keys!
end
module AuthlogicConnect
- VERSION = "0.0.1"
+ KEY = "connect"
class << self
attr_accessor :config
-
+
def config=(value)
value.recursively_symbolize_keys!
@config = value
end
-
+
def key(path)
result = self.config
path.to_s.split(".").each { |node| result = result[node.to_sym] if result }
result
end
def credentials(service)
- key("services.#{service.to_s}")
+ key("#{KEY}.#{service.to_s}")
end
def services
- key("services")
+ key(KEY)
end
def service_names
- key("services").keys.collect(&:to_s)
+ services.keys.collect(&:to_s)
end
def include?(service)
@@ -89,15 +78,17 @@ def consumer(key)
end
end
+require "#{this}/open_id_authentication"
require "#{library}/callback_filter"
require "#{library}/token"
require "#{library}/openid"
require "#{library}/oauth"
require "#{library}/common"
+require "#{library}/engine" if defined?(Rails) && Rails::VERSION::MAJOR == 3
-custom_models = ["#{library}/token"]
-custom_models += Dir["#{library}/oauth/tokens"]
-custom_models +=Dir["#{library}/openid/tokens"]
+custom_models = ["#{library}/token"]
+custom_models += Dir["#{library}/oauth/tokens"]
+custom_models += Dir["#{library}/openid/tokens"]
custom_models.each do |path|
$LOAD_PATH << path
View
@@ -3,12 +3,16 @@ def initialize(app)
@app = app
end
+ # this intercepts how the browser interprets the url.
+ # so we override it and say,
+ # "if we've stored a variable in the session called :auth_callback_method,
+ # then convert that into a POST call so we re-call the original method"
def call(env)
if env["rack.session"].nil?
raise "Make sure you are setting the session in Rack too! Place this in config/application.rb"
end
- unless env["rack.session"][:oauth_callback_method].blank?
- env["REQUEST_METHOD"] = env["rack.session"].delete(:oauth_callback_method).to_s.upcase
+ unless env["rack.session"][:auth_callback_method].blank?
+ env["REQUEST_METHOD"] = env["rack.session"].delete(:auth_callback_method).to_s.upcase
end
@app.call(env)
end
View
1 lib/authlogic_connect/common.rb 100644 → 100755
@@ -1,6 +1,7 @@
module AuthlogicConnect::Common
end
+require File.dirname(__FILE__) + "/common/ext"
require File.dirname(__FILE__) + "/common/variables"
require File.dirname(__FILE__) + "/common/user"
require File.dirname(__FILE__) + "/common/session"
@@ -0,0 +1,55 @@
+class String
+ # normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization
+ def normalize_identifier
+ # clean up whitespace
+ identifier = self.dup.strip
+
+ # if an XRI has a prefix, strip it.
+ identifier.gsub!(/xri:\/\//i, '')
+
+ # dodge XRIs -- TODO: validate, don't just skip.
+ unless ['=', '@', '+', '$', '!', '('].include?(identifier.at(0))
+ # does it begin with http? if not, add it.
+ identifier = "http://#{identifier}" unless identifier =~ /^http/i
+
+ # strip any fragments
+ identifier.gsub!(/\#(.*)$/, '')
+
+ begin
+ uri = URI.parse(identifier)
+ uri.scheme = uri.scheme.downcase # URI should do this
+ identifier = uri.normalize.to_s
+ rescue URI::InvalidURIError
+ raise InvalidOpenId.new("#{identifier} is not an OpenID identifier")
+ end
+ end
+
+ return identifier
+ end
+end
+
+class Hash
+ def recursively_symbolize_keys!
+ self.symbolize_keys!
+ self.values.each do |v|
+ if v.is_a? Hash
+ v.recursively_symbolize_keys!
+ elsif v.is_a? Array
+ v.recursively_symbolize_keys!
+ end
+ end
+ self
+ end
+end
+
+class Array
+ def recursively_symbolize_keys!
+ self.each do |item|
+ if item.is_a? Hash
+ item.recursively_symbolize_keys!
+ elsif item.is_a? Array
+ item.recursively_symbolize_keys!
+ end
+ end
+ end
+end
View
No changes.
View
No changes.
View
No changes.
@@ -0,0 +1,15 @@
+module AuthlogicConnect
+ class Engine < Rails::Engine
+ engine_name :authlogic_connect
+
+ initializer "authlogic_connect.authentication_hook" do |app|
+ app.middleware.use AuthlogicConnect::CallbackFilter
+ app.middleware.use OpenIdAuthentication
+ end
+
+ initializer "authlogic_connect.finalize", :after => "authlogic_connect.authentication_hook" do |app|
+ OpenID::Util.logger = Rails.logger
+ ActionController::Base.send :include, OpenIdAuthentication
+ end
+ end
+end
View
0 lib/authlogic_connect/oauth.rb 100644 → 100755
No changes.
View
No changes.
View
@@ -34,13 +34,14 @@ def redirect_to_oauth
end
def save_oauth_callback
+ puts "save_oauth_callback"
# Store the class which is redirecting, so we can ensure other classes
# don't get confused and attempt to use the response
auth_session[:oauth_request_class] = self.class.name
auth_session[:oauth_provider] = auth_params[:oauth_provider]
# Tell our rack callback filter what method the current request is using
- auth_session[:oauth_callback_method] = auth_controller.request.method
+ auth_session[:auth_callback_method] = auth_controller.request.method
end
def save_auth_session(request)
View
No changes.
No changes.
No changes.
View
No changes.
No changes.
View
No changes.
View
No changes.
No changes.
View
No changes.
View
No changes.
View
No changes.
Oops, something went wrong.

0 comments on commit cd57ce1

Please sign in to comment.