ruby-kafka 0.5.0 → 0.5.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,56 +1,48 @@
1
- require 'kafka/sasl_gssapi_authenticator'
2
- require 'kafka/sasl_plain_authenticator'
1
+ require 'kafka/sasl/plain'
2
+ require 'kafka/sasl/gssapi'
3
+ require 'kafka/sasl/scram'
3
4
 
4
5
  module Kafka
5
6
  class SaslAuthenticator
6
- def initialize(logger:, sasl_gssapi_principal:, sasl_gssapi_keytab:, sasl_plain_authzid:, sasl_plain_username:, sasl_plain_password:)
7
+ def initialize(logger:, sasl_gssapi_principal:, sasl_gssapi_keytab:,
8
+ sasl_plain_authzid:, sasl_plain_username:, sasl_plain_password:,
9
+ sasl_scram_username:, sasl_scram_password:, sasl_scram_mechanism:)
7
10
  @logger = logger
8
- @sasl_gssapi_principal = sasl_gssapi_principal
9
- @sasl_gssapi_keytab = sasl_gssapi_keytab
10
- @sasl_plain_authzid = sasl_plain_authzid
11
- @sasl_plain_username = sasl_plain_username
12
- @sasl_plain_password = sasl_plain_password
13
- end
14
-
15
- def authenticate!(connection)
16
- if authenticate_using_sasl_gssapi?
17
- sasl_gssapi_authenticate(connection)
18
- elsif authenticate_using_sasl_plain?
19
- sasl_plain_authenticate(connection)
20
- end
21
- end
22
-
23
- private
24
11
 
25
- def sasl_gssapi_authenticate(connection)
26
- auth = SaslGssapiAuthenticator.new(
27
- connection: connection,
12
+ @plain = Sasl::Plain.new(
13
+ authzid: sasl_plain_authzid,
14
+ username: sasl_plain_username,
15
+ password: sasl_plain_password,
28
16
  logger: @logger,
29
- sasl_gssapi_principal: @sasl_gssapi_principal,
30
- sasl_gssapi_keytab: @sasl_gssapi_keytab
31
17
  )
32
18
 
33
- auth.authenticate!
34
- end
35
-
36
- def sasl_plain_authenticate(connection)
37
- auth = SaslPlainAuthenticator.new(
38
- connection: connection,
19
+ @gssapi = Sasl::Gssapi.new(
20
+ principal: sasl_gssapi_principal,
21
+ keytab: sasl_gssapi_keytab,
39
22
  logger: @logger,
40
- authzid: @sasl_plain_authzid,
41
- username: @sasl_plain_username,
42
- password: @sasl_plain_password
43
23
  )
44
24
 
45
- auth.authenticate!
25
+ @scram = Sasl::Scram.new(
26
+ username: sasl_scram_username,
27
+ password: sasl_scram_password,
28
+ mechanism: sasl_scram_mechanism,
29
+ logger: @logger,
30
+ )
46
31
  end
47
32
 
48
- def authenticate_using_sasl_gssapi?
49
- !@ssl_context && @sasl_gssapi_principal && !@sasl_gssapi_principal.empty?
50
- end
33
+ def authenticate!(connection)
34
+ mechanism = [@gssapi, @plain, @scram].find(&:configured?)
35
+
36
+ return if mechanism.nil?
37
+
38
+ ident = mechanism.ident
39
+ response = connection.send_request(Kafka::Protocol::SaslHandshakeRequest.new(ident))
40
+
41
+ unless response.error_code == 0 && response.enabled_mechanisms.include?(ident)
42
+ raise Kafka::Error, "#{ident} is not supported."
43
+ end
51
44
 
52
- def authenticate_using_sasl_plain?
53
- @sasl_plain_authzid && @sasl_plain_username && @sasl_plain_password
45
+ mechanism.authenticate!(connection.to_s, connection.encoder, connection.decoder)
54
46
  end
55
47
  end
56
48
  end
data/lib/kafka/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kafka
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1.beta1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-kafka
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Schierbeck
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-27 00:00:00.000000000 Z
11
+ date: 2017-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -255,6 +255,7 @@ executables: []
255
255
  extensions: []
256
256
  extra_rdoc_files: []
257
257
  files:
258
+ - ".circleci/config.yml"
258
259
  - ".gitignore"
259
260
  - ".rspec"
260
261
  - ".rubocop.yml"
@@ -271,7 +272,7 @@ files:
271
272
  - ci/consumer.rb
272
273
  - ci/init.rb
273
274
  - ci/producer.rb
274
- - circle.yml
275
+ - docker-compose.yml
275
276
  - examples/consumer-group.rb
276
277
  - examples/firehose-consumer.rb
277
278
  - examples/firehose-producer.rb
@@ -305,7 +306,11 @@ files:
305
306
  - lib/kafka/produce_operation.rb
306
307
  - lib/kafka/producer.rb
307
308
  - lib/kafka/protocol.rb
309
+ - lib/kafka/protocol/api_versions_request.rb
310
+ - lib/kafka/protocol/api_versions_response.rb
308
311
  - lib/kafka/protocol/consumer_group_protocol.rb
312
+ - lib/kafka/protocol/create_topics_request.rb
313
+ - lib/kafka/protocol/create_topics_response.rb
309
314
  - lib/kafka/protocol/decoder.rb
310
315
  - lib/kafka/protocol/encoder.rb
311
316
  - lib/kafka/protocol/fetch_request.rb
@@ -337,9 +342,10 @@ files:
337
342
  - lib/kafka/protocol/sync_group_response.rb
338
343
  - lib/kafka/protocol/topic_metadata_request.rb
339
344
  - lib/kafka/round_robin_assignment_strategy.rb
345
+ - lib/kafka/sasl/gssapi.rb
346
+ - lib/kafka/sasl/plain.rb
347
+ - lib/kafka/sasl/scram.rb
340
348
  - lib/kafka/sasl_authenticator.rb
341
- - lib/kafka/sasl_gssapi_authenticator.rb
342
- - lib/kafka/sasl_plain_authenticator.rb
343
349
  - lib/kafka/snappy_codec.rb
344
350
  - lib/kafka/socket_with_timeout.rb
345
351
  - lib/kafka/ssl_socket_with_timeout.rb
@@ -376,12 +382,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
376
382
  version: 2.1.0
377
383
  required_rubygems_version: !ruby/object:Gem::Requirement
378
384
  requirements:
379
- - - ">="
385
+ - - ">"
380
386
  - !ruby/object:Gem::Version
381
- version: '0'
387
+ version: 1.3.1
382
388
  requirements: []
383
389
  rubyforge_project:
384
- rubygems_version: 2.6.11
390
+ rubygems_version: 2.6.13
385
391
  signing_key:
386
392
  specification_version: 4
387
393
  summary: A client library for the Kafka distributed commit log.
data/circle.yml DELETED
@@ -1,23 +0,0 @@
1
- machine:
2
- pre:
3
- - curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0
4
- services:
5
- - docker
6
- environment:
7
- LOG_LEVEL: DEBUG
8
- ruby:
9
- version: 2.4.1
10
-
11
- dependencies:
12
- pre:
13
- - docker -v
14
- - docker pull ches/kafka:0.10.0.0
15
- - docker pull jplock/zookeeper:3.4.6
16
-
17
- test:
18
- override:
19
- - bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/unit.xml
20
- - bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/functional.xml --tag functional
21
- post:
22
- - bundle exec rubocop
23
- - cp *.log $CIRCLE_ARTIFACTS/ || true
@@ -1,77 +0,0 @@
1
- module Kafka
2
- class SaslGssapiAuthenticator
3
- GSSAPI_IDENT = "GSSAPI"
4
- GSSAPI_CONFIDENTIALITY = false
5
-
6
- def initialize(connection:, logger:, sasl_gssapi_principal:, sasl_gssapi_keytab:)
7
- @connection = connection
8
- @logger = logger
9
- @principal = sasl_gssapi_principal
10
- @keytab = sasl_gssapi_keytab
11
-
12
- load_gssapi
13
- initialize_gssapi_context
14
- end
15
-
16
- def authenticate!
17
- proceed_sasl_gssapi_negotiation
18
- end
19
-
20
- private
21
-
22
- def proceed_sasl_gssapi_negotiation
23
- response = @connection.send_request(Kafka::Protocol::SaslHandshakeRequest.new(GSSAPI_IDENT))
24
-
25
- @encoder = @connection.encoder
26
- @decoder = @connection.decoder
27
-
28
- unless response.error_code == 0 && response.enabled_mechanisms.include?(GSSAPI_IDENT)
29
- raise Kafka::Error, "#{GSSAPI_IDENT} is not supported."
30
- end
31
-
32
- # send gssapi token and receive token to verify
33
- token_to_verify = send_and_receive_sasl_token
34
-
35
- # verify incoming token
36
- unless @gssapi_ctx.init_context(token_to_verify)
37
- raise Kafka::Error, "GSSAPI context verification failed."
38
- end
39
-
40
- # we can continue, so send OK
41
- @encoder.write([0, 2].pack('l>c'))
42
-
43
- # read wrapped message and return it back with principal
44
- handshake_messages
45
- end
46
-
47
- def handshake_messages
48
- msg = @decoder.bytes
49
- raise Kafka::Error, "GSSAPI negotiation failed." unless msg
50
- # unwrap with integrity only
51
- msg_unwrapped = @gssapi_ctx.unwrap_message(msg, GSSAPI_CONFIDENTIALITY)
52
- msg_wrapped = @gssapi_ctx.wrap_message(msg_unwrapped + @principal, GSSAPI_CONFIDENTIALITY)
53
- @encoder.write_bytes(msg_wrapped)
54
- end
55
-
56
- def send_and_receive_sasl_token
57
- @encoder.write_bytes(@gssapi_token)
58
- @decoder.bytes
59
- end
60
-
61
- def load_gssapi
62
- begin
63
- require "gssapi"
64
- rescue LoadError
65
- @logger.error "In order to use GSSAPI authentication you need to install the `gssapi` gem."
66
- raise
67
- end
68
- end
69
-
70
- def initialize_gssapi_context
71
- @logger.debug "GSSAPI: Initializing context with #{@connection.to_s}, principal #{@principal}"
72
-
73
- @gssapi_ctx = GSSAPI::Simple.new(@connection.to_s, @principal, @keytab)
74
- @gssapi_token = @gssapi_ctx.init_context(nil)
75
- end
76
- end
77
- end
@@ -1,37 +0,0 @@
1
- module Kafka
2
- class SaslPlainAuthenticator
3
- PLAIN_IDENT = "PLAIN"
4
-
5
- def initialize(connection:, logger:, authzid:, username:, password:)
6
- @connection = connection
7
- @logger = logger
8
- @authzid = authzid
9
- @username = username
10
- @password = password
11
- end
12
-
13
- def authenticate!
14
- response = @connection.send_request(Kafka::Protocol::SaslHandshakeRequest.new(PLAIN_IDENT))
15
-
16
- @encoder = @connection.encoder
17
- @decoder = @connection.decoder
18
-
19
- unless response.error_code == 0 && response.enabled_mechanisms.include?(PLAIN_IDENT)
20
- raise Kafka::Error, "#{PLAIN_IDENT} is not supported."
21
- end
22
-
23
- # SASL PLAIN
24
- msg = [@authzid.to_s,
25
- @username.to_s,
26
- @password.to_s].join("\000").force_encoding('utf-8')
27
- @encoder.write_bytes(msg)
28
- begin
29
- msg = @decoder.bytes
30
- raise Kafka::Error, 'SASL PLAIN authentication failed: unknown error' unless msg
31
- rescue Errno::ETIMEDOUT, EOFError => e
32
- raise Kafka::Error, "SASL PLAIN authentication failed: #{e.message}"
33
- end
34
- @logger.debug 'SASL PLAIN authentication successful.'
35
- end
36
- end
37
- end