redis_token 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +31 -11
- data/lib/redis_token/version.rb +1 -1
- data/lib/redis_token.rb +66 -26
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84a99d9c046e1eb837705dca92549fc3061b47ab
|
4
|
+
data.tar.gz: 9a841fbadb69db584aba0717c158191e24daedc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4baad3526458c71db2fa647f55c092d5e0e31f9b64b5459d9f10ad36d216f7de78f864f2ff0a7757c8ec423debeb7fbf27d5de23db398e482e52c90ac9435071
|
7
|
+
data.tar.gz: f861fd550a022cdb802daa1c1f88a784b62a35fa41f6c52f23ac5b8494c5064a9df4be3aaad237d841ac111fbf96840e685f94f83c4d2d1ca69124bb6545aa68
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ def auth
|
|
27
27
|
client = Client.find_by_email(params[:email])
|
28
28
|
|
29
29
|
if client.password == params[:password]
|
30
|
-
token = @redis_token.create("client.#{client.id}", payload: { source: :native })
|
30
|
+
token = @redis_token.create(owner: "client.#{client.id}", payload: { source: :native })
|
31
31
|
json(access_token: token)
|
32
32
|
|
33
33
|
# ...
|
@@ -47,10 +47,9 @@ def secured_method
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def client_tokens
|
50
|
-
@tokens = []
|
51
50
|
|
52
|
-
@redis_token.owned_by("client.#{client.id}").
|
53
|
-
|
51
|
+
@tokens = @redis_token.owned_by("client.#{client.id}").map do |token, value|
|
52
|
+
{ token: token, value: value }
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
@@ -84,20 +83,24 @@ r = RedisToken.new(redis)
|
|
84
83
|
### Create token
|
85
84
|
|
86
85
|
```ruby
|
87
|
-
client_token = r.create("client.#{client.id}")
|
86
|
+
client_token = r.create(owner: "client.#{client.id}")
|
88
87
|
# => "eca431add3b1f0bbc6cfc73980b68708"
|
89
88
|
|
90
89
|
# Redefine default ttl:
|
91
|
-
user_token = r.create("u:#{current_user.id}", ttl: 15.hours)
|
90
|
+
user_token = r.create(owner: "u:#{current_user.id}", ttl: 15.hours)
|
92
91
|
# => "548a5d54eaf474c750bf83ed04bd242a"
|
93
92
|
|
94
93
|
# Create token with payload:
|
95
|
-
mobile_token = r.create("c.#{client.id}", payload: { source: :native })
|
94
|
+
mobile_token = r.create(owner: "c.#{client.id}", payload: { source: :native })
|
96
95
|
# => "865249d6b87c4e6dd8f6b0796ace7fa0"
|
97
96
|
|
98
97
|
# Save exist token:
|
99
|
-
r.create('api', token: SecureRandom.uuid)
|
98
|
+
r.create(owner: 'api', token: SecureRandom.uuid)
|
100
99
|
# => "aed6e179-14b4-4a8c-9a1b-6b0f9150ede3"
|
100
|
+
|
101
|
+
# Token without an owner:
|
102
|
+
r.create
|
103
|
+
# => "9dfb0d52280965fe4dd95d21447941c2"
|
101
104
|
```
|
102
105
|
|
103
106
|
### Get token
|
@@ -116,6 +119,10 @@ r.ttl('865249d6b87c4e6dd8f6b0796ace7fa0')
|
|
116
119
|
|
117
120
|
# To prevent ttl sliding set slide_expire to false:
|
118
121
|
r.get('865249d6b87c4e6dd8f6b0796ace7fa0', slide_expire: false)
|
122
|
+
|
123
|
+
# Token without an owner:
|
124
|
+
rt.get('9dfb0d52280965fe4dd95d21447941c2')
|
125
|
+
# => {:at=>1503327773}
|
119
126
|
```
|
120
127
|
|
121
128
|
### Get all tokens owned by someone
|
@@ -132,19 +139,32 @@ r.owned_by('u.555').each { |t,v| p "#{t}: #{v}" }
|
|
132
139
|
# => nil
|
133
140
|
```
|
134
141
|
|
135
|
-
###
|
142
|
+
### Deletion
|
136
143
|
|
144
|
+
Single token:
|
137
145
|
```ruby
|
138
146
|
r.delete('865249d6b87c4e6dd8f6b0796ace7fa0')
|
139
147
|
# => true
|
140
148
|
```
|
141
149
|
|
142
|
-
|
150
|
+
All tokens of an owner:
|
143
151
|
```ruby
|
144
|
-
r.
|
152
|
+
r.delete_owned_by('client.1')
|
145
153
|
# => 8
|
146
154
|
```
|
147
155
|
|
156
|
+
All tokens without an owner:
|
157
|
+
```ruby
|
158
|
+
r.delete_without_owner
|
159
|
+
# => 1
|
160
|
+
```
|
161
|
+
|
162
|
+
All tokens:
|
163
|
+
```ruby
|
164
|
+
r.delete_all
|
165
|
+
# => 99
|
166
|
+
```
|
167
|
+
|
148
168
|
### Serialization
|
149
169
|
|
150
170
|
redis_token uses native Marshal class for data serialization by default. You can override it like this:
|
data/lib/redis_token/version.rb
CHANGED
data/lib/redis_token.rb
CHANGED
@@ -9,7 +9,7 @@ require 'time'
|
|
9
9
|
class RedisToken
|
10
10
|
# Token lives 14 days by default
|
11
11
|
DEFAULT_TTL = 14 * 24 * 60 * 60
|
12
|
-
DEFAULT_PREFIX = 'tokens
|
12
|
+
DEFAULT_PREFIX = 'tokens'.freeze
|
13
13
|
|
14
14
|
attr_reader :redis
|
15
15
|
attr_accessor :default_ttl
|
@@ -43,18 +43,19 @@ class RedisToken
|
|
43
43
|
|
44
44
|
# Create a new token
|
45
45
|
#
|
46
|
-
# @param [String] owner owner of a token, e.g. 'client.1' or 'user-123'
|
47
46
|
# @param [Hash] args
|
47
|
+
# @option args [String] :owner owner of a token, e.g. 'client.1' or 'user-123'
|
48
48
|
# @option args [String] :token (SecureRandom.hex(16)) user defined token
|
49
49
|
# @option args :payload
|
50
50
|
# @option args [Integer] :ttl redefines the default ttl
|
51
51
|
#
|
52
52
|
# @return [String] a new token
|
53
|
-
def create(
|
54
|
-
raise 'owner should be specified' unless owner
|
55
|
-
|
53
|
+
def create(args = {})
|
56
54
|
token = args[:token] || generate_token
|
57
|
-
value = {
|
55
|
+
value = { at: Time.now.to_i }
|
56
|
+
|
57
|
+
owner = args[:owner]
|
58
|
+
value[:owner] = owner if owner
|
58
59
|
|
59
60
|
payload = args[:payload]
|
60
61
|
value[:payload] = payload if payload
|
@@ -106,6 +107,7 @@ class RedisToken
|
|
106
107
|
key = token_to_key(token)
|
107
108
|
value = redis_get(key)
|
108
109
|
return false unless value
|
110
|
+
|
109
111
|
value[:payload] = args[:payload]
|
110
112
|
|
111
113
|
key_ttl = args[:ttl] || @redis.ttl(key)
|
@@ -124,7 +126,21 @@ class RedisToken
|
|
124
126
|
#
|
125
127
|
# @return [Enumerator]
|
126
128
|
def owned_by(owner)
|
127
|
-
owned_tokens(owner)
|
129
|
+
owned_tokens(owner)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Tokens without an owner
|
133
|
+
#
|
134
|
+
# @return [Enumerator]
|
135
|
+
def without_owner
|
136
|
+
owned_tokens
|
137
|
+
end
|
138
|
+
|
139
|
+
# All tokens
|
140
|
+
#
|
141
|
+
# @return [Enumerator]
|
142
|
+
def all
|
143
|
+
all_tokens
|
128
144
|
end
|
129
145
|
|
130
146
|
# Delete a token
|
@@ -132,7 +148,7 @@ class RedisToken
|
|
132
148
|
# @param [String] token
|
133
149
|
#
|
134
150
|
# @return [Boolean]
|
135
|
-
def
|
151
|
+
def delete(token)
|
136
152
|
key = token_to_key(token)
|
137
153
|
value = redis_get(key)
|
138
154
|
return false unless value
|
@@ -145,24 +161,30 @@ class RedisToken
|
|
145
161
|
true
|
146
162
|
end
|
147
163
|
|
148
|
-
alias delete
|
164
|
+
alias del delete
|
149
165
|
|
150
166
|
# Delete all tokens of an owner
|
151
167
|
#
|
152
168
|
# @params [String] owner
|
153
169
|
#
|
154
170
|
# @return [Integer] number of deleted tokens
|
155
|
-
def
|
156
|
-
|
157
|
-
|
158
|
-
del(token)
|
159
|
-
deleted += 1
|
160
|
-
end
|
171
|
+
def delete_owned_by(owner)
|
172
|
+
delete_tokens(owned_tokens(owner))
|
173
|
+
end
|
161
174
|
|
162
|
-
|
175
|
+
# Delete tokens without an owner
|
176
|
+
#
|
177
|
+
# @return [Integer] number of deleted tokens
|
178
|
+
def delete_without_owner
|
179
|
+
delete_tokens(owned_tokens)
|
163
180
|
end
|
164
181
|
|
165
|
-
|
182
|
+
# Delete all tokens
|
183
|
+
#
|
184
|
+
# @return [Integer] number of deleted tokens
|
185
|
+
def delete_all
|
186
|
+
delete_tokens(all_tokens)
|
187
|
+
end
|
166
188
|
|
167
189
|
# Retrieve the remaining ttl of a token
|
168
190
|
#
|
@@ -201,7 +223,7 @@ class RedisToken
|
|
201
223
|
# end
|
202
224
|
# end
|
203
225
|
#
|
204
|
-
# RedisToken.new
|
226
|
+
# r = RedisToken.new.use(MsgPackSerializer)
|
205
227
|
#
|
206
228
|
# @param [Object] serializer_class
|
207
229
|
#
|
@@ -226,15 +248,19 @@ class RedisToken
|
|
226
248
|
end
|
227
249
|
|
228
250
|
def token_to_key(token)
|
229
|
-
"#{@prefix}
|
251
|
+
"#{@prefix}.t.#{token}"
|
230
252
|
end
|
231
253
|
|
232
254
|
def token_to_owner(owner, token)
|
233
|
-
"#{@prefix}
|
255
|
+
"#{@prefix}.o.#{owner}.#{token}"
|
234
256
|
end
|
235
257
|
|
236
258
|
def owner_key_to_token(owner, key)
|
237
|
-
key.sub("#{@prefix}
|
259
|
+
key.sub("#{@prefix}.o.#{owner}.", '')
|
260
|
+
end
|
261
|
+
|
262
|
+
def key_to_token(key)
|
263
|
+
key.sub("#{@prefix}.t.", '')
|
238
264
|
end
|
239
265
|
|
240
266
|
def redis_get(key)
|
@@ -243,8 +269,16 @@ class RedisToken
|
|
243
269
|
serializer.unpack(value)
|
244
270
|
end
|
245
271
|
|
246
|
-
def owned_tokens(owner)
|
247
|
-
|
272
|
+
def owned_tokens(owner = nil)
|
273
|
+
iterator(owner)
|
274
|
+
end
|
275
|
+
|
276
|
+
def all_tokens
|
277
|
+
iterator(nil, true)
|
278
|
+
end
|
279
|
+
|
280
|
+
def iterator(owner = nil, all = false)
|
281
|
+
mask = all ? "#{@prefix}.t.*" : "#{@prefix}.o.#{owner}.*"
|
248
282
|
|
249
283
|
Enumerator.new do |y|
|
250
284
|
cursor = '0'
|
@@ -252,8 +286,7 @@ class RedisToken
|
|
252
286
|
cursor, r = @redis.scan(cursor, match: mask)
|
253
287
|
|
254
288
|
r.each do |key|
|
255
|
-
|
256
|
-
y << token
|
289
|
+
y << (all ? key_to_token(key) : owner_key_to_token(owner, key))
|
257
290
|
end
|
258
291
|
|
259
292
|
break if cursor == '0'
|
@@ -261,12 +294,19 @@ class RedisToken
|
|
261
294
|
end
|
262
295
|
end
|
263
296
|
|
297
|
+
def delete_tokens(enum)
|
298
|
+
enum.reduce(0) do |deleted, token|
|
299
|
+
del(token)
|
300
|
+
deleted += 1
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
264
304
|
def serializer
|
265
305
|
@serializer ||= @serializer_class.new
|
266
306
|
end
|
267
307
|
|
268
308
|
# Some serializers can't store symbols out of the box
|
269
309
|
def hash_get(hash, sym)
|
270
|
-
hash.
|
310
|
+
hash.fetch(sym, hash[sym.to_s])
|
271
311
|
end
|
272
312
|
end
|