Module: Flapjack::Gateways::JSONAPI::Helpers::Miscellaneous

Defined in:
lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb

Instance Method Summary collapse

Instance Method Details

#request_urlObject



9
10
11
12
13
# File 'lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb', line 9

def request_url
  rurl = request.url.split('?').first
  rurl << "?#{request.params.to_param}" unless request.params.empty?
  rurl
end

#validate_and_parsetime(value) ⇒ Object



124
125
126
127
128
129
130
# File 'lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb', line 124

def validate_and_parsetime(value)
  return unless value
  Time.iso8601(value).getutc
rescue ArgumentError
  logger.error "Couldn't parse time from '#{value}'"
  nil
end

#validate_data(data, options = {}) ⇒ Object



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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb', line 67

def validate_data(data, options = {})
  valid_keys = ['id', 'type', 'attributes', 'relationships']
  valid_attrs = (options[:attributes] || []).map(&:to_s)
  sl = options[:singular_links] ? options[:singular_links].keys.map(&:to_s) : []
  ml = options[:multiple_links] ? options[:multiple_links].keys.map(&:to_s) : []
  all_links = sl + ml

  # FIXME check error codes against JSONAPI spec

  data.each do |d|
    invalid_keys = d.keys - valid_keys
    halt(err(403, "Invalid key(s): #{invalid_keys.join(', ')}")) unless invalid_keys.empty?
    if d.has_key?('attributes')
      attrs = d['attributes']
      halt(err(403, "Attributes must be a Hash with String keys")) unless attrs.is_a?(Hash) &&
        attrs.keys.all? {|k| k.is_a?(String)}
      invalid_attrs = attrs.keys - valid_attrs
      halt(err(403, "Invalid attribute(s): #{invalid_attrs.join(', ')}")) unless invalid_attrs.empty?
    end
    if d.has_key?('relationships')
      links = d['relationships']
      halt(err(403, "Relationships(s) must be a Hash with String keys")) unless links.is_a?(Hash) &&
        links.keys.all? {|k| k.is_a?(String)}
      invalid_links = links.keys - all_links
      halt(err(404, "Unknown relationship type(s): #{invalid_links.join(', ')}")) unless invalid_links.empty?
      links.each_pair do |k, v|
        halt(err(403, "Related data for '#{k}' must be a Hash with String keys")) unless v.is_a?(Hash) && v.keys.all? {|vk| vk.is_a?(String)}
        halt(err(403, "Related data for '#{k}' must have data references")) unless links[k].has_key?('data')

        if sl.include?(k)
          halt(err(403, "Data reference for '#{k}' must be a Hash with 'id' & 'type' String values")) unless links[k]['data'].is_a?(Hash) &&
            v['data'].has_key?('id') &&
            v['data'].has_key?('type') &&
            v['data']['id'].is_a?(String) &&
            v['data']['type'].is_a?(String)

          unless options[:singular_links][k.to_sym].type == v['data']['type']
            halt(err(403, "Related '#{k}' has wrong type #{v['data']['type']}"))
          end
        else
          halt(err(403, "Data reference for '#{k}' must be an Array of Hashes with 'id' & 'type' String values")) unless v['data'].is_a?(Array) &&
            v['data'].all? {|l| l.has_key?('id') } &&
            v['data'].all? {|l| l.has_key?('type') } &&
            v['data'].all? {|l| l['id'].is_a?(String) } &&
            v['data'].all? {|l| l['type'].is_a?(String) }

          t = options[:multiple_links][k.to_sym].type
          bad_type = v['data'].detect {|l| !t.eql?(l['type'])}
          unless bad_type.nil?
            halt(403, "Data reference for '#{k}' has invalid type '#{bad_type}', should be '#{t}")
          end
        end
      end
    end
  end
end


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
# File 'lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb', line 38

def wrapped_link_params(options = {})
  result = params['data']

  assoc = options[:association]
  number = assoc.number

  if result.nil?
    return([nil, false]) if :singular.eql?(number) && options[:allow_nil].is_a?(TrueClass)
    logger.debug("No 'data' object found in the following supplied JSON:")
    logger.debug(request.body.is_a?(StringIO) ? request.body.read : request.body)
    halt err(403, "No 'data' object received")
  end

  case number
  when :multiple
    unless result.is_a?(Array) && result.all? {|r| assoc.type.eql?(r['type']) && !r['id'].nil? }
      halt(err(403, "Malformed data for multiple link endpoint"))
    end
    [result.map {|r| r[:id]}, false]
  when :singular
    unless result.is_a?(Hash) && assoc.type.eql?(result['type'])
      halt(err(403, "Malformed data for singular link endpoint"))
    end
    [[result[:id]], true]
  else
    halt(err(403, "Invalid endpoint definition"))
  end
end

#wrapped_params(options = {}) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb', line 15

def wrapped_params(options = {})
  result = params['data']

  if result.nil?
    return([nil, false]) if options[:allow_nil].is_a?(TrueClass)
    logger.debug("No 'data' object found in the supplied JSON:")
    logger.debug(request.body.is_a?(StringIO) ? request.body.read : request.body)
    halt(err(403, "Data object must be provided"))
  end

  ext_bulk = !(request.content_type =~ /^(?:.+;)?\s*ext=bulk(?:\s*;\s*.+)?$/).nil?
  case result
  when Array
    halt(err(406, "JSONAPI Bulk Extension not set in headers")) unless ext_bulk
    [result, false]
  when Hash
    halt(err(406, "JSONAPI Bulk Extension was set in headers")) if ext_bulk
    [[result], true]
  else
    halt(err(403, "The received data object is not an Array or a Hash"))
  end
end