Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Update application.rb for newer rails and implement openid login

  • Loading branch information...
commit 226d57c68442a7e2991f61377ddf753916647ee4 1 parent 178c6f3
@courtenay courtenay authored
Showing with 1,126 additions and 24 deletions.
  1. 0  app/controllers/{application.rb → application_controller.rb}
  2. +20 −0 app/controllers/monitorships_controller.rb
  3. +65 −1 app/controllers/sessions_controller.rb
  4. +4 −2 app/controllers/users_controller.rb
  5. +9 −0 app/models/monitorships_sweeper.rb
  6. +12 −0 app/models/posts_sweeper.rb
  7. +16 −1 app/models/user.rb
  8. +2 −2 app/models/user/states.rb
  9. +8 −1 app/models/user/validation.rb
  10. +1 −1  app/views/forums/index.html.erb
  11. +2 −3 app/views/layouts/_head.html.erb
  12. +4 −0 app/views/monitorships/create.rjs
  13. +4 −0 app/views/monitorships/destroy.rjs
  14. +30 −4 app/views/sessions/new.html.erb
  15. +1 −1  app/views/topics/show.html.erb
  16. +4 −0 app/views/users/new.rhtml
  17. +3 −1 config/environment.rb
  18. +1 −0  config/initializers/application.rb
  19. +12 −3 config/routes.rb
  20. +28 −0 db/migrate/20090317123901_add_open_id_authentication_tables.rb
  21. +2 −1  lib/html_formatting.rb
  22. +25 −3 public/javascripts/application.js
  23. +2 −0  spec/controllers/monitorships_controller_spec.rb
  24. +6 −0 spec/models/user_spec.rb
  25. +35 −0 vendor/plugins/open_id_authentication/CHANGELOG
  26. +231 −0 vendor/plugins/open_id_authentication/README
  27. +22 −0 vendor/plugins/open_id_authentication/Rakefile
  28. +11 −0 .../open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb
  29. +20 −0 vendor/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb
  30. +26 −0 vendor/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb
  31. +11 −0 ...ication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb
  32. +18 −0 vendor/plugins/open_id_authentication/init.rb
  33. +240 −0 vendor/plugins/open_id_authentication/lib/open_id_authentication.rb
  34. +9 −0 vendor/plugins/open_id_authentication/lib/open_id_authentication/association.rb
  35. +55 −0 vendor/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb
  36. +5 −0 vendor/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb
  37. +23 −0 vendor/plugins/open_id_authentication/lib/open_id_authentication/request.rb
  38. +20 −0 vendor/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb
  39. +30 −0 vendor/plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake
  40. +32 −0 vendor/plugins/open_id_authentication/test/normalize_test.rb
  41. +46 −0 vendor/plugins/open_id_authentication/test/open_id_authentication_test.rb
  42. +14 −0 vendor/plugins/open_id_authentication/test/status_test.rb
  43. +17 −0 vendor/plugins/open_id_authentication/test/test_helper.rb
View
0  app/controllers/application.rb → app/controllers/application_controller.rb
File renamed without changes
View
20 app/controllers/monitorships_controller.rb
@@ -0,0 +1,20 @@
+class MonitorshipsController < ApplicationController
+ before_filter :login_required
+
+ def create
+ @monitorship = Monitorship.find_or_initialize_by_user_id_and_topic_id(current_user.id, params[:topic_id])
+ @monitorship.update_attribute :active, true
+ respond_to do |format|
+ format.html { redirect_to topic_path(params[:forum_id], params[:topic_id]) }
+ format.js
+ end
+ end
+
+ def destroy
+ Monitorship.update_all ['active = ?', false], ['user_id = ? and topic_id = ?', current_user.id, params[:topic_id]]
+ respond_to do |format|
+ format.html { redirect_to topic_path(params[:forum_id], params[:topic_id]) }
+ format.js
+ end
+ end
+end
View
66 app/controllers/sessions_controller.rb
@@ -18,8 +18,24 @@ def create
redirect_back_or_default('/')
flash[:notice] = "Logged in successfully"
else
+ if using_open_id?
+ cookies[:use_open_id] = {:value => '1', :expires => 1.year.from_now.utc}
+ open_id_authentication(params[:openid_url])
+ else
+ cookies[:use_open_id] = {:value => '0', :expires => 1.year.ago.utc}
+ password_authentication params[:login], params[:password]
+ end
+ end
+ end
+
+ def create
+ if using_open_id?
+ cookies[:use_open_id] = {:value => '1', :expires => 1.year.from_now.utc}
+ open_id_authentication(params[:openid_url])
+ else
+ cookies[:use_open_id] = {:value => '0', :expires => 1.year.ago.utc}
+ password_authentication params[:login], params[:password]
flash[:error] = "Invalid login"
- render :action => 'new'
end
end
@@ -30,4 +46,52 @@ def destroy
flash[:notice] = "You have been logged out."
redirect_back_or_default('/')
end
+
+ protected
+
+ def password_authentication(name, password)
+ if @current_user = current_site.users.authenticate(params[:name], params[:password])
+ successful_login
+ else
+ failed_login "Sorry, that username/password doesn't work"
+ end
+ end
+
+ def open_id_authentication(openid_url)
+ authenticate_with_open_id(openid_url, :required => [:nickname, :email]) do |result, openid_url, registration|
+ if result.successful?
+ @user = User.find_or_initialize_by_openid_url(openid_url)
+ @current_user = @user
+ if @current_user
+ if @user.new_record?
+ @user.login = openid_url
+ @user.email = registration['email']
+ @user.password = 123456
+ @user.site = Site.find(:first)
+ @user.display_name = registration['nickname']
+ @user.save(false)
+ end
+ successful_login
+ else
+ failed_login "Sorry, no user by the identity URL {openid_url} exists"[:openid_no_user_message, openid_url.inspect]
+ end
+ else
+ failed_login result.message
+ end
+ end
+ end
+
+
+ private
+ def successful_login
+ flash[:notice] = 'You are now logged in! Welcome.'
+ session[:user_id] = @current_user.id
+ redirect_back_or_default('/')
+ end
+
+ def failed_login(message)
+ flash[:error] = message
+ redirect_to(new_session_url)
+ end
+
end
View
6 app/controllers/users_controller.rb
@@ -95,9 +95,11 @@ def make_admin
protected
def find_user
@user = if admin?
- current_site.all_users.find_by_permalink(params[:id])
+ current_site.all_users.find params[:id]
+ elsif params[:id] == current_user.id?
+ current_user
else
- current_site.users.find_by_permalink(params[:id])
+ current_site.users.find params[:id]
end or raise ActiveRecord::RecordNotFound
end
View
9 app/models/monitorships_sweeper.rb
@@ -0,0 +1,9 @@
+class MonitorshipsSweeper < ActionController::Caching::Sweeper
+ observe Monitorship
+
+ def after_save(monitorship)
+ FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'users', monitorship.user_id.to_s)
+ end
+
+ alias_method :after_destroy, :after_save
+end
View
12 app/models/posts_sweeper.rb
@@ -0,0 +1,12 @@
+class PostsSweeper < ActionController::Caching::Sweeper
+ observe Post
+
+ def after_save(post)
+ FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'forums', post.forum_id.to_s, 'posts.rss')
+ FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'forums', post.forum_id.to_s, 'topics', "#{post.topic_id}.rss")
+ FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'users')
+ FileUtils.rm_rf File.join(RAILS_ROOT, 'public', 'posts.rss')
+ end
+
+ alias_method :after_destroy, :after_save
+end
View
17 app/models/user.rb
@@ -65,6 +65,21 @@ def seen!
end
def to_param
- permalink
+ id.to_s # permalink || login
end
+
+ def openid_url=(value)
+ write_attribute :openid_url, value.blank? ? nil : OpenIdAuthentication.normalize_identifier(value)
+ end
+
+ def using_openid
+ self.openid_url.blank? ? false : true
+ end
+
+ def to_xml(options = {})
+ options[:except] ||= []
+ options[:except] << :email << :login_key << :login_key_expires_at << :password_hash << :openid_url << :activated << :admin
+ super
+ end
+
end
View
4 app/models/user/states.rb
@@ -38,7 +38,7 @@ def do_activation
self.deleted_at = nil
self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
- UserMailer.deliver_signup_notification(self)
+ UserMailer.deliver_signup_notification(self) unless using_openid
end
protected
@@ -52,7 +52,7 @@ def do_activate
self.deleted_at = nil
self.activation_code = ""
- UserMailer.deliver_activation(self)
+ UserMailer.deliver_activation(self) unless using_openid
end
def remove_moderatorships
View
9 app/models/user/validation.rb
@@ -14,6 +14,8 @@ class User
before_save :downcase_email_and_login
before_save :encrypt_password
before_create :set_first_user_as_admin
+ # validates_email_format_of :email, :message=>"is invalid"
+ validates_uniqueness_of :openid_url, :case_sensitive => false, :allow_nil => true
# prevents a user from submitting a crafted form that bypasses activation
# anything else you want your user to change should be added here.
@@ -42,7 +44,12 @@ def encrypt_password
self.crypted_password = encrypt(password)
end
- def password_required?
+ def using_openid
+ self.openid_url.blank? ? false : true
+ end
+
+ def password_required?
+ return false if using_openid
crypted_password.blank? || !password.blank?
end
View
2  app/views/forums/index.html.erb
@@ -25,7 +25,7 @@
<th class="la" width="30%" colspan="1"><%= 'Last Post'[:last_post] %></th>
</tr>
<% for forum in @forums do %>
- <tr>
+ <tr class="forum" id="forum_<%= forum.id %>_row">
<td class="vat c1">
<% if recent_forum_activity(forum) %>
View
5 app/views/layouts/_head.html.erb
@@ -1,11 +1,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title><%= "#{h @page_title} - " if @page_title %> <%=h @current_site && current_site.name %></title>
<%= stylesheet_link_tag 'display' %>
- <%= javascript_include_tag "prototype", "effects", "lowpro", "time", "application", :cache => 'beast' %>
+ <%= javascript_include_tag "prototype", "effects", "lowpro", "time", "application", :cache => "beast" %>
<% unless @feed_icons.blank? -%>
<% @feed_icons.each do |feed| -%>
<%= auto_discovery_link_tag :atom, feed[:url], :title => "Subscribe to '#{feed[:title]}'" %>
@@ -27,7 +26,7 @@
<li><%= link_to_function 'Search'[:search_title], "#", :href => root_path, :id => 'search-link' %></li>
<% if @current_site and logged_in? -%>
- <li class="login"><%= link_to current_user.login, user_path(current_user) %></li>
+ <li class="login"><%= link_to current_user.display_name, user_path(current_user) %></li>
<li class="logout"><%= link_to 'Settings'[:settings_title], settings_path %></li>
<li class="logout"><%= link_to 'Logout'[:logout_title], logout_path(:to => CGI.escape(request.request_uri)) %></li>
<% else -%>
View
4 app/views/monitorships/create.rjs
@@ -0,0 +1,4 @@
+#page["monitorship-icon-topics-#{params[:topic_id]}"].remove_class_name(:grey)
+#page["monitorship-icon-topics-#{params[:topic_id]}"].add_class_name(:green)
+
+page[:monitor_label].innerHTML = "Monitoring topic"[]
View
4 app/views/monitorships/destroy.rjs
@@ -0,0 +1,4 @@
+#page["monitorship-icon-topics-#{params[:topic_id]}"].remove_class_name(:green)
+#page["monitorship-icon-topics-#{params[:topic_id]}"].add_class_name(:darkgrey)
+
+page[:monitor_label].innerHTML = "Monitor topic"[]
View
34 app/views/sessions/new.html.erb
@@ -1,16 +1,42 @@
<h1>Log In</h1>
-<% form_tag session_path do -%>
+<% form_tag(session_path) do -%>
+<div id="openid_fields" style="display:none">
+<p>
+ <label for="openid_url">Login with OpenID</label>
+ <br />
+ <%= text_field_tag 'openid_url', params[:openid_url], :class => "openid_url" %>
+</p>
+<p>or login with <a href="#" onclick="LoginForm.setToPassword()">username/password</a></p>
+</div>
+
+<div id="password_fields">
<p><%= label_tag 'login' %><br />
<%= text_field_tag 'login', @login %></p>
<p><%= label_tag 'password' %><br/>
<%= password_field_tag 'password', nil %></p>
-<!-- Uncomment this if you want this functionality
<p><%= label_tag 'remember_me', 'Remember me' %>
<%= check_box_tag 'remember_me', '1', @remember_me %></p>
--->
-<p><%= submit_tag 'Log in' %></p>
+<p>or login with <a href="#" onclick="LoginForm.setToOpenID()">OpenID</a></p>
+</div>
+
+<p><%= submit_tag 'Log in' %> or <%= link_to_function('reset password'[], "$('reset-password').toggle();") %></p>
+
<% end -%>
+
+<% form_tag users_path, :id => 'reset-password', :style => 'display:none' do -%>
+
+ <hr />
+ <h5><%= 'Reset Password'[] %></h5>
+
+ <p><%= 'Enter your email, and a brand new login key will be sent to you. Click the link in the email to log in, and then change your password.'[:email_directions] %></p>
+ <p><%= text_field_tag :email, "", :size => 30 %></p>
+ <p><%= submit_tag 'E-mail me the link'[:email_submit] %>
+ or <%= link_to_function('cancel'[], "$('reset-password').hide()") %></p>
+
+<% end -%>
+
+<%= javascript_tag "$('openid_input').focus();"%>
View
2  app/views/topics/show.html.erb
@@ -13,7 +13,7 @@
<% end # right content -%>
-<% if false#logged_in? %>
+<% if logged_in? %>
<% form_tag monitorship_path(@forum, @topic), :style => 'margin-top:0em; float:right;' do -%>
<div>
View
4 app/views/users/new.rhtml
@@ -12,5 +12,9 @@
<p><label for="password_confirmation">Confirm Password</label><br/>
<%= f.password_field :password_confirmation %></p>
+<p><label for="user_openid_url">OpenID URL</label><br />
+<%= f.text_field :openid_url %>
+</p>
+
<p><%= submit_tag 'Sign up' %></p>
<% end -%>
View
4 config/environment.rb
@@ -5,7 +5,7 @@
# ENV['RAILS_ENV'] ||= 'production'
# Specifies gem version of Rails to use when vendor/rails is not present
-RAILS_GEM_VERSION = '2.2.2' unless defined? RAILS_GEM_VERSION
+RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
@@ -18,6 +18,8 @@
config.gem 'mislav-will_paginate', :lib => "will_paginate",
:source => "http://gems.github.com"
+
+ config.gem "bluecloth"
# Skip frameworks you're not going to use (only works if using vendor/rails).
# To use Rails without a database, you must remove the Active Record framework
View
1  config/initializers/application.rb
@@ -0,0 +1 @@
+OpenIdAuthentication.store = :file
View
15 config/routes.rb
@@ -1,7 +1,10 @@
ActionController::Routing::Routes.draw do |map|
- map.resource :session
+ map.open_id_complete '/session',
+ :controller => "sessions", :action => "create",
+ :requirements => { :method => :get }
- map.resources :sites, :moderatorships
+ map.resources :sites, :moderatorships, :monitorship
+
map.resources :forums, :has_many => :posts do |forum|
forum.resources :topics do |topic|
@@ -11,8 +14,8 @@
forum.resources :posts
end
+ map.user '/users/:id', :controller => "users", :action => "show"
map.resources :posts, :collection => {:search => :get}
-
map.resources :users, :member => { :suspend => :put,
:settings => :get,
:make_admin => :put,
@@ -26,5 +29,11 @@
map.logout '/logout', :controller => 'sessions', :action => 'destroy'
map.settings '/settings', :controller => 'users', :action => 'settings'
map.resource :session
+
+ map.with_options :controller => 'posts', :action => 'monitored' do |map|
+ map.formatted_monitored_posts 'users/:user_id/monitored.:format'
+ map.monitored_posts 'users/:user_id/monitored'
+ end
+
map.root :controller => 'forums', :action => 'index'
end
View
28 db/migrate/20090317123901_add_open_id_authentication_tables.rb
@@ -0,0 +1,28 @@
+class AddOpenIdAuthenticationTables < ActiveRecord::Migration
+ def self.up
+ create_table "open_id_authentication_associations", :force => true do |t|
+ t.column "server_url", :binary
+ t.column "handle", :string
+ t.column "secret", :binary
+ t.column "issued", :integer
+ t.column "lifetime", :integer
+ t.column "assoc_type", :string
+ end
+
+ create_table "open_id_authentication_nonces", :force => true do |t|
+ t.column "nonce", :string
+ t.column "created", :integer
+ end
+
+ create_table "open_id_authentication_settings", :force => true do |t|
+ t.column "setting", :string
+ t.column "value", :binary
+ end
+ end
+
+ def self.down
+ drop_table "open_id_authentication_associations"
+ drop_table "open_id_authentication_nonces"
+ drop_table "open_id_authentication_settings"
+ end
+end
View
3  lib/html_formatting.rb
@@ -1,3 +1,4 @@
+require 'redcloth'
module HtmlFormatting
protected
@@ -5,7 +6,7 @@ def format_attributes
self.class.formatted_attributes.each do |attr|
raw = read_attribute attr
linked = auto_link(raw) { |text| truncate(text, :length => 50) }
- textilized = RedCloth.new(linked, [:hard_breaks])
+ textilized = ::RedCloth.new(linked, [:hard_breaks])
textilized.hard_breaks = true if textilized.respond_to?("hard_breaks=")
write_attribute "#{attr}_html", white_list_sanitizer.sanitize(textilized.to_html)
end
View
28 public/javascripts/application.js
@@ -80,6 +80,19 @@ var PostForm = {
}
}
+var RowManager = {
+ addMouseBehavior : function(ele){
+ ele.onmouseover = function(e){
+ ele.addClassName('topic_over');
+ }
+
+ ele.onmouseout = function(e){
+ ele.removeClassName('topic_over');
+ }
+ }
+};
+
+
Event.addBehavior({
'span.time': toTimeAgoInWords,
'#search, #reply': function() { this.hide() },
@@ -88,11 +101,20 @@ Event.addBehavior({
$('search_box').focus();
return false
},
-
+
+ 'tr.forum' : function() {
+ RowManager.addMouseBehavior(this);
+ },
+
+ 'tr.topic' : function(){
+ RowManager.addMouseBehavior(this);
+ },
+
'tr.post': function() {
var postId = this.id.match(/^post_(\d+)-/)[1]
- var anchor = this.down(".edit a")
- if(anchor) { PostForm.edit.attach(anchor, postId) };
+ var anchor = this.down(".edit a")
+ if(anchor) { PostForm.edit.attach(anchor, postId) };
+ RowManager.addMouseBehavior(this);
},
'#reply-link': function() {
View
2  spec/controllers/monitorships_controller_spec.rb
@@ -0,0 +1,2 @@
+
+TODO
View
6 spec/models/user_spec.rb
@@ -13,6 +13,12 @@
end
end
+ it 'logs in with openid' do
+ u = User.new(:openid_url => 'http://foo', :email => 'zoe@girl.com')
+ u.login = 'zoegirl'
+ assert_valid u
+ end
+
it 'increments User.count' do
@creating_user.should change(User, :count).by(1)
end
View
35 vendor/plugins/open_id_authentication/CHANGELOG
@@ -0,0 +1,35 @@
+* Fake HTTP method from OpenID server since they only support a GET. Eliminates the need to set an extra route to match the server's reply. [Josh Peek]
+
+* OpenID 2.0 recommends that forms should use the field name "openid_identifier" rather than "openid_url" [Josh Peek]
+
+* Return open_id_response.display_identifier to the application instead of .endpoints.claimed_id. [nbibler]
+
+* Add Timeout protection [Rick]
+
+* An invalid identity url passed through authenticate_with_open_id will no longer raise an InvalidOpenId exception. Instead it will return Result[:missing] to the completion block.
+
+* Allow a return_to option to be used instead of the requested url [Josh Peek]
+
+* Updated plugin to use Ruby OpenID 2.x.x [Josh Peek]
+
+* Tied plugin to ruby-openid 1.1.4 gem until we can make it compatible with 2.x [DHH]
+
+* Use URI instead of regexps to normalize the URL and gain free, better matching #8136 [dkubb]
+
+* Allow -'s in #normalize_url [Rick]
+
+* remove instance of mattr_accessor, it was breaking tests since they don't load ActiveSupport. Fix Timeout test [Rick]
+
+* Throw a InvalidOpenId exception instead of just a RuntimeError when the URL can't be normalized [DHH]
+
+* Just use the path for the return URL, so extra query parameters don't interfere [DHH]
+
+* Added a new default database-backed store after experiencing trouble with the filestore on NFS. The file store is still available as an option [DHH]
+
+* Added normalize_url and applied it to all operations going through the plugin [DHH]
+
+* Removed open_id? as the idea of using the same input box for both OpenID and username has died -- use using_open_id? instead (which checks for the presence of params[:openid_url] by default) [DHH]
+
+* Added OpenIdAuthentication::Result to make it easier to deal with default situations where you don't care to do something particular for each error state [DHH]
+
+* Stop relying on root_url being defined, we can just grab the current url instead [DHH]
View
231 vendor/plugins/open_id_authentication/README
@@ -0,0 +1,231 @@
+OpenIdAuthentication
+====================
+
+Provides a thin wrapper around the excellent ruby-openid gem from JanRan. Be sure to install that first:
+
+ gem install ruby-openid
+
+To understand what OpenID is about and how it works, it helps to read the documentation for lib/openid/consumer.rb
+from that gem.
+
+The specification used is http://openid.net/specs/openid-authentication-2_0.html.
+
+
+Prerequisites
+=============
+
+OpenID authentication uses the session, so be sure that you haven't turned that off. It also relies on a number of
+database tables to store the authentication keys. So you'll have to run the migration to create these before you get started:
+
+ rake open_id_authentication:db:create
+
+Or, use the included generators to install or upgrade:
+
+ ./script/generate open_id_authentication_tables MigrationName
+ ./script/generate upgrade_open_id_authentication_tables MigrationName
+
+Alternatively, you can use the file-based store, which just relies on on tmp/openids being present in RAILS_ROOT. But be aware that this store only works if you have a single application server. And it's not safe to use across NFS. It's recommended that you use the database store if at all possible. To use the file-based store, you'll also have to add this line to your config/environment.rb:
+
+ OpenIdAuthentication.store = :file
+
+This particular plugin also relies on the fact that the authentication action allows for both POST and GET operations.
+If you're using RESTful authentication, you'll need to explicitly allow for this in your routes.rb.
+
+The plugin also expects to find a root_url method that points to the home page of your site. You can accomplish this by using a root route in config/routes.rb:
+
+ map.root :controller => 'articles'
+
+This plugin relies on Rails Edge revision 6317 or newer.
+
+
+Example
+=======
+
+This example is just to meant to demonstrate how you could use OpenID authentication. You might well want to add
+salted hash logins instead of plain text passwords and other requirements on top of this. Treat it as a starting point,
+not a destination.
+
+Note that the User model referenced in the simple example below has an 'identity_url' attribute. You will want to add the same or similar field to whatever
+model you are using for authentication.
+
+Also of note is the following code block used in the example below:
+
+ authenticate_with_open_id do |result, identity_url|
+ ...
+ end
+
+In the above code block, 'identity_url' will need to match user.identity_url exactly. 'identity_url' will be a string in the form of 'http://example.com' -
+If you are storing just 'example.com' with your user, the lookup will fail.
+
+There is a handy method in this plugin called 'normalize_url' that will help with validating OpenID URLs.
+
+ OpenIdAuthentication.normalize_url(user.identity_url)
+
+The above will return a standardized version of the OpenID URL - the above called with 'example.com' will return 'http://example.com/'
+It will also raise an InvalidOpenId exception if the URL is determined to not be valid.
+Use the above code in your User model and validate OpenID URLs before saving them.
+
+config/routes.rb
+
+ map.root :controller => 'articles'
+ map.resource :session
+
+
+app/views/sessions/new.erb
+
+ <% form_tag(session_url) do %>
+ <p>
+ <label for="name">Username:</label>
+ <%= text_field_tag "name" %>
+ </p>
+
+ <p>
+ <label for="password">Password:</label>
+ <%= password_field_tag %>
+ </p>
+
+ <p>
+ ...or use:
+ </p>
+
+ <p>
+ <label for="openid_identifier">OpenID:</label>
+ <%= text_field_tag "openid_identifier" %>
+ </p>
+
+ <p>
+ <%= submit_tag 'Sign in', :disable_with => "Signing in&hellip;" %>
+ </p>
+ <% end %>
+
+app/controllers/sessions_controller.rb
+ class SessionsController < ApplicationController
+ def create
+ if using_open_id?
+ open_id_authentication
+ else
+ password_authentication(params[:name], params[:password])
+ end
+ end
+
+
+ protected
+ def password_authentication(name, password)
+ if @current_user = @account.users.authenticate(params[:name], params[:password])
+ successful_login
+ else
+ failed_login "Sorry, that username/password doesn't work"
+ end
+ end
+
+ def open_id_authentication
+ authenticate_with_open_id do |result, identity_url|
+ if result.successful?
+ if @current_user = @account.users.find_by_identity_url(identity_url)
+ successful_login
+ else
+ failed_login "Sorry, no user by that identity URL exists (#{identity_url})"
+ end
+ else
+ failed_login result.message
+ end
+ end
+ end
+
+
+ private
+ def successful_login
+ session[:user_id] = @current_user.id
+ redirect_to(root_url)
+ end
+
+ def failed_login(message)
+ flash[:error] = message
+ redirect_to(new_session_url)
+ end
+ end
+
+
+
+If you're fine with the result messages above and don't need individual logic on a per-failure basis,
+you can collapse the case into a mere boolean:
+
+ def open_id_authentication
+ authenticate_with_open_id do |result, identity_url|
+ if result.successful? && @current_user = @account.users.find_by_identity_url(identity_url)
+ successful_login
+ else
+ failed_login(result.message || "Sorry, no user by that identity URL exists (#{identity_url})")
+ end
+ end
+ end
+
+
+Simple Registration OpenID Extension
+====================================
+
+Some OpenID Providers support this lightweight profile exchange protocol. See more: http://www.openidenabled.com/openid/simple-registration-extension
+
+You can support it in your app by changing #open_id_authentication
+
+ def open_id_authentication(identity_url)
+ # Pass optional :required and :optional keys to specify what sreg fields you want.
+ # Be sure to yield registration, a third argument in the #authenticate_with_open_id block.
+ authenticate_with_open_id(identity_url,
+ :required => [ :nickname, :email ],
+ :optional => :fullname) do |result, identity_url, registration|
+ case result.status
+ when :missing
+ failed_login "Sorry, the OpenID server couldn't be found"
+ when :invalid
+ failed_login "Sorry, but this does not appear to be a valid OpenID"
+ when :canceled
+ failed_login "OpenID verification was canceled"
+ when :failed
+ failed_login "Sorry, the OpenID verification failed"
+ when :successful
+ if @current_user = @account.users.find_by_identity_url(identity_url)
+ assign_registration_attributes!(registration)
+
+ if current_user.save
+ successful_login
+ else
+ failed_login "Your OpenID profile registration failed: " +
+ @current_user.errors.full_messages.to_sentence
+ end
+ else
+ failed_login "Sorry, no user by that identity URL exists"
+ end
+ end
+ end
+ end
+
+ # registration is a hash containing the valid sreg keys given above
+ # use this to map them to fields of your user model
+ def assign_registration_attributes!(registration)
+ model_to_registration_mapping.each do |model_attribute, registration_attribute|
+ unless registration[registration_attribute].blank?
+ @current_user.send("#{model_attribute}=", registration[registration_attribute])
+ end
+ end
+ end
+
+ def model_to_registration_mapping
+ { :login => 'nickname', :email => 'email', :display_name => 'fullname' }
+ end
+
+Attribute Exchange OpenID Extension
+===================================
+
+Some OpenID providers also support the OpenID AX (attribute exchange) protocol for exchanging identity information between endpoints. See more: http://openid.net/specs/openid-attribute-exchange-1_0.html
+
+Accessing AX data is very similar to the Simple Registration process, described above -- just add the URI identifier for the AX field to your :optional or :required parameters. For example:
+
+ authenticate_with_open_id(identity_url,
+ :required => [ :email, 'http://schema.openid.net/birthDate' ]) do |result, identity_url, registration|
+
+This would provide the sreg data for :email, and the AX data for 'http://schema.openid.net/birthDate'
+
+
+
+Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
View
22 vendor/plugins/open_id_authentication/Rakefile
@@ -0,0 +1,22 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the open_id_authentication plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the open_id_authentication plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'OpenIdAuthentication'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
View
11 ...en_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb
@@ -0,0 +1,11 @@
+class OpenIdAuthenticationTablesGenerator < Rails::Generator::NamedBase
+ def initialize(runtime_args, runtime_options = {})
+ super
+ end
+
+ def manifest
+ record do |m|
+ m.migration_template 'migration.rb', 'db/migrate'
+ end
+ end
+end
View
20 vendor/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb
@@ -0,0 +1,20 @@
+class <%= class_name %> < ActiveRecord::Migration
+ def self.up
+ create_table :open_id_authentication_associations, :force => true do |t|
+ t.integer :issued, :lifetime
+ t.string :handle, :assoc_type
+ t.binary :server_url, :secret
+ end
+
+ create_table :open_id_authentication_nonces, :force => true do |t|
+ t.integer :timestamp, :null => false
+ t.string :server_url, :null => true
+ t.string :salt, :null => false
+ end
+ end
+
+ def self.down
+ drop_table :open_id_authentication_associations
+ drop_table :open_id_authentication_nonces
+ end
+end
View
26 ...r/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb
@@ -0,0 +1,26 @@
+class <%= class_name %> < ActiveRecord::Migration
+ def self.up
+ drop_table :open_id_authentication_settings
+ drop_table :open_id_authentication_nonces
+
+ create_table :open_id_authentication_nonces, :force => true do |t|
+ t.integer :timestamp, :null => false
+ t.string :server_url, :null => true
+ t.string :salt, :null => false
+ end
+ end
+
+ def self.down
+ drop_table :open_id_authentication_nonces
+
+ create_table :open_id_authentication_nonces, :force => true do |t|
+ t.integer :created
+ t.string :nonce
+ end
+
+ create_table :open_id_authentication_settings, :force => true do |t|
+ t.string :setting
+ t.binary :value
+ end
+ end
+end
View
11 ...tion/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb
@@ -0,0 +1,11 @@
+class UpgradeOpenIdAuthenticationTablesGenerator < Rails::Generator::NamedBase
+ def initialize(runtime_args, runtime_options = {})
+ super
+ end
+
+ def manifest
+ record do |m|
+ m.migration_template 'migration.rb', 'db/migrate'
+ end
+ end
+end
View
18 vendor/plugins/open_id_authentication/init.rb
@@ -0,0 +1,18 @@
+if config.respond_to?(:gems)
+ config.gem 'ruby-openid', :lib => 'openid', :version => '>=2.0.4'
+else
+ begin
+ require 'openid'
+ rescue LoadError
+ begin
+ gem 'ruby-openid', '>=2.0.4'
+ rescue Gem::LoadError
+ puts "Install the ruby-openid gem to enable OpenID support"
+ end
+ end
+end
+
+config.to_prepare do
+ OpenID::Util.logger = Rails.logger
+ ActionController::Base.send :include, OpenIdAuthentication
+end
View
240 vendor/plugins/open_id_authentication/lib/open_id_authentication.rb
@@ -0,0 +1,240 @@
+require 'uri'
+require 'openid/extensions/sreg'
+require 'openid/extensions/ax'
+require 'openid/store/filesystem'
+
+require File.dirname(__FILE__) + '/open_id_authentication/association'
+require File.dirname(__FILE__) + '/open_id_authentication/nonce'
+require File.dirname(__FILE__) + '/open_id_authentication/db_store'
+require File.dirname(__FILE__) + '/open_id_authentication/request'
+require File.dirname(__FILE__) + '/open_id_authentication/timeout_fixes' if OpenID::VERSION == "2.0.4"
+
+module OpenIdAuthentication
+ OPEN_ID_AUTHENTICATION_DIR = RAILS_ROOT + "/tmp/openids"
+
+ def self.store
+ @@store
+ end
+
+ def self.store=(*store_option)
+ store, *parameters = *([ store_option ].flatten)
+
+ @@store = case store
+ when :db
+ OpenIdAuthentication::DbStore.new
+ when :file
+ OpenID::Store::Filesystem.new(OPEN_ID_AUTHENTICATION_DIR)
+ else
+ store
+ end
+ end
+
+ self.store = :db
+
+ class InvalidOpenId < StandardError
+ end
+
+ class Result
+ ERROR_MESSAGES = {
+ :missing => "Sorry, the OpenID server couldn't be found",
+ :invalid => "Sorry, but this does not appear to be a valid OpenID",
+ :canceled => "OpenID verification was canceled",
+ :failed => "OpenID verification failed",
+ :setup_needed => "OpenID verification needs setup"
+ }
+
+ def self.[](code)
+ new(code)
+ end
+
+ def initialize(code)
+ @code = code
+ end
+
+ def status
+ @code
+ end
+
+ ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } }
+
+ def successful?
+ @code == :successful
+ end
+
+ def unsuccessful?
+ ERROR_MESSAGES.keys.include?(@code)
+ end
+
+ def message
+ ERROR_MESSAGES[@code]
+ end
+ end
+
+ # normalizes an OpenID according to http://openid.net/specs/openid-authentication-2_0.html#normalization
+ def self.normalize_identifier(identifier)
+ # clean up whitespace
+ identifier = identifier.to_s.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
+
+ # deprecated for OpenID 2.0, where not all OpenIDs are URLs
+ def self.normalize_url(url)
+ ActiveSupport::Deprecation.warn "normalize_url has been deprecated, use normalize_identifier instead"
+ self.normalize_identifier(url)
+ end
+
+ protected
+ def normalize_url(url)
+ OpenIdAuthentication.normalize_url(url)
+ end
+
+ def normalize_identifier(url)
+ OpenIdAuthentication.normalize_identifier(url)
+ end
+
+ # The parameter name of "openid_identifier" is used rather than the Rails convention "open_id_identifier"
+ # because that's what the specification dictates in order to get browser auto-complete working across sites
+ def using_open_id?(identity_url = nil) #:doc:
+ identity_url ||= params[:openid_identifier] || params[:openid_url]
+ !identity_url.blank? || params[:open_id_complete]
+ end
+
+ def authenticate_with_open_id(identity_url = nil, options = {}, &block) #:doc:
+ identity_url ||= params[:openid_identifier] || params[:openid_url]
+
+ if params[:open_id_complete].nil?
+ begin_open_id_authentication(identity_url, options, &block)
+ else
+ complete_open_id_authentication(&block)
+ end
+ end
+
+ private
+ def begin_open_id_authentication(identity_url, options = {})
+ identity_url = normalize_identifier(identity_url)
+ return_to = options.delete(:return_to)
+ method = options.delete(:method)
+
+ options[:required] ||= [] # reduces validation later
+ options[:optional] ||= []
+
+ open_id_request = open_id_consumer.begin(identity_url)
+ add_simple_registration_fields(open_id_request, options)
+ add_ax_fields(open_id_request, options)
+ redirect_to(open_id_redirect_url(open_id_request, return_to, method))
+ rescue OpenIdAuthentication::InvalidOpenId => e
+ yield Result[:invalid], identity_url, nil
+ rescue OpenID::OpenIDError, Timeout::Error => e
+ logger.error("[OPENID] #{e}")
+ yield Result[:missing], identity_url, nil
+ end
+
+ def complete_open_id_authentication
+ params_with_path = params.reject { |key, value| request.path_parameters[key] }
+ params_with_path.delete(:format)
+ open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params_with_path, requested_url) }
+ identity_url = normalize_identifier(open_id_response.display_identifier) if open_id_response.display_identifier
+
+ case open_id_response.status
+ when OpenID::Consumer::SUCCESS
+ profile_data = {}
+
+ # merge the SReg data and the AX data into a single hash of profile data
+ [ OpenID::SReg::Response, OpenID::AX::FetchResponse ].each do |data_response|
+ if data_response.from_success_response( open_id_response )
+ profile_data.merge! data_response.from_success_response( open_id_response ).data
+ end
+ end
+
+ yield Result[:successful], identity_url, profile_data
+ when OpenID::Consumer::CANCEL
+ yield Result[:canceled], identity_url, nil
+ when OpenID::Consumer::FAILURE
+ yield Result[:failed], identity_url, nil
+ when OpenID::Consumer::SETUP_NEEDED
+ yield Result[:setup_needed], open_id_response.setup_url, nil
+ end
+ end
+
+ def open_id_consumer
+ OpenID::Consumer.new(session, OpenIdAuthentication.store)
+ end
+
+ def add_simple_registration_fields(open_id_request, fields)
+ sreg_request = OpenID::SReg::Request.new
+
+ # filter out AX identifiers (URIs)
+ required_fields = fields[:required].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact
+ optional_fields = fields[:optional].collect { |f| f.to_s unless f =~ /^https?:\/\// }.compact
+
+ sreg_request.request_fields(required_fields, true) unless required_fields.blank?
+ sreg_request.request_fields(optional_fields, false) unless optional_fields.blank?
+ sreg_request.policy_url = fields[:policy_url] if fields[:policy_url]
+ open_id_request.add_extension(sreg_request)
+ end
+
+ def add_ax_fields( open_id_request, fields )
+ ax_request = OpenID::AX::FetchRequest.new
+
+ # look through the :required and :optional fields for URIs (AX identifiers)
+ fields[:required].each do |f|
+ next unless f =~ /^https?:\/\//
+ ax_request.add( OpenID::AX::AttrInfo.new( f, nil, true ) )
+ end
+
+ fields[:optional].each do |f|
+ next unless f =~ /^https?:\/\//
+ ax_request.add( OpenID::AX::AttrInfo.new( f, nil, false ) )
+ end
+
+ open_id_request.add_extension( ax_request )
+ end
+
+ def open_id_redirect_url(open_id_request, return_to = nil, method = nil)
+ open_id_request.return_to_args['_method'] = (method || request.method).to_s
+ open_id_request.return_to_args['open_id_complete'] = '1'
+ open_id_request.redirect_url(root_url, return_to || requested_url)
+ end
+
+ def requested_url
+ relative_url_root = self.class.respond_to?(:relative_url_root) ?
+ self.class.relative_url_root.to_s :
+ request.relative_url_root
+ "#{request.protocol}#{request.host_with_port}#{ActionController::Base.relative_url_root}#{request.path}"
+ end
+
+ def timeout_protection_from_identity_server
+ yield
+ rescue Timeout::Error
+ Class.new do
+ def status
+ OpenID::FAILURE
+ end
+
+ def msg
+ "Identity server timed out"
+ end
+ end.new
+ end
+end
View
9 vendor/plugins/open_id_authentication/lib/open_id_authentication/association.rb
@@ -0,0 +1,9 @@
+module OpenIdAuthentication
+ class Association < ActiveRecord::Base
+ set_table_name :open_id_authentication_associations
+
+ def from_record
+ OpenID::Association.new(handle, secret, issued, lifetime, assoc_type)
+ end
+ end
+end
View
55 vendor/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb
@@ -0,0 +1,55 @@
+require 'openid/store/interface'
+
+module OpenIdAuthentication
+ class DbStore < OpenID::Store::Interface
+ def self.cleanup_nonces
+ now = Time.now.to_i
+ Nonce.delete_all(["timestamp > ? OR timestamp < ?", now + OpenID::Nonce.skew, now - OpenID::Nonce.skew])
+ end
+
+ def self.cleanup_associations
+ now = Time.now.to_i
+ Association.delete_all(['issued + lifetime > ?',now])
+ end
+
+ def store_association(server_url, assoc)
+ remove_association(server_url, assoc.handle)
+ Association.create(:server_url => server_url,
+ :handle => assoc.handle,
+ :secret => assoc.secret,
+ :issued => assoc.issued,
+ :lifetime => assoc.lifetime,
+ :assoc_type => assoc.assoc_type)
+ end
+
+ def get_association(server_url, handle = nil)
+ assocs = if handle.blank?
+ Association.find_all_by_server_url(server_url)
+ else
+ Association.find_all_by_server_url_and_handle(server_url, handle)
+ end
+
+ assocs.reverse.each do |assoc|
+ a = assoc.from_record
+ if a.expires_in == 0
+ assoc.destroy
+ else
+ return a
+ end
+ end if assocs.any?
+
+ return nil
+ end
+
+ def remove_association(server_url, handle)
+ Association.delete_all(['server_url = ? AND handle = ?', server_url, handle]) > 0
+ end
+
+ def use_nonce(server_url, timestamp, salt)
+ return false if Nonce.find_by_server_url_and_timestamp_and_salt(server_url, timestamp, salt)
+ return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew
+ Nonce.create(:server_url => server_url, :timestamp => timestamp, :salt => salt)
+ return true
+ end
+ end
+end
View
5 vendor/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb
@@ -0,0 +1,5 @@
+module OpenIdAuthentication
+ class Nonce < ActiveRecord::Base
+ set_table_name :open_id_authentication_nonces
+ end
+end
View
23 vendor/plugins/open_id_authentication/lib/open_id_authentication/request.rb
@@ -0,0 +1,23 @@
+module OpenIdAuthentication
+ module Request
+ def self.included(base)
+ base.alias_method_chain :request_method, :openid
+ end
+
+ def request_method_with_openid
+ if !parameters[:_method].blank? && parameters[:open_id_complete] == '1'
+ parameters[:_method].to_sym
+ else
+ request_method_without_openid
+ end
+ end
+ end
+end
+
+# In Rails 2.3, the request object has been renamed
+# from AbstractRequest to Request
+if defined? ActionController::Request
+ ActionController::Request.send :include, OpenIdAuthentication::Request
+else
+ ActionController::AbstractRequest.send :include, OpenIdAuthentication::Request
+end
View
20 vendor/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb
@@ -0,0 +1,20 @@
+# http://trac.openidenabled.com/trac/ticket/156
+module OpenID
+ @@timeout_threshold = 20
+
+ def self.timeout_threshold
+ @@timeout_threshold
+ end
+
+ def self.timeout_threshold=(value)
+ @@timeout_threshold = value
+ end
+
+ class StandardFetcher
+ def make_http(uri)
+ http = @proxy.new(uri.host, uri.port)
+ http.read_timeout = http.open_timeout = OpenID.timeout_threshold
+ http
+ end
+ end
+end
View
30 vendor/plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake
@@ -0,0 +1,30 @@
+namespace :open_id_authentication do
+ namespace :db do
+ desc "Creates authentication tables for use with OpenIdAuthentication"
+ task :create => :environment do
+ generate_migration(["open_id_authentication_tables", "add_open_id_authentication_tables"])
+ end
+
+ desc "Upgrade authentication tables from ruby-openid 1.x.x to 2.x.x"
+ task :upgrade => :environment do
+ generate_migration(["upgrade_open_id_authentication_tables", "upgrade_open_id_authentication_tables"])
+ end
+
+ def generate_migration(args)
+ require 'rails_generator'
+ require 'rails_generator/scripts/generate'
+
+ if ActiveRecord::Base.connection.supports_migrations?
+ Rails::Generator::Scripts::Generate.new.run(args)
+ else
+ raise "Task unavailable to this database (no migration support)"
+ end
+ end
+
+ desc "Clear the authentication tables"
+ task :clear => :environment do
+ OpenIdAuthentication::DbStore.cleanup_nonces
+ OpenIdAuthentication::DbStore.cleanup_associations
+ end
+ end
+end
View
32 vendor/plugins/open_id_authentication/test/normalize_test.rb
@@ -0,0 +1,32 @@
+require File.dirname(__FILE__) + '/test_helper'
+
+class NormalizeTest < Test::Unit::TestCase
+ include OpenIdAuthentication
+
+ NORMALIZATIONS = {
+ "openid.aol.com/nextangler" => "http://openid.aol.com/nextangler",
+ "http://openid.aol.com/nextangler" => "http://openid.aol.com/nextangler",
+ "https://openid.aol.com/nextangler" => "https://openid.aol.com/nextangler",
+ "HTTP://OPENID.AOL.COM/NEXTANGLER" => "http://openid.aol.com/NEXTANGLER",
+ "HTTPS://OPENID.AOL.COM/NEXTANGLER" => "https://openid.aol.com/NEXTANGLER",
+ "loudthinking.com" => "http://loudthinking.com/",
+ "http://loudthinking.com" => "http://loudthinking.com/",
+ "http://loudthinking.com:80" => "http://loudthinking.com/",
+ "https://loudthinking.com:443" => "https://loudthinking.com/",
+ "http://loudthinking.com:8080" => "http://loudthinking.com:8080/",
+ "techno-weenie.net" => "http://techno-weenie.net/",
+ "http://techno-weenie.net" => "http://techno-weenie.net/",
+ "http://techno-weenie.net " => "http://techno-weenie.net/",
+ "=name" => "=name"
+ }
+
+ def test_normalizations
+ NORMALIZATIONS.each do |from, to|
+ assert_equal to, normalize_identifier(from)
+ end
+ end
+
+ def test_broken_open_id
+ assert_raises(InvalidOpenId) { normalize_identifier(nil) }
+ end
+end
View
46 vendor/plugins/open_id_authentication/test/open_id_authentication_test.rb
@@ -0,0 +1,46 @@
+require File.dirname(__FILE__) + '/test_helper'
+
+class OpenIdAuthenticationTest < Test::Unit::TestCase
+ def setup
+ @controller = Class.new do
+ include OpenIdAuthentication
+ def params() {} end
+ end.new
+ end
+
+ def test_authentication_should_fail_when_the_identity_server_is_missing
+ open_id_consumer = mock()
+ open_id_consumer.expects(:begin).raises(OpenID::OpenIDError)
+ @controller.expects(:open_id_consumer).returns(open_id_consumer)
+ @controller.expects(:logger).returns(mock(:error => true))
+
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url|
+ assert result.missing?
+ assert_equal "Sorry, the OpenID server couldn't be found", result.message
+ end
+ end
+
+ def test_authentication_should_be_invalid_when_the_identity_url_is_invalid
+ @controller.send(:authenticate_with_open_id, "!") do |result, identity_url|
+ assert result.invalid?, "Result expected to be invalid but was not"
+ assert_equal "Sorry, but this does not appear to be a valid OpenID", result.message
+ end
+ end
+
+ def test_authentication_should_fail_when_the_identity_server_times_out
+ open_id_consumer = mock()
+ open_id_consumer.expects(:begin).raises(Timeout::Error, "Identity Server took too long.")
+ @controller.expects(:open_id_consumer).returns(open_id_consumer)
+ @controller.expects(:logger).returns(mock(:error => true))
+
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url|
+ assert result.missing?
+ assert_equal "Sorry, the OpenID server couldn't be found", result.message
+ end
+ end
+
+ def test_authentication_should_begin_when_the_identity_server_is_present
+ @controller.expects(:begin_open_id_authentication)
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com")
+ end
+end
View
14 vendor/plugins/open_id_authentication/test/status_test.rb
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/test_helper'
+
+class StatusTest < Test::Unit::TestCase
+ include OpenIdAuthentication
+
+ def test_state_conditional
+ assert Result[:missing].missing?
+ assert Result[:missing].unsuccessful?
+ assert !Result[:missing].successful?
+
+ assert Result[:successful].successful?
+ assert !Result[:successful].unsuccessful?
+ end
+end
View
17 vendor/plugins/open_id_authentication/test/test_helper.rb
@@ -0,0 +1,17 @@
+require 'test/unit'
+require 'rubygems'
+
+gem 'activesupport'
+require 'active_support'
+
+gem 'actionpack'
+require 'action_controller'
+
+gem 'mocha'
+require 'mocha'
+
+gem 'ruby-openid'
+require 'openid'
+
+RAILS_ROOT = File.dirname(__FILE__) unless defined? RAILS_ROOT
+require File.dirname(__FILE__) + "/../lib/open_id_authentication"
Please sign in to comment.
Something went wrong with that request. Please try again.