locked-rb 0.0.2 → 0.0.3

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: 7bb0ddbc28a9ad9f08852ff6c570c2a225a1572a2ac654b58eba21848e5b4b26
4
- data.tar.gz: c21af9b3d3a4eff168fc7097a6b51240173b60ad2974ce0b83f5e8526cc00106
3
+ metadata.gz: 64951c658b06a83e358adbc3c642bea2436f1eb1bd3860571a211440b48a5077
4
+ data.tar.gz: e95b6a99564437a343ae196f408c9baa994044628eeb7570f9e9d8ca8df75c4e
5
5
  SHA512:
6
- metadata.gz: ccd2c32486cd302541cbf8d69ee5d0bf08dc8f36bc574d4b38257ce6c9a20e1f33c945e01e30c09eff494794b7ba0e249dc9265a7e953db24db88bcdb5989820
7
- data.tar.gz: ff7bee55ea1dc0e853cdcb8d1c6a17976754a5afc29658341ca7f91d0382b23e5b1afc012f095b838c736f9e8a47b4ce92355861332c43fa1386e0f7554f20bd
6
+ metadata.gz: e0a4cf2b3ae6a0fab35bac7f61e84fae9115ee9e9804eddeb18e500b2a8df93d8257b14988356560fa4b8db7b34ccd41937ce2738a62eedd391937964425bc0e
7
+ data.tar.gz: 51a40bf5f9494e7948180042f820dfb0b311513b0d1c35b4026689f27697f67b461c402a05241aa37df95e51dcf56032d12947820bca1249a95089e77a8a1d8b
data/lib/locked.rb CHANGED
@@ -23,8 +23,9 @@
23
23
  locked/commands/identify
24
24
  locked/commands/authenticate
25
25
  locked/commands/review
26
+ locked/commands/verify
26
27
  locked/configuration
27
- locked/failover_auth_response
28
+ locked/failover_response
28
29
  locked/client
29
30
  locked/header_formatter
30
31
  locked/secure_mode
@@ -36,6 +37,7 @@
36
37
  locked/api/request/build
37
38
  locked/review
38
39
  locked/api
40
+ locked/configurations/merger
39
41
  ].each(&method(:require))
40
42
 
41
43
  # main sdk module
data/lib/locked/client.rb CHANGED
@@ -43,7 +43,31 @@ module Locked
43
43
  Locked::API.request(command).merge(failover: false, failover_reason: nil)
44
44
  rescue Locked::RequestError, Locked::InternalServerError => error
45
45
  self.class.failover_response_or_raise(
46
- FailoverAuthResponse.new(options[:user_id], reason: error.to_s), error
46
+ Locked::FailoverResponse::Auth.new(options[:user_id], reason: error.to_s), error
47
+ )
48
+ end
49
+ end
50
+
51
+ def failed_in_verification(token = {})
52
+ command = Locked::Commands::Verify.new(@context).build('deny_verification', token)
53
+ begin
54
+ response = Locked::API.request(command)
55
+ response.merge(failover: false, failover_reason: nil)
56
+ rescue Locked::RequestError, Locked::InternalServerError => error
57
+ self.class.failover_response_or_raise(
58
+ Locked::FailoverResponse::Verification.new(reason: error.to_s), error
59
+ )
60
+ end
61
+ end
62
+
63
+ def succeeded_in_verification(token = {})
64
+ command = Locked::Commands::Verify.new(@context).build('allow_verification', token)
65
+ begin
66
+ response = Locked::API.request(command)
67
+ response.merge(failover: false, failover_reason: nil)
68
+ rescue Locked::RequestError, Locked::InternalServerError => error
69
+ self.class.failover_response_or_raise(
70
+ Locked::FailoverResponse::Verification.new(reason: error.to_s), error
47
71
  )
48
72
  end
49
73
  end
@@ -11,10 +11,11 @@ module Locked
11
11
  Locked::Validators::Present.call(options, %i[event])
12
12
  context = Locked::Context::Merger.call(@context, options[:context])
13
13
  context = Locked::Context::Sanitizer.call(context)
14
+ options_with_config = Locked::Configurations::Merger.call(options)
14
15
 
15
16
  Locked::Command.new(
16
17
  'authenticate',
17
- options.merge(context: context),
18
+ options_with_config.merge(context: context),
18
19
  :post
19
20
  )
20
21
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Locked
4
+ module Commands
5
+ class Verify
6
+ def initialize(context)
7
+ @context = context
8
+ end
9
+
10
+ def build(path, body, **options)
11
+ context = Locked::Context::Merger.call(@context, options[:context])
12
+ context = Locked::Context::Sanitizer.call(context)
13
+ body_with_context = body.merge(context: context)
14
+
15
+ Locked::Command.new(path, body_with_context, :post)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -3,8 +3,14 @@
3
3
  module Locked
4
4
  # manages configuration variables
5
5
  class Configuration
6
- HOST = 'locked.jp'
7
- PORT = 443
6
+ HOST = if ENV['DOCKER_USE'].to_i == 1
7
+ 'app'
8
+ elsif ENV['LOCKED_RUBY_DEV_MODE'].to_s == 'on'
9
+ 'localhost'
10
+ else
11
+ 'api.locked.jp'
12
+ end
13
+ PORT = ENV['LOCKED_RUBY_DEV_MODE'] == 'on' ? 3000 : 443
8
14
  URL_PREFIX = 'api/v1/client'
9
15
  FAILOVER_STRATEGY = :deny
10
16
  REQUEST_TIMEOUT = 1000 # in milliseconds
@@ -25,9 +31,10 @@ module Locked
25
31
  'CF_CONNECTING_IP'
26
32
  ].freeze
27
33
  BLACKLISTED = ['HTTP_COOKIE'].freeze
34
+ CUSTOM_VERIFICATION = %i[email].freeze
28
35
 
29
36
  attr_accessor :host, :port, :request_timeout, :url_prefix
30
- attr_reader :api_key, :whitelisted, :blacklisted, :failover_strategy
37
+ attr_reader :api_key, :whitelisted, :blacklisted, :failover_strategy, :custom_verification
31
38
 
32
39
  def initialize
33
40
  @formatter = Locked::HeaderFormatter.new
@@ -39,6 +46,7 @@ module Locked
39
46
  self.whitelisted = WHITELISTED
40
47
  self.blacklisted = BLACKLISTED
41
48
  self.api_key = ''
49
+ self.custom_verification = []
42
50
  end
43
51
 
44
52
  def api_key=(value)
@@ -62,6 +70,14 @@ module Locked
62
70
  raise Locked::ConfigurationError, 'unrecognized failover strategy' if @failover_strategy.nil?
63
71
  end
64
72
 
73
+ def custom_verification=(values)
74
+ return @custom_verification = [] if values.empty?
75
+ @custom_verification = values.each_with_object([]) do |value, array|
76
+ raise Locked::ConfigurationError, 'unrecognized custom verification' unless CUSTOM_VERIFICATION.include?(value)
77
+ array << value
78
+ end
79
+ end
80
+
65
81
  private
66
82
 
67
83
  def respond_to_missing?(method_name, _include_private)
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Locked
4
+ module Configurations
5
+ class Merger
6
+ class << self
7
+ def call(options)
8
+ return options if Locked.config.custom_verification.empty?
9
+
10
+ options.merge(custom_verification: Locked.config.custom_verification)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Locked
4
+ module FailoverResponse
5
+ # generate failover authentication response
6
+ class Auth
7
+ def initialize(user_id, strategy: Locked.config.failover_strategy, reason:)
8
+ @strategy = strategy
9
+ @reason = reason
10
+ @user_id = user_id
11
+ end
12
+
13
+ def generate
14
+ {
15
+ data: {
16
+ action: @strategy.to_s,
17
+ user_id: @user_id,
18
+ },
19
+ failover: true,
20
+ failover_reason: @reason
21
+ }
22
+ end
23
+ end
24
+
25
+ class Verification
26
+ def initialize(strategy: Locked.config.failover_strategy, reason:)
27
+ @strategy = strategy
28
+ @reason = reason
29
+ end
30
+
31
+ def generate
32
+ {
33
+ data: {
34
+ action: @strategy.to_s,
35
+ },
36
+ failover: true,
37
+ failover_reason: @reason
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Locked
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
@@ -142,7 +142,7 @@ describe Locked::Client do
142
142
  before { request_response }
143
143
 
144
144
  it do
145
- assert_requested :post, 'https://locked.jp/api/v1/client/authenticate', times: 1 do |req|
145
+ assert_requested :post, 'https://api.locked.jp/api/v1/client/authenticate', times: 1 do |req|
146
146
  JSON.parse(req.body) == JSON.parse(request_body.to_json)
147
147
  end
148
148
  end
@@ -155,7 +155,7 @@ describe Locked::Client do
155
155
  end
156
156
 
157
157
  it do
158
- assert_requested :post, 'https://locked.jp/api/v1/client/authenticate', times: 1 do |req|
158
+ assert_requested :post, 'https://api.locked.jp/api/v1/client/authenticate', times: 1 do |req|
159
159
  JSON.parse(req.body) == JSON.parse(request_body.to_json)
160
160
  end
161
161
  end
@@ -168,7 +168,7 @@ describe Locked::Client do
168
168
  end
169
169
 
170
170
  it do
171
- assert_requested :post, 'https://locked.jp/api/v1/client/authenticate', times: 1 do |req|
171
+ assert_requested :post, 'https://api.locked.jp/api/v1/client/authenticate', times: 1 do |req|
172
172
  JSON.parse(req.body) == JSON.parse(request_body.to_json)
173
173
  end
174
174
  end
@@ -181,7 +181,7 @@ describe Locked::Client do
181
181
  before { request_response }
182
182
 
183
183
  it do
184
- assert_requested :post, 'https://locked.jp/api/v1/client/authenticate', times: 1 do |req|
184
+ assert_requested :post, 'https://api.locked.jp/api/v1/client/authenticate', times: 1 do |req|
185
185
  JSON.parse(req.body) == JSON.parse(request_body.to_json)
186
186
  end
187
187
  end
@@ -223,4 +223,70 @@ describe Locked::Client do
223
223
  end
224
224
  end
225
225
  end
226
+
227
+ describe '#failed_in_verification' do
228
+ let(:request_body) { { token: 'sample25f90350c69f50acc968' } }
229
+
230
+ subject { client.failed_in_verification(request_body) }
231
+
232
+ context '正常系' do
233
+ it '期待したrequest bodyが生成されること' do
234
+ subject
235
+
236
+ assert_requested :post, 'https://api.locked.jp/api/v1/client/deny_verification', times: 1 do |req|
237
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
238
+ end
239
+ end
240
+ end
241
+
242
+ context '異常系' do
243
+ before { allow(Locked::API).to receive(:request).and_raise(Locked::RequestError.new(Timeout::Error)) }
244
+
245
+ context 'with request error and throw strategy' do
246
+ before { allow(Locked.config).to receive(:failover_strategy).and_return(:throw) }
247
+
248
+ it { expect { subject }.to raise_error(Locked::RequestError) }
249
+ end
250
+
251
+ context 'with request error and not throw on eg deny strategy' do
252
+ it { assert_not_requested :post, 'https://locked.jp/api/v1/client/deny_verification' }
253
+ it { expect(subject[:data][:action]).to be_eql('deny') }
254
+ it { expect(subject[:failover]).to be true }
255
+ it { expect(subject[:failover_reason]).to be_eql('Locked::RequestError') }
256
+ end
257
+ end
258
+ end
259
+
260
+ describe '#succeeded_in_verification' do
261
+ let(:request_body) { { token: 'sample25f90350c69f50acc968' } }
262
+
263
+ subject { client.succeeded_in_verification(request_body) }
264
+
265
+ context '正常系' do
266
+ it '期待したrequest bodyが生成されること' do
267
+ subject
268
+
269
+ assert_requested :post, 'https://api.locked.jp/api/v1/client/allow_verification', times: 1 do |req|
270
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
271
+ end
272
+ end
273
+ end
274
+
275
+ context '異常系' do
276
+ before { allow(Locked::API).to receive(:request).and_raise(Locked::RequestError.new(Timeout::Error)) }
277
+
278
+ context 'with request error and throw strategy' do
279
+ before { allow(Locked.config).to receive(:failover_strategy).and_return(:throw) }
280
+
281
+ it { expect { subject }.to raise_error(Locked::RequestError) }
282
+ end
283
+
284
+ context 'with request error and not throw on eg deny strategy' do
285
+ it { assert_not_requested :post, 'https://locked.jp/api/v1/client/allow_verification' }
286
+ it { expect(subject[:data][:action]).to be_eql('deny') }
287
+ it { expect(subject[:failover]).to be true }
288
+ it { expect(subject[:failover_reason]).to be_eql('Locked::RequestError') }
289
+ end
290
+ end
291
+ end
226
292
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Locked::Commands::Verify do
4
+ let(:context) { { test: { test1: '1' } } }
5
+
6
+ describe '.build' do
7
+ subject { Locked::Commands::Verify.new(context).build('deny_verification', token: 'f68c5f338f2ba6b14e17') }
8
+
9
+ it '期待したpathが返ること' do
10
+ expect(subject.path).to eq 'deny_verification'
11
+ end
12
+
13
+ it '期待したbodyが返ること' do
14
+ expect(subject.data).to include token: 'f68c5f338f2ba6b14e17'
15
+ end
16
+
17
+ it '期待したhttpメソッドが返ること' do
18
+ expect(subject.method).to eq :post
19
+ end
20
+ end
21
+ end
@@ -7,7 +7,7 @@ describe Locked::Configuration do
7
7
 
8
8
  describe 'host' do
9
9
  context 'with default' do
10
- it { expect(config.host).to be_eql('locked.jp') }
10
+ it { expect(config.host).to be_eql('api.locked.jp') }
11
11
  end
12
12
 
13
13
  context 'with setter' do
@@ -143,4 +143,28 @@ describe Locked::Configuration do
143
143
  end
144
144
  end
145
145
  end
146
+
147
+ describe 'custom_verification' do
148
+ it do
149
+ expect(config.custom_verification).to be_eql([])
150
+ end
151
+
152
+ context 'with setter' do
153
+ before do
154
+ config.custom_verification = [:email]
155
+ end
156
+
157
+ it do
158
+ expect(config.custom_verification).to be_eql([:email])
159
+ end
160
+ end
161
+
162
+ context 'when broken' do
163
+ it do
164
+ expect do
165
+ config.custom_verification = [:unknown]
166
+ end.to raise_error(Locked::ConfigurationError)
167
+ end
168
+ end
169
+ end
146
170
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Locked::Configurations::Merger do
4
+ describe '.call' do
5
+ context '正常系' do
6
+ let(:options) do
7
+ {
8
+ event: '$login.success',
9
+ user_id: 1234,
10
+ user_ip: '1.1.1.1',
11
+ user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063',
12
+ email: 'example@locked.jp',
13
+ callback_url: 'https://locked.jp/login/result'
14
+ }
15
+ end
16
+
17
+ context 'configでcustom_verificationが設定されていない場合' do
18
+ it '引数で投げられたoptionsが返ること' do
19
+ expect(Locked::Configurations::Merger.call(options)).to eq options
20
+ end
21
+ end
22
+
23
+ context 'configでcustom_verificationが設定されている場合' do
24
+ before do
25
+ Locked.config.custom_verification = [:email]
26
+ end
27
+
28
+ it '引数で投げられたoptionsにcustom verificationがマージされて返ること' do
29
+ expect(Locked::Configurations::Merger.call(options)).to include custom_verification: [:email]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,11 +4,10 @@ require 'rubygems'
4
4
  require 'bundler/setup'
5
5
  require 'rack'
6
6
  require 'webmock/rspec'
7
- require 'byebug'
8
7
  require 'timecop'
9
8
 
10
- require 'coveralls'
11
- Coveralls.wear!
9
+ # require 'coveralls'
10
+ # Coveralls.wear!
12
11
 
13
12
  require 'locked'
14
13
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: locked-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoshiki Takeda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-20 00:00:00.000000000 Z
11
+ date: 2019-09-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: locked protects your users from account compromise
14
14
  email: takeda@locked.jp
@@ -28,7 +28,9 @@ files:
28
28
  - lib/locked/commands/authenticate.rb
29
29
  - lib/locked/commands/identify.rb
30
30
  - lib/locked/commands/review.rb
31
+ - lib/locked/commands/verify.rb
31
32
  - lib/locked/configuration.rb
33
+ - lib/locked/configurations/merger.rb
32
34
  - lib/locked/context/default.rb
33
35
  - lib/locked/context/merger.rb
34
36
  - lib/locked/context/sanitizer.rb
@@ -36,7 +38,7 @@ files:
36
38
  - lib/locked/extractors/client_id.rb
37
39
  - lib/locked/extractors/headers.rb
38
40
  - lib/locked/extractors/ip.rb
39
- - lib/locked/failover_auth_response.rb
41
+ - lib/locked/failover_response.rb
40
42
  - lib/locked/header_formatter.rb
41
43
  - lib/locked/review.rb
42
44
  - lib/locked/secure_mode.rb
@@ -60,7 +62,9 @@ files:
60
62
  - spec/lib/Locked/commands/authenticate_spec.rb
61
63
  - spec/lib/Locked/commands/identify_spec.rb
62
64
  - spec/lib/Locked/commands/review_spec.rb
65
+ - spec/lib/Locked/commands/verify_spec.rb
63
66
  - spec/lib/Locked/configuration_spec.rb
67
+ - spec/lib/Locked/configurations/merger_spec.rb
64
68
  - spec/lib/Locked/context/default_spec.rb
65
69
  - spec/lib/Locked/context/merger_spec.rb
66
70
  - spec/lib/Locked/context/sanitizer_spec.rb
@@ -104,6 +108,7 @@ specification_version: 4
104
108
  summary: locked
105
109
  test_files:
106
110
  - spec/spec_helper.rb
111
+ - spec/lib/Locked/configurations/merger_spec.rb
107
112
  - spec/lib/Locked/review_spec.rb
108
113
  - spec/lib/Locked/client_spec.rb
109
114
  - spec/lib/Locked/context/default_spec.rb
@@ -122,6 +127,7 @@ test_files:
122
127
  - spec/lib/Locked/api/request/build_spec.rb
123
128
  - spec/lib/Locked/commands/review_spec.rb
124
129
  - spec/lib/Locked/commands/authenticate_spec.rb
130
+ - spec/lib/Locked/commands/verify_spec.rb
125
131
  - spec/lib/Locked/commands/identify_spec.rb
126
132
  - spec/lib/Locked/validators/not_supported_spec.rb
127
133
  - spec/lib/Locked/validators/present_spec.rb
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Locked
4
- # generate failover authentication response
5
- class FailoverAuthResponse
6
- def initialize(user_id, strategy: Locked.config.failover_strategy, reason:)
7
- @strategy = strategy
8
- @reason = reason
9
- @user_id = user_id
10
- end
11
-
12
- def generate
13
- {
14
- data: {
15
- action: @strategy.to_s,
16
- user_id: @user_id,
17
- },
18
- failover: true,
19
- failover_reason: @reason
20
- }
21
- end
22
- end
23
- end