This commit is contained in:
James 2017-04-04 09:33:28 +00:00 committed by GitHub
commit d984addfb4
12 changed files with 92 additions and 7 deletions

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class Admin::DomainWhitelistController < ApplicationController
before_action :require_admin!
layout 'admin'
def index
@unblocks = DomainWhitelist.paginate(page: params[:page], per_page: 40)
end
def create
end
end

View File

@ -0,0 +1,4 @@
# frozen_string_literal: true
module Admin::DomainWhitelistHelper
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
class DomainWhitelist < ApplicationRecord
enum severity: [:silence, :enable]
def self.enabled?
return Setting.where(var: 'whitelist_enabled').first_or_initialize(var: 'whitelist_enabled', value: false)
end
validates :domain, presence: true, uniqueness: true
def self.blocked?(domain)
!where(domain: domain).exists?
end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
class AllowDomainService < BaseService
def call(domain)
if DomainWhitelist.enabled?
domain = DomainWhitelist.where(domain: domain).first
if domain.nil?
return :suspend
end
return domain.severity
else
domain = DomainBlock.where(domain: domain).first
if domain.nil?
return :enable
end
return domain.severity
end
end
def blocked?(domain)
return self.call(domain) == :suspend
end
def reject_media?(domain)
record_type = if DomainWhitelist.enabled? then DomainWhitelist else DomainBlock end
return record_type.find_by(domain: domain)&.reject_media?
end
end

View File

@ -35,15 +35,15 @@ class FollowRemoteAccountService < BaseService
Rails.logger.debug "Creating new remote account for #{uri}"
domain_block = DomainBlock.find_by(domain: domain)
allow_domain_service = AllowDomainService.new
account.remote_url = data.link('http://schemas.google.com/g/2010#updates-from').href
account.salmon_url = data.link('salmon').href
account.url = data.link('http://webfinger.net/rel/profile-page').href
account.public_key = magic_key_to_pem(data.link('magic-public-key').href)
account.private_key = nil
account.suspended = true if domain_block && domain_block.suspend?
account.silenced = true if domain_block && domain_block.silence?
account.suspended = allow_domain_service.call(domain) == :suspend
account.silenced = allow_domain_service.call(domain) == :silence
xml = get_feed(account.remote_url)
hubs = get_hubs(xml)

View File

@ -185,7 +185,7 @@ class ProcessFeedService < BaseService
end
def media_from_xml(parent, xml)
return if DomainBlock.find_by(domain: parent.account.domain)&.reject_media?
return if AllowDomainService.new.reject_media?(parent.account.domain)
xml.xpath('./xmlns:link[@rel="enclosure"]', xmlns: TagManager::XMLNS).each do |link|
next unless link['href']

View File

@ -4,7 +4,7 @@ class Pubsubhubbub::SubscribeService < BaseService
def call(account, callback, secret, lease_seconds)
return ['Invalid topic URL', 422] if account.nil?
return ['Invalid callback URL', 422] unless !callback.blank? && callback =~ /\A#{URI.regexp(%w(http https))}\z/
return ['Callback URL not allowed', 403] if DomainBlock.blocked?(Addressable::URI.parse(callback).host)
return ['Callback URL not allowed', 403] if AllowDomainService.new.blocked?(Addressable::URI.parse(callback).host)
subscription = Subscription.where(account: account, callback_url: callback).first_or_create!(account: account, callback_url: callback)
Pubsubhubbub::ConfirmationWorker.perform_async(subscription.id, 'subscribe', secret, lease_seconds)

View File

@ -12,7 +12,7 @@ class UpdateRemoteProfileService < BaseService
account.note = author_xml.at_xpath('./poco:note', poco: TagManager::POCO_XMLNS).content unless author_xml.at_xpath('./poco:note', poco: TagManager::POCO_XMLNS).nil?
account.locked = author_xml.at_xpath('./mastodon:scope', mastodon: TagManager::MTDN_XMLNS)&.content == 'private'
unless account.suspended? || DomainBlock.find_by(domain: account.domain)&.reject_media?
unless account.suspended? || AllowDomainService.new.reject_media?(account.domain)
account.avatar_remote_url = author_xml.at_xpath('./xmlns:link[@rel="avatar"]', xmlns: TagManager::XMLNS)['href'] unless author_xml.at_xpath('./xmlns:link[@rel="avatar"]', xmlns: TagManager::XMLNS).nil? || author_xml.at_xpath('./xmlns:link[@rel="avatar"]', xmlns: TagManager::XMLNS)['href'].blank?
account.header_remote_url = author_xml.at_xpath('./xmlns:link[@rel="header"]', xmlns: TagManager::XMLNS)['href'] unless author_xml.at_xpath('./xmlns:link[@rel="header"]', xmlns: TagManager::XMLNS).nil? || author_xml.at_xpath('./xmlns:link[@rel="header"]', xmlns: TagManager::XMLNS)['href'].blank?
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class WhitelistDomainService < BaseService
def call(domain, severity)
DomainWhitelist.where(domain: domain).first_or_create!(domain: domain, severity: severity)
if severity == :silence
Account.where(domain: domain).update_all(silenced: true)
end
end
end

View File

@ -17,7 +17,7 @@ class Pubsubhubbub::DistributionWorker
Subscription.where(account: account).active.select('id, callback_url').find_each do |subscription|
host = Addressable::URI.parse(subscription.callback_url).host
next if DomainBlock.blocked?(host) # || !domains.include?(host)
next if AllowDomainService.new.blocked?(host) # || !domains.include?(host)
Pubsubhubbub::DeliveryWorker.perform_async(subscription.id, payload)
end
rescue ActiveRecord::RecordNotFound

View File

@ -15,6 +15,7 @@ defaults: &defaults
interactions:
must_be_follower: false
must_be_following: false
whitelist_enabled: false
development:
<<: *defaults

View File

@ -0,0 +1,12 @@
class AddWhitelists < ActiveRecord::Migration[5.0]
def change
create_table :domain_whitelists do |t|
t.string :domain, null: false, default: ''
t.integer :severity, default: 0
t.boolean :reject_media
t.timestamps
end
add_index :domain_whitelists, :domain, unique: true
end
end