active_record_openid_store 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
6
+ .bundle
7
+ *.swo
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@active_record_openid_store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in active_record_openid_store.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,49 @@
1
+ =ActiveRecord Based OpenID Store
2
+
3
+ A store is required by an OpenID server and optionally by the consumer to store associations, nonces, and auth key information across requests and processes. If rails is distributed across several machines, they must must all have access to the same OpenID store data, so the FilesystemStore won't do.
4
+
5
+ This directory contains a plugin for connecting your OpenID enabled rails app to an ActiveRecord based OpenID store. <b>The code here is copied from the {openid-ruby library}[https://github.com/openid/ruby-openid] examples (https://github.com/openid/ruby-openid/tree/master/examples/active_record_openid_store)</b>. All I did was move some things around, add a namespace and package it all up as a rails engine/plugin, with some conveniences, for use with Rails 3.
6
+
7
+ ==Usage
8
+
9
+ Just add it as a gem in your Gemfile
10
+
11
+ <tt>gem 'active_record_openid_store'</tt>
12
+
13
+ You will now have access to a rails generator to create the necessary migrations. Simply run:
14
+
15
+ <tt>rails g active_record_openid_store</tt>
16
+
17
+ Now that we have the migration we can create the necessary tables:
18
+
19
+ <tt>rake db:migrate</tt>
20
+
21
+ You should now have two extra tables, +open_id_associations+ and +open_id_nonces+.
22
+
23
+ At this stage you're essentially good to go, you can create a new store like this:
24
+
25
+ <tt>ActiveRecordOpenidStore::ActiveRecordStore.new</tt>
26
+
27
+ You can do this anywhere in your Rails app.
28
+
29
+ ==What about garbage collection?
30
+
31
+ Adding the +active_record_openid_store+ gem to your Gemfile also gives you access to the <tt>openid:gc</tt> rake task. You may use this task at any time to clean up any expired nonces and associations.
32
+
33
+ <tt>rake openid:gc</tt>
34
+
35
+ This task isn't doing anything fancy under the hood, it simply calls the cleanup method of the active record store (i.e.: <tt>ActiveRecordOpenidStore::ActiveRecordStore.new.cleanup</tt>)
36
+
37
+ ==Example With Omniauth
38
+
39
+ Let's say you're using omniauth[https://github.com/intridea/omniauth] and you're also using Google OpenID to authenticate your users. You want to configure Google OpenID to use the ActiveRecord OpenID store. Given that you've followed the instructions above to add the gem and create the tables, you would configure Google OpenID like this.
40
+
41
+ In your <tt>config/initializers/omniauth.rb</tt>:
42
+
43
+
44
+ Rails.application.config.middleware.use OmniAuth::Builder do
45
+ provider :openid, ActiveRecordOpenidStore::ActiveRecordStore.new, :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id'
46
+ end
47
+
48
+
49
+ Having done this, if you go to +/auth/google+ (as per how omniauth works) you will find that your associations and nonces are being stored in the database. Sweet!
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "active_record_openid_store/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "active_record_openid_store"
7
+ s.version = ActiveRecordOpenidStore::VERSION
8
+ s.authors = ["Alan Skorkin"]
9
+ s.email = ["alan@skorks.com"]
10
+ s.homepage = "https://github.com/skorks/active_record_openid_store"
11
+ s.summary = %q{An Active Record-based OpenID store}
12
+ s.description = %q{A store is required by an OpenID server and optionally by the consumer to store associations, nonces, and auth key information across requests and processes. If rails is distributed across several machines, they must must all have access to the same OpenID store data, so the FilesystemStore won't do. The code here is copied from the openid-ruby library examples. All I did was move some things around, add a namespace and package it all up as a rails engine/plugin, with some conveniences, for use with Rails 3.}
13
+
14
+ s.rubyforge_project = "active_record_openid_store"
15
+
16
+ s.add_dependency 'ruby-openid', '~> 2.1.0'
17
+
18
+ s.add_development_dependency 'rake'
19
+ s.add_development_dependency 'rspec', '~> 2.5.0'
20
+ s.add_development_dependency 'json', '~> 1.4.3' # multi_json implementation
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,10 @@
1
+ require 'openid/association'
2
+ require 'time'
3
+
4
+ class ActiveRecordOpenidStore::Association < ActiveRecord::Base
5
+ set_table_name 'open_id_associations'
6
+ def from_record
7
+ OpenID::Association.new(handle, secret, Time.at(issued), lifetime, assoc_type)
8
+ end
9
+ end
10
+
@@ -0,0 +1,3 @@
1
+ class ActiveRecordOpenidStore::Nonce < ActiveRecord::Base
2
+ set_table_name 'open_id_nonces'
3
+ end
@@ -0,0 +1,14 @@
1
+ require "active_record_openid_store/version"
2
+
3
+ module ActiveRecordOpenidStore
4
+ if defined?(Rails)
5
+ require 'active_record_openid_store/engine'
6
+ else
7
+ models_dir = Pathname.new(File.expand_path(File.dirname(__FILE__))).join("../app/models").to_s
8
+ lib_dir = File.expand_path(File.dirname(__FILE__))
9
+ $:.unshift(models_dir) unless $:.include?(models_dir)
10
+ $:.unshift(lib_dir) unless $:.include?(lib_dir)
11
+ require 'active_record_openid_store/active_record_store'
12
+ end
13
+ end
14
+
@@ -0,0 +1,58 @@
1
+ require 'openid'
2
+ require 'openid/store/interface'
3
+ require 'active_record_openid_store/association'
4
+ require 'active_record_openid_store/nonce'
5
+
6
+ module ActiveRecordOpenidStore
7
+ class ActiveRecordStore < OpenID::Store::Interface
8
+ def store_association(server_url, assoc)
9
+ remove_association(server_url, assoc.handle)
10
+ ActiveRecordOpenidStore::Association.create!(:server_url => server_url,
11
+ :handle => assoc.handle,
12
+ :secret => assoc.secret,
13
+ :issued => assoc.issued.to_i,
14
+ :lifetime => assoc.lifetime,
15
+ :assoc_type => assoc.assoc_type)
16
+ end
17
+
18
+ def get_association(server_url, handle=nil)
19
+ assocs = if handle.blank?
20
+ ActiveRecordOpenidStore::Association.find_all_by_server_url(server_url)
21
+ else
22
+ ActiveRecordOpenidStore::Association.find_all_by_server_url_and_handle(server_url, handle)
23
+ end
24
+
25
+ assocs.reverse.each do |assoc|
26
+ a = assoc.from_record
27
+ if a.expires_in == 0
28
+ assoc.destroy
29
+ else
30
+ return a
31
+ end
32
+ end if assocs.any?
33
+
34
+ return nil
35
+ end
36
+
37
+ def remove_association(server_url, handle)
38
+ ActiveRecordOpenidStore::Association.delete_all(['server_url = ? AND handle = ?', server_url, handle]) > 0
39
+ end
40
+
41
+ def use_nonce(server_url, timestamp, salt)
42
+ return false if ActiveRecordOpenidStore::Nonce.find_by_server_url_and_timestamp_and_salt(server_url, timestamp, salt)
43
+ return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew
44
+ ActiveRecordOpenidStore::Nonce.create!(:server_url => server_url, :timestamp => timestamp, :salt => salt)
45
+ return true
46
+ end
47
+
48
+ def cleanup_nonces
49
+ now = Time.now.to_i
50
+ ActiveRecordOpenidStore::Nonce.delete_all(["timestamp > ? OR timestamp < ?", now + OpenID::Nonce.skew, now - OpenID::Nonce.skew])
51
+ end
52
+
53
+ def cleanup_associations
54
+ now = Time.now.to_i
55
+ ActiveRecordOpenidStore::Association.delete_all(['issued + lifetime > ?',now])
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ require "active_record_openid_store"
2
+ require "rails"
3
+
4
+ module ActiveRecordOpenidStore
5
+ class Engine < Rails::Engine
6
+ #engine_name :active_record_openid_store
7
+ initializer "active_record_openid_store init" do |app|
8
+ require 'active_record_openid_store/active_record_store'
9
+ end
10
+ rake_tasks do
11
+ load "active_record_openid_store/railties/tasks.rake"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ namespace :openid do
2
+ desc 'Garbage Collect ActiveRecord OpenID store'
3
+ task :gc => :environment do
4
+ ActiveRecordOpenidStore::ActiveRecordStore.new.cleanup
5
+ end
6
+ end
7
+
@@ -0,0 +1,3 @@
1
+ module ActiveRecordOpenidStore
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ Description:
2
+ Creates the two tables that are needed for an ActiveRecord based OpenID
3
+ store. The tables are open_id_associations, and open_id_nonces.
4
+
5
+ Example:
6
+ rails g active_record_openid_store
@@ -0,0 +1,24 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ class ActiveRecordOpenidStoreGenerator < Rails::Generators::Base
5
+ include Rails::Generators::Migration
6
+
7
+ desc "Create the tables necessary for an ActiveRecord OpenID store"
8
+
9
+ def self.source_root
10
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
11
+ end
12
+
13
+ def self.next_migration_number(dirname)
14
+ if ActiveRecord::Base.timestamped_migrations
15
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
16
+ else
17
+ "%.3d" % (current_migration_number(dirname) + 1)
18
+ end
19
+ end
20
+
21
+ def create_migration_file
22
+ migration_template 'migration.rb', 'db/migrate/create_active_record_openid_store_tables.rb'
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ class CreateActiveRecordOpenidStoreTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :open_id_associations do |t|
4
+ t.binary :server_url, :null => false
5
+ t.string :handle, :null => false
6
+ t.binary :secret, :null => false
7
+ t.integer :issued, :null => false
8
+ t.integer :lifetime, :null => false
9
+ t.string :assoc_type, :null => false
10
+
11
+ t.timestamps
12
+ end
13
+
14
+ create_table :open_id_nonces do |t|
15
+ t.string :server_url, :null => false
16
+ t.integer :timestamp, :null => false
17
+ t.string :salt, :null => false
18
+
19
+ t.timestamps
20
+ end
21
+ end
22
+
23
+ def self.down
24
+ drop_table :open_id_associations
25
+ drop_table :open_id_nonces
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ begin
4
+ require 'rubygems'
5
+ rescue LoadError
6
+ nil
7
+ end
8
+ require 'bundler'
9
+ Bundler.setup
10
+ require 'rspec'
11
+ require 'active_record_openid_store'
12
+
13
+ # Requires supporting files with custom matchers and macros, etc,
14
+ # in ./support/ and its subdirectories.
15
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
16
+
17
+ RSpec.configure do |config|
18
+
19
+ end
@@ -0,0 +1,212 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ require 'test/unit'
3
+ RAILS_ENV = "test"
4
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
5
+
6
+ module StoreTestCase
7
+ @@allowed_handle = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
8
+ @@allowed_nonce = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
9
+
10
+ def _gen_nonce
11
+ OpenID::CryptUtil.random_string(8, @@allowed_nonce)
12
+ end
13
+
14
+ def _gen_handle(n)
15
+ OpenID::CryptUtil.random_string(n, @@allowed_handle)
16
+ end
17
+
18
+ def _gen_secret(n, chars=nil)
19
+ OpenID::CryptUtil.random_string(n, chars)
20
+ end
21
+
22
+ def _gen_assoc(issued, lifetime=600)
23
+ secret = _gen_secret(20)
24
+ handle = _gen_handle(128)
25
+ OpenID::Association.new(handle, secret, Time.now + issued, lifetime,
26
+ 'HMAC-SHA1')
27
+ end
28
+
29
+ def _check_retrieve(url, handle=nil, expected=nil)
30
+ ret_assoc = @store.get_association(url, handle)
31
+
32
+ if expected.nil?
33
+ assert_nil(ret_assoc)
34
+ else
35
+ assert_equal(expected, ret_assoc)
36
+ assert_equal(expected.handle, ret_assoc.handle)
37
+ assert_equal(expected.secret, ret_assoc.secret)
38
+ end
39
+ end
40
+
41
+ def _check_remove(url, handle, expected)
42
+ present = @store.remove_association(url, handle)
43
+ assert_equal(expected, present)
44
+ end
45
+
46
+ def test_store
47
+ server_url = "http://www.myopenid.com/openid"
48
+ assoc = _gen_assoc(issued=0)
49
+
50
+ # Make sure that a missing association returns no result
51
+ _check_retrieve(server_url)
52
+
53
+ # Check that after storage, getting returns the same result
54
+ @store.store_association(server_url, assoc)
55
+ _check_retrieve(server_url, nil, assoc)
56
+
57
+ # more than once
58
+ _check_retrieve(server_url, nil, assoc)
59
+
60
+ # Storing more than once has no ill effect
61
+ @store.store_association(server_url, assoc)
62
+ _check_retrieve(server_url, nil, assoc)
63
+
64
+ # Removing an association that does not exist returns not present
65
+ _check_remove(server_url, assoc.handle + 'x', false)
66
+
67
+ # Removing an association that does not exist returns not present
68
+ _check_remove(server_url + 'x', assoc.handle, false)
69
+
70
+ # Removing an association that is present returns present
71
+ _check_remove(server_url, assoc.handle, true)
72
+
73
+ # but not present on subsequent calls
74
+ _check_remove(server_url, assoc.handle, false)
75
+
76
+ # Put assoc back in the store
77
+ @store.store_association(server_url, assoc)
78
+
79
+ # More recent and expires after assoc
80
+ assoc2 = _gen_assoc(issued=1)
81
+ @store.store_association(server_url, assoc2)
82
+
83
+ # After storing an association with a different handle, but the
84
+ # same server_url, the handle with the later expiration is returned.
85
+ _check_retrieve(server_url, nil, assoc2)
86
+
87
+ # We can still retrieve the older association
88
+ _check_retrieve(server_url, assoc.handle, assoc)
89
+
90
+ # Plus we can retrieve the association with the later expiration
91
+ # explicitly
92
+ _check_retrieve(server_url, assoc2.handle, assoc2)
93
+
94
+ # More recent, and expires earlier than assoc2 or assoc. Make sure
95
+ # that we're picking the one with the latest issued date and not
96
+ # taking into account the expiration.
97
+ assoc3 = _gen_assoc(issued=2, lifetime=100)
98
+ @store.store_association(server_url, assoc3)
99
+
100
+ _check_retrieve(server_url, nil, assoc3)
101
+ _check_retrieve(server_url, assoc.handle, assoc)
102
+ _check_retrieve(server_url, assoc2.handle, assoc2)
103
+ _check_retrieve(server_url, assoc3.handle, assoc3)
104
+
105
+ _check_remove(server_url, assoc2.handle, true)
106
+
107
+ _check_retrieve(server_url, nil, assoc3)
108
+ _check_retrieve(server_url, assoc.handle, assoc)
109
+ _check_retrieve(server_url, assoc2.handle, nil)
110
+ _check_retrieve(server_url, assoc3.handle, assoc3)
111
+
112
+ _check_remove(server_url, assoc2.handle, false)
113
+ _check_remove(server_url, assoc3.handle, true)
114
+
115
+ _check_retrieve(server_url, nil, assoc)
116
+ _check_retrieve(server_url, assoc.handle, assoc)
117
+ _check_retrieve(server_url, assoc2.handle, nil)
118
+ _check_retrieve(server_url, assoc3.handle, nil)
119
+
120
+ _check_remove(server_url, assoc2.handle, false)
121
+ _check_remove(server_url, assoc.handle, true)
122
+ _check_remove(server_url, assoc3.handle, false)
123
+
124
+ _check_retrieve(server_url, nil, nil)
125
+ _check_retrieve(server_url, assoc.handle, nil)
126
+ _check_retrieve(server_url, assoc2.handle, nil)
127
+ _check_retrieve(server_url, assoc3.handle, nil)
128
+
129
+ _check_remove(server_url, assoc2.handle, false)
130
+ _check_remove(server_url, assoc.handle, false)
131
+ _check_remove(server_url, assoc3.handle, false)
132
+
133
+ assocValid1 = _gen_assoc(-3600, 7200)
134
+ assocValid2 = _gen_assoc(-5)
135
+ assocExpired1 = _gen_assoc(-7200, 3600)
136
+ assocExpired2 = _gen_assoc(-7200, 3600)
137
+
138
+ @store.cleanup_associations
139
+ @store.store_association(server_url + '1', assocValid1)
140
+ @store.store_association(server_url + '1', assocExpired1)
141
+ @store.store_association(server_url + '2', assocExpired2)
142
+ @store.store_association(server_url + '3', assocValid2)
143
+
144
+ cleaned = @store.cleanup_associations()
145
+ assert_equal(2, cleaned, "cleaned up associations")
146
+ end
147
+
148
+ def _check_use_nonce(nonce, expected, server_url, msg='')
149
+ stamp, salt = OpenID::Nonce::split_nonce(nonce)
150
+ actual = @store.use_nonce(server_url, stamp, salt)
151
+ assert_equal(expected, actual, msg)
152
+ end
153
+
154
+ def test_nonce
155
+ server_url = "http://www.myopenid.com/openid"
156
+ [server_url, ''].each{|url|
157
+ nonce1 = OpenID::Nonce::mk_nonce
158
+
159
+ _check_use_nonce(nonce1, true, url, "#{url}: nonce allowed by default")
160
+ _check_use_nonce(nonce1, false, url, "#{url}: nonce not allowed twice")
161
+ _check_use_nonce(nonce1, false, url, "#{url}: nonce not allowed third time")
162
+
163
+ # old nonces shouldn't pass
164
+ old_nonce = OpenID::Nonce::mk_nonce(3600)
165
+ _check_use_nonce(old_nonce, false, url, "Old nonce #{old_nonce.inspect} passed")
166
+
167
+ }
168
+
169
+ now = Time.now.to_i
170
+ old_nonce1 = OpenID::Nonce::mk_nonce(now - 20000)
171
+ old_nonce2 = OpenID::Nonce::mk_nonce(now - 10000)
172
+ recent_nonce = OpenID::Nonce::mk_nonce(now - 600)
173
+
174
+ orig_skew = OpenID::Nonce.skew
175
+ OpenID::Nonce.skew = 0
176
+ count = @store.cleanup_nonces
177
+ OpenID::Nonce.skew = 1000000
178
+ ts, salt = OpenID::Nonce::split_nonce(old_nonce1)
179
+ assert(@store.use_nonce(server_url, ts, salt), "oldnonce1")
180
+ ts, salt = OpenID::Nonce::split_nonce(old_nonce2)
181
+ assert(@store.use_nonce(server_url, ts, salt), "oldnonce2")
182
+ ts, salt = OpenID::Nonce::split_nonce(recent_nonce)
183
+ assert(@store.use_nonce(server_url, ts, salt), "recent_nonce")
184
+
185
+
186
+ OpenID::Nonce.skew = 1000
187
+ cleaned = @store.cleanup_nonces
188
+ assert_equal(2, cleaned, "Cleaned #{cleaned} nonces")
189
+
190
+ OpenID::Nonce.skew = 100000
191
+ ts, salt = OpenID::Nonce::split_nonce(old_nonce1)
192
+ assert(@store.use_nonce(server_url, ts, salt), "oldnonce1 after cleanup")
193
+ ts, salt = OpenID::Nonce::split_nonce(old_nonce2)
194
+ assert(@store.use_nonce(server_url, ts, salt), "oldnonce2 after cleanup")
195
+ ts, salt = OpenID::Nonce::split_nonce(recent_nonce)
196
+ assert(!@store.use_nonce(server_url, ts, salt), "recent_nonce after cleanup")
197
+
198
+ OpenID::Nonce.skew = orig_skew
199
+
200
+ end
201
+ end
202
+
203
+
204
+ class TestARStore < Test::Unit::TestCase
205
+ include StoreTestCase
206
+
207
+ def setup
208
+ @store = ActiveRecordStore.new
209
+ end
210
+
211
+ end
212
+
data/todos.txt ADDED
@@ -0,0 +1,5 @@
1
+ - make sure the store can be easily used outside of rails (e.g. try it out with sinatra)
2
+ - do some rake tasks to create the database tables and stuff when using active record outside of rails (e.g. with sinatra)
3
+ - make sure that requiring the active_record_openid_store outside or rails works properly
4
+ - add some specs
5
+ - fix up some of the code (after specs have been added)
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_record_openid_store
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.1
6
+ platform: ruby
7
+ authors:
8
+ - Alan Skorkin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-20 00:00:00 +10:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: ruby-openid
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 2.1.0
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 2.5.0
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: json
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ version: 1.4.3
58
+ type: :development
59
+ version_requirements: *id004
60
+ description: A store is required by an OpenID server and optionally by the consumer to store associations, nonces, and auth key information across requests and processes. If rails is distributed across several machines, they must must all have access to the same OpenID store data, so the FilesystemStore won't do. The code here is copied from the openid-ruby library examples. All I did was move some things around, add a namespace and package it all up as a rails engine/plugin, with some conveniences, for use with Rails 3.
61
+ email:
62
+ - alan@skorks.com
63
+ executables: []
64
+
65
+ extensions: []
66
+
67
+ extra_rdoc_files: []
68
+
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - .rvmrc
73
+ - Gemfile
74
+ - README.rdoc
75
+ - Rakefile
76
+ - active_record_openid_store.gemspec
77
+ - app/models/active_record_openid_store/association.rb
78
+ - app/models/active_record_openid_store/nonce.rb
79
+ - lib/active_record_openid_store.rb
80
+ - lib/active_record_openid_store/active_record_store.rb
81
+ - lib/active_record_openid_store/engine.rb
82
+ - lib/active_record_openid_store/railties/tasks.rake
83
+ - lib/active_record_openid_store/version.rb
84
+ - lib/generators/active_record_openid_store/USAGE
85
+ - lib/generators/active_record_openid_store/active_record_openid_store_generator.rb
86
+ - lib/generators/active_record_openid_store/templates/migration.rb
87
+ - spec/spec_helper.rb
88
+ - test/store_test.rb
89
+ - todos.txt
90
+ has_rdoc: true
91
+ homepage: https://github.com/skorks/active_record_openid_store
92
+ licenses: []
93
+
94
+ post_install_message:
95
+ rdoc_options: []
96
+
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: "0"
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: "0"
111
+ requirements: []
112
+
113
+ rubyforge_project: active_record_openid_store
114
+ rubygems_version: 1.6.2
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: An Active Record-based OpenID store
118
+ test_files:
119
+ - spec/spec_helper.rb
120
+ - test/store_test.rb