lhs 21.3.0.pre.autoauth.1 → 21.3.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.
- checksums.yaml +4 -4
- data/README.md +149 -108
- data/lhs.gemspec +1 -1
- data/lib/lhs/concerns/record/configuration.rb +23 -14
- data/lib/lhs/concerns/record/request.rb +18 -13
- data/lib/lhs/interceptors/auto_oauth/interceptor.rb +16 -1
- data/lib/lhs/version.rb +1 -1
- data/spec/auto_oauth_spec.rb +102 -24
- data/spec/dummy/app/controllers/application_controller.rb +9 -1
- data/spec/dummy/app/controllers/automatic_authentication_controller.rb +11 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb +7 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb +7 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb +6 -0
- data/spec/dummy/config/routes.rb +1 -0
- metadata +13 -9
- data/spec/dummy/config/initializers/lhs.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cadb661567a1a911f12d612030d14ca963216bc6cca0874525b50ec9afe6d2c1
|
4
|
+
data.tar.gz: f110c85be3c7ff12f00797f1268f14ba9376c235e1d8dbe9665fb51515f7c0b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed5dc79199bd8563b951f0131dbb4965e7133898f703104f054cbffe52953ed2c6d9526d046d2077d7b1420ba15e6a3c1ef6ac8168a8087c62d9cc50e227a8cc
|
7
|
+
data.tar.gz: 2cf77b9a2955eac7cf408f3f35174863b6b773133149b77e0aea47a74808d5d43ab43d99e00cd7bdab4a1c41e8c59c831d31dfae64f8f5d3723f65102288aa06
|
data/README.md
CHANGED
@@ -39,113 +39,116 @@ record.review # "Lunch was great
|
|
39
39
|
|
40
40
|
## Table of contents
|
41
41
|
* [LHS](#lhs)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
42
|
+
* [Quickstart](#quickstart)
|
43
|
+
* [Installation/Startup checklist](#installationstartup-checklist)
|
44
|
+
* [Record](#record)
|
45
|
+
* [Endpoints](#endpoints)
|
46
|
+
* [Configure endpoint hosts](#configure-endpoint-hosts)
|
47
|
+
* [Endpoint Priorities](#endpoint-priorities)
|
48
|
+
* [Provider](#provider)
|
49
|
+
* [Record inheritance](#record-inheritance)
|
50
|
+
* [Find multiple records](#find-multiple-records)
|
51
|
+
* [fetch](#fetch)
|
52
|
+
* [where](#where)
|
53
|
+
* [Reuse/Dry where statements: Use scopes](#reusedry-where-statements-use-scopes)
|
54
|
+
* [all](#all)
|
55
|
+
* [all with unpaginated endpoints](#all-with-unpaginated-endpoints)
|
56
|
+
* [Retrieve the amount of a collection of items: count vs. length](#retrieve-the-amount-of-a-collection-of-items-count-vs-length)
|
57
|
+
* [Find single records](#find-single-records)
|
58
|
+
* [find](#find)
|
59
|
+
* [find_by](#find_by)
|
60
|
+
* [first](#first)
|
61
|
+
* [last](#last)
|
62
|
+
* [Work with retrieved data](#work-with-retrieved-data)
|
63
|
+
* [Automatic detection/conversion of collections](#automatic-detectionconversion-of-collections)
|
64
|
+
* [Map complex data for easy access](#map-complex-data-for-easy-access)
|
65
|
+
* [Access and identify nested records](#access-and-identify-nested-records)
|
66
|
+
* [Relations / Associations](#relations--associations)
|
67
|
+
* [has_many](#has_many)
|
68
|
+
* [has_one](#has_one)
|
69
|
+
* [Unwrap nested items from the response body](#unwrap-nested-items-from-the-response-body)
|
70
|
+
* [Determine collections from the response body](#determine-collections-from-the-response-body)
|
71
|
+
* [Load additional data based on retrieved data](#load-additional-data-based-on-retrieved-data)
|
72
|
+
* [Chain complex queries](#chain-complex-queries)
|
73
|
+
* [Chain where queries](#chain-where-queries)
|
74
|
+
* [Expand plain collections of links: expanded](#expand-plain-collections-of-links-expanded)
|
75
|
+
* [Error handling with chains](#error-handling-with-chains)
|
76
|
+
* [Resolve chains: fetch](#resolve-chains-fetch)
|
77
|
+
* [Add request options to a query chain: options](#add-request-options-to-a-query-chain-options)
|
78
|
+
* [Control pagination within a query chain](#control-pagination-within-a-query-chain)
|
79
|
+
* [Record pagination](#record-pagination)
|
80
|
+
* [Pagination strategy](#pagination-strategy)
|
81
|
+
* [Pagination strategy: offset (default)](#pagination-strategy-offset-default)
|
82
|
+
* [Pagination strategy: page](#pagination-strategy-page)
|
83
|
+
* [Pagination strategy: start](#pagination-strategy-start)
|
84
|
+
* [Pagination strategy: link](#pagination-strategy-link)
|
85
|
+
* [Pagination keys](#pagination-keys)
|
86
|
+
* [limit_key](#limit_key)
|
87
|
+
* [pagination_key](#pagination_key)
|
88
|
+
* [total_key](#total_key)
|
89
|
+
* [Pagination links](#pagination-links)
|
90
|
+
* [next?](#next)
|
91
|
+
* [previous?](#previous)
|
92
|
+
* [Kaminari support (limited)](#kaminari-support-limited)
|
93
|
+
* [Build, create and update records](#build-create-and-update-records)
|
94
|
+
* [Create new records](#create-new-records)
|
95
|
+
* [create](#create)
|
96
|
+
* [Unwrap nested data when creation response nests created record data](#unwrap-nested-data-when-creation-response-nests-created-record-data)
|
97
|
+
* [Create records through associations: Nested sub resources](#create-records-through-associations-nested-sub-resources)
|
98
|
+
* [Start building new records](#start-building-new-records)
|
99
|
+
* [Change/Update existing records](#changeupdate-existing-records)
|
100
|
+
* [save](#save)
|
101
|
+
* [update](#update)
|
102
|
+
* [partial_update](#partial_update)
|
103
|
+
* [Endpoint url parameter injection during record creation/change](#endpoint-url-parameter-injection-during-record-creationchange)
|
104
|
+
* [Record validation](#record-validation)
|
105
|
+
* [Configure record validations](#configure-record-validations)
|
106
|
+
* [HTTP Status Codes for validation errors](#http-status-codes-for-validation-errors)
|
107
|
+
* [Reset validation errors](#reset-validation-errors)
|
108
|
+
* [Add validation errors](#add-validation-errors)
|
109
|
+
* [Validation errors for nested data](#validation-errors-for-nested-data)
|
110
|
+
* [Translation of validation errors](#translation-of-validation-errors)
|
111
|
+
* [Validation error types: errors vs. warnings](#validation-error-types-errors-vs-warnings)
|
112
|
+
* [Persistance failed: errors](#persistance-failed-errors)
|
113
|
+
* [Persistance succeeded: warnings](#persistance-succeeded-warnings)
|
114
|
+
* [Using ActiveModel::Validations none the less](#using-activemodelvalidations-none-the-less)
|
115
|
+
* [Use form_helper to create and update records](#use-form_helper-to-create-and-update-records)
|
116
|
+
* [Destroy records](#destroy-records)
|
117
|
+
* [Record getters and setters](#record-getters-and-setters)
|
118
|
+
* [Record setters](#record-setters)
|
119
|
+
* [Record getters](#record-getters)
|
120
|
+
* [Include linked resources (hyperlinks and hypermedia)](#include-linked-resources-hyperlinks-and-hypermedia)
|
121
|
+
* [Generate links from parameters](#generate-links-from-parameters)
|
122
|
+
* [Ensure the whole linked collection is included: includes_all](#ensure-the-whole-linked-collection-is-included-includes_all)
|
123
|
+
* [Include the first linked page or single item is included: include](#include-the-first-linked-page-or-single-item-is-included-include)
|
124
|
+
* [Include various levels of linked data](#include-various-levels-of-linked-data)
|
125
|
+
* [Identify and cast known records when including records](#identify-and-cast-known-records-when-including-records)
|
126
|
+
* [Apply options for requests performed to fetch included records](#apply-options-for-requests-performed-to-fetch-included-records)
|
127
|
+
* [Record batch processing](#record-batch-processing)
|
128
|
+
* [all](#all-1)
|
129
|
+
* [Using all, when endpoint does not implement response pagination meta data](#using-all-when-endpoint-does-not-implement-response-pagination-meta-data)
|
130
|
+
* [find_each](#find_each)
|
131
|
+
* [find_in_batches](#find_in_batches)
|
132
|
+
* [Convert/Cast specific record types: becomes](#convertcast-specific-record-types-becomes)
|
133
|
+
* [Assign attributes](#assign-attributes)
|
134
|
+
* [Request Cycle Cache](#request-cycle-cache)
|
135
|
+
* [Change store for LHS' request cycle cache](#change-store-for-lhs-request-cycle-cache)
|
136
|
+
* [Disable request cycle cache](#disable-request-cycle-cache)
|
137
|
+
* [Automatic Authentication (OAuth)](#automatic-authentication-oauth)
|
138
|
+
* [Configure multiple auth providers (even per endpoint)](#configure-multiple-auth-providers-even-per-endpoint)
|
139
|
+
* [Option Blocks](#option-blocks)
|
140
|
+
* [Request tracing](#request-tracing)
|
141
|
+
* [Extended Rollbar Logging](#extended-rollbar-logging)
|
142
|
+
* [Testing with LHS](#testing-with-lhs)
|
143
|
+
* [Test helper](#test-helper)
|
144
|
+
* [Stub](#stub)
|
145
|
+
* [stub_all](#stub_all)
|
146
|
+
* [Test query chains](#test-query-chains)
|
147
|
+
* [By explicitly resolving the chain: fetch](#by-explicitly-resolving-the-chain-fetch)
|
148
|
+
* [Without resolving the chain: where_values_hash](#without-resolving-the-chain-where_values_hash)
|
149
|
+
* [License](#license)
|
150
|
+
|
151
|
+
|
149
152
|
|
150
153
|
## Installation/Startup checklist
|
151
154
|
|
@@ -2450,7 +2453,7 @@ LHS provides a way to have records automatically fetch and use OAuth authenticat
|
|
2450
2453
|
|
2451
2454
|
In order to enable automatic oauth authentication, perform the following steps:
|
2452
2455
|
|
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.
|
2456
|
+
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
2457
|
```ruby
|
2455
2458
|
# config/initializers/lhs.rb
|
2456
2459
|
|
@@ -2504,6 +2507,44 @@ https://records/1
|
|
2504
2507
|
Authentication: 'Bearer token-12345'
|
2505
2508
|
```
|
2506
2509
|
|
2510
|
+
### Configure multiple auth providers (even per endpoint)
|
2511
|
+
|
2512
|
+
In case you need to configure multiple auth provider access_tokens within your application,
|
2513
|
+
make sure you provide a proc returning a hash when configuring `auto_oauth`,
|
2514
|
+
naming every single provider and the responsive method to retrieve the access_tokens in the controller context:
|
2515
|
+
|
2516
|
+
```ruby
|
2517
|
+
# config/initializers/lhs.rb
|
2518
|
+
LHS.configure do |config|
|
2519
|
+
config.auto_oauth = proc do
|
2520
|
+
{
|
2521
|
+
provider1: access_token_provider_1,
|
2522
|
+
provider2: access_token_provider_2
|
2523
|
+
}
|
2524
|
+
end
|
2525
|
+
end
|
2526
|
+
```
|
2527
|
+
|
2528
|
+
Then make sure you either define which provider to use on a record level:
|
2529
|
+
|
2530
|
+
```ruby
|
2531
|
+
# model/record.rb
|
2532
|
+
class Record < LHS::Record
|
2533
|
+
oauth(:provider1)
|
2534
|
+
#...
|
2535
|
+
end
|
2536
|
+
```
|
2537
|
+
|
2538
|
+
or on an endpoint level:
|
2539
|
+
|
2540
|
+
```ruby
|
2541
|
+
# model/record.rb
|
2542
|
+
class Record < LHS::Record
|
2543
|
+
endpoint 'https://service/records', oauth: :provider1
|
2544
|
+
#...
|
2545
|
+
end
|
2546
|
+
```
|
2547
|
+
|
2507
2548
|
## Option Blocks
|
2508
2549
|
|
2509
2550
|
In order to apply options to all requests performed in a give block, LHS provides option blocks.
|
data/lhs.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
|
|
32
32
|
s.add_development_dependency 'pry'
|
33
33
|
s.add_development_dependency 'pry-byebug'
|
34
34
|
s.add_development_dependency 'rails', '>= 4.2.11'
|
35
|
-
s.add_development_dependency 'rollbar'
|
35
|
+
s.add_development_dependency 'rollbar', '<= 2.24.0'
|
36
36
|
s.add_development_dependency 'rspec-rails', '>= 3.7.0'
|
37
37
|
s.add_development_dependency 'rubocop', '~> 0.57.1'
|
38
38
|
s.add_development_dependency 'rubocop-rspec', '~> 1.26.0'
|
@@ -12,53 +12,62 @@ class LHS::Record
|
|
12
12
|
mattr_accessor :configuration
|
13
13
|
|
14
14
|
module ClassMethods
|
15
|
-
def configuration(args)
|
16
|
-
|
15
|
+
def configuration(args = nil)
|
16
|
+
if !args.nil?
|
17
|
+
@configuration = args
|
18
|
+
else
|
19
|
+
@configuration || {}
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
def auto_oauth?
|
20
|
-
LHS.config.auto_oauth &&
|
24
|
+
LHS.config.auto_oauth && configuration && auto_oauth
|
21
25
|
end
|
22
26
|
|
23
|
-
def
|
24
|
-
|
27
|
+
def auto_oauth
|
28
|
+
configuration.fetch(:auto_oauth, false)
|
29
|
+
end
|
30
|
+
|
31
|
+
def oauth(provider = nil)
|
32
|
+
value = provider || true
|
33
|
+
configuration.present? ? configuration.merge!(auto_oauth: value) : configuration(auto_oauth: value)
|
25
34
|
end
|
26
35
|
|
27
36
|
def item_key
|
28
37
|
symbolize_unless_complex(
|
29
|
-
|
38
|
+
configuration.dig(:item_key) || :item
|
30
39
|
)
|
31
40
|
end
|
32
41
|
|
33
42
|
def items_key
|
34
43
|
symbolize_unless_complex(
|
35
|
-
|
44
|
+
configuration.dig(:items_key) || :items
|
36
45
|
)
|
37
46
|
end
|
38
47
|
|
39
48
|
def item_created_key
|
40
49
|
symbolize_unless_complex(
|
41
|
-
|
50
|
+
configuration.dig(:item_created_key)
|
42
51
|
)
|
43
52
|
end
|
44
53
|
|
45
54
|
def limit_key(type = nil)
|
46
55
|
symbolize_unless_complex(
|
47
|
-
pagination_parameter(
|
56
|
+
pagination_parameter(configuration.dig(:limit_key), type) ||
|
48
57
|
:limit
|
49
58
|
)
|
50
59
|
end
|
51
60
|
|
52
61
|
def total_key
|
53
62
|
symbolize_unless_complex(
|
54
|
-
|
63
|
+
configuration.dig(:total_key) || :total
|
55
64
|
)
|
56
65
|
end
|
57
66
|
|
58
67
|
# Key used for determine current page
|
59
68
|
def pagination_key(type = nil)
|
60
69
|
symbolize_unless_complex(
|
61
|
-
pagination_parameter(
|
70
|
+
pagination_parameter(configuration.dig(:pagination_key), type) ||
|
62
71
|
:offset
|
63
72
|
)
|
64
73
|
end
|
@@ -66,15 +75,15 @@ class LHS::Record
|
|
66
75
|
# Strategy used for calculationg next pages and navigate pages
|
67
76
|
def pagination_strategy
|
68
77
|
symbolize_unless_complex(
|
69
|
-
|
78
|
+
configuration.dig(:pagination_strategy) || :offset
|
70
79
|
)
|
71
80
|
end
|
72
81
|
|
73
82
|
# Allows record to be configured as not paginated,
|
74
83
|
# as by default it's considered paginated
|
75
84
|
def paginated
|
76
|
-
return true if
|
77
|
-
|
85
|
+
return true if configuration.blank?
|
86
|
+
configuration.fetch(:paginated, true)
|
78
87
|
end
|
79
88
|
|
80
89
|
private
|
@@ -522,19 +522,24 @@ class LHS::Record
|
|
522
522
|
end
|
523
523
|
|
524
524
|
def inject_interceptors!(options)
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
525
|
+
if LHS.config.request_cycle_cache_enabled
|
526
|
+
inject_interceptor!(
|
527
|
+
options,
|
528
|
+
LHS::Interceptors::RequestCycleCache::Interceptor,
|
529
|
+
LHC::Caching,
|
530
|
+
"[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)!"
|
531
|
+
)
|
532
|
+
end
|
533
|
+
|
534
|
+
endpoint = find_endpoint(options[:params], options.fetch(:url, nil))
|
535
|
+
if auto_oauth? || (endpoint.options&.dig(:oauth) && LHS.config.auto_oauth)
|
536
|
+
inject_interceptor!(
|
537
|
+
options.merge!(record: self),
|
538
|
+
LHS::Interceptors::AutoOauth::Interceptor,
|
539
|
+
LHC::Auth,
|
540
|
+
"[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)!"
|
541
|
+
)
|
542
|
+
end
|
538
543
|
end
|
539
544
|
|
540
545
|
def inject_interceptor!(options, interceptor, dependecy, warning)
|
@@ -10,7 +10,22 @@ module LHS
|
|
10
10
|
class Interceptor < LHC::Interceptor
|
11
11
|
|
12
12
|
def before_request
|
13
|
-
request.options[:auth] = { bearer:
|
13
|
+
request.options[:auth] = { bearer: token }
|
14
|
+
end
|
15
|
+
|
16
|
+
def tokens
|
17
|
+
@tokens ||= LHS::Interceptors::AutoOauth::ThreadRegistry.access_token
|
18
|
+
end
|
19
|
+
|
20
|
+
def token
|
21
|
+
if tokens.is_a?(Hash)
|
22
|
+
tokens.dig(
|
23
|
+
request.options[:oauth] ||
|
24
|
+
request.options[:record]&.auto_oauth
|
25
|
+
)
|
26
|
+
else
|
27
|
+
tokens
|
28
|
+
end
|
14
29
|
end
|
15
30
|
end
|
16
31
|
end
|
data/lib/lhs/version.rb
CHANGED
data/spec/auto_oauth_spec.rb
CHANGED
@@ -6,6 +6,12 @@ describe 'Auto OAuth Authentication', type: :request, dummy_models: true do
|
|
6
6
|
|
7
7
|
context 'without LHC::Auth interceptor enabled' do
|
8
8
|
|
9
|
+
before do
|
10
|
+
LHS.configure do |config|
|
11
|
+
config.auto_oauth = -> { access_token }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
9
15
|
it 'shows a warning that it can not perform auto authentication' do
|
10
16
|
expect(lambda do
|
11
17
|
get '/automatic_authentication/oauth'
|
@@ -16,36 +22,108 @@ describe 'Auto OAuth Authentication', type: :request, dummy_models: true do
|
|
16
22
|
end
|
17
23
|
|
18
24
|
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
25
|
|
26
|
-
|
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
|
26
|
+
context 'with only one auth provider' do
|
32
27
|
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
let(:token) { ApplicationController::ACCESS_TOKEN }
|
29
|
+
|
30
|
+
let(:record_request) do
|
31
|
+
stub_request(:get, "http://datastore/v2/records_with_oauth/1")
|
32
|
+
.with(
|
33
|
+
headers: { 'Authorization' => "Bearer #{token}" }
|
34
|
+
).to_return(status: 200, body: { name: 'Record' }.to_json)
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:records_request) do
|
38
|
+
stub_request(:get, "http://datastore/v2/records_with_oauth?color=blue")
|
39
|
+
.with(
|
40
|
+
headers: { 'Authorization' => "Bearer #{token}" }
|
41
|
+
).to_return(status: 200, body: { items: [{ name: 'Record' }] }.to_json)
|
42
|
+
end
|
43
|
+
|
44
|
+
before do
|
45
|
+
LHS.configure do |config|
|
46
|
+
config.auto_oauth = -> { access_token }
|
47
|
+
end
|
48
|
+
LHC.configure do |config|
|
49
|
+
config.interceptors = [LHC::Auth]
|
50
|
+
end
|
51
|
+
record_request
|
52
|
+
records_request
|
53
|
+
end
|
54
|
+
|
55
|
+
after do
|
56
|
+
LHC.config.reset
|
36
57
|
end
|
37
|
-
record_request
|
38
|
-
records_request
|
39
|
-
end
|
40
58
|
|
41
|
-
|
42
|
-
|
59
|
+
it 'applies OAuth credentials for the individual request automatically' do
|
60
|
+
get '/automatic_authentication/oauth'
|
61
|
+
expect(record_request).to have_been_requested
|
62
|
+
expect(records_request).to have_been_requested
|
63
|
+
end
|
43
64
|
end
|
44
65
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
66
|
+
context 'with multiple auth providers' do
|
67
|
+
|
68
|
+
before do
|
69
|
+
LHS.configure do |config|
|
70
|
+
config.auto_oauth = proc do
|
71
|
+
{
|
72
|
+
provider1: access_token_provider_1,
|
73
|
+
provider2: access_token_provider_2
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
LHC.configure do |config|
|
78
|
+
config.interceptors = [LHC::Auth]
|
79
|
+
end
|
80
|
+
record_request_provider_1
|
81
|
+
records_request_provider_2
|
82
|
+
records_request_per_endpoint_provider_1
|
83
|
+
record_request_per_endpoint_provider_2
|
84
|
+
end
|
85
|
+
|
86
|
+
let(:token) { ApplicationController::ACCESS_TOKEN }
|
87
|
+
|
88
|
+
let(:record_request_provider_1) do
|
89
|
+
stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_1/1")
|
90
|
+
.with(
|
91
|
+
headers: { 'Authorization' => "Bearer #{token}_provider_1" }
|
92
|
+
).to_return(status: 200, body: { name: 'Record' }.to_json)
|
93
|
+
end
|
94
|
+
|
95
|
+
let(:records_request_provider_2) do
|
96
|
+
stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_2?color=blue")
|
97
|
+
.with(
|
98
|
+
headers: { 'Authorization' => "Bearer #{token}_provider_2" }
|
99
|
+
).to_return(status: 200, body: { items: [{ name: 'Record' }] }.to_json)
|
100
|
+
end
|
101
|
+
|
102
|
+
let(:records_request_per_endpoint_provider_1) do
|
103
|
+
stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_per_endpoint?color=blue")
|
104
|
+
.with(
|
105
|
+
headers: { 'Authorization' => "Bearer #{token}_provider_1" }
|
106
|
+
).to_return(status: 200, body: { items: [{ name: 'Record' }] }.to_json)
|
107
|
+
end
|
108
|
+
|
109
|
+
let(:record_request_per_endpoint_provider_2) do
|
110
|
+
stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_per_endpoint/1")
|
111
|
+
.with(
|
112
|
+
headers: { 'Authorization' => "Bearer #{token}_provider_2" }
|
113
|
+
).to_return(status: 200, body: { name: 'Record' }.to_json)
|
114
|
+
end
|
115
|
+
|
116
|
+
after do
|
117
|
+
LHC.config.reset
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'applies OAuth credentials for the individual request automatically no matter how many auth providers are configured ' do
|
121
|
+
get '/automatic_authentication/oauth_with_multiple_providers'
|
122
|
+
expect(record_request_provider_1).to have_been_requested
|
123
|
+
expect(records_request_provider_2).to have_been_requested
|
124
|
+
expect(records_request_per_endpoint_provider_1).to have_been_requested
|
125
|
+
expect(record_request_per_endpoint_provider_2).to have_been_requested
|
126
|
+
end
|
49
127
|
end
|
50
128
|
end
|
51
129
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class ApplicationController < ActionController::Base
|
4
4
|
include LHS::OAuth
|
5
|
-
ACCESS_TOKEN = 'token-12345'
|
5
|
+
ACCESS_TOKEN = 'token-12345'
|
6
6
|
|
7
7
|
# Prevent CSRF attacks by raising an exception.
|
8
8
|
# For APIs, you may want to use :null_session instead.
|
@@ -15,4 +15,12 @@ class ApplicationController < ActionController::Base
|
|
15
15
|
def access_token
|
16
16
|
ACCESS_TOKEN
|
17
17
|
end
|
18
|
+
|
19
|
+
def access_token_provider_1
|
20
|
+
"#{ACCESS_TOKEN}_provider_1"
|
21
|
+
end
|
22
|
+
|
23
|
+
def access_token_provider_2
|
24
|
+
"#{ACCESS_TOKEN}_provider_2"
|
25
|
+
end
|
18
26
|
end
|
@@ -8,4 +8,15 @@ class AutomaticAuthenticationController < ApplicationController
|
|
8
8
|
records: DummyRecordWithOauth.where(color: 'blue').as_json
|
9
9
|
}
|
10
10
|
end
|
11
|
+
|
12
|
+
def o_auth_with_multiple_providers
|
13
|
+
render json: {
|
14
|
+
record: DummyRecordWithMultipleOauthProviders1.find(1).as_json,
|
15
|
+
records: DummyRecordWithMultipleOauthProviders2.where(color: 'blue').as_json,
|
16
|
+
per_endpoint: {
|
17
|
+
record: DummyRecordWithMultipleOauthProvidersPerEndpoint.find(1).as_json,
|
18
|
+
records: DummyRecordWithMultipleOauthProvidersPerEndpoint.where(color: 'blue').as_json
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
11
22
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DummyRecordWithMultipleOauthProviders1 < LHS::Record
|
4
|
+
oauth(:provider1)
|
5
|
+
endpoint 'http://datastore/v2/records_with_multiple_oauth_providers_1'
|
6
|
+
endpoint 'http://datastore/v2/records_with_multiple_oauth_providers_1/{id}'
|
7
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DummyRecordWithMultipleOauthProviders2 < LHS::Record
|
4
|
+
oauth(:provider2)
|
5
|
+
endpoint 'http://datastore/v2/records_with_multiple_oauth_providers_2'
|
6
|
+
endpoint 'http://datastore/v2/records_with_multiple_oauth_providers_2/{id}'
|
7
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DummyRecordWithMultipleOauthProvidersPerEndpoint < LHS::Record
|
4
|
+
endpoint 'http://datastore/v2/records_with_multiple_oauth_providers_per_endpoint', oauth: :provider1
|
5
|
+
endpoint 'http://datastore/v2/records_with_multiple_oauth_providers_per_endpoint/{id}', oauth: :provider2
|
6
|
+
end
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -5,6 +5,7 @@ Rails.application.routes.draw do
|
|
5
5
|
|
6
6
|
# Automatic Authentication
|
7
7
|
get 'automatic_authentication/oauth' => 'automatic_authentication#o_auth'
|
8
|
+
get 'automatic_authentication/oauth_with_multiple_providers' => 'automatic_authentication#o_auth_with_multiple_providers'
|
8
9
|
|
9
10
|
# Request Cycle Cache
|
10
11
|
get 'request_cycle_cache/simple' => 'request_cycle_cache#simple'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 21.3.0
|
4
|
+
version: 21.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhs/graphs/contributors
|
@@ -146,16 +146,16 @@ dependencies:
|
|
146
146
|
name: rollbar
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
148
148
|
requirements:
|
149
|
-
- - "
|
149
|
+
- - "<="
|
150
150
|
- !ruby/object:Gem::Version
|
151
|
-
version:
|
151
|
+
version: 2.24.0
|
152
152
|
type: :development
|
153
153
|
prerelease: false
|
154
154
|
version_requirements: !ruby/object:Gem::Requirement
|
155
155
|
requirements:
|
156
|
-
- - "
|
156
|
+
- - "<="
|
157
157
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
158
|
+
version: 2.24.0
|
159
159
|
- !ruby/object:Gem::Dependency
|
160
160
|
name: rspec-rails
|
161
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -388,6 +388,9 @@ files:
|
|
388
388
|
- spec/dummy/app/models/concerns/.keep
|
389
389
|
- spec/dummy/app/models/dummy_customer.rb
|
390
390
|
- spec/dummy/app/models/dummy_record.rb
|
391
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb
|
392
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb
|
393
|
+
- spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb
|
391
394
|
- spec/dummy/app/models/dummy_record_with_oauth.rb
|
392
395
|
- spec/dummy/app/models/dummy_user.rb
|
393
396
|
- spec/dummy/app/models/providers/customer_system.rb
|
@@ -410,7 +413,6 @@ files:
|
|
410
413
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
411
414
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
412
415
|
- spec/dummy/config/initializers/inflections.rb
|
413
|
-
- spec/dummy/config/initializers/lhs.rb
|
414
416
|
- spec/dummy/config/initializers/mime_types.rb
|
415
417
|
- spec/dummy/config/initializers/rollbar.rb
|
416
418
|
- spec/dummy/config/initializers/session_store.rb
|
@@ -555,9 +557,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
555
557
|
version: 2.3.0
|
556
558
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
557
559
|
requirements:
|
558
|
-
- - "
|
560
|
+
- - ">="
|
559
561
|
- !ruby/object:Gem::Version
|
560
|
-
version:
|
562
|
+
version: '0'
|
561
563
|
requirements:
|
562
564
|
- Ruby >= 2.3.0
|
563
565
|
rubygems_version: 3.0.6
|
@@ -611,6 +613,9 @@ test_files:
|
|
611
613
|
- spec/dummy/app/models/concerns/.keep
|
612
614
|
- spec/dummy/app/models/dummy_customer.rb
|
613
615
|
- spec/dummy/app/models/dummy_record.rb
|
616
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb
|
617
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb
|
618
|
+
- spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb
|
614
619
|
- spec/dummy/app/models/dummy_record_with_oauth.rb
|
615
620
|
- spec/dummy/app/models/dummy_user.rb
|
616
621
|
- spec/dummy/app/models/providers/customer_system.rb
|
@@ -633,7 +638,6 @@ test_files:
|
|
633
638
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
634
639
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
635
640
|
- spec/dummy/config/initializers/inflections.rb
|
636
|
-
- spec/dummy/config/initializers/lhs.rb
|
637
641
|
- spec/dummy/config/initializers/mime_types.rb
|
638
642
|
- spec/dummy/config/initializers/rollbar.rb
|
639
643
|
- spec/dummy/config/initializers/session_store.rb
|