diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/fetch_feed_service.rb | 5 | ||||
-rw-r--r-- | app/services/follow_remote_user_service.rb | 60 | ||||
-rw-r--r-- | app/services/process_feed_update_service.rb | 20 |
3 files changed, 85 insertions, 0 deletions
diff --git a/app/services/fetch_feed_service.rb b/app/services/fetch_feed_service.rb new file mode 100644 index 000000000..3b8efbe3b --- /dev/null +++ b/app/services/fetch_feed_service.rb @@ -0,0 +1,5 @@ +class FetchFeedService + def call(account) + # todo + end +end diff --git a/app/services/follow_remote_user_service.rb b/app/services/follow_remote_user_service.rb new file mode 100644 index 000000000..f3c0e68df --- /dev/null +++ b/app/services/follow_remote_user_service.rb @@ -0,0 +1,60 @@ +class FollowRemoteUserService + include GrapeRouteHelpers::NamedRouteMatcher + + def call(user) + username, domain = user.split('@') + account = Account.where(username: username, domain: domain).first + + return account unless account.nil? + + account = Account.new(username: username, domain: domain) + data = Goldfinger.finger("acct:#{user}") + + account.remote_url = data.link('http://schemas.google.com/g/2010#updates-from').href + account.salmon_url = data.link('salmon').href + account.public_key = magic_key_to_pem(data.link('magic-public-key').href) + account.private_key = nil + + account.secret = SecureRandom.hex + account.verify_token = SecureRandom.hex + + feed = get_feed(account.remote_url) + hubs = feed.xpath('//xmlns:link[@rel="hub"]') + + return false if hubs.empty? || hubs.first.attribute('href').nil? + + account.hub_url = hubs.first.attribute('href').value + account.save! + + subscription = account.subscription(subscription_url(account)) + subscription.subscribe + rescue Goldfinger::Error, HTTP::Error => e + false + end + + private + + def get_feed(url) + response = http_client.get(Addressable::URI.parse(url)) + Nokogiri::XML(response) + end + + def magic_key_to_pem(magic_key) + _, modulus, exponent = magic_key.split('.') + modulus, exponent = [modulus, exponent].map { |n| Base64.urlsafe_decode64(n).bytes.inject(0) { |num, byte| (num << 8) | byte } } + + key = OpenSSL::PKey::RSA.new + key.n = modulus + key.d = exponent + + key.to_pem + end + + def http_client + HTTP + end + + def subscription_url(account) + "https://649841dc.ngrok.io/api#{subscriptions_path(id: account.id)}" + end +end diff --git a/app/services/process_feed_update_service.rb b/app/services/process_feed_update_service.rb new file mode 100644 index 000000000..0585fad7a --- /dev/null +++ b/app/services/process_feed_update_service.rb @@ -0,0 +1,20 @@ +class ProcessFeedUpdateService + def call(body, account) + xml = Nokogiri::XML(body) + + xml.xpath('/xmlns:feed/xmlns:entry').each do |entry| + uri = entry.at_xpath('./xmlns:id').content + status = Status.find_by(uri: uri) + + next unless status.nil? + + status = Status.new + status.account = account + status.uri = uri + status.text = entry.at_xpath('./xmlns:content').content + status.created_at = entry.at_xpath('./xmlns:published').content + status.updated_at = entry.at_xpath('./xmlns:updated').content + status.save! + end + end +end |