Skip to content

Commit

Permalink
object fact request (#320)
Browse files Browse the repository at this point in the history
  • Loading branch information
adriacidre authored Jun 18, 2024
1 parent 48cd474 commit bd9929b
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 17 deletions.
72 changes: 72 additions & 0 deletions examples/object_fact_request/lib.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2020 Self Group Ltd. All Rights Reserved.
# frozen_string_literal: true

module ObjectFactRequest
class Runner
def initialize(client, prompt)
@client = client
@prompt = prompt
end

def help
<<-MSG
Your app can request certain bits of information to your
connected users. To do this, you'll only need its _SelfID_
and the fields you want to request you can find a list of
updated valid fields [here](https://github.com/selfid-net/selfid-gem/blob/main/lib/sources.rb).
Due of its nature the information request is an asynchronous
process, where your program should wait for user's input before
processing the response. This process is fully managed by
`request_information` gem function.
MSG
end

def run
# printexample
begin
# Request the user id to send a fact request to
user_id = @prompt.ask("Please introduce the user id you want to send a fact request to: ") do |q|
q.required true
end

mutex = Mutex.new
condvar = ConditionVariable.new

# Send an fact request
puts ""
puts "we're sending an fact reuqest to #{user_id}'s device"
@client.facts.request(user_id, [{sources: [:passport], fact: :photo}]) do |res|
# Information request has been rejected by the user
if res.status == "rejected"
puts 'Information request rejected'
condvar.signal
end

# Response comes in form of facts easy to access with facts method
attestations = res.attestation_values_for(:photo)
photo = res.object(attestations.first)

path = "/tmp/tmp.jpg"
# puts photo.original_issuer
# puts photo.original_subscriberin
photo.save(path)

puts "The requested passport photo has been stored at #{path}!"
condvar.signal
end
rescue => e
# Raised exceptions usually happen because of requests timing out.
puts "Oops! this is embarassing, but we found an error with your request"
puts "#{e}"
condvar.signal
end

mutex.synchronize do
condvar.wait(mutex)
end
puts "DONE"
# !printexample
end
end
end
25 changes: 13 additions & 12 deletions lib/messages/attestation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,35 @@
module SelfSDK
module Messages
class Attestation
attr_accessor :verified, :origin, :source, :value, :operator, :expected_value, :fact_name, :to, :audience
attr_accessor :verified, :origin, :source, :value, :operator, :expected_value, :fact_name, :to, :audience, :payload

def initialize(messaging)
@messaging = messaging
end

def parse(name, attestation)
payload = JSON.parse(@messaging.jwt.decode(attestation[:payload]), symbolize_names: true)
@origin = payload[:iss]
@to = payload[:sub]
@audience = payload[:aud]
@source = payload[:source]
@payload = JSON.parse(@messaging.jwt.decode(attestation[:payload]), symbolize_names: true)
@origin = @payload[:iss]
@to = @payload[:sub]
@audience = @payload[:aud]
@source = @payload[:source]
header = JSON.parse(@messaging.jwt.decode(attestation[:protected]), symbolize_names: true)
@verified = valid_signature?(attestation, header[:kid])
@expected_value = payload[:expected_value]
@operator = payload[:operator]
@expected_value = @payload[:expected_value]
@operator = @payload[:operator]
@fact_name = name.to_s
if payload[name].nil?
return if payload[:facts].nil?

payload[:facts].each do |f|
if @payload[name].nil?
return if @payload[:facts].nil?

@payload[:facts].each do |f|
if f[:key] == name.to_s
@value = f[:value]
break
end
end
else
@value = payload[name]
@value = @payload[name]
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/messages/fact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def parse(fact)
fact[:attestations]&.each do |a|
attestation = SelfSDK::Messages::Attestation.new(@messaging)
attestation.parse(fact[:fact].to_sym, a)
@attestations.push(attestation)
@attestations.push(attestation) unless attestation.value.nil?
end
end

Expand Down
19 changes: 17 additions & 2 deletions lib/messages/fact_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ def parse(input, envelope=nil)
payload[:facts].each do |f|
begin
fact = SelfSDK::Messages::Fact.new(@messaging)
if f[:fact] == 'photo'
f[:fact] = :image_hash
end
fact.parse(f)
@facts.push(fact)
rescue StandardError => e
Expand All @@ -45,10 +48,12 @@ def parse(input, envelope=nil)
issuer = envelope.sender.split(":")
@from_device = issuer.last
end

end

def fact(name)
name = @messaging.source.normalize_fact_name(name)
name = "image_hash" if name == 'photo'
@facts.select{|f| f.name == name}.first
end

Expand All @@ -59,8 +64,8 @@ def attestations_for(name)
end

def attestation_values_for(name)
a = attestations_for(name)
a.map{|a| a.value}
aa = attestations_for(name)
aa.map{|a| a.value}
end

def validate!(original)
Expand Down Expand Up @@ -92,6 +97,16 @@ def body
def auth_response?
@auth == true
end

def object(hash)
payload[:objects].each do |o|
if o[:image_hash] == hash
return SelfSDK::Chat::FileObject.new(
@messaging.client.jwt.auth_token,
@messaging.client.self_url).build_from_object(o)
end
end
end
end
end
end
4 changes: 2 additions & 2 deletions test/messages/fact_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def test_parse

assert_equal "display_name", parsed_fact[:fact]
assert_equal "==", parsed_fact[:operator]
assert_equal 1, parsed_fact[:attestations].length
assert_equal nil, parsed_fact[:attestations]
assert_equal "lol", parsed_fact[:expected_value]
end
end
end
end
end

0 comments on commit bd9929b

Please sign in to comment.