diff --git a/app/signin.rb b/app/signin.rb index 7a531272..e756c594 100644 --- a/app/signin.rb +++ b/app/signin.rb @@ -1,7 +1,7 @@ get '/signin/?' do dashboard_if_signed_in @title = 'Sign In' - erb :'signin' + erb :'signin/index' end post '/signin' do @@ -16,6 +16,11 @@ post '/signin' do redirect '/signin' end + if site.is_deleted + session[:deleted_site_id] = site.id + redirect '/signin/restore' + end + session[:id] = site.id redirect '/' else @@ -25,6 +30,33 @@ post '/signin' do end end +get '/signin/restore' do + redirect '/' unless session[:deleted_site_id] + @site = Site[session[:deleted_site_id]] + redirect '/' if @site.nil? + erb :'signin/restore' +end + +get '/signin/cancel_restore' do + session[:deleted_site_id] = nil + flash[:success] = 'Site restore was cancelled.' + redirect '/' +end + +post '/signin/restore' do + redirect '/' unless session[:deleted_site_id] + @site = Site[session[:deleted_site_id]] + session[:deleted_site_id] = nil + + if @site.undelete! + session[:id] = @site.id + else + flash[:error] = "Sorry, we cannot restore this account." + end + + redirect '/' +end + get '/signin/:username' do require_login @site = Site[username: params[:username]] diff --git a/models/site.rb b/models/site.rb index 08281900..b01bb2e2 100644 --- a/models/site.rb +++ b/models/site.rb @@ -287,7 +287,7 @@ class Site < Sequel::Model def get_site_from_login(username_or_email, plaintext) site = get_with_identifier username_or_email - return nil if site.nil? || site.is_deleted || site.is_banned || !site.valid_password?(plaintext) + return nil if site.nil? || site.is_banned || !site.valid_password?(plaintext) site end @@ -445,19 +445,26 @@ class Site < Sequel::Model def before_destroy DB.transaction { owner.end_supporter_membership! if parent? - - if !Dir.exist? DELETED_SITES_ROOT - FileUtils.mkdir DELETED_SITES_ROOT - end - FileUtils.mkdir_p File.join(DELETED_SITES_ROOT, self.class.sharding_dir(username)) - FileUtils.mv files_path, File.join(DELETED_SITES_ROOT, self.class.sharding_dir(username), '/') + FileUtils.mv files_path, deleted_files_path remove_all_tags #remove_all_events #Event.where(actioning_site_id: id).destroy } end + def undelete! + return false unless Dir.exist? deleted_files_path + FileUtils.mkdir_p File.join(SITE_FILES_ROOT, self.class.sharding_dir(username)) + + DB.transaction { + FileUtils.mv deleted_files_path, files_path + self.is_deleted = false + save_changes + } + true + end + def is_banned? is_banned end @@ -1033,6 +1040,11 @@ class Site < Sequel::Model File.join SITE_FILES_ROOT, self.class.sharding_dir(name), name end + def base_deleted_files_path(name=username) + raise 'username missing' if name.nil? || name.empty? + File.join DELETED_SITES_ROOT, self.class.sharding_dir(name), name + end + def self.sharding_base_path(name) File.join SITE_FILES_ROOT, sharding_dir(name) end @@ -1065,6 +1077,10 @@ class Site < Sequel::Model File.join base_files_path, scrubbed_path(path) end + def deleted_files_path(path='') + File.join base_deleted_files_path, scrubbed_path(path) + end + def file_list(path='') list = Dir.glob(File.join(files_path(path), '*')).collect do |file_path| file = { diff --git a/tests/acceptance/signin_tests.rb b/tests/acceptance/signin_tests.rb index 83c2198b..abe40ed3 100644 --- a/tests/acceptance/signin_tests.rb +++ b/tests/acceptance/signin_tests.rb @@ -13,6 +13,23 @@ describe 'signin' do Capybara.reset_sessions! end + it 'restores a deleted site' do + pass = SecureRandom.hex + @site = Fabricate :site, password: pass + @site.destroy + Dir.exist?(@site.files_path).must_equal false + Dir.exist?(@site.deleted_files_path).must_equal true + visit '/signin' + fill_in 'username', with: @site.username + fill_in 'password', with: pass + click_button 'Sign In' + page.must_have_content 'Restore Site' + click_button 'Restore Site' + Dir.exist?(@site.deleted_files_path).must_equal false + Dir.exist?(@site.files_path).must_equal true + @site.reload.is_deleted.must_equal false + end + it 'fails for invalid signin' do visit '/' click_link 'Sign In' @@ -53,4 +70,4 @@ describe 'signin' do click_button 'Sign In' page.must_have_content 'Your Feed' end -end \ No newline at end of file +end diff --git a/views/index_layout.erb b/views/index_layout.erb index d94281c8..fd597031 100644 --- a/views/index_layout.erb +++ b/views/index_layout.erb @@ -10,7 +10,7 @@ - + diff --git a/views/signin.erb b/views/signin/index.erb similarity index 100% rename from views/signin.erb rename to views/signin/index.erb diff --git a/views/signin/restore.erb b/views/signin/restore.erb new file mode 100644 index 00000000..16110650 --- /dev/null +++ b/views/signin/restore.erb @@ -0,0 +1,21 @@ +
+
+

Restore Site

+

+
+
+ +
+ <%== flash_display %> + +

Your site was deleted.

+ +

Would you like to restore your site?

<%= @site.username %>.neocities.org

+ +
+ + +
+
+ No, please keep this site deleted. +