We need to download the most recent CONSUL and check its `.ruby-version`
file before installing Ruby.
The `rvm1-capistrano` gem knows it and was invoking the `updating` task
before installing Ruby. So we were getting a warning in Capistrano about
the `updating` task being executed twice.
New CONSUL instances who didn't use the newest installer and haven't
done any deployments with capistrano would get an exception because the
`current` capistrano folder doesn't exist yet.
In this case using `joins` doesn't prevent N+1 queries to get titles for
every record, and since we cannot order translations with just SQL due
to fallbacks, we don't need it.
Automatic SQL injection checks were showing a false positive in this
scope; there was no real vulnerability here because foreign keys, table
names and locales were under our control.
Using `sanitize` we make sure the `href` attribute does not execute any
dangerous code. The possibility of a banner pointing to a dangerous URL
was very reduced, though, since only administrators can edit this
attribute.
We make the code easier to read and at the same time we remove a SQL
injection false positive regarding the use of `WHERE id = #{id}`.
We still get a warning about SQL injection regarding the `tsv =` part.
It's a false positive, since the value of that parameter does not
depend on user input.
We were using Capistrano's shared folder because it was the default
folder used by the capistrano-puma gem. However, it's easier to manage
it if it's under version control.
So we're moving the old `puma.rb` to `puma/development.rb`, and we use
the new `puma.rb` file for all environments except development. Anyone
installing CONSUL can change these files at will or change the specific
files for preproduction, production and staging environments.
This was actually a false positive, since our new regular expression
does the exact same thing. However, false positives generate noise and
make it harder to deal with real issues, so I'm changing it anyway.
We could add a more advanced regular expression, like
`URI::MailTo::EMAIL_REGEXP`. However, this expression marks emails with
non-English characters as invalid, when in practice it's possible to
have an email address with non-English characters.
It was being incorrectly detected as used in a dangerous send. We can
get rid of the warning by taking advantage of the `has_orders` method
and getting rid of this code.
Deploy environment files were loaded after config/deploy.rb was loaded,
meaning if we used settings like `deploy_to` or `current_path` to set
variables inside the config/deploy.rb file, we'd be using the default
settings instead of the ones dictated by the deploy environment files.
These files are only loaded when the stage already has the value set
inside them, so we don't need to set it again.
On the other hand, the `rails_env` setting is configured in the
`config/deploy.rb` file.
In theory it's possible to add a `host` parameter to a URL, and we could
end up redirecting to that host if we just redirect using query
parameters.
Generating the path using `url_for` with `only_path` solves the issue.
Note in the tests I'm using the `get` method because the `patch` method
wouldn't send query parameters. This doesn't mean the action can be
accessed through GET requests, since controller tests don't check route
verbs. Using feature specs doesn't seem to work because `controller` and
`host` parameters are filtered automatically in feature specs.
Also note I'm not testing every hidden/moderation controller because
they basically use the same code.
These actions are never called with query parameters in our application,
so there's no need to use these parameters in a redirect.
Note in the test I'm using the `get` method because the `patch` method
wouldn't send query parameters. This doesn't mean the action can be
accessed through GET requests, since controller tests don't check route
verbs.
This is the same configuration we had with unicorn.
With several workers, we've got two basic configuration options:
* Preload the application and use a hot restart
* Don't preload the application and use a phased restart
I've decided to preload the application because using a hot restart
changes are available immediately, while with a phased restart there are
a few seconds when both workers for the old code and workers for the new
code exist.
Using a phased restart also has advantages, so some forks might want to
disable the `puma_preload_app` setting in order to use it.
Old versions of the installer created this file as root, making it
impossible to change it as a regular user.
So for old installations we need to make sure we've got write access to
this file.
We're using `sudo` because in these applications the installer gives
`sudo` access to the deploy user, so everything works fine with the
default configuration.
While this is not a secret and in theory should be in a file under
version control, currently the CONSUL installer disables delayed jobs by
default, meaning we were keeping two versions of the delayed jobs
configuration file, and some existing configurations have their settings
defined in a file in capistrano's `shared` folder.
So we're moving existing settings to the secrets file.
We were copying the current SMTP and SSL settings to the secrets file
after overwriting them, but we need to copy them before overwriting
them.
The workaround I've found is to copy the tasks to the folder of the
previous release and execute them there.
this is usually configured in the production.rb file (which is under
version control), the natural place to configure it is the secrets.yml
file.
Until now we were using the capistrano shared folder, but that's a bit
inconvenient since changes we've done to the production.rb file (like
changing eager_load_paths when we upgraded to Rails 5) won't take effect
after a deployment.
Existing installations having their configuration settings in the
capistrano shared folder needed this migration.
Note we can't just use `YAML.load` because we'd lose the anchors defined
in the file. So we have to parse the file the hard way.
Since SMTP passwords should not be in a file under version control, and
they're usually configured in the production.rb file (which is under
version control), the natural place to configure it is the secrets.yml
file.
Until now we were using the capistrano shared folder, but that's a bit
inconvenient since changes we've done to the production.rb file (like
changing eager_load_paths when we upgraded to Rails 5) won't take effect
after a deployment.
Creating more than 25 records isn't necessary to test pagination; we can
stub the number of records per page in a test.
On my machine we save about one second per test with these changes.