Class: Netfira::WebConnect::RackApp::Action
- Inherits:
-
Object
- Object
- Netfira::WebConnect::RackApp::Action
- Includes:
- Exceptions::HttpExceptions
- Defined in:
- lib/netfira/web_connect/rack_app/action.rb,
lib/netfira/web_connect/rack_app/action_helpers/send_file.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
Direct Known Subclasses
Version1::DeprecatedDownstream, Version1::Info, Version8::Checksums, Version8::Commit, Version8::Confirm, Version8::Fetch, Version8::Files, Version8::Records, Version8::Settings, Version8::Web
Defined Under Namespace
Constant Summary collapse
- VALID_BASE64 =
%r`^([a-z\d+/]{4})*([a-z\d+/]{4}|[a-z\d+/]{3}=|[a-z\d+/]{2}==)$`i
Instance Attribute Summary collapse
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#input ⇒ Object
readonly
Returns the value of attribute input.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#query_string ⇒ Object
readonly
Returns the value of attribute query_string.
-
#shop ⇒ Object
readonly
Returns the value of attribute shop.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
-
#verb ⇒ Object
readonly
Returns the value of attribute verb.
Class Method Summary collapse
Instance Method Summary collapse
-
#allow(*args) ⇒ Object
This method restricts request verbs (symbols) and input types (classes).
- #class_for_record_type(type) ⇒ Object
- #class_for_relation_type(type) ⇒ Object
- #dispatch_event(*args, &block) ⇒ Object
-
#header(name, value) ⇒ Object
This method sets a response header, e.g.header ‘Content-Type’, ‘text/plain’.
- #import_env(env) ⇒ Object
-
#initialize ⇒ Action
constructor
A new instance of Action.
- #send_file(path) ⇒ Object
Constructor Details
#initialize ⇒ Action
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
#env ⇒ Object (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 |
#headers ⇒ Object (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 |
#input ⇒ Object (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 |
#path ⇒ Object (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_string ⇒ Object (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 |
#shop ⇒ Object (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 |
#timeout ⇒ Object (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 |
#verb ⇒ Object (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_classes ⇒ Object
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 |
.latest_version ⇒ Object
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
#allow(*args) ⇒ Object
This method restricts request verbs (symbols) and input types (classes)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_methods.rb', line 22 def allow(*args) # Restrict verbs verbs = args.select { |x| Symbol === x } unless verbs.empty? || verbs.include?(verb) raise MethodNotAllowed.new("The #{verb.to_s.upcase} verb is not allowed", allowed: verbs.map{ |v| v.to_s.upcase }) end # Restrict input type types = args.select { |x| Class === x } unless types.empty? || types.find { |t| t === input } raise BadRequest.new('Unexpected request body type', allowed: types.map { |t| t.name }) end end |
#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 |
#dispatch_event(*args, &block) ⇒ Object
31 32 33 |
# File 'lib/netfira/web_connect/rack_app/action.rb', line 31 def dispatch_event(*args, &block) Netfira::WebConnect.dispatch_event *args, &block 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
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/netfira/web_connect/rack_app/action_helpers/env_importer.rb', line 7 def import_env(env) @env = env @shop = nil session = nil # Parse the environment request = Rack::Request.new env # Restore sessions session_lifetime = Netfira::WebConnect.session_lifetime session_token = session_lifetime && env['HTTP_X_SESSION'] if session_token session = Models::Session.by_token(session_token) if session @shop = session.shop else raise Unauthorized, 'Session has expired' end end # Authentication unless @shop 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 # Make shop_name a copy, so the authenticator can't mutate # the original string shop_name = shop_name.dup if shop_name result = authenticator.call shop_name, password raise Unauthorized unless result @shop = Netfira::WebConnect::Models::Shop.find_or_create_by(name: shop_name) header :x_vary_password, result if String === result # Sessions if session_lifetime session ||= @shop.sessions.new session.expires_at = Time.now + session_lifetime if Fixnum === session_lifetime session.save header :x_session, session.token end elsif authenticator.nil? @shop = Netfira::WebConnect.anonymous_shop else raise 'Authenticator is not callable' end 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 # Decode base64 if (env['HTTP_CONTENT_ENCODING'] || env['CONTENT_ENCODING'] || '').downcase == 'base64' input = @input.read.gsub(/\s+/, '') raise BadRequest, 'Invalid base64 in request body' unless input.length % 4 == 0 && input =~ VALID_BASE64 @input = StringIO.new(input.unpack('m').first) end # Unserialize JSON begin @input = JSON.parse @input.read.sub(/\A\z/, 'null'), quirks_mode: true if request.media_type == 'application/json' rescue JSON::ParserError => error raise BadRequest.new('Invalid JSON in request body', details: error..sub(/^\d+:\s*/, '')) end end end |
#send_file(path) ⇒ Object
6 7 8 9 10 11 12 13 |
# File 'lib/netfira/web_connect/rack_app/action_helpers/send_file.rb', line 6 def send_file(path) content = nil if path.to_s.end_with? '.erb' template = ERB.new(path.read) content = template.result(binding) end raise RackApp::Exceptions::SendFile.new(path, content) end |