lib/redis_token.rb in redis_token-0.0.4 vs lib/redis_token.rb in redis_token-0.0.5
- old
+ new
@@ -1,6 +1,8 @@
require 'redis_token/version'
+require 'redis_token/serializers/native'
+
require 'redis'
require 'securerandom'
require 'time'
@@ -23,10 +25,11 @@
# RedisToken.new(redis, ttl: 5.days, prefix: 'project.tokens.')
#
# @param [Hash] args
# @option args [String] :prefix redis keys prefix (e.g. 'myproject.tokens.')
# @option args [Integer] :ttl token time to live value (14 days by default)
+ # @option args [Class] :serializer_class serialization class, see RedisToken::Serializers::Native, or #use method
#
# @return [RedisToken] a new RedisToken instance
def initialize(args = {}, opts = {})
@redis = if args.nil? || args.is_a?(Hash)
init_params(args)
@@ -39,28 +42,29 @@
# Create a new token
#
# @param [String] owner owner of a token, e.g. 'client.1' or 'user-123'
# @param [Hash] args
+ # @option args [String] :token (SecureRandom.hex(16)) user defined token
# @option args :payload
# @option args [Integer] :ttl redefines the default ttl
#
# @return [String] a new token
def create(owner, args = {})
raise 'owner should be specified' unless owner
token = args[:token] || generate_token
- value = { owner: owner, at: Time.now }
+ value = { owner: owner, at: Time.now.to_i }
payload = args[:payload]
value[:payload] = payload if payload
@created_value = value
key_ttl = args[:ttl] || @default_ttl
@redis.multi do |multi|
- multi.set(token_to_key(token), Marshal.dump(value), ex: key_ttl)
+ multi.set(token_to_key(token), serializer.pack(value), ex: key_ttl)
multi.set(token_to_owner(owner, token), nil, ex: key_ttl)
end
token
end
@@ -81,11 +85,11 @@
key_ttl = args[:ttl] || @default_ttl
@redis.multi do |multi|
multi.expire(key, key_ttl)
- multi.expire(token_to_owner(value[:owner], token), key_ttl)
+ multi.expire(token_to_owner(hash_get(value, :owner), token), key_ttl)
end
value
end
@@ -104,12 +108,12 @@
value[:payload] = args[:payload]
key_ttl = args[:ttl] || @redis.ttl(key)
@redis.multi do |multi|
- multi.set(key, Marshal.dump(value), ex: key_ttl)
- multi.expire(token_to_owner(value[:owner], token), key_ttl)
+ multi.set(key, serializer.pack(value), ex: key_ttl)
+ multi.expire(token_to_owner(hash_get(value, :owner), token), key_ttl)
end
true
end
@@ -117,11 +121,11 @@
#
# @param [String] owner
#
# @return [Enumerator]
def owned_by(owner)
- owned_tokens(owner).map { |token| [token, redis_get(token_to_key(token))]}
+ owned_tokens(owner).map { |token| [token, redis_get(token_to_key(token))] }
end
# Delete a token
#
# @param [String] token
@@ -132,11 +136,11 @@
value = redis_get(key)
return false unless value
@redis.multi do |multi|
multi.del(key)
- multi.del(token_to_owner(value[:owner], token))
+ multi.del(token_to_owner(hash_get(value, :owner), token))
end
true
end
@@ -164,19 +168,62 @@
# @return [Integer] ttl
def ttl(token)
@redis.ttl(token_to_key(token))
end
+ # Use custom serialization class
+ #
+ # Base serializer example:
+ # class RedisToken
+ # class Serializers
+ # class Native
+ # def pack(value)
+ # Marshal.dump(value)
+ # end
+ #
+ # def unpack(value)
+ # Marshal.load(value)
+ # end
+ # end
+ # end
+ # end
+ #
+ # MessagePack example:
+ # require 'msgpack'
+ #
+ # class MsgPackSerializer
+ # def pack(value)
+ # MessagePack.pack(value)
+ # end
+ #
+ # def unpack(value)
+ # MessagePack.unpack(value)
+ # end
+ # end
+ #
+ # RedisToken.new(prefix: PREFIX).use(MsgPackSerializer)
+ #
+ # @param [Object] serializer_class
+ #
+ # @return [RedisToken]
+ def use(serializer_class)
+ @serializer_class = serializer_class
+ self
+ end
+
private
def generate_token
SecureRandom.hex(16)
end
def init_params(args)
@default_ttl = args[:ttl] || DEFAULT_TTL
@prefix = args[:prefix]
+
+ @serializer_class = args[:serializer_class]
+ @serializer_class = Serializers::Native unless @serializer_class
end
def token_to_key(token)
"#{@prefix}#{token}"
end
@@ -190,27 +237,35 @@
end
def redis_get(key)
value = @redis.get(key)
return unless value
- Marshal.load(value)
+ serializer.unpack(value)
end
def owned_tokens(owner)
mask = "#{@prefix}#{owner}.*"
Enumerator.new do |y|
- cursor = 0
+ cursor = '0'
loop do
cursor, r = @redis.scan(cursor, match: mask)
- cursor = cursor.to_i
r.each do |key|
token = owner_key_to_token(owner, key)
y << token
end
- break if cursor == 0
+ break if cursor == '0'
end
end
+ end
+
+ def serializer
+ @serializer ||= @serializer_class.new
+ end
+
+ # Some serializers can't store symbols out of the box
+ def hash_get(hash, sym)
+ hash.key?(sym) ? hash[sym] : hash[sym.to_s]
end
end