From 53d25cba1d874c7b4f2d2a4256d22715204e310e Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Thu, 6 Nov 2014 14:05:34 -0800 Subject: [PATCH 1/2] use style.css for new installs, refactor new install to use store_file --- models/site.rb | 23 ++++++++++++++++++----- tests/acceptance/signup_tests.rb | 6 ++++++ tests/site_file_tests.rb | 4 ++-- views/templates/index.erb | 18 +++++++----------- views/templates/not_found.erb | 6 +----- views/templates/style.css | 5 +++++ 6 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 views/templates/style.css diff --git a/models/site.rb b/models/site.rb index 21db0433..28bcc2e4 100644 --- a/models/site.rb +++ b/models/site.rb @@ -296,12 +296,24 @@ class Site < Sequel::Model FileUtils.mkdir_p files_path %w{index not_found}.each do |name| - File.write files_path("#{name}.html"), render_template("#{name}.erb") + tmpfile = Tempfile.new "newinstall-#{name}" + tmpfile.write render_template("#{name}.erb") + tmpfile.close + + store_file "#{name}.html", tmpfile, new_install: true purge_cache "/#{name}.html" ScreenshotWorker.perform_async values[:username], "#{name}.html" end - FileUtils.cp template_file_path('cat.png'), files_path('cat.png') + tmpfile = Tempfile.new 'style.css' + tmpfile.close + FileUtils.cp template_file_path('style.css'), tmpfile.path + store_file 'style.css', tmpfile, new_install: true + + tmpfile = Tempfile.new 'cat.png' + tmpfile.close + FileUtils.cp template_file_path('cat.png'), tmpfile.path + store_file 'cat.png', tmpfile, new_install: true end def get_file(path) @@ -451,7 +463,7 @@ class Site < Sequel::Model PurgeCacheWorker.perform_async payload end - def store_file(path, uploaded) + def store_file(path, uploaded, opts={}) relative_path = scrubbed_path path path = files_path path @@ -486,7 +498,8 @@ class Site < Sequel::Model end pathname = Pathname(path) - if pathname.basename.to_s == 'index.html' + + if pathname.basename.to_s == 'index.html' && opts[:new_install] != true begin new_title = Nokogiri::HTML(File.read(uploaded.path)).css('title').first.text rescue NoMethodError => e @@ -533,7 +546,7 @@ class Site < Sequel::Model ThumbnailWorker.perform_async values[:username], relative_path end - SiteChange.record self, relative_path + SiteChange.record self, relative_path unless opts[:new_install] true end diff --git a/tests/acceptance/signup_tests.rb b/tests/acceptance/signup_tests.rb index f29eddc6..9eff5628 100644 --- a/tests/acceptance/signup_tests.rb +++ b/tests/acceptance/signup_tests.rb @@ -38,10 +38,16 @@ describe 'signup' do fill_in_valid click_signup_button site_created?.must_equal true + assert_equal( true, File.exist?(File.join(Site::SITE_FILES_ROOT, @site[:username], 'index.html')) ) + + site = Site[username: @site[:username]] + site.site_files.length.must_equal 4 + site.site_changed.must_equal false + site.site_updated_at.must_equal nil end it 'fails to create for existing site' do diff --git a/tests/site_file_tests.rb b/tests/site_file_tests.rb index 76e0a2ed..62ed59ca 100644 --- a/tests/site_file_tests.rb +++ b/tests/site_file_tests.rb @@ -72,8 +72,8 @@ describe 'site_files' do upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/img/test.jpg', 'image/jpeg') last_response.body.must_match /successfully uploaded/i @site.reload.changed_count.must_equal 2 - @site.site_files.count.must_equal 1 - digest.wont_equal @site.reload.site_files.first.sha1_hash + @site.site_files.select {|f| f.path == 'test.jpg'}.length.must_equal 1 + digest.wont_equal @site.site_files_dataset.where(path: 'test.jpg').first.sha1_hash end it 'works with directory path' do diff --git a/views/templates/index.erb b/views/templates/index.erb index d7f350e7..1ffb0b31 100644 --- a/views/templates/index.erb +++ b/views/templates/index.erb @@ -3,16 +3,12 @@ The web site of <%= username %> - + + + +

Welcome to my Website!

@@ -22,7 +18,7 @@

Here's how you can make bold and italic text.

Here's how you can add an image:

- +

Here's how to make a list:

diff --git a/views/templates/not_found.erb b/views/templates/not_found.erb index dc6a06c8..2ed111e2 100644 --- a/views/templates/not_found.erb +++ b/views/templates/not_found.erb @@ -3,11 +3,7 @@ Not Found - +

Page Not Found

diff --git a/views/templates/style.css b/views/templates/style.css new file mode 100644 index 00000000..3cc790dd --- /dev/null +++ b/views/templates/style.css @@ -0,0 +1,5 @@ +body { + background-color: white; + color: black; + font-family: Verdana; +} \ No newline at end of file From 4983a9b24eac00b8d8bfd300a18cdcee0152a271 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Fri, 7 Nov 2014 00:41:10 -0800 Subject: [PATCH 2/2] Cryptographically scramble IPs stored by Neocities "There is a time when the operation of the machine becomes so odious, makes you so sick at heart, that you can't take part; you can't even passively take part, and you've got to put your bodies upon the gears and upon the wheels, upon the levers, upon all the apparatus, and you've got to make it stop. And you've got to indicate to the people who run it, to the people who own it, that unless you're free, the machine will be prevented from working at all." Mario Savio Sproul Hall Steps University of California, Berkeley December 3, 1964 --- Gemfile | 1 + Gemfile.lock | 11 +++++++++-- Rakefile | 9 +++++++++ app.rb | 12 +++++++----- config.yml.template | 2 ++ environment.rb | 2 ++ models/site.rb | 31 ++++++++++++++++++++----------- tests/acceptance/signup_tests.rb | 2 ++ 8 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index f250144a..99ab1cbe 100644 --- a/Gemfile +++ b/Gemfile @@ -24,6 +24,7 @@ gem 'sass', require: nil gem 'dav4rack' gem 'filesize' gem 'thread' +gem 'scrypt' platform :mri do gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic diff --git a/Gemfile.lock b/Gemfile.lock index 436ef6bd..f6d17b97 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,7 +54,10 @@ GEM i18n (~> 0.5) faraday (0.9.0) multipart-post (>= 1.2, < 3) - ffi (1.9.3) + ffi (1.9.6) + ffi-compiler (0.1.3) + ffi (>= 1.0.0) + rake filesize (0.0.3) google-api-client (0.7.1) addressable (>= 2.3.2) @@ -133,7 +136,7 @@ GEM rack (~> 1.1) unicorn (~> 4.8) raindrops (0.13.0) - rake (10.2.1) + rake (10.3.2) redis (3.0.7) redis-namespace (1.4.1) redis (~> 3.0.4) @@ -146,6 +149,9 @@ GEM sass (3.3.8) screencap (0.1.1) phantomjs + scrypt (2.0.0) + ffi-compiler (>= 0.0.2) + rake sequel (4.8.0) sequel_pg (1.6.9) pg (>= 0.8.0) @@ -242,6 +248,7 @@ DEPENDENCIES ruby-debug sass screencap + scrypt sequel (= 4.8.0) sequel_pg shotgun diff --git a/Rakefile b/Rakefile index fb4371b1..e5042035 100644 --- a/Rakefile +++ b/Rakefile @@ -188,6 +188,15 @@ task :prime_site_updated_at => [:environment] do end end +desc 'hash_ips' +task :hash_ips => [:environment] do + Site.select(:id,:ip).order(:id).all.each do |s| + next if s.ip.nil? || s.ip.match(/#{$config['ip_hash_salt']}/) + s.ip = s.ip + s.save_changes validate: false + end +end + =begin desc 'Update screenshots' task :update_screenshots => [:environment] do diff --git a/app.rb b/app.rb index 49f40b7d..338c0dcd 100644 --- a/app.rb +++ b/app.rb @@ -1216,8 +1216,7 @@ post '/admin/banip' do flash[:error] = 'IP is blank, cannot continue' redirect '/admin' end - - sites = Site.filter(ip: site.ip, is_banned: false).all + sites = Site.filter(ip: Site.hash_ip(site.ip), is_banned: false).all sites.each {|s| s.ban!} flash[:error] = "#{sites.length} sites have been banned." redirect '/admin' @@ -1495,7 +1494,7 @@ post '/site/:username/report' do |username| redirect request.referer if current_site.id == site.id report.reporting_site_id = current_site.id else - report.ip = request.ip + report.ip = Site.hash_ip request.ip end report.save @@ -1533,8 +1532,8 @@ def dashboard_if_signed_in end def require_login_ajax - halt 'You are banned.' if Site.banned_ip?(request.ip) halt 'You are not logged in!' unless signed_in? + halt 'You are banned.' if current_site.is_banned? || parent_site.is_banned? end def csrf_safe? @@ -1546,8 +1545,11 @@ def csrf_token end def require_login - require_unbanned_ip redirect '/' unless signed_in? + if current_site.is_banned || parent_site.is_banned + session[:id] = nil + redirect '/' + end end def signed_in? diff --git a/config.yml.template b/config.yml.template index 1aba4e99..afb13194 100644 --- a/config.yml.template +++ b/config.yml.template @@ -8,6 +8,7 @@ development: sidekiq_pass: ENTER PASS HERE stripe_publishable_key: fillout stripe_api_key: fillout + ip_hash_salt: "400$8$1$fc21863da5d531c1" test: database: 'postgres://neocities@127.0.0.1/neocities_test' database_pool: 1 @@ -18,3 +19,4 @@ test: sidekiq_pass: ENTER PASS HERE stripe_publishable_key: fillout stripe_api_key: fillout + ip_hash_salt: "400$8$1$fc21863da5d531c1" \ No newline at end of file diff --git a/environment.rb b/environment.rb index 4095bccc..edc67d5c 100644 --- a/environment.rb +++ b/environment.rb @@ -26,6 +26,8 @@ else end # :nocov: +raise 'hash_ip_salt is required' unless $config['ip_hash_salt'] + DB = Sequel.connect $config['database'], sslmode: 'disable', max_connections: $config['database_pool'] DB.extension :pagination diff --git a/models/site.rb b/models/site.rb index 28bcc2e4..3c9e1dd9 100644 --- a/models/site.rb +++ b/models/site.rb @@ -202,20 +202,29 @@ class Site < Sequel::Model end def ip_create_limit?(ip) - Site.where('created_at > ?', Date.today.to_time).where(ip: ip).count > IP_CREATE_LIMIT || - Site.where(ip: ip).count > TOTAL_IP_CREATE_LIMIT + hashed_ip = hash_ip ip + Site.where('created_at > ?', Date.today.to_time).where(ip: hashed_ip).count > IP_CREATE_LIMIT || + Site.where(ip: hashed_ip).count > TOTAL_IP_CREATE_LIMIT + end + + def hash_ip(ip) + SCrypt::Engine.hash_secret ip, $config['ip_hash_salt'] + end + + def banned_ip?(ip) + return true if Site.where(is_banned: true). + where(ip: hash_ip(ip)). + where(['updated_at > ?', Time.now-BANNED_TIME]). + first + + return true if BlockedIp[ip] + + false end end - def self.banned_ip?(ip) - return true if Site.where(is_banned: true). - where(ip: ip). - where(['updated_at > ?', Time.now-BANNED_TIME]). - first - - return true if BlockedIp[ip] - - false + def ip=(ip) + super self.class.hash_ip(ip) end def is_following?(site) diff --git a/tests/acceptance/signup_tests.rb b/tests/acceptance/signup_tests.rb index 9eff5628..3ab21c5d 100644 --- a/tests/acceptance/signup_tests.rb +++ b/tests/acceptance/signup_tests.rb @@ -48,6 +48,8 @@ describe 'signup' do site.site_files.length.must_equal 4 site.site_changed.must_equal false site.site_updated_at.must_equal nil + + site.ip.must_equal Site.hash_ip('127.0.0.1') end it 'fails to create for existing site' do