mc-openid 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +35 -0
- data/README +0 -0
- data/Rakefile +23 -0
- data/lib/mc-openid.rb +27 -0
- data/lib/mc-openid/version.rb +5 -0
- data/lib/open_id_authentication/lib/open_id_authentication.rb +175 -0
- data/mc-openid.gemspec +21 -0
- data/spec/mc-openid_spec.rb +34 -0
- data/spec/spec_helper.rb +8 -0
- data/test/normalize_test.rb +32 -0
- data/test/open_id_authentication_test.rb +38 -0
- data/test/status_test.rb +19 -0
- data/test/test_helper.rb +14 -0
- metadata +87 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|
+
|
data/lib/mc-openid.rb
ADDED
@@ -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,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
|
data/mc-openid.gemspec
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
data/test/status_test.rb
ADDED
@@ -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
|
data/test/test_helper.rb
ADDED
@@ -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
|