lhs 21.2.4 → 21.3.0.pre.autoauth.1

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: 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