get '/settings/?' do require_login @site = parent_site erb :'settings/account' end def require_ownership_for_settings @site = Site[username: params[:username]] not_found if @site.nil? unless @site.owned_by? parent_site flash[:error] = 'Cannot edit this site, you do not have permission.' redirect request.referrer end end get '/settings/:username/?' do require_login require_ownership_for_settings erb :'settings/site' end post '/settings/:username/profile' do require_login require_ownership_for_settings @site.update( profile_comments_enabled: params[:site][:profile_comments_enabled] ) flash[:success] = 'Profile settings changed.' redirect "/settings/#{@site.username}#profile" end post '/settings/:username/ssl' do require_login require_ownership_for_settings unless params[:key] && params[:cert] flash[:error] = 'SSL key and certificate are required.' redirect "/settings/#{@site.username}#custom_domain" end begin key = OpenSSL::PKey::RSA.new params[:key][:tempfile].read, '' rescue => e flash[:error] = 'Could not process SSL key, file may be incorrect, damaged, or passworded (you need to remove the password).' redirect "/settings/#{@site.username}#custom_domain" end if !key.private? flash[:error] = 'SSL Key file does not have private key data.' redirect "/settings/#{@site.username}#custom_domain" end certs_string = params[:cert][:tempfile].read cert_array = certs_string.lines.slice_before(/-----BEGIN CERTIFICATE-----/).to_a.collect {|a| a.join} if cert_array.empty? flash[:error] = 'Cert file does not contain any certificates.' redirect "/settings/#{@site.username}#custom_domain" end cert_valid_for_domain = false cert_array.each do |cert_string| begin cert = OpenSSL::X509::Certificate.new cert_string rescue => e flash[:error] = 'Could not process SSL certificate, file may be incorrect or damaged.' redirect "/settings/#{@site.username}#custom_domain" end if cert.not_after < Time.now flash[:error] = 'SSL Certificate has expired, please create a new one.' redirect "/settings/#{@site.username}#custom_domain" end cert_cn = cert.subject.to_a.select {|a| a.first == 'CN'}.flatten[1] cert_valid_for_domain = true if cert_cn && cert_cn.match(@site.domain) end unless cert_valid_for_domain flash[:error] = "Your certificate CN (common name) does not match your domain: #{@site.domain}" redirect "/settings/#{@site.username}#custom_domain" end # Everything else was worse. crtfile = Tempfile.new 'crtfile' crtfile.write cert_array.join crtfile.close keyfile = Tempfile.new 'keyfile' keyfile.write key.to_pem keyfile.close if ENV['TRAVIS'] != 'true' nginx_testfile = Tempfile.new 'nginx_testfile' nginx_testfile.write %{ pid /tmp/throwaway.pid; events {} error_log /dev/null error; http { access_log off; server { listen 60000 ssl; server_name #{@site.domain} *.#{@site.domain}; ssl_certificate #{crtfile.path}; ssl_certificate_key #{keyfile.path}; } } } nginx_testfile.close line = Cocaine::CommandLine.new( "nginx", "-t -c :path", expected_outcodes: [0], swallow_stderr: true ) begin output = line.run path: nginx_testfile.path rescue Cocaine::ExitStatusError => e flash[:error] = "There is something wrong with your certificate, please check with your issuing CA." redirect "/settings/#{@site.username}#custom_domain" end end @site.update ssl_key: key.to_pem, ssl_cert: cert_array.join flash[:success] = 'Updated SSL key/certificate.' redirect "/settings/#{@site.username}#custom_domain" end post '/settings/:username/change_name' do require_login require_ownership_for_settings old_username = @site.username if params[:name] == nil || params[:name] == '' flash[:error] = 'Name cannot be blank.' redirect "/settings/#{@site.username}#username" end if old_username == params[:name] flash[:error] = 'You already have this name.' redirect "/settings/#{@site.username}#username" end old_host = @site.host old_file_paths = @site.file_list.collect {|f| f[:path]} @site.username = params[:name] if @site.valid? DB.transaction { @site.save_changes @site.move_files_from old_username } old_file_paths.each do |file_path| @site.purge_cache file_path end flash[:success] = "Site/user name has been changed. You will need to use this name to login, don't forget it." redirect "/settings/#{@site.username}#username" else flash[:error] = @site.errors.first.last.first redirect "/settings/#{old_username}#username" end end post '/settings/:username/change_nsfw' do require_login require_ownership_for_settings @site.update is_nsfw: params[:is_nsfw] flash[:success] = @site.is_nsfw ? 'Marked 18+' : 'Unmarked 18+' redirect "/settings/#{@site.username}#nsfw" end post '/settings/:username/custom_domain' do require_login require_ownership_for_settings @site.domain = params[:domain] if @site.valid? @site.save_changes flash[:success] = 'The domain has been successfully updated.' redirect "/settings/#{@site.username}#custom_domain" else flash[:error] = @site.errors.first.last.first redirect "/settings/#{@site.username}#custom_domain" end end post '/settings/change_password' do require_login if !Site.valid_login?(parent_site.username, params[:current_password]) flash[:error] = 'Your provided password does not match the current one.' redirect "/settings#password" end parent_site.password = params[:new_password] parent_site.valid? if params[:new_password] != params[:new_password_confirm] parent_site.errors.add :password, 'New passwords do not match.' end if parent_site.errors.empty? parent_site.save_changes flash[:success] = 'Successfully changed password.' redirect "/settings#password" else flash[:error] = current_site.errors.first.last.first redirect '/settings#password' end end post '/settings/change_email' do require_login if params[:email] == parent_site.email flash[:error] = 'You are already using this email address for this account.' redirect '/settings#email' end parent_site.email = params[:email] parent_site.email_confirmation_token = SecureRandom.hex 3 parent_site.email_confirmed = false if parent_site.valid? parent_site.save_changes send_confirmation_email flash[:success] = 'Successfully changed email. We have sent a confirmation email, please use it to confirm your email address.' redirect '/settings#email' end flash[:error] = parent_site.errors.first.last.first redirect '/settings#email' end post '/settings/create_child' do require_login if !current_site.plan_feature(:unlimited_site_creation) flash[:error] = 'Cannot create a new site with your current plan, please become a supporter.' redirect '/settings#sites' end site = Site.new site.parent_site_id = parent_site.id site.username = params[:username] if site.valid? site.save flash[:success] = 'Your new site has been created! To manage it, click your username in the top right and go to "Switch Site".' redirect '/settings#sites' else flash[:error] = site.errors.first.last.first redirect '/settings#sites' end end