class Oxy::RSVP

RSVP middleware to transform 'RSVP' requests into corresponding contacts in your Google Contacts via Google People API.

Constants

ALLOWED_STRING_LENGTH

First and last name allowed string length

ELIGIBLE_FORMS_FIELDS

The set of allowed fields. Requests that do not have fields present in this list will not be eligible to be enqueued.

EMAIL_REGEX_VALIDATOR

Email validation regex

Public Class Methods

new(app, logger = $stderr) click to toggle source

ctor.

# File lib/oxy/middleware/rsvp.rb, line 15
def initialize(app, logger = $stderr)
  @app = app
  @logger = logger
  # middleware to deflect abusive clients, 10/90 rps
  @deflect = Rack::Deflect.new(app, :log => logger, :request_threshold => 10, :interval => 90, :log_format => "[Rack::Deflect]: (%s) ~> %s")
end

Public Instance Methods

call(env) click to toggle source

Middleware's entry point

# File lib/oxy/middleware/rsvp.rb, line 23
def call(env)
  # instantiate the request object
  req = Rack::Request.new(env)
  if req.path == "/rsvp" && req.post?
    # first ask deflect layer for permission to process the request
    resp = @deflect.call(env)
    return resp if forbidden(resp)
    # next ask validation layer for permission to process the request
    # ...
    # enqueue background processing for valid submissions only
    Threaded.enqueue(Subscribe, req.POST, @logger) if valid_form(req.POST)
    # redirect anyways
    [302, { "Location" => "/thank-you" }, []]
  else
    @app.call(env)
  end
end

Private Instance Methods

forbidden(resp) click to toggle source

simple helper to find out whether the request is forbidden or not

# File lib/oxy/middleware/rsvp.rb, line 43
def forbidden(resp)
  resp[0] == 403
end
valid_form(form) click to toggle source

only request with eligible and valid form fields are allowed

# File lib/oxy/middleware/rsvp.rb, line 57
def valid_form(form)
  # validate fields eligibility
  is_valid = form.all? { |key, _| ELIGIBLE_FORMS_FIELDS.include?(key) }
  # validate email address
  is_valid = false unless validate_email(form["email_address"]) && is_valid
  # validate first name
  is_valid = false unless validate_length(form["first_name"]) && is_valid
  # validate last name
  is_valid = false unless validate_length(form["last_name"]) && is_valid
  # form is not valid
  unless is_valid
    @logger.write("[RSVP]: Received an invalid form ~> #{form.inspect}\n")
    return false
  end
  # form is valid
  return true
end
validate_email(value) click to toggle source
# File lib/oxy/middleware/rsvp.rb, line 47
def validate_email(value)
  # match or no match?
  EMAIL_REGEX_VALIDATOR.match?(value)
end
validate_length(value) click to toggle source
# File lib/oxy/middleware/rsvp.rb, line 52
def validate_length(value)
  value.nil? || value.empty? || value.length <= ALLOWED_STRING_LENGTH
end