yes-read-api 2.4.5 → 2.5.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/app/controllers/yes/read/api/queries_controller.rb +29 -1
- data/config/routes.rb +16 -2
- data/lib/yes/read/api/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ffccff57e5b684bd457f73ee8812236bdfff0adef1179e040600a8f60ae9e477
|
|
4
|
+
data.tar.gz: '09c52031f2424362d6437a0f0e3fbb7697a78389990c0da1436f6ac84aa2daf5'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da42b024bd288d04c96b97e06806008d9365adfc77f5d9d1488951a0988730ce529cf8a0198fa15e6c3d84cdb102677b6d5b6dbd91f7526ce4e07cf2329f902f
|
|
7
|
+
data.tar.gz: 78e070d987e4c42bee1f905d364380e4446aa26e6cb879bc1ddec1a989f4ab80e41fee3f02adfeba210c9537ce9399631db87bd5e46fdf5b1f7f58565221407e
|
|
@@ -10,6 +10,10 @@ module Yes
|
|
|
10
10
|
before_action :validate_advanced_payload, only: :advanced
|
|
11
11
|
before_action :process_own_filter, only: :call
|
|
12
12
|
|
|
13
|
+
IGNORED_FILTER_PARAM = { basic: :filter_definition, advanced: :filters }.freeze
|
|
14
|
+
|
|
15
|
+
# Covers AuthenticationError raised outside #authenticate_with_token, e.g. by consumer
|
|
16
|
+
# request authorizers, filters or serializers.
|
|
13
17
|
rescue_from(Yes::Core::AuthenticationError, with: :auth_error_response)
|
|
14
18
|
|
|
15
19
|
rescue_from(
|
|
@@ -43,7 +47,7 @@ module Yes
|
|
|
43
47
|
end
|
|
44
48
|
|
|
45
49
|
def response_json(filter_type: :basic, persisted_filter: nil)
|
|
46
|
-
filter_options = persisted_filter
|
|
50
|
+
filter_options = applied_filter_options(persisted_filter:, filter_type:)
|
|
47
51
|
|
|
48
52
|
request_authorizer.call(filter_options, auth_data)
|
|
49
53
|
|
|
@@ -56,6 +60,19 @@ module Yes
|
|
|
56
60
|
serialize(paginated_records, filter_options)
|
|
57
61
|
end
|
|
58
62
|
|
|
63
|
+
# The options the query is built from. They are what the request authorizer is handed too, so
|
|
64
|
+
# it never authorizes a parameter the query does not apply: a basic query applies `filters` and
|
|
65
|
+
# an advanced one `filter_definition`.
|
|
66
|
+
#
|
|
67
|
+
# @param persisted_filter [#body, nil] stored filter whose body replaces the request params
|
|
68
|
+
# @param filter_type [Symbol] `:basic` or `:advanced`
|
|
69
|
+
# @return [Hash] the params without the key the filter type ignores
|
|
70
|
+
def applied_filter_options(persisted_filter:, filter_type:)
|
|
71
|
+
options = persisted_filter&.body&.deep_symbolize_keys&.merge(model: params[:model]) || params
|
|
72
|
+
|
|
73
|
+
options.except(IGNORED_FILTER_PARAM.fetch(filter_type))
|
|
74
|
+
end
|
|
75
|
+
|
|
59
76
|
def request_authorizer
|
|
60
77
|
authorizer_class = "ReadModels::#{read_model_name.classify}::RequestAuthorizer"
|
|
61
78
|
Kernel.const_get(authorizer_class)
|
|
@@ -93,15 +110,26 @@ module Yes
|
|
|
93
110
|
@params ||= request.parameters.deep_symbolize_keys
|
|
94
111
|
end
|
|
95
112
|
|
|
113
|
+
# Authenticates the request using the configured auth adapter and stores the returned auth data.
|
|
114
|
+
# Rescues at call time (not via rescue_from) because the adapter, and with it its error
|
|
115
|
+
# classes, is configured in an initializer that may run after this controller loads.
|
|
116
|
+
#
|
|
117
|
+
# @return [void]
|
|
96
118
|
def authenticate_with_token
|
|
97
119
|
adapter = Yes::Core.configuration.auth_adapter
|
|
98
120
|
raise Yes::Core::AuthenticationError, 'No auth adapter configured' if adapter.nil?
|
|
99
121
|
|
|
100
122
|
@auth_data = adapter.authenticate(request)
|
|
123
|
+
rescue *Yes::Core.configuration.auth_error_classes => e
|
|
124
|
+
auth_error_response(e)
|
|
101
125
|
end
|
|
102
126
|
|
|
103
127
|
attr_reader :auth_data
|
|
104
128
|
|
|
129
|
+
# Renders a 401 for an authentication failure.
|
|
130
|
+
#
|
|
131
|
+
# @param error [StandardError] the error raised by the auth adapter
|
|
132
|
+
# @return [void]
|
|
105
133
|
def auth_error_response(error)
|
|
106
134
|
render(
|
|
107
135
|
json: { title: 'Auth Token Invalid', detail: error.message }.to_json,
|
data/config/routes.rb
CHANGED
|
@@ -50,7 +50,7 @@ module Yes
|
|
|
50
50
|
request.body.rewind # restore the cursor to the beginning able read again body
|
|
51
51
|
|
|
52
52
|
auth_token = env['HTTP_AUTHORIZATION'] || ''
|
|
53
|
-
auth_data =
|
|
53
|
+
auth_data = unverified_auth_data(auth_token)
|
|
54
54
|
{
|
|
55
55
|
auth_token:,
|
|
56
56
|
auth_data: auth_data.to_json,
|
|
@@ -58,9 +58,23 @@ module Yes
|
|
|
58
58
|
}.stringify_keys
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
# Decodes the bearer token without verifying it, only to enrich the span. A missing or
|
|
62
|
+
# undecodable token yields an empty result: span enrichment must never decide the outcome
|
|
63
|
+
# of the request, the controller answers with 401 for such tokens.
|
|
64
|
+
#
|
|
65
|
+
# @param auth_token [String] the raw Authorization header value (may be empty)
|
|
66
|
+
# @return [Array<Hash>, Hash] the decoded JWT payload and header, or an empty hash
|
|
67
|
+
def unverified_auth_data(auth_token)
|
|
68
|
+
return {} if auth_token.blank?
|
|
69
|
+
|
|
70
|
+
JWT.decode(auth_token.gsub('Bearer ', ''), nil, false)
|
|
71
|
+
rescue JWT::DecodeError
|
|
72
|
+
{}
|
|
73
|
+
end
|
|
74
|
+
|
|
61
75
|
def get_otl_auth_data(request, env)
|
|
62
76
|
auth_token = env['HTTP_AUTHORIZATION'] || ''
|
|
63
|
-
auth_data =
|
|
77
|
+
auth_data = unverified_auth_data(auth_token)
|
|
64
78
|
{
|
|
65
79
|
auth_token:,
|
|
66
80
|
auth_data: auth_data.to_json,
|
data/lib/yes/read/api/version.rb
CHANGED