forked from mirrors/catstodon
Incoming Salmon requests can be turned into follows and unfollows
This commit is contained in:
parent
fa33750105
commit
ee73d35eea
3 changed files with 49 additions and 13 deletions
|
@ -11,3 +11,9 @@ The core ideals of this project are:
|
||||||
- Ease of deployment. The end-goal of this project is to be distributable as a Docker image.
|
- Ease of deployment. The end-goal of this project is to be distributable as a Docker image.
|
||||||
|
|
||||||
**Current status of the project is early development. Documentation, licensing information &co will be added later**
|
**Current status of the project is early development. Documentation, licensing information &co will be added later**
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
- `LOCAL_DOMAIN` should be the domain/hostname of your instance. This is **absolutely required** as it is used for generating unique IDs for everything federation-related
|
||||||
|
- `LOCAL_HTTPS` set it to `true` if HTTPS works on your website. This is used to generate canonical URLs, which is also important when generating and parsing federation-related IDs
|
||||||
|
- `HUB_URL` should be the URL of the PubsubHubbub service that your instance is going to use. By default it is the open service of Superfeedr
|
||||||
|
|
|
@ -1,35 +1,64 @@
|
||||||
class ProcessInteractionService
|
class ProcessInteractionService
|
||||||
|
include ApplicationHelper
|
||||||
|
|
||||||
def call(envelope, target_account)
|
def call(envelope, target_account)
|
||||||
body = salmon.unpack(envelope)
|
body = salmon.unpack(envelope)
|
||||||
xml = Nokogiri::XML(body)
|
xml = Nokogiri::XML(body)
|
||||||
|
|
||||||
return if !involves_target_account(xml, target_account) || xml.at_xpath('//xmlns:author/xmlns:name').nil? || xml.at_xpath('//xmlns:author/xmlns:uri').nil?
|
return unless involves_target_account?(xml, target_account) && contains_author?(xml)
|
||||||
|
|
||||||
username = xml.at_xpath('//xmlns:author/xmlns:name').content
|
username = xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:name').content
|
||||||
url = xml.at_xpath('//xmlns:author/xmlns:uri').content
|
url = xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:uri').content
|
||||||
domain = Addressable::URI.parse(url).host
|
domain = Addressable::URI.parse(url).host
|
||||||
account = Account.find_by(username: username, domain: domain)
|
account = Account.find_by(username: username, domain: domain)
|
||||||
|
|
||||||
if account.nil?
|
if account.nil?
|
||||||
account = follow_remote_account_service.("acct:#{username}@#{domain}")
|
account = follow_remote_account_service.("acct:#{username}@#{domain}")
|
||||||
|
return if account.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
if salmon.verify(envelope, account.keypair)
|
if salmon.verify(envelope, account.keypair)
|
||||||
verb = xml.at_path('//activity:verb').content
|
case get_verb(xml)
|
||||||
|
when :follow
|
||||||
case verb
|
|
||||||
when 'http://activitystrea.ms/schema/1.0/follow', 'follow'
|
|
||||||
account.follow!(target_account)
|
account.follow!(target_account)
|
||||||
when 'http://activitystrea.ms/schema/1.0/unfollow', 'unfollow'
|
when :unfollow
|
||||||
account.unfollow!(target_account)
|
account.unfollow!(target_account)
|
||||||
|
when :favorite
|
||||||
|
# todo: a favourite
|
||||||
|
when :post
|
||||||
|
# todo: a reply
|
||||||
|
when :share
|
||||||
|
# todo: a reblog
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def involves_target_account(target_account)
|
def contains_author?(xml)
|
||||||
# todo
|
!(xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:name').nil? || xml.at_xpath('/xmlns:entry/xmlns:author/xmlns:uri').nil?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def involves_target_account?(xml, account)
|
||||||
|
targeted_at_account?(xml, account) || mentions_account?(xml, account)
|
||||||
|
end
|
||||||
|
|
||||||
|
def targeted_at_account?(xml, account)
|
||||||
|
target_id = xml.at_xpath('/xmlns:entry/activity:object/xmlns:id')
|
||||||
|
!target_id.nil? && target_id.content == profile_url(name: account.username)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mentions_account?(xml, account)
|
||||||
|
xml.xpath('/xmlns:entry/xmlns:link[@rel="mentioned"]').each do |mention_link|
|
||||||
|
return true if mention_link.attribute('ref') == profile_url(name: account.username)
|
||||||
|
end
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_verb(xml)
|
||||||
|
verb = xml.at_xpath('//activity:verb').content.gsub 'http://activitystrea.ms/schema/1.0/', ''
|
||||||
|
verb.to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
def salmon
|
def salmon
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
LOCAL_DOMAIN = ENV['LOCAL_DOMAIN'] || 'localhost'
|
LOCAL_DOMAIN = ENV['LOCAL_DOMAIN'] || 'localhost'
|
||||||
HUB_URL = ENV['HUB_URL'] || 'https://pubsubhubbub.superfeedr.com'
|
HUB_URL = ENV['HUB_URL'] || 'https://pubsubhubbub.superfeedr.com'
|
||||||
|
CANONICAL_PROTOCOL = ENV['LOCAL_HTTPS'] == 'true' ? 'https://' : 'http://'
|
||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
config.action_mailer.default_url_options = { host: LOCAL_DOMAIN }
|
config.action_mailer.default_url_options = { host: LOCAL_DOMAIN, protocol: CANONICAL_PROTOCOL }
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue