decidim-decidim_awesome 0.12.0 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -0
- data/README.md +25 -15
- data/Rakefile +12 -0
- data/app/cells/concerns/decidim/decidim_awesome/global_menu_cell_override.rb +14 -2
- data/app/cells/concerns/decidim/decidim_awesome/proposal_l_cell_override.rb +5 -4
- data/app/cells/decidim/decidim_awesome/voting/voting_cards_proposal/show.erb +3 -3
- data/app/cells/decidim/decidim_awesome/voting/voting_cards_proposal/vote_block_for.erb +1 -1
- data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +39 -5
- data/app/commands/decidim/decidim_awesome/admin/create_authorization_group.rb +42 -0
- data/app/commands/decidim/decidim_awesome/admin/create_custom_redirect.rb +10 -14
- data/app/commands/decidim/decidim_awesome/admin/create_menu_hack.rb +9 -8
- data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +3 -8
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +4 -8
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_style.rb +3 -7
- data/app/commands/decidim/decidim_awesome/admin/destroy_authorization_group.rb +37 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_custom_redirect.rb +10 -9
- data/app/commands/decidim/decidim_awesome/admin/destroy_menu_hack.rb +8 -7
- data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +7 -13
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +7 -10
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +6 -11
- data/app/commands/decidim/decidim_awesome/admin/update_config.rb +12 -1
- data/app/commands/decidim/decidim_awesome/admin/update_custom_redirect.rb +11 -11
- data/app/commands/decidim/decidim_awesome/admin/update_menu_hack.rb +10 -8
- data/app/controllers/concerns/decidim/decidim_awesome/admin/maintenance_context.rb +0 -28
- data/app/controllers/concerns/decidim/decidim_awesome/enforce_access_authorizations.rb +49 -0
- data/app/controllers/concerns/decidim/decidim_awesome/needs_hashcash.rb +43 -0
- data/app/controllers/concerns/decidim/decidim_awesome/not_found_redirect.rb +2 -2
- data/app/controllers/decidim/decidim_awesome/admin/admin_authorizations_controller.rb +2 -2
- data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +0 -4
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +2 -1
- data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +2 -0
- data/app/controllers/decidim/decidim_awesome/admin/custom_redirects_controller.rb +1 -2
- data/app/controllers/decidim/decidim_awesome/admin/force_authorizations_controller.rb +44 -0
- data/app/controllers/decidim/decidim_awesome/admin/hashcash_controller.rb +39 -0
- data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +1 -1
- data/app/controllers/decidim/decidim_awesome/admin/{maintenance_controller.rb → private_data_controller.rb} +9 -9
- data/app/controllers/decidim/decidim_awesome/required_authorizations_controller.rb +51 -13
- data/app/controllers/decidim/decidim_awesome/utils_controller.rb +17 -0
- data/app/forms/concerns/decidim/decidim_awesome/proposals/admin/proposal_form_customizations.rb +59 -0
- data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_customizations.rb +28 -28
- data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_customizations_base.rb +36 -0
- data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_override.rb +7 -1
- data/app/forms/decidim/decidim_awesome/admin/authorization_group_form.rb +66 -0
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +23 -24
- data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +2 -0
- data/app/helpers/concerns/decidim/decidim_awesome/amendments_helper_override.rb +2 -1
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +21 -18
- data/app/helpers/decidim/decidim_awesome/map_helper.rb +4 -2
- data/app/models/decidim/decidim_awesome/paper_trail_version.rb +1 -1
- data/app/overrides/decidim/assemblies/admin/assemblies/_form/add_visibility_callout.html.erb.deface +3 -0
- data/app/overrides/decidim/conferences/admin/conferences/_form/add_visibility_callout.html.erb.deface +3 -0
- data/app/overrides/decidim/devise/registrations/new/add_hashcash.html.erb.deface +3 -0
- data/app/overrides/decidim/devise/sessions/new/add_hashcash.html.erb.deface +3 -0
- data/app/overrides/decidim/participatory_processes/admin/participatory_process_groups/_form/add_visibility_callout.html.erb.deface +3 -0
- data/app/overrides/decidim/participatory_processes/admin/participatory_processes/_form/add_visibility_callout.html.erb.deface +3 -0
- data/app/overrides/decidim/shared/_login_modal/add_hashcash.html.erb.deface +3 -0
- data/app/overrides/layouts/decidim/_head/add_awesome_custom_styles.html.erb.deface +3 -0
- data/app/overrides/layouts/decidim/_head/add_awesome_tags.html.erb.deface +0 -2
- data/app/packs/entrypoints/decidim_decidim_awesome_hashcash.js +4 -0
- data/app/packs/src/decidim/decidim_awesome/admin/auto_edit.js +25 -6
- data/app/packs/src/decidim/decidim_awesome/admin/custom_fields_builder.js +4 -2
- data/app/packs/src/decidim/decidim_awesome/admin/verifications.js +6 -3
- data/app/packs/src/decidim/decidim_awesome/awesome_admin.js +0 -1
- data/app/packs/src/decidim/decidim_awesome/awesome_map/api/proposals_fetcher.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/controller.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controllers/proposals_controller.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/awesome_map/controls_ui.js +6 -6
- data/app/packs/src/decidim/decidim_awesome/awesome_map/load_map.js +1 -1
- data/app/packs/src/decidim/decidim_awesome/forms/autosave.js +3 -3
- data/app/packs/src/decidim/decidim_awesome/forms/custom_fields_renderer.js +1 -113
- data/app/packs/src/decidim/decidim_awesome/proposals/images.js +1 -1
- data/app/packs/src/vendor/form_builder_langs/ar-SA.lang +111 -0
- data/app/packs/src/vendor/form_builder_langs/ar-TN.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/ca-ES.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/cs-CZ.lang +105 -0
- data/app/packs/src/vendor/form_builder_langs/da-DK.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/de-DE.lang +109 -0
- data/app/packs/src/vendor/form_builder_langs/el-GR.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/en-US.lang +117 -0
- data/app/packs/src/vendor/form_builder_langs/es-ES.lang +103 -0
- data/app/packs/src/vendor/form_builder_langs/fa-IR.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/fi-FI.lang +107 -0
- data/app/packs/src/vendor/form_builder_langs/fr-FR.lang +117 -0
- data/app/packs/src/vendor/form_builder_langs/he-IL.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/hi-IN.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/hu-HU.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/id-ID.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/it-IT.lang +107 -0
- data/app/packs/src/vendor/form_builder_langs/ja-JP.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/my-MM.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/nb-NO.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/nl-NL.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/pl-PL.lang +122 -0
- data/app/packs/src/vendor/form_builder_langs/pt-BR.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/pu-IN.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/qz-MM.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/ro-RO.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/ru-RU.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/sl-SI.lang +110 -0
- data/app/packs/src/vendor/form_builder_langs/th-TH.lang +111 -0
- data/app/packs/src/vendor/form_builder_langs/tr-TR.lang +115 -0
- data/app/packs/src/vendor/form_builder_langs/uk-UA.lang +108 -0
- data/app/packs/src/vendor/form_builder_langs/vi-VN.lang +94 -0
- data/app/packs/src/vendor/form_builder_langs/zh-CN.lang +100 -0
- data/app/packs/src/vendor/form_builder_langs/zh-TW.lang +94 -0
- data/app/packs/src/vendor/hashcash.js +83 -0
- data/app/packs/src/vendor/sha1.js +143 -0
- data/app/packs/src/vendor/stamp.js +50 -0
- data/app/packs/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +6 -1
- data/app/packs/stylesheets/decidim/decidim_awesome/admin/constraints.scss +5 -0
- data/app/packs/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +1 -2
- data/app/packs/stylesheets/decidim/decidim_awesome/forms/autosave.scss +2 -12
- data/app/presenters/decidim/decidim_awesome/private_data_presenter.rb +2 -2
- data/app/queries/decidim/decidim_awesome/space_constraint_finder.rb +43 -0
- data/app/serializers/concerns/decidim/decidim_awesome/proposals/proposal_serializer_methods.rb +3 -2
- data/app/services/decidim/decidim_awesome/access_authorization_service.rb +79 -0
- data/app/types/concerns/decidim/decidim_awesome/add_proposal_type_custom_fields.rb +2 -1
- data/app/views/decidim/decidim_awesome/admin/admin_accountability/index.html.erb +4 -4
- data/app/views/decidim/decidim_awesome/admin/admin_authorizations/callout.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/admin_authorizations/conflict.html.erb +4 -4
- data/app/views/decidim/decidim_awesome/admin/admin_authorizations/edit.html.erb +6 -5
- data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +6 -6
- data/app/views/decidim/decidim_awesome/admin/config/_authorization_options_form.html.erb +19 -0
- data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +3 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +4 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +4 -4
- data/app/views/decidim/decidim_awesome/admin/config/_form_scoped_styles.html.erb +3 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_surveys.html.erb +40 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_verifications.html.erb +71 -9
- data/app/views/decidim/decidim_awesome/admin/constraints/_form.html.erb +5 -4
- data/app/views/decidim/decidim_awesome/admin/hashcash/_filters.html.erb +55 -0
- data/app/views/decidim/decidim_awesome/admin/hashcash/index.html.erb +33 -0
- data/app/views/decidim/decidim_awesome/admin/hashcash/ip_addresses.html.erb +29 -0
- data/app/views/decidim/decidim_awesome/admin/hashcash/show.html.erb +42 -0
- data/app/views/decidim/decidim_awesome/admin/menu_hacks/index.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/{maintenance → private_data}/_private_data.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/{maintenance/show.html.erb → private_data/index.html.erb} +2 -3
- data/app/views/decidim/decidim_awesome/admin/proposals/_private_body.html.erb +1 -1
- data/app/views/decidim/decidim_awesome/admin/shared/_visibility_notice.html.erb +8 -0
- data/app/views/decidim/decidim_awesome/amendments/_modal.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/hashcash/_hidden_field.html.erb +4 -0
- data/app/views/decidim/decidim_awesome/required_authorizations/index.html.erb +14 -4
- data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +2 -2
- data/app/views/layouts/decidim/decidim_awesome/admin/maintenance.html.erb +2 -11
- data/config/assets.rb +1 -0
- data/config/i18n-tasks.yml +2 -0
- data/config/locales/ca.yml +100 -37
- data/config/locales/cs.yml +100 -36
- data/config/locales/de.yml +98 -35
- data/config/locales/en.yml +117 -44
- data/config/locales/es.yml +100 -36
- data/config/locales/eu.yml +34 -39
- data/config/locales/fr.yml +77 -31
- data/config/locales/ja.yml +99 -36
- data/config/locales/sv.yml +49 -0
- data/lib/decidim/decidim_awesome/admin_engine.rb +9 -5
- data/lib/decidim/decidim_awesome/{authorizator.rb → authorizer.rb} +1 -1
- data/lib/decidim/decidim_awesome/awesome.rb +34 -24
- data/lib/decidim/decidim_awesome/awesome_helpers.rb +14 -5
- data/lib/decidim/decidim_awesome/checksums.yml +26 -40
- data/lib/decidim/decidim_awesome/config.rb +18 -7
- data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +1 -1
- data/lib/decidim/decidim_awesome/engine.rb +14 -3
- data/lib/decidim/decidim_awesome/menu.rb +151 -138
- data/lib/decidim/decidim_awesome/middleware/current_config.rb +5 -10
- data/lib/decidim/decidim_awesome/test/initializer.rb +5 -2
- data/lib/decidim/decidim_awesome/test/shared_examples/config_examples.rb +1 -3
- data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +2 -1
- data/lib/decidim/decidim_awesome/test/shared_examples/proposal_form_examples.rb +191 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/summary_examples.rb +15 -4
- data/lib/decidim/decidim_awesome/version.rb +1 -1
- data/lib/tasks/decidim_awesome_upgrade_tasks.rake +4 -1
- data/package.json +7 -8
- metadata +86 -13
- data/app/controllers/concerns/decidim/decidim_awesome/check_login_authorizations.rb +0 -60
- data/app/packs/src/decidim/decidim_awesome/admin/verification_selects.js +0 -21
- data/config/rubocop/disabled.yml +0 -11
- data/config/rubocop/faker.yml +0 -480
- data/config/rubocop/rails.yml +0 -88
- data/config/rubocop/rspec.yml +0 -65
- data/config/rubocop/ruby.yml +0 -1210
@@ -2,14 +2,17 @@
|
|
2
2
|
|
3
3
|
module Decidim
|
4
4
|
module DecidimAwesome
|
5
|
-
#
|
5
|
+
# Lists the authorizations required for the current user/context and helps
|
6
6
|
class RequiredAuthorizationsController < DecidimAwesome::ApplicationController
|
7
|
+
include ActionView::Helpers::SanitizeHelper
|
7
8
|
layout "layouts/decidim/authorizations"
|
8
|
-
helper_method :granted_authorizations, :pending_authorizations, :missing_authorizations, :redirect_url
|
9
|
+
helper_method :granted_authorizations, :pending_authorizations, :missing_authorizations, :redirect_url, :authorization_help_text, :service
|
9
10
|
|
10
11
|
before_action do
|
11
|
-
|
12
|
-
|
12
|
+
# If the user is already authorized for the required handlers, send them
|
13
|
+
# back to the original destination (or root). This avoids loops because
|
14
|
+
# redirect_url defaults to decidim.root_path when it points back here.
|
15
|
+
redirect_to redirect_url if user_signed_in? && service.granted? && request.path != redirect_url
|
13
16
|
end
|
14
17
|
|
15
18
|
def redirect_url
|
@@ -23,35 +26,70 @@ module Decidim
|
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
26
|
-
def index
|
27
|
-
enforce_permission_to :read, :required_authorizations, user_is_authorized: user_is_authorized?
|
28
|
-
end
|
29
|
-
|
30
29
|
private
|
31
30
|
|
31
|
+
delegate :authorization_handlers, :adapters, to: :service
|
32
|
+
|
33
|
+
def current_authorizations
|
34
|
+
@current_authorizations ||= Decidim::Verifications::Authorizations.new(
|
35
|
+
organization: current_organization,
|
36
|
+
user: current_user,
|
37
|
+
name: authorization_handlers,
|
38
|
+
granted: true
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
32
42
|
def missing_authorizations
|
33
|
-
@missing_authorizations ||=
|
43
|
+
@missing_authorizations ||= adapters.filter do |manifest|
|
34
44
|
Decidim::Verifications::Authorizations.new(
|
35
45
|
organization: current_organization,
|
36
46
|
user: current_user,
|
37
|
-
name:
|
47
|
+
name: authorization_handlers
|
38
48
|
).pluck(:name).exclude?(manifest.name)
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
42
52
|
def pending_authorizations
|
43
|
-
@pending_authorizations ||=
|
53
|
+
@pending_authorizations ||= adapters.filter do |manifest|
|
44
54
|
Decidim::Verifications::Authorizations.new(
|
45
55
|
organization: current_organization,
|
46
56
|
user: current_user,
|
47
|
-
name:
|
57
|
+
name: authorization_handlers,
|
48
58
|
granted: false
|
49
59
|
).pluck(:name).include?(manifest.name)
|
50
60
|
end
|
51
61
|
end
|
52
62
|
|
53
63
|
def granted_authorizations
|
54
|
-
@granted_authorizations ||=
|
64
|
+
@granted_authorizations ||= adapters.filter { |manifest| current_authorizations.pluck(:name).include?(manifest.name) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def service
|
68
|
+
@service ||= Decidim::DecidimAwesome::AccessAuthorizationService.new(current_user, current_organization, context_authorizations)
|
69
|
+
end
|
70
|
+
|
71
|
+
# we need to detect the context from the redirect_url passed
|
72
|
+
def context_force_authorizations
|
73
|
+
@context_force_authorizations ||= begin
|
74
|
+
config = Config.new(current_organization)
|
75
|
+
config.context_from_request!(redirect_url)
|
76
|
+
config.application_context!(current_user:)
|
77
|
+
config.collect_sub_configs_values("force_authorization")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def context_authorizations
|
82
|
+
@context_authorizations ||= (context_force_authorizations.pluck("authorization_handlers").compact_blank if context_force_authorizations.is_a?(Array))
|
83
|
+
end
|
84
|
+
|
85
|
+
# show the first help text available
|
86
|
+
def authorization_help_text
|
87
|
+
return unless context_force_authorizations.is_a?(Array)
|
88
|
+
|
89
|
+
context_force_authorizations.pluck("force_authorization_help_text").find do |text|
|
90
|
+
text = translated_attribute(text)
|
91
|
+
strip_tags(text).strip.present? ? text : nil
|
92
|
+
end
|
55
93
|
end
|
56
94
|
end
|
57
95
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
# Abstract component class for components without any admin controllers (only settings)
|
6
|
+
class UtilsController < DecidimAwesome::ApplicationController
|
7
|
+
def form_builder_i18n
|
8
|
+
lang = I18n.locale
|
9
|
+
folder = "app/packs/src/vendor/form_builder_langs/"
|
10
|
+
file = Decidim::DecidimAwesome::Engine.root.join(folder, "#{lang}.lang")
|
11
|
+
file = Dir[Decidim::DecidimAwesome::Engine.root.join(folder, "#{lang}-*.lang")].first unless File.exist?(file)
|
12
|
+
file = Decidim::DecidimAwesome::Engine.root.join(folder, "en-US.lang") unless file && File.exist?(file)
|
13
|
+
render plain: File.read(file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/app/forms/concerns/decidim/decidim_awesome/proposals/admin/proposal_form_customizations.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Recreate validations to take into account custom fields and ignore the length limit in proposals
|
4
|
+
module Decidim
|
5
|
+
module DecidimAwesome
|
6
|
+
module Proposals
|
7
|
+
module Admin
|
8
|
+
module ProposalFormCustomizations
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
include ProposalFormCustomizationsBase
|
12
|
+
|
13
|
+
class_methods do
|
14
|
+
def overridden_validators
|
15
|
+
_validators.filter do |attribute, _validators|
|
16
|
+
attribute.to_s.start_with?("title") || attribute.to_s.start_with?("body")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def overridden_validate_callbacks
|
21
|
+
_validate_callbacks.filter do |callback|
|
22
|
+
filter = callback.filter
|
23
|
+
if filter.is_a?(ActiveModel::Validations::LengthValidator) ||
|
24
|
+
filter.is_a?(ActiveModel::Validations::PresenceValidator) ||
|
25
|
+
filter.is_a?(TranslatablePresenceValidator)
|
26
|
+
|
27
|
+
filter.attributes.any? { |attr| attr.to_s.start_with?("title") || attr.to_s.start_with?("body") }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# remove presence, length and etiquette validators from :title and :body
|
33
|
+
def clear_overridden_validators!
|
34
|
+
overridden_validators.keys.each do |attribute|
|
35
|
+
_validators.delete(attribute)
|
36
|
+
end
|
37
|
+
overridden_validate_callbacks.each do |callback|
|
38
|
+
_validate_callbacks.delete(callback)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
included do
|
44
|
+
clear_overridden_validators!
|
45
|
+
|
46
|
+
translatable_attribute :title, String do |field, _locale|
|
47
|
+
validates field, proposal_length: {
|
48
|
+
minimum: ->(form) { form.minimum_title_length },
|
49
|
+
maximum: 150
|
50
|
+
}, if: proc { |resource| resource.send(field).present? }
|
51
|
+
end
|
52
|
+
|
53
|
+
validates :title, :body, translatable_presence: true, unless: ->(form) { form.override_validations? }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -7,8 +7,35 @@ module Decidim
|
|
7
7
|
module ProposalFormCustomizations
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
|
+
include ProposalFormCustomizationsBase
|
11
|
+
|
12
|
+
class_methods do
|
13
|
+
def overridden_validate_callbacks
|
14
|
+
_validate_callbacks.filter do |callback|
|
15
|
+
filter = callback.filter
|
16
|
+
|
17
|
+
case filter
|
18
|
+
when EtiquetteValidator, ActiveModel::Validations::LengthValidator, ProposalLengthValidator, ActiveModel::Validations::PresenceValidator
|
19
|
+
filter.attributes.include?(:title) || filter.attributes.include?(:body)
|
20
|
+
when :body_is_not_bare_template
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# remove presence, length and etiquette validators from :title and :body
|
27
|
+
def clear_overridden_validators!
|
28
|
+
_validators.delete(:title)
|
29
|
+
_validators.delete(:body)
|
30
|
+
|
31
|
+
overridden_validate_callbacks.each do |callback|
|
32
|
+
_validate_callbacks.delete(callback)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
10
37
|
included do
|
11
|
-
|
38
|
+
clear_overridden_validators!
|
12
39
|
|
13
40
|
validates :title, presence: true, etiquette: true
|
14
41
|
validates :title, proposal_length: {
|
@@ -22,34 +49,7 @@ module Decidim
|
|
22
49
|
minimum: ->(form) { form.minimum_body_length },
|
23
50
|
maximum: ->(form) { form.override_validations? ? 0 : form.component.settings.proposal_length }
|
24
51
|
}
|
25
|
-
|
26
52
|
validate :body_is_not_bare_template, unless: ->(form) { form.override_validations? }
|
27
|
-
|
28
|
-
def override_validations?
|
29
|
-
return false if context.current_component.settings.participatory_texts_enabled
|
30
|
-
|
31
|
-
custom_fields.present?
|
32
|
-
end
|
33
|
-
|
34
|
-
def minimum_title_length
|
35
|
-
awesome_config.config[:validate_title_min_length].to_i
|
36
|
-
end
|
37
|
-
|
38
|
-
def minimum_body_length
|
39
|
-
awesome_config.config[:validate_body_min_length].to_i
|
40
|
-
end
|
41
|
-
|
42
|
-
def custom_fields
|
43
|
-
@custom_fields ||= awesome_config.collect_sub_configs_values("proposal_custom_field")
|
44
|
-
end
|
45
|
-
|
46
|
-
def awesome_config
|
47
|
-
@awesome_config ||= begin
|
48
|
-
conf = Decidim::DecidimAwesome::Config.new(context.current_organization)
|
49
|
-
conf.context_from_component(context.current_component)
|
50
|
-
conf
|
51
|
-
end
|
52
|
-
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/app/forms/concerns/decidim/decidim_awesome/proposals/proposal_form_customizations_base.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Proposals
|
6
|
+
module ProposalFormCustomizationsBase
|
7
|
+
def override_validations?
|
8
|
+
return false if context.current_component.settings.participatory_texts_enabled
|
9
|
+
|
10
|
+
custom_fields.present?
|
11
|
+
end
|
12
|
+
|
13
|
+
def minimum_title_length
|
14
|
+
awesome_config.config[:validate_title_min_length].to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
def minimum_body_length
|
18
|
+
awesome_config.config[:validate_body_min_length].to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
def custom_fields
|
22
|
+
@custom_fields ||= awesome_config.collect_sub_configs_values("proposal_custom_field")
|
23
|
+
end
|
24
|
+
|
25
|
+
def awesome_config
|
26
|
+
@awesome_config ||= begin
|
27
|
+
conf = Decidim::DecidimAwesome::Config.new(context.current_organization)
|
28
|
+
conf.context_from_component!(context.current_component)
|
29
|
+
conf.application_context!(current_user: context.current_user)
|
30
|
+
conf
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -8,7 +8,13 @@ module Decidim
|
|
8
8
|
|
9
9
|
included do
|
10
10
|
alias_method :decidim_original_map_model, :map_model
|
11
|
-
attribute :private_body,
|
11
|
+
attribute :private_body, Decidim::Attributes::RichText
|
12
|
+
|
13
|
+
if name == "Decidim::Proposals::ProposalForm"
|
14
|
+
# the original decidim uses CleanString, as no images are allowed for non admins
|
15
|
+
# The RichText attribute transforms signed_id blobs to ObjectIDs
|
16
|
+
attribute :body, Decidim::Attributes::RichText
|
17
|
+
end
|
12
18
|
|
13
19
|
def map_model(model)
|
14
20
|
decidim_original_map_model(model)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module DecidimAwesome
|
5
|
+
module Admin
|
6
|
+
class AuthorizationGroupForm < Decidim::Form
|
7
|
+
include TranslatableAttributes
|
8
|
+
|
9
|
+
attribute :authorization_handlers, { String => Object }
|
10
|
+
attribute :authorization_handlers_names, Array[String]
|
11
|
+
attribute :authorization_handlers_options, { String => Object }
|
12
|
+
translatable_attribute :force_authorization_help_text, String, default: {}
|
13
|
+
|
14
|
+
def verification_settings
|
15
|
+
{
|
16
|
+
authorization_handlers: parsed_authorization_handlers,
|
17
|
+
force_authorization_help_text: force_authorization_help_text || {}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def parsed_authorization_handlers
|
22
|
+
authorization_handlers_names.filter_map do |name|
|
23
|
+
next if name.blank?
|
24
|
+
|
25
|
+
[
|
26
|
+
name,
|
27
|
+
{ options: authorization_handler_options(name) }
|
28
|
+
]
|
29
|
+
end.to_h
|
30
|
+
end
|
31
|
+
|
32
|
+
def options_schema(handler_name)
|
33
|
+
options_manifest(handler_name).schema.new(authorization_handler_options(handler_name))
|
34
|
+
end
|
35
|
+
|
36
|
+
def authorization_handlers_names
|
37
|
+
super.presence || authorization_handlers.keys.map(&:to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
def authorization_handler_options(handler_name)
|
41
|
+
authorization_handlers_options&.dig(handler_name.to_s) || authorization_handlers&.dig(handler_name, "options").presence || {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def options_attributes(handler_name)
|
45
|
+
manifest = options_manifest(handler_name)
|
46
|
+
manifest ? manifest.attributes : []
|
47
|
+
end
|
48
|
+
|
49
|
+
def manifest(handler_name)
|
50
|
+
Decidim::Verifications.find_workflow_manifest(handler_name)
|
51
|
+
end
|
52
|
+
|
53
|
+
def options_manifest(handler_name)
|
54
|
+
manifest(handler_name).options
|
55
|
+
end
|
56
|
+
|
57
|
+
# Helper for the view, at this point, ephemeral authorizations are not supported yet
|
58
|
+
def available_authorizations
|
59
|
+
Decidim.authorization_workflows.filter do |workflow|
|
60
|
+
current_organization.available_authorizations.include?(workflow.name) && !workflow.ephemeral?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -18,9 +18,11 @@ module Decidim
|
|
18
18
|
attribute :proposal_custom_fields, Hash
|
19
19
|
attribute :proposal_private_custom_fields, Hash
|
20
20
|
attribute :user_timezone, Boolean
|
21
|
-
attribute :
|
22
|
-
attribute :
|
23
|
-
|
21
|
+
attribute :force_authorizations, Hash, default: {}
|
22
|
+
attribute :hashcash_signup, Boolean
|
23
|
+
attribute :hashcash_signup_bits, Integer, default: Decidim::DecidimAwesome.hashcash_signup_bits
|
24
|
+
attribute :hashcash_login, Boolean
|
25
|
+
attribute :hashcash_login_bits, Integer, default: Decidim::DecidimAwesome.hashcash_login_bits
|
24
26
|
attribute :scoped_admins, Hash
|
25
27
|
attribute :menu, [MenuForm]
|
26
28
|
attribute :intergram_for_admins, Boolean
|
@@ -49,27 +51,29 @@ module Decidim
|
|
49
51
|
validates :validate_body_min_length, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
50
52
|
validates :validate_body_max_caps_percent, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }
|
51
53
|
validates :validate_body_max_marks_together, presence: true, numericality: { greater_than_or_equal_to: 1 }
|
52
|
-
|
54
|
+
validates :hashcash_signup_bits, presence: true, numericality: { greater_than_or_equal_to: 10, less_than_or_equal_to: 50 }
|
55
|
+
validates :hashcash_login_bits, presence: true, numericality: { greater_than_or_equal_to: 10, less_than_or_equal_to: 50 }
|
53
56
|
# TODO: validate non general admins are here
|
54
57
|
|
55
58
|
def self.from_params(params, additional_params = {})
|
56
59
|
instance = super(params, additional_params)
|
57
|
-
instance.
|
58
|
-
instance.
|
60
|
+
instance.valid_keys = params.keys.map(&:to_sym) || []
|
61
|
+
instance.force_authorizations = build_force_authorizations(instance.force_authorizations)
|
59
62
|
instance.sanitize_labels!
|
63
|
+
instance.sanitize_arrays!
|
60
64
|
instance
|
61
65
|
end
|
62
66
|
|
63
|
-
def self.
|
64
|
-
|
65
|
-
|
66
|
-
keys << if key.to_s.starts_with?("force_authorization_help_text_")
|
67
|
-
:force_authorization_help_text if keys.exclude?(:force_authorization_help_text)
|
68
|
-
else
|
69
|
-
key.to_sym
|
70
|
-
end
|
67
|
+
def self.build_force_authorizations(raw_groups)
|
68
|
+
raw_groups.transform_values do |group_data|
|
69
|
+
group_data.is_a?(AuthorizationGroupForm) ? group_data : AuthorizationGroupForm.new(group_data)
|
71
70
|
end
|
72
|
-
|
71
|
+
end
|
72
|
+
|
73
|
+
def force_authorizations_attributes
|
74
|
+
return {} unless force_authorizations.is_a?(Hash)
|
75
|
+
|
76
|
+
force_authorizations.transform_values(&:verification_settings)
|
73
77
|
end
|
74
78
|
|
75
79
|
def additional_proposal_sorting_labels
|
@@ -135,15 +139,10 @@ module Decidim
|
|
135
139
|
end
|
136
140
|
end
|
137
141
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
invalid = force_authorization_after_login - (current_organization.available_authorizations & Decidim.authorization_workflows.map(&:name))
|
144
|
-
return if invalid.empty?
|
145
|
-
|
146
|
-
errors.add(:force_authorization_after_login, :invalid)
|
142
|
+
def sanitize_arrays!
|
143
|
+
scoped_admins.transform_values! do |code|
|
144
|
+
code.is_a?(Array) ? code.compact_blank : code
|
145
|
+
end
|
147
146
|
end
|
148
147
|
end
|
149
148
|
end
|
@@ -9,11 +9,13 @@ module Decidim
|
|
9
9
|
attribute :participatory_space_slug, String
|
10
10
|
attribute :component_manifest, String
|
11
11
|
attribute :component_id, Integer
|
12
|
+
attribute :application_context, String
|
12
13
|
|
13
14
|
validates :component_manifest, absence: true, if: lambda { |form|
|
14
15
|
form.component_id.present? || ConfigConstraintsHelpers::OTHER_MANIFESTS.include?(form.participatory_space_manifest&.to_sym)
|
15
16
|
}
|
16
17
|
validates :component_id, absence: true, if: ->(form) { form.component_manifest.present? }
|
18
|
+
validates :application_context, inclusion: { in: ConfigConstraintsHelpers::APPLICATION_CONTEXTS.map(&:to_s) }, allow_blank: true
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -53,7 +53,8 @@ module Decidim
|
|
53
53
|
return if component.settings.participatory_texts_enabled?
|
54
54
|
|
55
55
|
awesome_config = Decidim::DecidimAwesome::Config.new(component.organization)
|
56
|
-
awesome_config.context_from_component(component)
|
56
|
+
awesome_config.context_from_component!(component)
|
57
|
+
awesome_config.application_context!(current_user:)
|
57
58
|
|
58
59
|
pub = awesome_config.collect_sub_configs_values("proposal_custom_field")
|
59
60
|
priv = awesome_config.collect_sub_configs_values("proposal_private_custom_field")
|
@@ -5,10 +5,11 @@ module Decidim
|
|
5
5
|
module Admin
|
6
6
|
module ConfigConstraintsHelpers
|
7
7
|
OTHER_MANIFESTS = [:none, :system, :process_groups].freeze
|
8
|
+
APPLICATION_CONTEXTS = [:user_logged_in, :anonymous].freeze
|
8
9
|
|
9
10
|
include Decidim::TranslatableAttributes
|
10
11
|
|
11
|
-
delegate :menus, :config_enabled?, to: "Decidim::DecidimAwesome::Menu"
|
12
|
+
delegate :menus, :main_path_for, :config_enabled?, to: "Decidim::DecidimAwesome::Menu"
|
12
13
|
|
13
14
|
def check(status)
|
14
15
|
content_tag(:span, icon(status ? "check-line" : "close-line", class: "inline-block", aria_label: status, role: "img"), class: "fill-#{status ? "success" : "alert"}")
|
@@ -50,30 +51,32 @@ module Decidim
|
|
50
51
|
space = model_for_manifest(manifest)
|
51
52
|
return {} unless space&.column_names&.include? "slug"
|
52
53
|
|
53
|
-
components = Component.where(participatory_space: space.find_by(slug:))
|
54
|
+
components = Decidim::Component.where(participatory_space: space.find_by(slug:))
|
54
55
|
components.to_h do |item|
|
55
56
|
[item.id, "#{item.id}: #{translated_attribute(item.name)}"]
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
60
|
+
def contexts_list
|
61
|
+
ConfigConstraintsHelpers::APPLICATION_CONTEXTS.index_with { |c| I18n.t("decidim.decidim_awesome.admin.config.#{c}") }
|
62
|
+
end
|
63
|
+
|
59
64
|
def translate_constraint_value(constraint, key)
|
60
65
|
value = constraint.settings[key]
|
61
|
-
case key.to_sym
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
value
|
76
|
-
end
|
66
|
+
translation = case key.to_sym
|
67
|
+
when :participatory_space_manifest
|
68
|
+
participatory_space_manifests[value.to_sym]
|
69
|
+
when :participatory_space_slug
|
70
|
+
participatory_spaces_list(constraint.settings["participatory_space_manifest"])[value]
|
71
|
+
when :component_manifest
|
72
|
+
component_manifests[value.to_sym]
|
73
|
+
when :component_id
|
74
|
+
component = Decidim::Component.find_by(id: value)
|
75
|
+
"#{component.id}: #{translated_attribute(component.name)}" if component
|
76
|
+
when :application_context
|
77
|
+
I18n.t("decidim.decidim_awesome.admin.config.#{value}")
|
78
|
+
end
|
79
|
+
translation.presence || value
|
77
80
|
end
|
78
81
|
|
79
82
|
def md5(text)
|
@@ -10,7 +10,7 @@ module Decidim
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# rubocop:disable Metrics/CyclomaticComplexity
|
13
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
13
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
14
14
|
def awesome_map_for(components, &)
|
15
15
|
return unless map_utility_dynamic
|
16
16
|
|
@@ -57,7 +57,7 @@ module Decidim
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
# rubocop:enable Metrics/CyclomaticComplexity
|
60
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
60
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
61
61
|
|
62
62
|
def step_settings
|
63
63
|
settings_source.try(:current_settings)
|
@@ -71,6 +71,7 @@ module Decidim
|
|
71
71
|
try(:current_component) || self
|
72
72
|
end
|
73
73
|
|
74
|
+
# rubocop:disable Rails/HelperInstanceVariable
|
74
75
|
def current_categories(categories)
|
75
76
|
return @current_categories if @current_categories
|
76
77
|
|
@@ -114,6 +115,7 @@ module Decidim
|
|
114
115
|
color: format("#%02x%02x%02x", r, g, b)
|
115
116
|
)
|
116
117
|
end
|
118
|
+
# rubocop:enable Rails/HelperInstanceVariable
|
117
119
|
|
118
120
|
# HSV values in [0..1[
|
119
121
|
# returns [r, g, b] values from 0 to 255
|
@@ -20,7 +20,7 @@ module Decidim
|
|
20
20
|
# add users that might have been completly destroyed in any organization
|
21
21
|
relevant_user_ids += user_ids_from_object_changes - Decidim::User.select("id").where(id: user_ids_from_object_changes).pluck(:id)
|
22
22
|
|
23
|
-
role_changes.where("object_changes ~ ANY (array[?])", relevant_user_ids.map { |id| "decidim_user_id:\n- ?\n- #{id}" })
|
23
|
+
role_changes.where("object_changes ~ ANY (array[?])", relevant_user_ids.map { |id| "decidim_user_id:\n- ?\n- #{id}(?!\\d)" })
|
24
24
|
}
|
25
25
|
|
26
26
|
scope :in_organization, lambda { |organization|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
<!-- insert_after "erb[loud]:contains('append_stylesheet_pack_tag')" -->
|
2
2
|
|
3
3
|
<% append_stylesheet_pack_tag "decidim_decidim_awesome", media: "all" %>
|
4
|
-
<%= render(partial: "layouts/decidim/decidim_awesome/custom_styles") if awesome_scoped_styles.present? %>
|
5
|
-
|
6
4
|
<% append_javascript_pack_tag "decidim_decidim_awesome", defer: false %>
|
7
5
|
<% append_javascript_pack_tag("decidim_decidim_awesome_custom_fields") if Decidim::DecidimAwesome.enabled?(:proposal_custom_fields) %>
|