diff --git a/.gitignore b/.gitignore index 6fd2737a..c44ce044 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ files/sslsites.zip .tm_properties ./black_box.rb .vagrant +public/banned_sites +public/deleted_sites diff --git a/app/dashboard.rb b/app/dashboard.rb index 79a3943f..f9a96fe2 100644 --- a/app/dashboard.rb +++ b/app/dashboard.rb @@ -12,7 +12,7 @@ def dashboard_init if !File.directory?(current_site.files_path(params[:dir])) if !File.directory?(current_site.files_path) flash[:error] = 'Could not find your web site, please contact support.' - session[:id] = nil + signout redirect '/' else flash[:error] = 'Could not find the requested directory.' diff --git a/app/settings.rb b/app/settings.rb index 29387b36..fb35e541 100644 --- a/app/settings.rb +++ b/app/settings.rb @@ -18,12 +18,43 @@ end get '/settings/:username/?' do |username| # This is for the email_unsubscribe below pass if Site.select(:id).where(username: username).first.nil? - require_login require_ownership_for_settings erb :'settings/site' end +post '/settings/:username/delete' do + require_login + require_ownership_for_settings + + if params[:confirm_username] != @site.username + flash[:error] = 'Site user name and entered user name did not match.' + redirect "/settings/#{@site.username}#delete" + end + + if @site.parent? && @site.stripe_customer_id + customer = Stripe::Customer.retrieve @site.stripe_customer_id + subscription = customer.subscriptions.retrieve @site.stripe_subscription_id + subscription.plan = 'free' + subscription.save + @site.plan_type = 'free' + @site.save_changes validate: false + end + + @site.deleted_reason = params[:deleted_reason] + @site.save validate: false + @site.destroy + + flash[:success] = 'Site deleted.' + + if @site.username == current_site.username + signout + redirect '/' + end + + redirect '/settings#sites' +end + post '/settings/:username/profile' do require_login require_ownership_for_settings diff --git a/app/signin.rb b/app/signin.rb index e59a180f..2f265f69 100644 --- a/app/signin.rb +++ b/app/signin.rb @@ -41,6 +41,10 @@ end get '/signout' do require_login - session[:id] = nil + signout redirect '/' +end + +def signout + session[:id] = nil end \ No newline at end of file diff --git a/app_helpers.rb b/app_helpers.rb index 47905238..2a741a41 100644 --- a/app_helpers.rb +++ b/app_helpers.rb @@ -18,7 +18,7 @@ end def require_login redirect '/' unless signed_in? if session[:banned] || current_site.is_banned || parent_site.is_banned - session[:id] = nil + signout session[:banned] = true redirect '/' end @@ -40,7 +40,7 @@ end def require_unbanned_ip if session[:banned] || Site.banned_ip?(request.ip) - session[:id] = nil + signout session[:banned] = true flash[:error] = 'Site creation has been banned due to ToS violation/spam. '+ 'If you believe this to be in error, contact the site admin.' diff --git a/migrations/054_add_deleted_reason.rb b/migrations/054_add_deleted_reason.rb new file mode 100644 index 00000000..35d68ee7 --- /dev/null +++ b/migrations/054_add_deleted_reason.rb @@ -0,0 +1,9 @@ +Sequel.migration do + up { + DB.add_column :sites, :deleted_reason, :text + } + + down { + DB.drop_column :sites, :deleted_reason + } +end \ No newline at end of file diff --git a/models/site.rb b/models/site.rb index b26c7ef8..cd832674 100644 --- a/models/site.rb +++ b/models/site.rb @@ -49,6 +49,8 @@ class Site < Sequel::Model THUMBNAILS_ROOT = File.join(PUBLIC_ROOT, (ENV['RACK_ENV'] == 'test' ? 'site_thumbnails_test' : 'site_thumbnails')) SCREENSHOTS_URL_ROOT = ENV['RACK_ENV'] == 'test' ? '/site_screenshots_test' : '/site_screenshots' THUMBNAILS_URL_ROOT = ENV['RACK_ENV'] == 'test' ? '/site_thumbnails_test' : '/site_thumbnails' + DELETED_SITES_ROOT = File.join PUBLIC_ROOT, 'deleted_sites' + BANNED_SITES_ROOT = File.join PUBLIC_ROOT, 'banned_sites' IMAGE_REGEX = /jpg|jpeg|png|bmp|gif/ LOSSLESS_IMAGE_REGEX = /png|bmp|gif/ LOSSY_IMAGE_REGEX = /jpg|jpeg/ @@ -376,31 +378,13 @@ class Site < Sequel::Model end def before_destroy - raise 'not finished' DB.transaction { - remove_all_tags - profile_comments.destroy - profile_commentings.destroy - follows.destroy - followings.destroy - #tips.destroy - #tippings.destroy - #blocks.destroy - #blockings.destroy - #reports.destroy - #reportings.destroy - #stats.destroy - #events.destroy - #site_changes.destroy - # TODO FIND THE REST, ASSOCIATE THEM PROPERLY!!! - } - end + if !Dir.exist? DELETED_SITES_ROOT + FileUtils.mkdir DELETED_SITES_ROOT + end - def delete_site! - raise 'not finished' - DB.transaction { - destroy - FileUtils.mv files_path, File.join(PUBLIC_ROOT, 'deleted_sites', username) + FileUtils.mv files_path, File.join(DELETED_SITES_ROOT, username) + remove_all_tags } end @@ -419,7 +403,12 @@ class Site < Sequel::Model self.is_banned = true self.updated_at = Time.now save(validate: false) - FileUtils.mv files_path, File.join(PUBLIC_ROOT, 'banned_sites', username) + + if !Dir.exist? BANNED_SITES_ROOT + FileUtils.mkdir BANNED_SITES_ROOT + end + + FileUtils.mv files_path, File.join(BANNED_SITES_ROOT, username) } file_list.each do |path| diff --git a/public/banned_sites/.gitignore b/public/banned_sites/.gitignore index 72e8ffc0..e69de29b 100644 --- a/public/banned_sites/.gitignore +++ b/public/banned_sites/.gitignore @@ -1 +0,0 @@ -* diff --git a/tests/acceptance/settings/site_tests.rb b/tests/acceptance/settings/site_tests.rb index c7b6236f..968037ff 100644 --- a/tests/acceptance/settings/site_tests.rb +++ b/tests/acceptance/settings/site_tests.rb @@ -225,4 +225,120 @@ describe 'site/settings' do Site[username: ''].must_equal nil end end +end + +describe 'delete' do + include Capybara::DSL + + before do + Capybara.reset_sessions! + @site = Fabricate :site + page.set_rack_session id: @site.id + visit "/settings/#{@site[:username]}#delete" + end + + after do + StripeMock.stop + end + + it 'fails for incorrect entered username' do + fill_in 'username', with: 'NOPE' + click_button 'Delete Site' + + page.body.must_match /Site user name and entered user name did not match/i + @site.reload.is_deleted.must_equal false + end + + it 'succeeds' do + deleted_reason = 'Penelope left a hairball on my site' + + fill_in 'confirm_username', with: @site.username + fill_in 'deleted_reason', with: deleted_reason + click_button 'Delete Site' + + @site.reload + @site.is_deleted.must_equal true + @site.deleted_reason.must_equal deleted_reason + page.current_path.must_equal '/' + + File.exist?(@site.files_path('./index.html')).must_equal false + Dir.exist?(@site.files_path).must_equal false + + path = File.join Site::DELETED_SITES_ROOT, @site.username + Dir.exist?(path).must_equal true + File.exist?(File.join(path, 'index.html')).must_equal true + + visit "/site/#{@site.username}" + page.status_code.must_equal 404 + end + + it 'stops charging for supporter account' do + @stripe_helper = StripeMock.create_test_helper + StripeMock.start + @stripe_helper.create_plan id: 'supporter', amount: 500 + @stripe_helper.create_plan id: 'free', amount: 0 + + customer = Stripe::Customer.create( + card: @stripe_helper.generate_card_token + ) + + subscription = customer.subscriptions.create plan: 'supporter' + + @site.update( + stripe_customer_id: customer.id, + stripe_subscription_id: subscription.id, + plan_type: 'supporter' + ) + + @site.plan_type = subscription.plan.id + @site.save_changes + + fill_in 'confirm_username', with: @site.username + fill_in 'deleted_reason', with: 'derp' + click_button 'Delete Site' + + subscription = Stripe::Customer.retrieve(@site.stripe_customer_id).subscriptions.first + + subscription.plan.id.must_equal 'free' + @site.reload + @site.is_deleted.must_equal true + @site.plan_type.must_equal 'free' + end + + it 'should fail unless owned by current user' do + someone_elses_site = Fabricate :site + page.set_rack_session id: @site.id + + page.driver.post "/settings/#{someone_elses_site.username}/delete", { + username: someone_elses_site.username, + deleted_reason: 'Dade Murphy enters Acid Burns turf' + } + + page.driver.status_code.must_equal 302 + URI.parse(page.driver.response_headers['Location']).path.must_equal '/' + someone_elses_site.reload + someone_elses_site.is_deleted.must_equal false + end + + it 'should succeed if you own the site' do + owned_site = Fabricate :site, parent_site_id: @site.id + visit "/settings/#{owned_site.username}#delete" + fill_in 'confirm_username', with: owned_site.username + fill_in 'deleted_reason', with: 'got bored with it' + click_button 'Delete Site' + + @site.reload + owned_site.reload + owned_site.is_deleted.must_equal true + owned_site.deleted_reason.must_equal 'got bored with it' + @site.is_deleted.must_equal false + + page.current_path.must_equal "/settings" + end + + it 'fails to delete parent site if children exist' do + owned_site = Fabricate :site, parent_site_id: @site.id + visit "/settings/#{@site.username}#delete" + page.body.must_match /You cannot delete the parent site without deleting the children sites first/i + end end \ No newline at end of file diff --git a/views/settings/account.erb b/views/settings/account.erb index 22372e92..7f49c35b 100644 --- a/views/settings/account.erb +++ b/views/settings/account.erb @@ -43,17 +43,6 @@ - - diff --git a/views/settings/site.erb b/views/settings/site.erb index 192e789e..c7339aad 100644 --- a/views/settings/site.erb +++ b/views/settings/site.erb @@ -27,6 +27,7 @@
  • Custom Domain
  • Username
  • 18+
  • +
  • Delete
  • @@ -41,6 +42,9 @@
    <%== erb :'settings/site/nsfw' %>
    +
    + <%== erb :'settings/site/delete' %> +
    diff --git a/views/settings/site/delete.erb b/views/settings/site/delete.erb new file mode 100644 index 00000000..7a88fd9e --- /dev/null +++ b/views/settings/site/delete.erb @@ -0,0 +1,27 @@ +

    Delete Site

    +
    + <% if @site.parent? && @site.children.count > 0 %> +

    + You cannot delete the parent site without deleting the children sites first. +

    + <% else %> +
    + <%== csrf_token_input_html %> +

    + WARNING: This will delete your site <%= @site.username %> (<%= @site.host %>). There is no undo! Be very sure you want to do this. +

    + +

    + + +

    + +

    + + .neocities.org +

    + + +
    + <% end %> +
    \ No newline at end of file