decidim 0.23.5 → 0.24.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim might be problematic. Click here for more details.

Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -0
  3. data/docs/README.adoc +74 -0
  4. data/docs/antora.yml +7 -0
  5. data/docs/modules/configure/pages/environment_variables.adoc +69 -0
  6. data/docs/modules/configure/pages/index.adoc +16 -0
  7. data/docs/modules/configure/pages/initializer.adoc +376 -0
  8. data/docs/modules/customize/assets/images/header-snippet.png +0 -0
  9. data/docs/modules/customize/assets/images/menu.png +0 -0
  10. data/docs/modules/customize/assets/images/organization-colors.png +0 -0
  11. data/docs/modules/customize/pages/authorizations.adoc +22 -0
  12. data/docs/{customization/code.md → modules/customize/pages/code.adoc} +12 -9
  13. data/docs/{customization/gemfile.md → modules/customize/pages/gemfile.adoc} +5 -4
  14. data/docs/modules/customize/pages/images.adoc +7 -0
  15. data/docs/modules/customize/pages/javascript.adoc +59 -0
  16. data/docs/modules/customize/pages/menu.adoc +25 -0
  17. data/docs/modules/customize/pages/oauth.adoc +33 -0
  18. data/docs/modules/customize/pages/styles.adoc +64 -0
  19. data/docs/modules/customize/pages/texts.adoc +30 -0
  20. data/docs/modules/customize/pages/users_registration_mode.adoc +17 -0
  21. data/docs/{customization/views.md → modules/customize/pages/views.adoc} +13 -13
  22. data/docs/modules/develop/assets/images/barcelona.png +0 -0
  23. data/docs/modules/develop/assets/images/helsinki.png +0 -0
  24. data/docs/modules/develop/assets/images/indices.png +0 -0
  25. data/docs/{advanced/api.md → modules/develop/pages/api.adoc} +2 -2
  26. data/docs/{advanced/authorship.md → modules/develop/pages/authorable.adoc} +5 -5
  27. data/docs/modules/develop/pages/c4_component.adoc +91 -0
  28. data/docs/modules/develop/pages/c4_container.adoc +42 -0
  29. data/docs/modules/develop/pages/c4_context.adoc +35 -0
  30. data/docs/{advanced/components.md → modules/develop/pages/components.adoc} +47 -10
  31. data/docs/{advanced/content_blocks.md → modules/develop/pages/content_blocks.adoc} +16 -13
  32. data/docs/{advanced/content_processors.md → modules/develop/pages/content_processors.adoc} +25 -19
  33. data/docs/modules/develop/pages/data-picker.adoc +85 -0
  34. data/docs/modules/develop/pages/deploy.adoc +15 -0
  35. data/docs/modules/develop/pages/docker.adoc +12 -0
  36. data/docs/{advanced/embeddable.md → modules/develop/pages/embeddable.adoc} +6 -6
  37. data/docs/{advanced/endorsable.md → modules/develop/pages/endorsable.adoc} +31 -25
  38. data/docs/{advanced/fixing_locales.md → modules/develop/pages/fixing_locales.adoc} +36 -23
  39. data/docs/{advanced/followers.md → modules/develop/pages/followable.adoc} +9 -8
  40. data/docs/modules/develop/pages/guide.adoc +16 -0
  41. data/docs/modules/develop/pages/guide_architecture.adoc +17 -0
  42. data/docs/modules/develop/pages/guide_changelog.adoc +8 -0
  43. data/docs/modules/develop/pages/guide_commands.adoc +86 -0
  44. data/docs/modules/develop/pages/guide_development_app.adoc +44 -0
  45. data/docs/modules/develop/pages/guide_development_with_custom_seed_data.adoc +31 -0
  46. data/docs/modules/develop/pages/guide_development_with_localhost_ssl.adoc +63 -0
  47. data/docs/modules/develop/pages/guide_example_apps.adoc +59 -0
  48. data/docs/modules/develop/pages/guide_git_conventions.adoc +75 -0
  49. data/docs/modules/develop/pages/guide_github_projects.adoc +42 -0
  50. data/docs/modules/develop/pages/guide_semver.adoc +7 -0
  51. data/docs/{advanced/how_to_fix_metrics.md → modules/develop/pages/how_to_fix_metrics.adoc} +76 -59
  52. data/docs/modules/develop/pages/machine_translations.adoc +42 -0
  53. data/docs/modules/develop/pages/managing_translations_i18n.adoc +24 -0
  54. data/docs/modules/develop/pages/maps.adoc +499 -0
  55. data/docs/modules/develop/pages/metrics.adoc +119 -0
  56. data/docs/{advanced/modules.md → modules/develop/pages/modules.adoc} +16 -6
  57. data/docs/{advanced/newsletter_templates.md → modules/develop/pages/newsletter_templates.adoc} +12 -10
  58. data/docs/{advanced/notifications.md → modules/develop/pages/notifications.adoc} +40 -38
  59. data/docs/{advanced/open-data.md → modules/develop/pages/open-data.adoc} +4 -3
  60. data/docs/modules/develop/pages/permissions.adoc +92 -0
  61. data/docs/{advanced/profiling.md → modules/develop/pages/profiling.adoc} +15 -12
  62. data/docs/modules/develop/pages/releases.adoc +148 -0
  63. data/docs/modules/develop/pages/reportable.adoc +31 -0
  64. data/docs/modules/develop/pages/security.adoc +33 -0
  65. data/docs/{advanced/share_tokens.md → modules/develop/pages/share_tokens.adoc} +18 -14
  66. data/docs/{advanced/templates.md → modules/develop/pages/templates.adoc} +14 -12
  67. data/docs/{advanced/testing.md → modules/develop/pages/testing.adoc} +21 -20
  68. data/docs/{advanced/activity_log.md → modules/develop/pages/traceable.adoc} +31 -26
  69. data/docs/modules/develop/pages/turbolinks.adoc +7 -0
  70. data/docs/{advanced/view_hooks.md → modules/develop/pages/view_hooks.adoc} +29 -23
  71. data/docs/modules/develop/pages/view_models_aka_cells.adoc +105 -0
  72. data/docs/modules/install/pages/checklist.adoc +39 -0
  73. data/docs/modules/install/pages/index.adoc +148 -0
  74. data/docs/{manual-installation.md → modules/install/pages/manual.adoc} +54 -42
  75. data/docs/modules/install/pages/update.adoc +95 -0
  76. data/docs/{services/activejob.md → modules/services/pages/activejob.adoc} +3 -3
  77. data/docs/modules/services/pages/elections_bulletin_board.adoc +52 -0
  78. data/docs/{services/etherpad.md → modules/services/pages/etherpad.adoc} +15 -12
  79. data/docs/modules/services/pages/maps.adoc +311 -0
  80. data/docs/modules/services/pages/smtp.adoc +10 -0
  81. data/docs/modules/services/pages/social_providers.adoc +122 -0
  82. data/lib/decidim/gem_manager.rb +5 -5
  83. data/lib/decidim/version.rb +1 -1
  84. metadata +135 -98
  85. data/README.md +0 -157
  86. data/docs/advanced/add_authorizable_action.md +0 -63
  87. data/docs/advanced/adding_fixtures_aka_dummy_content.md +0 -9
  88. data/docs/advanced/data-picker.md +0 -83
  89. data/docs/advanced/deploy.md +0 -9
  90. data/docs/advanced/how_to_create_a_module.md +0 -9
  91. data/docs/advanced/machine_translation_service.md +0 -12
  92. data/docs/advanced/managing_translations_i18n.md +0 -24
  93. data/docs/advanced/metrics.md +0 -114
  94. data/docs/advanced/permissions.md +0 -23
  95. data/docs/advanced/releases.md +0 -114
  96. data/docs/advanced/tradeoffs.md +0 -14
  97. data/docs/advanced/view_models_aka_cells.md +0 -99
  98. data/docs/checklist.md +0 -55
  99. data/docs/customization/authorizations.md +0 -5
  100. data/docs/customization/images.md +0 -7
  101. data/docs/customization/javascript.md +0 -9
  102. data/docs/customization/machine_translations.md +0 -30
  103. data/docs/customization/maps.md +0 -610
  104. data/docs/customization/oauth.md +0 -50
  105. data/docs/customization/styles.md +0 -11
  106. data/docs/customization/texts.md +0 -27
  107. data/docs/customization/users_registration_mode.md +0 -17
  108. data/docs/development_guide.md +0 -166
  109. data/docs/getting_started.md +0 -191
  110. data/docs/possible_flows_for_proposal.png +0 -0
  111. data/docs/services/analytics.md +0 -23
  112. data/docs/services/elections_bulletin_board.md +0 -38
  113. data/docs/services/maps.md +0 -362
  114. data/docs/services/social_providers.md +0 -98
@@ -0,0 +1,119 @@
1
+ = Metrics
2
+
3
+ Metrics calculations must be executed everyday. Some `rake task` have been added to perform it.
4
+
5
+ * To execute all metrics at once. Related to previous date from _today_
6
+ +
7
+ [source,ruby]
8
+ ----
9
+ bundle exec rake decidim:metrics:all
10
+ ----
11
+
12
+ * To execute an specific metric. Related to previous date from _today_
13
+ +
14
+ [source,ruby]
15
+ ----
16
+ bundle exec rake decidim:metrics:one["<metric name>"]
17
+ ----
18
+
19
+ * To execute metrics for a given date (all or an specific one)
20
+ +
21
+ [source,ruby]
22
+ ----
23
+ bundle exec rake decidim:metrics:all["YYYY-MM-DD"]
24
+ bundle exec rake decidim:metrics:one["<metric name>","YYYY-MM-DD"]
25
+ ----
26
+
27
+ * It is possible to rebuild one or all metrics since some specific day. This is useful in case current metrics are no generated or corrupt. *Depending on the size of the database this can take a long time!*. The command will execute the same calculations as the commands above for *each* day between _today_ and the date specified.
28
+ * To rebuild metrics since a given date (all or an specific one)
29
+ +
30
+ [source,ruby]
31
+ ----
32
+ bundle exec rake decidim:metrics:rebuild["YYYY-MM-DD"]
33
+ bundle exec rake decidim:metrics:rebuild["<metric name>","YYYY-MM-DD"]
34
+ ----
35
+
36
+ == Available metrics
37
+
38
+ * Use the command `decidim:metrics:list` to list all available metrics using the console:
39
+
40
+ [source,ruby]
41
+ ----
42
+ bundle exec rake decidim:metrics:list
43
+ ----
44
+
45
+ Currently, available metrics are:
46
+
47
+ * *users*, created `Users`
48
+ * *proposals*, published, not withdrawn and not _hidden_ `Proposals`
49
+ * *accepted_proposals*, accepted `Proposals`
50
+ * *supports*, supports given to `Proposals`
51
+ * *assemblies*, published `Assemblies`
52
+ * *participatory_processes*, published `ParticipatoryProcesses`
53
+ * *results*, `Results` in `Accountability`
54
+ * *comments*, `Comments` generated by users, related to public elements and not _hidden_
55
+ * *meetings*, public `Meetings`
56
+
57
+ Only available for `ParticipatorySpaces` (restricted to `ParticipatoryProcesses`)
58
+
59
+ * *participants*, unique users who make at least one of the following actions:
60
+ ** Answer a survey
61
+ ** Create a debate
62
+ ** Create a proposal
63
+ ** Endorse a proposal
64
+ ** Leave a comment
65
+ ** Support a proposal
66
+ ** Vote a participatory budgeting project
67
+ * *followers*, unique users who follow any participatory element in a `ParticipatorySpace`
68
+ * *endorsements*, number of `Endorsements` in `Proposals`, within a `ParticipatorySpace`
69
+ * *debates*, number of `Debates` within a `ParticipatorySpace`
70
+ * *survey_answers*, number of answered `Surveys` by users within a `ParticipatorySpace`
71
+
72
+ == Configuration
73
+
74
+ * A *crontab* line must be added to your server to maintain them updated daily. You could use https://github.com/javan/whenever[Whenever] to manage it directly from the APP. You probably want to schedule a `bundle exec rake decidim:metrics:all` every night.
75
+ * An *ActiveJob* queue, like https://github.com/mperham/sidekiq[Sidekiq] or https://github.com/collectiveidea/delayed_job/[DelayedJob]
76
+
77
+ == Persistence
78
+
79
+ The metrics module percomutes calculations and persists them into
80
+ `decidim_metrics` database table. So this module only uses one single table to
81
+ persist metrics from all times and types.
82
+
83
+ The `decidim_metrics` table has the following fields:
84
+
85
+ * `day`: the day for which the metric has been computed.
86
+ * `metric_type`: the type of the metric. One of: users, proposals, accepted_proposals, supports, assemblies.
87
+ * `cumulative`: quantity accumulated to day `"day`".
88
+ * `quantity`: quantity for the current day, `"day`".
89
+ * `decidim_organization_id`: the FK to the organization to which this Metric belongs to.
90
+ * `participatory_space_type` + `participatory_space_id`: the FK to the participatory space to which this Metric belongs to, if any.
91
+ * `related_object_type` + `related_object_id`: the FK to the object to which this Metric belongs to, if any.
92
+ * `decidim_category_id`: the FK to the category for this Metric, if any.
93
+
94
+ Relations around `decidim_metrics` table:
95
+
96
+ [source,ascii]
97
+ ----
98
+ +------------------------+
99
+ +--------------+ | ParticipatoryProcesses |
100
+ | Organization | +----+------------------------+
101
+ +------+-------+ |
102
+ | +--------------------+ | +------------+
103
+ | | | +----+ Assemblies |
104
+ | +----->+ ParticipatorySpace +<----+ +------------+
105
+ | | | | | +-------------+
106
+ | | +--------------------+ +----+ Initiatives |
107
+ | | | +-------------+
108
+ | | |
109
+ | | | +---------------+
110
+ +-----+-------+---+ +----+ Consultations |
111
+ | | +---------------+
112
+ | decidim_metrics |
113
+ | |
114
+ +--------+--------+ +----------------+
115
+ | | related_object |
116
+ +--------------->+ |
117
+ | [polymorphic] |
118
+ +----------------+
119
+ ----
@@ -1,15 +1,26 @@
1
- # Modules
1
+ = Modules
2
2
 
3
3
  Modules are subapplications that are run as application plugins.
4
4
  They're used to define pieces of functionality that are pluggable to Decidim.
5
5
 
6
6
  Decidim's modules are no more than Ruby on Rails engines that should be required in the application's `Gemfile`.
7
7
 
8
- ## Example
8
+ You can see some of our more popular modules at https://decidim.org/modules[Decidim's Modules].
9
+
10
+ == Types
11
+
12
+ You can have multiple modules types:
13
+
14
+ * For Spaces
15
+ * For xref:develop:components.adoc[Components]
16
+ * For Verifications
17
+
18
+ == Example
9
19
 
10
20
  A typical engine looks like the following:
11
21
 
12
- ```ruby
22
+ [source,ruby]
23
+ ----
13
24
  module Decidim
14
25
  module Verifications
15
26
  module MyVerifier
@@ -39,14 +50,13 @@ module Decidim
39
50
  end
40
51
  end
41
52
  end
42
- ```
53
+ ----
43
54
 
44
55
  It is a standard Ruby on Rails engine.
45
56
 
46
- ## Decidim gotchas with engines
57
+ == Decidim gotchas with engines
47
58
 
48
59
  If you have an external module that defines rake tasks and more than one
49
60
  engine, you probably want to add `paths["lib/tasks"]= nil` to all engines but
50
61
  the main one, otherwise the tasks you define are probably running multiple
51
62
  times unintentionally. Check #3892 for more details.
52
-
@@ -1,14 +1,15 @@
1
- # Newsletter templates
1
+ = Newsletter templates
2
2
 
3
3
  The newsletter templates allow the user to select a template amongst a set of of them, and use it as base to send newsletters. This allow for more customization on newsletter, tematic newsletters, etc.
4
4
 
5
- Code-wise, they use the content blocks system internally, so [check the docs](https://github.com/decidim/decidim/blob/master/docs/advanced/content_blocks.md) for that section first.
5
+ Code-wise, they use the content blocks system internally, so https://github.com/decidim/decidim/blob/develop/docs/advanced/content_blocks.md[check the docs] for that section first.
6
6
 
7
- ## Adding a new template
7
+ == Adding a new template
8
8
 
9
9
  You'll first need to register the template as a content block, but specifying `:newsletter_template` as its scope:
10
10
 
11
- ```ruby
11
+ [source,ruby]
12
+ ----
12
13
  Decidim.content_blocks.register(:newsletter_template, :my_template) do |content_block|
13
14
  content_block.cell "decidim/newsletter_templates/my_template"
14
15
  content_block.settings_form_cell = "decidim/newsletter_templates/my_template_settings_form"
@@ -31,7 +32,7 @@ Decidim.content_blocks.register(:newsletter_template, :my_template) do |content_
31
32
  )
32
33
  end
33
34
  end
34
- ```
35
+ ----
35
36
 
36
37
  You'll need to add this into an initializer. Note that if you're adding this from a module, then you need to add it from the `engine.rb` file (check the docs for content blocks for more info).
37
38
 
@@ -43,15 +44,16 @@ Then we define the cell that will be used to render the form in the admin sectio
43
44
 
44
45
  In the third line inside the block we define the I18n path to the public name of the template. This name will serve as identifier for the users who write the newsletters, so be sure to make it descriptive.
45
46
 
46
- After that we define the images this newsletter supports. We give it a unique name, the class name of the uploader we'll use (the example one is the default one, but you might want to customize this value) and a way to preview this image. This preview image will only be used in the "Preview" page of the template, it's not a fallback. If you want a fallback, please implement it through a custom uploader (see `carrierwave`'s docs for that). There's no limit of the amount of images you add.
47
+ After that we define the images this newsletter supports. We give it a unique name, the class name of the uploader we'll use (the example one is the default one, but you might want to customize this value) and a way to preview this image. This preview image will only be used in the "Preview" page of the template, it's not a fallback. If you want a fallback, please implement it through a custom uploader (see ``carrierwave``'s docs for that). There's no limit of the amount of images you add.
47
48
 
48
49
  Finally, we define the attributes for the newsletter. In this case we define a body attribute, which is a translatable text. Whether this text require an editor or not will be defined by the settings cell. We also have a way to preview that attribute. There's no limit on the number of attributes you define.
49
50
 
50
- ## Interpolating the recipient name
51
+ == Interpolating the recipient name
51
52
 
52
- Decidim accepts `%{name}` as a placeholder for the recipient name. If you want your template to use it, you'll need to call `parse_interpolations` in your public cell:
53
+ Decidim accepts `+%{name}+` as a placeholder for the recipient name. If you want your template to use it, you'll need to call `parse_interpolations` in your public cell:
53
54
 
54
- ```ruby
55
+ [source,ruby]
56
+ ----
55
57
  class Decidim::NewsletterTemplates::MyTemplate < Decidim::ViewModel
56
58
  include Decidim::NewslettersHelper
57
59
 
@@ -59,6 +61,6 @@ class Decidim::NewsletterTemplates::MyTemplate < Decidim::ViewModel
59
61
  parse_interpolations(uninterpolated_body, recipient_user, newsletter.id)
60
62
  end
61
63
  end
62
- ```
64
+ ----
63
65
 
64
66
  The newsletter subject is automatically interpolated.
@@ -1,19 +1,20 @@
1
- # Notifications
1
+ = Notifications
2
2
 
3
3
  In Decidim, notifications may mean two things:
4
4
 
5
- - he concept of notifying an event to a user. This is the wider use of "notification".
6
- - the notification's participant space, which lists the `Decidim::Notification`s she has received.
5
+ * he concept of notifying an event to a user. This is the wider use of "notification".
6
+ * the notification's participant space, which lists the ``Decidim::Notification``s she has received.
7
7
 
8
8
  So, in the wider sense, notifications are messages that are sent to the users, admins or participants, when something interesting occurs in the platform.
9
9
 
10
10
  Each notification is sent via two communication channels: email and internal notifications.
11
11
 
12
- ## A Decidim Event
12
+ == A Decidim Event
13
13
 
14
14
  Technically, a Decidim event is nothing but an `ActiveSupport::Notification` with a payload of the form
15
15
 
16
- ```ruby
16
+ [source,ruby]
17
+ ----
17
18
  ActiveSupport::Notifications.publish(
18
19
  event,
19
20
  event_class: event_class.name,
@@ -22,11 +23,12 @@ ActiveSupport::Notifications.publish(
22
23
  followers: followers.uniq.compact,
23
24
  extra: extra
24
25
  )
25
- ```
26
+ ----
26
27
 
27
28
  To publish an event to send a notification, Decidim's `EventManager` should be used:
28
29
 
29
- ```ruby
30
+ [source,ruby]
31
+ ----
30
32
  # Note the convention between the `event` key, and the `event_class` that will be used later to wrap the payload and be used as the email or notification model.
31
33
  data = {
32
34
  event: "decidim.events.comments.comment_created",
@@ -40,75 +42,75 @@ data = {
40
42
  }
41
43
 
42
44
  Decidim::EventsManager.publish(data)
43
- ```
45
+ ----
44
46
 
45
47
  Both, `EmailNotificationGenerator` and `NotificationGenerator` are use the same arguments:
46
48
 
47
- - **event**: A String with the name of the event.
48
- - **event_class**: A class that wraps the event.
49
- - **resource**: an instance of a class implementing the `Decidim::Resource` concern.
50
- - **followers**: a collection of Users that receive the notification because they're following it.
51
- - **affected_users**: a collection of Users that receive the notification because they're affected by it.
52
- - **force_send**: boolean indicating if EventPublisherJob should skip the `notifiable?` check it performs before notifying.
53
- - **extra**: a Hash with extra information to be included in the notification.
49
+ * *event*: A String with the name of the event.
50
+ * *event_class*: A class that wraps the event.
51
+ * *resource*: an instance of a class implementing the `Decidim::Resource` concern.
52
+ * *followers*: a collection of Users that receive the notification because they're following it.
53
+ * *affected_users*: a collection of Users that receive the notification because they're affected by it.
54
+ * *force_send*: boolean indicating if EventPublisherJob should skip the `notifiable?` check it performs before notifying.
55
+ * *extra*: a Hash with extra information to be included in the notification.
54
56
 
55
57
  Again, both generators will check for each user
56
58
 
57
- - in the *followers* array, if she has the `notification_types` set to "all" or "followed-only".
58
- - in the *affected_users* array, if she has the `notification_types` set to "all" or "own-only".
59
+ * in the _followers_ array, if she has the `notification_types` set to "all" or "followed-only".
60
+ * in the _affected_users_ array, if she has the `notification_types` set to "all" or "own-only".
59
61
 
60
62
  Event names must start with "decidim.events." (the `event` data key). This way `Decidim::EventPublisherJob` will automatically process them. Otherwise no artifact in Decidim will process them, and will be the developer's responsibility to subscribe to them and process.
61
63
 
62
64
  Sometimes, when something that must be notified to users happen, a service is defined to manage the logic involved to decide which events should be published. See for example `Decidim::Comments::NewCommentNotificationCreator`.
63
65
 
64
- Please refer to [Ruby on Rails Notifications documentation](https://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) if you need to hack the Decidim's events system.
66
+ Please refer to https://api.rubyonrails.org/classes/ActiveSupport/Notifications.html[Ruby on Rails Notifications documentation] if you need to hack the Decidim's events system.
65
67
 
66
- ## How Decidim's `EventPublisherJob` processes the events?
68
+ == How Decidim's `EventPublisherJob` processes the events?
67
69
 
68
- The `EventPublisherJob` in Decidim's core engine subscribes to all notifications matching the regular expression `/^decidim\.events\./`. This is, starting with "decidim.events.". It will then be invoked when an imaginary event named "decidim.events.harmonica_blues" is published.
70
+ The `EventPublisherJob` in Decidim's core engine subscribes to all notifications matching the regular expression `+/^decidim\.events\./+`. This is, starting with "decidim.events.". It will then be invoked when an imaginary event named "decidim.events.harmonica_blues" is published.
69
71
 
70
72
  When invoked it simply performs some validations and enqueue an `EmailNotificationGeneratorJob` and a `NotificationGeneratorJob`.
71
73
 
72
74
  The validations it performs check if the resource, the component, or the participatory space are published (when the concept applies to the artifact).
73
75
 
74
- ## The \*Event class
76
+ == The *Event class
75
77
 
76
78
  Generates the email and notification messages from the information related with the notification.
77
79
 
78
80
  Event classes are subclasses of `Decidim::Events::SimpleEvent`.
79
81
  A subset of the payload of the notification is passed to the event class's constructor:
80
82
 
81
- - The `resource`
82
- - The `event` name
83
- - The notified user, either from the `followers` or from the `affected_users` arrays
84
- - The `extra` hash, with content specific for the given SimpleEvent subclass
85
- - The user_role, either :follower or :affected_user
83
+ * The `resource`
84
+ * The `event` name
85
+ * The notified user, either from the `followers` or from the `affected_users` arrays
86
+ * The `extra` hash, with content specific for the given SimpleEvent subclass
87
+ * The user_role, either :follower or :affected_user
86
88
 
87
89
  With the previous information the event class is able to generate the following contents.
88
90
 
89
91
  Developers will be able to customize those messages by adding translations to the `config/locales/en.yml` file of the corresponding module.
90
92
  The keys to be used will have the translation scope corresponding to the event name ("decidim.events.comments.comment_by_followed_user" for example) and the key will be the content to override (email_subject, email_intro, etc.)
91
93
 
92
- ### Email contents
94
+ === Email contents
93
95
 
94
96
  The following are the parts of the notification email:
95
97
 
96
- - *email_subject*, to be customized
97
- - email_greeting, with a good default, usually there's no need to cusomize it
98
- - *email_intro*, to be customized
99
- - *resource_text* (optional), rendered `html_safe` if present
100
- - *resource_url*, a link to the involved resource if resource_url and resource_title are present
101
- - *email_outro*
98
+ * _email_subject_, to be customized
99
+ * email_greeting, with a good default, usually there's no need to cusomize it
100
+ * _email_intro_, to be customized
101
+ * _resource_text_ (optional), rendered `html_safe` if present
102
+ * _resource_url_, a link to the involved resource if resource_url and resource_title are present
103
+ * _email_outro_
102
104
 
103
105
  All contents except the `email_greeting` use to require customization on each notification.
104
106
 
105
- ### Notification contents
107
+ === Notification contents
106
108
 
107
109
  Only the `notification_title` is generated in the event class. The rest of the contents are produced by the templates from the `resource` and the `notification` objects.
108
110
 
109
- ## Testing notifications
111
+ == Testing notifications
110
112
 
111
- - Test that the event has been published (usually a command test)
112
- - Test the event returns the expected contents for the email and the notification.
113
+ * Test that the event has been published (usually a command test)
114
+ * Test the event returns the expected contents for the email and the notification.
113
115
 
114
- Developers should we aware when adding URLs in the email's content, be sure to use absolute URLs and not relative paths.
116
+ Developers should we aware when adding URLs in the email's content, be sure to use absolute URLs and not relative paths.
@@ -1,9 +1,10 @@
1
- # Open Data
1
+ = Open Data
2
2
 
3
3
  In order for users to be able to download Open Data files they have to be generated previously, since generating them on the fly would take too much time and resources.
4
4
 
5
5
  You should schedule this command to be run everyday, using `cron` or `whenever` or your favorite tool:
6
6
 
7
- ```ruby
7
+ [source,ruby]
8
+ ----
8
9
  bundle exec rake decidim:open_data:export
9
- ```
10
+ ----
@@ -0,0 +1,92 @@
1
+ = Permissions
2
+
3
+ Since Decidim has multiple roles, we needed a permissions system to discover what actions can a user perform, given their roles. The basis of the current permissions system were added on https://github.com/decidim/decidim/pull/3029[#3029], so be sure to check that PR (and the related ones) to read the discussion and the motivations behind the change.
4
+
5
+ == Overview
6
+
7
+ When checking for permission to perform an action, we check this chain:
8
+
9
+ . The component permissions
10
+ . The participatory space permissions
11
+ . The core permissions
12
+
13
+ This way we're going from more specific to more general.
14
+
15
+ == Explanation
16
+
17
+ We wrap the permission and its context in a `PermissionsAction` object. It also holds the state of the permission (whether it's been allowed or not).
18
+
19
+ Each component and space must define a `Permissions` class, inheriting from `Decidim::DefaultPermissions`. The `Permissions` class must define a `permissions` instance method. this class will receive the permission action, and the `permissions` method must return the permission action. The `Permissions` class can set the action as allowed or disallowed.
20
+
21
+ There's a small limitation in the permission action state machine: once it's been disallowed it can't be reallowed. This is to avoid mischievous modules modifying permissions.
22
+
23
+ Permission actions have a scope. It's usually either `:public` or `:admin`, and the `Permissions` class usually handles the `:public` scope, while it delegates the `:admin` one to another specialized class.
24
+
25
+ == Add a new Action
26
+
27
+ === Proposals example
28
+
29
+ We're going to reproduce the steps to add an action (endorse) for a proposal step by step.
30
+
31
+ ==== Configuring a new 'endorse' action
32
+
33
+ . Edit decidim-proposals/lib/decidim/proposals/component.rb
34
+ . Add the new 'endorse' action into the `component.actions` array and save the file:
35
+
36
+ [source,ruby]
37
+ ----
38
+ component.actions = %w(endorse vote create)
39
+ ----
40
+
41
+ . Translate the action for the corresponding key: `en.decidim.components.proposals.actions.endorse = Endorse`
42
+ . Edit `app/permissions/decidim/proposals/permissions.rb` and add the corresponding permission, using `authorized?` method to run the `authorization handler` logic.
43
+ . In the endorse proposals controller, enforce that the user has permissions to perform the `endorse` action before actually doing it, using the `enforce_permission_to` method:
44
+
45
+ [source,ruby]
46
+ ----
47
+ enforce_permission_to :endorse, :proposal, proposal: proposal
48
+ ----
49
+
50
+ . In the proposals templates, change regular links and buttons to endorse a proposal with calls to `action_authorized_link_to` and `action_authorized_button_to` helpers.
51
+ . Restart the server to pick up the changes.
52
+
53
+ ==== Using the new 'endorse' action
54
+
55
+ . Now an admin user should be able to go to a participatory space with a `proposals` component panel and click on its `Permissions` link (the icon with a key). There, an `authorization handler` can be set for the `endorse` action.
56
+ . Go to a Proposal detail in the front-end
57
+ . Try to endorse the current proposal
58
+ ** If the user has not granted the selected permission, the 'endorse' button should block the action and allow the user to grant the permission with the selected `authorization handler` logic.
59
+ ** If the logger user has already granted the selected permission, the user should be able to perform the endorsement.
60
+
61
+ ==== Allow to configure the related permissions at resource level
62
+
63
+ Permissions settings could also be set for an specific resources appart from the full component. Actions should also be related to the resource.
64
+
65
+ . Edit decidim-proposals/lib/decidim/proposals/component.rb
66
+ . Add the 'endorse' action into the `resource.actions` array for the `proposal` resource definition and save the file:
67
+
68
+ [source,ruby]
69
+ ----
70
+ resource.actions = %w(endorse vote)
71
+ ----
72
+
73
+ . Only if this is the first resource action added, edit the proposals admin templates and use the `resource_permissions_link` helper to link the resource permissions page from each resource in the listing.
74
+
75
+ [source,erb]
76
+ ----
77
+ <%= resource_permissions_link(proposal) %>
78
+ ----
79
+
80
+ . In the proposals permission class, pass an extra `resource` named parameter to the calls to the `authorized?` method.
81
+
82
+ [source,ruby]
83
+ ----
84
+ authorized?(:endorse, resource: proposal)
85
+ ----
86
+
87
+ . In the proposals templates, also add the extra `resource` parameter to the `action_authorized_link_to` and `action_authorized_button_to` helpers.
88
+ . Restart the server to pick up the changes.
89
+
90
+ ==== Using permissions at resource level
91
+
92
+ . Now an admin user should be able to go to a participatory space with a `proposals` component panel and click on its `Permissions` link (the icon with a key). There, an `authorization handler` can be set for the `endorse` action.