Commit Graph

527 Commits

Author SHA1 Message Date
Javi Martín
90f753af98 Remove tasks to upgrade to version 2.0.0
These tasks have already been executed.
2024-02-13 18:11:24 +01:00
dependabot[bot]
21d39bac62 Bump rubocop-rails from 2.20.2 to 2.21.2
Bumps [rubocop-rails](https://github.com/rubocop/rubocop-rails) from 2.20.2 to 2.21.2.
- [Release notes](https://github.com/rubocop/rubocop-rails/releases)
- [Changelog](https://github.com/rubocop/rubocop-rails/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rails/compare/v2.20.2...v2.21.2)

---
updated-dependencies:
- dependency-name: rubocop-rails
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Note version 2.21.0 relaxes the default `Include` path for
`Rails/FindEach`, and so this version can find and correct offenses
outside the `app/models/` folder [1].

Also note this version replaces `unless something.include?` with `if
something.exclude?`; since we don't use the `exclude?` method anywhere,
we're removing the `include?` method from the list of methods checked by
this cop.

Finally, the Rails/HttpStatus method now returns a false positive when
rendering a dashboard partial and passing the `status` variable. In
order to avoid this issue, we could change the name of the local
variable or move the partial to a component, but for now we're simply
excluding these files for this cop.

[1] https://github.com/rubocop/rubocop-rails/pull/1059/commits/0066b3505

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-20 14:22:09 +01:00
Senén Rodero Rodríguez
9112d2d73b Include a timestamp in every authentication logger message 2023-10-25 10:13:04 +02:00
Senén Rodero Rodríguez
b7073691f1 Log successful and failed login attempts in a separate log file
We log the login parameter and the request IP address.

Quoting the ENS:

> [op.acc.5.r5.1] Se registrarán los accesos con éxito y los fallidos.
2023-10-25 10:13:03 +02:00
Javi Martín
827bb125b2 Explicitly open markdown links in the same window
We were already opening them in the same window because we were
accidentall sanitizing the `target` attribute, but now we're making the
point more explicit.
2023-10-24 16:41:03 +02:00
Javi Martín
cdf859621e Allow links in forms to open in new tabs
We used to open these links in new tabs, but accidentally stopped doing
so in commit 75a28fafc.

While, in general, automatically opening a link in a new tab/window is a
bad idea, the exception comes when people are filling in a form and
there are links to pages that contain information which will help them
fill in a form.

There are mainly two advantages of this approach. First, it makes less
likely for people to accidentally lose the information they were filling
in. And, second, having both the form and a help page open at the same
time can make it easier to fill in the form.

However, opening these links in new tabs also has disadvantages, like
taking control away from people or making it harder to navigate through
pages when using a mobile phone.

So this is a compromise solution.
2023-10-23 18:19:48 +02:00
Javi Martín
f87d4b589d Add and apply Naming/BlockForwarding rubocop rule
This syntax has been added in Ruby 3.1.

Not using a variable name might not be very descriptive, but it's just
as descriptive as using "block" as a variable name. Using just `&` we
get the same amount of information than using `&block`: that we're
passing a block.

We're still using `&action` in `around_action` methods because here we
aren't using a generic name for the variable, so (at least for now) we
aren't running this cop on controllers using `around_action`.
2023-09-12 15:17:28 +02:00
Javi Martín
28aafbd4bc Add and apply Style/InvertibleUnlessCondition rule
This rule was added in rubocop 1.44.0. It's useful to avoid accidental
`unless !condition` clauses.

Note we aren't replacing `unless zero?` with `if nonzero?` because we
never use `nonzero?`; using it sounds like `if !zero?`.

Replacing `unless any?` with `if none?` is only consistent if we also replace
`unless present?` with `if blank?`, so we're also adding this case. For
consistency, we're also replacing `unless blank?` with `if present?`.

We're also simplifying code dealing with `> 0` conditions in order to
make the code (hopefully) easier to understand.

Also for consistency, we're enabling the `Style/InverseMethods` rule,
which follows a similar idea.
2023-09-07 19:14:03 +02:00
Javi Martín
a1439d0790 Apply Layout/LineLength rubocop rule
Note we're excluding a few files:

* Configuration files that weren't generated by us
* Migration files that weren't generated by us
* The Gemfile, since it includes an important comment that must be on
  the same line as the gem declaration
* The Budget::Stats class, since the heading statistics are a mess and
  having shorter lines would require a lot of refactoring
2023-08-30 14:46:35 +02:00
Javi Martín
8898c30f55 Rename AvailableLocales.available_locales method
I'm not sure whether we should rename the class instead. I'm renaming
the method because renaming the class would require more changes.
2023-08-30 14:46:35 +02:00
Javi Martín
36c3ba6601 Extract variable in manager authenticator method 2023-08-30 14:46:35 +02:00
Javi Martín
8b13daad95 Add and apply rules for multi-line hashes
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.
2023-08-18 14:56:16 +02:00
Javi Martín
d137df67bf Fix release version number in rake tasks
When we added the tasks, we thought the new version was going to be
version 1.6.0, but in the end we're renaming it to version 2.0.0.
2023-07-13 17:48:26 +02:00
Javi Martín
a668ecd1a8 Merge pull request #5136 from Meet-Democracy/Legislation-draft-render-markdown-tables
Render markdown tables in legislation draft
2023-06-30 00:09:33 +02:00
Javi Martín
af618eaa45 Extract markdown helper logic to a class
This way it'll be easier for other Consul installations to overwrite
parts of the code, like the default options.
2023-06-29 20:48:01 +02:00
Karim Semmoud
3faaa8521d Render markdown tables in legislation draft
* Add Tables option to Redcarpet in Legislation draft

* Allow table tags in Admin Legislation Sanitizer

* Add Test to render markdown tables in Legislation drafts

* Add Test for Admin Legislation Sanitizer

We include test for image, table and h1 to h6 tags and additional tests to strengthen the allowed and disallowed parameters

* Add Table from markdown test in System and Factories

* Add test to render  tables for admin user

* Remove comment line about Redcarpet options

* Edit custom css for legislation draft table to make it responsive
2023-06-29 20:48:01 +02:00
Senén Rodero Rodríguez
83b5965821 Fix Serbian locale code
I accidentally duplicated the locale code within
commit 3c3ff65.
2023-06-27 18:06:19 +02:00
Senén Rodero Rodríguez
3c3ff65be1 Update search dictionaries
Since the creation of this list 3 years ago we added more languages to the
application and PostgreSQL added more dictionaries too.
2023-06-23 12:53:43 +02:00
Senén Rodero Rodríguez
1d7c821935 Sort languages alphabetically
So it's easier to know where to add new ones when needed.
2023-06-23 12:53:41 +02:00
taitus
306e7356c3 Allow translate locales that need to be mapping
It has been detected that for the :pt-BR, :zh-CN and :zh-TW locales,
the translate button was being displayed, but when requesting the
translation, the remote translation validation failed due to:

'''
validates :locale, inclusion: { in: ->(_) {
     RemoteTranslations::Microsoft::AvailableLocales.available_locales }}
'''

That available_locales method did not contemplate these 3 languages
in the format used by the application.

To solve this problem the api response is mapped to return all
locales in the format expected by the application.

Add remote translation model test to ensure that a remote translation
is valid when its locale is pt-BR.

Co-Authored-By: Javi Martín <35156+javierm@users.noreply.github.com>
2023-03-15 15:52:51 +01:00
taitus
c64b49b128 Change gem from TranslatorText to BingTranslator
TranslatorText isn't compatible with Ruby 3, so we need to use a
different gem.

The 'translator-text' gem response was an array of one or more objects.
Now with the 'bing_translator' gem the response is an array with one or
several translated texts.

We remove the concept of object in the code. And we also remove the
"create_response" method from the specs since it is no longer necessary
to emulate that object and we can simply use arrays with texts to emulate
the new response.
2023-03-09 06:00:41 +01:00
Javi Martín
63d0e316cf Replace instance variable usage with a method
We usually use this approach because methods are easier to override and
stub.
2023-03-09 05:50:27 +01:00
Javi Martín
b030a198a3 Include SentencesParser inside the right class
We were including it in the Object class, making its methods
available everywhere.
2023-03-09 05:50:16 +01:00
Javi Martín
efc46fe6c8 Add Performance/StringIdentifierArgument rule
It was added in rubocop-performance 1.13.0. We were already applying it
in most places.

We aren't adding it for performance reasons but in order to make the
code more consistent.
2023-01-11 16:05:20 +01:00
Javi Martín
edd47877c2 Extract methods to get tenant subfolder/file paths
We were using the same logic in many different places, so we're
simplifying the code. I'm not convinced about the method names, though,
so we might change them in the future.

Note using this method for the default tenant in the `TenantDiskService`
class resulted in a `//` in the path, which is probably harmless but
very ugly and it also generates a different key than the one we got
until now. I've added an extra test to make sure that isn't the case.
2022-11-11 01:41:14 +01:00
Eduardo Vilar
0ea61b9b61 Allow different omniauth settings per tenant
Co-Authored-By: Javi Martín <javim@elretirao.net>
2022-11-11 01:39:30 +01:00
Javi Martín
18f1d5c1a3 Allow different remote translation keys per tenant
Note we don't need to update the tests; the tests themselves help us
confirm that `Rails.application.secrets` and `Tenant.current_secrets`
return the same object on single-tenant applications.
2022-11-11 01:39:29 +01:00
Javi Martín
338f4929ca Allow different manager auth settings per tenant 2022-11-11 01:39:29 +01:00
Javi Martín
eb2cf00ddf Allow different SMS settings for different tenants 2022-11-11 01:39:29 +01:00
Javi Martín
314ce70000 Use a different attachments folder per tenant
While this is not strictly necessary, it can help moving the data of one
tenant to a different server or removing it.

Note we're using subfolders inside the `tenants` subfolder. If we simply
used subfolders with the schema names, if the schema names were, for
instance, language codes like `es`, `en`, `it`, ... they would conflict
with the default subfolders used by Active Storage.
2022-11-11 01:39:19 +01:00
Javi Martín
9759288f3b Run DB rake tasks on all tenants
Some tasks don't have to run on every tenant. The task to calculate the
TSV is only done for records which were present before we added the TSV
column, and that isn't going to happen in any tenants because we added
the TSV column before adding the tenants table. Similarly, the migration
needed for existing polls isn't necessary because there weren't any
tenants before we allowed to set the starting/ending time to polls.

We aren't adding any tests for these tasks because tests for rake tasks
are slow and tests creating tenants are also slow, making the
combination of the two even slower, particularly if we add tests for
every single task we're changing. We're adding tests for the
`.run_on_each` method instead.
2022-11-09 18:19:20 +01:00
Javi Martín
fe9463cb5f Allow specifying the tenant in budget tasks
The `budgets📧selected` and `budgets📧unselected` tasks are
supposed to be run manually because they only make sense at a specific
point during the life of a budget.

However, they would only run on the default tenant, and it was
impossible to run them on a different tenant.

So we're introducing an argument in the rake task accepting the name of
the tenant whose users we want to send emails to.
2022-11-09 18:19:20 +01:00
Javi Martín
796214528e Send emails to current budget authors in rake tasks
We were using `Budget.last`, but the last budget might not be published
yet.

I must admit I don't know whether these tasks are useful, but I'm not
removing them because I'm not sure that won't harm any CONSUL
installations.
2022-11-09 18:19:20 +01:00
Javi Martín
a98c363d4d Allow seeding a specific tenant with db:dev_seed
Until now, running `db:dev_seed` created development data for the
default tenant but it was impossible to create this data for other
tenants.

Now the tenant can be provided as a parameter.

Note that, in order to be able to execute this task twice while running
the tests, we need to use `load` instead of `require_relative`, since
`require_relative` doesn't load the file again if it's already loaded.

Also note that having two optional parameters in a rake task results in
a cumbersome syntax to execute it. To avoid this, we're simply removing
the `print_log` parameter, which was used mainly for the test
environment. Now we use a different logic to get the same result.

From now on it won't be possible to pass the option to avoid the log in
the development environment. I don't know a developer who's ever used
this option, though, and it can always be done using `> /dev/null`.
2022-11-09 18:19:20 +01:00
Javi Martín
c483c6036a Install extensions in a shared schema
This way all tenants will be able to access them instead of just the
default one.

The apartment gem recommends using a rake task instead of a migration,
but that's a solution which is primarily meant for new installations.
Migrations are easier to execute on existing installations.

However, since this migration doesn't affect the `schema.rb` file, we
still need to make sure the shared schema is created in tasks which do
not execute migrations, like `db:schema:load` or `db:test:prepare`, just
like the apartment gem recommends. That's why we're enhancing these
tasks so they execute this migration.

Note that there might be cases where the database user isn't a superuser
(as it's usually the case on production environments), meaning commands
to create, alter or drop extensions will fail. There's also the case
where users don't have permissions to create schemas, which is needed in
order to create the shared extensions schema and the schemas used by the
tenants. For these reasons, we're minimizing the number of commands, and
so we only alter or create extensions when it is really necessary.

When users don't have permission, we aren't running the commands but
showing a warning with the steps needed to run the migration manually.
This is only necessary on installations which are going to use
multitenancy; single-tenant applications upgrading don't need to run
this migration, and that's why we aren't raising exceptions when we
can't run it.

For new installations, we'll change the CONSUL installer so extensions
are automatically created in the shared schema.

Also note the plpgsql extension is not handled here. This is a special
extension which must be installed on the pg_catalog schema, which is
always in the search path and so is shared by all tenants.

Finally, we also need to change the `database.yml` file in order to
search for shared extensions while running migrations or model tests,
since none of our enabled extensions are executed during migrations;
we're also adding a rake task for existing installations. Quoting the
apartment documentation:

> your database.yml file must mimic what you've set for your default and
> persistent schemas in Apartment. When you run migrations with Rails,
> it won't know about the extensions schema because Apartment isn't
> injected into the default connection, it's done on a per-request
> basis.
2022-11-09 17:53:31 +01:00
Javi Martín
4a851c0d82 Add and apply Style/MapToHash rubocop rule
This rule was added in Rubocop 1.24.0. Applying it slightly simplifies
the code.
2022-10-19 14:26:49 +02:00
Javi Martín
f15f250150 Remove unused task to reset the vote counters
This task was added in commit 2b9b78e38. According to the notes in the
pull request introducing the change:

> If you have had [map validations] in production, you might want to run
> the rake task votes:reset_vote_counter to reset the cached votes
> counter. Otherwise, until there is another vote for a proposal, the
> counter will not be updated, and there might be some votes which are
> not yet displayed

In short, this was a task that was introduced for a specific release and
had to be run manually. So we can remove it now.
2022-10-02 16:52:59 +02:00
Javi Martín
e221c3cd1a Remove unused task to send dashboard notifications
This task was "temporarily" removed in commit 7b6619528. Since that was
done three and a half years ago, right after the dashboard was
introduced, I think it's time to make this "temporary" measure a bit
more permanent ;).
2022-10-02 16:52:59 +02:00
Javi Martín
5719f32758 Remove tasks to upgrade to version 1.5.0
These tasks are not needed for new installations, and in existing
installations they've already been executed when upgrading to version
1.5.0.
2022-10-02 16:52:59 +02:00
Javi Martín
5a0fde4048 Allow selecting the time when a poll starts/ends
We were already saving it as a time, but we didn't offer an interface to
select the time due to lack of decent browser support for this field
back when this feature was added.

However, nowadays all major browsers support this field type and, at the
time of writing, at least 86.5% of the browsers support it [1]. This
percentage could be much higher, since support in 11.25% of the browsers
is unknown.

Note we still need to support the case where this field isn't supported,
and so we offer a fallback and on the server side we don't assume we're
always getting a time. We're doing a strange hack so we set the field
type to text before changing its value; otherwise old Firefox browsers
crashed.

Also note that, until now, we were storing end dates in the database as
a date with 00:00 as its time, but we were considering the poll to be
open until 23:59 that day. So, in order to keep backwards compatibility,
we're adding a task to update the dates of existing polls so we get the
same behavior we had until now.

This also means budget polls are now created so they end at the
beginning of the day when the balloting phase ends. This is consistent
with the dates we display in the budget phases table.

Finally, there's one test where we're using `beginning_of_minute` when
creating a poll. That's because Chrome provides an interface to enter a
time in a `%H:%M` format when the "seconds" value of the provided time
is zero. However, when the "seconds" value isn't zero, Chrome provides
an interface to enter a time in a `%H:%M:%S` format. Since Capybara
doesn't enter the seconds when using `fill_in` with a time, the test
failed when Capybara tried to enter a time in the `%H:%M` format when
Chrome expected a time in the `%H:%M:%S` format.

To solve this last point, an alternative would be to manually provide
the format when using `fill_in` so it includes the seconds.

[1] https://caniuse.com/mdn-html_elements_input_type_datetime-local
2022-09-14 15:14:23 +02:00
Jacek Skrzypacz
2af7e32415 Add search form for hidden content
Added search for comments and proposal_notifications, added tsv column
for search and rake tasks to update/create tsv vector.
2022-08-23 14:30:38 +02:00
Finn Heemeyer
c984e666ff Add new GraphQL types, schema (with fields) & base mutation
The current consul GraphQL API has two problems.

1) It uses some unnecessary complicated magic to automatically create
   the GraphQL types and querys using an `api.yml` file. This approach
   is over-engineered, complex and has no benefits. It's just harder to
   understand the code for people which are not familiar with the
   project (like me, lol).

2) It uses a deprecated DSL [1] that is soon going to be removed from
   `graphql-ruby` completely. We are already seeing deprecation warning
   because of this (see References).

There was one problem. I wanted to create the API so that it is fully
backwards compatible with the old one, BUT the old one uses field names
which are directly derived from the ruby code, which results in
snake_case field names - not the GraphQL way. When I'm using the
graphql-ruby Class-based syntax, it automatically creates the fields in
camelCase, which breaks backwards-compatibility.

So I've added deprecated snake_case field names to keep it
backwards-compatible.

[1] https://graphql-ruby.org/schema/class_based_api.html
2022-06-01 11:41:09 +02:00
taitus
923c2a7ee2 Check labels styles
We are use a display: block style for labels containing check boxes inside
them, and the label has a width of 100%.

This means that clicking on the blank space on the right of the label text
will check/uncheck the checkbox. To avoid this behaviour we modify the
"display" attribute of the labels.

In order to prevent unexpected behaviour in terms_of_service form labels,
we add specific css for this case when define a checkbox within the
.actions class.
2022-04-04 18:55:56 +02:00
Javi Martín
1fa05b1f54 Fix crash on attributes with interpolation arguments
The application crashed when we generated hints to attributes with
interpolation arguments in their `human_attribute_name`.

When generating the hint, we used the `custom_label` method to generate
a label and get the `for` attribute and, since we weren't passing a
text, it used the default human attribute name for the field. However,
it crashes if the default attribute name requires an interpolation
argument.

So now, since we were only using the `custom_label` method in order to
get the `for` attribute, we're simply passing an arbitrary text to the
method.
2022-03-28 14:55:42 +02:00
taitus
d719b2291e Do not generate an empty hint element when there's an empty hint 2022-03-28 14:55:42 +02:00
Javi Martín
7212657c02 Remove Paperclip and use just Active Storage 2022-02-23 18:43:48 +01:00
Javi Martín
8c82ff290b Handle CKEditor attachments with Active Storage
The code is based on what's generated using CKEditor's code generator.

We're doing one minor change to the `Ckeditor::Backend::ActiveStorage`
module; we're assigning the data in a `before_validation` instead of a
`before_save` callback. Validations with `file_validations` didn't work
otherwise; it looks like this backend was written with
`active_storage_validations` in mind [1].

Note we don't need to update the `name` column in the attachments table
because, when using Active Storage, CKEditor uses both `data` (as
attribute accessor) and `storage_data` (as attachment attribute).

[1] https://github.com/galetahub/ckeditor/blob/f9e48420ccb6dc/lib/generators/ckeditor/templates/active_record/active_storage/ckeditor/picture.rb#L4
2022-02-23 18:21:38 +01:00
Javi Martín
e0e35298d5 Use Active Storage to handle cached attachments
This fixes a few issues we've had for years.

First, when attaching an image and then sending a form with validation
errors, the image preview would not be rendered when the form was
displayed once again. Now it's rendered as expected.

Second, when attaching an image, removing it, and attaching a new
one, browsers were displaying the image preview of the first one. That's
because Paperclip generated the same URL from both files (as they both
had the same hash data and prefix). Browsers usually cache images and
render the cached image when getting the same URL.

Since now we're storing each image in a different Blob, the images have
different URLs and so the preview of the second one is correctly
displayed.

Finally, when users downloaded a document, they were getting files with
a very long hexadecimal hash as filename. Now they get the original
filename.
2022-02-23 18:21:38 +01:00
Javi Martín
cd58b96fad Support geozone segments with non-Latin characters
The `parameterize` method uses the `I18n.transliterate` method, whose
documentation says:

```
I18n.transliterate("Ærøskøbing")
=> "AEroskobing"

I18n.transliterate("日本語")
=> "???"
```

That means we can't use it for dictionaries where characters don't have
a transliteration to the latin alphabet.

So we're changing the code in order to only transliterate characters
with a transliteration to the latin alphabet.

Note the first example ("Česká republika") already worked with the
previous code; the test has been added to make sure accented characters
are handled properly.
2021-12-20 17:18:53 +01:00
rgarcia
25a8950330 Add geozones as user segments 2021-12-20 15:30:42 +01:00