Class: Decidim::Initiatives::SignatureHandler
- Inherits:
-
Form
- Object
- Form
- Decidim::Initiatives::SignatureHandler
- Includes:
- ValidatableAuthorizations
- Defined in:
- app/services/decidim/initiatives/signature_handler.rb
Overview
This is the base class for signature handlers, all implementations should inherit from it. Each SignatureHandler is a form that will be used to check if the signature is valid or not. When it is valid the initiatives votes defined by the initiative type will be created for the user.
Feel free to use validations to assert fields against a remote API, local database, or whatever.
It also sets two default attributes, ‘user` and `initiative`.
Direct Known Subclasses
Class Method Summary collapse
Instance Method Summary collapse
- #already_voted? ⇒ Boolean
- #authorization_handler ⇒ Object
-
#authorization_handler_params ⇒ Object
Params to be sent to the authorization handler.
-
#authorized_scopes ⇒ Object
Public: Builds the list of scopes where the user is authorized to vote in.
- #encrypted_metadata ⇒ Object
-
#form_attributes ⇒ Object
The attributes of the handler that should be exposed as form input when rendering the handler in a form.
- #hash_id ⇒ Object
-
#metadata ⇒ Object
Any data that the developer would like to inject to the ‘metadata` field of a vote when it is created.
-
#signature_scope_candidates ⇒ Object
Public: Builds a list of Decidim::Scopes where the user could have a valid authorization.
-
#signature_scope_id ⇒ Object
The signature_scope_id can be defined in the signature workflow to be used by the author scope feature.
- #signature_workflow_name ⇒ Object
-
#to_partial_path ⇒ Object
The String partial path so Rails can render the handler as a form.
-
#unique_id ⇒ Object
A unique ID to be implemented by the signature handler that ensures no duplicates are created.
-
#user_signature_scope ⇒ Object
Public: Finds the scope the user has an authorization for, this way the user can vote on that scope and its parents.
Class Method Details
.requires_extra_attributes? ⇒ Boolean
172 173 174 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 172 def self.requires_extra_attributes? new.form_attributes.present? end |
Instance Method Details
#already_voted? ⇒ Boolean
176 177 178 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 176 def already_voted? Decidim::InitiativesVote.exists?(author: user, initiative:) end |
#authorization_handler ⇒ Object
128 129 130 131 132 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 128 def return if .blank? @authorization_handler ||= .from_params() end |
#authorization_handler_params ⇒ Object
Params to be sent to the authorization handler. By default consists on the metadata hash including the signer user
116 117 118 119 120 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 116 def params = .merge(user:) params = params.merge(tos_agreement:) if ephemeral_tos_pending? params end |
#authorized_scopes ⇒ Object
Public: Builds the list of scopes where the user is authorized to vote in. This is used when the initiative allows also voting on child scopes, not only the main scope.
Instead of just listing the children of the main scope, we just want to select the ones that have been added to the InitiativeType with its voting settings.
59 60 61 62 63 64 65 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 59 def initiative.votable_initiative_type_scopes.select do |initiative_type_scope| initiative_type_scope.global_scope? || initiative_type_scope.scope == user_signature_scope || initiative_type_scope.scope.ancestor_of?(user_signature_scope) end.flat_map(&:scope) end |
#encrypted_metadata ⇒ Object
47 48 49 50 51 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 47 def return if .blank? @encrypted_metadata ||= encryptor.encrypt() end |
#form_attributes ⇒ Object
The attributes of the handler that should be exposed as form input when rendering the handler in a form.
Returns an Array of Strings.
154 155 156 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 154 def form_attributes attributes.except("id", "user", "initiative", "tos_agreement", "transfer_status").keys end |
#hash_id ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 138 def hash_id return unless initiative && (unique_id || user) @hash_id ||= Digest::SHA256.hexdigest( [ initiative.id, unique_id || user.id, Rails.application.secret_key_base ].compact.join("-") ) end |
#metadata ⇒ Object
Any data that the developer would like to inject to the ‘metadata` field of a vote when it is created. Can be useful if some of the params the user sent with the signature form want to be persisted for future use.
Returns a Hash.
110 111 112 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 110 def {} end |
#signature_scope_candidates ⇒ Object
Public: Builds a list of Decidim::Scopes where the user could have a valid authorization.
If the initiative is set with a global scope (meaning the scope is nil), all the scopes in the organization are valid.
Returns an array of Decidim::Scopes.
95 96 97 98 99 100 101 102 103 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 95 def signature_scope_candidates signature_scope_candidates = [initiative.scope] signature_scope_candidates += if initiative.scope.present? initiative.scope.descendants else initiative.organization.scopes end signature_scope_candidates.uniq end |
#signature_scope_id ⇒ Object
The signature_scope_id can be defined in the signature workflow to be used by the author scope feature
124 125 126 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 124 def signature_scope_id scope.id end |
#signature_workflow_name ⇒ Object
134 135 136 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 134 def signature_workflow_name @signature_workflow_name ||= initiative&.type&. end |
#to_partial_path ⇒ Object
The String partial path so Rails can render the handler as a form. This is useful if you want to have a custom view to render the form instead of the default view.
Example:
A handler named Decidim::CensusHandler would look for its partial in:
decidim/census/form
Returns a String.
168 169 170 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 168 def to_partial_path "decidim/initiatives/initiative_signatures/#{signature_workflow_name.sub(/_handler$/, "")}/form" end |
#unique_id ⇒ Object
A unique ID to be implemented by the signature handler that ensures no duplicates are created.
43 44 45 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 43 def unique_id nil end |
#user_signature_scope ⇒ Object
Public: Finds the scope the user has an authorization for, this way the user can vote on that scope and its parents.
This is can be used to allow users that are authorized with a children scope to sign an initiative with a parent scope.
As an example: A city (global scope) has many districts (scopes with parent nil), and each district has different neighbourhoods (with its parent as a district). If we setup the authorization handler to match a neighbourhood, the same authorization can be used to participate in district, neighbourhoods or city initiatives.
Returns a Decidim::Scope.
80 81 82 83 84 85 86 |
# File 'app/services/decidim/initiatives/signature_handler.rb', line 80 def user_signature_scope return if signature_scope_id.blank? @user_signature_scope ||= signature_scope_candidates.find do |scope_candidate| scope_candidate&.id == signature_scope_id end end |