This way only verified users will be able to access this page, which
shows the username of the receiver of the direct message. With this,
it's no longer possible for unverified users to browse direct message
URLs in order to collect usernames from every user.
As far as possible I think the code is clearer if we use CRUD actions
rather than custom actions. This will make it easier to add the action
to remove votes in the next commit.
Note that we are adding this line as we need to validate it that a vote
can be created on a comment by the current user:
```authorize! :create, Vote.new(voter: current_user, votable: @comment)```
We have done it this way and not with the following code as you might
expect, as this way two votes are created instead of one.
```load_and_authorize_resource through: :comment, through_association: :votes_for```
This line tries to load the resource @comment and through the association
"votes_for" it tries to create a new vote associated to that debate.
Therefore a vote is created when trying to authorise the resource and
then another one in the create action, when calling @comment.vote.
As far as possible I think the code is clearer if we use CRUD actions
rather than custom actions. This will make it easier to add the action
to remove votes in the next commit.
Note that we are adding this line as we need to validate it that a vote
can be created on a debate by the current user:
```authorize! :create, Vote.new(voter: current_user, votable: @debate)```
We have done it this way and not with the following code as you might
expect, as this way two votes are created instead of one.
```load_and_authorize_resource through: :debate, through_association: :votes_for```
This line tries to load the resource @debate and through the association
"votes_for" it tries to create a new vote associated to that debate.
Therefore a vote is created when trying to authorise the resource and
then another one in the create action, when calling @debate.vote_by (which
is called by @debate.register_vote).
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
By using the bindPopup function instead of the click event
popups work when using the keyboard.
Note that now we are loading all the map markers in the first
request in a single query to the database (needed when there
is a lot or markers to show). Because of that we removed the
AJAX endpoint.
The only view that linked to this action was never used and so it was
deleted in commit 0bacd5baf.
Since now the proposals controller is the only one place rendering the
`shared/map` partial, we're moving it to the proposals views.
Note we could use `acts_as_paranoid` with the `without_default_scope`
option, but we aren't doing so because it isn't possible to consider
deleted records in uniqueness validations with the paranoia gem [1].
I've added tests for these cases so we don't accidentally add
`acts_as_paranoid` in the future.
Also note we're extracting a `RowComponent` because, when
enabling/disabling a tenant, we're also enabling/disabling the link
pointing to its URL, and so we need to update the URL column after the
AJAX call.
[1] See issues 285 and 319 in https://github.com/rubysherpas/paranoia/
Note we aren't allowing to delete a tenant because it would delete all
its data, so this action is a very dangerous one. We might need to add a
warning when creating a tenant, indicating the tenant cannot be
destroyed. We can also add an action to delete a tenant which forces the
admin to write the name of the tenant before deleting it and with a big
warning about the danger of this operation.
For now, we're letting administrators of the "main" (default) tenant to
create other tenants. However, we're only allowing to manage tenants
when the multitenancy configuration option is enabled. This way the
interface won't get in the way on single-tenant applications.
We've thought about creating a new role to manage tenants or a new URL
out of the admin area. We aren't doing so for simplicity purposes and
because we want to keep CONSUL working the same way it has for
single-tenant installations, but we might change it in the future.
There's also the fact that by default we create one user with a known
password, and if by default we create a new role and a new user to
handle tenants, the chances of people forgetting to change the password
of one of these users increases dramatically, particularly if they
aren't using multitenancy.
Note that the `create` action doesn't create an image but updates an
answer instead. We're removing the references to `:create` in the
abilities since it isn't used.
In the future we might change the form to add an image to an answer
because it's been broken for ages since it shows all the attached
images.
Adding, modifiying, and/or deleting questions for an already started
poll is far away from being democratic and can lead to unwanted side
effects like missing votes in the results or stats.
So, from now on, only modifiying questions will be possible only if
the poll has not started yet.
Actions :search_booths and :search_officers in admin polls controller
are moved to other controllers since commit 20e31133a for
:search_booths and commit 19ec7f93b for :search_officers.
This then allows us to remove the code that references these actions in
the controller and in the administrator abilities.
The action and the views were almost identical, with the supports
progress and the HTML classes of the success message element being the
only exceptions; we can use CSS for the styles instead.
The `legislation_proposals#index` action was never used because it used
the same URL as `legislation_processes#proposals`.
In commit 702bfec24 we removed the view, but we forgot to remove the
controller action, the route, and some partials which were rendered from
the index view.
In the past, users had permission to edit their own legislation
proposals. However, that changed in commit ebfa3fb01, where we replaced
the `can` method with `cannot`.
An easier way to remove this permission is to simply remove the whole
statement, since by default users don't have permissions to do anything.
We're also adding a test checking users can't edit their own legislation
proposals, since it was missing.
The `edit` action is automatically authorized with the rules used for
`:update`, the same way the `new` action is authorized with the rules
used for `:create`.
So we don't need to authorize the edit and new actions.
These changes make it easier for institutions customizing Consul to
notice what they need to change if (for instance) they want users to be
able to edit investments under certain conditions.
Calculating winners before the balloting is over is useless (results
aren't published at that point) and can lead to the wrong results since
users are still voting and results might change.
And we were showing the button to calculate winners even when a budget
had finished. However, in this case the action to calculate winners did
nothing, which resulted in administrators seeing nothing happened after
pressing the button.
Note we don't cast negative votes when users remove their support. That
way we provide compatibility for institutions who have implemented real
negative votes (in case there are / will be any), and we also keep the
database meaningful: it's not that users downvoted something; they
simply removed their upvote.
Co-Authored-By: Javi Martín <javim@elretirao.net>
Co-Authored-By: Julian Nicolas Herrero <microweb10@gmail.com>
Since we're going to add an action to remove supports, having a separate
controller makes things easier.
Note there was a strange piece of code which assumed users were not
verified if they couldn't vote investments. Now the code is also
strange, since it assumes users are not verified if they can't create
votes. We might need to revisit these conditions if our logic changes in
the future.
In this page we will render a list of clickable Goals icons that will show their
targets and related local targets
Co-authored-by: Senen <senenrodero@gmail.com>
Previously the draft mode was a phase of the PB, but that had some
limitations.
Now the phase drafting disappears and therefore the PB can have the
status published or not published (in draft mode).
That will give more flexibility in order to navigate through the
different phases and see how it looks for administrators before
publishing the PB and everybody can see.
By default, the PB is always created in draft mode, so it gives you
the flexibility to adjust and modify anything before publishing it.
These cards will be displayed in the SDG homepage.
Note there seems to be a strange behavior in cancancan. If we define
these rules:
can :manage, Widget::Card, page_type: "SDG::Phase"
can :manage, Widget::Card
The expected behavior is the first rule will always be ignored because
the second one overwrites it. However, when creating a new card with
`load_and_authorize_resource` will automatically add `page_type:
"SDG::Phase"`.
Similarly, if we do something like:
can :manage, Widget::Card, id: 3
can :manage, Widget::Card
Then the new card will have `3` as an ID.
Maybe upgrading cancancan solves the issue; we haven't tried it. For now
we're defining a different rule when creating widget cards.
On production environments the application wasn't loading because
the `SDG::Manager` class was defined in two places. We don't know
the exact reasons for the conflict and why these changes fix it.
It was removed in commit 128a8164 because we hadn't reviewed it nor
tested it properly. We're now adding it again, fixing the issues we've
found while reviewing.
The link to show stats for these polls is nowhere to be seen in the
application, and these stats are included in the budget stats, so it
makes sense to restrict access to them.
When defining abilities, scopes cover more cases because they can be
used to check permissions for a record and to filter a collection. Ruby
blocks can only be used to check permissions for a record.
Note the `Budget::Phase.kind_or_later` name sounds funny, probably
because we use the word "phase" for both an an attribute in the budgets
table and an object associated with the budget, and so naming methods
for a budget phase is a bit tricky.