lhs 21.2.4 → 21.3.0.pre.autoauth.1

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: d29a70798d8ce33c3fbd253465123d32fe2fd4a97e213a9f3cdce1350e45bd85
4
- data.tar.gz: 50d2cd571874e523de51ed9652d4faec1406087e69940ee87f4941f5d416e9b4
3
+ metadata.gz: a8391f6f7e78b219c2f48ca87b7f160a28feab0f5e113553a41b339d8f3b72df
4
+ data.tar.gz: 30e48a8d78cca4d1ed76595cfd72c90bda2cfd77873590254bdf92685df97df1
5
5
  SHA512:
6
- metadata.gz: a6fcfc2a0507d730e88045b0489d0f463bcff6235fe5a10cafdbd6c3560ae0e561479f3f2ae766ef7495be8c8e6d0efbce2636f468ae98a488d413ece8d6ca75
7
- data.tar.gz: c7c48a2130f9cf32de2fdc657f0ba3b50b71e10b062a297797b383b0c5f2fd9cbdf1a9023237dcf1ca44c9f822ec3dd25ef3180a9915c166850477592c623b48
6
+ metadata.gz: 00f6961b5546311a919830c913153ecfcbbbeec7a67079db66284ec9280caa6656ea023db44945b0387a0cf02b372736e20632318315f0b3d87811ded26f6aa8
7
+ data.tar.gz: 56c2dd947ba8c5b82800997198c7185bc4d331195d3d1040b779431569ece6bed89eb6822d98bf80aa880482e176f6337cf98518ee176c951363644ce01c2d64
data/README.md CHANGED
@@ -2444,6 +2444,66 @@ LHS.configure do |config|
2444
2444
  end
2445
2445
  ```
2446
2446
 
2447
+ ## Automatic Authentication (OAuth)
2448
+
2449
+ LHS provides a way to have records automatically fetch and use OAuth authentication when performing requests within Rails.
2450
+
2451
+ In order to enable automatic oauth authentication, perform the following steps:
2452
+
2453
+ 1. Make sure LHS is configured to perform `auto_oauth`. Provide a block that when executed in the controller context returns a valid access_token/bearer_token.
2454
+ ```ruby
2455
+ # config/initializers/lhs.rb
2456
+
2457
+ LHS.configure do |config|
2458
+ config.auto_oauth = -> { access_token }
2459
+ end
2460
+ ```
2461
+
2462
+ 2. Opt-in records requiring oauth authentication:
2463
+
2464
+ ```ruby
2465
+ # app/models/record.rb
2466
+
2467
+ class Record < LHS::Record
2468
+ oauth
2469
+ # ...
2470
+ end
2471
+ ```
2472
+
2473
+ 3. Include the `LHS::OAuth` context into your application controller:
2474
+
2475
+ ```ruby
2476
+ # app/controllers/application_controller.rb
2477
+
2478
+ class ApplicationController < ActionController::Base
2479
+ include LHS::OAuth
2480
+
2481
+ # ...
2482
+ end
2483
+ ```
2484
+
2485
+ 4. Make sure you have the `LHC::Auth` interceptor enabled:
2486
+
2487
+ ```ruby
2488
+ # config/initializers/lhc.rb
2489
+
2490
+ LHC.configure do |config|
2491
+ config.interceptors = [LHC::Auth]
2492
+ end
2493
+ ```
2494
+
2495
+ Now you can perform requests based on the record that will be auto authenticated from now on:
2496
+
2497
+ ```ruby
2498
+ # app/controllers/some_controller.rb
2499
+
2500
+ Record.find(1)
2501
+ ```
2502
+ ```
2503
+ https://records/1
2504
+ Authentication: 'Bearer token-12345'
2505
+ ```
2506
+
2447
2507
  ## Option Blocks
2448
2508
 
2449
2509
  In order to apply options to all requests performed in a give block, LHS provides option blocks.
data/lib/lhs.rb CHANGED
@@ -22,6 +22,12 @@ module LHS
22
22
  autoload :Inspect,
23
23
  'lhs/concerns/inspect'
24
24
  module Interceptors
25
+ module AutoOauth
26
+ autoload :ThreadRegistry,
27
+ 'lhs/interceptors/auto_oauth/thread_registry'
28
+ autoload :Interceptor,
29
+ 'lhs/interceptors/auto_oauth/interceptor'
30
+ end
25
31
  module RequestCycleCache
26
32
  autoload :ThreadRegistry,
27
33
  'lhs/interceptors/request_cycle_cache/thread_registry'
@@ -41,6 +47,8 @@ module LHS
41
47
  'lhs/concerns/is_href'
42
48
  autoload :Item,
43
49
  'lhs/item'
50
+ autoload :OAuth,
51
+ 'lhs/concerns/o_auth.rb'
44
52
  autoload :OptionBlocks,
45
53
  'lhs/concerns/option_blocks'
46
54
  autoload :Pagination,
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+
5
+ module LHS
6
+ module OAuth
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ prepend_before_action :lhs_store_oauth_access_token
11
+ end
12
+
13
+ private
14
+
15
+ def lhs_store_oauth_access_token
16
+ lhs_check_auto_oauth_enabled!
17
+ LHS::Interceptors::AutoOauth::ThreadRegistry.access_token = instance_exec(&LHS.config.auto_oauth)
18
+ end
19
+
20
+ def lhs_check_auto_oauth_enabled!
21
+ return if LHS.config.auto_oauth.present? && LHS.config.auto_oauth.is_a?(Proc)
22
+ raise 'You have to enable LHS.config.auto_oauth by passing a proc returning an access token!'
23
+ end
24
+ end
25
+ end
@@ -13,7 +13,15 @@ class LHS::Record
13
13
 
14
14
  module ClassMethods
15
15
  def configuration(args)
16
- @configuration = args.freeze || {}
16
+ @configuration = args || {}
17
+ end
18
+
19
+ def auto_oauth?
20
+ LHS.config.auto_oauth && @configuration && @configuration.fetch(:auto_oauth, false)
21
+ end
22
+
23
+ def oauth
24
+ @configuration.present? ? @configuration.merge!(auto_oauth: true) : configuration(auto_oauth: true)
17
25
  end
18
26
 
19
27
  def item_key
@@ -517,20 +517,34 @@ class LHS::Record
517
517
  options[:url] = compute_url!(options[:params]) unless options.key?(:url)
518
518
  merge_explicit_params!(options[:params])
519
519
  options.delete(:params) if options[:params]&.empty?
520
- inject_request_cycle_cache!(options)
520
+ inject_interceptors!(options)
521
521
  options
522
522
  end
523
523
 
524
- # Injects options into request, that enable the request cycle cache interceptor
525
- def inject_request_cycle_cache!(options)
526
- return unless LHS.config.request_cycle_cache_enabled
524
+ def inject_interceptors!(options)
525
+ inject_interceptor!(
526
+ options,
527
+ LHS::Interceptors::RequestCycleCache::Interceptor,
528
+ LHC::Caching,
529
+ "[WARNING] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured (see https://github.com/local-ch/lhc/blob/master/README.md#caching-interceptor)!"
530
+ ) if LHS.config.request_cycle_cache_enabled
531
+
532
+ inject_interceptor!(
533
+ options,
534
+ LHS::Interceptors::AutoOauth::Interceptor,
535
+ LHC::Auth,
536
+ "[WARNING] Can't enable auto oauth as LHC::Auth interceptor is not enabled/configured (see https://github.com/local-ch/lhc/blob/master/README.md#authentication-interceptor)!"
537
+ ) if self.auto_oauth?
538
+ end
539
+
540
+ def inject_interceptor!(options, interceptor, dependecy, warning)
527
541
  interceptors = options[:interceptors] || LHC.config.interceptors
528
- if interceptors.include?(LHC::Caching)
542
+ if interceptors.include?(dependecy)
529
543
  # Ensure interceptor is prepend
530
- interceptors = interceptors.unshift(LHS::Interceptors::RequestCycleCache::Interceptor)
544
+ interceptors = interceptors.unshift(interceptor)
531
545
  options[:interceptors] = interceptors
532
546
  else
533
- warn("[WARNING] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured (see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor)!")
547
+ warn(warning)
534
548
  end
535
549
  end
536
550
 
@@ -5,7 +5,7 @@ require 'singleton'
5
5
  class LHS::Config
6
6
  include Singleton
7
7
 
8
- attr_accessor :request_cycle_cache_enabled, :request_cycle_cache, :trace
8
+ attr_accessor :request_cycle_cache_enabled, :request_cycle_cache, :trace, :auto_oauth
9
9
 
10
10
  def initialize
11
11
  self.request_cycle_cache_enabled ||= true
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+
5
+ module LHS
6
+ module Interceptors
7
+ module AutoOauth
8
+ extend ActiveSupport::Concern
9
+
10
+ class Interceptor < LHC::Interceptor
11
+
12
+ def before_request
13
+ request.options[:auth] = { bearer: LHS::Interceptors::AutoOauth::ThreadRegistry.access_token }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/per_thread_registry'
5
+
6
+ module LHS
7
+ module Interceptors
8
+ module AutoOauth
9
+ extend ActiveSupport::Concern
10
+ class ThreadRegistry
11
+ # Using ActiveSupports PerThreadRegistry to be able to support Active Support v4.
12
+ # Will switch to thread_mattr_accessor (which comes with Activesupport) when we dropping support for Active Support v4.
13
+ extend ActiveSupport::PerThreadRegistry
14
+ attr_accessor :access_token
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHS
4
- VERSION = '21.2.4'
4
+ VERSION = '21.3.0.pre.autoauth.1'
5
5
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe 'Auto OAuth Authentication', type: :request, dummy_models: true do
6
+
7
+ context 'without LHC::Auth interceptor enabled' do
8
+
9
+ it 'shows a warning that it can not perform auto authentication' do
10
+ expect(lambda do
11
+ get '/automatic_authentication/oauth'
12
+ end).to output(
13
+ %r{\[WARNING\] Can't enable auto oauth as LHC::Auth interceptor is not enabled\/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#authentication-interceptor\)!}
14
+ ).to_stderr
15
+ end
16
+ end
17
+
18
+ context 'with LHC::Auth interceptor enabled' do
19
+ let(:record_request) do
20
+ stub_request(:get, "http://datastore/v2/records_with_oauth/1")
21
+ .with(
22
+ headers: { 'Authorization' => "Bearer #{ApplicationController::ACCESS_TOKEN}" }
23
+ ).to_return(status: 200, body: { name: 'Record' }.to_json)
24
+ end
25
+
26
+ let(:records_request) do
27
+ stub_request(:get, "http://datastore/v2/records_with_oauth?color=blue")
28
+ .with(
29
+ headers: { 'Authorization' => "Bearer #{ApplicationController::ACCESS_TOKEN}" }
30
+ ).to_return(status: 200, body: { items: [ { name: 'Record' } ] }.to_json)
31
+ end
32
+
33
+ before do
34
+ LHC.configure do |config|
35
+ config.interceptors = [LHC::Auth]
36
+ end
37
+ record_request
38
+ records_request
39
+ end
40
+
41
+ after do
42
+ LHC.config.reset
43
+ end
44
+
45
+ it 'applies OAuth credentials for the individual request automatically' do
46
+ get '/automatic_authentication/oauth'
47
+ expect(record_request).to have_been_requested
48
+ expect(records_request).to have_been_requested
49
+ end
50
+ end
51
+ end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ApplicationController < ActionController::Base
4
+ include LHS::OAuth
5
+ ACCESS_TOKEN = 'token-12345'.freeze
6
+
4
7
  # Prevent CSRF attacks by raising an exception.
5
8
  # For APIs, you may want to use :null_session instead.
6
9
  protect_from_forgery with: :exception
@@ -8,4 +11,8 @@ class ApplicationController < ActionController::Base
8
11
  def root
9
12
  render nothing: true
10
13
  end
14
+
15
+ def access_token
16
+ ACCESS_TOKEN
17
+ end
11
18
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AutomaticAuthenticationController < ApplicationController
4
+
5
+ def o_auth
6
+ render json: {
7
+ record: DummyRecordWithOauth.find(1).as_json,
8
+ records: DummyRecordWithOauth.where(color: 'blue').as_json
9
+ }
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DummyRecordWithOauth < LHS::Record
4
+ oauth
5
+ endpoint 'http://datastore/v2/records_with_oauth'
6
+ endpoint 'http://datastore/v2/records_with_oauth/{id}'
7
+ end
@@ -0,0 +1,3 @@
1
+ LHS.configure do |config|
2
+ config.auto_oauth = -> { access_token }
3
+ end
@@ -3,6 +3,9 @@
3
3
  Rails.application.routes.draw do
4
4
  root 'application#root'
5
5
 
6
+ # Automatic Authentication
7
+ get 'automatic_authentication/oauth' => 'automatic_authentication#o_auth'
8
+
6
9
  # Request Cycle Cache
7
10
  get 'request_cycle_cache/simple' => 'request_cycle_cache#simple'
8
11
  get 'request_cycle_cache/no_caching_interceptor' => 'request_cycle_cache#no_caching_interceptor'
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails_helper'
4
- require 'lhc/test/cache_helper.rb'
4
+ require 'lhc/rspec'
5
5
 
6
6
  describe 'Error handling with chains', type: :request do
7
7
  let!(:request) do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails_helper'
4
- require 'lhc/test/cache_helper.rb'
4
+ require 'lhc/rspec'
5
5
 
6
6
  describe 'Request Cycle Cache', type: :request do
7
7
  let!(:request) do
@@ -37,7 +37,7 @@ describe 'Request Cycle Cache', type: :request do
37
37
  expect(lambda do
38
38
  get '/request_cycle_cache/no_caching_interceptor'
39
39
  end).to output(
40
- %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
40
+ %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#caching-interceptor\)!}
41
41
  ).to_stderr
42
42
  expect(request).to have_been_made.times(2)
43
43
  end
@@ -70,7 +70,7 @@ describe 'Request Cycle Cache', type: :request do
70
70
  expect(lambda do
71
71
  get '/request_cycle_cache/no_caching_interceptor'
72
72
  end).not_to output(
73
- %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/docs/interceptors/caching.md#caching-interceptor\)!}
73
+ %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#caching-interceptor\)!}
74
74
  ).to_stderr
75
75
  expect(request).to have_been_made.times(2)
76
76
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhs
3
3
  version: !ruby/object:Gem::Version
4
- version: 21.2.4
4
+ version: 21.3.0.pre.autoauth.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhs/graphs/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-20 00:00:00.000000000 Z
11
+ date: 2020-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -283,6 +283,7 @@ files:
283
283
  - lib/lhs/concerns/item/save.rb
284
284
  - lib/lhs/concerns/item/update.rb
285
285
  - lib/lhs/concerns/item/validation.rb
286
+ - lib/lhs/concerns/o_auth.rb
286
287
  - lib/lhs/concerns/option_blocks.rb
287
288
  - lib/lhs/concerns/proxy/accessors.rb
288
289
  - lib/lhs/concerns/proxy/create.rb
@@ -314,6 +315,8 @@ files:
314
315
  - lib/lhs/config.rb
315
316
  - lib/lhs/data.rb
316
317
  - lib/lhs/endpoint.rb
318
+ - lib/lhs/interceptors/auto_oauth/interceptor.rb
319
+ - lib/lhs/interceptors/auto_oauth/thread_registry.rb
317
320
  - lib/lhs/interceptors/extended_rollbar/handler.rb
318
321
  - lib/lhs/interceptors/extended_rollbar/interceptor.rb
319
322
  - lib/lhs/interceptors/extended_rollbar/thread_registry.rb
@@ -340,6 +343,7 @@ files:
340
343
  - lib/lhs/version.rb
341
344
  - script/ci/build.sh
342
345
  - spec/.DS_Store
346
+ - spec/auto_oauth_spec.rb
343
347
  - spec/autoloading_spec.rb
344
348
  - spec/collection/accessors_spec.rb
345
349
  - spec/collection/collection_items_spec.rb
@@ -372,6 +376,7 @@ files:
372
376
  - spec/dummy/app/assets/javascripts/application.js
373
377
  - spec/dummy/app/assets/stylesheets/application.css
374
378
  - spec/dummy/app/controllers/application_controller.rb
379
+ - spec/dummy/app/controllers/automatic_authentication_controller.rb
375
380
  - spec/dummy/app/controllers/concerns/.keep
376
381
  - spec/dummy/app/controllers/error_handling_with_chains_controller.rb
377
382
  - spec/dummy/app/controllers/extended_rollbar_controller.rb
@@ -383,6 +388,7 @@ files:
383
388
  - spec/dummy/app/models/concerns/.keep
384
389
  - spec/dummy/app/models/dummy_customer.rb
385
390
  - spec/dummy/app/models/dummy_record.rb
391
+ - spec/dummy/app/models/dummy_record_with_oauth.rb
386
392
  - spec/dummy/app/models/dummy_user.rb
387
393
  - spec/dummy/app/models/providers/customer_system.rb
388
394
  - spec/dummy/app/views/error_handling_with_chains/error.html.erb
@@ -404,6 +410,7 @@ files:
404
410
  - spec/dummy/config/initializers/cookies_serializer.rb
405
411
  - spec/dummy/config/initializers/filter_parameter_logging.rb
406
412
  - spec/dummy/config/initializers/inflections.rb
413
+ - spec/dummy/config/initializers/lhs.rb
407
414
  - spec/dummy/config/initializers/mime_types.rb
408
415
  - spec/dummy/config/initializers/rollbar.rb
409
416
  - spec/dummy/config/initializers/session_store.rb
@@ -548,9 +555,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
548
555
  version: 2.3.0
549
556
  required_rubygems_version: !ruby/object:Gem::Requirement
550
557
  requirements:
551
- - - ">="
558
+ - - ">"
552
559
  - !ruby/object:Gem::Version
553
- version: '0'
560
+ version: 1.3.1
554
561
  requirements:
555
562
  - Ruby >= 2.3.0
556
563
  rubygems_version: 3.0.6
@@ -559,6 +566,7 @@ specification_version: 4
559
566
  summary: 'REST services accelerator: Rails gem providing an easy, active-record-like
560
567
  interface for http (hypermedia) json services'
561
568
  test_files:
569
+ - spec/auto_oauth_spec.rb
562
570
  - spec/autoloading_spec.rb
563
571
  - spec/collection/accessors_spec.rb
564
572
  - spec/collection/collection_items_spec.rb
@@ -591,6 +599,7 @@ test_files:
591
599
  - spec/dummy/app/assets/javascripts/application.js
592
600
  - spec/dummy/app/assets/stylesheets/application.css
593
601
  - spec/dummy/app/controllers/application_controller.rb
602
+ - spec/dummy/app/controllers/automatic_authentication_controller.rb
594
603
  - spec/dummy/app/controllers/concerns/.keep
595
604
  - spec/dummy/app/controllers/error_handling_with_chains_controller.rb
596
605
  - spec/dummy/app/controllers/extended_rollbar_controller.rb
@@ -602,6 +611,7 @@ test_files:
602
611
  - spec/dummy/app/models/concerns/.keep
603
612
  - spec/dummy/app/models/dummy_customer.rb
604
613
  - spec/dummy/app/models/dummy_record.rb
614
+ - spec/dummy/app/models/dummy_record_with_oauth.rb
605
615
  - spec/dummy/app/models/dummy_user.rb
606
616
  - spec/dummy/app/models/providers/customer_system.rb
607
617
  - spec/dummy/app/views/error_handling_with_chains/error.html.erb
@@ -623,6 +633,7 @@ test_files:
623
633
  - spec/dummy/config/initializers/cookies_serializer.rb
624
634
  - spec/dummy/config/initializers/filter_parameter_logging.rb
625
635
  - spec/dummy/config/initializers/inflections.rb
636
+ - spec/dummy/config/initializers/lhs.rb
626
637
  - spec/dummy/config/initializers/mime_types.rb
627
638
  - spec/dummy/config/initializers/rollbar.rb
628
639
  - spec/dummy/config/initializers/session_store.rb