apia 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|