This will allow us to keep using the timezone used when running
the installer.
We keep using Madrid as default timezone in the installer and in
the application.
As this secret is currently not programmed to be customisable for each Tenant,
we take it out of the security section. The reason is that so far everything inside this security section can be overwritten per tenant. With this change we are trying
to prevent anyone from trying to overwrite it on a per Tenant basis, as it would have
no effect.
Other packages depend on jQuery, so that's why these are the first one
we move from the Gemfile to the package.json file.
This way we can also test whether dependabot correctly opens pull
requests to update Node packages.
I've tried several configuration options for the asset pipeline in order
to be able to include images referenced in jQuery UI CSS files. So far,
adding the `node_modules/jquery-ui/themes/base` folder to the assets
paths is the only way I've found to make it work. Hopefully we can find
a better solution in the future so we don't have to study the internals
of every Node package in order to integrate it with the assets pipeline.
Note that, even if we're excluding the `node_modules/` folder from
version control, we aren't adding it to Capistrano's shared folders
because, when `node_modules` is a symbolic link, NPM removes it when
running `npm install`.
We can remove the `new_framework_defaults_6_1` file by using Rails 6.1
default options and overwriting the one we haven't enabled.
We've experienced problems while running the tests (probably the same
would happen on production) when enabling the `has_many_inversing`
option. For example, after creating a legislation answer for a question
with no answers, calling `question.answers_count` would then return `2`
instead of `1`.
So we aren't enabling this option.
For the HashAlignment rule, we're using the default `key` style (keys
are aligned and values aren't) instead of the `table` style (both keys
and values are aligned) because, even if we used both in the
application, we used the `key` style a lot more. Furthermore, the
`table` style looks strange in places where there are both very long and
very short keys and sometimes we weren't even consistent with the
`table` style, aligning some keys without aligning other keys.
Ideally we could align hashes to "either key or table", so developers
can decide whether keeping the symmetry of the code is worth it in a
case-per-case basis, but Rubocop doesn't allow this option.
We were already applying these rules in most cases.
Note we aren't enabling the `MultilineArrayLineBreaks` rule because
we've got places with many elements whire it isn't clear whether
having one element per line would make the code more readable.
Just like we respond with "not found" for any other record. This
improves the user experience because with the "Not found" error message
people realize the URL is wrong instead of thinking that they broke the
application.
The subdomain elevator we were using, which is included in apartment,
didn't work on hosts already including a subdomain (like
demo.consul.dev, for instance). In those cases, we would manually add
the subdomain to the list of excluded subdomains. Since these subdomains
will be different for different CONSUL installations, it meant each
installation had to customize the code. Furthermore, existing
installations using subdomains would stop working.
So we're using a custom method to find the current tenant, based on the
host defined in `default_url_options`.
In order to avoid any side-effects on single-tenant applications, we're
adding a new configuration option to enable multitenancy
We're enabling two ways to handle this configuration option:
a) Change the application_custom.rb file, which is under version control
b) Change the secrets.yml file, which is not under version control
This way people prefering to handle configuration options through
version control can do so, while people who prefer handling
configuration options through te secrets.yml file can do so as well.
We're also disabling the super-annoying warnings mentioning there are no
tenants which we got every time we run migrations on single-tenant
applications. These messages will only be enabled when the multitenancy
feature is enabled too. For this reason, we're also disabling the
multitenancy feature in the development environment by default.
We were getting a warning because it won't be included by default in
Rails 6.1:
DEPRECATION WARNING: Using I18n fallbacks with an empty `defaults` sets
the defaults to include the `default_locale`. This behavior will change
in Rails 6.1 . If you desire the default locale to be included in the
defaults, please explicitly configure it with
`config.i18n.fallbacks.defaults = [I18n.default_locale]` or
`config.i18n.fallbacks = [I18n.default_locale, {...}]`. If you want to
opt-in to the new behavior, use `config.i18n.fallbacks.defaults = [nil,
{...}] `.
We can remove the `new_framework_defaults_6_0` file by using Rails 6.0
default options and overwriting the ones we haven't enabled.
We're still using the classic autoloader because we still haven't
checked how switching to zeitwerk will affect the way CONSUL
installations customize their code.
And we're using the default queues for Active Storage because we were
already using them and that will be the default option in Rails 6.1.
All the code in the `bin/` and the `config/` folders has been generated
running `rake app:update`. The only exception is the code in
`config/application.rb` where we've excluded the engines that Rails 6.0
has added, since we don't use them.
There are a few changes in Active Storage which aren't compatible with
the code we were using until now.
Since the method to assign an attachment in ActiveStorage has changed
and is incompatible with the hack we used to allow assigning `nil`
attachments, and since ActiveStorage now supports assigning `nil`
attachments, we're removing the mentioned hack. This makes the
HasAttachment module redundant, so we're removing it.
Another change in ActiveStorage is files are no longer saved before
saving the `ActiveStorage::Attachment` record. This means we need to
manually upload the file when using direct uploads. We also have to
change the width and height validations we used for images; however,
doing so results in very complex code, and we currently have to write
that code for both images and site customization images.
So, for now, we're just uploading the file before checking its
dimensions. Not ideal, though. We might use active_storage_validations
in the future to fix this issue (when they support a proc/lambda, as
mentioned in commit 600f5c35e).
We also need to update a couple of tests due to a small change in
response headers. Now the content disposition returns something like:
```
attachment; filename="budget_investments.csv"; filename*=UTF-8''budget_investments.csv
```
So we're updating regular expression we use to check the filename.
Finally, Rails 6.0.1 changed the way the host is set in integration
tests [1] and so both `Capybara.app_host` and `Capybara.default_host`
were ignored when generating URLs in the relationable examples. The only
way I've found to make it work is to explicitely assign the host to the
integration session. Rails 6.1 will change this setup again, so maybe
then we can remove this hack.
[1] https://github.com/rails/rails/pull/36283/commits/fe00711e9
Without this change, we were getting errors when manually creating an
annotation using symbols in the ranges hash (that is, `ranges: [{ start:
"/p[1] }]` instead of `ranges: [{ "start" => "/p[1] }]`.
Using symbols isn't really supported and it might cause strange issues
with code like: `@draft_version.annotations.find_by(range_start: ...)`.
However, this might be an extreme case and using symbols might work
properly most of the time (if not all the time), and we've been using
them in our demo for years.
So I'm not writing a test for this case because I'm not sure we should
support it, but I'm still allowing symbols so we don't get exceptions in
cases where everything might be working fine. Rails already adds Symbol
by default to column permitted classes [1], so it's safe to enable it.
[1] https://github.com/rails/rails/pull/45584/commits/c2b96e3e8
This release introduces an incompatibility in order to fix a security
issue when using YAML for serialization. We use YAML to serialize the
`ranges` column in the `legislation_annotations` table, so we have to
allow the `ActiveSupport::HashWithIndifferentAccess` class in order to
properly read this column.
Ideally we'd use a JSONB column for the ranges (like we do in other
places), but that would require migrating existing data.
Bumps [rails](https://github.com/rails/rails) from 5.2.7.1 to 5.2.8.1.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](https://github.com/rails/rails/compare/v5.2.7.1...v5.2.8.1)
---
updated-dependencies:
- dependency-name: rails
...
When there was a custom JavaScript file, we weren't loading the original
one, meaning that, in order to customize it, it was necessary to copy
the whole original file and then changing it.
Now we're loading both the original and the custom file, so the custom
file can simply add more functions or overwrite the ones we'd like to
customize, without copying the whole file.
Existing copies of original files will still overwrite the whole file
and won't be affected.
`dalli_store` is deprecated since dalli 2.7.11.
We can now enable cache_versioning. We didn't enable it when upgrading
to Rails 5.2 because of possible incompatibility with `dalli_store` [1],
even though apparently some the issues were fixed in dalli 2.7.9 and
dalli 2.7.10 [2].
Since using cache versioning makes cache expiration more efficient, and
I'm not sure whether the options we were passing to the dalli store are
valid with memcache store (documentation here is a bit lacking), I'm
just removing the option we used to double the default cache size on
production.
[1] https://www.schneems.com/2018/10/17/cache-invalidation-complexity-rails-52-and-dalli-cache-store
[2] https://github.com/petergoldstein/dalli/blob/master/History.md
When administrators disabled features and users tried to access them
with the browser, we were responding with a 500 "Internal Server Error"
page, which in my humble opinion was incorrect. There was no error at
all; the server worked exactly as expected.
I think a 403 "Forbidden" code is better; since that feature is
disabled, we're refusing to let users access it.
We could also respond with a 404 "Not found", although I wonder whether
that'll be confusing when administrators temporarily or accidentally
disable a feature.
A similar thing might happen if we responded with a 410 "Gone" code.
Actually this case might be more confusing since users aren't that
familiar with this code.
In any case, all these options are better than the 500 error.
While Rails provides a lot of functionality by default, there's one
missing piece which is present in frameworks like Django or Phoenix: the
so-called "view models", or "components".
It isn't easy to extract methods in a standard Rails view/partial, since
extracting them to a helper will make them available to all views, and
so two helper methods can't have the same name. It's also hard to
organize the code in modules, and due to that it's hard to figure out
where a certain helper method is supposed to be called from.
Furthermore, object-oriented techniques like inheritance can't be
applied, and so in CONSUL customizing views is harder that customizing
models.
Components fix all these issues, and work the way Ruby objects usually
do.
Components are also a pattern whose popularity has increased a lot in
the last few years, with JavaScript frameworks like React using them
heavily. While React's components aren't exactly the same as the
components we're going to use, the concept is really similar.
I've always liked the idea of components. However, there wasn't a stable
gem we could safely use. The most popular gem (cells) hasn't been
maintained for years, and we have to be very careful choosing which gems
CONSUL should depend on.
The view_component gem is maintained by GitHub, which is as a guarantee
of future maintenance as it can be (not counting the Rails core team),
and its usage started growing after RailsConf 2019. While that's
certainly not a huge amount of time, it's not that we're using an
experimental gem either.
There's currently a conflict between view_component and wicked_pdf.
We're adding a monkey-patch with the fix until it's merged in
wicked_pdf.
We aren't using ActiveStorage, but Rails was including its routes
anyway.
In Rails 6.1 there will be an option to disable these routes [1], but
for now we're changing the line requiring "rails/all" to the values
generated by a new Rails application with the --skip-active-storage
flag.
[1] https://github.com/rails/rails/commit/3cf65bcb8
We can remove the `new_framework_defaults_5_2` file by using Rails 5.2
default options and overwriting the ones we haven't enabled.
We're disabling `use_authenticated_message_encryption` because, even if
we don't use it, some CONSUL installations might be using it, and
enabling this options would make it harder to decrypt existing encrypted
messages.
And we're disabling `cache_versioning` until we verify our cache keeps
working and expires as expected on production environments, particularly
for stats.
We're not replacing `form_for` with `form_with` for now, and even if we
did, most of our forms are not remote, so making them remote by default
would be inconvenient.
This is the default in Rails 5.1 applications. If we want to use an
asset in the public folder, we need to add the `public_folder: true`
option, making it clear that we don't expect the asset to be in the
asset pipeline.
Since we don't use `asset_path` to reference assets in the public
folder, we can safely disable the `unknown_asset_fallback` option.
Changing it would mean reviewing and changing all our existing models,
and some of them might be tricky (like our Document and Image models,
which only validate certain associations in some cases), so we're
keeping it the way it's been until now.
The default options (which apply when `force_ssl` is set, which is the
default in CONSUL) are `{ hsts: { subdomains: true } }`, which means we
tell browsers to apply our SSL settings to subdomains as well [1].
CONSUL installations implementing multitenancy with subdomains will
benefit from this change.
[1] https://api.rubyonrails.org/classes/ActionDispatch/SSL.html
Quoting the Rails DateAndTime::Compatibility module:
> With Ruby 2.4+ the default for +to_time+ changed from
> converting to the local system time, to preserving the offset
> of the receiver. For backwards compatibility we're overriding
> this behavior
We don't need backwards compatibility in our application because we
aren't converting any time objects to the local system timezone but use
the application timezone all the time instead.
This is the default in Rails 5 applications.
This option is not enabled by default in existing applications because
it would break applications running on several domains and doing POST
requests between them or running a reverse proxy that rewrites the Host
header. Since those aren't our cases, it's safe to enable it.
This is the default for new Rails application, and adds an extra layer
of security since now the token will only be valid for its action, and
so attackers managing to change the form action will not do any harm
since the CSRF token will not work for the attackers' action.
Note that we've had InvalidAuthenticityToken exceptions for years; if we
keep getting them, chances are this change is *not* related.
The goal here is to have a notion on what the defaults are in a Rails 5
application, know why our application is working in a different way
(it's because these defaults aren't loaded in an application which was
originally developed using Rails 4), and have an explicit list of things
we are overwriting.
Furthermore, running the `app:update` rake task to upgrade to Rails 5.2
will by default add the line loading default options for Rails 5.0, so
by adopting those default options we prevent accidental mistakes when
upgrading.
We'll have to review these items and see which ones can be changed to
their default values for Rails 5 applications.
Consul uses two variants of Serbian: Serbian (Cirylic), and
Serbian (Latin) so wee need to use different locale codes for each of
them to avoid collisions.
The folder names of both languages were correct but the locale code within
the files was the same for both languages "sr" so translations were mixed.
This commit changes the locale code within Serbian (Latin) translations
files to "sr-CS", also adds a new language mapping to the Crowdin config
file so next ConsulBot commits with Serbian (Latin) translations will be
done using the locale code defined at new language mapping.
Following locales are now available by default:
* "bg" (Bulgarian): 98,5% translated
* "ca" (Catalan): 100 % translated
* "es-PE" (Spanish from Perú): 64,8% translated
* "eu" (Euskara): 67,8% translated
* "ka" (Georgian): 98,9% translated
* "oc" (Occitan): 98,9% translated
* "ro" (Romanian): 99,1% translated
Spanish and Euskara were enabled becuase both are near the 70% and its
fallback language (Spanish) is complete.
Add custom fallbacks:
* Catalan (ca) => Español (es).
* Español de Perú (es-PE) => Español (es).
* Euskara (eu) => Español (es).
* Portuguese-Brazilero (pt-BR) => Español (es).
* Occitan (oc) => French (fr)
Rails 5.2 crashes in the `db:create` task because it tries to run the
`after_initialize` block before the database is created.
The easiest way to solve it is to move the code out of the initializer
and calculate the API type definitions on demand. Note results are still
cached using a class instance variable (not to be confused with a class
variable), and so once definitions are obtained, they will remain
constant until the application is restarted, even in the development
environment.
The line:
```
config.i18n.load_path += Dir[Rails.root.join("config", "locales", "**", "*.{rb,yml}")]
```
Was adding every locale under the `config/locales` folder, including the
ones inside `config/locales/custom/`. The files were loaded in the same
order as listed using `ls -f`.
So if the custom locales were loaded before the folder
`config/locales/#{I18n.locale}`, the default locales would override the
custom ones, and we want the custom locales to override the default
ones so CONSUL is easier to customize.