Check secrets and ssl in production 2 #297
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class ErrorsController < ApplicationController | ||
skip_before_action :check_requirements | ||
skip_before_action :authenticate_user! | ||
|
||
def show | ||
@fix = fixes | ||
@fix[:database] = env["action_dispatch.exception"].class.name.starts_with? "ActiveRecord" | ||
render layout: false | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<html> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Couldn't you use the main layout ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the main layout has calls to the database thus it will create an infinite loop if the error is the database connection. |
||
<head> | ||
<title>Portus error page</title> | ||
<%= stylesheet_link_tag 'application', media: 'all' %> | ||
<%= javascript_include_tag 'application'%> | ||
<%= csrf_meta_tags %> | ||
</head> | ||
<body> | ||
<center><%= image_tag "layout/portus-error.png" %></center> | ||
<% if @fix.value?(true) %> | ||
<p> | ||
<center><h1>Ops... something went wrong...</h1></center> | ||
<center><h1>Please review your configuration</h1></center> | ||
</p> | ||
<div style="margin: 100px"> | ||
<% if @fix[:ssl] %> | ||
<h2>SSL</h2> | ||
<p>For security reasons you need to use SSL. SSL is not configured, please review your server configuration.</p> | ||
<% end %> | ||
<% if @fix[:secret_key_base] %> | ||
<h2>Fix secret key base</h2> | ||
<p>For security reasons you need to set a <i>secret_key_base</i>. You have a default value and this is not safe. Run:</p> | ||
<p><i> rake secret</i></p> | ||
to generate a new secret, and then | ||
<% if Rails.env.production? %> | ||
set <i>PORTUS_SECRET_KEY_BASE</i> environment variable to this value. | ||
<% else %> | ||
set <i>secret_key_base</i> to this value in <i>config/secret.yml</i>. | ||
<% end %> | ||
</p> | ||
<% end %> | ||
<% if @fix[:secret_machine_fqdn] %> | ||
<h2>Fix secret machine fqdn value</h2> | ||
You need to set the machine fdqn value for Portus to work. | ||
<% if Rails.env.production? %> | ||
Set <i>PORTUS_MACHINE_FQDN</i> environment variable. | ||
<% else %> | ||
Set <i>machine_fqdn</i> in <i>config/secrets.yml</i>. | ||
<% end %> | ||
<% end %> | ||
<% if @fix[:secret_encryption_private_key_path] %> | ||
<h2>Fix secret encryption private key path value</h2> | ||
You need to set the secret encryption private key path value for Portus to work. | ||
<% if Rails.env.production? %> | ||
Set <i>PORTUS_KEY_PATH</i> environment variable. | ||
<% else %> | ||
Set <i>encryption_private_key_path</i> in <i>config/secrets.yml</i>. | ||
<% end %> | ||
<% end %> | ||
<% if @fix[:secret_portus_password] %> | ||
<h2>Fix secret portus password</h2> | ||
You need to set the secret encryption private key path value for Portus to work. | ||
<% if Rails.env.production? %> | ||
Set <i>PORTUS_PASSWORD</i> environment variable. | ||
<% else %> | ||
Set <i>portus_password</i> in <i>config/secrets.yml</i>. | ||
<% end %> | ||
<% end %> | ||
<% if @fix[:database] %> | ||
<h2>Database</h2> | ||
<p>We cannot access the database. | ||
<% if Rails.env.production? %> | ||
Please set the following environment variables: | ||
<ul> | ||
<li>PORTUS_PRODUCTION_USERNAME</li> | ||
<li>PORTUS_PRODUCTION_PASSWORD</li> | ||
<li>PORTUS_PRODUCTION_HOST</li> | ||
<li>PORTUS_PRODUCTION_DATABASE</li> | ||
</ul> | ||
<% else %> | ||
Please review <i>config/database.yml</i> file. | ||
<% end %> | ||
|
||
<% end %> | ||
</div> | ||
<% else %> | ||
<p> | ||
We're sorry, but something went wrong.<br/> | ||
If you are the application owner check the logs for more information. | ||
</p> | ||
<% end %> | ||
|
||
</body> | ||
</html> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,7 +80,11 @@ | |
# Run pending migrations | ||
unless ENV["SKIP_MIGRATION"] | ||
config.after_initialize do | ||
ActiveRecord::Migrator.migrate(Rails.root.join("db/migrate"), nil) | ||
begin | ||
ActiveRecord::Migrator.migrate(Rails.root.join("db/migrate"), nil) | ||
rescue | ||
$stderr.puts "Error running migration! Please review database configuration" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the Rails logger There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rails logger has not yet been initialized here and it is nil. |
||
end | ||
end | ||
end | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
Rails.application.routes.draw do | ||
|
||
resources :errors, only: [:show] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of doing this, maybe do this: resources :errors, only: [:show], constraints: { id: /\d{3}/ } Note that now the |
||
resources :teams, only: [:index, :show, :create] | ||
resources :team_users, only: [:create, :destroy, :update] | ||
resources :namespaces, only: [:create, :index, :show] do | ||
|
@@ -41,5 +41,6 @@ | |
put "toggle_admin", on: :member | ||
end | ||
end | ||
match "(errors)/:status", to: "errors#show", constraints: { status: /\d{3}/ }, via: :all | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And now you can remove this match no ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no i can't. This match is for routing the (errors) to the errors controller. By (errors) I mean 500, 400 errors, like when an exception is raised. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does that include also the errors raised in other circumstances (like the 404 error trying to view a non existing team)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes it does. Should we handle it differently? I don't know this case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I just think it's great. |
||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
require "rails_helper" | ||
|
||
describe ErrorsController do | ||
describe "GET #show" do | ||
|
||
before :all do | ||
secrets = Rails.application.secrets | ||
@secret_key_base = secrets.secret_key_base | ||
@secret_machine_fqdn = secrets.machine_fqdn | ||
@secret_encryption_private_key_path = secrets.encryption_private_key_path | ||
@secret_portus_password = secrets.portus_password | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can get rid of this block because you have the same code inside of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not the same. Note the "@". This is to get a backup of the values and restore them before each test example and after all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, sorry |
||
|
||
before :each do | ||
secrets = Rails.application.secrets | ||
secrets.secret_key_base = @secret_key_base | ||
secrets.machine_fqdn = @secret_machine_fqdn | ||
secrets.encryption_private_key_path = @secret_encryption_private_key_path | ||
secrets.portus_password = @secret_portus_password | ||
end | ||
|
||
after :all do | ||
secrets = Rails.application.secrets | ||
secrets.secret_key_base = @secret_key_base | ||
secrets.machine_fqdn = @secret_machine_fqdn | ||
secrets.encryption_private_key_path = @secret_encryption_private_key_path | ||
secrets.portus_password = @secret_portus_password | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need that? Is that because otherwise the other tests are screwed up? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exactly |
||
|
||
it "sets @fix[:secret_key_base] as true" do | ||
Rails.application.secrets.secret_key_base = "CHANGE_ME" | ||
get :show, id: 1 | ||
expect(assigns(:fix)[:secret_key_base]).to be true | ||
end | ||
|
||
it "sets @fix[:secret_machine_fqdn] as true" do | ||
Rails.application.secrets.machine_fqdn = nil | ||
get :show, id: 1 | ||
expect(assigns(:fix)[:secret_machine_fqdn]).to be true | ||
end | ||
|
||
it "sets @fix[:secret_encryption_private_key_path] as true" do | ||
Rails.application.secrets.encryption_private_key_path = nil | ||
get :show, id: 1 | ||
expect(assigns(:fix)[:secret_encryption_private_key_path]).to be true | ||
end | ||
|
||
it "sets @fix[:secret_portus_password] as true" do | ||
Rails.application.secrets.portus_password = nil | ||
get :show, id: 1 | ||
expect(assigns(:fix)[:secret_portus_password]).to be true | ||
end | ||
|
||
end | ||
|
||
describe "GET #show in production mode" do | ||
|
||
after :all do | ||
Rails.env = ActiveSupport::StringInquirer.new("test") | ||
end | ||
|
||
it "sets @fix[:ssl] as true" do | ||
Rails.env = ActiveSupport::StringInquirer.new("production") | ||
get :show, id: 1 | ||
expect(assigns(:fix)[:ssl]).to be true | ||
end | ||
|
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require "rails_helper" | ||
|
||
feature "custom error handler page" do | ||
describe "with custom handler setup" do | ||
|
||
around :each do |example| | ||
begin | ||
Rails.application.config.consider_all_requests_local = false | ||
Rails.application.config.action_dispatch.show_exceptions = true | ||
Rails.env = ActiveSupport::StringInquirer.new("production") | ||
example.run | ||
ensure | ||
Rails.application.config.consider_all_requests_local = true | ||
Rails.application.config.action_dispatch.show_exceptions = false | ||
Rails.env = ActiveSupport::StringInquirer.new("test") | ||
end | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be safer to rewrite the code in that way: around :each do |example|
begin
Rails.application.config.consider_all_requests_local = false
Rails.application.config.action_dispatch.show_exceptions = true
Rails.env = ActiveSupport::StringInquirer.new("production")
example.run
ensure
Rails.application.config.consider_all_requests_local = true
Rails.application.config.action_dispatch.show_exceptions = false
Rails.env = ActiveSupport::StringInquirer.new("test")
end
end |
||
|
||
scenario "when no permissions routes to custom error page" do | ||
visit "/teams/show?id=1234" | ||
expect(page).to have_content("Ops... something went wrong...") | ||
end | ||
|
||
scenario "when no database routes to custom error page" do | ||
ActiveRecord::Base.connection.disconnect! | ||
visit "/" | ||
expect(page).to have_content("Ops... something went wrong...") | ||
end | ||
|
||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave an empty line before the method definition