apia 3.0.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 +7 -0
- data/VERSION +1 -0
- data/lib/apia.rb +21 -0
- data/lib/apia/api.rb +100 -0
- data/lib/apia/argument_set.rb +221 -0
- data/lib/apia/authenticator.rb +57 -0
- data/lib/apia/callable_with_environment.rb +43 -0
- data/lib/apia/controller.rb +32 -0
- data/lib/apia/defineable.rb +60 -0
- data/lib/apia/definition.rb +27 -0
- data/lib/apia/definitions/api.rb +51 -0
- data/lib/apia/definitions/argument.rb +77 -0
- data/lib/apia/definitions/argument_set.rb +33 -0
- data/lib/apia/definitions/authenticator.rb +46 -0
- data/lib/apia/definitions/controller.rb +41 -0
- data/lib/apia/definitions/endpoint.rb +74 -0
- data/lib/apia/definitions/enum.rb +31 -0
- data/lib/apia/definitions/error.rb +59 -0
- data/lib/apia/definitions/field.rb +117 -0
- data/lib/apia/definitions/lookup_argument_set.rb +27 -0
- data/lib/apia/definitions/object.rb +29 -0
- data/lib/apia/definitions/polymorph.rb +29 -0
- data/lib/apia/definitions/polymorph_option.rb +53 -0
- data/lib/apia/definitions/scalar.rb +23 -0
- data/lib/apia/definitions/type.rb +109 -0
- data/lib/apia/dsl.rb +23 -0
- data/lib/apia/dsls/api.rb +37 -0
- data/lib/apia/dsls/argument.rb +27 -0
- data/lib/apia/dsls/argument_set.rb +35 -0
- data/lib/apia/dsls/authenticator.rb +38 -0
- data/lib/apia/dsls/concerns/has_fields.rb +38 -0
- data/lib/apia/dsls/controller.rb +34 -0
- data/lib/apia/dsls/endpoint.rb +79 -0
- data/lib/apia/dsls/enum.rb +19 -0
- data/lib/apia/dsls/error.rb +26 -0
- data/lib/apia/dsls/field.rb +27 -0
- data/lib/apia/dsls/lookup_argument_set.rb +24 -0
- data/lib/apia/dsls/object.rb +19 -0
- data/lib/apia/dsls/polymorph.rb +19 -0
- data/lib/apia/dsls/route_group.rb +43 -0
- data/lib/apia/dsls/route_set.rb +40 -0
- data/lib/apia/dsls/scalar.rb +23 -0
- data/lib/apia/dsls/scope_descriptions.rb +17 -0
- data/lib/apia/endpoint.rb +110 -0
- data/lib/apia/enum.rb +43 -0
- data/lib/apia/environment_error_handling.rb +74 -0
- data/lib/apia/error.rb +61 -0
- data/lib/apia/error_set.rb +15 -0
- data/lib/apia/errors/error_exception_error.rb +32 -0
- data/lib/apia/errors/field_spec_parse_error.rb +23 -0
- data/lib/apia/errors/invalid_argument_error.rb +68 -0
- data/lib/apia/errors/invalid_enum_option_error.rb +21 -0
- data/lib/apia/errors/invalid_helper_error.rb +6 -0
- data/lib/apia/errors/invalid_json_error.rb +23 -0
- data/lib/apia/errors/invalid_polymorph_value_error.rb +21 -0
- data/lib/apia/errors/invalid_scalar_value_error.rb +21 -0
- data/lib/apia/errors/manifest_error.rb +43 -0
- data/lib/apia/errors/missing_argument_error.rb +40 -0
- data/lib/apia/errors/null_field_value_error.rb +37 -0
- data/lib/apia/errors/parse_error.rb +10 -0
- data/lib/apia/errors/runtime_error.rb +30 -0
- data/lib/apia/errors/scope_not_granted_error.rb +15 -0
- data/lib/apia/errors/standard_error.rb +6 -0
- data/lib/apia/field_set.rb +76 -0
- data/lib/apia/field_spec.rb +155 -0
- data/lib/apia/helpers.rb +34 -0
- data/lib/apia/hook_set.rb +30 -0
- data/lib/apia/lookup_argument_set.rb +57 -0
- data/lib/apia/lookup_environment.rb +27 -0
- data/lib/apia/manifest_errors.rb +62 -0
- data/lib/apia/mock_request.rb +18 -0
- data/lib/apia/object.rb +68 -0
- data/lib/apia/object_set.rb +21 -0
- data/lib/apia/pagination_object.rb +34 -0
- data/lib/apia/polymorph.rb +50 -0
- data/lib/apia/rack.rb +184 -0
- data/lib/apia/rack_error.rb +17 -0
- data/lib/apia/request.rb +67 -0
- data/lib/apia/request_environment.rb +84 -0
- data/lib/apia/request_headers.rb +42 -0
- data/lib/apia/response.rb +64 -0
- data/lib/apia/route.rb +61 -0
- data/lib/apia/route_group.rb +20 -0
- data/lib/apia/route_set.rb +89 -0
- data/lib/apia/scalar.rb +52 -0
- data/lib/apia/scalars.rb +25 -0
- data/lib/apia/scalars/base64.rb +31 -0
- data/lib/apia/scalars/boolean.rb +37 -0
- data/lib/apia/scalars/date.rb +45 -0
- data/lib/apia/scalars/decimal.rb +36 -0
- data/lib/apia/scalars/integer.rb +34 -0
- data/lib/apia/scalars/string.rb +24 -0
- data/lib/apia/scalars/unix_time.rb +40 -0
- data/lib/apia/schema/api_controller_schema_type.rb +17 -0
- data/lib/apia/schema/api_schema_type.rb +43 -0
- data/lib/apia/schema/argument_schema_type.rb +28 -0
- data/lib/apia/schema/argument_set_schema_type.rb +21 -0
- data/lib/apia/schema/authenticator_schema_type.rb +22 -0
- data/lib/apia/schema/controller.rb +39 -0
- data/lib/apia/schema/controller_endpoint_schema_type.rb +17 -0
- data/lib/apia/schema/controller_schema_type.rb +32 -0
- data/lib/apia/schema/endpoint_schema_type.rb +35 -0
- data/lib/apia/schema/enum_schema_type.rb +20 -0
- data/lib/apia/schema/enum_value_schema_type.rb +14 -0
- data/lib/apia/schema/error_schema_type.rb +23 -0
- data/lib/apia/schema/field_schema_type.rb +38 -0
- data/lib/apia/schema/field_spec_options_schema_type.rb +16 -0
- data/lib/apia/schema/lookup_argument_set_schema_type.rb +25 -0
- data/lib/apia/schema/object_schema_polymorph.rb +31 -0
- data/lib/apia/schema/object_schema_type.rb +21 -0
- data/lib/apia/schema/polymorph_option_schema_type.rb +16 -0
- data/lib/apia/schema/polymorph_schema_type.rb +20 -0
- data/lib/apia/schema/request_method_enum.rb +21 -0
- data/lib/apia/schema/route_group_schema_type.rb +19 -0
- data/lib/apia/schema/route_schema_type.rb +31 -0
- data/lib/apia/schema/route_set_schema_type.rb +20 -0
- data/lib/apia/schema/scalar_schema_type.rb +15 -0
- data/lib/apia/schema/scope_type.rb +14 -0
- data/lib/apia/version.rb +12 -0
- metadata +188 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 834322a8dd87426fd34415e096964a331ca3fefd5101e05e23a216da197e1820
|
4
|
+
data.tar.gz: d422b240f990920a61e520e360d15414aef1b8c0f39021684fa32d31d0aaf1a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6a42e4aaf195d8bd6dc7053a473bbc107ff4303d184bfae3c5bf1e7bb25ef618f57dbc86436c697b06786847f67077d9a06ae9451c6211fbf6072a5cfd6b755e
|
7
|
+
data.tar.gz: 73762ac070550ec052ffa79f2a5e8fdbb0317b8cdb62020b74d494706a1f2e63a65d52691fed82da4f2ba60ed2d66a2572686d3e0c9fef237ec2632a67bc339b
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.0.0
|
data/lib/apia.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'apia/api'
|
4
|
+
require 'apia/argument_set'
|
5
|
+
require 'apia/authenticator'
|
6
|
+
require 'apia/controller'
|
7
|
+
require 'apia/endpoint'
|
8
|
+
require 'apia/enum'
|
9
|
+
require 'apia/error'
|
10
|
+
require 'apia/lookup_argument_set'
|
11
|
+
require 'apia/scalar'
|
12
|
+
require 'apia/object'
|
13
|
+
require 'apia/polymorph'
|
14
|
+
|
15
|
+
require 'apia/scalars/string'
|
16
|
+
require 'apia/scalars/integer'
|
17
|
+
require 'apia/scalars/boolean'
|
18
|
+
require 'apia/scalars/date'
|
19
|
+
require 'apia/scalars/unix_time'
|
20
|
+
require 'apia/scalars/decimal'
|
21
|
+
require 'apia/scalars/base64'
|
data/lib/apia/api.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'apia/defineable'
|
4
|
+
require 'apia/definitions/api'
|
5
|
+
require 'apia/helpers'
|
6
|
+
require 'apia/manifest_errors'
|
7
|
+
require 'apia/object_set'
|
8
|
+
require 'apia/errors/standard_error'
|
9
|
+
require 'apia/mock_request'
|
10
|
+
|
11
|
+
module Apia
|
12
|
+
class API
|
13
|
+
|
14
|
+
extend Defineable
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
# Return the definition for this API
|
19
|
+
#
|
20
|
+
# @return [Apia::Definitions::API]
|
21
|
+
def definition
|
22
|
+
@definition ||= Definitions::API.new(Helpers.class_name_to_id(name))
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return all objects which are referenced by the API. This list is used for the purposes
|
26
|
+
# of validating all objects and generating schemas.
|
27
|
+
#
|
28
|
+
# @param include_apia_controller [Boolean] whether the schema/internal API should be included
|
29
|
+
# @return [Apia::ObjectSet]
|
30
|
+
def objects
|
31
|
+
set = ObjectSet.new([self])
|
32
|
+
if definition.authenticator
|
33
|
+
set.add_object(definition.authenticator)
|
34
|
+
end
|
35
|
+
|
36
|
+
definition.route_set.controllers.each do |con|
|
37
|
+
set.add_object(con)
|
38
|
+
end
|
39
|
+
|
40
|
+
definition.route_set.endpoints.each do |endpoint|
|
41
|
+
set.add_object(endpoint)
|
42
|
+
end
|
43
|
+
|
44
|
+
set
|
45
|
+
end
|
46
|
+
|
47
|
+
# Validate all objects in the API and return details of any issues encountered
|
48
|
+
#
|
49
|
+
# @return [Apia::ManifestErrors]
|
50
|
+
def validate_all
|
51
|
+
errors = ManifestErrors.new
|
52
|
+
objects.each do |object|
|
53
|
+
next unless object.respond_to?(:definition)
|
54
|
+
|
55
|
+
object.definition.validate(errors)
|
56
|
+
end
|
57
|
+
errors
|
58
|
+
end
|
59
|
+
|
60
|
+
# Return the schema hash for this API
|
61
|
+
#
|
62
|
+
# @param host [String]
|
63
|
+
# @param namespace [String]
|
64
|
+
# @return [Hash]
|
65
|
+
def schema(host:, namespace:)
|
66
|
+
require 'apia/schema/controller'
|
67
|
+
Schema::Controller.definition.endpoints[:schema].definition.fields.generate_hash({
|
68
|
+
schema_version: 1,
|
69
|
+
host: host,
|
70
|
+
namespace: namespace,
|
71
|
+
api: definition.id,
|
72
|
+
objects: objects.map(&:definition).select(&:schema?)
|
73
|
+
})
|
74
|
+
end
|
75
|
+
|
76
|
+
# Execute a request for a given controller & endpoint
|
77
|
+
#
|
78
|
+
# @param controller [Apia::Controller]
|
79
|
+
# @param endpoint_name [Symbol]
|
80
|
+
# @return [Apia::Response]
|
81
|
+
def test_endpoint(endpoint, controller: nil)
|
82
|
+
if controller && endpoint.is_a?(Symbol) || endpoint.is_a?(String)
|
83
|
+
endpoint_name = endpoint
|
84
|
+
endpoint = controller.definition.endpoints[endpoint.to_sym]
|
85
|
+
if endpoint.nil?
|
86
|
+
raise Apia::StandardError, "Invalid endpoint name '#{endpoint_name}' for '#{controller.name}'"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
endpoint.test do |r|
|
91
|
+
r.api = self
|
92
|
+
r.controller = controller
|
93
|
+
yield r if block_given?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'apia/defineable'
|
4
|
+
require 'apia/definitions/argument_set'
|
5
|
+
require 'apia/errors/invalid_argument_error'
|
6
|
+
require 'apia/errors/missing_argument_error'
|
7
|
+
require 'apia/helpers'
|
8
|
+
|
9
|
+
module Apia
|
10
|
+
class ArgumentSet
|
11
|
+
|
12
|
+
# This is a constant that represents a missing value where `nil` means
|
13
|
+
# the user actually wanted to send null/nil.
|
14
|
+
class MissingValue
|
15
|
+
|
16
|
+
def self.singleton
|
17
|
+
@singleton ||= new
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
extend Defineable
|
23
|
+
|
24
|
+
class << self
|
25
|
+
|
26
|
+
# Return the definition for this argument set
|
27
|
+
#
|
28
|
+
# @return [Apia::Definitions::ArgumentSet]
|
29
|
+
def definition
|
30
|
+
@definition ||= Definitions::ArgumentSet.new(Helpers.class_name_to_id(name))
|
31
|
+
end
|
32
|
+
|
33
|
+
# Finds all objects referenced by this argument set and add them
|
34
|
+
# to the provided set.
|
35
|
+
#
|
36
|
+
# @param set [Apia::ObjectSet]
|
37
|
+
# @return [void]
|
38
|
+
def collate_objects(set)
|
39
|
+
definition.arguments.each_value do |argument|
|
40
|
+
set.add_object(argument.type.klass) if argument.type.usable_for_argument?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Create a new argument set from a request object
|
45
|
+
#
|
46
|
+
# @param request [Apia::Request]
|
47
|
+
# @return [Apia::ArgumentSet]
|
48
|
+
def create_from_request(request)
|
49
|
+
new(request.json_body || request.params || {}, request: request)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
# Create a new argument set by providing a hash containing the raw
|
55
|
+
# arguments
|
56
|
+
#
|
57
|
+
# @param hash [Hash]
|
58
|
+
# @param path [Array]
|
59
|
+
# @return [Apia::ArgumentSet]
|
60
|
+
def initialize(hash, path: [], request: nil)
|
61
|
+
unless hash.is_a?(Hash)
|
62
|
+
raise Apia::RuntimeError, 'Hash was expected for argument'
|
63
|
+
end
|
64
|
+
|
65
|
+
@path = path
|
66
|
+
@request = request
|
67
|
+
@source = self.class.definition.arguments.each_with_object({}) do |(arg_key, argument), source|
|
68
|
+
given_value = lookup_value(hash, arg_key, argument, request)
|
69
|
+
|
70
|
+
if argument.required? && (given_value.nil? || given_value.is_a?(MissingValue))
|
71
|
+
raise MissingArgumentError.new(argument, path: @path + [argument])
|
72
|
+
end
|
73
|
+
|
74
|
+
# If the given value is missing, we'll just skip adding this to the hash
|
75
|
+
next if given_value.is_a?(MissingValue)
|
76
|
+
|
77
|
+
given_value = parse_value(argument, given_value)
|
78
|
+
validation_errors = argument.validate_value(given_value)
|
79
|
+
unless validation_errors.empty?
|
80
|
+
raise InvalidArgumentError.new(argument, issue: :validation_errors, errors: validation_errors, path: @path + [argument])
|
81
|
+
end
|
82
|
+
|
83
|
+
source[argument.name.to_sym] = given_value
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return an item from the argument set
|
88
|
+
#
|
89
|
+
# @param value [String, Symbol]
|
90
|
+
# @return [Object, nil]
|
91
|
+
def [](value)
|
92
|
+
@source[value.to_sym]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Return an item from this argument set
|
96
|
+
#
|
97
|
+
# @param values [Array<String, Symbol>]
|
98
|
+
# @return [Object, nil]
|
99
|
+
def dig(*values)
|
100
|
+
@source.dig(*values)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Return the source object
|
104
|
+
#
|
105
|
+
# @return [Hash]
|
106
|
+
def to_hash
|
107
|
+
@source.transform_values do |value|
|
108
|
+
value.is_a?(ArgumentSet) ? value.to_hash : value
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return whether an argument has been provided or not?
|
113
|
+
#
|
114
|
+
# @param name [Symbol]
|
115
|
+
# @return [Boolean]
|
116
|
+
def has?(key)
|
117
|
+
@source.key?(key.to_sym)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Validate an argument set and return any errors as appropriate
|
121
|
+
#
|
122
|
+
# @param argument [Apia::Argument]
|
123
|
+
def validate(argument, index: nil)
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def lookup_value(hash, key, argument, request)
|
129
|
+
if hash.key?(key.to_s)
|
130
|
+
hash[key.to_s]
|
131
|
+
elsif hash.key?(key.to_sym)
|
132
|
+
hash[key.to_sym]
|
133
|
+
else
|
134
|
+
route_value = value_from_route(argument, request)
|
135
|
+
return route_value unless route_value.is_a?(MissingValue)
|
136
|
+
return argument.default unless argument.default.nil?
|
137
|
+
|
138
|
+
MissingValue.singleton
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def parse_value(argument, value, index: nil, in_array: false)
|
143
|
+
if value.nil?
|
144
|
+
nil
|
145
|
+
|
146
|
+
elsif argument.array? && value.is_a?(Array)
|
147
|
+
value.each_with_index.map do |v, i|
|
148
|
+
parse_value(argument, v, index: i, in_array: true)
|
149
|
+
end
|
150
|
+
|
151
|
+
elsif argument.array? && !in_array
|
152
|
+
raise InvalidArgumentError.new(argument, issue: :array_expected, index: index, path: @path + [argument])
|
153
|
+
|
154
|
+
elsif argument.type.scalar?
|
155
|
+
begin
|
156
|
+
type = argument.type.klass.parse(value)
|
157
|
+
rescue Apia::ParseError => e
|
158
|
+
# If we cannot parse the given input, this is cause for a parse error to be raised.
|
159
|
+
raise InvalidArgumentError.new(argument, issue: :parse_error, errors: [e.message], index: index, path: @path + [argument])
|
160
|
+
end
|
161
|
+
|
162
|
+
unless argument.type.klass.valid?(type)
|
163
|
+
# If value we have parsed is not actually valid, we 'll raise an argument error.
|
164
|
+
# In most cases, it is likely that an integer has been provided to string etc...
|
165
|
+
raise InvalidArgumentError.new(argument, issue: :invalid_scalar, index: index, path: @path + [argument])
|
166
|
+
end
|
167
|
+
|
168
|
+
type
|
169
|
+
|
170
|
+
elsif argument.type.argument_set?
|
171
|
+
unless value.is_a?(Hash)
|
172
|
+
raise InvalidArgumentError.new(argument, issue: :object_expected, index: index, path: @path + [argument])
|
173
|
+
end
|
174
|
+
|
175
|
+
value = argument.type.klass.new(value, path: @path + [argument], request: @request)
|
176
|
+
value.validate(argument, index: index)
|
177
|
+
value
|
178
|
+
|
179
|
+
elsif argument.type.enum?
|
180
|
+
unless argument.type.klass.definition.values[value]
|
181
|
+
raise InvalidArgumentError.new(argument, issue: :invalid_enum_value, index: index, path: @path + [argument])
|
182
|
+
end
|
183
|
+
|
184
|
+
value
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def check_for_missing_required_arguments
|
189
|
+
self.class.definition.arguments.each_value do |arg|
|
190
|
+
next unless arg.required?
|
191
|
+
next if self[arg.name]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def value_from_route(argument, request)
|
196
|
+
return MissingValue.singleton if request.nil?
|
197
|
+
return MissingValue.singleton if request.route.nil?
|
198
|
+
|
199
|
+
route_args = request.route.extract_arguments(request.api_path)
|
200
|
+
unless route_args.key?(argument.name.to_s)
|
201
|
+
return MissingValue.singleton
|
202
|
+
end
|
203
|
+
|
204
|
+
value_for_arg = route_args[argument.name.to_s]
|
205
|
+
return nil if value_for_arg.nil?
|
206
|
+
|
207
|
+
if argument.type.argument_set?
|
208
|
+
# If the argument is an argument set, we'll just want to try and
|
209
|
+
# populate the first argument.
|
210
|
+
if first_arg = argument.type.klass.definition.arguments.keys.first
|
211
|
+
{ first_arg.to_s => value_for_arg }
|
212
|
+
else
|
213
|
+
{}
|
214
|
+
end
|
215
|
+
else
|
216
|
+
value_for_arg
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'apia/defineable'
|
4
|
+
require 'apia/definitions/authenticator'
|
5
|
+
require 'apia/helpers'
|
6
|
+
require 'apia/callable_with_environment'
|
7
|
+
|
8
|
+
module Apia
|
9
|
+
class Authenticator
|
10
|
+
|
11
|
+
extend Defineable
|
12
|
+
include CallableWithEnvironment
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
# Return the definition for this authenticator
|
17
|
+
#
|
18
|
+
# @return [Apia::Definitions::Authenticator]
|
19
|
+
def definition
|
20
|
+
@definition ||= Definitions::Authenticator.new(Helpers.class_name_to_id(name))
|
21
|
+
end
|
22
|
+
|
23
|
+
# Finds all objects referenced by this authenticator and add them
|
24
|
+
# to the provided set.
|
25
|
+
#
|
26
|
+
# @param set [Apia::ObjectSet]
|
27
|
+
# @return [void]
|
28
|
+
def collate_objects(set)
|
29
|
+
definition.potential_errors.each do |error|
|
30
|
+
set.add_object(error)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Execute this authenticator within the given environment
|
35
|
+
#
|
36
|
+
# @param environment [Apia::RequestEnvironment]
|
37
|
+
# @return [void]
|
38
|
+
def execute(environment)
|
39
|
+
new(environment).call
|
40
|
+
end
|
41
|
+
|
42
|
+
# If any of the given scopes are valid
|
43
|
+
#
|
44
|
+
# @param environment [Apia::RequestEnvironment]
|
45
|
+
# @param scope [String]
|
46
|
+
# @return [Boolean]
|
47
|
+
def authorized_scope?(environment, scopes)
|
48
|
+
return true if definition.scope_validator.nil?
|
49
|
+
return true if scopes.empty?
|
50
|
+
|
51
|
+
scopes.any? { |s| environment.call(s, &definition.scope_validator) }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Apia
|
4
|
+
module CallableWithEnvironment
|
5
|
+
|
6
|
+
def initialize(environment, action_name: :action)
|
7
|
+
@environment = environment
|
8
|
+
@action_name = action_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
action = self.class.definition.send(@action_name)
|
13
|
+
return if action.nil?
|
14
|
+
|
15
|
+
instance_exec(@environment.request, @environment.response, &action)
|
16
|
+
end
|
17
|
+
|
18
|
+
# rubocop:disable Lint/RescueException
|
19
|
+
def call_with_error_handling
|
20
|
+
call
|
21
|
+
rescue Exception => e
|
22
|
+
raise_exception(e)
|
23
|
+
end
|
24
|
+
# rubocop:enable Lint/RescueException
|
25
|
+
|
26
|
+
def respond_to_missing?(name, _include_private = false)
|
27
|
+
@environment.respond_to?(name) || super
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(name, *args, **kwargs, &block)
|
31
|
+
if @environment.respond_to?(name)
|
32
|
+
if kwargs.empty?
|
33
|
+
return @environment.send(name, *args, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
return @environment.send(name, *args, **kwargs, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|