openid-redis-store 0.0.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/README.md +33 -0
- data/lib/open_id/store/redis.rb +107 -0
- metadata +96 -0
data/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Redis Store for OpenID
|
|
2
|
+
======================
|
|
3
|
+
|
|
4
|
+
This is a simple store for OpenID authentication.
|
|
5
|
+
|
|
6
|
+
Usage
|
|
7
|
+
-----
|
|
8
|
+
|
|
9
|
+
1) Install the plugin:
|
|
10
|
+
|
|
11
|
+
./script/plugin install git://github.com/dekart/openid-redis-store.git
|
|
12
|
+
|
|
13
|
+
2) Set your OpenID store (for Rails put this to a new file in config/initializers):
|
|
14
|
+
|
|
15
|
+
# Initializing Redis client
|
|
16
|
+
redis_client = Redis.new(
|
|
17
|
+
:host => "127.0.0.1",
|
|
18
|
+
:port => "",
|
|
19
|
+
:db => 0
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
OpenIdAuthentication.store = OpenID::Store::Redis.new(redis_client)
|
|
23
|
+
|
|
24
|
+
Testing
|
|
25
|
+
-------
|
|
26
|
+
|
|
27
|
+
No tests yet :( You can fork this plugin at GitHub (http://github.com/dekart/openid-redis-store)
|
|
28
|
+
and add your own tests. I'll be happy to accept patches!
|
|
29
|
+
|
|
30
|
+
Credits
|
|
31
|
+
-------
|
|
32
|
+
|
|
33
|
+
Written by [Alex Dmitriev](http://railorz.ru)
|
|
@@ -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 Redis < Interface
|
|
9
|
+
attr_accessor :key_prefix
|
|
10
|
+
|
|
11
|
+
def initialize(cache_client, key_prefix = 'openid-store:')
|
|
12
|
+
@cache_client = cache_client
|
|
13
|
+
@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
|
+
key = assoc_key(server_url, association.handle)
|
|
22
|
+
value = serialize(association)
|
|
23
|
+
|
|
24
|
+
@cache_client.setex(key, association.lifetime, value)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Returns a Association object from storage that matches
|
|
28
|
+
# the server_url. Returns nil if no such association is found or if
|
|
29
|
+
# the one matching association is expired. (Is allowed to GC expired
|
|
30
|
+
# associations when found.)
|
|
31
|
+
def get_association(server_url, handle=nil)
|
|
32
|
+
value = @cache_client.get(assoc_key(server_url, handle))
|
|
33
|
+
|
|
34
|
+
value ? deserialize(value) : nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# If there is a matching association, remove it from the store and
|
|
38
|
+
# return true, otherwise return false.
|
|
39
|
+
def remove_association(server_url, handle)
|
|
40
|
+
deleted = delete(assoc_key(server_url, handle))
|
|
41
|
+
server_assoc = get_association(server_url)
|
|
42
|
+
|
|
43
|
+
if server_assoc && server_assoc.handle == handle
|
|
44
|
+
deleted = delete(assoc_key(server_url)) | deleted
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
deleted
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Return true if the nonce has not been used before, and store it
|
|
51
|
+
# for a while to make sure someone doesn't try to use the same value
|
|
52
|
+
# again. Return false if the nonce has already been used or if the
|
|
53
|
+
# timestamp is not current.
|
|
54
|
+
# You can use OpenID::Store::Nonce::SKEW for your timestamp window.
|
|
55
|
+
# server_url: URL of the server from which the nonce originated
|
|
56
|
+
# timestamp: time the nonce was created in seconds since unix epoch
|
|
57
|
+
# salt: A random string that makes two nonces issued by a server in
|
|
58
|
+
# the same second unique
|
|
59
|
+
def use_nonce(server_url, timestamp, salt)
|
|
60
|
+
return false if (timestamp - Time.now.to_i).abs > Nonce.skew
|
|
61
|
+
ts = timestamp.to_s # base 10 seconds since epoch
|
|
62
|
+
nonce_key = key_prefix + 'N' + server_url + '|' + ts + '|' + salt
|
|
63
|
+
|
|
64
|
+
if result = @cache_client.setnx(nonce_key, '')
|
|
65
|
+
@cache_client.expire(nonce_key, Nonce.skew + 5)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
result
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def assoc_key(server_url, assoc_handle=nil)
|
|
72
|
+
key = key_prefix + 'A' + server_url
|
|
73
|
+
|
|
74
|
+
if assoc_handle
|
|
75
|
+
key += '|' + assoc_handle
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
key
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def cleanup_nonces
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def cleanup
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def cleanup_associations
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
protected
|
|
91
|
+
|
|
92
|
+
def delete(key)
|
|
93
|
+
@cache_client.del(key)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def serialize(assoc)
|
|
97
|
+
Marshal.dump(assoc)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def deserialize(assoc_str)
|
|
101
|
+
Marshal.load(assoc_str)
|
|
102
|
+
rescue ArgumentError
|
|
103
|
+
nil
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: openid-redis-store
|
|
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
|
+
- Alex Dmitriev
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2011-02-28 00:00:00 +01:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies:
|
|
21
|
+
- !ruby/object:Gem::Dependency
|
|
22
|
+
name: ruby-openid
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 3
|
|
30
|
+
segments:
|
|
31
|
+
- 0
|
|
32
|
+
version: "0"
|
|
33
|
+
type: :runtime
|
|
34
|
+
version_requirements: *id001
|
|
35
|
+
- !ruby/object:Gem::Dependency
|
|
36
|
+
name: redis
|
|
37
|
+
prerelease: false
|
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
hash: 3
|
|
44
|
+
segments:
|
|
45
|
+
- 0
|
|
46
|
+
version: "0"
|
|
47
|
+
type: :runtime
|
|
48
|
+
version_requirements: *id002
|
|
49
|
+
description: Implementation of the ruby-openid Store interface that stores information in Redis
|
|
50
|
+
email:
|
|
51
|
+
- rene.dekart@gmail.com
|
|
52
|
+
executables: []
|
|
53
|
+
|
|
54
|
+
extensions: []
|
|
55
|
+
|
|
56
|
+
extra_rdoc_files: []
|
|
57
|
+
|
|
58
|
+
files:
|
|
59
|
+
- lib/open_id/store/redis.rb
|
|
60
|
+
- README.md
|
|
61
|
+
has_rdoc: true
|
|
62
|
+
homepage: https://github.com/dekart/openid-redis-store
|
|
63
|
+
licenses: []
|
|
64
|
+
|
|
65
|
+
post_install_message:
|
|
66
|
+
rdoc_options: []
|
|
67
|
+
|
|
68
|
+
require_paths:
|
|
69
|
+
- lib
|
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
|
+
none: false
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
hash: 3
|
|
76
|
+
segments:
|
|
77
|
+
- 0
|
|
78
|
+
version: "0"
|
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
|
+
none: false
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
hash: 3
|
|
85
|
+
segments:
|
|
86
|
+
- 0
|
|
87
|
+
version: "0"
|
|
88
|
+
requirements: []
|
|
89
|
+
|
|
90
|
+
rubyforge_project:
|
|
91
|
+
rubygems_version: 1.3.7
|
|
92
|
+
signing_key:
|
|
93
|
+
specification_version: 3
|
|
94
|
+
summary: Redis store for OpenID
|
|
95
|
+
test_files: []
|
|
96
|
+
|