mc-openid 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mc-openid.gemspec
4
+ gemspec
5
+
6
+ gem "ruby-openid-apps-discovery", :require => 'gapps_openid'
7
+ gem "ruby-openid"
8
+
9
+ #test
10
+ gem 'rspec'
11
+ gem 'activesupport'
12
+ gem 'mocha'
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mc-openid (0.0.1.pre)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activesupport (3.0.3)
10
+ diff-lcs (1.1.2)
11
+ mocha (0.9.10)
12
+ rake
13
+ rake (0.8.7)
14
+ rspec (2.4.0)
15
+ rspec-core (~> 2.4.0)
16
+ rspec-expectations (~> 2.4.0)
17
+ rspec-mocks (~> 2.4.0)
18
+ rspec-core (2.4.0)
19
+ rspec-expectations (2.4.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.4.0)
22
+ ruby-openid (2.1.8)
23
+ ruby-openid-apps-discovery (1.2.0)
24
+ ruby-openid (>= 2.1.7)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ activesupport
31
+ mc-openid!
32
+ mocha
33
+ rspec
34
+ ruby-openid
35
+ ruby-openid-apps-discovery
data/README ADDED
File without changes
@@ -0,0 +1,23 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ ##TEST UNIT
5
+ require 'rake'
6
+ require 'rake/testtask'
7
+
8
+
9
+ desc 'Test the open_id_authentication plugin.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib/'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = false
14
+ end
15
+
16
+ ###RSPEC
17
+ require 'rspec/core/rake_task'
18
+
19
+ RSpec::Core::RakeTask.new('spec')
20
+
21
+ desc 'Default: run unit tests.'
22
+ task :default => [:test, :spec]
23
+
@@ -0,0 +1,27 @@
1
+ require 'open_id_authentication/lib/open_id_authentication'
2
+
3
+ module ModCloth
4
+ module OpenID
5
+ include ::OpenIdAuthentication
6
+
7
+ protected
8
+
9
+ def check_openid
10
+ unless session && session[:user_email]
11
+ open_id_authentication("https://www.google.com/accounts/o8/site-xrds?hd=modcloth.com")
12
+ else
13
+ session
14
+ end
15
+ end
16
+
17
+ def open_id_authentication(openid_url)
18
+ authenticate_with_open_id(openid_url, [{:name => :email, :uri => 'http://axschema.org/contact/email'}]) do |result, identity_url, registration|
19
+ if result.successful?
20
+ session[:user_email] = registration.data['http://axschema.org/contact/email'].first
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,5 @@
1
+ module ModCloth
2
+ module OpenID
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,175 @@
1
+ require 'uri'
2
+ require 'openid/extensions/sreg'
3
+ require 'openid/extensions/ax'
4
+ require 'openid/store/filesystem'
5
+
6
+ module OpenIdAuthentication
7
+ OPEN_ID_AUTHENTICATION_DIR = "tmp/openids"
8
+ @@logger = Logger.new(STDERR)
9
+
10
+ def self.store
11
+ @@store
12
+ end
13
+
14
+ def self.store=(value)
15
+ @@store = value
16
+ end
17
+
18
+ self.store = :file
19
+
20
+ def store
21
+ OpenIdAuthentication.store
22
+ end
23
+
24
+ class InvalidOpenId < StandardError
25
+ end
26
+
27
+ class Result
28
+ ERROR_MESSAGES = {
29
+ :missing => "Sorry, the OpenID server couldn't be found",
30
+ :canceled => "OpenID verification was canceled",
31
+ :failed => "OpenID verification failed",
32
+ :setup_needed => "OpenID verification needs setup"
33
+ }
34
+
35
+ def self.[](code)
36
+ new(code)
37
+ end
38
+
39
+ def initialize(code)
40
+ @code = code
41
+ end
42
+
43
+ def ===(code)
44
+ if code == :unsuccessful && unsuccessful?
45
+ true
46
+ else
47
+ @code == code
48
+ end
49
+ end
50
+
51
+ ERROR_MESSAGES.keys.each { |state| define_method("#{state}?") { @code == state } }
52
+
53
+ def successful?
54
+ @code == :successful
55
+ end
56
+
57
+ def unsuccessful?
58
+ ERROR_MESSAGES.keys.include?(@code)
59
+ end
60
+
61
+ def message
62
+ ERROR_MESSAGES[@code]
63
+ end
64
+ end
65
+
66
+ def self.normalize_url(url)
67
+ uri = URI.parse(url.to_s.strip)
68
+ uri = URI.parse("http://#{uri}") unless uri.scheme
69
+ uri.scheme = uri.scheme.downcase # URI should do this
70
+ uri.normalize.to_s
71
+ rescue URI::InvalidURIError
72
+ raise InvalidOpenId.new("#{url} is not an OpenID URL")
73
+ end
74
+
75
+ protected
76
+ def normalize_url(url)
77
+ OpenIdAuthentication.normalize_url(url)
78
+ end
79
+
80
+ # The parameter name of "openid_url" is used rather than the Rails convention "open_id_url"
81
+ # because that's what the specification dictates in order to get browser auto-complete working across sites
82
+ def using_open_id?(identity_url = params[:openid_url]) #:doc:
83
+ !identity_url.blank? || params[:open_id_complete]
84
+ end
85
+
86
+ def authenticate_with_open_id(identity_url = params[:openid_url], options = {}, &block) #:doc:
87
+ if params[:open_id_complete].nil?
88
+ begin_open_id_authentication(normalize_url(identity_url), options, &block)
89
+ else
90
+ complete_open_id_authentication(&block)
91
+ end
92
+ end
93
+
94
+ private
95
+ def begin_open_id_authentication(identity_url, options = {})
96
+ return_to = options.delete(:return_to)
97
+ open_id_request = open_id_consumer.begin(identity_url)
98
+ # use AX instead of SREG
99
+ # add_simple_registration_fields(open_id_request, options)
100
+ add_attribute_exchange_fields(open_id_request, options)
101
+ redirect_to(open_id_redirect_url(open_id_request, return_to))
102
+ rescue OpenID::OpenIDError, Timeout::Error => e
103
+ @@logger.error("[OPENID] #{e}")
104
+ yield Result[:missing], identity_url, nil
105
+ end
106
+
107
+ def complete_open_id_authentication
108
+ params_with_path = params.reject { |key, value| request.path_parameters[key.to_sym] }
109
+ params_with_path.delete(:format)
110
+ open_id_response = timeout_protection_from_identity_server { open_id_consumer.complete(params_with_path, requested_url) }
111
+ identity_url = normalize_url(open_id_response.endpoint.claimed_id) if open_id_response.endpoint.claimed_id
112
+ case open_id_response.status
113
+ when OpenID::Consumer::SUCCESS
114
+ # we need to use AX that's why I commented out this line(it looks like google open id is not recognizing the SREG params)
115
+ #yield Result[:successful], identity_url, OpenID::SReg::Response.from_success_response(open_id_response)
116
+ yield Result[:successful], identity_url, OpenID::AX::FetchResponse.from_success_response(open_id_response)
117
+ when OpenID::Consumer::CANCEL
118
+ yield Result[:canceled], identity_url, nil
119
+ when OpenID::Consumer::FAILURE
120
+ yield Result[:failed], identity_url, nil
121
+ when OpenID::Consumer::SETUP_NEEDED
122
+ yield Result[:setup_needed], open_id_response.setup_url, nil
123
+ end
124
+ end
125
+
126
+ def open_id_consumer
127
+ OpenID::Consumer.new(session, open_id_store)
128
+ end
129
+
130
+ def open_id_store
131
+ OpenID::Store::Filesystem.new(OPEN_ID_AUTHENTICATION_DIR)
132
+ end
133
+
134
+ # this method is to use AX(Attribute Exchange) instead of SRGE(Simple Registration) that comes with this plugin.
135
+ def add_attribute_exchange_fields(open_id_request, fields)
136
+ ax_request = OpenID::AX::FetchRequest.new
137
+ fields.each {|field| ax_request.add(OpenID::AX::AttrInfo.new(field[:uri],field[:name].to_s,true)) }
138
+ open_id_request.add_extension(ax_request)
139
+ end
140
+
141
+ def add_simple_registration_fields(open_id_request, fields)
142
+ sreg_request = OpenID::SReg::Request.new
143
+ sreg_request.request_fields(Array(fields[:required]).map(&:to_s), true) if fields[:required]
144
+ sreg_request.request_fields(Array(fields[:optional]).map(&:to_s), false) if fields[:optional]
145
+ sreg_request.policy_url = fields[:policy_url] if fields[:policy_url]
146
+ open_id_request.add_extension(sreg_request)
147
+ end
148
+
149
+ def open_id_redirect_url(open_id_request, return_to = nil)
150
+ open_id_request.return_to_args['open_id_complete'] = '1'
151
+ open_id_request.redirect_url(realm, return_to || requested_url)
152
+ end
153
+
154
+ def requested_url
155
+ "#{request.protocol + request.host_with_port + request.path}"
156
+ end
157
+
158
+ def realm
159
+ respond_to?(:root_url) ? root_url : "#{request.protocol + request.host_with_port}"
160
+ end
161
+
162
+ def timeout_protection_from_identity_server
163
+ yield
164
+ rescue Timeout::Error
165
+ Class.new do
166
+ def status
167
+ OpenID::FAILURE
168
+ end
169
+
170
+ def msg
171
+ "Identity server timed out"
172
+ end
173
+ end.new
174
+ end
175
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mc-openid/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mc-openid"
7
+ s.version = ModCloth::OpenID::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Luis Flores, Juan Esparza, Rudy Sombillo, Sergio Figueroa"]
10
+ s.email = ["l.flores@modcloth, juan.esparza@crowdint.com, r.sombillo@modcloth.com, sergio.figueroa@crowdint.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{summary}
13
+ s.description = %q{description}
14
+
15
+ s.rubyforge_project = "mc-openid"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features,lib/open_id_authentication/test}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ class Fake
4
+ include ModCloth::OpenID
5
+
6
+ def params()
7
+ {}
8
+ end
9
+
10
+ end
11
+
12
+ describe ModCloth::OpenID do
13
+ include OpenIdAuthentication
14
+
15
+ before(:each) do
16
+ @controller = Fake.new
17
+ end
18
+
19
+ describe "authentication" do
20
+ it "return successful if open id authentication passes" do
21
+ open_id_consumer = mock()
22
+ @controller.stub!(:session).and_return({})
23
+ @controller.stub!(:open_id_consumer).and_return(open_id_consumer)
24
+ @controller.stub!(:begin_open_id_authentication).and_return({:user_email => "test@modcloth.com"})
25
+ @controller.check_openid.should == {:user_email => "test@modcloth.com"}
26
+ end
27
+
28
+ it "return successful if exist a session" do
29
+ session = {:user_email =>"test@modcloth.com"}
30
+ @controller.stub!(:session).and_return(session)
31
+ @controller.check_openid.should == session
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'mc-openid'
5
+
6
+ RSpec.configure do |config|
7
+
8
+ end
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class NormalizeTest < Test::Unit::TestCase
4
+ include OpenIdAuthentication
5
+
6
+ NORMALIZATIONS = {
7
+ "openid.aol.com/nextangler" => "http://openid.aol.com/nextangler",
8
+ "http://openid.aol.com/nextangler" => "http://openid.aol.com/nextangler",
9
+ "https://openid.aol.com/nextangler" => "https://openid.aol.com/nextangler",
10
+ "HTTP://OPENID.AOL.COM/NEXTANGLER" => "http://openid.aol.com/NEXTANGLER",
11
+ "HTTPS://OPENID.AOL.COM/NEXTANGLER" => "https://openid.aol.com/NEXTANGLER",
12
+ "loudthinking.com" => "http://loudthinking.com/",
13
+ "http://loudthinking.com" => "http://loudthinking.com/",
14
+ "http://loudthinking.com:80" => "http://loudthinking.com/",
15
+ "https://loudthinking.com:443" => "https://loudthinking.com/",
16
+ "http://loudthinking.com:8080" => "http://loudthinking.com:8080/",
17
+ "techno-weenie.net" => "http://techno-weenie.net/",
18
+ "http://techno-weenie.net" => "http://techno-weenie.net/",
19
+ "http://techno-weenie.net " => "http://techno-weenie.net/"
20
+ }
21
+
22
+ def test_normalizations
23
+ NORMALIZATIONS.each do |from, to|
24
+ assert_equal to, normalize_url(from)
25
+ end
26
+ end
27
+
28
+ def test_broken_open_id
29
+ assert_raises(InvalidOpenId) { normalize_url(nil) }
30
+ assert_raises(InvalidOpenId) { normalize_url("=name") }
31
+ end
32
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class OpenIdAuthenticationTest < Test::Unit::TestCase
4
+ def setup
5
+ @controller = Class.new do
6
+ include OpenIdAuthentication
7
+ def params() {} end
8
+ end.new
9
+ end
10
+
11
+ def test_authentication_should_fail_when_the_identity_server_is_missing
12
+ open_id_consumer = mock()
13
+ open_id_consumer.expects(:begin).raises(OpenID::OpenIDError)
14
+ @controller.stubs(:open_id_consumer).returns(open_id_consumer)
15
+
16
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url|
17
+ assert result.missing?
18
+ assert_equal "Sorry, the OpenID server couldn't be found", result.message
19
+ end
20
+ end
21
+
22
+ def test_authentication_should_fail_when_the_identity_server_times_out
23
+ open_id_consumer = mock()
24
+ open_id_consumer.expects(:begin).raises(Timeout::Error, "Identity Server took too long.")
25
+ @controller.stubs(:open_id_consumer).returns(open_id_consumer)
26
+
27
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com") do |result, identity_url|
28
+ assert result.missing?
29
+ assert_equal "Sorry, the OpenID server couldn't be found", result.message
30
+ end
31
+ end
32
+
33
+ def test_authentication_should_begin_when_the_identity_server_is_present
34
+ @controller.stubs(:open_id_consumer).returns(stub(:begin => true))
35
+ @controller.expects(:begin_open_id_authentication)
36
+ @controller.send(:authenticate_with_open_id, "http://someone.example.com")
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class StatusTest < Test::Unit::TestCase
4
+ include OpenIdAuthentication
5
+
6
+ def test_all_error_codes_should_compare_to_unsuccessful
7
+ assert Result[:missing] === :unsuccessful
8
+ assert Result[:missing] === :missing
9
+ end
10
+
11
+ def test_state_conditional
12
+ assert Result[:missing].missing?
13
+ assert Result[:missing].unsuccessful?
14
+ assert !Result[:missing].successful?
15
+
16
+ assert Result[:successful].successful?
17
+ assert !Result[:successful].unsuccessful?
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+
4
+ gem 'activesupport'
5
+ require 'active_support'
6
+
7
+ gem 'mocha'
8
+ require 'mocha'
9
+
10
+ gem 'ruby-openid'
11
+ require 'openid'
12
+
13
+ RAILS_ROOT = File.dirname(__FILE__) unless defined? RAILS_ROOT
14
+ require File.dirname(__FILE__) + "/../lib/open_id_authentication/lib/open_id_authentication"
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mc-openid
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Luis Flores, Juan Esparza, Rudy Sombillo, Sergio Figueroa
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-24 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: description
23
+ email:
24
+ - l.flores@modcloth, juan.esparza@crowdint.com, r.sombillo@modcloth.com, sergio.figueroa@crowdint.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - Gemfile.lock
35
+ - README
36
+ - Rakefile
37
+ - lib/mc-openid.rb
38
+ - lib/mc-openid/version.rb
39
+ - lib/open_id_authentication/lib/open_id_authentication.rb
40
+ - mc-openid.gemspec
41
+ - spec/mc-openid_spec.rb
42
+ - spec/spec_helper.rb
43
+ - test/normalize_test.rb
44
+ - test/open_id_authentication_test.rb
45
+ - test/status_test.rb
46
+ - test/test_helper.rb
47
+ has_rdoc: true
48
+ homepage: ""
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ requirements: []
75
+
76
+ rubyforge_project: mc-openid
77
+ rubygems_version: 1.3.7
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: summary
81
+ test_files:
82
+ - spec/mc-openid_spec.rb
83
+ - spec/spec_helper.rb
84
+ - test/normalize_test.rb
85
+ - test/open_id_authentication_test.rb
86
+ - test/status_test.rb
87
+ - test/test_helper.rb