castle-rb 2.3.2 → 3.0.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.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +55 -9
  3. data/lib/castle.rb +17 -7
  4. data/lib/castle/api.rb +20 -22
  5. data/lib/castle/client.rb +50 -19
  6. data/lib/castle/command.rb +5 -0
  7. data/lib/castle/commands/authenticate.rb +25 -0
  8. data/lib/castle/commands/identify.rb +30 -0
  9. data/lib/castle/commands/review.rb +13 -0
  10. data/lib/castle/commands/track.rb +25 -0
  11. data/lib/castle/commands/with_context.rb +28 -0
  12. data/lib/castle/configuration.rb +46 -14
  13. data/lib/castle/context_merger.rb +13 -0
  14. data/lib/castle/default_context.rb +28 -0
  15. data/lib/castle/errors.rb +2 -0
  16. data/lib/castle/extractors/client_id.rb +4 -14
  17. data/lib/castle/extractors/headers.rb +6 -18
  18. data/lib/castle/failover_auth_response.rb +21 -0
  19. data/lib/castle/header_formatter.rb +9 -0
  20. data/lib/castle/request.rb +7 -13
  21. data/lib/castle/response.rb +2 -0
  22. data/lib/castle/review.rb +11 -0
  23. data/lib/castle/secure_mode.rb +11 -0
  24. data/lib/castle/support/hanami.rb +19 -0
  25. data/lib/castle/support/padrino.rb +1 -1
  26. data/lib/castle/support/rails.rb +1 -1
  27. data/lib/castle/support/sinatra.rb +4 -2
  28. data/lib/castle/utils.rb +55 -0
  29. data/lib/castle/utils/cloner.rb +11 -0
  30. data/lib/castle/utils/merger.rb +23 -0
  31. data/lib/castle/version.rb +1 -1
  32. data/spec/lib/castle/api_spec.rb +16 -25
  33. data/spec/lib/castle/client_spec.rb +175 -39
  34. data/spec/lib/castle/command_spec.rb +9 -0
  35. data/spec/lib/castle/commands/authenticate_spec.rb +106 -0
  36. data/spec/lib/castle/commands/identify_spec.rb +85 -0
  37. data/spec/lib/castle/commands/review_spec.rb +24 -0
  38. data/spec/lib/castle/commands/track_spec.rb +107 -0
  39. data/spec/lib/castle/configuration_spec.rb +75 -27
  40. data/spec/lib/castle/context_merger_spec.rb +34 -0
  41. data/spec/lib/castle/default_context_spec.rb +35 -0
  42. data/spec/lib/castle/extractors/client_id_spec.rb +13 -5
  43. data/spec/lib/castle/extractors/headers_spec.rb +6 -5
  44. data/spec/lib/castle/extractors/ip_spec.rb +2 -9
  45. data/spec/lib/castle/header_formatter_spec.rb +21 -0
  46. data/spec/lib/castle/request_spec.rb +12 -9
  47. data/spec/lib/castle/response_spec.rb +1 -3
  48. data/spec/lib/castle/review_spec.rb +23 -0
  49. data/spec/lib/castle/secure_mode_spec.rb +9 -0
  50. data/spec/lib/castle/utils/cloner_spec.rb +18 -0
  51. data/spec/lib/castle/utils/merger_spec.rb +13 -0
  52. data/spec/lib/castle/utils_spec.rb +156 -0
  53. data/spec/lib/castle/version_spec.rb +1 -5
  54. data/spec/lib/castle_spec.rb +8 -15
  55. data/spec/spec_helper.rb +3 -9
  56. metadata +46 -12
  57. data/lib/castle/cookie_store.rb +0 -52
  58. data/lib/castle/headers.rb +0 -39
  59. data/lib/castle/support.rb +0 -11
  60. data/lib/castle/system.rb +0 -36
  61. data/spec/lib/castle/headers_spec.rb +0 -82
  62. data/spec/lib/castle/system_spec.rb +0 -70
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Castle
4
- module CookieStore
5
- class Base
6
- EXPIRATION_TIME = 20 * 365 * 24 * 60 * 60 # cookie expiration time 20y
7
-
8
- def initialize(request, response)
9
- @request = request
10
- @response = response
11
- end
12
-
13
- def [](key)
14
- @request.cookies[key]
15
- end
16
-
17
- def []=(key, value)
18
- @request.cookies[key] = value
19
- if value
20
- @response.set_cookie(key,
21
- value: value,
22
- expires: Time.now + EXPIRATION_TIME,
23
- path: '/')
24
- else
25
- @response.delete_cookie(key)
26
- end
27
- end
28
- end
29
-
30
- class Rack
31
- def initialize(cookies)
32
- @cookies = cookies
33
- end
34
-
35
- def [](key)
36
- @cookies[key]
37
- end
38
-
39
- def []=(key, value)
40
- if value
41
- @cookies[key] = {
42
- value: value,
43
- expires: Time.now + EXPIRATION_TIME,
44
- path: '/'
45
- }
46
- else
47
- @cookies.delete(key)
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Castle
4
- # setups headers for requests
5
- class Headers
6
- def initialize
7
- @config = Castle.config
8
- @headers = {
9
- 'Content-Type' => 'application/json',
10
- 'User-Agent' => "Castle/v1 RubyBindings/#{Castle::VERSION}"
11
- }
12
- end
13
-
14
- def prepare(client_id, ip, castle_headers)
15
- @headers.merge!(
16
- 'X-Castle-Client-Id' => client_id,
17
- 'X-Castle-Ip' => ip,
18
- 'X-Castle-Headers' => castle_headers,
19
- 'X-Castle-Client-User-Agent' => JSON.generate(client_user_agent),
20
- 'X-Castle-Source' => @config.source_header
21
- )
22
- @headers.delete_if { |_k, header_value| header_value.nil? }
23
- @headers
24
- end
25
-
26
- private
27
-
28
- def client_user_agent
29
- {
30
- bindings_version: Castle::VERSION,
31
- lang: 'ruby',
32
- lang_version: Castle::System.ruby_version,
33
- platform: Castle::System.platform,
34
- publisher: 'castle',
35
- uname: Castle::System.uname
36
- }
37
- end
38
- end
39
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'castle/support/rails' if defined?(Rails::Railtie)
4
-
5
- if defined?(Sinatra::Base)
6
- if defined?(Padrino)
7
- require 'castle/support/padrino'
8
- else
9
- require 'castle/support/sinatra'
10
- end
11
- end
data/lib/castle/system.rb DELETED
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Castle
4
- # Get information regarding system
5
- module System
6
- class << self
7
- # Returns hardware name, nodename, operating system release,
8
- # name and version
9
- # @example Castle::System.uname #=>
10
- # Linux server 3.18.44-vs2.3.7.5-beng #1 SMP
11
- # Thu Oct 27 14:11:29 BST 2016 x86_64 GNU/Linux
12
- def uname
13
- `uname -a 2>/dev/null`.strip if platform =~ /linux|darwin/i
14
- rescue Errno::ENOMEM # couldn't create subprocess
15
- 'uname lookup failed'
16
- end
17
-
18
- # Returns current system platform
19
- # @example Castle::System.platform #=> 'x86_64-pc-linux-gnu'
20
- def platform
21
- begin
22
- require 'rbconfig'
23
- RbConfig::CONFIG['host'] || RUBY_PLATFORM
24
- rescue LoadError
25
- RUBY_PLATFORM
26
- end.downcase
27
- end
28
-
29
- # Returns ruby version
30
- # @example Castle::System.ruby_version #=> '2.4.1-p111 (2017-03-22)'
31
- def ruby_version
32
- "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
33
- end
34
- end
35
- end
36
- end
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Castle::Headers do
6
- subject do
7
- described_class.new
8
- end
9
-
10
- before do
11
- allow(Castle.config).to receive(:source_header).and_return('web')
12
- stub_const('Castle::VERSION', '2.2.0')
13
- end
14
-
15
- let(:ip) { '1.1.1.1' }
16
- let(:castle_headers) { 'headers' }
17
- let(:client_id) { 'some_id' }
18
-
19
- let(:prepared_headers) do
20
- subject.prepare(client_id, ip, castle_headers)
21
- end
22
-
23
- shared_examples 'for_header' do |header, value|
24
- let(:header) { header }
25
-
26
- it "has header #{header}" do
27
- expect(prepared_headers[header]).to eql(value)
28
- end
29
- end
30
- it_behaves_like 'for_header', 'Content-Type', 'application/json'
31
- it_behaves_like 'for_header', 'X-Castle-Client-Id', 'some_id'
32
- it_behaves_like 'for_header', 'X-Castle-Ip', '1.1.1.1'
33
- it_behaves_like 'for_header', 'X-Castle-Headers', 'headers'
34
- it_behaves_like 'for_header', 'X-Castle-Source', 'web'
35
- it_behaves_like 'for_header',
36
- 'User-Agent',
37
- 'Castle/v1 RubyBindings/2.2.0'
38
-
39
- describe 'X-Castle-Client-User-Agent' do
40
- let(:header) { 'X-Castle-Client-User-Agent' }
41
- let(:prepared_header_parsed) { JSON.parse(prepared_headers[header]) }
42
-
43
- before do
44
- allow(Castle::System).to receive(:uname).and_return('name')
45
- end
46
-
47
- it { expect(prepared_header_parsed).to include('lang') }
48
- it { expect(prepared_header_parsed).to include('lang_version') }
49
- it { expect(prepared_header_parsed).to include('platform') }
50
- it { expect(prepared_header_parsed).to include('publisher') }
51
- it { expect(prepared_header_parsed['bindings_version']).to eql('2.2.0') }
52
- it { expect(prepared_header_parsed['uname']).to eql('name') }
53
- end
54
-
55
- context 'missing' do
56
- shared_examples 'for_missing_header' do |header|
57
- let(:header) { header }
58
-
59
- it "it missing header #{header}" do
60
- expect(prepared_headers.key?(header)).to be_falsey
61
- end
62
- end
63
-
64
- context 'ip' do
65
- let(:ip) { nil }
66
-
67
- it_behaves_like 'for_missing_header', 'X-Castle-Ip'
68
- end
69
-
70
- context 'client_id' do
71
- let(:client_id) { nil }
72
-
73
- it_behaves_like 'for_missing_header', 'X-Castle-Cookie-Id'
74
- end
75
-
76
- context 'castle headers' do
77
- let(:castle_headers) { nil }
78
-
79
- it_behaves_like 'for_missing_header', 'X-Castle-Headers'
80
- end
81
- end
82
- end
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Castle::System do
6
- describe '.uname' do
7
- subject(:uname) { described_class.uname }
8
-
9
- before { allow(described_class).to receive(:platform) { platform } }
10
-
11
- context 'darwin' do
12
- let(:platform) { 'x86_64-apple-darwin16.6.0' }
13
-
14
- it { expect { uname }.not_to raise_error }
15
- it { expect(uname).to be_kind_of(String) }
16
- end
17
-
18
- context 'linux' do
19
- let(:platform) { 'x86_64-pc-linux-gnu' }
20
-
21
- it { expect { uname }.not_to raise_error }
22
- it { expect(uname).to be_kind_of(String) }
23
- end
24
-
25
- context 'different' do
26
- let(:platform) { 'different' }
27
-
28
- it { expect { uname }.not_to raise_error }
29
- it { expect(uname).to be_nil }
30
- end
31
-
32
- context 'Errno::ENOMEM' do
33
- let(:platform) { 'x86_64-pc-linux-gnu' }
34
-
35
- before do
36
- allow(described_class).to receive(:`).with(
37
- 'uname -a 2>/dev/null'
38
- ).and_raise(Errno::ENOMEM)
39
- end
40
-
41
- it { expect { uname }.not_to raise_error }
42
- it { expect(uname).to be_kind_of(String) }
43
- it { expect(uname).to eql('uname lookup failed') }
44
- end
45
- end
46
-
47
- describe '.platform' do
48
- subject(:platform) { described_class.platform }
49
-
50
- context 'rbconfig' do
51
- it { expect(platform).to eq(RbConfig::CONFIG['host']) }
52
- end
53
-
54
- context 'RUBY_PLATFORM' do
55
- before { stub_const('RbConfig::CONFIG', host: nil) }
56
-
57
- it { expect(platform).to eq(RUBY_PLATFORM) }
58
- end
59
- end
60
-
61
- describe '.ruby_version' do
62
- subject(:ruby_version) { described_class.ruby_version }
63
-
64
- let(:version) do
65
- "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
66
- end
67
-
68
- it { expect(ruby_version).to eq(version) }
69
- end
70
- end