moro-repim 0.1.1

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.
data/ChangeLog ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 / 2009-03-04
2
+
3
+ * initial release
4
+
data/README.rdoc ADDED
@@ -0,0 +1,30 @@
1
+
2
+ = repim
3
+
4
+
5
+ == Description
6
+
7
+ Relying Party in minutes.
8
+
9
+ == Installation
10
+
11
+ === Archive Installation
12
+
13
+ rake install
14
+
15
+ === Gem Installation
16
+
17
+ gem install moro-repim
18
+
19
+
20
+ == Features/Problems
21
+
22
+
23
+ == Synopsis
24
+
25
+
26
+ == Copyright
27
+
28
+ Author:: MOROHASHI Kyosuke <moronatural@gmail.com>
29
+ Copyright:: Copyright (c) 2009 MOROHASHI Kyosuke
30
+ License:: MIT
data/Rakefile ADDED
@@ -0,0 +1,184 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'fileutils'
9
+ require 'spec/rake/spectask'
10
+ require 'lib/repim'
11
+ include FileUtils
12
+
13
+ use_rubyforge = false
14
+ NAME = "repim"
15
+ AUTHOR = "MOROHASHI Kyosuke"
16
+ EMAIL = "moronatural@gmail.com"
17
+ DESCRIPTION = "Relying Party in minutes."
18
+
19
+ if use_rubyforge
20
+ require 'rake/contrib/rubyforgepublisher'
21
+ require 'rake/contrib/sshpublisher'
22
+ RUBYFORGE_PROJECT = "repim"
23
+ HOMEPAGE = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
24
+ else
25
+ HOMEPAGE = "http://github.com/moro/#{NAME}/"
26
+ end
27
+ BIN_FILES = %w( )
28
+
29
+ VERS = Repim::Version
30
+ REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
31
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
32
+ RDOC_OPTS = [
33
+ '--title', "#{NAME} documentation",
34
+ "--charset", "utf-8",
35
+ "--opname", "index.html",
36
+ "--line-numbers",
37
+ "--main", "README.rdoc",
38
+ "--inline-source",
39
+ ]
40
+
41
+ task :default => [:spec]
42
+ task :package => [:clean]
43
+
44
+ desc "Run all specs in spec directory"
45
+ Spec::Rake::SpecTask.new(:spec) do |t|
46
+ t.spec_opts = %w[--colour --format progress --loadby --reverse]
47
+ t.spec_files = FileList['spec/**/*_spec.rb']
48
+ end
49
+
50
+ namespace :spec do
51
+ desc "Run both plugin's and sample_app's"
52
+ task :all => %w[spec spec:sample_app]
53
+
54
+ desc "Run Sample app's tests"
55
+ task :sample_app do
56
+ begin
57
+ Dir.chdir("integration/sample-app") do
58
+ unless File.directory?("./vendor/plugins/open_id_authentication")
59
+ system(*%w[script/plugin install git://github.com/rails/open_id_authentication.git])
60
+ end
61
+ system("script/generate relying_party sessions")
62
+ system($0, "db:migrate")
63
+ system($0, "spec")
64
+ end
65
+ ensure
66
+ Rake::Task["spec:sample_app:clean"].invoke
67
+ end
68
+ end
69
+
70
+ namespace :sample_app do
71
+ desc "Clean Sample app's generated datas"
72
+ task :clean do
73
+ Dir.chdir("integration/sample-app") do
74
+ system("script/destroy relying_party sessions")
75
+ FileUtils.rm_f(["db/development.sqlite3", "db/test.sqlite3"])
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ spec = Gem::Specification.new do |s|
82
+ s.name = NAME
83
+ s.version = VERS
84
+ s.platform = Gem::Platform::RUBY
85
+ s.has_rdoc = true
86
+ s.extra_rdoc_files = ["README.rdoc", "ChangeLog"]
87
+ s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
88
+ s.summary = DESCRIPTION
89
+ s.description = DESCRIPTION
90
+ s.author = AUTHOR
91
+ s.email = EMAIL
92
+ s.homepage = HOMEPAGE
93
+ s.executables = BIN_FILES
94
+ s.rubyforge_project = RUBYFORGE_PROJECT if use_rubyforge
95
+ s.bindir = "bin"
96
+ s.require_path = "lib"
97
+ s.test_files = Dir["test/*_test.rb"]
98
+
99
+ #s.add_dependency('activesupport', '>=1.3.1')
100
+ #s.required_ruby_version = '>= 1.8.2'
101
+
102
+ s.files = %w(README.rdoc ChangeLog Rakefile) +
103
+ Dir.glob("{bin,doc,test,lib,templates,generators,extras,website,script}/**/*") +
104
+ Dir.glob("ext/**/*.{h,c,rb}") +
105
+ Dir.glob("examples/**/*.rb") +
106
+ Dir.glob("tools/*.rb") +
107
+ Dir.glob("rails/*.rb")
108
+
109
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
110
+ end
111
+
112
+ Rake::GemPackageTask.new(spec) do |p|
113
+ p.need_tar = true
114
+ p.gem_spec = spec
115
+ end
116
+
117
+ task :install do
118
+ name = "#{NAME}-#{VERS}.gem"
119
+ sh %{rake package}
120
+ sh %{gem install pkg/#{name}}
121
+ end
122
+
123
+ task :uninstall => [:clean] do
124
+ sh %{gem uninstall #{NAME}}
125
+ end
126
+
127
+ desc 'Show information about the gem.'
128
+ task :debug_gem do
129
+ puts spec.to_ruby
130
+ end
131
+
132
+ desc 'Update gem spec'
133
+ task :gemspec do
134
+ open("#{NAME}.gemspec", 'w').write spec.to_ruby
135
+ end
136
+
137
+
138
+ Rake::RDocTask.new do |rdoc|
139
+ rdoc.rdoc_dir = 'html'
140
+ rdoc.options += RDOC_OPTS
141
+ rdoc.template = "resh"
142
+ #rdoc.template = "#{ENV['template']}.rb" if ENV['template']
143
+ if ENV['DOC_FILES']
144
+ rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
145
+ else
146
+ rdoc.rdoc_files.include('README', 'ChangeLog')
147
+ rdoc.rdoc_files.include('lib/**/*.rb')
148
+ rdoc.rdoc_files.include('ext/**/*.c')
149
+ end
150
+ end
151
+
152
+ if use_rubyforge
153
+ desc "Publish to RubyForge"
154
+ task :rubyforge => [:rdoc, :package] do
155
+ require 'rubyforge'
156
+ Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'moro').upload
157
+ end
158
+
159
+ desc 'Package and upload the release to rubyforge.'
160
+ task :release => [:clean, :package] do |t|
161
+ v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
162
+ abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
163
+ pkg = "pkg/#{NAME}-#{VERS}"
164
+
165
+ require 'rubyforge'
166
+ rf = RubyForge.new.configure
167
+ puts "Logging in"
168
+ rf.login
169
+
170
+ c = rf.userconfig
171
+ # c["release_notes"] = description if description
172
+ # c["release_changes"] = changes if changes
173
+ c["preformatted"] = true
174
+
175
+ files = [
176
+ "#{pkg}.tgz",
177
+ "#{pkg}.gem"
178
+ ].compact
179
+
180
+ puts "Releasing #{NAME} v. #{VERS}"
181
+ rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
182
+ end
183
+ end
184
+
@@ -0,0 +1,114 @@
1
+ class RelyingPartyGenerator < Rails::Generator::NamedBase
2
+ def add_options!(opt)
3
+ opt.on("--skip-plugins-spec",
4
+ "Do'nt copy application_controller_spec.rb and #{plural_name}_controller_spec.rb, default is #{!using_rspec?}"){|v| options[:skip_sessions_spec] = true }
5
+ opt.on("--user-class=klass",
6
+ "Specify User class name defailt is [User]"){|v| opt[:user_klass] = "User" }
7
+ opt.on("--user-management=generation_type",
8
+ "'model' for generate (rspec_)model, 'singnup' for controller using Repim::Signup. default is 'signup'"){|v| options[:user_model_only] = (v == "model") }
9
+ opt.on("--openid-migration=migration_name",
10
+ "Specify openid migration name, default is 'open_id_authentication_tables'. If value is 'none' generate nothing.") do |v|
11
+ options[:openid_migration] = v
12
+ end
13
+ end
14
+
15
+ def manifest
16
+ controller_file_name = plural_name + "_controller"
17
+ controller_class_name = controller_file_name.camelize
18
+
19
+ record do |m|
20
+ m.file "sessions_controller.rb", "app/controllers/#{controller_file_name}.rb"
21
+ assign_session_routing(singular_name, m)
22
+
23
+ m.directory "app/views/layouts"
24
+ m.file "views/layouts/sessions.html.erb", "app/views/layouts/#{plural_name}.html.erb"
25
+
26
+ m.directory "app/views/#{plural_name}"
27
+ m.file "views/sessions/new.html.erb", "app/views/#{plural_name}/new.html.erb"
28
+
29
+ %w[public/images/openid-login.gif public/stylesheets/repim.css].each do |asset|
30
+ m.directory File.dirname(asset)
31
+ m.file asset, asset
32
+ end
33
+
34
+ unless options[:skip_sessions_spec]
35
+ m.directory "spec/controllers"
36
+ m.file "spec/application_controller_spec.rb", "spec/controllers/application_controller_spec.rb"
37
+
38
+ m.file "spec/sessions_controller_spec.rb", "spec/controllers/#{controller_file_name}_spec.rb"
39
+ m.file "spec/sessions_routing_spec.rb", "spec/controllers/#{plural_name}_routing_spec.rb"
40
+ end
41
+
42
+ generate_user_management(m, !options[:skip_sessions_spec]) unless options[:user_model_only]
43
+ m.dependency(care_rspec("model"), [user_klass_name, "identity_url:string", @args].flatten.compact)
44
+
45
+ # FIXME very veriy dirty
46
+ # "sleep 3" is for changing timestamp of 'create_user' or 'open_id_authentication_tables'
47
+ if options[:command] == :create
48
+ m.gsub_file(app_controller, /(^\s*helper\s.*?$)/mi) do |ms|
49
+ sleep 3
50
+ "#{ms}\n include Repim::Application"
51
+ end
52
+ else
53
+ m.gsub_file(app_controller, /(^\s*include Repim::Application\s*$)/mi){|m| "" }
54
+ end
55
+
56
+ unless options[:openid_migration] == "none"
57
+ name = options[:openid_migration] || "open_id_authentication_tables"
58
+ m.dependency("open_id_authentication_tables", [name])
59
+ end
60
+ end
61
+ end
62
+
63
+ private
64
+ def app_controller
65
+ %w[application_controller application].
66
+ map{|f| "app/controllers/#{f}.rb" }.
67
+ detect{|c| File.exists?(File.expand_path(c, RAILS_ROOT)) }
68
+ end
69
+
70
+ def care_rspec(base); using_rspec? ? "rspec_#{base}" : base end
71
+
72
+ def using_rspec?; File.directory?( File.expand_path("spec", RAILS_ROOT) ) end
73
+
74
+ def assign_session_routing(name, manifest)
75
+ sentinel = 'ActionController::Routing::Routes.draw do |map|'
76
+
77
+ logger.route "map.resource #{name}"
78
+ route = <<EOS
79
+
80
+ map.signin '/signin', :controller => 'sessions', :action => 'new'
81
+ map.signout '/signout', :controller => 'sessions', :action => 'destroy'
82
+ map.resource :session
83
+ EOS
84
+
85
+ unless options[:pretend]
86
+ if options[:command] == :create
87
+ manifest.gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
88
+ "#{match}#{route}"
89
+ end
90
+ else
91
+ manifest.gsub_file 'config/routes.rb', route, ''
92
+ end
93
+ end
94
+ end
95
+
96
+ def user_klass_name
97
+ options[:user_klass] || "User"
98
+ end
99
+ def generate_user_management(m, with_spec = true)
100
+ users = user_klass_name.pluralize.underscore
101
+ user_controller_name = users + "_controller"
102
+
103
+ m.route_resources users.to_sym
104
+ m.file("users_controller.rb", "app/controllers/#{user_controller_name}.rb")
105
+
106
+ m.directory "app/views/#{users}"
107
+ m.template "views/users/new.html.erb", "app/views/#{users}/new.html.erb", :assigns => {:user => user_klass_name.underscore, :users => users}
108
+
109
+ if with_spec
110
+ m.file "spec/users_controller_spec.rb", "spec/controllers/#{user_controller_name}_spec.rb"
111
+ m.file "spec/users_routing_spec.rb", "spec/controllers/#{users}_routing_spec.rb"
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,9 @@
1
+ div#login-or-signup input[name=openid_url] {
2
+ font-size: 16px;
3
+ width: 20em;
4
+ padding: 2px 2px 2px 20px;
5
+ background-image: url("../images/openid-login.gif");
6
+ background-repeat: no-repeat;
7
+ background-attachment: scroll;
8
+ background-position: 0 50%;
9
+ }
@@ -0,0 +1,4 @@
1
+ class SessionsController < ApplicationController
2
+ include OpenIdAuthentication
3
+ include Repim::RelyingParty
4
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe ApplicationController do
4
+ before :all do
5
+ ApplicationController.user_klass = mock("User-Klass")
6
+ end
7
+ describe "#logged in" do
8
+ before do
9
+ session[:user_id] = 12345
10
+ ApplicationController.user_klass.should_receive(:find_by_id).with(12345).and_return(@user = mock("user"))
11
+ end
12
+
13
+ it{ controller.should be_signed_in }
14
+ it{ controller.current_user.should == @user }
15
+ end
16
+ end
17
+
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe SessionsController do
4
+ before :all do
5
+ SessionsController.user_klass = mock("User-Klass")
6
+ end
7
+
8
+ #Delete this example and add some real ones
9
+ it "should use SessionsController" do
10
+ controller.should be_an_instance_of(SessionsController)
11
+ end
12
+
13
+ it "get new should be success" do
14
+ get :new
15
+ response.should be_success
16
+ end
17
+
18
+ describe "authentication success" do
19
+ before do
20
+ url = "---openid-url---"
21
+
22
+ @user = mock("user", :id => 12345)
23
+ SessionsController.user_klass.should_receive(:find_by_identity_url).with(url).and_return(@user)
24
+
25
+ result = mock("result")
26
+ result.should_receive(:successful?).and_return true
27
+
28
+ controller.should_receive(:root_path).and_return("/")
29
+ controller.should_receive(:authenticate_with_open_id).with(url, {}).and_yield(result,url, {})
30
+
31
+ post :create, :openid_url =>url
32
+ end
33
+
34
+ it{ response.should redirect_to("/") }
35
+ it{ session[:user_id].should == 12345 }
36
+ it{ controller.current_user.should == @user }
37
+ it{ controller.should be_signed_in }
38
+ end
39
+
40
+ describe "authentication success but user not found then render users/new" do
41
+ before do
42
+ url = "---openid-url---"
43
+ SessionsController.user_klass.should_receive(:find_by_identity_url).with(url).and_return(nil)
44
+ SessionsController.user_klass.should_receive(:new).with({}).and_return(@user = mock("user"))
45
+
46
+ result = mock("result")
47
+ result.should_receive(:successful?).and_return true
48
+
49
+ controller.should_receive(:authenticate_with_open_id).with(url, {}).and_yield(result,url, {})
50
+
51
+ post :create, :openid_url =>url
52
+ end
53
+
54
+ it{ response.should render_template("users/new") }
55
+ it{ controller.current_user.should be_nil }
56
+ it{ controller.should_not be_signed_in }
57
+ it{ assigns[:user].should == @user }
58
+ end
59
+
60
+ describe "authentication failed" do
61
+ before do
62
+ url = "---openid-url---"
63
+
64
+ result = mock("result")
65
+ result.should_receive(:successful?).and_return false
66
+
67
+ controller.should_receive(:authenticate_with_open_id).with(url, {}).and_yield(result,url, {})
68
+
69
+ post :create, :openid_url =>url
70
+ end
71
+
72
+ it{ response.should render_template("sessions/new") }
73
+ it{ assigns[:user].should be_nil }
74
+ it{ controller.current_user.should be_nil }
75
+ it{ session[:user_id].should be_nil }
76
+ it{ flash[:error].should_not be_blank }
77
+ end
78
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe SessionsController do
4
+ describe "route generation" do
5
+ it "should map #new -> /signin" do
6
+ route_for(:controller => "sessions", :action => "new").should == "/signin"
7
+ end
8
+
9
+ it "should map #destroy -> /signout" do
10
+ route_for(:controller => "sessions", :action => "destroy").should == "/signout"
11
+ end
12
+
13
+ it "should map #show" do
14
+ route_for(:controller => "sessions", :action => "show").should == "/session"
15
+ end
16
+
17
+ it "should map #edit" do
18
+ route_for(:controller => "sessions", :action => "edit").should == "/session/edit"
19
+ end
20
+
21
+ it "should map #update" do
22
+ route_for(:controller => "sessions", :action => "update").should == "/session"
23
+ end
24
+ end
25
+
26
+ describe "route recognition" do
27
+ it "should generate params for #new" do
28
+ params_from(:get, "/signin").should == {:controller => "sessions", :action => "new"}
29
+ end
30
+
31
+ it "should generate params for #new" do
32
+ params_from(:get, "/session/new").should == {:controller => "sessions", :action => "new"}
33
+ end
34
+
35
+ it "should generate params for #create" do
36
+ params_from(:post, "/session").should == {:controller => "sessions", :action => "create"}
37
+ end
38
+
39
+ it "should generate params for #show (JS)" do
40
+ params_from(:get, "/session.js").should == {:controller => "sessions", :action => "show", :format => "js"}
41
+ end
42
+
43
+ it "should generate params for #destroy" do
44
+ params_from(:get, "/signout").should == {:controller => "sessions", :action => "destroy"}
45
+ end
46
+
47
+ it "should generate params for #destroy" do
48
+ params_from(:delete, "/session").should == {:controller => "sessions", :action => "destroy"}
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,98 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe UsersController do
4
+ def mock_user(stubs={})
5
+ @mock_user ||= mock_model(User, stubs)
6
+ end
7
+
8
+ describe "responding to GET index" do
9
+ before do
10
+ controller.stub!(:authenticate).and_return true
11
+ end
12
+ it "should expose all users as @users" do
13
+ User.should_receive(:find).with(:all).and_return([mock_user])
14
+ get :index
15
+ assigns[:users].should == [mock_user]
16
+ end
17
+
18
+ describe "with mime type of xml" do
19
+ it "should render all users as xml" do
20
+ request.env["HTTP_ACCEPT"] = "application/xml"
21
+ User.should_receive(:find).with(:all).and_return(users = mock("Array of Users"))
22
+ users.should_receive(:to_xml).and_return("generated XML")
23
+ get :index
24
+ response.body.should == "generated XML"
25
+ end
26
+ end
27
+ end
28
+
29
+ describe "responding to GET show" do
30
+ before do
31
+ controller.stub!(:authenticate).and_return true
32
+ end
33
+
34
+ it "should expose the requested user as @user" do
35
+ User.should_receive(:find).with("37").and_return(mock_user)
36
+ get :show, :id => "37"
37
+ assigns[:user].should equal(mock_user)
38
+ end
39
+
40
+ describe "with mime type of xml" do
41
+ it "should render the requested user as xml" do
42
+ request.env["HTTP_ACCEPT"] = "application/xml"
43
+ User.should_receive(:find).with("37").and_return(mock_user)
44
+ mock_user.should_receive(:to_xml).and_return("generated XML")
45
+ get :show, :id => "37"
46
+ response.body.should == "generated XML"
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "responding to POST create" do
52
+ describe "with valid params" do
53
+ before do
54
+ User.should_receive(:new).with({'these' => 'params'}).and_return(mock_user(:save => true))
55
+
56
+ @identity_url = session[:identity_url] = "http://moro.openid.example.com/"
57
+ mock_user.should_receive(:identity_url=).with(@identity_url)
58
+
59
+ post :create, :user => {:these => 'params'}
60
+ end
61
+
62
+ it "should expose a newly created user as @user" do
63
+ assigns(:user).should equal(mock_user)
64
+ end
65
+
66
+ it "session[:identity_url] should be removed" do
67
+ session[:identity_url].should be_blank
68
+ end
69
+
70
+ it "should redirect to the created user" do
71
+ response.should redirect_to(user_url(mock_user))
72
+ end
73
+ end
74
+
75
+ describe "with invalid params" do
76
+ before do
77
+ User.stub!(:new).with({'these' => 'params'}).and_return(mock_user(:save => false))
78
+
79
+ @identity_url = session[:identity_url] = "http://moro.openid.example.com/"
80
+ mock_user.should_receive(:identity_url=).with(@identity_url)
81
+
82
+ post :create, :user => {:these => 'params'}
83
+ end
84
+
85
+ it "should expose a newly created but unsaved user as @user" do
86
+ assigns(:user).should equal(mock_user)
87
+ end
88
+
89
+ it "should re-render the 'new' template" do
90
+ response.should render_template('new')
91
+ end
92
+
93
+ it "session[:identity_url] should == original" do
94
+ session[:identity_url].should == @identity_url
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe UsersController do
4
+ describe "route generation" do
5
+ it "should map #index" do
6
+ route_for(:controller => "users", :action => "index").should == "/users"
7
+ end
8
+
9
+ it "should map #new" do
10
+ route_for(:controller => "users", :action => "new").should == "/users/new"
11
+ end
12
+
13
+ it "should map #show" do
14
+ route_for(:controller => "users", :action => "show", :id => 1).should == "/users/1"
15
+ end
16
+
17
+ it "should map #edit" do
18
+ route_for(:controller => "users", :action => "edit", :id => 1).should == "/users/1/edit"
19
+ end
20
+
21
+ it "should map #update" do
22
+ route_for(:controller => "users", :action => "update", :id => 1).should == "/users/1"
23
+ end
24
+
25
+ it "should map #destroy" do
26
+ route_for(:controller => "users", :action => "destroy", :id => 1).should == "/users/1"
27
+ end
28
+ end
29
+
30
+ describe "route recognition" do
31
+ it "should generate params for #index" do
32
+ params_from(:get, "/users").should == {:controller => "users", :action => "index"}
33
+ end
34
+
35
+ it "should generate params for #new" do
36
+ params_from(:get, "/users/new").should == {:controller => "users", :action => "new"}
37
+ end
38
+
39
+ it "should generate params for #create" do
40
+ params_from(:post, "/users").should == {:controller => "users", :action => "create"}
41
+ end
42
+
43
+ it "should generate params for #show" do
44
+ params_from(:get, "/users/1").should == {:controller => "users", :action => "show", :id => "1"}
45
+ end
46
+
47
+ it "should generate params for #edit" do
48
+ params_from(:get, "/users/1/edit").should == {:controller => "users", :action => "edit", :id => "1"}
49
+ end
50
+
51
+ it "should generate params for #update" do
52
+ params_from(:put, "/users/1").should == {:controller => "users", :action => "update", :id => "1"}
53
+ end
54
+
55
+ it "should generate params for #destroy" do
56
+ params_from(:delete, "/users/1").should == {:controller => "users", :action => "destroy", :id => "1"}
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,21 @@
1
+ class UsersController < ApplicationController
2
+ include Repim::Signup
3
+
4
+ def index
5
+ @users = User.find(:all)
6
+
7
+ respond_to do |format|
8
+ format.html
9
+ format.xml { render :xml => @users }
10
+ end
11
+ end
12
+
13
+ def show
14
+ @user = User.find(params[:id])
15
+
16
+ respond_to do |format|
17
+ format.html
18
+ format.xml { render :xml => @user }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ <html>
2
+ <head>
3
+ <%= stylesheet_link_tag "repim" %>
4
+ <%= javascript_include_tag :defaults %>
5
+ </head>
6
+ <body>
7
+ <div id="header">
8
+ <% if signed_in? -%>
9
+ <span class="current-user"> Logged in as <%= current_user.identity_url %> </span>
10
+ <% else -%>
11
+ <span class="sign-in"><%= link_to "Sign in", new_session_path %></span>
12
+ <% end -%>
13
+ </div>
14
+ <div id="content">
15
+ <%= yield %>
16
+ </div>
17
+ </body>
18
+ </html>
@@ -0,0 +1,13 @@
1
+ <h1>Welcome</h1>
2
+
3
+ <div id="login-or-signup">
4
+ <p> Please login or signup using OpenID.</p>
5
+
6
+ <% form_tag session_path do -%>
7
+ <label for="openid_url">OpenID URL</label>
8
+ <%= text_field_tag "openid_url", params[:openid_url] %>
9
+
10
+ <%= submit_tag "Login or Signup" %>
11
+ <% end %>
12
+ </div>
13
+
@@ -0,0 +1,23 @@
1
+ <h1>Sign up</h1>
2
+
3
+ <%% form_for(@<%= user %>) do |f| %>
4
+ <%%= f.error_messages %>
5
+
6
+ <table>
7
+ <% for attribute in attributes -%>
8
+ <tr>
9
+ <th> <%%= f.label :<%= attribute.name %> %></th>
10
+ <td><%%= f.<%= attribute.field_type %> :<%= attribute.name %> %></td>
11
+ </tr>
12
+ <% end -%>
13
+ <tr>
14
+ <th>OpenID URL</th>
15
+ <td><%%=h session[:identity_url] %></td>
16
+ </tr>
17
+ </table>
18
+ <p>
19
+ <%%= f.submit 'Create' %>
20
+ </p>
21
+ <%% end %>
22
+
23
+ <%%= link_to 'Back', <%= users %>_path %>
@@ -0,0 +1,54 @@
1
+ module Repim
2
+ module Application
3
+ def self.included(base)
4
+ base.cattr_accessor :user_klass
5
+ base.cattr_accessor :login_template
6
+ base.user_klass = (User rescue nil) # assign nil when LoadError and/or ConstMissing
7
+ base.login_template = "sessions/new"
8
+
9
+ [:current_user, :signed_in?, :logged_in?].each do |method|
10
+ base.helper_method method
11
+ base.hide_action method
12
+ end
13
+ end
14
+
15
+ def signed_in?; !!current_user ; end
16
+ alias logged_in? signed_in?
17
+
18
+ def current_user
19
+ return nil if @__current_user__ == false
20
+ return @__current_user__ if @__current_user__
21
+ @__current_user__ ||= (user_from_session || false)
22
+ current_user # call again
23
+ end
24
+
25
+ private
26
+ def authenticate
27
+ signed_in? || access_denied("Login required.")
28
+ end
29
+ alias login_required authenticate
30
+
31
+ def access_denied(message = nil)
32
+ store_location
33
+ flash[:error] = message if message
34
+ render :template => login_template, :status => :unauthorized
35
+ end
36
+
37
+ def store_location
38
+ session[:return_to] = request.request_uri if request.get?
39
+ end
40
+
41
+ def current_user=(user)
42
+ @__current_user__ = user
43
+ session[:user_id] = user.id
44
+ end
45
+
46
+ def user_from_session
47
+ session[:user_id] && user_klass.find_by_id(session[:user_id])
48
+ end
49
+
50
+ def redirect_back_or(default)
51
+ redirect_to(session[:return_to] || default)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,32 @@
1
+ require 'active_support'
2
+
3
+ module Repim
4
+ class AxAttributeAdapter
5
+ attr_reader :rule, :necessity
6
+
7
+ # TODO refactor
8
+ def initialize(prefixes, propaties)
9
+ @rule = {}
10
+ @necessity = :optional
11
+ propaties.each do |model_attr, property|
12
+ @rule[model_attr] = prefixes.map{|px| px + property }
13
+ end
14
+ end
15
+
16
+ def keys
17
+ rule.values.flatten
18
+ end
19
+
20
+ def required!
21
+ @necessity = :required
22
+ end
23
+
24
+ def adapt(fetched)
25
+ returning({}) do |res|
26
+ rule.each do |k, vs|
27
+ fetched.each{|fk, (fv,_)| res[k] = fv if !fv.blank? && vs.include?(fk) }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,90 @@
1
+ require 'repim/ax_attributes_adapter'
2
+
3
+ module Repim
4
+ module RelyingParty
5
+ def self.included(base)
6
+ base.cattr_accessor :attribute_adapter
7
+ base.cattr_accessor :signup_template
8
+
9
+ base.signup_template = "users/new"
10
+
11
+ base.extend(ClassMethods)
12
+ end
13
+
14
+ module ClassMethods
15
+ def use_attribute_exchange(prefixes, propaties)
16
+ self.attribute_adapter = AxAttributeAdapter.new(prefixes, propaties)
17
+ end
18
+ end
19
+
20
+ # render new.rhtml
21
+ def new
22
+ end
23
+
24
+ def create
25
+ options = {}
26
+ options[attribute_adapter.necessity] = attribute_adapter.keys if attribute_adapter
27
+
28
+ begin
29
+ authenticate_with_open_id(params[:openid_url], options) do |result, identity_url, personal_data|
30
+ if result.successful?
31
+ authenticate_success(identity_url, personal_data)
32
+ else
33
+ authenticate_failure(params.merge(:openid_url=>identity_url))
34
+ end
35
+ end
36
+ rescue OpenID::OpenIDError => why
37
+ logger.debug{ [why.message, why.backtrace].flatten.join("\n\t") }
38
+ authenticate_failure(params)
39
+ end
40
+ end
41
+
42
+ def destroy
43
+ session[:user_id] = nil
44
+ reset_session
45
+ flash[:notice] = "You have been logged out."
46
+
47
+ redirect_back_or(after_logout_path)
48
+ end
49
+
50
+ private
51
+ def authenticate_success(identity_url, personal_data = {})
52
+ if user = user_klass.find_by_identity_url(identity_url)
53
+ login_successfully(user, personal_data)
54
+ redirect_back_or(after_login_path)
55
+ else
56
+ signup(identity_url, personal_data)
57
+ render(:template => signup_template)
58
+ end
59
+ end
60
+
61
+ def login_successfully(user, personal_data)
62
+ reset_session
63
+ self.current_user = user
64
+ flash[:notice] ||= "Logged in successfully"
65
+ end
66
+
67
+ def signup(identity_url, ax = {})
68
+ session[:identity_url] = identity_url
69
+ @user = user_klass.new( attribute_adapter ? attribute_adapter.adapt(ax) : {} )
70
+ end
71
+
72
+ # log login faulure. and re-render sessions/new
73
+ def authenticate_failure(assigns = params)
74
+ flash[:error] = "Couldn't log you in as '#{assigns[:openid_url] || assigns["openid.claimed_id"]}'"
75
+ logger.warn "Failed login for '#{assigns[:openid_url]}' from #{request.remote_ip} at #{Time.now.utc}"
76
+
77
+ @openid_url = assigns[:openid_url]
78
+
79
+ render :action => 'new'
80
+ end
81
+
82
+ def after_login_path; root_path ; end
83
+ def after_logout_path; login_path ; end
84
+
85
+ def method_missing(m, *args, &b)
86
+ return [request.protocol, request.host_with_port, "/"].join if m.to_sym == :root_url
87
+ super
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,28 @@
1
+ module Repim
2
+ module Signup
3
+ def self.included(base)
4
+ base.before_filter :authenticate, :except => [:create]
5
+ end
6
+
7
+ def create
8
+ @user = User.new(params[:user])
9
+ @user.identity_url = session[:identity_url]
10
+
11
+ respond_to do |format|
12
+ if @user.save
13
+ flash[:notice] = 'User was successfully created.'
14
+ reset_session
15
+ self.current_user = @user
16
+ format.html { redirect_to(after_create_url) }
17
+ else
18
+ format.html { render :action => "new" }
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+ def after_create_url
25
+ current_user
26
+ end
27
+ end
28
+ end
data/lib/repim.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Repim
2
+ Version = '0.1.1'
3
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,5 @@
1
+ # add hook to activate in rails app.
2
+ #
3
+ # example.
4
+ # ActiveRecrod::Base.send(:include, Repim)
5
+
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moro-repim
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - MOROHASHI Kyosuke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-10 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Relying Party in minutes.
17
+ email: moronatural@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - ChangeLog
25
+ files:
26
+ - README.rdoc
27
+ - ChangeLog
28
+ - Rakefile
29
+ - lib/repim
30
+ - lib/repim/application.rb
31
+ - lib/repim/ax_attributes_adapter.rb
32
+ - lib/repim/relying_party.rb
33
+ - lib/repim/signup.rb
34
+ - lib/repim.rb
35
+ - generators/relying_party
36
+ - generators/relying_party/relying_party_generator.rb
37
+ - generators/relying_party/templates
38
+ - generators/relying_party/templates/public
39
+ - generators/relying_party/templates/public/images
40
+ - generators/relying_party/templates/public/images/openid-login.gif
41
+ - generators/relying_party/templates/public/stylesheets
42
+ - generators/relying_party/templates/public/stylesheets/repim.css
43
+ - generators/relying_party/templates/sessions_controller.rb
44
+ - generators/relying_party/templates/spec
45
+ - generators/relying_party/templates/spec/application_controller_spec.rb
46
+ - generators/relying_party/templates/spec/sessions_controller_spec.rb
47
+ - generators/relying_party/templates/spec/sessions_routing_spec.rb
48
+ - generators/relying_party/templates/spec/users_controller_spec.rb
49
+ - generators/relying_party/templates/spec/users_routing_spec.rb
50
+ - generators/relying_party/templates/users_controller.rb
51
+ - generators/relying_party/templates/views
52
+ - generators/relying_party/templates/views/layouts
53
+ - generators/relying_party/templates/views/layouts/sessions.html.erb
54
+ - generators/relying_party/templates/views/sessions
55
+ - generators/relying_party/templates/views/sessions/new.html.erb
56
+ - generators/relying_party/templates/views/users
57
+ - generators/relying_party/templates/views/users/new.html.erb
58
+ - rails/init.rb
59
+ has_rdoc: false
60
+ homepage: http://github.com/moro/repim/
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --title
64
+ - repim documentation
65
+ - --charset
66
+ - utf-8
67
+ - --opname
68
+ - index.html
69
+ - --line-numbers
70
+ - --main
71
+ - README.rdoc
72
+ - --inline-source
73
+ - --exclude
74
+ - ^(examples|extras)/
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ version:
89
+ requirements: []
90
+
91
+ rubyforge_project:
92
+ rubygems_version: 1.2.0
93
+ signing_key:
94
+ specification_version: 2
95
+ summary: Relying Party in minutes.
96
+ test_files: []
97
+