aerospike 2.20.1 → 2.22.0

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.
@@ -18,17 +18,22 @@ module Aerospike
18
18
 
19
19
  private
20
20
  # Commands
21
- AUTHENTICATE = 0
22
- CREATE_USER = 1
23
- DROP_USER = 2
24
- SET_PASSWORD = 3
25
- CHANGE_PASSWORD = 4
26
- GRANT_ROLES = 5
27
- REVOKE_ROLES = 6
28
- #CREATE_ROLE = 8
29
- QUERY_USERS = 9
30
- #QUERY_ROLES = 10
31
- LOGIN = 20
21
+ AUTHENTICATE = 0
22
+ CREATE_USER = 1
23
+ DROP_USER = 2
24
+ SET_PASSWORD = 3
25
+ CHANGE_PASSWORD = 4
26
+ GRANT_ROLES = 5
27
+ REVOKE_ROLES = 6
28
+ QUERY_USERS = 9
29
+ CREATE_ROLE = 10
30
+ DROP_ROLE = 11
31
+ GRANT_PRIVILEGES = 12
32
+ REVOKE_PRIVILEGES = 13
33
+ SET_WHITELIST = 14
34
+ SET_QUOTAS = 15
35
+ QUERY_ROLES = 16
36
+ LOGIN = 20
32
37
 
33
38
  # Field IDs
34
39
  USER = 0
@@ -36,8 +41,17 @@ module Aerospike
36
41
  OLD_PASSWORD = 2
37
42
  CREDENTIAL = 3
38
43
  CLEAR_PASSWORD = 4
44
+ SESSION_TOKEN = 5
45
+ SESSION_TTL = 6
39
46
  ROLES = 10
40
- #PRIVILEGES = 11
47
+ ROLE = 11
48
+ PRIVILEGES = 12
49
+ ALLOWLIST = 13
50
+ READ_QUOTA = 14
51
+ WRITE_QUOTA = 15
52
+ READ_INFO = 16
53
+ WRITE_INFO = 17
54
+ CONNECTIONS = 18
41
55
 
42
56
  # Misc
43
57
  MSG_VERSION = 2
@@ -55,34 +69,6 @@ module Aerospike
55
69
  @data_offset = 8
56
70
  end
57
71
 
58
- def authenticate(conn, user, password)
59
- begin
60
- set_authenticate(user, password)
61
- conn.write(@data_buffer, @data_offset)
62
- conn.read(@data_buffer, HEADER_SIZE)
63
-
64
- result = @data_buffer.read(RESULT_CODE)
65
-
66
- # read the rest of the buffer
67
- size = @data_buffer.read_int64(0)
68
- length = (size & 0xFFFFFFFFFFFF) - HEADER_REMAINING
69
- conn.read(@data_buffer, length)
70
-
71
- raise Exceptions::Aerospike.new(result, "Authentication failed") if result != 0
72
- ensure
73
- Buffer.put(@data_buffer)
74
- end
75
- end
76
-
77
- def set_authenticate(user, password)
78
- write_header(LOGIN, 2)
79
- write_field_str(USER, user)
80
- write_field_bytes(CREDENTIAL, password)
81
- write_size
82
-
83
- return @data_offset
84
- end
85
-
86
72
  def create_user(cluster, policy, user, password, roles)
87
73
  write_header(CREATE_USER, 3)
88
74
  write_field_str(USER, user)
@@ -126,6 +112,61 @@ module Aerospike
126
112
  execute_command(cluster, policy)
127
113
  end
128
114
 
115
+ def create_role(cluster, policy, role_name, privileges = [], allowlist = [], read_quota = 0, write_quota = 0)
116
+ field_count = 1
117
+ field_count += 1 if privileges.size > 0
118
+ field_count += 1 if allowlist.size > 0
119
+ field_count += 1 if read_quota > 0
120
+ field_count += 1 if write_quota > 0
121
+
122
+ write_header(CREATE_ROLE, field_count)
123
+ write_field_str(ROLE, role_name)
124
+
125
+ write_privileges(privileges) if privileges.size > 0
126
+ write_allowlist(allowlist) if allowlist.size > 0
127
+
128
+ write_field_uint32(READ_QUOTA, read_quota) if read_quota > 0
129
+ write_field_uint32(WRITE_QUOTA, write_quota) if write_quota > 0
130
+
131
+ execute_command(cluster, policy)
132
+ end
133
+
134
+ def drop_role(cluster, policy, role)
135
+ write_header(DROP_ROLE, 1)
136
+ write_field_str(ROLE, role)
137
+ execute_command(cluster, policy)
138
+ end
139
+
140
+ def grant_privileges(cluster, policy, role, privileges)
141
+ write_header(GRANT_PRIVILEGES, 2)
142
+ write_field_str(ROLE, role)
143
+ write_privileges(privileges)
144
+ execute_command(cluster, policy)
145
+ end
146
+
147
+ def revoke_privileges(cluster, policy, role, privileges)
148
+ write_header(REVOKE_PRIVILEGES, 2)
149
+ write_field_str(ROLE, role)
150
+ write_privileges(privileges)
151
+ execute_command(cluster, policy)
152
+ end
153
+
154
+ def set_allowlist(cluster, policy, role, allowlist = [])
155
+ field_count = 1
156
+ field_count += 1 if allowlist.size > 0
157
+ write_header(SET_WHITELIST, field_count)
158
+ write_allowlist(allowlist) if allowlist.size > 0
159
+ execute_command(cluster, policy)
160
+ end
161
+
162
+ def set_quotas(cluster, policy, role, read_quota, write_quota)
163
+ write_header(SET_QUOTAS, 3)
164
+ write_field_str(ROLE, role)
165
+ write_field_uint32(READ_QUOTA, read_quota)
166
+ write_field_uint32(WRITE_QUOTA, write_quota)
167
+ execute_command(cluster, policy)
168
+ end
169
+
129
170
  def query_user(cluster, policy, user)
130
171
  # TODO: Remove the workaround in the future
131
172
  sleep(0.010)
@@ -152,6 +193,32 @@ module Aerospike
152
193
  end
153
194
  end
154
195
 
196
+ def query_role(cluster, policy, role)
197
+ # TODO: Remove the workaround in the future
198
+ sleep(0.010)
199
+
200
+ list = []
201
+ begin
202
+ write_header(QUERY_ROLES, 1)
203
+ write_field_str(ROLE, role)
204
+ list = read_roles(cluster, policy)
205
+ return (list.is_a?(Array) && list.length > 0 ? list.first : nil)
206
+ ensure
207
+ Buffer.put(@data_buffer)
208
+ end
209
+ end
210
+
211
+ def query_roles(cluster, policy)
212
+ # TODO: Remove the workaround in the future
213
+ sleep(0.010)
214
+ begin
215
+ write_header(QUERY_ROLES, 0)
216
+ return read_roles(cluster, policy)
217
+ ensure
218
+ Buffer.put(@data_buffer)
219
+ end
220
+ end
221
+
155
222
  def write_roles(roles)
156
223
  offset = @data_offset + FIELD_HEADER_SIZE
157
224
  @data_buffer.write_byte(roles.length.ord, offset)
@@ -174,6 +241,54 @@ module Aerospike
174
241
  @data_buffer.write_int64(size, 0)
175
242
  end
176
243
 
244
+ def write_privileges(privileges)
245
+ offset = @data_offset
246
+ @data_offset += FIELD_HEADER_SIZE
247
+ write_byte(privileges.size)
248
+
249
+ for privilege in privileges
250
+ write_byte(privilege.to_code)
251
+ if privilege.can_scope?
252
+ if privilege.set_name.to_s.size > 0 && privilege.namespace.to_s.size == 0
253
+ raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_PRIVILEGE, "Admin privilege #{privilege.namespace} has a set scope with an empty namespace")
254
+ end
255
+
256
+ write_str(privilege.namespace.to_s)
257
+ write_str(privilege.set_name.to_s)
258
+ else
259
+ if privilege.set_name.to_s.bytesize > 0 || privilege.namespace.to_s.bytesize > 0
260
+ raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_PRIVILEGE, "Admin global privilege #{privilege} can't have a namespace or set")
261
+ end
262
+ end
263
+ end
264
+
265
+ size = @data_offset - offset - FIELD_HEADER_SIZE
266
+ @data_offset = offset
267
+ write_field_header(PRIVILEGES, size)
268
+ @data_offset += size
269
+ end
270
+
271
+ def write_allowlist(allowlist)
272
+ offset = @data_offset
273
+ @data_offset += FIELD_HEADER_SIZE
274
+
275
+ comma = false
276
+ for addr in allowlist
277
+ if comma
278
+ write_byte(",")
279
+ else
280
+ comma = true
281
+ end
282
+
283
+ @data_offset += @data_buffer.write_binary(addr, @data_offset)
284
+ end
285
+
286
+ size = @data_offset - offset - FIELD_HEADER_SIZE
287
+ @data_offset = offset
288
+ write_field_header(ALLOWLIST, size)
289
+ @data_offset += size
290
+ end
291
+
177
292
  def write_header(command, field_count)
178
293
  # Authenticate header is almost all zeros
179
294
  i = @data_offset
@@ -186,12 +301,27 @@ module Aerospike
186
301
  @data_offset += 16
187
302
  end
188
303
 
304
+ def write_byte(b)
305
+ @data_offset += @data_buffer.write_byte(b, @data_offset)
306
+ end
307
+
308
+ def write_str(str)
309
+ @data_offset += @data_buffer.write_byte(str.bytesize, @data_offset)
310
+ @data_offset += @data_buffer.write_binary(str, @data_offset)
311
+ end
312
+
189
313
  def write_field_str(id, str)
190
314
  len = @data_buffer.write_binary(str, @data_offset+FIELD_HEADER_SIZE)
191
315
  write_field_header(id, len)
192
316
  @data_offset += len
193
317
  end
194
318
 
319
+ def write_field_uint32(id, val)
320
+ len = @data_buffer.write_uint32(val, @data_offset+FIELD_HEADER_SIZE)
321
+ write_field_header(id, len)
322
+ @data_offset += len
323
+ end
324
+
195
325
  def write_field_bytes(id, bytes)
196
326
  @data_buffer.write_binary(bytes, @data_offset+FIELD_HEADER_SIZE)
197
327
  write_field_header(id, bytes.bytesize)
@@ -251,7 +381,7 @@ module Aerospike
251
381
  raise e
252
382
  end
253
383
 
254
- raise Exceptions::Aerospike.new(result) if status > 0
384
+ raise Exceptions::Aerospike.new(status) if status > 0
255
385
 
256
386
  return list
257
387
  end
@@ -292,7 +422,7 @@ module Aerospike
292
422
  return (result_code == QUERY_END ? -1 : result_code)
293
423
  end
294
424
 
295
- userRoles = UserRoles.new
425
+ user_roles = UserRoles.new
296
426
  field_count = @data_buffer.read(@data_offset+3)
297
427
  @data_offset += HEADER_REMAINING
298
428
 
@@ -306,10 +436,17 @@ module Aerospike
306
436
 
307
437
  case id
308
438
  when USER
309
- userRoles.user = @data_buffer.read(@data_offset, len)
439
+ user_roles.user = @data_buffer.read(@data_offset, len)
310
440
  @data_offset += len
311
441
  when ROLES
312
- parse_roles(userRoles)
442
+ parse_roles(user_roles)
443
+ when READ_INFO
444
+ user_roles.read_info = parse_info
445
+ when WRITE_INFO
446
+ user_roles.write_info = parse_info
447
+ when CONNECTIONS
448
+ user_roles.conns_in_use = @data_buffer.read_int32(@data_offset)
449
+ @data_offset += len
313
450
  else
314
451
  @data_offset += len
315
452
  end
@@ -317,19 +454,19 @@ module Aerospike
317
454
  i = i.succ
318
455
  end
319
456
 
320
- next if userRoles.user == "" && userRoles.roles == nil
457
+ next if user_roles.user == "" && user_roles.roles == nil
321
458
 
322
- userRoles.roles = [] if userRoles.roles == nil
323
- list << userRoles
459
+ user_roles.roles = [] if user_roles.roles == nil
460
+ list << user_roles
324
461
  end
325
462
 
326
463
  return 0, list
327
464
  end
328
465
 
329
- def parse_roles(userRoles)
466
+ def parse_roles(user_roles)
330
467
  size = @data_buffer.read(@data_offset)
331
468
  @data_offset += 1
332
- userRoles.roles = []
469
+ user_roles.roles = []
333
470
 
334
471
  i = 0
335
472
  while i < size
@@ -337,17 +474,188 @@ module Aerospike
337
474
  @data_offset += 1
338
475
  role = @data_buffer.read(@data_offset, len)
339
476
  @data_offset += len
340
- userRoles.roles << role
477
+ user_roles.roles << role
341
478
 
342
479
  i = i.succ
343
480
  end
344
481
  end
345
482
 
346
- SALT = '$2a$10$7EqJtq98hPqEX7fNZaFWoO'
347
- def self.hash_password(password)
348
- # Hashing the password with the cost of 10, with a static salt
349
- return BCrypt::Engine.hash_secret(password, SALT, :cost => 10)
483
+ def parse_info
484
+ size = @data_buffer.read(@data_offset)
485
+ @data_offset += 1
486
+ list = []
487
+
488
+ i = 0
489
+ while i < size
490
+ val = @data_buffer.read_int32(@data_offset)
491
+ @data_offset += 4
492
+ list << val
493
+
494
+ i = i.succ
495
+ end
496
+
497
+ list
350
498
  end
499
+
500
+ def read_roles(cluster, policy)
501
+ write_size
502
+ node = cluster.random_node
503
+
504
+ timeout = 1
505
+ timeout = policy.timeout if policy != nil && policy.timeout > 0
506
+
507
+ status = -1
508
+ list = []
509
+ begin
510
+ conn = node.get_connection(timeout)
511
+ conn.write(@data_buffer, @data_offset)
512
+ status, list = read_role_blocks(conn)
513
+ node.put_connection(conn)
514
+ rescue => e
515
+ conn.close if conn
516
+ raise e
517
+ end
518
+
519
+ raise Exceptions::Aerospike.new(status) if status > 0
520
+
521
+ return list
522
+ end
523
+
524
+ def read_role_blocks(conn)
525
+ rlist = []
526
+ status = 0
527
+ begin
528
+ while status == 0
529
+ conn.read(@data_buffer, 8)
530
+ size = @data_buffer.read_int64(0)
531
+ receive_size = (size & 0xFFFFFFFFFFFF)
532
+
533
+ if receive_size > 0
534
+ @data_buffer.resize(receive_size) if receive_size > @data_buffer.size
535
+
536
+ conn.read(@data_buffer, receive_size)
537
+ status, list = parse_roles_full(receive_size)
538
+ rlist.concat(list.to_a)
539
+ else
540
+ break
541
+ end
542
+ end
543
+ return status, rlist
544
+ rescue => e
545
+ return -1, []
546
+ end
547
+ end
548
+
549
+ def parse_roles_full(receive_size)
550
+ @data_offset = 0
551
+ list = []
552
+
553
+ while @data_offset < receive_size
554
+ result_code = @data_buffer.read(@data_offset+1)
555
+
556
+ if result_code != 0
557
+ return (result_code == QUERY_END ? -1 : result_code)
558
+ end
559
+
560
+ role = Role.new
561
+ field_count = @data_buffer.read(@data_offset+3)
562
+ @data_offset += HEADER_REMAINING
563
+
564
+ i = 0
565
+ while i < field_count
566
+ len = @data_buffer.read_int32(@data_offset)
567
+ @data_offset += 4
568
+ id = @data_buffer.read(@data_offset)
569
+ @data_offset += 1
570
+ len -= 1
571
+
572
+ case id
573
+ when ROLE
574
+ role.name = @data_buffer.read(@data_offset, len).to_s
575
+ @data_offset += len
576
+ when PRIVILEGES
577
+ parse_privileges(role)
578
+ when ALLOWLIST
579
+ role.allowlist = parse_allowlist(len)
580
+ when READ_QUOTA
581
+ role.read_quota = @data_buffer.read_uint32(@data_offset)
582
+ @data_offset += len
583
+ when WRITE_QUOTA
584
+ role.write_quota = @data_buffer.read_uint32(@data_offset)
585
+ @data_offset += len
586
+ else
587
+ @data_offset += len
588
+ end
589
+
590
+ i = i.succ
591
+ end
592
+
593
+ next if role.name == "" && role.privileges == nil
594
+
595
+ role.privileges ||= []
596
+ list << role
597
+ end
598
+
599
+ return 0, list
600
+ end
601
+
602
+ def parse_privileges(role)
603
+ size = @data_buffer.read(@data_offset)
604
+ @data_offset += 1
605
+ role.privileges = []
606
+
607
+ i = 0
608
+ while i < size
609
+ priv = Privilege.new
610
+ priv.code = Privilege.from(@data_buffer.read(@data_offset))
611
+ @data_offset += 1
612
+
613
+ if priv.can_scope?
614
+ len = @data_buffer.read(@data_offset)
615
+ @data_offset += 1
616
+ priv.namespace = @data_buffer.read(@data_offset, len)
617
+ @data_offset += len
618
+
619
+ len = @data_buffer.read(@data_offset)
620
+ @data_offset += 1
621
+ priv.set_name = @data_buffer.read(@data_offset, len)
622
+ @data_offset += len
623
+ end
624
+
625
+ role.privileges << priv
626
+
627
+ i = i.succ
628
+ end
629
+ end
630
+
631
+ def parse_allowlist(len)
632
+ list = []
633
+ begn = @data_offset
634
+ max = begn + len
635
+
636
+ while @data_offset < max
637
+ if @data_buffer.read(@data_offset) == ','
638
+ l = @data_offset - begn
639
+ if l > 0
640
+ s = @data_buffer.read(begn, l)
641
+ list << s
642
+ end
643
+ @data_offset += 1
644
+ begn = @data_offset
645
+ else
646
+ @data_offset += 1
647
+ end
648
+ end
649
+
650
+ l = @data_offset - begn
651
+ if l > 0
652
+ s = @data_buffer.read(begn, l)
653
+ list << s
654
+ end
655
+
656
+ list
657
+ end
658
+
351
659
  end
352
660
  end
353
661
 
@@ -840,12 +840,6 @@ module Aerospike
840
840
  end
841
841
 
842
842
  def size_buffer_sz(size)
843
- # Corrupted data streams can result in a hug.length.
844
- # Do a sanity check here.
845
- if size > Buffer::MAX_BUFFER_SIZE
846
- raise Aerospike::Exceptions::Parse.new("Invalid size for buffer: #{size}")
847
- end
848
-
849
843
  @data_buffer.resize(size)
850
844
  end
851
845
 
@@ -0,0 +1,164 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
+ #
4
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
+ # license agreements.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
+ # use this file except in compliance with the License. You may obtain a copy of
9
+ # the License at http:#www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations under
15
+ # the License.
16
+
17
+ require 'aerospike/command/admin_command'
18
+
19
+ module Aerospike
20
+
21
+ private
22
+
23
+ attr_reader :session_token, :session_expiration
24
+
25
+ class LoginCommand < AdminCommand #:nodoc:
26
+
27
+ def login(conn, policy)
28
+ hashed_pass = LoginCommand.hash_password(policy.password)
29
+ authenticate(conn, policy, hashed_pass)
30
+ end
31
+
32
+ def authenticate(conn, user, hashed_pass)
33
+ write_header(LOGIN, 2)
34
+ write_field_str(USER, policy.user)
35
+ write_field_bytes(CREDENTIAL, hashed_pass)
36
+
37
+ parse_tokens(conn)
38
+ end
39
+
40
+ def authenticate_new(conn, cluster)
41
+ @data_offset = 8
42
+ policy = cluster.client_policy
43
+ case policy.auth_mode
44
+ when Aerospike::AuthMode::EXTERNAL
45
+ write_header(LOGIN, 3)
46
+ write_field_str(USER, policy.user)
47
+ write_field_bytes(CREDENTIAL, cluster.password)
48
+ write_field_str(CLEAR_PASSWORD, policy.password)
49
+ when Aerospike::AuthMode::INTERNAL
50
+ write_header(LOGIN, 2)
51
+ write_field_str(USER, policy.user)
52
+ write_field_bytes(CREDENTIAL, cluster.password)
53
+ when Aerospike::AuthMode::PKI
54
+ write_header(LOGIN, 0)
55
+ else
56
+ raise Exceptions::Aerospike.new(Aerospike::ResultCode::COMMAND_REJECTED, "Invalid client_policy#auth_mode.")
57
+ end
58
+
59
+ parse_tokens(conn)
60
+ cluster.session_token = @session_token
61
+ cluster.session_expiration = @session_expiration
62
+ end
63
+
64
+ def parse_tokens(conn)
65
+ begin
66
+ write_size
67
+ conn.write(@data_buffer, @data_offset)
68
+ conn.read(@data_buffer, HEADER_SIZE)
69
+
70
+ result = @data_buffer.read(RESULT_CODE)
71
+
72
+ if result != 0
73
+ return if result == Aerospike::ResultCode::SECURITY_NOT_ENABLED
74
+ raise Exceptions::Aerospike.new(result, "Authentication failed")
75
+ end
76
+
77
+ # read the rest of the buffer
78
+ size = @data_buffer.read_int64(0)
79
+ receive_size = (size & 0xFFFFFFFFFFFF) - HEADER_REMAINING
80
+ field_count = @data_buffer.read(11) & 0xFF
81
+
82
+ if receive_size <= 0 || receive_size > @data_buffer.size || field_count <= 0
83
+ raise Exceptions::Aerospike.new(result, "Node failed to retrieve session token")
84
+ end
85
+
86
+ if @data_buffer.size < receive_size
87
+ @data_buffer.resize(receive_size)
88
+ end
89
+
90
+ conn.read(@data_buffer, receive_size)
91
+
92
+ @data_offset = 0
93
+ for i in 0...field_count
94
+ mlen = @data_buffer.read_int32(@data_offset)
95
+ @data_offset += 4
96
+ id = @data_buffer.read(@data_offset)
97
+ @data_offset += 1
98
+ mlen -= 1
99
+
100
+ case id
101
+ when SESSION_TOKEN
102
+ # copy the contents of the buffer into a new byte slice
103
+ @session_token = @data_buffer.read(@data_offset, mlen)
104
+
105
+ when SESSION_TTL
106
+ # Subtract 60 seconds from TTL so client session expires before server session.
107
+ seconds = @data_buffer.read_int32(@data_offset) - 60
108
+
109
+ if seconds > 0
110
+ @session_expiration = Time.now + (seconds/86400)
111
+ else
112
+ Aerospike.logger.warn("Invalid session TTL: #{seconds}")
113
+ raise Exceptions::Aerospike.new(result, "Node failed to retrieve session token")
114
+ end
115
+ end
116
+
117
+ @data_offset += mlen
118
+ end
119
+
120
+ if !@session_token
121
+ raise Exceptions::Aerospike.new(result, "Node failed to retrieve session token")
122
+ end
123
+ ensure
124
+ Buffer.put(@data_buffer)
125
+ end
126
+ end
127
+
128
+ def authenticate_via_token(conn, cluster)
129
+ @data_offset = 8
130
+ policy = cluster.client_policy
131
+ if policy.auth_mode != Aerospike::AuthMode::PKI
132
+ write_header(AUTHENTICATE, 2)
133
+ write_field_str(USER, policy.user)
134
+ else
135
+ write_header(AUTHENTICATE, 1)
136
+ end
137
+
138
+ write_field_bytes(SESSION_TOKEN, cluster.session_token) if cluster.session_token
139
+ write_size
140
+
141
+ conn.write(@data_buffer, @data_offset)
142
+ conn.read(@data_buffer, HEADER_SIZE)
143
+
144
+ result = @data_buffer.read(RESULT_CODE)
145
+ size = @data_buffer.read_int64(0)
146
+ receive_size = (size & 0xFFFFFFFFFFFF) - HEADER_REMAINING
147
+ conn.read(@data_buffer, receive_size)
148
+
149
+ if result != 0
150
+ return if result == Aerospike::ResultCode::SECURITY_NOT_ENABLED
151
+ raise Exceptions::Aerospike.new(result, "Authentication failed")
152
+ end
153
+
154
+ nil
155
+ end
156
+
157
+ SALT = '$2a$10$7EqJtq98hPqEX7fNZaFWoO'
158
+ def self.hash_password(password)
159
+ # Hashing the password with the cost of 10, with a static salt
160
+ return BCrypt::Engine.hash_secret(password, SALT, :cost => 10)
161
+ end
162
+ end
163
+ end
164
+