gruf 1.2.7 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +98 -119
- data/bin/gruf +9 -3
- data/lib/gruf.rb +4 -4
- data/lib/gruf/configuration.rb +11 -20
- data/lib/gruf/controllers/base.rb +82 -0
- data/lib/gruf/controllers/request.rb +96 -0
- data/lib/gruf/controllers/service_binder.rb +86 -0
- data/lib/gruf/error.rb +9 -0
- data/lib/gruf/errors/helpers.rb +40 -0
- data/lib/gruf/{hooks → interceptors}/active_record/connection_reset.rb +4 -10
- data/lib/gruf/interceptors/authentication/basic.rb +80 -0
- data/lib/gruf/interceptors/base.rb +51 -0
- data/lib/gruf/{instrumentation/output_metadata_timer.rb → interceptors/context.rb} +25 -15
- data/lib/gruf/interceptors/instrumentation/output_metadata_timer.rb +59 -0
- data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/base.rb +15 -13
- data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/logstash.rb +15 -13
- data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/plain.rb +21 -19
- data/lib/gruf/interceptors/instrumentation/request_logging/interceptor.rb +191 -0
- data/lib/gruf/interceptors/instrumentation/statsd.rb +80 -0
- data/lib/gruf/interceptors/registry.rb +131 -0
- data/lib/gruf/{authentication/none.rb → interceptors/server_interceptor.rb} +8 -7
- data/lib/gruf/interceptors/timer.rb +79 -0
- data/lib/gruf/response.rb +1 -2
- data/lib/gruf/server.rb +40 -25
- data/lib/gruf/version.rb +1 -1
- metadata +19 -20
- data/lib/gruf/authentication.rb +0 -65
- data/lib/gruf/authentication/base.rb +0 -65
- data/lib/gruf/authentication/basic.rb +0 -74
- data/lib/gruf/authentication/strategies.rb +0 -107
- data/lib/gruf/hooks/base.rb +0 -66
- data/lib/gruf/hooks/registry.rb +0 -110
- data/lib/gruf/instrumentation/base.rb +0 -114
- data/lib/gruf/instrumentation/registry.rb +0 -104
- data/lib/gruf/instrumentation/request_context.rb +0 -82
- data/lib/gruf/instrumentation/request_logging/hook.rb +0 -185
- data/lib/gruf/instrumentation/statsd.rb +0 -80
- data/lib/gruf/service.rb +0 -333
@@ -0,0 +1,82 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
+
# Software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
#
|
17
|
+
require_relative 'request'
|
18
|
+
require_relative 'service_binder'
|
19
|
+
|
20
|
+
module Gruf
|
21
|
+
module Controllers
|
22
|
+
##
|
23
|
+
# Base controller object for Gruf gRPC requests
|
24
|
+
#
|
25
|
+
class Base
|
26
|
+
include Gruf::Errors::Helpers
|
27
|
+
|
28
|
+
# @var [Gruf::Controller::Request] request
|
29
|
+
attr_reader :request
|
30
|
+
# @var [Gruf::Error] error
|
31
|
+
attr_reader :error
|
32
|
+
|
33
|
+
##
|
34
|
+
# Initialize the controller within the given request context
|
35
|
+
#
|
36
|
+
# @param [Symbol] method_key
|
37
|
+
# @param [GRPC::GenericService] service
|
38
|
+
# @param [GRPC::RpcDesc] rpc_desc
|
39
|
+
# @param [GRPC::ActiveCall] active_call
|
40
|
+
# @param [Google::Protobuf::MessageExts] message
|
41
|
+
#
|
42
|
+
def initialize(method_key:, service:, rpc_desc:, active_call:, message:)
|
43
|
+
@request = Request.new(
|
44
|
+
method_key: method_key,
|
45
|
+
service: service,
|
46
|
+
rpc_desc: rpc_desc,
|
47
|
+
active_call: active_call,
|
48
|
+
message: message
|
49
|
+
)
|
50
|
+
@error = Gruf::Error.new
|
51
|
+
@interceptors = Gruf.interceptors.prepare(@request, @error)
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Bind the controller to the given service and add it to the service registry
|
56
|
+
#
|
57
|
+
# @param [GRPC::GenericService] service
|
58
|
+
#
|
59
|
+
def self.bind(service)
|
60
|
+
Gruf.services << service.name.constantize
|
61
|
+
ServiceBinder.new(service).bind!(self)
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Call a method on this controller
|
66
|
+
#
|
67
|
+
# @param [Symbol] method_key
|
68
|
+
#
|
69
|
+
def call(method_key, &block)
|
70
|
+
Interceptors::Context.new(@interceptors).intercept! do
|
71
|
+
send(method_key, &block)
|
72
|
+
end
|
73
|
+
rescue GRPC::BadStatus
|
74
|
+
raise # passthrough
|
75
|
+
rescue => e
|
76
|
+
set_debug_info(e.message, e.backtrace) if Gruf.backtrace_on_error
|
77
|
+
error_message = Gruf.use_exception_message ? e.message : Gruf.internal_error_message
|
78
|
+
fail!(:internal, :unknown, error_message)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
+
# Software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
#
|
17
|
+
module Gruf
|
18
|
+
module Controllers
|
19
|
+
##
|
20
|
+
# Encapsulates a request for a controller
|
21
|
+
#
|
22
|
+
class Request
|
23
|
+
# @var [Object] message
|
24
|
+
attr_reader :message
|
25
|
+
# @var [GRPC::ActiveCall] active_call
|
26
|
+
attr_reader :active_call
|
27
|
+
# @var [Symbol] method_key
|
28
|
+
attr_reader :method_key
|
29
|
+
# @var [Gruf::Controllers::Request::Type] type
|
30
|
+
attr_reader :type
|
31
|
+
|
32
|
+
delegate :metadata, to: :active_call
|
33
|
+
delegate :messages, :client_streamer?, :server_streamer?, :bidi_streamer?, :request_response?, to: :type
|
34
|
+
|
35
|
+
class Type
|
36
|
+
delegate :client_streamer?, :server_streamer?, :bidi_streamer?, :request_response?, to: :@rpc_desc
|
37
|
+
|
38
|
+
##
|
39
|
+
# @param [GRPC::RpcDesc] rpc_desc
|
40
|
+
#
|
41
|
+
def initialize(rpc_desc)
|
42
|
+
@rpc_desc = rpc_desc
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# @param [Symbol] method_key The method symbol of the RPC method being executed
|
48
|
+
# @param [Class] service The class of the service being executed against
|
49
|
+
# @param [GRPC::RpcDesc] rpc_desc The RPC descriptor of the call
|
50
|
+
# @param [GRPC::ActiveCall] active_call The restricted view of the call
|
51
|
+
# @param [Object] message The protobuf message (or messages) of the request
|
52
|
+
#
|
53
|
+
def initialize(method_key:, service:, rpc_desc:, active_call:, message:)
|
54
|
+
@method_key = method_key
|
55
|
+
@service = service
|
56
|
+
@active_call = active_call
|
57
|
+
@message = message
|
58
|
+
@type = Type.new(rpc_desc)
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Returns the service name as a translated name separated by periods. Strips
|
63
|
+
# the superfluous "Service" suffix from the name
|
64
|
+
#
|
65
|
+
# @return [String]
|
66
|
+
#
|
67
|
+
def service_key
|
68
|
+
@service.name.underscore.tr('/', '.').gsub('.service', '')
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Parse the method signature into a service.method name format
|
73
|
+
#
|
74
|
+
# @return [String] The parsed service method name
|
75
|
+
#
|
76
|
+
def method_name
|
77
|
+
"#{service_key}.#{method_key}"
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Return all messages for this request, properly handling different request types
|
82
|
+
#
|
83
|
+
# @return Enumerable<Object>
|
84
|
+
#
|
85
|
+
def messages
|
86
|
+
if client_streamer?
|
87
|
+
message.call { |msg| yield msg }
|
88
|
+
elsif bidi_streamer?
|
89
|
+
message
|
90
|
+
else
|
91
|
+
[message]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
+
# Software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
#
|
17
|
+
module Gruf
|
18
|
+
module Controllers
|
19
|
+
##
|
20
|
+
# Binds gRPC services to a gruf controller
|
21
|
+
#
|
22
|
+
class ServiceBinder
|
23
|
+
##
|
24
|
+
# Represents a bound RPC descriptor for future-proofing internal helpers
|
25
|
+
#
|
26
|
+
class BoundDesc < SimpleDelegator; end
|
27
|
+
|
28
|
+
##
|
29
|
+
# @param [GRPC::GenericService] service
|
30
|
+
#
|
31
|
+
def initialize(service)
|
32
|
+
@service = service
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# @param [Gruf::Controllers::Base]
|
37
|
+
#
|
38
|
+
def bind!(controller)
|
39
|
+
rpc_methods.each { |name, desc| bind_method(controller, name, desc) }
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
##
|
45
|
+
# @param [Gruf::Controllers::Base] controller
|
46
|
+
# @param [Symbol] method_name
|
47
|
+
# @param [BoundDesc] desc
|
48
|
+
#
|
49
|
+
def bind_method(controller, method_name, desc)
|
50
|
+
method_key = method_name.to_s.underscore.to_sym
|
51
|
+
service_ref = @service
|
52
|
+
|
53
|
+
@service.class_eval do
|
54
|
+
if desc.request_response?
|
55
|
+
define_method(method_key) do |message, active_call|
|
56
|
+
c = controller.new(method_key: method_key, service: service_ref, message: message, active_call: active_call, rpc_desc: desc)
|
57
|
+
c.call(method_key)
|
58
|
+
end
|
59
|
+
elsif desc.client_streamer?
|
60
|
+
define_method(method_key) do |active_call|
|
61
|
+
c = controller.new(method_key: method_key, service: service_ref, message: proc { |&block| active_call.each_remote_read(&block) }, active_call: active_call, rpc_desc: desc)
|
62
|
+
c.call(method_key)
|
63
|
+
end
|
64
|
+
elsif desc.server_streamer?
|
65
|
+
define_method(method_key) do |message, active_call, &block|
|
66
|
+
c = controller.new(method_key: method_key, service: service_ref, message: message, active_call: active_call, rpc_desc: desc)
|
67
|
+
c.call(method_key, &block)
|
68
|
+
end
|
69
|
+
else # bidi
|
70
|
+
define_method(method_key) do |messages, active_call, &block|
|
71
|
+
c = controller.new(method_key: method_key, service: service_ref, message: messages, active_call: active_call, rpc_desc: desc)
|
72
|
+
c.call(method_key, &block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# @return Array<Gruf::Controllers::ServiceBinder::BoundDesc>
|
80
|
+
#
|
81
|
+
def rpc_methods
|
82
|
+
@service.rpc_descs.map { |rd| BoundDesc.new(rd) }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/gruf/error.rb
CHANGED
@@ -90,6 +90,15 @@ module Gruf
|
|
90
90
|
@field_errors << Errors::Field.new(field_name, error_code, message)
|
91
91
|
end
|
92
92
|
|
93
|
+
##
|
94
|
+
# Return true if there are any present field errors
|
95
|
+
#
|
96
|
+
# @return [Boolean] True if the service has any field errors
|
97
|
+
#
|
98
|
+
def has_field_errors?
|
99
|
+
@field_errors.any?
|
100
|
+
end
|
101
|
+
|
93
102
|
##
|
94
103
|
# Set the debugging information for the error message
|
95
104
|
#
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
+
# Software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
#
|
17
|
+
module Gruf
|
18
|
+
module Errors
|
19
|
+
module Helpers
|
20
|
+
delegate :add_field_error, :set_debug_info, :has_field_errors?, to: :error
|
21
|
+
|
22
|
+
##
|
23
|
+
# Will issue a GRPC BadStatus exception, with a code based on the code passed.
|
24
|
+
#
|
25
|
+
# @param [Symbol] error_code The network error code that maps to gRPC status codes
|
26
|
+
# @param [Symbol] app_code The application-specific code for the error
|
27
|
+
# @param [String] message (Optional) A detail message about the error
|
28
|
+
# @param [Hash] metadata (Optional) Any metadata to inject into the trailing metadata for the response
|
29
|
+
#
|
30
|
+
def fail!(error_code, app_code = nil, message = '', metadata = {})
|
31
|
+
e = error
|
32
|
+
e.code = error_code.to_sym
|
33
|
+
e.app_code = app_code ? app_code.to_sym : e.code
|
34
|
+
e.message = message.to_s
|
35
|
+
e.metadata = metadata
|
36
|
+
e.fail!(request.active_call)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -15,25 +15,19 @@
|
|
15
15
|
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
16
|
#
|
17
17
|
module Gruf
|
18
|
-
module
|
18
|
+
module Interceptors
|
19
19
|
module ActiveRecord
|
20
20
|
##
|
21
21
|
# Resets the ActiveRecord connection to maintain accurate connected state in the thread pool
|
22
22
|
#
|
23
|
-
class ConnectionReset < Gruf::
|
23
|
+
class ConnectionReset < ::Gruf::Interceptors::ServerInterceptor
|
24
24
|
##
|
25
25
|
# Reset any ActiveRecord connections after a gRPC service is called. Because of the way gRPC manages its
|
26
26
|
# connection pool, we need to ensure that this is done to properly
|
27
27
|
#
|
28
|
-
|
29
|
-
# @param [Object] _response The protobuf response object
|
30
|
-
# @param [Symbol] _call_signature The gRPC method on the service that was called
|
31
|
-
# @param [Object] _request The protobuf request object
|
32
|
-
# @param [GRPC::ActiveCall] _call the gRPC core active call object, which represents marshalled data for
|
33
|
-
# the call itself
|
34
|
-
#
|
35
|
-
def after(_success, _response, _call_signature, _request, _call)
|
28
|
+
def call
|
36
29
|
::ActiveRecord::Base.clear_active_connections! if enabled?
|
30
|
+
yield
|
37
31
|
end
|
38
32
|
|
39
33
|
private
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
+
# Software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
#
|
17
|
+
require 'base64'
|
18
|
+
|
19
|
+
module Gruf
|
20
|
+
module Interceptors
|
21
|
+
module Authentication
|
22
|
+
##
|
23
|
+
# Handles basic authentication for gRPC requests
|
24
|
+
#
|
25
|
+
class Basic < Gruf::Interceptors::ServerInterceptor
|
26
|
+
|
27
|
+
def call
|
28
|
+
fail!(:unauthenticated, :unauthenticated) unless bypass? || valid?
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
##
|
35
|
+
# @return [Boolean] If this method is in the excluded list, bypass
|
36
|
+
#
|
37
|
+
def bypass?
|
38
|
+
options.fetch(:excluded_methods, []).include?(request.method_name)
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# @return [Boolean] True if the basic authentication was valid
|
43
|
+
#
|
44
|
+
def valid?
|
45
|
+
server_credentials.any? do |cred|
|
46
|
+
username = cred.fetch(:username, '').to_s
|
47
|
+
password = cred.fetch(:password, '').to_s
|
48
|
+
if username.empty?
|
49
|
+
request_password == password
|
50
|
+
else
|
51
|
+
request_credentials == "#{username}:#{password}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# @return [Array<Hash>] An array of valid server credentials for this service
|
58
|
+
#
|
59
|
+
def server_credentials
|
60
|
+
options.fetch(:credentials, [])
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# @return [String] The decoded request credentials
|
65
|
+
#
|
66
|
+
def request_credentials
|
67
|
+
credentials = request.active_call.respond_to?(:metadata) ? request.active_call.metadata['authorization'].to_s : ''
|
68
|
+
Base64.decode64(credentials.to_s.gsub('Basic ', '').strip)
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# @return [String] The decoded request password
|
73
|
+
#
|
74
|
+
def request_password
|
75
|
+
@request_password ||= request_credentials.split(':').last
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
+
#
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
+
# Software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
+
#
|
17
|
+
module Gruf
|
18
|
+
module Interceptors
|
19
|
+
##
|
20
|
+
# Base class for interception requests
|
21
|
+
#
|
22
|
+
class Base
|
23
|
+
# @var [Gruf::Controllers::Request] request
|
24
|
+
attr_reader :request
|
25
|
+
# @var [Gruf::Error] error
|
26
|
+
attr_reader :error
|
27
|
+
# @var [Hash] options
|
28
|
+
attr_reader :options
|
29
|
+
|
30
|
+
##
|
31
|
+
# @param [Gruf::Controllers::Request] request
|
32
|
+
# @param [Gruf::Error] error
|
33
|
+
# @param [Hash] options
|
34
|
+
#
|
35
|
+
def initialize(request, error, options = {})
|
36
|
+
@request = request
|
37
|
+
@error = error
|
38
|
+
@options = options || {}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
require_relative 'server_interceptor'
|
45
|
+
require_relative 'context'
|
46
|
+
require_relative 'timer'
|
47
|
+
require_relative 'active_record/connection_reset'
|
48
|
+
require_relative 'authentication/basic'
|
49
|
+
require_relative 'instrumentation/statsd'
|
50
|
+
require_relative 'instrumentation/output_metadata_timer'
|
51
|
+
require_relative 'instrumentation/request_logging/interceptor'
|