Class: Cloak::Redis

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Utils
Defined in:
lib/cloak/redis.rb

Overview

don’t extend Redis so we can confirm operations are safe before adding

Constant Summary

Constants included from Utils

Utils::HLL_ELEMENT_NONCE, Utils::KEY_NONCE, Utils::MEMBER_NONCE

Instance Method Summary collapse

Constructor Details

#initialize(key: nil, **options) ⇒ Redis

Returns a new instance of Redis.



15
16
17
18
# File 'lib/cloak/redis.rb', line 15

def initialize(key: nil, **options)
  @redis = ::Redis.new(**options)
  create_encryptor(key)
end

Instance Method Details

#bitcount(key, start = 0, stop = -1)) ⇒ Object

append not supported



232
233
234
235
236
# File 'lib/cloak/redis.rb', line 232

def bitcount(key, start = 0, stop = -1)
  on_result(@redis.get(encrypt_key(key))) do |res|
    decrypt_value(res)[start..stop].unpack1("B*").count("1")
  end
end

#bitpos(key, bit, start = nil, stop = nil) ⇒ Object

bitop not supported



240
241
242
243
244
245
# File 'lib/cloak/redis.rb', line 240

def bitpos(key, bit, start = nil, stop = nil)
  on_result(@redis.get(encrypt_key(key))) do |res|
    pos = decrypt_value(res)[(start || 0)..(stop || -1)].unpack1("B*").index(bit.to_s)
    pos ? pos + (start.to_i * 8) : -1
  end
end

#blpop(*args) ⇒ Object



292
293
294
# File 'lib/cloak/redis.rb', line 292

def blpop(*args)
  _bpop(:blpop, args)
end

#brpop(*args) ⇒ Object



296
297
298
# File 'lib/cloak/redis.rb', line 296

def brpop(*args)
  _bpop(:brpop, args)
end

#brpoplpush(source, destination, deprecated_timeout = 0, timeout: deprecated_timeout) ⇒ Object



300
301
302
# File 'lib/cloak/redis.rb', line 300

def brpoplpush(source, destination, deprecated_timeout = 0, timeout: deprecated_timeout)
  @redis.brpoplpush(encrypt_key(source), encrypt_key(destination), timeout: timeout)
end

#bzpopmax(*args) ⇒ Object



458
459
460
# File 'lib/cloak/redis.rb', line 458

def bzpopmax(*args)
  _bpop(:bzpopmax, args, zset: true)
end

#bzpopmin(*args) ⇒ Object



462
463
464
# File 'lib/cloak/redis.rb', line 462

def bzpopmin(*args)
  _bpop(:bzpopmin, args, zset: true)
end

#debug(*args) ⇒ Object



30
31
32
33
# File 'lib/cloak/redis.rb', line 30

def debug(*args)
  args[1] = encrypt_key(args[1]) if args[0] == "object"
  @redis.debug(*args)
end

#decr(key) ⇒ Object



140
141
142
# File 'lib/cloak/redis.rb', line 140

def decr(key)
  @redis.decr(encrypt_key(key))
end

#decrby(key, decrement) ⇒ Object



144
145
146
# File 'lib/cloak/redis.rb', line 144

def decrby(key, decrement)
  @redis.decrby(encrypt_key(key), decrement)
end

#del(*keys) ⇒ Object



87
88
89
# File 'lib/cloak/redis.rb', line 87

def del(*keys)
  @redis.del(*keys.map { |k| encrypt_key(k) })
end

#dump(key) ⇒ Object



79
80
81
# File 'lib/cloak/redis.rb', line 79

def dump(key)
  @redis.dump(encrypt_key(key))
end

#echo(value) ⇒ Object



45
46
47
48
49
# File 'lib/cloak/redis.rb', line 45

def echo(value)
  on_result(@redis.echo(encrypt_value(value))) do |res|
    decrypt_value(res)
  end
end

#exists(*keys) ⇒ Object



95
96
97
# File 'lib/cloak/redis.rb', line 95

def exists(*keys)
  @redis.exists(*keys.map { |k| encrypt_key(k) })
end

#exists?(*keys) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/cloak/redis.rb', line 99

def exists?(*keys)
  @redis.exists?(*keys.map { |k| encrypt_key(k) })
end

#expire(key, seconds) ⇒ Object



55
56
57
# File 'lib/cloak/redis.rb', line 55

def expire(key, seconds)
  @redis.expire(encrypt_key(key), seconds)
end

#expireat(key, unix_time) ⇒ Object



59
60
61
# File 'lib/cloak/redis.rb', line 59

def expireat(key, unix_time)
  @redis.expireat(encrypt_key(key), unix_time)
end

#get(key) ⇒ Object



194
195
196
197
198
# File 'lib/cloak/redis.rb', line 194

def get(key)
  on_result(@redis.get(encrypt_key(key))) do |res|
    decrypt_value(res)
  end
end

#getbit(key, offset) ⇒ Object

TODO raise “ERR bit offset is not an integer or out of range” when needed



223
224
225
226
227
228
# File 'lib/cloak/redis.rb', line 223

def getbit(key, offset)
  on_result(@redis.get(encrypt_key(key))) do |res|
    v = decrypt_value(res)
    v.nil? ? 0 : v.unpack1("B*")[offset].to_i
  end
end

#getrange(key, start, stop) ⇒ Object

setrange not supported



214
215
216
217
218
# File 'lib/cloak/redis.rb', line 214

def getrange(key, start, stop)
  on_result(@redis.get(encrypt_key(key))) do |res|
    decrypt_value(res)[start..stop]
  end
end

#getset(key, value) ⇒ Object



247
248
249
250
251
# File 'lib/cloak/redis.rb', line 247

def getset(key, value)
  on_result(@redis.getset(encrypt_key(key), encrypt_value(value))) do |res|
    decrypt_value(res)
  end
end

#hdel(key, *fields) ⇒ Object



593
594
595
596
# File 'lib/cloak/redis.rb', line 593

def hdel(key, *fields)
  ek = encrypt_key(key)
  @redis.hdel(ek, *fields.map { |v| encrypt_field(ek, v) })
end

#hexists(key, field) ⇒ Object



598
599
600
601
# File 'lib/cloak/redis.rb', line 598

def hexists(key, field)
  ek = encrypt_key(key)
  @redis.hexists(ek, encrypt_field(ek, field))
end

#hget(key, field) ⇒ Object



572
573
574
575
576
577
# File 'lib/cloak/redis.rb', line 572

def hget(key, field)
  ek = encrypt_key(key)
  on_result(@redis.hget(ek, encrypt_field(ek, field))) do |res|
    decrypt_value(res)
  end
end

#hgetall(key) ⇒ Object



627
628
629
630
631
632
# File 'lib/cloak/redis.rb', line 627

def hgetall(key)
  ek = encrypt_key(key)
  on_result(@redis.hgetall(ek)) do |res|
    res.map { |f, v| [decrypt_field(ek, f), decrypt_value(v)] }.to_h
  end
end

#hincrby(key, field, increment) ⇒ Object



603
604
605
606
# File 'lib/cloak/redis.rb', line 603

def hincrby(key, field, increment)
  ek = encrypt_key(key)
  @redis.hincrby(ek, encrypt_field(ek, field), increment)
end

#hincrbyfloat(key, field, increment) ⇒ Object



608
609
610
611
# File 'lib/cloak/redis.rb', line 608

def hincrbyfloat(key, field, increment)
  ek = encrypt_key(key)
  @redis.hincrbyfloat(ek, encrypt_field(ek, field), increment)
end

#hkeys(key) ⇒ Object



613
614
615
616
617
618
# File 'lib/cloak/redis.rb', line 613

def hkeys(key)
  ek = encrypt_key(key)
  on_result(@redis.hkeys(ek)) do |res|
    res.map { |v| decrypt_field(ek, v) }
  end
end

#hlen(key) ⇒ Object



546
547
548
# File 'lib/cloak/redis.rb', line 546

def hlen(key)
  @redis.hlen(encrypt_key(key))
end

#hmget(key, *fields, &blk) ⇒ Object



579
580
581
582
583
584
# File 'lib/cloak/redis.rb', line 579

def hmget(key, *fields, &blk)
  ek = encrypt_key(key)
  on_result(@redis.hmget(ek, *fields.map { |f| encrypt_field(ek, f) }, &blk)) do |res|
    res.map { |v| decrypt_value(v) }
  end
end

#hmset(key, *attrs) ⇒ Object



562
563
564
565
# File 'lib/cloak/redis.rb', line 562

def hmset(key, *attrs)
  ek = encrypt_key(key)
  @redis.hset(ek, attrs.map.with_index { |v, i| i % 2 == 0 ? encrypt_field(ek, v) : encrypt_value(v) })
end

#hscan(key, cursor, count: nil) ⇒ Object

match option not supported



657
658
659
660
661
662
# File 'lib/cloak/redis.rb', line 657

def hscan(key, cursor, count: nil)
  ek = encrypt_key(key)
  on_result(@redis.hscan(ek, cursor, count: count)) do |res|
    [res[0], res[1].map { |v| [decrypt_field(ek, v[0]), decrypt_value(v[1])] }]
  end
end

#hscan_each(key, **options, &block) ⇒ Object

match redis



665
666
667
668
669
670
671
672
673
674
675
# File 'lib/cloak/redis.rb', line 665

def hscan_each(key, **options, &block)
  return to_enum(:hscan_each, key, **options) unless block_given?

  cursor = 0
  loop do
    # hscan encrypts key
    cursor, values = hscan(key, cursor, **options)
    values.each(&block)
    break if cursor == "0"
  end
end

#hset(key, *attrs) ⇒ Object



550
551
552
553
554
555
# File 'lib/cloak/redis.rb', line 550

def hset(key, *attrs)
  attrs = attrs.first.flatten if attrs.size == 1 && attrs.first.is_a?(Hash)

  ek = encrypt_key(key)
  @redis.hset(ek, attrs.map.with_index { |v, i| i % 2 == 0 ? encrypt_field(ek, v) : encrypt_value(v) })
end

#hsetnx(key, field, value) ⇒ Object



557
558
559
560
# File 'lib/cloak/redis.rb', line 557

def hsetnx(key, field, value)
  ek = encrypt_key(key)
  @redis.hsetnx(ek, encrypt_field(ek, field), encrypt_value(value))
end

#hvals(key) ⇒ Object



620
621
622
623
624
625
# File 'lib/cloak/redis.rb', line 620

def hvals(key)
  ek = encrypt_key(key)
  on_result(@redis.hvals(ek)) do |res|
    res.map { |v| decrypt_value(v) }
  end
end

#incr(key) ⇒ Object



148
149
150
# File 'lib/cloak/redis.rb', line 148

def incr(key)
  @redis.incr(encrypt_key(key))
end

#incrby(key, increment) ⇒ Object



152
153
154
# File 'lib/cloak/redis.rb', line 152

def incrby(key, increment)
  @redis.incrby(encrypt_key(key), increment)
end

#incrbyfloat(key, increment) ⇒ Object



156
157
158
# File 'lib/cloak/redis.rb', line 156

def incrbyfloat(key, increment)
  @redis.incrbyfloat(encrypt_key(key), increment)
end

#keys(pattern = "*") ⇒ Object

could match in-memory



104
105
106
107
108
109
# File 'lib/cloak/redis.rb', line 104

def keys(pattern = "*")
  raise "Only * pattern supported" if pattern != "*"
  on_result(@redis.keys(pattern)) do |res|
    res.map { |k| decrypt_key(k) }
  end
end

#lindex(key, index) ⇒ Object



304
305
306
307
308
# File 'lib/cloak/redis.rb', line 304

def lindex(key, index)
  on_result(@redis.lindex(encrypt_key(key), index)) do |res|
    decrypt_element(res)
  end
end

#linsert(key, where, pivot, value) ⇒ Object



310
311
312
# File 'lib/cloak/redis.rb', line 310

def linsert(key, where, pivot, value)
  @redis.linsert(encrypt_key(key), where, pivot, encrypt_element(value))
end

#llen(key) ⇒ Object



260
261
262
# File 'lib/cloak/redis.rb', line 260

def llen(key)
  @redis.llen(encrypt_key(key))
end

#lpop(key) ⇒ Object



280
281
282
# File 'lib/cloak/redis.rb', line 280

def lpop(key)
  @redis.lpop(encrypt_key(key))
end

#lpush(key, value) ⇒ Object



264
265
266
# File 'lib/cloak/redis.rb', line 264

def lpush(key, value)
  @redis.lpush(encrypt_key(key), value.is_a?(Array) ? value.map { |v| encrypt_element(v) } : encrypt_element(value))
end

#lpushx(key, value) ⇒ Object



268
269
270
# File 'lib/cloak/redis.rb', line 268

def lpushx(key, value)
  @redis.lpushx(encrypt_key(key), encrypt_element(value))
end

#lrange(key, start, stop) ⇒ Object



314
315
316
# File 'lib/cloak/redis.rb', line 314

def lrange(key, start, stop)
  @redis.lrange(encrypt_key(key), start, stop)
end

#lset(key, index, value) ⇒ Object

lrem not possible with random nonce



320
321
322
# File 'lib/cloak/redis.rb', line 320

def lset(key, index, value)
  @redis.lset(encrypt_key(key), index, encrypt_element(value))
end

#ltrim(key, start, stop) ⇒ Object



324
325
326
# File 'lib/cloak/redis.rb', line 324

def ltrim(key, start, stop)
  @redis.ltrim(encrypt_key(key), start, stop)
end

#mapped_hmget(key, *fields) ⇒ Object



586
587
588
589
590
591
# File 'lib/cloak/redis.rb', line 586

def mapped_hmget(key, *fields)
  ek = encrypt_key(key)
  on_result(@redis.mapped_hmget(ek, *fields.map { |f| encrypt_field(ek, f) })) do |res|
    res.map { |f, v| [decrypt_field(ek, f), decrypt_value(v)] }.to_h
  end
end

#mapped_hmset(key, hash) ⇒ Object

match redis



568
569
570
# File 'lib/cloak/redis.rb', line 568

def mapped_hmset(key, hash)
  hmset(key, hash.to_a.flatten)
end

#mapped_mget(*keys) ⇒ Object



206
207
208
209
210
# File 'lib/cloak/redis.rb', line 206

def mapped_mget(*keys)
  on_result(@redis.mapped_mget(*keys.map { |k| encrypt_key(k) })) do |res|
    res.map { |k, v| [decrypt_key(k), decrypt_value(v)] }.to_h
  end
end

#mapped_mset(hash) ⇒ Object

match redis



181
182
183
# File 'lib/cloak/redis.rb', line 181

def mapped_mset(hash)
  mset(hash.to_a.flatten)
end

#mapped_msetnx(hash) ⇒ Object

match redis



190
191
192
# File 'lib/cloak/redis.rb', line 190

def mapped_msetnx(hash)
  msetnx(hash.to_a.flatten)
end

#mget(*keys, &blk) ⇒ Object



200
201
202
203
204
# File 'lib/cloak/redis.rb', line 200

def mget(*keys, &blk)
  on_result(@redis.mget(*keys.map { |k| encrypt_key(k) }, &blk)) do |res|
    res.map { |v| decrypt_value(v) }
  end
end

#move(key, db) ⇒ Object



111
112
113
# File 'lib/cloak/redis.rb', line 111

def move(key, db)
  @redis.move(encrypt_key(key), db)
end

#mset(*args) ⇒ Object



176
177
178
# File 'lib/cloak/redis.rb', line 176

def mset(*args)
  @redis.mset(args.map.with_index { |v, i| i % 2 == 0 ? encrypt_key(v) : encrypt_value(v) })
end

#msetnx(*args) ⇒ Object



185
186
187
# File 'lib/cloak/redis.rb', line 185

def msetnx(*args)
  @redis.msetnx(args.map.with_index { |v, i| i % 2 == 0 ? encrypt_key(v) : encrypt_value(v) })
end

#multi(&block) ⇒ Object

Raises:



25
26
27
28
# File 'lib/cloak/redis.rb', line 25

def multi(&block)
  raise Error, "multi with block parameter not supported yet" if block&.arity != 0
  @redis.multi(&block)
end

#object(*args) ⇒ Object



115
116
117
118
# File 'lib/cloak/redis.rb', line 115

def object(*args)
  args[1] = encrypt_key(args[1]) if args.size > 1
  @redis.object(*args)
end

#persist(key) ⇒ Object



51
52
53
# File 'lib/cloak/redis.rb', line 51

def persist(key)
  @redis.persist(encrypt_key(key))
end

#pexpire(key, milliseconds) ⇒ Object



67
68
69
# File 'lib/cloak/redis.rb', line 67

def pexpire(key, milliseconds)
  @redis.pexpire(encrypt_key(key), milliseconds)
end

#pexpireat(key, ms_unix_time) ⇒ Object



71
72
73
# File 'lib/cloak/redis.rb', line 71

def pexpireat(key, ms_unix_time)
  @redis.pexpireat(encrypt_key(key), ms_unix_time)
end

#pfadd(key, member) ⇒ Object



717
718
719
# File 'lib/cloak/redis.rb', line 717

def pfadd(key, member)
  @redis.pfadd(encrypt_key(key), member.is_a?(Array) ? member.map { |v| encrypt_hll_element(v) } : encrypt_hll_element(member))
end

#pfcount(*keys) ⇒ Object



721
722
723
# File 'lib/cloak/redis.rb', line 721

def pfcount(*keys)
  @redis.pfcount(*keys.map { |k| encrypt_key(k) })
end

#pfmerge(dest_key, *source_key) ⇒ Object



725
726
727
# File 'lib/cloak/redis.rb', line 725

def pfmerge(dest_key, *source_key)
  @redis.pfmerge(encrypt_key(dest_key), *source_key.map { |k| encrypt_key(k) })
end

#ping(message = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/cloak/redis.rb', line 35

def ping(message = nil)
  if message.nil?
    @redis.ping
  else
    on_result(@redis.ping(encrypt_value(message))) do |res|
      decrypt_value(res)
    end
  end
end

#pipelined(&block) ⇒ Object

Raises:



20
21
22
23
# File 'lib/cloak/redis.rb', line 20

def pipelined(&block)
  raise Error, "pipelined with block parameter not supported yet" if block&.arity != 0
  @redis.pipelined(&block)
end

#psetex(key, ttl, value) ⇒ Object



168
169
170
# File 'lib/cloak/redis.rb', line 168

def psetex(key, ttl, value)
  @redis.psetex(encrypt_key(key), ttl, encrypt_value(value))
end

#pttl(key) ⇒ Object



75
76
77
# File 'lib/cloak/redis.rb', line 75

def pttl(key)
  @redis.pttl(encrypt_key(key))
end

#randomkeyObject



120
121
122
123
124
# File 'lib/cloak/redis.rb', line 120

def randomkey
  on_result(@redis.randomkey) do |res|
    res.nil? ? res : decrypt_key(res)
  end
end

#rename(old_name, new_name) ⇒ Object



126
127
128
# File 'lib/cloak/redis.rb', line 126

def rename(old_name, new_name)
  @redis.rename(encrypt_key(old_name), encrypt_key(new_name))
end

#renamenx(old_name, new_name) ⇒ Object



130
131
132
# File 'lib/cloak/redis.rb', line 130

def renamenx(old_name, new_name)
  @redis.renamenx(encrypt_key(old_name), encrypt_key(new_name))
end

#restore(key, ttl, serialized_value, replace: nil) ⇒ Object



83
84
85
# File 'lib/cloak/redis.rb', line 83

def restore(key, ttl, serialized_value, replace: nil)
  @redis.restore(encrypt_key(key), ttl, serialized_value, replace: replace)
end

#rpop(key) ⇒ Object



284
285
286
# File 'lib/cloak/redis.rb', line 284

def rpop(key)
  @redis.rpop(encrypt_key(key))
end

#rpoplpush(source, destination) ⇒ Object



288
289
290
# File 'lib/cloak/redis.rb', line 288

def rpoplpush(source, destination)
  @redis.rpoplpush(encrypt_key(source), encrypt_key(destination))
end

#rpush(key, value) ⇒ Object



272
273
274
# File 'lib/cloak/redis.rb', line 272

def rpush(key, value)
  @redis.rpush(encrypt_key(key), value.is_a?(Array) ? value.map { |v| encrypt_element(v) } : encrypt_element(value))
end

#rpushx(key, value) ⇒ Object



276
277
278
# File 'lib/cloak/redis.rb', line 276

def rpushx(key, value)
  @redis.rpushx(encrypt_key(key), encrypt_element(value))
end

#sadd(key, member) ⇒ Object



332
333
334
# File 'lib/cloak/redis.rb', line 332

def sadd(key, member)
  @redis.sadd(encrypt_key(key), encrypt_member(member))
end

#sadd?(key, member) ⇒ Boolean

Returns:

  • (Boolean)


336
337
338
# File 'lib/cloak/redis.rb', line 336

def sadd?(key, member)
  @redis.sadd?(encrypt_key(key), encrypt_member(member))
end

#scan(cursor, count: nil) ⇒ Object

match option not supported



638
639
640
641
642
# File 'lib/cloak/redis.rb', line 638

def scan(cursor, count: nil)
  on_result(@redis.scan(cursor, count: count)) do |res|
    [res[0], res[1].map { |v| decrypt_key(v) }]
  end
end

#scan_each(**options, &block) ⇒ Object

match redis



645
646
647
648
649
650
651
652
653
654
# File 'lib/cloak/redis.rb', line 645

def scan_each(**options, &block)
  return to_enum(:scan_each, **options) unless block_given?

  cursor = 0
  loop do
    cursor, keys = scan(cursor, **options)
    keys.each(&block)
    break if cursor == "0"
  end
end

#scard(key) ⇒ Object



328
329
330
# File 'lib/cloak/redis.rb', line 328

def scard(key)
  @redis.scard(encrypt_key(key))
end

#sdiff(*keys) ⇒ Object



382
383
384
385
386
# File 'lib/cloak/redis.rb', line 382

def sdiff(*keys)
  on_result(@redis.sdiff(*keys.map { |k| encrypt_key(k) })) do |res|
    res.map { |v| decrypt_member(v) }
  end
end

#sdiffstore(destination, *keys) ⇒ Object



388
389
390
# File 'lib/cloak/redis.rb', line 388

def sdiffstore(destination, *keys)
  @redis.sdiffstore(encrypt_key(destination), *keys.map { |k| encrypt_key(k) })
end

#set(key, value, **options) ⇒ Object



160
161
162
# File 'lib/cloak/redis.rb', line 160

def set(key, value, **options)
  @redis.set(encrypt_key(key), encrypt_value(value), **options)
end

#setex(key, ttl, value) ⇒ Object



164
165
166
# File 'lib/cloak/redis.rb', line 164

def setex(key, ttl, value)
  @redis.setex(encrypt_key(key), ttl, encrypt_value(value))
end

#setnx(key, value) ⇒ Object



172
173
174
# File 'lib/cloak/redis.rb', line 172

def setnx(key, value)
  @redis.setnx(encrypt_key(key), ttl, encrypt_value(value))
end

#sinter(*keys) ⇒ Object



392
393
394
395
396
# File 'lib/cloak/redis.rb', line 392

def sinter(*keys)
  on_result(@redis.sinter(*keys.map { |k| encrypt_key(k) })) do |res|
    res.map { |v| decrypt_member(v) }
  end
end

#sinterstore(destination, *keys) ⇒ Object



398
399
400
# File 'lib/cloak/redis.rb', line 398

def sinterstore(destination, *keys)
  @redis.sinterstore(encrypt_key(destination), *keys.map { |k| encrypt_key(k) })
end

#sismember(key, member) ⇒ Object



372
373
374
# File 'lib/cloak/redis.rb', line 372

def sismember(key, member)
  @redis.sismember(encrypt_key(key), encrypt_member(member))
end

#smembers(key) ⇒ Object



376
377
378
379
380
# File 'lib/cloak/redis.rb', line 376

def smembers(key)
  on_result(@redis.smembers(encrypt_key(key))) do |res|
    res.map { |v| decrypt_member(v) }
  end
end

#smove(source, destination, member) ⇒ Object



368
369
370
# File 'lib/cloak/redis.rb', line 368

def smove(source, destination, member)
  @redis.smove(encrypt_key(source), encrypt_key(destination), encrypt_member(member))
end

#spop(key, count = nil) ⇒ Object



348
349
350
351
352
353
354
355
356
# File 'lib/cloak/redis.rb', line 348

def spop(key, count = nil)
  on_result(@redis.spop(encrypt_key(key))) do |res|
    if count.nil?
      decrypt_member(res)
    else
      res.map { |v| decrypt_member(v) }
    end
  end
end

#srandmember(key, count = nil) ⇒ Object



358
359
360
361
362
363
364
365
366
# File 'lib/cloak/redis.rb', line 358

def srandmember(key, count = nil)
  on_result(@redis.srandmember(encrypt_key(key))) do |res|
    if count.nil?
      decrypt_member(res)
    else
      res.map { |v| decrypt_member(v) }
    end
  end
end

#srem(key, member) ⇒ Object



340
341
342
# File 'lib/cloak/redis.rb', line 340

def srem(key, member)
  @redis.srem(encrypt_key(key), encrypt_member(member))
end

#srem?(key, member) ⇒ Boolean

Returns:

  • (Boolean)


344
345
346
# File 'lib/cloak/redis.rb', line 344

def srem?(key, member)
  @redis.srem?(encrypt_key(key), encrypt_member(member))
end

#sscan(key, cursor, count: nil) ⇒ Object

match option not supported



698
699
700
701
702
# File 'lib/cloak/redis.rb', line 698

def sscan(key, cursor, count: nil)
  on_result(@redis.sscan(encrypt_key(key), cursor, count: count)) do |res|
    [res[0], res[1].map { |v| decrypt_member(v) }]
  end
end

#sscan_each(key, **options, &block) ⇒ Object

match redis



705
706
707
708
709
710
711
712
713
714
715
# File 'lib/cloak/redis.rb', line 705

def sscan_each(key, **options, &block)
  return to_enum(:sscan_each, key, **options) unless block_given?

  cursor = 0
  loop do
    # sscan encrypts key
    cursor, keys = sscan(key, cursor, **options)
    keys.each(&block)
    break if cursor == "0"
  end
end

#strlen(key) ⇒ Object

subtract nonce size (16) and auth tag (16)



254
255
256
257
258
# File 'lib/cloak/redis.rb', line 254

def strlen(key)
  on_result(@redis.strlen(encrypt_key(key))) do |res|
    res == 0 ? 0 : res - 32
  end
end

#sunion(*keys) ⇒ Object



402
403
404
405
406
# File 'lib/cloak/redis.rb', line 402

def sunion(*keys)
  on_result(@redis.sunion(*keys.map { |k| encrypt_key(k) })) do |res|
    res.map { |v| decrypt_member(v) }
  end
end

#sunionstore(destination, *keys) ⇒ Object



408
409
410
# File 'lib/cloak/redis.rb', line 408

def sunionstore(destination, *keys)
  @redis.sunionstore(encrypt_key(destination), *keys.map { |k| encrypt_key(k) })
end

#ttl(key) ⇒ Object



63
64
65
# File 'lib/cloak/redis.rb', line 63

def ttl(key)
  @redis.ttl(encrypt_key(key))
end

#type(key) ⇒ Object

sort not supported



136
137
138
# File 'lib/cloak/redis.rb', line 136

def type(key)
  @redis.type(encrypt_key(key))
end


91
92
93
# File 'lib/cloak/redis.rb', line 91

def unlink(*keys)
  @redis.unlink(*keys.map { |k| encrypt_key(k) })
end

#zadd(key, *args, **options) ⇒ Object



416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/cloak/redis.rb', line 416

def zadd(key, *args, **options)
  if args.size == 1 && args[0].is_a?(Array)
    args = args[0]
  elsif args.size == 2
    args = [args]
  else
    raise ArgumentError, "wrong number of arguments"
  end

  # convert score to numeric to avoid data leakage
  # if there's an issue with arguments
  @redis.zadd(encrypt_key(key), args.map { |v| [to_score(v[0]), encrypt_member(v[1])] }, **options)
end

#zcard(key) ⇒ Object



412
413
414
# File 'lib/cloak/redis.rb', line 412

def zcard(key)
  @redis.zcard(encrypt_key(key))
end

#zcount(key, min, max) ⇒ Object



534
535
536
# File 'lib/cloak/redis.rb', line 534

def zcount(key, min, max)
  @redis.zcount(encrypt_key(key), min, max)
end

#zincrby(key, increment, member) ⇒ Object



430
431
432
# File 'lib/cloak/redis.rb', line 430

def zincrby(key, increment, member)
  @redis.zincrby(encrypt_key(key), increment, encrypt_member(member))
end

#zinterstore(destination, keys, weights: nil, aggregate: nil) ⇒ Object



538
539
540
# File 'lib/cloak/redis.rb', line 538

def zinterstore(destination, keys, weights: nil, aggregate: nil)
  @redis.zinterstore(encrypt_key(destination), keys.map { |k| encrypt_key(k) }, weights: weights, aggregate: aggregate)
end

#zpopmax(key, count = nil) ⇒ Object



438
439
440
441
442
443
444
445
446
# File 'lib/cloak/redis.rb', line 438

def zpopmax(key, count = nil)
  on_result(@redis.zpopmax(encrypt_key(key), count)) do |res|
    if count.to_i > 1
      res.map { |v, s| [decrypt_member(v), s] }
    else
      [decrypt_member(res[0]), res[1]]
    end
  end
end

#zpopmin(key, count = nil) ⇒ Object



448
449
450
451
452
453
454
455
456
# File 'lib/cloak/redis.rb', line 448

def zpopmin(key, count = nil)
  on_result(@redis.zpopmin(encrypt_key(key), count)) do |res|
    if count.to_i > 1
      res.map { |v, s| [decrypt_member(v), s] }
    else
      [decrypt_member(res[0]), res[1]]
    end
  end
end

#zrange(key, start, stop, withscores: false, with_scores: withscores) ⇒ Object

can’t guarantee lexographical order without potentially fetching all elements



471
472
473
474
475
476
477
478
479
# File 'lib/cloak/redis.rb', line 471

def zrange(key, start, stop, withscores: false, with_scores: withscores)
  on_result(@redis.zrange(encrypt_key(key), start, stop, with_scores: with_scores)) do |res|
    if with_scores
      res.map { |v, s| [decrypt_member(v), s] }
    else
      res.map { |v| decrypt_member(v) }
    end
  end
end

#zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil) ⇒ Object

could guarantee lexographical order when limit not used



509
510
511
512
513
514
515
516
517
# File 'lib/cloak/redis.rb', line 509

def zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil)
  on_result(@redis.zrangebyscore(encrypt_key(key), min, max, with_scores: with_scores, limit: limit)) do |res|
    if with_scores
      res.map { |v, s| [decrypt_member(v), s] }
    else
      res.map { |v| decrypt_member(v) }
    end
  end
end

#zrank(key, member) ⇒ Object



492
493
494
# File 'lib/cloak/redis.rb', line 492

def zrank(key, member)
  @redis.zrank(encrypt_key(key), encrypt_member(member))
end

#zrem(key, member) ⇒ Object



434
435
436
# File 'lib/cloak/redis.rb', line 434

def zrem(key, member)
  @redis.zrem(encrypt_key(key), member.is_a?(Array) ? member.map { |v| encrypt_member(v) } : encrypt_member(member))
end

#zremrangebyrank(key, start, stop) ⇒ Object



500
501
502
# File 'lib/cloak/redis.rb', line 500

def zremrangebyrank(key, start, stop)
  @redis.zremrangebyrank(encrypt_key(key), start, stop)
end

#zremrangebyscore(key, min, max) ⇒ Object



530
531
532
# File 'lib/cloak/redis.rb', line 530

def zremrangebyscore(key, min, max)
  @redis.zremrangebyscore(encrypt_key(key), min, max)
end

#zrevrange(key, start, stop, withscores: false, with_scores: withscores) ⇒ Object

can’t guarantee lexographical order without potentially fetching all elements



482
483
484
485
486
487
488
489
490
# File 'lib/cloak/redis.rb', line 482

def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
  on_result(@redis.zrevrange(encrypt_key(key), start, stop, with_scores: with_scores)) do |res|
    if with_scores
      res.map { |v, s| [decrypt_member(v), s] }
    else
      res.map { |v| decrypt_member(v) }
    end
  end
end

#zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil) ⇒ Object

could guarantee lexographical order when limit not used



520
521
522
523
524
525
526
527
528
# File 'lib/cloak/redis.rb', line 520

def zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil)
  on_result(@redis.zrevrangebyscore(encrypt_key(key), max, min, with_scores: with_scores, limit: limit)) do |res|
    if with_scores
      res.map { |v, s| [decrypt_member(v), s] }
    else
      res.map { |v| decrypt_member(v) }
    end
  end
end

#zrevrank(key, member) ⇒ Object



496
497
498
# File 'lib/cloak/redis.rb', line 496

def zrevrank(key, member)
  @redis.zrevrank(encrypt_key(key), encrypt_member(member))
end

#zscan(key, cursor, count: nil) ⇒ Object

match option not supported



678
679
680
681
682
# File 'lib/cloak/redis.rb', line 678

def zscan(key, cursor, count: nil)
  on_result(@redis.zscan(encrypt_key(key), cursor, count: count)) do |res|
    [res[0], res[1].map { |v| [decrypt_member(v[0]), v[1]] }]
  end
end

#zscan_each(key, **options, &block) ⇒ Object

match redis



685
686
687
688
689
690
691
692
693
694
695
# File 'lib/cloak/redis.rb', line 685

def zscan_each(key, **options, &block)
  return to_enum(:zscan_each, key, **options) unless block_given?

  cursor = 0
  loop do
    # zscan encrypts key
    cursor, values = zscan(key, cursor, **options)
    values.each(&block)
    break if cursor == "0"
  end
end

#zscore(key, member) ⇒ Object



466
467
468
# File 'lib/cloak/redis.rb', line 466

def zscore(key, member)
  @redis.zscore(encrypt_key(key), encrypt_member(member))
end

#zunionstore(destination, keys, weights: nil, aggregate: nil) ⇒ Object



542
543
544
# File 'lib/cloak/redis.rb', line 542

def zunionstore(destination, keys, weights: nil, aggregate: nil)
  @redis.zunionstore(encrypt_key(destination), keys.map { |k| encrypt_key(k) }, weights: weights, aggregate: aggregate)
end