FEATURE: Allow using array indexes in json paths (#22)

This commit is contained in:
Josh Kerxhalli-Kleinfield 2020-04-21 09:46:42 -04:00 committed by GitHub
parent 1b9937b27d
commit ca5f555750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 4 deletions

View File

@ -87,22 +87,39 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
"Basic " + Base64.strict_encode64("#{SiteSetting.oauth2_client_id}:#{SiteSetting.oauth2_client_secret}")
end
def walk_path(fragment, segments)
first_seg = segments[0]
def walk_path(fragment, segments, seg_index = 0)
first_seg = segments[seg_index]
return if first_seg.blank? || fragment.blank?
return nil unless fragment.is_a?(Hash) || fragment.is_a?(Array)
first_seg = segments[seg_index].scan(/([\d+])/).length > 0 ? first_seg.split("[")[0] : first_seg
if fragment.is_a?(Hash)
deref = fragment[first_seg] || fragment[first_seg.to_sym]
else
deref = fragment[0] # Take just the first array for now, maybe later we can teach it to walk the array if we need to
array_index = 0
if (seg_index > 0)
last_index = segments[seg_index - 1].scan(/([\d+])/).flatten() || [0]
array_index = last_index.length > 0 ? last_index[0].to_i : 0
end
if fragment.any? && fragment.length >= array_index - 1
deref = fragment[array_index][first_seg]
else
deref = nil
end
end
(deref.blank? || segments.size == 1) ? deref : walk_path(deref, segments[1..-1])
if (deref.blank? || seg_index == segments.size - 1)
deref
else
seg_index += 1
walk_path(deref, segments, seg_index)
end
end
def json_walk(result, user_json, prop)
path = SiteSetting.public_send("oauth2_json_#{prop}_path")
if path.present?
#this.[].that is the same as this.that, allows for both this[0].that and this.[0].that path styles
path = path.gsub(".[].", ".").gsub(".[", "[")
segments = path.split('.')
val = walk_path(user_json, segments)
result[prop] = val if val.present?

View File

@ -195,6 +195,15 @@ describe OAuth2BasicAuthenticator do
expect(result).to eq nil
end
it 'can walk json and find values by index in an array' do
authenticator = OAuth2BasicAuthenticator.new
json_string = '{"emails":[{"value":"test@example.com"},{"value":"test2@example.com"}]}'
SiteSetting.oauth2_json_email_path = 'emails[1].value'
result = authenticator.json_walk({}, JSON.parse(json_string), :email)
expect(result).to eq "test2@example.com"
end
it 'can walk json and download avatar' do
authenticator = OAuth2BasicAuthenticator.new
json_string = '{"user":{"avatar":"http://example.com/1.png"}}'