Class: Netfira::WebConnect::RackApp::Action

Inherits:
Object
  • Object
show all
Includes:
Exceptions::HttpExceptions
Defined in:
lib/netfira/web_connect/rack_app/action.rb,
lib/netfira/web_connect/rack_app/action_helpers/data_types.rb,
lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb,
lib/netfira/web_connect/rack_app/action_helpers/env_importer.rb

Defined Under Namespace

Modules: Version1, Version8

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAction

Returns a new instance of Action.



27
28
29
# File 'lib/netfira/web_connect/rack_app/action.rb', line 27

def initialize
  @headers = ActiveSupport::HashWithIndifferentAccess.new
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def env
  @env
end

#headersObject (readonly)

Returns the value of attribute headers.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def headers
  @headers
end

#inputObject (readonly)

Returns the value of attribute input.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def input
  @input
end

#pathObject (readonly)

Returns the value of attribute path.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def path
  @path
end

#query_stringObject (readonly)

Returns the value of attribute query_string.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def query_string
  @query_string
end

#shopObject (readonly)

Returns the value of attribute shop.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def shop
  @shop
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def timeout
  @timeout
end

#verbObject (readonly)

Returns the value of attribute verb.



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 4

def verb
  @verb
end

Class Method Details

.action_classesObject



9
10
11
# File 'lib/netfira/web_connect/rack_app/action.rb', line 9

def self.action_classes
  @action_classes ||= find_action_classes
end

.create(action, version = nil) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/netfira/web_connect/rack_app/action.rb', line 17

def self.create(action, version = nil)
  version ||= latest_version
  klass = nil
  until klass or version < 1
    klass = (action_classes[version] || {})[action] # todo needs explination or to be rewritten to be easily readable
    version -= 1
  end
  klass and klass.new
end

.find_action_classesObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/netfira/web_connect/rack_app/action.rb', line 33

def self.find_action_classes
  action_classes = {}

  # Loop through all constants in this class's namespace
  constants.each do |constant|

    # Match Version# constants (modules containing actions)
    if constant =~ /\AVersion(\d+)\z/

      # The module containing the actions
      mod = const_get(constant)

      # A hash of actions, e.g. :commit => Action::Version8::Commit
      action_classes[$1.to_i] = Hash[mod.constants.map do |name|
        mod.const_get(name)
      end.select do |klass|
        klass < self
      end.map do |klass|
        [klass.name.demodulize.underscore.to_sym, klass]
      end]
    end
  end

  action_classes
end

.latest_versionObject



13
14
15
# File 'lib/netfira/web_connect/rack_app/action.rb', line 13

def self.latest_version
  @latest_version ||= action_classes.keys.max
end

Instance Method Details

#class_for_record_type(type) ⇒ Object



4
5
6
# File 'lib/netfira/web_connect/rack_app/action_helpers/data_types.rb', line 4

def class_for_record_type(type)
  class_for_type type, Model::Record
end

#class_for_relation_type(type) ⇒ Object



8
9
10
# File 'lib/netfira/web_connect/rack_app/action_helpers/data_types.rb', line 8

def class_for_relation_type(type)
  class_for_type type, Model::Relation
end

#header(name, value) ⇒ Object

This method sets a response header, e.g.header ‘Content-Type’, ‘text/plain’



7
8
9
10
11
12
13
14
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 7

def header(name, value)
  name = name.to_s.split(/[- _]/).map(&:capitalize).join('-').to_sym
  if value
    headers[name] = value
  else
    headers.delete name
  end
end

#import_env(env) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_importer.rb', line 4

def import_env(env)
  @env = env

  # Parse the environment
  request = Rack::Request.new env

  # Authentication
  authenticator = Netfira::WebConnect.authenticator
  if authenticator.respond_to? :call
    shop_name = env['HTTP_X_SHOP_NAME']
    password = request['pw'] || env['HTTP_X_PASSWORD']

    # Basic auth
    auth = Rack::Auth::Basic::Request.new(env)
    if auth.provided? && auth.basic?
      shop_name ||= auth.username
      password ||= auth.credentials[1]
    end

    result = authenticator.call shop_name, password
    raise Unauthorized unless result
    header :x_vary_password, result if String === result
    @shop = Netfira::WebConnect::Models::Shop.find_or_create_by(name: shop_name)

  elsif authenticator.nil?
    @shop = Netfira::WebConnect.anonymous_shop
  else
    raise 'Authenticator is not callable'
  end

  # The request verb (PUT, GET, POST etc)
  @verb = request.request_method.downcase.to_sym

  # Query string
  @query_string = request.GET

  # The X-Timeout header
  timeout = env['HTTP_X_TIMEOUT']
  @timeout = timeout.to_i if timeout

  # Path components
  if env['PATH_INFO'] =~ /\A\/\d+\/[^\/]+\/(.+)\z/
    @path = $1.split('/').map{ |x| Rack::Utils.unescape x }
  end

  # Input
  if put? or post?
    @input = request.body
    @input = StringIO.new(@input.read.unpack('m').first) if env['CONTENT_ENCODING'] == 'base64'
    @input = JSON.parse @input.read if request.media_type == 'application/json'
  end

end