diff options
author | Starfall <root@starfall.blue> | 2020-04-11 20:04:56 -0500 |
---|---|---|
committer | Starfall <root@starfall.blue> | 2020-04-11 20:04:56 -0500 |
commit | b107e4f771f036b214563764fcd95786f8016ee7 (patch) | |
tree | 22397105f42f30eceacdf84671d1c4d807c9dd73 /app/lib | |
parent | 144ecfcfc7d9974117f1563084409a9558290a60 (diff) | |
parent | c47be5bd864a1f5244f35122ba7fae31a149c73d (diff) |
Merge branch 'glitch'
Diffstat (limited to 'app/lib')
-rw-r--r-- | app/lib/activitypub/tag_manager.rb | 2 | ||||
-rw-r--r-- | app/lib/entity_cache.rb | 4 | ||||
-rw-r--r-- | app/lib/exceptions.rb | 1 | ||||
-rw-r--r-- | app/lib/formatter.rb | 8 | ||||
-rw-r--r-- | app/lib/language_detector.rb | 4 | ||||
-rw-r--r-- | app/lib/rate_limiter.rb | 64 | ||||
-rw-r--r-- | app/lib/sanitize_config.rb | 14 |
7 files changed, 91 insertions, 6 deletions
diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index ed680d762..1523f86d4 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -15,6 +15,8 @@ class ActivityPub::TagManager def url_for(target) return target.url if target.respond_to?(:local?) && !target.local? + return unless target.respond_to?(:object_type) + case target.object_type when :person target.instance_actor? ? about_more_url(instance_actor: true) : short_account_url(target) diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb index 35a3773d2..afdbd70f2 100644 --- a/app/lib/entity_cache.rb +++ b/app/lib/entity_cache.rb @@ -7,6 +7,10 @@ class EntityCache MAX_EXPIRATION = 7.days.freeze + def status(url) + Rails.cache.fetch(to_key(:status, url), expires_in: MAX_EXPIRATION) { FetchRemoteStatusService.new.call(url) } + end + def mention(username, domain) Rails.cache.fetch(to_key(:mention, username, domain), expires_in: MAX_EXPIRATION) { Account.select(:id, :username, :domain, :url).find_remote(username, domain) } end diff --git a/app/lib/exceptions.rb b/app/lib/exceptions.rb index 01346bfe5..3362576b0 100644 --- a/app/lib/exceptions.rb +++ b/app/lib/exceptions.rb @@ -8,6 +8,7 @@ module Mastodon class LengthValidationError < ValidationError; end class DimensionsValidationError < ValidationError; end class RaceConditionError < Error; end + class RateLimitExceededError < Error; end class UnexpectedResponseError < Error def initialize(response = nil) diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index fcc99d009..051f27408 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -59,7 +59,7 @@ class Formatter html = "RT @#{prepend_reblog} #{html}" if prepend_reblog html = format_markdown(html) if status.content_type == 'text/markdown' html = encode_and_link_urls(html, linkable_accounts, keep_html: %w(text/markdown text/html).include?(status.content_type)) - html = reformat(html) if %w(text/markdown text/html).include?(status.content_type) + html = reformat(html, true) if %w(text/markdown text/html).include?(status.content_type) html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify] unless %w(text/markdown text/html).include?(status.content_type) @@ -75,8 +75,8 @@ class Formatter html.delete("\r").delete("\n") end - def reformat(html) - sanitize(html, Sanitize::Config::MASTODON_STRICT) + def reformat(html, outgoing = false) + sanitize(html, Sanitize::Config::MASTODON_STRICT.merge(outgoing: outgoing)) rescue ArgumentError '' end @@ -131,7 +131,7 @@ class Formatter end def link_url(url) - "<a href=\"#{encode(url)}\" target=\"blank\" rel=\"nofollow noopener\">#{link_html(url)}</a>" + "<a href=\"#{encode(url)}\" target=\"blank\" rel=\"nofollow noopener noreferrer\">#{link_html(url)}</a>" end private diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb index 302072bcc..05a06726d 100644 --- a/app/lib/language_detector.rb +++ b/app/lib/language_detector.rb @@ -52,8 +52,10 @@ class LanguageDetector def detect_language_code(text) return if unreliable_input?(text) + result = @identifier.find_language(text) - iso6391(result.language.to_s).to_sym if result.reliable? + + iso6391(result.language.to_s).to_sym if result&.reliable? end def iso6391(bcp47) diff --git a/app/lib/rate_limiter.rb b/app/lib/rate_limiter.rb new file mode 100644 index 000000000..0e2c9a894 --- /dev/null +++ b/app/lib/rate_limiter.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +class RateLimiter + include Redisable + + FAMILIES = { + follows: { + limit: 400, + period: 24.hours.freeze, + }.freeze, + + statuses: { + limit: 300, + period: 3.hours.freeze, + }.freeze, + + reports: { + limit: 400, + period: 24.hours.freeze, + }.freeze, + }.freeze + + def initialize(by, options = {}) + @by = by + @family = options[:family] + @limit = FAMILIES[@family][:limit] + @period = FAMILIES[@family][:period].to_i + end + + def record! + count = redis.get(key) + + if count.nil? + redis.set(key, 0) + redis.expire(key, (@period - (last_epoch_time % @period) + 1).to_i) + end + + raise Mastodon::RateLimitExceededError if count.present? && count.to_i >= @limit + + redis.incr(key) + end + + def rollback! + redis.decr(key) + end + + def to_headers(now = Time.now.utc) + { + 'X-RateLimit-Limit' => @limit.to_s, + 'X-RateLimit-Remaining' => (@limit - (redis.get(key) || 0).to_i).to_s, + 'X-RateLimit-Reset' => (now + (@period - now.to_i % @period)).iso8601(6), + } + end + + private + + def key + @key ||= "rate_limit:#{@by.id}:#{@family}:#{(last_epoch_time / @period).to_i}" + end + + def last_epoch_time + @last_epoch_time ||= Time.now.to_i + end +end diff --git a/app/lib/sanitize_config.rb b/app/lib/sanitize_config.rb index e3fc94ba6..34793ed93 100644 --- a/app/lib/sanitize_config.rb +++ b/app/lib/sanitize_config.rb @@ -54,6 +54,18 @@ class Sanitize end end + LINK_REL_TRANSFORMER = lambda do |env| + return unless env[:node_name] == 'a' + + node = env[:node] + + rel = (node['rel'] || '').split(' ') & ['tag'] + unless env[:config][:outgoing] && TagManager.instance.local_url?(node['href']) + rel += ['nofollow', 'noopener', 'noreferrer'] + end + node['rel'] = rel.join(' ') + end + UNSUPPORTED_HREF_TRANSFORMER = lambda do |env| return unless env[:node_name] == 'a' @@ -82,7 +94,6 @@ class Sanitize add_attributes: { 'a' => { - 'rel' => 'nofollow noopener tag noreferrer', 'target' => '_blank', }, }, @@ -96,6 +107,7 @@ class Sanitize CLASS_WHITELIST_TRANSFORMER, IMG_TAG_TRANSFORMER, UNSUPPORTED_HREF_TRANSFORMER, + LINK_REL_TRANSFORMER, ] ) |