aerospike 2.20.0 → 2.21.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bed472fc5bda556a4f67f2d6e4e0ee8a82188253b34e0bfab3a0b05be3526d2e
4
- data.tar.gz: 4a11f36509d86792412e764ef978ec6e27753eab2a96e65353b73786ea383591
3
+ metadata.gz: f0685f64b5853e918eca12c6ad4a64a1c7ac5c1d0370627c252e598f4686be68
4
+ data.tar.gz: a342e374dc180201176018cf1e13c7764a64963fe78e505d55d93b5f2ed83b70
5
5
  SHA512:
6
- metadata.gz: fa02cbf6bc8e6065e80849e5dcbe71d91550eb549c77af53c761df2e969d7f3135ea3641dcc8af28bd98d5f3e46ab868e61f4e61023c70f0a400e99c93747a00
7
- data.tar.gz: 47f9d0da4d7099b2e96992012deb79292c4de7d8bbd8fa9ca3a362dc5aa126841887d3eef8f0f0f15e176190a729dde8377f486f3c0ef357b312ab43569b31ce
6
+ metadata.gz: 4151a866e0ff1c36e924aa1a6123411499f7c1bcf48b01177028db5d7a7a72ac2cfde2febb398a42774c4b490c5e0f78839a14a52d5d0c19c9850f5e34dd7141
7
+ data.tar.gz: babd62c5d0307153073c51bfa879e0700a9ad56875da37eb711965da82ddc09b765cbbd770ec60c6973d818318200708ba27a4c4ee4a7b598076324ef9093176
data/CHANGELOG.md CHANGED
@@ -2,7 +2,27 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## [2.20.0] - 2020-11-08
5
+ ## [2.21.1] - 2022-06-21
6
+
7
+ This s hotfix release. It is recommended to upgrade your client if you use authentication.
8
+
9
+ * **Bug Fixes**
10
+ * Fix called function name in Authenticate.
11
+
12
+ ## [2.21.0] - 2022-06-07
13
+
14
+ * **New Features**
15
+ * Add support for new user management features. Adds `Client#query_role`, `Client#query_roles`, `Client#create_role`, `Client#drop_role`, `Client#grant_privileges`, `Client#revoke_privileges`. Adds the 'Role' class. Adds `UserRoles#read_info`, `UserRoles#write_info`, `UserRoles#conns_in_use` to the `UserRoles` class.
16
+
17
+ * **Improvements**
18
+ * Do not run PredExp tests for server v6+.
19
+
20
+ ## [2.20.1] - 2022-05-11
21
+
22
+ * **Improvements**
23
+ * Add basic support for the new authentication protocol.
24
+
25
+ ## [2.20.0] - 2021-11-08
6
26
 
7
27
  Notice: This version of the client only supports Aerospike Server v4.9 and later. Some features will work for the older server versions, but they are not tested, nor officially supported.
8
28
 
@@ -764,7 +764,7 @@ module Aerospike
764
764
  # before sending to server.
765
765
  def create_user(user, password, roles, options = nil)
766
766
  policy = create_policy(options, AdminPolicy, default_admin_policy)
767
- hash = AdminCommand.hash_password(password)
767
+ hash = LoginCommand.hash_password(password)
768
768
  command = AdminCommand.new
769
769
  command.create_user(@cluster, policy, user, hash, roles)
770
770
  end
@@ -781,7 +781,7 @@ module Aerospike
781
781
  raise Aerospike::Exceptions::Aerospike.new(INVALID_USER) unless @cluster.user && @cluster.user != ""
782
782
  policy = create_policy(options, AdminPolicy, default_admin_policy)
783
783
 
784
- hash = AdminCommand.hash_password(password)
784
+ hash = LoginCommand.hash_password(password)
785
785
  command = AdminCommand.new
786
786
 
787
787
  if user == @cluster.user
@@ -823,6 +823,50 @@ module Aerospike
823
823
  command.query_users(@cluster, policy)
824
824
  end
825
825
 
826
+ # Retrieve privileges for a given role.
827
+ def query_role(role, options = nil)
828
+ policy = create_policy(options, AdminPolicy, default_admin_policy)
829
+ command = AdminCommand.new
830
+ command.query_role(@cluster, policy, role)
831
+ end
832
+
833
+ # Retrieve all roles and their privileges.
834
+ def query_roles(options = nil)
835
+ policy = create_policy(options, AdminPolicy, default_admin_policy)
836
+ command = AdminCommand.new
837
+ command.query_roles(@cluster, policy)
838
+ end
839
+
840
+ # Create a user-defined role.
841
+ # Quotas require server security configuration "enable-quotas" to be set to true.
842
+ # Pass 0 for quota values for no limit.
843
+ def create_role(role_name, privileges = [], allowlist = [], read_quota = 0, write_quota = 0, options = nil)
844
+ policy = create_policy(options, AdminPolicy, default_admin_policy)
845
+ command = AdminCommand.new
846
+ command.create_role(@cluster, policy, role_name, privileges, allowlist, read_quota, write_quota)
847
+ end
848
+
849
+ # Remove a user-defined role.
850
+ def drop_role(role_name, options = nil)
851
+ policy = create_policy(options, AdminPolicy, default_admin_policy)
852
+ command = AdminCommand.new
853
+ command.drop_role(@cluster, policy, role_name)
854
+ end
855
+
856
+ # Grant privileges to a user-defined role.
857
+ def grant_privileges(role_name, privileges, options = nil)
858
+ policy = create_policy(options, AdminPolicy, default_admin_policy)
859
+ command = AdminCommand.new
860
+ command.grant_privileges(@cluster, policy, role_name, privileges)
861
+ end
862
+
863
+ # Revoke privileges from a user-defined role.
864
+ def revoke_privileges(role_name, privileges, options = nil)
865
+ policy = create_policy(options, AdminPolicy, default_admin_policy)
866
+ command = AdminCommand.new
867
+ command.revoke_privileges(@cluster, policy, role_name, privileges)
868
+ end
869
+
826
870
  private
827
871
 
828
872
  def set_default_policies(policies)
@@ -32,7 +32,7 @@ module Aerospike
32
32
  ).tap do |conn|
33
33
  if cluster.credentials_given?
34
34
  # Authenticate will raise and close connection if invalid credentials
35
- Connection::Authenticate.(conn, cluster.user, cluster.password)
35
+ Connection::AuthenticateNew.(conn, cluster)
36
36
  end
37
37
  end
38
38
  end
@@ -27,9 +27,12 @@ module Aerospike
27
27
  attr_reader :features, :tls_options
28
28
  attr_reader :cluster_id, :aliases
29
29
  attr_reader :cluster_name
30
+ attr_reader :client_policy
30
31
  attr_accessor :rack_aware, :rack_id
32
+ attr_accessor :session_token, :session_expiration
31
33
 
32
34
  def initialize(policy, hosts)
35
+ @client_policy = policy
33
36
  @cluster_seeds = hosts
34
37
  @fail_if_not_connected = policy.fail_if_not_connected
35
38
  @connection_queue_size = policy.connection_queue_size
@@ -56,7 +59,7 @@ module Aerospike
56
59
  # setup auth info for cluster
57
60
  if policy.requires_authentication
58
61
  @user = policy.user
59
- @password = AdminCommand.hash_password(policy.password)
62
+ @password = LoginCommand.hash_password(policy.password)
60
63
  end
61
64
 
62
65
  initialize_tls_host_names(hosts) if tls_enabled?
@@ -78,6 +81,15 @@ module Aerospike
78
81
  !(@user.nil? || @user.empty?)
79
82
  end
80
83
 
84
+ def session_valid?
85
+ @session_token && @session_expiration && @session_expiration.to_i < Time.now.to_i
86
+ end
87
+
88
+ def reset_session_info
89
+ @session_token = nil
90
+ @session_expiration = nil
91
+ end
92
+
81
93
  def tls_enabled?
82
94
  !tls_options.nil? && tls_options[:enable] != false
83
95
  end
@@ -436,6 +448,7 @@ module Aerospike
436
448
  cluster_config_changed = true
437
449
  end
438
450
 
451
+
439
452
  cluster_config_changed
440
453
  end
441
454
 
@@ -18,24 +18,40 @@ 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
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
31
37
 
32
38
  # Field IDs
33
- USER = 0
34
- PASSWORD = 1
35
- OLD_PASSWORD = 2
36
- CREDENTIAL = 3
37
- ROLES = 10
38
- #PRIVILEGES = 11
39
+ USER = 0
40
+ PASSWORD = 1
41
+ OLD_PASSWORD = 2
42
+ CREDENTIAL = 3
43
+ CLEAR_PASSWORD = 4
44
+ SESSION_TOKEN = 5
45
+ SESSION_TTL = 6
46
+ ROLES = 10
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
39
55
 
40
56
  # Misc
41
57
  MSG_VERSION = 2
@@ -53,28 +69,6 @@ module Aerospike
53
69
  @data_offset = 8
54
70
  end
55
71
 
56
- def authenticate(conn, user, password)
57
- begin
58
- set_authenticate(user, password)
59
- conn.write(@data_buffer, @data_offset)
60
- conn.read(@data_buffer, HEADER_SIZE)
61
-
62
- result = @data_buffer.read(RESULT_CODE)
63
- raise Exceptions::Aerospike.new(result, "Authentication failed") if result != 0
64
- ensure
65
- Buffer.put(@data_buffer)
66
- end
67
- end
68
-
69
- def set_authenticate(user, password)
70
- write_header(AUTHENTICATE, 2)
71
- write_field_str(USER, user)
72
- write_field_bytes(CREDENTIAL, password)
73
- write_size
74
-
75
- return @data_offset
76
- end
77
-
78
72
  def create_user(cluster, policy, user, password, roles)
79
73
  write_header(CREATE_USER, 3)
80
74
  write_field_str(USER, user)
@@ -118,6 +112,61 @@ module Aerospike
118
112
  execute_command(cluster, policy)
119
113
  end
120
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
+
121
170
  def query_user(cluster, policy, user)
122
171
  # TODO: Remove the workaround in the future
123
172
  sleep(0.010)
@@ -144,6 +193,32 @@ module Aerospike
144
193
  end
145
194
  end
146
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
+
147
222
  def write_roles(roles)
148
223
  offset = @data_offset + FIELD_HEADER_SIZE
149
224
  @data_buffer.write_byte(roles.length.ord, offset)
@@ -166,6 +241,54 @@ module Aerospike
166
241
  @data_buffer.write_int64(size, 0)
167
242
  end
168
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
+
169
292
  def write_header(command, field_count)
170
293
  # Authenticate header is almost all zeros
171
294
  i = @data_offset
@@ -178,12 +301,27 @@ module Aerospike
178
301
  @data_offset += 16
179
302
  end
180
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
+
181
313
  def write_field_str(id, str)
182
314
  len = @data_buffer.write_binary(str, @data_offset+FIELD_HEADER_SIZE)
183
315
  write_field_header(id, len)
184
316
  @data_offset += len
185
317
  end
186
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
+
187
325
  def write_field_bytes(id, bytes)
188
326
  @data_buffer.write_binary(bytes, @data_offset+FIELD_HEADER_SIZE)
189
327
  write_field_header(id, bytes.bytesize)
@@ -284,7 +422,7 @@ module Aerospike
284
422
  return (result_code == QUERY_END ? -1 : result_code)
285
423
  end
286
424
 
287
- userRoles = UserRoles.new
425
+ user_roles = UserRoles.new
288
426
  field_count = @data_buffer.read(@data_offset+3)
289
427
  @data_offset += HEADER_REMAINING
290
428
 
@@ -298,10 +436,17 @@ module Aerospike
298
436
 
299
437
  case id
300
438
  when USER
301
- userRoles.user = @data_buffer.read(@data_offset, len)
439
+ user_roles.user = @data_buffer.read(@data_offset, len)
302
440
  @data_offset += len
303
441
  when ROLES
304
- 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
305
450
  else
306
451
  @data_offset += len
307
452
  end
@@ -309,19 +454,19 @@ module Aerospike
309
454
  i = i.succ
310
455
  end
311
456
 
312
- next if userRoles.user == "" && userRoles.roles == nil
457
+ next if user_roles.user == "" && user_roles.roles == nil
313
458
 
314
- userRoles.roles = [] if userRoles.roles == nil
315
- list << userRoles
459
+ user_roles.roles = [] if user_roles.roles == nil
460
+ list << user_roles
316
461
  end
317
462
 
318
463
  return 0, list
319
464
  end
320
465
 
321
- def parse_roles(userRoles)
466
+ def parse_roles(user_roles)
322
467
  size = @data_buffer.read(@data_offset)
323
468
  @data_offset += 1
324
- userRoles.roles = []
469
+ user_roles.roles = []
325
470
 
326
471
  i = 0
327
472
  while i < size
@@ -329,17 +474,188 @@ module Aerospike
329
474
  @data_offset += 1
330
475
  role = @data_buffer.read(@data_offset, len)
331
476
  @data_offset += len
332
- userRoles.roles << role
477
+ user_roles.roles << role
333
478
 
334
479
  i = i.succ
335
480
  end
336
481
  end
337
482
 
338
- SALT = '$2a$10$7EqJtq98hPqEX7fNZaFWoO'
339
- def self.hash_password(password)
340
- # Hashing the password with the cost of 10, with a static salt
341
- 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
342
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
+
343
659
  end
344
660
  end
345
661
 
@@ -0,0 +1,162 @@
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
+ policy = cluster.client_policy
42
+ case policy.auth_mode
43
+ when Aerospike::AuthMode::EXTERNAL
44
+ write_header(LOGIN, 3)
45
+ write_field_str(USER, policy.user)
46
+ write_field_bytes(CREDENTIAL, cluster.password)
47
+ write_field_str(CLEAR_PASSWORD, policy.password)
48
+ when Aerospike::AuthMode::INTERNAL
49
+ write_header(LOGIN, 2)
50
+ write_field_str(USER, policy.user)
51
+ write_field_bytes(CREDENTIAL, cluster.password)
52
+ when Aerospike::AuthMode::PKI
53
+ write_header(LOGIN, 0)
54
+ else
55
+ raise Exceptions::Aerospike.new(Aerospike::ResultCode::COMMAND_REJECTED, "Invalid client_policy#auth_mode.")
56
+ end
57
+
58
+ parse_tokens(conn)
59
+ cluster.session_token = @session_token
60
+ cluster.session_expiration = @session_expiration
61
+ end
62
+
63
+ def parse_tokens(conn)
64
+ begin
65
+ write_size
66
+ conn.write(@data_buffer, @data_offset)
67
+ conn.read(@data_buffer, HEADER_SIZE)
68
+
69
+ result = @data_buffer.read(RESULT_CODE)
70
+
71
+ if result != 0
72
+ return if result == Aerospike::ResultCode::SECURITY_NOT_ENABLED
73
+ raise Exceptions::Aerospike.new(result, "Authentication failed")
74
+ end
75
+
76
+ # read the rest of the buffer
77
+ size = @data_buffer.read_int64(0)
78
+ receive_size = (size & 0xFFFFFFFFFFFF) - HEADER_REMAINING
79
+ field_count = @data_buffer.read(11) & 0xFF
80
+
81
+ if receive_size <= 0 || receive_size > @data_buffer.size || field_count <= 0
82
+ raise Exceptions::Aerospike.new(result, "Node failed to retrieve session token")
83
+ end
84
+
85
+ if @data_buffer.size < receive_size
86
+ @data_buffer.resize(receive_size)
87
+ end
88
+
89
+ conn.read(@data_buffer, receive_size)
90
+
91
+ @data_offset = 0
92
+ for i in 0...field_count
93
+ mlen = @data_buffer.read_int32(@data_offset)
94
+ @data_offset += 4
95
+ id = @data_buffer.read(@data_offset)
96
+ @data_offset += 1
97
+ mlen -= 1
98
+
99
+ case id
100
+ when SESSION_TOKEN
101
+ # copy the contents of the buffer into a new byte slice
102
+ @session_token = @data_buffer.read(@data_offset, mlen)
103
+
104
+ when SESSION_TTL
105
+ # Subtract 60 seconds from TTL so client session expires before server session.
106
+ seconds = @data_buffer.read_int32(@data_offset) - 60
107
+
108
+ if seconds > 0
109
+ @session_expiration = Time.now + (seconds/86400)
110
+ else
111
+ Aerospike.logger.warn("Invalid session TTL: #{seconds}")
112
+ raise Exceptions::Aerospike.new(result, "Node failed to retrieve session token")
113
+ end
114
+ end
115
+
116
+ @data_offset += mlen
117
+ end
118
+
119
+ if !@session_token
120
+ raise Exceptions::Aerospike.new(result, "Node failed to retrieve session token")
121
+ end
122
+ ensure
123
+ Buffer.put(@data_buffer)
124
+ end
125
+ end
126
+
127
+ def authenticate_via_token(conn, cluster)
128
+ policy = cluster.client_policy
129
+ if policy.auth_mode != Aerospike::AuthMode::PKI
130
+ write_header(AUTHENTICATE, 2)
131
+ write_field_str(USER, policy.user)
132
+ else
133
+ write_header(AUTHENTICATE, 1)
134
+ end
135
+
136
+ write_field_bytes(SESSION_TOKEN, cluster.session_token) if cluster.session_token
137
+ write_size
138
+
139
+ conn.write(@data_buffer, @data_offset)
140
+ conn.read(@data_buffer, HEADER_SIZE)
141
+
142
+ result = @data_buffer.read(RESULT_CODE)
143
+ size = @data_buffer.read_int64(0)
144
+ receive_size = (size & 0xFFFFFFFFFFFF) - HEADER_REMAINING
145
+ conn.read(@data_buffer, receive_size)
146
+
147
+ if result != 0
148
+ return if result == Aerospike::ResultCode::SECURITY_NOT_ENABLED
149
+ raise Exceptions::Aerospike.new(result, "Authentication failed")
150
+ end
151
+
152
+ nil
153
+ end
154
+
155
+ SALT = '$2a$10$7EqJtq98hPqEX7fNZaFWoO'
156
+ def self.hash_password(password)
157
+ # Hashing the password with the cost of 10, with a static salt
158
+ return BCrypt::Engine.hash_secret(password, SALT, :cost => 10)
159
+ end
160
+ end
161
+ end
162
+
@@ -21,9 +21,41 @@ module Aerospike
21
21
  module Connection # :nodoc:
22
22
  module Authenticate
23
23
  class << self
24
- def call(conn, user, password)
25
- command = AdminCommand.new
26
- command.authenticate(conn, user, password)
24
+ def call(conn, user, hashed_pass)
25
+ command = LoginCommand.new
26
+ command.authenticate(conn, user, hashed_pass)
27
+ true
28
+ rescue ::Aerospike::Exceptions::Aerospike
29
+ conn.close if conn
30
+ raise ::Aerospike::Exceptions::InvalidCredentials
31
+ end
32
+ end
33
+ end
34
+ module AuthenticateNew
35
+ class << self
36
+ INVALID_SESSION_ERR = [ResultCode::INVALID_CREDENTIAL,
37
+ ResultCode::EXPIRED_SESSION]
38
+
39
+ def call(conn, cluster)
40
+ command = LoginCommand.new
41
+ if !cluster.session_valid?
42
+ command.authenticate_new(conn, cluster)
43
+ else
44
+ begin
45
+ command.authenticate_via_token(conn, cluster)
46
+ rescue => ae
47
+ # always reset session info on errors to be on the safe side
48
+ cluster.reset_session_info
49
+ if ae.is_a?(Exceptions::Aerospike)
50
+ if INVALID_SESSION_ERR.include?(ae.result_code)
51
+ command.authenticate_new(conn, cluster)
52
+ return
53
+ end
54
+ end
55
+ raise ae
56
+ end
57
+ end
58
+
27
59
  true
28
60
  rescue ::Aerospike::Exceptions::Aerospike
29
61
  conn.close if conn
@@ -33,3 +65,4 @@ module Aerospike
33
65
  end
34
66
  end
35
67
  end
68
+
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http:#www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module Aerospike
17
+
18
+ module AuthMode
19
+
20
+ # INTERNAL uses internal authentication only when user/password defined. Hashed password is stored
21
+ # on the server. Do not send clear password. This is the default.
22
+ INTERNAL = 0
23
+
24
+ # EXTERNAL uses external authentication (like LDAP) when user/password defined. Specific external authentication is
25
+ # configured on server. If TLS is defined, sends clear password on node login via TLS.
26
+ # Will raise exception if TLS is not defined.
27
+ EXTERNAL = 1
28
+
29
+ # PKI allows authentication and authorization based on a certificate. No user name or
30
+ # password needs to be configured. Requires TLS and a client certificate.
31
+ # Requires server version 5.7.0+
32
+ PKI = 2
33
+
34
+ end # module
35
+
36
+ end # module
@@ -22,7 +22,7 @@ module Aerospike
22
22
  # Container object for client policy command.
23
23
  class ClientPolicy
24
24
 
25
- attr_accessor :user, :password
25
+ attr_accessor :user, :password, :auth_mode
26
26
  attr_accessor :timeout, :connection_queue_size, :fail_if_not_connected, :tend_interval
27
27
  attr_accessor :cluster_name
28
28
  attr_accessor :tls
@@ -44,6 +44,9 @@ module Aerospike
44
44
  # which the client checks for cluster state changes. Minimum interval is 10ms.
45
45
  self.tend_interval = opt[:tend_interval] || 1000 # 1 second
46
46
 
47
+ # Authentication mode
48
+ @auth_mode = opt[:auth_mode] || AuthMode::INTERNAL
49
+
47
50
  # user name
48
51
  @user = opt[:user]
49
52
 
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2022 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
+ module Aerospike
18
+
19
+ # Determines user access granularity.
20
+ class Privilege
21
+
22
+ # Role
23
+ attr_accessor :code
24
+
25
+ # Namespace determines namespace scope. Apply permission to this namespace only.
26
+ # If namespace is zero value, the privilege applies to all namespaces.
27
+ attr_accessor :namespace
28
+
29
+ # Set name scope. Apply permission to this set within namespace only.
30
+ # If set is zero value, the privilege applies to all sets within namespace.
31
+ attr_accessor :set_name
32
+
33
+ # Manage users and their roles.
34
+ USER_ADMIN = 'user-admin'
35
+
36
+ # Manage indicies, user-defined functions and server configuration.
37
+ SYS_ADMIN = 'sys-admin'
38
+
39
+ # Manage indicies and user defined functions.
40
+ DATA_ADMIN = 'data-admin'
41
+
42
+ # Manage user defined functions.
43
+ UDF_ADMIN = 'udf-admin'
44
+
45
+ # Manage indicies.
46
+ SINDEX_ADMIN = 'sindex-admin'
47
+
48
+ # Allow read, write and UDF transactions with the database.
49
+ READ_WRITE_UDF = "read-write-udf"
50
+
51
+ # Allow read and write transactions with the database.
52
+ READ_WRITE = 'read-write'
53
+
54
+ # Allow read transactions with the database.
55
+ READ = 'read'
56
+
57
+ # Write allows write transactions with the database.
58
+ WRITE = 'write'
59
+
60
+ # Truncate allow issuing truncate commands.
61
+ TRUNCATE = 'truncate'
62
+
63
+ def initialize(opt={})
64
+ @code = opt[:code]
65
+ @namespace = opt[:namespace]
66
+ @set_name = opt[:set_name]
67
+ end
68
+
69
+ def to_s
70
+ "code: #{@code}, namespace: #{@namespace}, set_name: #{@set_name}"
71
+ end
72
+
73
+ def to_code
74
+ case @code
75
+ when USER_ADMIN
76
+ 0
77
+ when SYS_ADMIN
78
+ 1
79
+ when DATA_ADMIN
80
+ 2
81
+ when UDF_ADMIN
82
+ 3
83
+ when SINDEX_ADMIN
84
+ 4
85
+ when READ
86
+ 10
87
+ when READ_WRITE
88
+ 11
89
+ when READ_WRITE_UDF
90
+ 12
91
+ when WRITE
92
+ 13
93
+ when TRUNCATE
94
+ 14
95
+ else
96
+ raise Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_PRIVILEGE, "Invalid role #{@code}")
97
+ end # case
98
+ end # def
99
+
100
+ def self.from(code)
101
+ case code
102
+ when 0
103
+ USER_ADMIN
104
+ when 1
105
+ SYS_ADMIN
106
+ when 2
107
+ DATA_ADMIN
108
+ when 3
109
+ UDF_ADMIN
110
+ when 4
111
+ SINDEX_ADMIN
112
+ when 10
113
+ READ
114
+ when 11
115
+ READ_WRITE
116
+ when 12
117
+ READ_WRITE_UDF
118
+ when 13
119
+ WRITE
120
+ when 14
121
+ TRUNCATE
122
+ else
123
+ raise Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_PRIVILEGE, "Invalid code #{code}")
124
+ end # case
125
+ end # def
126
+
127
+ def can_scope?
128
+ to_code >= 10
129
+ end
130
+
131
+ end # class
132
+
133
+ end
@@ -182,7 +182,7 @@ module Aerospike
182
182
  # Privilege is invalid.
183
183
  INVALID_PRIVILEGE = 72
184
184
 
185
- # Specified IP whitelist is invalid.
185
+ # Specified IP allowlist is invalid.
186
186
  INVALID_WHITELIST = 73
187
187
 
188
188
  # User must be authentication before performing database operations.
@@ -191,7 +191,7 @@ module Aerospike
191
191
  # User does not posses the required role to perform the database operation.
192
192
  ROLE_VIOLATION = 81
193
193
 
194
- # Client IP address is not on the IP whitelist.
194
+ # Client IP address is not on the IP allowlist.
195
195
  NOT_WHITELISTED = 82
196
196
 
197
197
  # LDAP feature not enabled on server.
@@ -422,7 +422,7 @@ module Aerospike
422
422
  "Invalid privilege"
423
423
 
424
424
  when INVALID_WHITELIST
425
- "Specified IP whitelist is invalid"
425
+ "Specified IP allowlist is invalid"
426
426
 
427
427
  when NOT_AUTHENTICATED
428
428
  "Not authenticated"
@@ -431,7 +431,7 @@ module Aerospike
431
431
  "Role violation"
432
432
 
433
433
  when NOT_WHITELISTED
434
- "Client IP address is not on the IP whitelist"
434
+ "Client IP address is not on the IP allowlist"
435
435
 
436
436
  when LDAP_NOT_ENABLED
437
437
  "LDAP feature not enabled on server"
@@ -0,0 +1,55 @@
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
+ module Aerospike
18
+
19
+ # Role provides granular access to database entities for users.
20
+ class Role
21
+
22
+ # Role name
23
+ attr_accessor :name
24
+
25
+ # List of assigned privileges
26
+ attr_accessor :privileges
27
+
28
+ # List of allowable IP addresses
29
+ attr_accessor :allowlist
30
+
31
+ # Maximum reads per second limit for the role
32
+ attr_accessor :read_quota
33
+
34
+ # Maximum writes per second limit for the role
35
+ attr_accessor :write_quota
36
+
37
+ # The following aliases are for backward compatibility reasons
38
+ USER_ADMIN = Privilege::USER_ADMIN # :nodoc:
39
+ SYS_ADMIN = Privilege::SYS_ADMIN # :nodoc:
40
+ DATA_ADMIN = Privilege::DATA_ADMIN # :nodoc:
41
+ UDF_ADMIN = Privilege::UDF_ADMIN # :nodoc:
42
+ SINDEX_ADMIN = Privilege::SINDEX_ADMIN # :nodoc:
43
+ READ_WRITE_UDF = Privilege::READ_WRITE_UDF # :nodoc:
44
+ READ_WRITE = Privilege::READ_WRITE # :nodoc:
45
+ READ = Privilege::READ # :nodoc:
46
+ WRITE = Privilege::WRITE # :nodoc:
47
+ TRUNCATE = Privilege::TRUNCATE # :nodoc:
48
+
49
+ def to_s
50
+ "Role [name=#{@name}, privileges=#{@privileges}, allowlist=#{@allowlist}, readQuota=#{@read_quota}, writeQuota=#{@write_quota}]";
51
+ end
52
+
53
+ end # class
54
+
55
+ end # module
@@ -25,6 +25,31 @@ module Aerospike
25
25
  # List of assigned roles.
26
26
  attr_accessor :roles
27
27
 
28
+ # List of read statistics. List may be nil.
29
+ # Current statistics by offset are:
30
+ #
31
+ # 0: read quota in records per second
32
+ # 1: single record read transaction rate (TPS)
33
+ # 2: read scan/query record per second rate (RPS)
34
+ # 3: number of limitless read scans/queries
35
+ #
36
+ # Future server releases may add additional statistics.
37
+ attr_accessor :read_info
38
+
39
+ # List of write statistics. List may be nil.
40
+ # Current statistics by offset are:
41
+ #
42
+ # 0: write quota in records per second
43
+ # 1: single record write transaction rate (TPS)
44
+ # 2: write scan/query record per second rate (RPS)
45
+ # 3: number of limitless write scans/queries
46
+ #
47
+ # Future server releases may add additional statistics.
48
+ attr_accessor :write_info
49
+
50
+ # Number of currently open connections for the user
51
+ attr_accessor :conns_in_use
52
+
28
53
  end
29
54
 
30
55
  end
@@ -136,16 +136,31 @@ module Aerospike
136
136
  vals.unpack(INT16)[0]
137
137
  end
138
138
 
139
+ def read_uint16(offset)
140
+ vals = @buf[offset..offset+1]
141
+ vals.unpack(UINT16)[0]
142
+ end
143
+
139
144
  def read_int32(offset)
140
145
  vals = @buf[offset..offset+3]
141
146
  vals.unpack(INT32)[0]
142
147
  end
143
148
 
149
+ def read_uint32(offset)
150
+ vals = @buf[offset..offset+3]
151
+ vals.unpack(UINT32)[0]
152
+ end
153
+
144
154
  def read_int64(offset)
145
155
  vals = @buf[offset..offset+7]
146
156
  vals.unpack(INT64)[0]
147
157
  end
148
158
 
159
+ def read_uint64(offset)
160
+ vals = @buf[offset..offset+7]
161
+ vals.unpack(UINT64)[0]
162
+ end
163
+
149
164
  def read_var_int64(offset, len)
150
165
  val = 0
151
166
  i = 0
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Aerospike
3
- VERSION = "2.20.0"
3
+ VERSION = "2.21.1"
4
4
  end
data/lib/aerospike.rb CHANGED
@@ -62,6 +62,7 @@ require 'aerospike/command/touch_command'
62
62
  require 'aerospike/command/read_command'
63
63
  require 'aerospike/command/delete_command'
64
64
  require 'aerospike/command/admin_command'
65
+ require 'aerospike/command/login_command'
65
66
  require 'aerospike/command/unsupported_particle_type_validator'
66
67
  require 'aerospike/key'
67
68
  require 'aerospike/operation'
@@ -101,6 +102,7 @@ require 'aerospike/policy/query_policy'
101
102
  require 'aerospike/policy/consistency_level'
102
103
  require 'aerospike/policy/commit_level'
103
104
  require 'aerospike/policy/admin_policy'
105
+ require 'aerospike/policy/auth_mode'
104
106
 
105
107
  require 'aerospike/socket/base'
106
108
  require 'aerospike/socket/ssl'
@@ -141,6 +143,8 @@ require 'aerospike/udf'
141
143
  require 'aerospike/bin'
142
144
  require 'aerospike/aerospike_exception'
143
145
  require 'aerospike/user_role'
146
+ require 'aerospike/privilege'
147
+ require 'aerospike/role'
144
148
 
145
149
  require 'aerospike/task/index_task'
146
150
  require 'aerospike/task/execute_task'
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aerospike
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.20.0
4
+ version: 2.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Khosrow Afroozeh
8
8
  - Jan Hecking
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-11-08 00:00:00.000000000 Z
12
+ date: 2022-06-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: msgpack
@@ -97,11 +97,11 @@ files:
97
97
  - lib/aerospike/command/execute_command.rb
98
98
  - lib/aerospike/command/exists_command.rb
99
99
  - lib/aerospike/command/field_type.rb
100
+ - lib/aerospike/command/login_command.rb
100
101
  - lib/aerospike/command/multi_command.rb
101
102
  - lib/aerospike/command/operate_command.rb
102
103
  - lib/aerospike/command/read_command.rb
103
104
  - lib/aerospike/command/read_header_command.rb
104
- - lib/aerospike/command/roles.rb
105
105
  - lib/aerospike/command/single_command.rb
106
106
  - lib/aerospike/command/touch_command.rb
107
107
  - lib/aerospike/command/unsupported_particle_type_validator.rb
@@ -138,6 +138,7 @@ files:
138
138
  - lib/aerospike/peers/fetch.rb
139
139
  - lib/aerospike/peers/parse.rb
140
140
  - lib/aerospike/policy/admin_policy.rb
141
+ - lib/aerospike/policy/auth_mode.rb
141
142
  - lib/aerospike/policy/batch_policy.rb
142
143
  - lib/aerospike/policy/client_policy.rb
143
144
  - lib/aerospike/policy/commit_level.rb
@@ -152,6 +153,7 @@ files:
152
153
  - lib/aerospike/policy/replica.rb
153
154
  - lib/aerospike/policy/scan_policy.rb
154
155
  - lib/aerospike/policy/write_policy.rb
156
+ - lib/aerospike/privilege.rb
155
157
  - lib/aerospike/query/filter.rb
156
158
  - lib/aerospike/query/pred_exp.rb
157
159
  - lib/aerospike/query/pred_exp/and_or.rb
@@ -168,6 +170,7 @@ files:
168
170
  - lib/aerospike/query/stream_command.rb
169
171
  - lib/aerospike/record.rb
170
172
  - lib/aerospike/result_code.rb
173
+ - lib/aerospike/role.rb
171
174
  - lib/aerospike/socket/base.rb
172
175
  - lib/aerospike/socket/ssl.rb
173
176
  - lib/aerospike/socket/tcp.rb
@@ -209,8 +212,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
212
  - !ruby/object:Gem::Version
210
213
  version: '0'
211
214
  requirements: []
212
- rubygems_version: 3.1.2
213
- signing_key:
215
+ rubygems_version: 3.2.15
216
+ signing_key:
214
217
  specification_version: 4
215
218
  summary: An Aerospike driver for Ruby.
216
219
  test_files: []
@@ -1,39 +0,0 @@
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
- module Aerospike
18
-
19
- # Pre-defined user roles.
20
- module Role
21
-
22
- # Manage users and their roles.
23
- USER_ADMIN = 'user-admin'
24
-
25
- # Manage indicies, user-defined functions and server configuration.
26
- SYS_ADMIN = 'sys-admin'
27
-
28
- # Allow read, write and UDF transactions with the database.
29
- READ_WRITE_UDF = "read-write-udf"
30
-
31
- # Allow read and write transactions with the database.
32
- READ_WRITE = 'read-write'
33
-
34
- # Allow read transactions with the database.
35
- READ = 'read'
36
-
37
- end # module
38
-
39
- end # module