summaryrefslogtreecommitdiff
path: root/helpers.rb
blob: a51ea3d233533d7db87d66328b0e50520a844a18 (plain)
1
2
3
4
5
6
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
helpers do

  def curl ext, url
    response = `/run/current-system/sw/bin/curl --fail-with-body -sSL #{ext} #{url}`
    $?.success? ? response : nil
  end

  def fetch url, accept = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
    response = curl("-H 'Accept: #{accept}'", url)
    response ? JSON.parse(response) : nil
  end

  # https://github.com/mastodon/mastodon/blob/main/app/lib/request.rb
  def send_signed object#, url

    keypair = OpenSSL::PKey::RSA.new(File.read('private.pem'))
    date = Time.now.utc.httpdate
    body = object.to_json
    sha256 = OpenSSL::Digest::SHA256.new
    digest = "SHA-256=" + sha256.base64digest(body)
    jj object
    #(object['to'] + object['cc'] + object['bto'] + object['bcc']).uniq.each do |url|
    object['to'].uniq.each do |url|
      unless url == 'https://www.w3.org/ns/activitystreams#Public'
        host = URI.parse(url).host
        inbox = fetch(url)["inbox"]
        if inbox
          request_uri = URI(inbox).request_uri

          signed_string = "(request-target): post #{request_uri}\nhost: #{host}\ndate: #{date}\ndigest: #{digest}\ncontent-type: application/activity+json"
          signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string))
          signed_header = 'keyId="' + ACTOR + '#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="' + signature + '"'

          p curl("-X POST -H 'Content-Type: application/activity+json' -H 'Host: #{host}' -H 'Date: #{date}' -H 'Digest: #{digest}' -H 'Signature: #{signed_header}' -d '#{body}'", inbox)
          #$?.success?
        else
          p "No inbox for #{url}"
        end
      end
    end

  end

  def people
    File.read('cache/people.tsv').split("\n").collect {|l| l.chomp.split("\t")}
  end

  def mention actor
    person = people.select{|p| p[1] == actor} 
    if person.empty?
      a = fetch(actor)
      return nil unless a
      mention = "#{a["preferredUsername"]}@#{URI(actor).host}"
      File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"}
      mention
    else
      person[0][0]
    end
  end

  def actor mention
    mention = mention.sub(/^@/, '').chomp
    actors = people.select{|p| p[0] == mention} 
    if actors.empty?
      user, server = mention.split("@")
      a = fetch("https://#{server}/.well-known/webfinger?resource=acct:#{mention}", "application/jrd+json")
      return nil unless a
      actor = a["links"].select { |l|
        l["rel"] == "self"
      }[0]["href"]
      File.open('cache/people.tsv','a'){|f| f.puts "#{mention}\t#{actor}"}
      actor
    else
      actors[0][1]
    end
  end

end