Class: Foobara::CommandConnector::Request

Inherits:
Object
  • Object
show all
Includes:
TruncatedInspect
Defined in:
foobara-0.6.4/projects/command_connectors/src/command_connector/request.rb,
foobara-0.6.4/projects/entities_plumbing/src/extensions/command_connector/request.rb

Constant Summary

Constants included from TruncatedInspect

TruncatedInspect::MAX_LENGTH

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from TruncatedInspect

#inspect, truncating

Constructor Details

#initialize(**opts) ⇒ Request

Returns a new instance of Request.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'projects/command_connectors/src/command_connector/request.rb', line 22

def initialize(**opts)
  valid_keys = [:inputs, :full_command_name, :action, :serializers, :authenticator, :auth_mappers]

  invalid_keys = opts.keys - valid_keys

  unless invalid_keys.empty?
    # simplecov:disable
    raise ArgumentError, "invalid keys: #{invalid_keys} expected only #{valid_keys}"
    # simplecov:enable
  end

  self.inputs = opts[:inputs] if opts.key?(:inputs)
  self.action = opts[:action] if opts.key?(:action)
  self.auth_mappers = opts[:auth_mappers] if opts.key?(:auth_mappers)
  self.authenticator = opts[:authenticator] if opts.key?(:authenticator)
  self.full_command_name = opts[:full_command_name] if opts.key?(:full_command_name)
  self.serializers = Util.array(opts[:serializers]) if opts.key?(:serializers)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'projects/command_connectors/src/command_connector/request.rb', line 101

def method_missing(method_name, ...)
  if auth_mapped_method?(method_name)
    auth_mapped_value_for(method_name)
  else
    # simplecov:disable
    super
    # simplecov:enable
  end
end

Instance Attribute Details

#action ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def action
  @action
end

#auth_mappers ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def auth_mappers
  @auth_mappers
end

#authenticated_credential ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def authenticated_credential
  @authenticated_credential
end

#authenticated_user ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def authenticated_user
  @authenticated_user
end

#authenticator ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def authenticator
  @authenticator
end

#command ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def command
  @command
end

#command_class ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def command_class
  @command_class
end

#command_connector ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def command_connector
  @command_connector
end

#error ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def error
  @error
end

#full_command_name ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def full_command_name
  @full_command_name
end

#inputs ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def inputs
  @inputs
end

#response ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def response
  @response
end

#serializers ⇒ Object

TODO: this feels like a smell of some sort...



7
8
9
# File 'projects/command_connectors/src/command_connector/request.rb', line 7

def serializers
  @serializers
end

Instance Method Details

#auth_mapped_method?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'projects/command_connectors/src/command_connector/request.rb', line 81

def auth_mapped_method?(method_name)
  auth_mappers&.key?(method_name)
end

#auth_mapped_value_for(name) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'projects/command_connectors/src/command_connector/request.rb', line 89

def auth_mapped_value_for(name)
  return unless authenticated_user

  @auth_mapper_cache ||= {}

  if @auth_mapper_cache.key?(name)
    @auth_mapper_cache[name]
  else
    @auth_mapper_cache[name] = auth_mapper_for(name)&.process_value!(authenticated_user)
  end
end

#auth_mapper_for(name) ⇒ Object



85
86
87
# File 'projects/command_connectors/src/command_connector/request.rb', line 85

def auth_mapper_for(name)
  auth_mappers&.[](name.to_sym)
end

#authenticate ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'projects/command_connectors/src/command_connector/request.rb', line 50

def authenticate
  return if error
  return unless requires_authentication? || authentication_optional?

  unless authenticator
    raise CommandConnector::NoAuthenticatorGivenError,
          "Running a #{command_class.full_command_name} via #{command_connector} " \
          "requires an authenticator but this connector does not have one"
  end

  authenticated_user, authenticated_credential = authenticator.authenticate(self)

  # TODO: why are these on the command instead of the request??
  self.authenticated_user = authenticated_user
  self.authenticated_credential = authenticated_credential

  return unless requires_authentication?

  unless authenticated_user
    self.error = CommandConnector::UnauthenticatedError.new
  end
end

#authentication_optional? ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
# File 'projects/command_connectors/src/command_connector/request.rb', line 73

def authentication_optional?
  command_class.respond_to?(:authentication_optional) && command_class.authentication_optional
end

#error_collection ⇒ Object



161
162
163
# File 'projects/command_connectors/src/command_connector/request.rb', line 161

def error_collection
  outcome.error_collection
end

#mutate_request ⇒ Object



41
42
43
44
45
46
47
48
# File 'projects/command_connectors/src/command_connector/request.rb', line 41

def mutate_request
  return if error

  # TODO: we really need to revisit these interfaces. Something is wrong.
  if command_class.respond_to?(:mutate_request)
    command_class.mutate_request(self)
  end
end

#outcome ⇒ Object



149
150
151
152
153
154
155
# File 'projects/command_connectors/src/command_connector/request.rb', line 149

def outcome
  if error
    Outcome.error(error)
  else
    command&.outcome
  end
end

#relevant_entity_classes ⇒ Object



4
5
6
7
8
9
10
11
12
13
# File 'projects/entities_plumbing/src/extensions/command_connector/request.rb', line 4

def relevant_entity_classes
  if command_class.is_a?(::Class) && command_class < TransformedCommand
    if authenticator.respond_to?(:relevant_entity_classes)
      entity_classes = authenticator.relevant_entity_classes(self)
      [*entity_classes, *relevant_entity_classes_from_inputs_transformer]
    else
      relevant_entity_classes_from_inputs_transformer
    end
  end || EMPTY_ARRAY
end

#requires_authentication? ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
# File 'projects/command_connectors/src/command_connector/request.rb', line 77

def requires_authentication?
  command_class.respond_to?(:requires_authentication) && command_class.requires_authentication
end

#respond_to_missing?(method_name, private = false) ⇒ Boolean

Returns:

  • (Boolean)


111
112
113
# File 'projects/command_connectors/src/command_connector/request.rb', line 111

def respond_to_missing?(method_name, private = false)
  auth_mapped_method?(method_name) || super
end

#response_body ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
# File 'projects/command_connectors/src/command_connector/request.rb', line 132

def response_body
  @response_body ||= begin
    # TODO: should we have separate ways to register success and failure serializers?
    body = success? ? result : error_collection

    if serializer
      serializer.process_value!(body)
    else
      body
    end
  end
end

#result ⇒ Object



157
158
159
# File 'projects/command_connectors/src/command_connector/request.rb', line 157

def result
  outcome.result
end

#serializer ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'projects/command_connectors/src/command_connector/request.rb', line 115

def serializer
  return @serializer if defined?(@serializer)

  if serializers.nil? || serializers.empty?
    @serializer = nil
    return
  end

  actual_serializers = objects_to_serializers(serializers)

  @serializer = if actual_serializers.size == 1
                  actual_serializers[0]
                else
                  Value::Processor::Pipeline.new(processors: actual_serializers)
                end
end

#success? ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'projects/command_connectors/src/command_connector/request.rb', line 145

def success?
  outcome.success?
end