diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 9a1f93df..6db39fb4 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -1,21 +1,26 @@ +# frozen_string_literal: true class Attachment < ApplicationRecord belongs_to :attachable, polymorphic: true has_attached_file :file, - styles: lambda { |a| - a.instance.is_image? ? { - small: 'x200>', - medium: 'x300>', - large: 'x400>' - } : {} - } + styles: lambda { |a| + if a.instance.image? + { + small: 'x200>', + medium: 'x300>', + large: 'x400>' + } + else + {} + end + } - validates_attachment_content_type :file, :content_type => [ - /\Aimage\/.*\Z/, - /\Avideo\/.*\Z/ + validates_attachment_content_type :file, content_type: [ + %r{\Aimage/.*\Z}, + %r{\Avideo/.*\Z} ] - def is_image? - file.instance.file_content_type =~ %r(image) + def image? + file.instance.file_content_type =~ /image/ end end diff --git a/app/models/topic.rb b/app/models/topic.rb index 56cc0acb..5b628d8b 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -132,16 +132,16 @@ class Topic < ApplicationRecord end def after_updated - attrs = ['name', 'desc', 'link', 'metacode_id', 'permission', 'defer_to_map_id'] - if attrs.any? {|k| changed_attributes.key?(k)} - new = self.attributes.select {|k| attrs.include?(k) } - old = changed_attributes.select {|k| attrs.include?(k) } - meta = new.merge(old) # we are prioritizing the old values, keeping them - meta['changed'] = changed_attributes.keys.select {|k| attrs.include?(k) } + attrs = %w(name desc link metacode_id permission defer_to_map_id) + if attrs.any? { |k| changed_attributes.key?(k) } + new = attributes.select { |k| attrs.include?(k) } + old = changed_attributes.select { |k| attrs.include?(k) } + meta = new.merge(old) # we are prioritizing the old values, keeping them + meta['changed'] = changed_attributes.keys.select { |k| attrs.include?(k) } Events::TopicUpdated.publish!(self, user, meta) - maps.each {|map| + maps.each do |map| ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicUpdated', id: id - } + end end end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 30160444..381bca7b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -30,6 +30,6 @@ Rails.application.configure do config.assets.debug = false config.assets.quiet = true - # S3 file storage - config.paperclip_defaults = {} # store on local machine for dev + # S3 file storage + config.paperclip_defaults = {} # store on local machine for dev end diff --git a/config/initializers/rack-attack.rb b/config/initializers/rack-attack.rb deleted file mode 100644 index 0fd76889..00000000 --- a/config/initializers/rack-attack.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true -class Rack::Attack - Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new - - # Throttle all requests by IP (60rpm) - # - # Key: "rack::attack:#{Time.now.to_i/:period}:req/ip:#{req.ip}" - # throttle('req/ip', :limit => 300, :period => 5.minutes) do |req| - # req.ip # unless req.path.start_with?('/assets') - # end - - # Throttle POST requests to /login by IP address - # - # Key: "rack::attack:#{Time.now.to_i/:period}:logins/ip:#{req.ip}" - throttle('logins/ip', limit: 5, period: 20.seconds) do |req| - req.ip if req.path == '/login' && req.post? - end - - # Throttle POST requests to /login by email param - # - # Key: "rack::attack:#{Time.now.to_i/:period}:logins/email:#{req.email}" - # - # Note: This creates a problem where a malicious user could intentionally - # throttle logins for another user and force their login requests to be - # denied, but that's not very common and shouldn't happen to you. (Knock - # on wood!) - throttle('logins/email', limit: 5, period: 20.seconds) do |req| - if req.path == '/login' && req.post? - # return the email if present, nil otherwise - req.params['email'].presence - end - end - - throttle('load_url_title/req/5mins/ip', limit: 300, period: 5.minutes) do |req| - req.ip if req.path == 'hacks/load_url_title' - end - throttle('load_url_title/req/1s/ip', limit: 5, period: 1.second) do |req| - # If the return value is truthy, the cache key for the return value - # is incremented and compared with the limit. In this case: - # "rack::attack:#{Time.now.to_i/1.second}:load_url_title/req/ip:#{req.ip}" - # - # If falsy, the cache key is neither incremented nor checked. - - req.ip if req.path == 'hacks/load_url_title' - end - - self.throttled_response = lambda do |env| - now = Time.now - match_data = env['rack.attack.match_data'] - period = match_data[:period] - limit = match_data[:limit] - - headers = { - 'X-RateLimit-Limit' => limit.to_s, - 'X-RateLimit-Remaining' => '0', - 'X-RateLimit-Reset' => (now + (period - now.to_i % period)).to_s - } - - [429, headers, ['']] - end -end diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb new file mode 100644 index 00000000..b79f0d10 --- /dev/null +++ b/config/initializers/rack_attack.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true +module Rack + class Attack + Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new + + # Throttle all requests by IP (60rpm) + # + # Key: "rack::attack:#{Time.now.to_i/:period}:req/ip:#{req.ip}" + # throttle('req/ip', :limit => 300, :period => 5.minutes) do |req| + # req.ip # unless req.path.start_with?('/assets') + # end + + # Throttle POST requests to /login by IP address + # + # Key: "rack::attack:#{Time.now.to_i/:period}:logins/ip:#{req.ip}" + throttle('logins/ip', limit: 5, period: 20.seconds) do |req| + req.ip if req.path == '/login' && req.post? + end + + # Throttle POST requests to /login by email param + # + # Key: "rack::attack:#{Time.now.to_i/:period}:logins/email:#{req.email}" + # + # Note: This creates a problem where a malicious user could intentionally + # throttle logins for another user and force their login requests to be + # denied, but that's not very common and shouldn't happen to you. (Knock + # on wood!) + throttle('logins/email', limit: 5, period: 20.seconds) do |req| + if req.path == '/login' && req.post? + # return the email if present, nil otherwise + req.params['email'].presence + end + end + + throttle('load_url_title/req/5mins/ip', limit: 300, period: 5.minutes) do |req| + req.ip if req.path == 'hacks/load_url_title' + end + throttle('load_url_title/req/1s/ip', limit: 5, period: 1.second) do |req| + # If the return value is truthy, the cache key for the return value + # is incremented and compared with the limit. In this case: + # "rack::attack:#{Time.now.to_i/1.second}:load_url_title/req/ip:#{req.ip}" + # + # If falsy, the cache key is neither incremented nor checked. + + req.ip if req.path == 'hacks/load_url_title' + end + + self.throttled_response = lambda do |env| + now = Time.zone.now + match_data = env['rack.attack.match_data'] + period = match_data[:period] + limit = match_data[:limit] + + headers = { + 'X-RateLimit-Limit' => limit.to_s, + 'X-RateLimit-Remaining' => '0', + 'X-RateLimit-Reset' => (now + (period - now.to_i % period)).to_s + } + + [429, headers, ['']] + end + end +end diff --git a/config/initializers/warden_hooks.rb b/config/initializers/warden_hooks.rb index da983955..a0d8fd88 100644 --- a/config/initializers/warden_hooks.rb +++ b/config/initializers/warden_hooks.rb @@ -1,9 +1,10 @@ -Warden::Manager.after_set_user do |user,auth,opts| +# frozen_string_literal: true +Warden::Manager.after_set_user do |user, auth, opts| scope = opts[:scope] auth.cookies.signed["#{scope}.id"] = user.id auth.cookies.signed["#{scope}.expires_at"] = 30.minutes.from_now end -Warden::Manager.before_logout do |user, auth, opts| +Warden::Manager.before_logout do |_user, auth, opts| scope = opts[:scope] auth.cookies.signed["#{scope}.id"] = nil auth.cookies.signed["#{scope}.expires_at"] = nil