From ebc01bf0f61e58648ea7bfd4c915b4f373761e1d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 5 Mar 2017 23:03:49 +0100 Subject: Make the paperclip filename interpolator smarter about the :original style If an :original gets converted into another format, it would get saved as original_filename *anyway*, so generating the extension is pointless and yields bad results for when you change the style definition later. This way, old gifs will still have correct URLs --- config/initializers/paperclip.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'config/initializers') diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb index 71a7b514e..580a3196e 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -2,6 +2,11 @@ Paperclip.options[:read_timeout] = 60 +Paperclip.interpolates :filename do |attachment, style| + return attachment.original_filename if style == :original + [basename(attachment, style), extension(attachment, style)].delete_if(&:empty?).join('.') +end + if ENV['S3_ENABLED'] == 'true' Aws.eager_autoload!(services: %w(S3)) -- cgit From 1fb3e8988b017155a9c23f19afa162b58e11590d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 6 Mar 2017 02:25:41 +0100 Subject: Revert earlier fix due to new bug reports --- app/controllers/api_controller.rb | 10 +++++----- config/initializers/rabl_init.rb | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'config/initializers') diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index c43011754..db16f82e5 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -102,14 +102,14 @@ class ApiController < ApplicationController def set_counters_maps(statuses) # rubocop:disable Style/AccessorMethodName status_ids = statuses.compact.map { |s| s.reblog? ? s.reblog_of_id : s.id }.uniq - @favourites_counts_map = Favourite.select('status_id, COUNT(*) AS favourites_count').group('status_id').where(status_id: status_ids).map { |f| [f.status_id, f.favourites_count] }.to_h - @reblogs_counts_map = Status.select('statuses.id, COUNT(*) AS reblogs_count').joins('LEFT OUTER JOIN statuses AS reblogs ON statuses.id = reblogs.reblog_of_id').where(id: status_ids).group('statuses.id').map { |r| [r.id, r.reblogs_count] }.to_h + @favourites_counts_map = Favourite.select('status_id, COUNT(id) AS favourites_count').group('status_id').where(status_id: status_ids).map { |f| [f.status_id, f.favourites_count] }.to_h + @reblogs_counts_map = Status.select('statuses.id, COUNT(reblogs.id) AS reblogs_count').joins('LEFT OUTER JOIN statuses AS reblogs ON statuses.id = reblogs.reblog_of_id').where(id: status_ids).group('statuses.id').map { |r| [r.id, r.reblogs_count] }.to_h end def set_account_counters_maps(accounts) # rubocop:disable Style/AccessorMethodName account_ids = accounts.compact.map(&:id).uniq - @followers_counts_map = Follow.unscoped.select('target_account_id, COUNT(*) AS followers_count').group('target_account_id').where(target_account_id: account_ids).map { |f| [f.target_account_id, f.followers_count] }.to_h - @following_counts_map = Follow.unscoped.select('account_id, COUNT(*) AS following_count').group('account_id').where(account_id: account_ids).map { |f| [f.account_id, f.following_count] }.to_h - @statuses_counts_map = Status.unscoped.select('account_id, COUNT(*) AS statuses_count').group('account_id').where(account_id: account_ids).map { |s| [s.account_id, s.statuses_count] }.to_h + @followers_counts_map = Follow.unscoped.select('target_account_id, COUNT(account_id) AS followers_count').group('target_account_id').where(target_account_id: account_ids).map { |f| [f.target_account_id, f.followers_count] }.to_h + @following_counts_map = Follow.unscoped.select('account_id, COUNT(target_account_id) AS following_count').group('account_id').where(account_id: account_ids).map { |f| [f.account_id, f.following_count] }.to_h + @statuses_counts_map = Status.unscoped.select('account_id, COUNT(id) AS statuses_count').group('account_id').where(account_id: account_ids).map { |s| [s.account_id, s.statuses_count] }.to_h end end diff --git a/config/initializers/rabl_init.rb b/config/initializers/rabl_init.rb index 325bf0c78..f7be0c607 100644 --- a/config/initializers/rabl_init.rb +++ b/config/initializers/rabl_init.rb @@ -1,6 +1,6 @@ Rabl.configure do |config| config.cache_all_output = false - config.cache_sources = !!Rails.env.production? + config.cache_sources = Rails.env.production? config.include_json_root = false config.view_paths = [Rails.root.join('app/views')] end -- cgit From 02349b32696d6559ed64dbe4f401892d5fa5ddf7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 14 Mar 2017 15:59:21 +0100 Subject: Obfuscate filenames better, double rate limits --- app/controllers/concerns/obfuscate_filename.rb | 6 +++++- config/initializers/rack-attack.rb | 4 ++-- docs/Using-the-API/Push-notifications.md | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'config/initializers') diff --git a/app/controllers/concerns/obfuscate_filename.rb b/app/controllers/concerns/obfuscate_filename.rb index dde7ce8c6..9c896fb09 100644 --- a/app/controllers/concerns/obfuscate_filename.rb +++ b/app/controllers/concerns/obfuscate_filename.rb @@ -13,6 +13,10 @@ module ObfuscateFilename file = params.dig(*path) return if file.nil? - file.original_filename = 'media' + File.extname(file.original_filename) + file.original_filename = secure_token + File.extname(file.original_filename) + end + + def secure_token(length = 16) + SecureRandom.hex(length / 2) end end diff --git a/config/initializers/rack-attack.rb b/config/initializers/rack-attack.rb index 3f0ee1d7a..70f7846d1 100644 --- a/config/initializers/rack-attack.rb +++ b/config/initializers/rack-attack.rb @@ -1,6 +1,6 @@ class Rack::Attack # Rate limits for the API - throttle('api', limit: 150, period: 5.minutes) do |req| + throttle('api', limit: 300, period: 5.minutes) do |req| req.ip if req.path.match(/\A\/api\/v/) end @@ -11,7 +11,7 @@ class Rack::Attack headers = { 'X-RateLimit-Limit' => match_data[:limit].to_s, 'X-RateLimit-Remaining' => '0', - 'X-RateLimit-Reset' => (now + (match_data[:period] - now.to_i % match_data[:period])).iso8601(6) + 'X-RateLimit-Reset' => (now + (match_data[:period] - now.to_i % match_data[:period])).iso8601(6), } [429, headers, [{ error: 'Throttled' }.to_json]] diff --git a/docs/Using-the-API/Push-notifications.md b/docs/Using-the-API/Push-notifications.md index d98c8833a..fc373e723 100644 --- a/docs/Using-the-API/Push-notifications.md +++ b/docs/Using-the-API/Push-notifications.md @@ -1,4 +1,4 @@ Push notifications ================== -**Note: This push notification design turned out to not be fully operational on the side of Firebase. A different approach is in consideration** +See for an example of how to create push notifications for a mobile app. It involves using the Mastodon streaming API on behalf of the app's users, as a sort of proxy. -- cgit