lhs 21.3.0.pre.autoauth.1 → 21.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|