Skip to content

Commit

Permalink
port tootsuite#11292 to monsterfork: Add whitelist mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Gargron authored and multiple creatures committed Feb 21, 2020
1 parent 08f6b74 commit b4d97bc
Show file tree
Hide file tree
Showing 43 changed files with 304 additions and 62 deletions.
5 changes: 5 additions & 0 deletions app/controllers/about_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class AboutController < ApplicationController
before_action :set_pack
layout 'public'

before_action :require_open_federation!, only: [:show, :more]
before_action :set_body_classes, only: :show
before_action :set_instance_presenter
before_action :set_expires_in
Expand All @@ -20,6 +21,10 @@ def terms; end

private

def require_open_federation!
not_found if whitelist_mode?
end

def new_user
User.new.tap do |user|
user.build_account
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/activitypub/base_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class ActivityPub::BaseController < Api::BaseController
skip_before_action :require_authenticated_user!

private

def set_cache_headers
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/activitypub/inboxes_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

class ActivityPub::InboxesController < Api::BaseController
class ActivityPub::InboxesController < ActivityPub::BaseController
include SignatureVerification
include JsonLdHelper
include AccountOwnedConcern
Expand Down
40 changes: 40 additions & 0 deletions app/controllers/admin/domain_allows_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

class Admin::DomainAllowsController < Admin::BaseController
before_action :set_domain_allow, only: [:destroy]

def new
authorize :domain_allow, :create?

@domain_allow = DomainAllow.new(domain: params[:_domain])
end

def create
authorize :domain_allow, :create?

@domain_allow = DomainAllow.new(resource_params)

if @domain_allow.save
log_action :create, @domain_allow
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.created_msg')
else
render :new
end
end

def destroy
authorize @domain_allow, :destroy?
UnallowDomainService.new.call(@domain_allow)
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
end

private

def set_domain_allow
@domain_allow = DomainAllow.find(params[:id])
end

def resource_params
params.require(:domain_allow).permit(:domain)
end
end
27 changes: 25 additions & 2 deletions app/controllers/admin/instances_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

module Admin
class InstancesController < BaseController
before_action :set_domain_block, only: :show
before_action :set_domain_allow, only: :show
before_action :set_instance, only: :show

def index
authorize :instance, :index?

Expand All @@ -11,7 +15,6 @@ def index
def show
authorize :instance, :show?

@instance = Instance.new(Account.by_domain_accounts.find_by(domain: params[:id]) || DomainBlock.find_by!(domain: params[:id]))
@following_count = Follow.where(account: Account.where(domain: params[:id])).count
@followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count
@reports_count = Report.where(target_account: Account.where(domain: params[:id])).count
Expand All @@ -23,8 +26,28 @@ def show

private

def set_domain_block
@domain_block = DomainBlock.rule_for(params[:id])
end

def set_domain_allow
@domain_allow = DomainAllow.rule_for(params[:id])
end

def set_instance
resource = Account.by_domain_accounts.find_by(domain: params[:id])
resource ||= @domain_block
resource ||= @domain_allow

if resource
@instance = Instance.new(resource)
else
not_found
end
end

def filtered_instances
InstanceFilter.new(filter_params).results
InstanceFilter.new(whitelist_mode? ? { allowed: true } : filter_params).results
end

def paginated_instances
Expand Down
9 changes: 9 additions & 0 deletions app/controllers/api/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Api::BaseController < ApplicationController
skip_before_action :store_current_location
skip_before_action :require_functional!

before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access?
before_action :set_cache_headers

protect_from_forgery with: :null_session
Expand Down Expand Up @@ -83,6 +84,10 @@ def current_user
nil
end

def require_authenticated_user!
render json: { error: 'This API requires an authenticated user' }, status: 401 unless current_user
end

def require_user!
if !current_user
render json: { error: 'This method requires an authenticated user' }, status: 422
Expand All @@ -108,4 +113,8 @@ def authorize_if_got_token!(*scopes)
def set_cache_headers
response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
end

def disallow_unauthenticated_api_access?
authorized_fetch_mode?
end
end
2 changes: 2 additions & 0 deletions app/controllers/api/v1/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class Api::V1::AccountsController < Api::BaseController
before_action :check_account_suspension, only: [:show]
before_action :check_enabled_registrations, only: [:create]

skip_before_action :require_authenticated_user!, only: :create

respond_to :json

def show
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/api/v1/apps_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class Api::V1::AppsController < Api::BaseController
skip_before_action :require_authenticated_user!

def create
@app = Doorkeeper::Application.create!(application_options)
render json: @app, serializer: REST::ApplicationSerializer, monsterfork_api: monsterfork_api
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/api/v1/instances/activity_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class Api::V1::Instances::ActivityController < Api::BaseController
before_action :require_enabled_api!

skip_before_action :set_cache_headers
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?

Expand Down Expand Up @@ -34,6 +35,6 @@ def activity
end

def require_enabled_api!
head 404 unless Setting.activity_api_enabled
head 404 unless Setting.activity_api_enabled && !whitelist_mode?
end
end
3 changes: 2 additions & 1 deletion app/controllers/api/v1/instances/peers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class Api::V1::Instances::PeersController < Api::BaseController
before_action :require_enabled_api!

skip_before_action :set_cache_headers
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?

Expand All @@ -20,6 +21,6 @@ def actively_federated_domains
end

def require_enabled_api!
head 404 unless Setting.peers_api_enabled
head 404 unless Setting.peers_api_enabled && !whitelist_mode?
end
end
1 change: 1 addition & 0 deletions app/controllers/api/v1/instances_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class Api::V1::InstancesController < Api::BaseController
respond_to :json

skip_before_action :set_cache_headers
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?

Expand Down
4 changes: 3 additions & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ class ApplicationController < ActionController::Base
include UserTrackingConcern
include SessionTrackingConcern
include CacheConcern
include DomainControlHelper

helper_method :current_account
helper_method :current_session
helper_method :current_flavour
helper_method :current_skin
helper_method :single_user_mode?
helper_method :use_seamless_external_login?
helper_method :whitelist_mode?

rescue_from ActionController::RoutingError, with: :not_found
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
Expand Down Expand Up @@ -45,7 +47,7 @@ def https_enabled?
end

def authorized_fetch_mode?
ENV['AUTHORIZED_FETCH'] == 'true' || Setting.auto_reject_unknown
ENV['AUTHORIZED_FETCH'] == 'true' || Setting.auto_reject_unknown || Rails.configuration.x.whitelist_mode
end

def public_fetch_mode?
Expand Down
1 change: 1 addition & 0 deletions app/controllers/concerns/account_owned_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module AccountOwnedConcern
extend ActiveSupport::Concern

included do
before_action :authenticate_user!, if: -> { whitelist_mode? && request.format != :json }
before_action :set_account, if: :account_required?
before_action :check_account_approval, if: :account_required?
before_action :check_account_suspension, if: :account_required?
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/directories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
class DirectoriesController < ApplicationController
layout 'public'

before_action :check_enabled
before_action :authenticate_user!, if: :whitelist_mode?
before_action :require_enabled!
before_action :set_instance_presenter
before_action :set_tag, only: :show
before_action :set_tags
Expand All @@ -26,7 +27,7 @@ def set_pack
use_pack 'share'
end

def check_enabled
def require_enabled!
return not_found unless Setting.profile_directory
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def initial_state_params
end

def default_redirect_path
if request.path.start_with?('/web')
if request.path.start_with?('/web') || whitelist_mode?
new_user_session_path
elsif single_user_mode?
short_account_path(Account.local.without_suspended.where('id > 0').first)
Expand Down
1 change: 1 addition & 0 deletions app/controllers/media_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class MediaController < ApplicationController
skip_before_action :store_current_location
skip_before_action :require_functional!

before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_media_attachment
before_action :verify_permitted_status!

Expand Down
2 changes: 2 additions & 0 deletions app/controllers/media_proxy_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class MediaProxyController < ApplicationController
skip_before_action :store_current_location
skip_before_action :require_functional!

before_action :authenticate_user!, if: :whitelist_mode?

def show
RedisLock.acquire(lock_options) do |lock|
if lock.acquired?
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/public_timelines_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ class PublicTimelinesController < ApplicationController
before_action :set_pack
layout 'public'

before_action :check_enabled
before_action :authenticate_user!, if: :whitelist_mode?
before_action :require_enabled!
before_action :set_body_classes
before_action :set_instance_presenter

Expand All @@ -17,7 +18,7 @@ def show

private

def check_enabled
def require_enabled!
not_found unless Setting.timeline_preview
end

Expand Down
4 changes: 3 additions & 1 deletion app/controllers/remote_interaction_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ class RemoteInteractionController < ApplicationController

layout 'modal'

before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_interaction_type
before_action :set_status
before_action :set_body_classes
before_action :set_pack
before_action :set_status

skip_before_action :require_functional!

Expand Down
1 change: 1 addition & 0 deletions app/controllers/tags_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class TagsController < ApplicationController
layout 'public'

before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_tag
before_action :set_body_classes
before_action :set_instance_presenter
Expand Down
10 changes: 9 additions & 1 deletion app/helpers/domain_control_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ def domain_not_allowed?(uri_or_domain)
end
end

DomainBlock.blocked?(domain)
if whitelist_mode?
!DomainAllow.allowed?(domain)
else
DomainBlock.blocked?(domain)
end
end

def whitelist_mode?
Rails.configuration.x.whitelist_mode
end
end
33 changes: 33 additions & 0 deletions app/models/domain_allow.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

# == Schema Information
#
# Table name: domain_allows
#
# id :bigint(8) not null, primary key
# domain :string default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
#

class DomainAllow < ApplicationRecord
include DomainNormalizable

validates :domain, presence: true, uniqueness: true

scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }

class << self
def allowed?(domain)
!rule_for(domain).nil?
end

def rule_for(domain)
return if domain.blank?

uri = Addressable::URI.new.tap { |u| u.host = domain.gsub(/[\/]/, '') }

find_by(domain: uri.normalized_host)
end
end
end
5 changes: 3 additions & 2 deletions app/models/instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ class Instance

def initialize(resource)
@domain = resource.domain
@accounts_count = resource.is_a?(DomainBlock) ? nil : resource.accounts_count
@domain_block = resource.is_a?(DomainBlock) ? resource : DomainBlock.find_by(domain: domain)
@accounts_count = resource.respond_to?(:accounts_count) ? resource.accounts_count : nil
@domain_block = resource.is_a?(DomainBlock) ? resource : DomainBlock.rule_for(domain)
@domain_allow = resource.is_a?(DomainAllow) ? resource : DomainAllow.rule_for(domain)
@updated_at = resource.is_a?(DomainBlock) ? resource.updated_at : 0
end

Expand Down
Loading

0 comments on commit b4d97bc

Please sign in to comment.