ruby-openid 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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