ruby-openid 1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-openid might be problematic. Click here for more details.

Files changed (114) hide show
  1. data/COPYING +21 -0
  2. data/INSTALL +34 -0
  3. data/README +67 -0
  4. data/TODO +9 -0
  5. data/examples/README +54 -0
  6. data/examples/cacert.pem +7815 -0
  7. data/examples/consumer.rb +285 -0
  8. data/examples/openid-store/associations/http-localhost_3A3000_2Fserver-EMQbAy3NnHVzA.s0u5KAcplKGzo +6 -0
  9. data/examples/openid-store/auth_key +1 -0
  10. data/examples/rails_active_record_store/README +59 -0
  11. data/examples/rails_active_record_store/XX_add_openidstore.rb +30 -0
  12. data/examples/rails_active_record_store/models/openid_association.rb +12 -0
  13. data/examples/rails_active_record_store/models/openid_nonce.rb +3 -0
  14. data/examples/rails_active_record_store/models/openid_setting.rb +2 -0
  15. data/examples/rails_active_record_store/openid_helper.rb +91 -0
  16. data/examples/rails_active_record_store/openidstore_test.rb +15 -0
  17. data/examples/rails_active_record_store/schema.mysql.sql +22 -0
  18. data/examples/rails_active_record_store/schema.postgresql.sql +21 -0
  19. data/examples/rails_active_record_store/schema.sqlite.sql +21 -0
  20. data/examples/rails_openid_login_generator/USAGE +23 -0
  21. data/examples/rails_openid_login_generator/openid_login_generator.rb +36 -0
  22. data/examples/rails_openid_login_generator/templates/README +116 -0
  23. data/examples/rails_openid_login_generator/templates/controller.rb +116 -0
  24. data/examples/rails_openid_login_generator/templates/controller_test.rb +0 -0
  25. data/examples/rails_openid_login_generator/templates/helper.rb +2 -0
  26. data/examples/rails_openid_login_generator/templates/openid_login_system.rb +87 -0
  27. data/examples/rails_openid_login_generator/templates/user.rb +14 -0
  28. data/examples/rails_openid_login_generator/templates/user_test.rb +0 -0
  29. data/examples/rails_openid_login_generator/templates/users.yml +0 -0
  30. data/examples/rails_openid_login_generator/templates/view_login.rhtml +15 -0
  31. data/examples/rails_openid_login_generator/templates/view_logout.rhtml +10 -0
  32. data/examples/rails_openid_login_generator/templates/view_welcome.rhtml +9 -0
  33. data/examples/rails_server/README +153 -0
  34. data/examples/rails_server/Rakefile +10 -0
  35. data/examples/rails_server/app/controllers/application.rb +4 -0
  36. data/examples/rails_server/app/controllers/login_controller.rb +35 -0
  37. data/examples/rails_server/app/controllers/server_controller.rb +185 -0
  38. data/examples/rails_server/app/helpers/application_helper.rb +3 -0
  39. data/examples/rails_server/app/helpers/login_helper.rb +2 -0
  40. data/examples/rails_server/app/helpers/server_helper.rb +9 -0
  41. data/examples/rails_server/app/views/layouts/server.rhtml +61 -0
  42. data/examples/rails_server/app/views/login/index.rhtml +32 -0
  43. data/examples/rails_server/app/views/server/decide.rhtml +11 -0
  44. data/examples/rails_server/config/boot.rb +19 -0
  45. data/examples/rails_server/config/database.yml +85 -0
  46. data/examples/rails_server/config/environment.rb +53 -0
  47. data/examples/rails_server/config/environments/development.rb +19 -0
  48. data/examples/rails_server/config/environments/production.rb +19 -0
  49. data/examples/rails_server/config/environments/test.rb +19 -0
  50. data/examples/rails_server/config/routes.rb +23 -0
  51. data/examples/rails_server/db/openid-store/associations/http-localhost_2F_7Cnormal-YU.tkND1J4fEZhnuAoT5Zc0yCA0 +6 -0
  52. data/examples/rails_server/doc/README_FOR_APP +2 -0
  53. data/examples/rails_server/log/development.log +6059 -0
  54. data/examples/rails_server/log/production.log +0 -0
  55. data/examples/rails_server/log/server.log +0 -0
  56. data/examples/rails_server/log/test.log +0 -0
  57. data/examples/rails_server/public/404.html +8 -0
  58. data/examples/rails_server/public/500.html +8 -0
  59. data/examples/rails_server/public/dispatch.cgi +12 -0
  60. data/examples/rails_server/public/dispatch.fcgi +26 -0
  61. data/examples/rails_server/public/dispatch.rb +12 -0
  62. data/examples/rails_server/public/favicon.ico +0 -0
  63. data/examples/rails_server/public/images/rails.png +0 -0
  64. data/examples/rails_server/public/javascripts/controls.js +750 -0
  65. data/examples/rails_server/public/javascripts/dragdrop.js +584 -0
  66. data/examples/rails_server/public/javascripts/effects.js +854 -0
  67. data/examples/rails_server/public/javascripts/prototype.js +1785 -0
  68. data/examples/rails_server/public/robots.txt +1 -0
  69. data/examples/rails_server/script/about +3 -0
  70. data/examples/rails_server/script/breakpointer +3 -0
  71. data/examples/rails_server/script/console +3 -0
  72. data/examples/rails_server/script/destroy +3 -0
  73. data/examples/rails_server/script/generate +3 -0
  74. data/examples/rails_server/script/performance/benchmarker +3 -0
  75. data/examples/rails_server/script/performance/profiler +3 -0
  76. data/examples/rails_server/script/plugin +3 -0
  77. data/examples/rails_server/script/process/reaper +3 -0
  78. data/examples/rails_server/script/process/spawner +3 -0
  79. data/examples/rails_server/script/process/spinner +3 -0
  80. data/examples/rails_server/script/runner +3 -0
  81. data/examples/rails_server/script/server +3 -0
  82. data/examples/rails_server/test/functional/login_controller_test.rb +18 -0
  83. data/examples/rails_server/test/functional/server_controller_test.rb +18 -0
  84. data/examples/rails_server/test/test_helper.rb +28 -0
  85. data/lib/hmac-md5.rb +11 -0
  86. data/lib/hmac-rmd160.rb +11 -0
  87. data/lib/hmac-sha1.rb +11 -0
  88. data/lib/hmac-sha2.rb +25 -0
  89. data/lib/hmac.rb +112 -0
  90. data/lib/openid/association.rb +109 -0
  91. data/lib/openid/consumer.rb +928 -0
  92. data/lib/openid/dh.rb +48 -0
  93. data/lib/openid/discovery.rb +89 -0
  94. data/lib/openid/fetchers.rb +119 -0
  95. data/lib/openid/filestore.rb +315 -0
  96. data/lib/openid/htmltokenizer.rb +355 -0
  97. data/lib/openid/parse.rb +23 -0
  98. data/lib/openid/server.rb +951 -0
  99. data/lib/openid/service.rb +135 -0
  100. data/lib/openid/stores.rb +178 -0
  101. data/lib/openid/trustroot.rb +100 -0
  102. data/lib/openid/util.rb +273 -0
  103. data/test/assoc.rb +38 -0
  104. data/test/consumer.rb +384 -0
  105. data/test/dh.rb +20 -0
  106. data/test/extensions.rb +30 -0
  107. data/test/linkparse.rb +305 -0
  108. data/test/runtests.rb +11 -0
  109. data/test/server2.rb +1053 -0
  110. data/test/storetestcase.rb +172 -0
  111. data/test/teststore.rb +23 -0
  112. data/test/trustroot.rb +113 -0
  113. data/test/util.rb +56 -0
  114. metadata +218 -0
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ # ugly way to get at StoreTestCase module
4
+ require File.dirname(__FILE__) + '/../../vendor/openid/test/storetestcase'
5
+
6
+ class OpenidTest < Test::Unit::TestCase
7
+
8
+ include OpenidHelper
9
+ include StoreTestCase
10
+
11
+ def setup
12
+ @store = self
13
+ end
14
+
15
+ end
@@ -0,0 +1,22 @@
1
+ CREATE TABLE openid_associations (
2
+ `id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
3
+ `server_url` blob,
4
+ `handle` varchar(255),
5
+ `secret` blob,
6
+ `issued` int(11),
7
+ `lifetime` int(11),
8
+ `assoc_type` varchar(255)
9
+ ) ENGINE=InnoDB;
10
+
11
+ CREATE TABLE openid_nonces (
12
+ `id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
13
+ `nonce` varchar(255),
14
+ `created` int(11)
15
+ ) ENGINE=InnoDB;
16
+
17
+ CREATE TABLE openid_settings (
18
+ `id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
19
+ `setting` varchar(255),
20
+ `value` blob
21
+ ) ENGINE=InnoDB;
22
+
@@ -0,0 +1,21 @@
1
+ CREATE TABLE openid_associations (
2
+ "id" serial primary key,
3
+ "server_url" bytea,
4
+ "handle" character varying(255),
5
+ "secret" bytea,
6
+ "issued" integer,
7
+ "lifetime" integer,
8
+ "assoc_type" character varying(255)
9
+ );
10
+
11
+ CREATE TABLE openid_nonces (
12
+ "id" serial primary key,
13
+ "nonce" character varying(255),
14
+ "created" integer
15
+ );
16
+
17
+ CREATE TABLE openid_settings (
18
+ "id" serial primary key,
19
+ "setting" character varying(255),
20
+ "value" bytea
21
+ );
@@ -0,0 +1,21 @@
1
+ CREATE TABLE openid_associations (
2
+ "id" INTEGER PRIMARY KEY NOT NULL,
3
+ "server_url" blob,
4
+ "handle" varchar(255),
5
+ "secret" blob,
6
+ "issued" integer,
7
+ "lifetime" integer,
8
+ "assoc_type" varchar(255)
9
+ );
10
+
11
+ CREATE TABLE openid_nonces (
12
+ "id" INTEGER PRIMARY KEY NOT NULL,
13
+ "nonce" varchar(255),
14
+ "created" integer
15
+ );
16
+
17
+ CREATE TABLE openid_settings (
18
+ "id" INTEGER PRIMARY KEY NOT NULL,
19
+ "setting" varchar(255),
20
+ "value" blob
21
+ );
@@ -0,0 +1,23 @@
1
+ NAME
2
+ openid_login - creates a functional openid login system
3
+
4
+ SYNOPSIS
5
+ openid_login [Controller name]
6
+
7
+ Good names are Account Myaccount Security
8
+
9
+ DESCRIPTION
10
+ This generator creates a general purpose login system.
11
+
12
+ Included:
13
+ - a User model which stores OpenID authenticated users
14
+ - a Controller with login, welcome and logoff actions
15
+ - a mixin which lets you easily add advanced authentication
16
+ features to your abstract base controller
17
+
18
+
19
+ EXAMPLE
20
+ ./script/generate openid_login Account
21
+
22
+ This will generate an Account controller with login and logout methods.
23
+ The model is always called User
@@ -0,0 +1,36 @@
1
+ class OpenidLoginGenerator < Rails::Generator::NamedBase
2
+ def manifest
3
+ record do |m|
4
+
5
+ # Login module, controller class, functional test, and helper.
6
+ m.template "openid_login_system.rb", "lib/openid_login_system.rb"
7
+ m.template "controller.rb", File.join("app/controllers", class_path, "#{file_name}_controller.rb")
8
+ m.template "controller_test.rb", File.join("test/functional", class_path, "#{file_name}_controller_test.rb")
9
+ m.template "helper.rb", File.join("app/helpers", class_path, "#{file_name}_helper.rb")
10
+
11
+ # Model class, unit test, fixtures, and example schema.
12
+ m.template "user.rb", "app/models/user.rb"
13
+ m.template "user_test.rb", "test/unit/user_test.rb"
14
+ m.template "users.yml", "test/fixtures/users.yml"
15
+
16
+ # Layout and stylesheet.
17
+ m.template "scaffold:layout.rhtml", "app/views/layouts/scaffold.rhtml"
18
+ m.template "scaffold:style.css", "public/stylesheets/scaffold.css"
19
+
20
+ # Views.
21
+ m.directory File.join("app/views", class_path, file_name)
22
+ login_views.each do |action|
23
+ m.template "view_#{action}.rhtml",
24
+ File.join("app/views", class_path, file_name, "#{action}.rhtml")
25
+ end
26
+
27
+ m.template "README", "README_LOGIN"
28
+ end
29
+ end
30
+
31
+ attr_accessor :controller_class_name
32
+
33
+ def login_views
34
+ %w(welcome login logout)
35
+ end
36
+ end
@@ -0,0 +1,116 @@
1
+ == About
2
+
3
+ This is a port of the standard LoginGenerator to use OpenID for
4
+ authentication. It is distributed with the Ruby OpenID library.
5
+
6
+ Read more at:
7
+ * http://openidenabled.com
8
+ * http://openidenabled.com/openid/libraries/ruby
9
+ * http://openid.net
10
+
11
+ == Installation
12
+
13
+ If you are reading this, then you have installed the openid_login
14
+ system, but there are still a few things you have to do
15
+ manually. First open your app/controllers/application.rb and add
16
+
17
+ require_dependency "openid_login_system"
18
+
19
+ to the top of the file and include the login system with
20
+
21
+ include OpenidLoginSystem
22
+
23
+ The beginning of your ApplicationController.
24
+ It should look something like this :
25
+
26
+ require_dependency "openid_login_system"
27
+
28
+ class ApplicationController < ActionController::Base
29
+ include OpenidLoginSystem
30
+ model :user
31
+
32
+ After you have done the modifications the the AbstractController you can import
33
+ the user model into the database. This model is meant as an example and you
34
+ should extend it.
35
+
36
+ The model :user is required when you are hitting problems to the degree of
37
+ "Session could not be restored becuase not all items in it are known"
38
+
39
+ == Requirements
40
+
41
+ You need a database table corresponding to the User model.
42
+
43
+ mysql syntax:
44
+ CREATE TABLE users (
45
+ id int(11) NOT NULL auto_increment,
46
+ openid_url varchar(256) default NULL,
47
+ PRIMARY KEY (id)
48
+ );
49
+
50
+ postgres :
51
+ CREATE TABLE "users" (
52
+ �"id" SERIAL NOT NULL UNIQUE,
53
+ �"openid_url" VARCHAR(256),
54
+ �PRIMARY KEY("id")
55
+ ) WITH OIDS;
56
+
57
+ sqlite:
58
+ CREATE TABLE 'users' (
59
+ 'id' INTEGER PRIMARY KEY NOT NULL,
60
+ 'openid_url' VARCHAR(256) DEFAULT NULL
61
+ );
62
+
63
+ Of course your user model can have any amount of extra fields. This is just a
64
+ starting point
65
+
66
+ == How to use it
67
+
68
+ Now you can go around and happily add "before_filter :login_required" to the
69
+ controllers which you would like to protect.
70
+
71
+ After integrating the login system with your rails application
72
+ navigate to your new controller's login method. There you may login
73
+ which will create a new User object if you've never logged in
74
+ before. After you are done you should have a look at your DB, and
75
+ you'll see the record for your User with the openid_url you entered.
76
+
77
+
78
+ == Tips & Tricks
79
+
80
+ How do I...
81
+
82
+ ... access the user who is currently logged in
83
+
84
+ A: You can get the user id from the session using @session[:user_id]
85
+ Example:
86
+
87
+ @session[:user_id]
88
+
89
+ To get the User object:
90
+
91
+ user = User.find(@session[:user_id])
92
+
93
+ The OpenidController also has a find_user method
94
+ which will return the User object of the logged in user, or nil
95
+ if no user is logged in.
96
+
97
+
98
+ ... restrict access to only a few methods?
99
+
100
+ A: Use before_filters build in scoping.
101
+ Example:
102
+ before_filter :login_required, :only => [:myaccount, :changepassword]
103
+ before_filter :login_required, :except => [:index]
104
+
105
+ ... check if a user is logged-in in my views?
106
+
107
+ A: @session[:user_id] will tell you. Here is an example helper which you can use to make this more pretty:
108
+ Example:
109
+ def user?
110
+ !@session[:user_id].nil?
111
+ end
112
+
113
+
114
+
115
+
116
+
@@ -0,0 +1,116 @@
1
+ require "pathname"
2
+ require "cgi"
3
+
4
+ require "openid/filestore"
5
+ require "openid/consumer"
6
+
7
+ class <%= class_name %>Controller < ApplicationController
8
+ layout 'scaffold'
9
+
10
+ # process the login request, disover the openid server, and
11
+ # then redirect.
12
+ def login
13
+ openid_url = @params[:openid_url]
14
+
15
+ if @request.post?
16
+ request = consumer.begin(openid_url)
17
+
18
+ p 'XXX', request
19
+
20
+ case request.status
21
+ when OpenID::SUCCESS
22
+ return_to = url_for(:action=> 'complete')
23
+ trust_root = url_for(:controller=>'')
24
+
25
+ url = request.redirect_url(trust_root, return_to)
26
+ p 'REDIRECTURL', url
27
+
28
+ redirect_to(url)
29
+
30
+ p 'REDIRECT SENT', @session
31
+ return
32
+
33
+ when OpenID::FAILURE
34
+ escaped_url = CGI::escape(openid_url)
35
+ flash[:notice] = "Could not find OpenID server for #{escaped_url}"
36
+
37
+ else
38
+ flash[:notice] = "An unknown error occured."
39
+
40
+ end
41
+ end
42
+
43
+ p 'Done'
44
+
45
+ end
46
+
47
+ # handle the openid server response
48
+ def complete
49
+ token = @params[:token]
50
+
51
+ response = consumer.complete(@params)
52
+
53
+ case response.status
54
+ when OpenID::SUCCESS
55
+
56
+ @user = User.get(response.identity_url)
57
+
58
+ # create user object if one does not exist
59
+ if @user.nil?
60
+ @user = User.new(:openid_url => response.identity_url)
61
+ @user.save
62
+ end
63
+
64
+ # storing both the openid_url and user id in the session for for quick
65
+ # access to both bits of information. Change as needed.
66
+ @session[:user_id] = @user.id
67
+
68
+ flash[:notice] = "Logged in as #{CGI::escape(response.identity_url)}"
69
+
70
+ redirect_to :action => "welcome"
71
+ return
72
+
73
+ when OpenID::FAILURE
74
+ if response.identity_url
75
+ flash[:notice] = "Verification of #{CGI::escape(response.identity_url)} failed."
76
+
77
+ else
78
+ flash[:notice] = 'Verification failed.'
79
+ end
80
+
81
+ when OpenID::CANCEL
82
+ flash[:notice] = 'Verification cancelled.'
83
+
84
+ else
85
+ flash[:notice] = 'Unknown response from OpenID server.'
86
+ end
87
+
88
+ redirect_to :action => 'login'
89
+ end
90
+
91
+ def logout
92
+ @session[:user_id] = nil
93
+ end
94
+
95
+ def welcome
96
+ end
97
+
98
+ private
99
+
100
+ # Get the OpenID::Consumer object.
101
+ def consumer
102
+ # create the OpenID store for storing associations and nonces,
103
+ # putting it in your app's db directory
104
+ store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
105
+ store = OpenID::FilesystemStore.new(store_dir)
106
+
107
+ return OpenID::Consumer.new(@session, store)
108
+ end
109
+
110
+ # get the logged in user object
111
+ def find_user
112
+ return nil if session[:user_id].nil?
113
+ User.find(session[:user_id])
114
+ end
115
+
116
+ end
@@ -0,0 +1,2 @@
1
+ module <%= class_name %>Helper
2
+ end
@@ -0,0 +1,87 @@
1
+ require_dependency "user"
2
+
3
+ module OpenidLoginSystem
4
+
5
+ protected
6
+
7
+ # overwrite this if you want to restrict access to only a few actions
8
+ # or if you want to check if the user has the correct rights
9
+ # example:
10
+ #
11
+ # # only allow nonbobs
12
+ # def authorize?(user)
13
+ # user.login != "bob"
14
+ # end
15
+ def authorize?(user)
16
+ true
17
+ end
18
+
19
+ # overwrite this method if you only want to protect certain actions of the controller
20
+ # example:
21
+ #
22
+ # # don't protect the login and the about method
23
+ # def protect?(action)
24
+ # if ['action', 'about'].include?(action)
25
+ # return false
26
+ # else
27
+ # return true
28
+ # end
29
+ # end
30
+ def protect?(action)
31
+ true
32
+ end
33
+
34
+ # login_required filter. add
35
+ #
36
+ # before_filter :login_required
37
+ #
38
+ # if the controller should be under any rights management.
39
+ # for finer access control you can overwrite
40
+ #
41
+ # def authorize?(user)
42
+ #
43
+ def login_required
44
+
45
+ if not protect?(action_name)
46
+ return true
47
+ end
48
+
49
+ if @session[:user_id] and authorize?(User.find(@session[:user_id]))
50
+ return true
51
+ end
52
+
53
+ # store current location so that we can
54
+ # come back after the user logged in
55
+ store_location
56
+
57
+ # call overwriteable reaction to unauthorized access
58
+ access_denied
59
+ return false
60
+ end
61
+
62
+ # overwrite if you want to have special behavior in case the user is not authorized
63
+ # to access the current operation.
64
+ # the default action is to redirect to the login screen
65
+ # example use :
66
+ # a popup window might just close itself for instance
67
+ def access_denied
68
+ redirect_to :controller=>"/<%= file_name %>", :action =>"login"
69
+ end
70
+
71
+ # store current uri in the session.
72
+ # we can return to this location by calling return_location
73
+ def store_location
74
+ @session[:return_to] = @request.request_uri
75
+ end
76
+
77
+ # move to the last store_location call or to the passed default one
78
+ def redirect_back_or_default(default)
79
+ if @session[:return_to].nil?
80
+ redirect_to default
81
+ else
82
+ redirect_to_url @session[:return_to]
83
+ @session[:return_to] = nil
84
+ end
85
+ end
86
+
87
+ end