ruby-openid 2.1.6 → 2.1.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby-openid might be problematic. Click here for more details.

data/CHANGELOG CHANGED
@@ -1,15 +1,35 @@
1
- Tue Apr 21 11:42:57 PDT 2009 cygnus@janrain.com
2
- tagged 2.1.6
3
- Ignore-this: b97ef05fbb348ace2f86513a5de7db46
1
+ Wed Jul 1 15:07:23 PDT 2009 chowells@janrain.com
2
+ tagged 2.1.7
3
+ Ignore-this: 9bef91a9c9d6232961500dd4b9416c14
4
+
5
+ Wed Jul 1 14:43:24 PDT 2009 chowells@janrain.com
6
+ * update version to 2.1.7
7
+ Ignore-this: 9b158a7f5c948b1a042331bf8137e95d
8
+
9
+ Wed Jul 1 12:23:50 PDT 2009 chowells@janrain.com
10
+ * Handle malformed associate responses better in negotiate association
11
+ Ignore-this: 13d2c5718f1f798d3e60ce9ffac9a135
12
+
13
+ Wed Jul 1 12:05:19 PDT 2009 chowells@janrain.com
14
+ * whitespace
15
+ Ignore-this: e4b91f8280dc1591726467448a468188
4
16
 
5
- Tue Apr 21 11:42:54 PDT 2009 cygnus@janrain.com
6
- * Set version to 2.1.6
7
- Ignore-this: 992c07fd2dca61765d11f90167008ebd
17
+ Mon Jun 29 15:19:08 PDT 2009 cygnus@janrain.com
18
+ * Add memcache store implementation and tests
19
+ Ignore-this: a8cde55ae2c28a9ba6f8c0a46436d336
8
20
 
9
- Mon Apr 20 12:57:11 PDT 2009 cygnus@janrain.com
10
- * Consumer: require that op_endpoint be signed in id_res responses
11
- Ignore-this: a0fbd71a105194bac2624f7cff8a3e7a
21
+ Mon Jun 29 15:18:41 PDT 2009 cygnus@janrain.com
22
+ * Store tests: loosen get_association tests so that it is only asserting that we are not returning deleted associations rather than testing that we return a particular association
23
+ Ignore-this: a2514be4e99da76ca8c55a78bf10817a
12
24
 
13
- Fri Apr 17 11:05:55 PDT 2009 cygnus@janrain.com
14
- tagged 2.1.5
15
- Ignore-this: 5f2efd8e91589c54cb0833b6379b9cfa
25
+ Mon Jun 29 15:17:04 PDT 2009 cygnus@janrain.com
26
+ * Store tests: separate cleanup tests from other store tests
27
+ Ignore-this: 49ce6bc616af0deb063d8b1a9633ee0a
28
+
29
+ Mon Jun 29 15:15:49 PDT 2009 cygnus@janrain.com
30
+ * whitespace
31
+ Ignore-this: a69795c5131e0cf6f687ccc8dfbba61a
32
+
33
+ Tue Apr 21 11:42:57 PDT 2009 cygnus@janrain.com
34
+ tagged 2.1.6
35
+ Ignore-this: b97ef05fbb348ace2f86513a5de7db46
data/admin/runtests.rb CHANGED
@@ -7,6 +7,16 @@ require "pathname"
7
7
  require 'test/unit/collector/dir'
8
8
  require 'test/unit/ui/console/testrunner'
9
9
 
10
+ begin
11
+ require 'rubygems'
12
+ require 'memcache'
13
+ rescue LoadError
14
+ else
15
+ if ENV['TESTING_MEMCACHE']
16
+ TESTING_MEMCACHE = MemCache.new(ENV['TESTING_MEMCACHE'])
17
+ end
18
+ end
19
+
10
20
  def main
11
21
  old_verbose = $VERBOSE
12
22
  $VERBOSE = true
@@ -26,7 +36,6 @@ def main
26
36
  suite = c.collect(tests_dir)
27
37
  end
28
38
 
29
-
30
39
  result = Test::Unit::UI::Console::TestRunner.run(suite)
31
40
  result.passed?
32
41
  ensure
data/lib/openid.rb CHANGED
@@ -13,7 +13,7 @@
13
13
  # permissions and limitations under the License.
14
14
 
15
15
  module OpenID
16
- VERSION = "2.1.6"
16
+ VERSION = "2.1.7"
17
17
  end
18
18
 
19
19
  require "openid/consumer"
@@ -143,6 +143,10 @@ module OpenID
143
143
  return nil
144
144
  end
145
145
  end
146
+ rescue InvalidOpenIDNamespace
147
+ Util.log("Server #{@server_url} returned a malformed association " \
148
+ "response. Falling back to check_id mode for this request.")
149
+ return nil
146
150
  end
147
151
  end
148
152
 
@@ -0,0 +1,107 @@
1
+ require 'openid/util'
2
+ require 'openid/store/interface'
3
+ require 'openid/store/nonce'
4
+ require 'time'
5
+
6
+ module OpenID
7
+ module Store
8
+ class Memcache < Interface
9
+ attr_accessor :key_prefix
10
+
11
+ def initialize(cache_client, key_prefix='openid-store:')
12
+ @cache_client = cache_client
13
+ self.key_prefix = key_prefix
14
+ end
15
+
16
+ # Put a Association object into storage.
17
+ # When implementing a store, don't assume that there are any limitations
18
+ # on the character set of the server_url. In particular, expect to see
19
+ # unescaped non-url-safe characters in the server_url field.
20
+ def store_association(server_url, association)
21
+ serialized = serialize(association)
22
+ [nil, association.handle].each do |handle|
23
+ key = assoc_key(server_url, handle)
24
+ @cache_client.set(key, serialized, expiry(association.lifetime))
25
+ end
26
+ end
27
+
28
+ # Returns a Association object from storage that matches
29
+ # the server_url. Returns nil if no such association is found or if
30
+ # the one matching association is expired. (Is allowed to GC expired
31
+ # associations when found.)
32
+ def get_association(server_url, handle=nil)
33
+ serialized = @cache_client.get(assoc_key(server_url, handle))
34
+ if serialized
35
+ return deserialize(serialized)
36
+ else
37
+ return nil
38
+ end
39
+ end
40
+
41
+ # If there is a matching association, remove it from the store and
42
+ # return true, otherwise return false.
43
+ def remove_association(server_url, handle)
44
+ deleted = delete(assoc_key(server_url, handle))
45
+ server_assoc = get_association(server_url)
46
+ if server_assoc && server_assoc.handle == handle
47
+ deleted = delete(assoc_key(server_url)) | deleted
48
+ end
49
+ return deleted
50
+ end
51
+
52
+ # Return true if the nonce has not been used before, and store it
53
+ # for a while to make sure someone doesn't try to use the same value
54
+ # again. Return false if the nonce has already been used or if the
55
+ # timestamp is not current.
56
+ # You can use OpenID::Store::Nonce::SKEW for your timestamp window.
57
+ # server_url: URL of the server from which the nonce originated
58
+ # timestamp: time the nonce was created in seconds since unix epoch
59
+ # salt: A random string that makes two nonces issued by a server in
60
+ # the same second unique
61
+ def use_nonce(server_url, timestamp, salt)
62
+ return false if (timestamp - Time.now.to_i).abs > Nonce.skew
63
+ ts = timestamp.to_s # base 10 seconds since epoch
64
+ nonce_key = key_prefix + 'N' + server_url + '|' + ts + '|' + salt
65
+ result = @cache_client.add(nonce_key, '', expiry(Nonce.skew + 5))
66
+ return !!(result =~ /^STORED/)
67
+ end
68
+
69
+ def assoc_key(server_url, assoc_handle=nil)
70
+ key = key_prefix + 'A' + server_url
71
+ if assoc_handle
72
+ key += '|' + assoc_handle
73
+ end
74
+ return key
75
+ end
76
+
77
+ def cleanup_nonces
78
+ end
79
+
80
+ def cleanup
81
+ end
82
+
83
+ def cleanup_associations
84
+ end
85
+
86
+ protected
87
+
88
+ def delete(key)
89
+ result = @cache_client.delete(key)
90
+ return !!(result =~ /^DELETED/)
91
+ end
92
+
93
+ def serialize(assoc)
94
+ Marshal.dump(assoc)
95
+ end
96
+
97
+ def deserialize(assoc_str)
98
+ Marshal.load(assoc_str)
99
+ end
100
+
101
+ # Convert a lifetime in seconds into a memcache expiry value
102
+ def expiry(t)
103
+ Time.now.to_i + t
104
+ end
105
+ end
106
+ end
107
+ end
@@ -314,9 +314,9 @@ module OpenID
314
314
  # in an unsupported-type response is absent.
315
315
  def test_empty_assoc_type
316
316
  msg = mk_message({'error' => 'Unsupported type',
317
- 'error_code' => 'unsupported-type',
318
- 'session_type' => 'new-session-type',
319
- })
317
+ 'error_code' => 'unsupported-type',
318
+ 'session_type' => 'new-session-type',
319
+ })
320
320
 
321
321
  assert_log_matches('Unsupported association type',
322
322
  "Server #{@server_url} responded with unsupported "\
@@ -331,9 +331,9 @@ module OpenID
331
331
  # in an unsupported-type response is absent.
332
332
  def test_empty_session_type
333
333
  msg = mk_message({'error' => 'Unsupported type',
334
- 'error_code' => 'unsupported-type',
335
- 'assoc_type' => 'new-assoc-type',
336
- })
334
+ 'error_code' => 'unsupported-type',
335
+ 'assoc_type' => 'new-assoc-type',
336
+ })
337
337
 
338
338
  assert_log_matches('Unsupported association type',
339
339
  "Server #{@server_url} responded with unsupported "\
@@ -352,10 +352,10 @@ module OpenID
352
352
  @allowed_types = [['assoc_bogus', 'session_bogus']]
353
353
  }
354
354
  msg = mk_message({'error' => 'Unsupported type',
355
- 'error_code' => 'unsupported-type',
356
- 'assoc_type' => 'not-allowed',
357
- 'session_type' => 'not-allowed',
358
- })
355
+ 'error_code' => 'unsupported-type',
356
+ 'assoc_type' => 'not-allowed',
357
+ 'session_type' => 'not-allowed',
358
+ })
359
359
 
360
360
  assert_log_matches('Unsupported association type',
361
361
  'Server sent unsupported session/association type:') {
@@ -367,10 +367,10 @@ module OpenID
367
367
  # retry to get an association with the new preferred type.
368
368
  def test_unsupported_with_retry
369
369
  msg = mk_message({'error' => 'Unsupported type',
370
- 'error_code' => 'unsupported-type',
371
- 'assoc_type' => 'HMAC-SHA1',
372
- 'session_type' => 'DH-SHA1',
373
- })
370
+ 'error_code' => 'unsupported-type',
371
+ 'assoc_type' => 'HMAC-SHA1',
372
+ 'session_type' => 'DH-SHA1',
373
+ })
374
374
 
375
375
  assoc = Association.new('handle', 'secret', Time.now, 10000, 'HMAC-SHA1')
376
376
 
@@ -383,10 +383,10 @@ module OpenID
383
383
  # retry, but the retry fails and nil is returned instead.
384
384
  def test_unsupported_with_retry_and_fail
385
385
  msg = mk_message({'error' => 'Unsupported type',
386
- 'error_code' => 'unsupported-type',
387
- 'assoc_type' => 'HMAC-SHA1',
388
- 'session_type' => 'DH-SHA1',
389
- })
386
+ 'error_code' => 'unsupported-type',
387
+ 'assoc_type' => 'HMAC-SHA1',
388
+ 'session_type' => 'DH-SHA1',
389
+ })
390
390
 
391
391
  assert_log_matches('Unsupported association type',
392
392
  "Server #{@server_url} refused") {
data/test/test_stores.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'test/unit'
2
2
  require 'openid/store/interface'
3
3
  require 'openid/store/filesystem'
4
+ require 'openid/store/memcache'
4
5
  require 'openid/store/memory'
5
6
  require 'openid/util'
6
7
  require 'openid/store/nonce'
@@ -11,7 +12,7 @@ module OpenID
11
12
  module StoreTestCase
12
13
  @@allowed_handle = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
13
14
  @@allowed_nonce = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
14
-
15
+
15
16
  def _gen_nonce
16
17
  OpenID::CryptUtil.random_string(8, @@allowed_nonce)
17
18
  end
@@ -28,9 +29,9 @@ module OpenID
28
29
  secret = _gen_secret(20)
29
30
  handle = _gen_handle(128)
30
31
  OpenID::Association.new(handle, secret, Time.now + issued, lifetime,
31
- 'HMAC-SHA1')
32
+ 'HMAC-SHA1')
32
33
  end
33
-
34
+
34
35
  def _check_retrieve(url, handle=nil, expected=nil)
35
36
  ret_assoc = @store.get_association(url, handle)
36
37
 
@@ -49,7 +50,6 @@ module OpenID
49
50
  end
50
51
 
51
52
  def test_store
52
- server_url = "http://www.myopenid.com/openid"
53
53
  assoc = _gen_assoc(issued=0)
54
54
 
55
55
  # Make sure that a missing association returns no result
@@ -117,7 +117,11 @@ module OpenID
117
117
  _check_remove(server_url, assoc2.handle, false)
118
118
  _check_remove(server_url, assoc3.handle, true)
119
119
 
120
- _check_retrieve(server_url, nil, assoc)
120
+ ret_assoc = @store.get_association(server_url, nil)
121
+ unexpected = [assoc2.handle, assoc3.handle]
122
+ assert(ret_assoc.nil? || !unexpected.member?(ret_assoc.handle),
123
+ ret_assoc)
124
+
121
125
  _check_retrieve(server_url, assoc.handle, assoc)
122
126
  _check_retrieve(server_url, assoc2.handle, nil)
123
127
  _check_retrieve(server_url, assoc3.handle, nil)
@@ -134,7 +138,9 @@ module OpenID
134
138
  _check_remove(server_url, assoc2.handle, false)
135
139
  _check_remove(server_url, assoc.handle, false)
136
140
  _check_remove(server_url, assoc3.handle, false)
141
+ end
137
142
 
143
+ def test_assoc_cleanup
138
144
  assocValid1 = _gen_assoc(-3600, 7200)
139
145
  assocValid2 = _gen_assoc(-5)
140
146
  assocExpired1 = _gen_assoc(-7200, 3600)
@@ -156,21 +162,26 @@ module OpenID
156
162
  assert_equal(expected, actual, msg)
157
163
  end
158
164
 
165
+ def server_url
166
+ "http://www.myopenid.com/openid"
167
+ end
168
+
159
169
  def test_nonce
160
- server_url = "http://www.myopenid.com/openid"
161
170
  [server_url, ''].each{|url|
162
171
  nonce1 = Nonce::mk_nonce
163
172
 
164
- _check_use_nonce(nonce1, true, url, "#{url}: nonce allowed by default")
165
- _check_use_nonce(nonce1, false, url, "#{url}: nonce not allowed twice")
173
+ _check_use_nonce(nonce1, true, url, "#{url}: nonce allowed by default")
174
+ _check_use_nonce(nonce1, false, url, "#{url}: nonce not allowed twice")
166
175
  _check_use_nonce(nonce1, false, url, "#{url}: nonce not allowed third time")
167
-
176
+
168
177
  # old nonces shouldn't pass
169
178
  old_nonce = Nonce::mk_nonce(3600)
170
179
  _check_use_nonce(old_nonce, false, url, "Old nonce #{old_nonce.inspect} passed")
171
180
 
172
181
  }
182
+ end
173
183
 
184
+ def test_nonce_cleanup
174
185
  now = Time.now.to_i
175
186
  old_nonce1 = Nonce::mk_nonce(now - 20000)
176
187
  old_nonce2 = Nonce::mk_nonce(now - 10000)
@@ -187,7 +198,6 @@ module OpenID
187
198
  ts, salt = Nonce::split_nonce(recent_nonce)
188
199
  assert(@store.use_nonce(server_url, ts, salt), "recent_nonce")
189
200
 
190
-
191
201
  Nonce.skew = 1000
192
202
  cleaned = @store.cleanup_nonces
193
203
  assert_equal(2, cleaned, "Cleaned #{cleaned} nonces")
@@ -204,7 +214,7 @@ module OpenID
204
214
 
205
215
  end
206
216
  end
207
-
217
+
208
218
  class FileStoreTestCase < Test::Unit::TestCase
209
219
  include StoreTestCase
210
220
 
@@ -220,50 +230,69 @@ module OpenID
220
230
 
221
231
  class MemoryStoreTestCase < Test::Unit::TestCase
222
232
  include StoreTestCase
223
-
233
+
224
234
  def setup
225
235
  @store = Memory.new
226
236
  end
227
237
  end
228
238
 
239
+ begin
240
+ ::TESTING_MEMCACHE
241
+ rescue NameError
242
+ else
243
+ class MemcacheStoreTestCase < Test::Unit::TestCase
244
+ include StoreTestCase
245
+ def setup
246
+ store_uniq = OpenID::CryptUtil.random_string(6, "0123456789")
247
+ store_namespace = "openid-store-#{store_uniq}:"
248
+ @store = Memcache.new(::TESTING_MEMCACHE, store_namespace)
249
+ end
250
+
251
+ def test_nonce_cleanup
252
+ end
253
+
254
+ def test_assoc_cleanup
255
+ end
256
+ end
257
+ end
258
+
229
259
  class AbstractStoreTestCase < Test::Unit::TestCase
230
260
  def test_abstract_class
231
261
  # the abstract made concrete
232
262
  abc = Interface.new()
233
263
  server_url = "http://server.com/"
234
264
  association = OpenID::Association.new("foo", "bar", Time.now, Time.now + 10, "dummy")
235
-
236
- assert_raise(NotImplementedError) {
265
+
266
+ assert_raise(NotImplementedError) {
237
267
  abc.store_association(server_url, association)
238
268
  }
239
269
 
240
- assert_raise(NotImplementedError) {
270
+ assert_raise(NotImplementedError) {
241
271
  abc.get_association(server_url)
242
272
  }
243
273
 
244
- assert_raise(NotImplementedError) {
274
+ assert_raise(NotImplementedError) {
245
275
  abc.remove_association(server_url, association.handle)
246
276
  }
247
277
 
248
- assert_raise(NotImplementedError) {
278
+ assert_raise(NotImplementedError) {
249
279
  abc.use_nonce(server_url, Time.now.to_i, "foo")
250
280
  }
251
281
 
252
- assert_raise(NotImplementedError) {
282
+ assert_raise(NotImplementedError) {
253
283
  abc.cleanup_nonces()
254
284
  }
255
285
 
256
- assert_raise(NotImplementedError) {
286
+ assert_raise(NotImplementedError) {
257
287
  abc.cleanup_associations()
258
288
  }
259
289
 
260
- assert_raise(NotImplementedError) {
290
+ assert_raise(NotImplementedError) {
261
291
  abc.cleanup()
262
292
  }
263
-
293
+
264
294
  end
265
295
 
266
296
  end
267
297
  end
268
298
  end
269
-
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: ruby-openid
5
5
  version: !ruby/object:Gem::Version
6
- version: 2.1.6
7
- date: 2009-04-21 00:00:00 -07:00
6
+ version: 2.1.7
7
+ date: 2009-07-01 00:00:00 -07:00
8
8
  summary: A library for consuming and serving OpenID identities.
9
9
  require_paths:
10
10
  - lib
@@ -168,6 +168,7 @@ files:
168
168
  - lib/openid/store/interface.rb
169
169
  - lib/openid/store/nonce.rb
170
170
  - lib/openid/store/memory.rb
171
+ - lib/openid/store/memcache.rb
171
172
  - lib/openid/extensions/sreg.rb
172
173
  - lib/openid/extensions/ax.rb
173
174
  - lib/openid/extensions/pape.rb