locked-rb 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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