add ability to restore deleted sites

This commit is contained in:
Kyle Drake 2017-06-03 23:43:05 -07:00
parent c4e307fcf1
commit c9ba1cf0f4
6 changed files with 96 additions and 10 deletions

View file

@ -1,7 +1,7 @@
get '/signin/?' do get '/signin/?' do
dashboard_if_signed_in dashboard_if_signed_in
@title = 'Sign In' @title = 'Sign In'
erb :'signin' erb :'signin/index'
end end
post '/signin' do post '/signin' do
@ -16,6 +16,11 @@ post '/signin' do
redirect '/signin' redirect '/signin'
end end
if site.is_deleted
session[:deleted_site_id] = site.id
redirect '/signin/restore'
end
session[:id] = site.id session[:id] = site.id
redirect '/' redirect '/'
else else
@ -25,6 +30,33 @@ post '/signin' do
end end
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 get '/signin/:username' do
require_login require_login
@site = Site[username: params[:username]] @site = Site[username: params[:username]]

View file

@ -287,7 +287,7 @@ class Site < Sequel::Model
def get_site_from_login(username_or_email, plaintext) def get_site_from_login(username_or_email, plaintext)
site = get_with_identifier username_or_email 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 site
end end
@ -445,19 +445,26 @@ class Site < Sequel::Model
def before_destroy def before_destroy
DB.transaction { DB.transaction {
owner.end_supporter_membership! if parent? 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.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_tags
#remove_all_events #remove_all_events
#Event.where(actioning_site_id: id).destroy #Event.where(actioning_site_id: id).destroy
} }
end 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? def is_banned?
is_banned is_banned
end end
@ -1033,6 +1040,11 @@ class Site < Sequel::Model
File.join SITE_FILES_ROOT, self.class.sharding_dir(name), name File.join SITE_FILES_ROOT, self.class.sharding_dir(name), name
end 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) def self.sharding_base_path(name)
File.join SITE_FILES_ROOT, sharding_dir(name) File.join SITE_FILES_ROOT, sharding_dir(name)
end end
@ -1065,6 +1077,10 @@ class Site < Sequel::Model
File.join base_files_path, scrubbed_path(path) File.join base_files_path, scrubbed_path(path)
end end
def deleted_files_path(path='')
File.join base_deleted_files_path, scrubbed_path(path)
end
def file_list(path='') def file_list(path='')
list = Dir.glob(File.join(files_path(path), '*')).collect do |file_path| list = Dir.glob(File.join(files_path(path), '*')).collect do |file_path|
file = { file = {

View file

@ -13,6 +13,23 @@ describe 'signin' do
Capybara.reset_sessions! Capybara.reset_sessions!
end 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 it 'fails for invalid signin' do
visit '/' visit '/'
click_link 'Sign In' click_link 'Sign In'

21
views/signin/restore.erb Normal file
View file

@ -0,0 +1,21 @@
<div class="header-Outro">
<div class="row content single-Col txt-Center">
<h1>Restore Site</h1>
<h3 class="subtitle"></h3>
</div>
</div>
<div class="content txt-Center single-Col misc-page">
<%== flash_display %>
<h3>Your site was deleted.</h3>
<p>Would you like to restore your site?<br><br><strong><%= @site.username %>.neocities.org</strong></p>
<form method="POST" action="/signin/restore" class="content">
<input name="csrf_token" type="hidden" value="<%= csrf_token %>">
<input class="btn-Action" type="submit" value="Restore Site">
</form>
<br>
<a href="/">No, please keep this site deleted.</a>
</div>