redis_token 0.0.6 → 0.0.7
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.
- 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
|