openid_login_generator 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/USAGE ADDED
@@ -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,111 @@
1
+ require "pathname"
2
+ require "cgi"
3
+
4
+ # load the openid library
5
+ begin
6
+ require "rubygems"
7
+ require_gem "ruby-openid", ">= 1.0.2"
8
+ rescue LoadError
9
+ require "openid"
10
+ end
11
+
12
+ class <%= class_name %>Controller < ApplicationController
13
+ layout 'scaffold'
14
+
15
+ # process the login request, disover the openid server, and
16
+ # then redirect.
17
+ def login
18
+ openid_url = @params[:openid_url]
19
+
20
+ if @request.post?
21
+ request = consumer.begin(openid_url)
22
+
23
+ case request.status
24
+ when OpenID::SUCCESS
25
+ return_to = url_for(:action=> 'complete')
26
+ trust_root = url_for(:controller=>'')
27
+
28
+ url = request.redirect_url(trust_root, return_to)
29
+ redirect_to(url)
30
+ return
31
+
32
+ when OpenID::FAILURE
33
+ escaped_url = CGI::escape(openid_url)
34
+ flash[:notice] = "Could not find OpenID server for #{escaped_url}"
35
+
36
+ else
37
+ flash[:notice] = "An unknown error occured."
38
+
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ # handle the openid server response
45
+ def complete
46
+ response = consumer.complete(@params)
47
+
48
+ case response.status
49
+ when OpenID::SUCCESS
50
+
51
+ @user = User.get(response.identity_url)
52
+
53
+ # create user object if one does not exist
54
+ if @user.nil?
55
+ @user = User.new(:openid_url => response.identity_url)
56
+ @user.save
57
+ end
58
+
59
+ # storing both the openid_url and user id in the session for for quick
60
+ # access to both bits of information. Change as needed.
61
+ @session[:user_id] = @user.id
62
+
63
+ flash[:notice] = "Logged in as #{CGI::escape(response.identity_url)}"
64
+
65
+ redirect_to :action => "welcome"
66
+ return
67
+
68
+ when OpenID::FAILURE
69
+ if response.identity_url
70
+ flash[:notice] = "Verification of #{CGI::escape(response.identity_url)} failed."
71
+
72
+ else
73
+ flash[:notice] = 'Verification failed.'
74
+ end
75
+
76
+ when OpenID::CANCEL
77
+ flash[:notice] = 'Verification cancelled.'
78
+
79
+ else
80
+ flash[:notice] = 'Unknown response from OpenID server.'
81
+ end
82
+
83
+ redirect_to :action => 'login'
84
+ end
85
+
86
+ def logout
87
+ @session[:user_id] = nil
88
+ end
89
+
90
+ def welcome
91
+ end
92
+
93
+ private
94
+
95
+ # Get the OpenID::Consumer object.
96
+ def consumer
97
+ # create the OpenID store for storing associations and nonces,
98
+ # putting it in your app's db directory
99
+ store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
100
+ store = OpenID::FilesystemStore.new(store_dir)
101
+
102
+ return OpenID::Consumer.new(@session, store)
103
+ end
104
+
105
+ # get the logged in user object
106
+ def find_user
107
+ return nil if session[:user_id].nil?
108
+ User.find(session[:user_id])
109
+ end
110
+
111
+ end
@@ -0,0 +1,111 @@
1
+ require "pathname"
2
+ require "cgi"
3
+
4
+ # load the openid library
5
+ begin
6
+ require "rubygems"
7
+ require_gem "ruby-openid", ">= 1.0"
8
+ rescue LoadError
9
+ require "openid"
10
+ end
11
+
12
+ class <%= class_name %>Controller < ApplicationController
13
+ layout 'scaffold'
14
+
15
+ # process the login request, disover the openid server, and
16
+ # then redirect.
17
+ def login
18
+ openid_url = @params[:openid_url]
19
+
20
+ if @request.post?
21
+ request = consumer.begin(openid_url)
22
+
23
+ case request.status
24
+ when OpenID::SUCCESS
25
+ return_to = url_for(:action=> 'complete')
26
+ trust_root = url_for(:controller=>'')
27
+
28
+ url = request.redirect_url(trust_root, return_to)
29
+ redirect_to(url)
30
+ return
31
+
32
+ when OpenID::FAILURE
33
+ escaped_url = CGI::escape(openid_url)
34
+ flash[:notice] = "Could not find OpenID server for #{escaped_url}"
35
+
36
+ else
37
+ flash[:notice] = "An unknown error occured."
38
+
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ # handle the openid server response
45
+ def complete
46
+ response = consumer.complete(@params)
47
+
48
+ case response.status
49
+ when OpenID::SUCCESS
50
+
51
+ @user = User.get(response.identity_url)
52
+
53
+ # create user object if one does not exist
54
+ if @user.nil?
55
+ @user = User.new(:openid_url => response.identity_url)
56
+ @user.save
57
+ end
58
+
59
+ # storing both the openid_url and user id in the session for for quick
60
+ # access to both bits of information. Change as needed.
61
+ @session[:user_id] = @user.id
62
+
63
+ flash[:notice] = "Logged in as #{CGI::escape(response.identity_url)}"
64
+
65
+ redirect_to :action => "welcome"
66
+ return
67
+
68
+ when OpenID::FAILURE
69
+ if response.identity_url
70
+ flash[:notice] = "Verification of #{CGI::escape(response.identity_url)} failed."
71
+
72
+ else
73
+ flash[:notice] = 'Verification failed.'
74
+ end
75
+
76
+ when OpenID::CANCEL
77
+ flash[:notice] = 'Verification cancelled.'
78
+
79
+ else
80
+ flash[:notice] = 'Unknown response from OpenID server.'
81
+ end
82
+
83
+ redirect_to :action => 'login'
84
+ end
85
+
86
+ def logout
87
+ @session[:user_id] = nil
88
+ end
89
+
90
+ def welcome
91
+ end
92
+
93
+ private
94
+
95
+ # Get the OpenID::Consumer object.
96
+ def consumer
97
+ # create the OpenID store for storing associations and nonces,
98
+ # putting it in your app's db directory
99
+ store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
100
+ store = OpenID::FilesystemStore.new(store_dir)
101
+
102
+ return OpenID::Consumer.new(@session, store)
103
+ end
104
+
105
+ # get the logged in user object
106
+ def find_user
107
+ return nil if session[:user_id].nil?
108
+ User.find(session[:user_id])
109
+ end
110
+
111
+ end
File without changes
@@ -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
@@ -0,0 +1,14 @@
1
+
2
+ # this model expects a certain database layout and its based on the name/login pattern.
3
+ class User < ActiveRecord::Base
4
+
5
+ def self.get(openid_url)
6
+ find_first(["openid_url = ?", openid_url])
7
+ end
8
+
9
+
10
+ protected
11
+
12
+ validates_uniqueness_of :openid_url, :on => :create
13
+ validates_presence_of :openid_url
14
+ end
File without changes
File without changes
@@ -0,0 +1,15 @@
1
+ <%%= start_form_tag :action=> "login" %>
2
+
3
+ <div title="Account login" id="loginform" class="form">
4
+ <h3>Please login</h3>
5
+
6
+ <label for="user_login">Login:</label><br/>
7
+ <input type="text" name="openid_url" id="openid_url" size="30" value="<%= @login %>"/><br/>
8
+
9
+ <br/>
10
+ <input type="submit" name="login" value="Login &#187;" class="primary" />
11
+
12
+ </div>
13
+
14
+ <%%= end_form_tag %>
15
+
@@ -0,0 +1,10 @@
1
+
2
+ <div class="memo">
3
+ <h3>Logoff</h3>
4
+
5
+ <p>You are now logged out of the system...</p>
6
+
7
+ <%%= link_to "&#171; login", :action=>"login"%>
8
+
9
+ </div>
10
+
@@ -0,0 +1,9 @@
1
+
2
+ <div class="memo">
3
+ <h3>Welcome</h3>
4
+
5
+ <p>You are now logged into the system...</p>
6
+
7
+ <%%= link_to "&#171; logout", :action=>"logout"%>
8
+
9
+ </div>
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: openid_login_generator
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2006-06-12 00:00:00 -07:00
8
+ summary: "[Rails] OpenID Login generator."
9
+ require_paths:
10
+ - .
11
+ email: brian@janrain.com
12
+ homepage: http://wiki.rubyonrails.org/rails/pages/OpenidLoginGenerator
13
+ rubyforge_project:
14
+ description: Generates Rails code implementing an OpenID based login system for your Rails app. Based on the original Rails Login Generator.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - Brian Ellin, JanRain Inc.
30
+ files:
31
+ - templates/controller.rb
32
+ - templates/README
33
+ - templates/user_test.rb
34
+ - templates/helper.rb
35
+ - templates/user.rb
36
+ - templates/view_login.rhtml
37
+ - templates/users.yml
38
+ - templates/view_logout.rhtml
39
+ - templates/controller.rb~
40
+ - templates/view_welcome.rhtml
41
+ - templates/controller_test.rb
42
+ - templates/openid_login_system.rb
43
+ - USAGE
44
+ - openid_login_generator.rb
45
+ test_files: []
46
+
47
+ rdoc_options: []
48
+
49
+ extra_rdoc_files: []
50
+
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ requirements: []
56
+
57
+ dependencies:
58
+ - !ruby/object:Gem::Dependency
59
+ name: ruby-openid
60
+ version_requirement:
61
+ version_requirements: !ruby/object:Gem::Version::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: 1.0.2
66
+ version: