decidim-core 0.7.4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +9 -2
- data/app/assets/javascripts/decidim.js.es6 +1 -0
- data/app/assets/javascripts/decidim/editor.js.es6 +8 -2
- data/app/assets/javascripts/decidim/form_filter.component.js.es6 +2 -2
- data/app/assets/javascripts/decidim/foundation.js.es6 +18 -8
- data/app/assets/javascripts/decidim/select2.js.es6 +3 -0
- data/app/assets/stylesheets/decidim/_decidim.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_buttons.scss +0 -4
- data/app/assets/stylesheets/decidim/modules/_cards.scss +41 -1
- data/app/assets/stylesheets/decidim/modules/_messages.scss +35 -0
- data/app/assets/stylesheets/decidim/modules/_modules.scss +1 -0
- data/app/assets/stylesheets/decidim/modules/_navbar.scss +2 -1
- data/app/assets/stylesheets/decidim/utils/_settings.scss +363 -69
- data/app/commands/decidim/messaging/reply_to_conversation.rb +55 -0
- data/app/commands/decidim/messaging/start_conversation.rb +55 -0
- data/app/controllers/concerns/decidim/action_authorization.rb +6 -22
- data/app/controllers/concerns/decidim/user_profile.rb +5 -3
- data/app/controllers/decidim/application_controller.rb +1 -0
- data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +2 -2
- data/app/controllers/decidim/devise/sessions_controller.rb +5 -3
- data/app/controllers/decidim/features/base_controller.rb +1 -0
- data/app/controllers/decidim/messaging/conversations_controller.rb +81 -0
- data/app/controllers/decidim/pages_controller.rb +2 -11
- data/app/forms/decidim/messaging/conversation_form.rb +19 -0
- data/app/forms/decidim/messaging/message_form.rb +14 -0
- data/app/forms/translatable_presence_validator.rb +7 -10
- data/app/helpers/decidim/authorization_form_helper.rb +1 -1
- data/app/helpers/decidim/cta_button_helper.rb +1 -1
- data/app/helpers/decidim/datetime_helper.rb +23 -0
- data/app/helpers/decidim/feature_path_helper.rb +4 -2
- data/app/helpers/decidim/layout_helper.rb +0 -2
- data/app/helpers/decidim/menu_helper.rb +10 -0
- data/app/helpers/decidim/messaging/conversation_helper.rb +36 -0
- data/app/helpers/decidim/sanitize_helper.rb +19 -0
- data/app/helpers/decidim/traceability_helper.rb +89 -0
- data/app/helpers/decidim/translations_helper.rb +4 -2
- data/app/helpers/decidim/view_hooks_helper.rb +15 -0
- data/app/jobs/decidim/email_notification_generator_job.rb +1 -1
- data/app/jobs/decidim/notification_generator_for_recipient_job.rb +1 -1
- data/app/jobs/decidim/notification_generator_job.rb +1 -1
- data/app/mailers/decidim/messaging/conversation_mailer.rb +47 -0
- data/app/mailers/decidim/newsletter_mailer.rb +1 -0
- data/app/models/decidim/abilities/base_ability.rb +16 -2
- data/app/models/decidim/authorization.rb +20 -2
- data/app/models/decidim/messaging/conversation.rb +129 -0
- data/app/models/decidim/messaging/message.rb +49 -0
- data/app/models/decidim/messaging/participation.rb +23 -0
- data/app/models/decidim/messaging/receipt.rb +27 -0
- data/app/models/decidim/moderation.rb +1 -1
- data/app/models/decidim/organization.rb +2 -2
- data/app/models/decidim/scope.rb +2 -1
- data/app/models/decidim/scope_type.rb +1 -1
- data/app/models/decidim/user.rb +11 -5
- data/app/models/decidim/user_group.rb +1 -1
- data/app/presenters/decidim/inline_menu_presenter.rb +10 -0
- data/app/presenters/decidim/menu_presenter.rb +1 -1
- data/app/queries/decidim/messaging/user_conversations.rb +29 -0
- data/app/scrubbers/decidim/user_input_scrubber.rb +31 -0
- data/app/services/decidim/action_authorizer.rb +48 -12
- data/app/services/decidim/traceability.rb +91 -0
- data/app/views/decidim/messaging/conversation_mailer/new_conversation.html.erb +9 -0
- data/app/views/decidim/messaging/conversation_mailer/new_message.html.erb +9 -0
- data/app/views/decidim/messaging/conversations/_message.html.erb +20 -0
- data/app/views/decidim/messaging/conversations/_reply.html.erb +11 -0
- data/app/views/decidim/messaging/conversations/_show.html.erb +21 -0
- data/app/views/decidim/messaging/conversations/_start.html.erb +12 -0
- data/app/views/decidim/messaging/conversations/create.js.erb +2 -0
- data/app/views/decidim/messaging/conversations/index.html.erb +51 -0
- data/app/views/decidim/messaging/conversations/new.html.erb +5 -0
- data/app/views/decidim/messaging/conversations/show.html.erb +9 -0
- data/app/views/decidim/messaging/conversations/update.js.erb +1 -0
- data/app/views/decidim/newsletter_mailer/newsletter.html.erb +1 -1
- data/app/views/decidim/notifications/_notification.html.erb +1 -1
- data/app/views/decidim/shared/_action_authorization_modal.html.erb +11 -1
- data/app/views/decidim/shared/_announcement.html.erb +1 -1
- data/app/views/decidim/shared/_version_author.html.erb +18 -0
- data/app/views/layouts/decidim/_wrapper.html.erb +3 -0
- data/app/views/layouts/decidim/user_profile.html.erb +1 -9
- data/app/views/pages/decidim_page.html.erb +1 -1
- data/app/views/pages/home.html.erb +0 -2
- data/app/views/pages/home/_footer_sub_hero.html.erb +5 -3
- data/app/views/pages/home/_hero.html.erb +1 -1
- data/app/views/pages/home/_highlighted_processes.html.erb +7 -37
- data/app/views/pages/home/_sub_hero.html.erb +6 -4
- data/config/locales/ca.yml +49 -21
- data/config/locales/en.yml +47 -19
- data/config/locales/es.yml +48 -20
- data/config/locales/eu.yml +51 -23
- data/config/locales/fi.yml +50 -22
- data/config/locales/fr.yml +50 -22
- data/config/locales/it.yml +89 -61
- data/config/locales/nl.yml +72 -44
- data/config/locales/pl.yml +49 -21
- data/config/locales/pt.yml +431 -0
- data/config/locales/ru.yml +4 -27
- data/config/locales/uk.yml +10 -23
- data/config/routes.rb +3 -5
- data/db/migrate/20170313095436_add_available_authorizations_to_organization.rb +2 -2
- data/db/migrate/20170713131308_migrate_user_roles_to_participatory_process_roles.rb +7 -3
- data/db/migrate/20170914092117_add_status_to_authorizations.rb +9 -0
- data/db/migrate/20171011194251_add_verification_metadata_to_authorizations.rb +11 -0
- data/db/migrate/20171013124505_add_verification_attachment_to_authorizations.rb +9 -0
- data/db/migrate/20171023123330_create_decidim_messaging.rb +23 -0
- data/db/migrate/20171107103253_create_versions.rb +18 -0
- data/db/migrate/20171107103254_add_object_changes_to_versions.rb +14 -0
- data/db/migrate/20171117100533_create_decidim_receipts.rb +13 -0
- data/db/seeds.rb +13 -3
- data/lib/decidim/core.rb +13 -6
- data/lib/decidim/core/engine.rb +37 -0
- data/lib/decidim/core/test/factories.rb +33 -21
- data/lib/decidim/core/test/shared_examples/follows_examples.rb +1 -1
- data/lib/decidim/core/test/shared_examples/manage_moderations_examples.rb +6 -11
- data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +2 -4
- data/lib/decidim/core/test/shared_examples/reportable.rb +33 -31
- data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +29 -31
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/engine_router.rb +4 -2
- data/lib/decidim/has_reference.rb +10 -2
- data/lib/decidim/messaging.rb +9 -0
- data/lib/decidim/participable.rb +1 -1
- data/lib/decidim/traceable.rb +31 -0
- data/lib/decidim/view_hooks.rb +108 -0
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.es.js +4 -2
- data/vendor/assets/javascripts/datepicker-locales/foundation-datepicker.pt.js +14 -0
- metadata +179 -113
- data/app/commands/decidim/authorize_user.rb +0 -59
- data/app/controllers/decidim/authorizations_controller.rb +0 -80
- data/app/services/decidim/authorization_handler.rb +0 -95
- data/app/views/decidim/authorizations/first_login.html.erb +0 -22
- data/app/views/decidim/authorizations/index.html.erb +0 -49
- data/app/views/decidim/authorizations/new.html.erb +0 -33
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Decidim
|
4
|
-
# A command to authorize a user with an authorization handler.
|
5
|
-
class AuthorizeUser < Rectify::Command
|
6
|
-
# Public: Initializes the command.
|
7
|
-
#
|
8
|
-
# handler - An AuthorizationHandler object.
|
9
|
-
def initialize(handler)
|
10
|
-
@handler = handler
|
11
|
-
end
|
12
|
-
|
13
|
-
# Executes the command. Broadcasts these events:
|
14
|
-
#
|
15
|
-
# - :ok when everything is valid.
|
16
|
-
# - :invalid if the handler wasn't valid and we couldn't proceed.
|
17
|
-
#
|
18
|
-
# Returns nothing.
|
19
|
-
def call
|
20
|
-
return broadcast(:invalid) unless handler.valid? && unique?
|
21
|
-
|
22
|
-
create_authorization
|
23
|
-
broadcast(:ok)
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
attr_reader :handler
|
29
|
-
|
30
|
-
def create_authorization
|
31
|
-
authorization = Authorization.find_or_initialize_by(
|
32
|
-
user: handler.user,
|
33
|
-
name: handler.handler_name
|
34
|
-
)
|
35
|
-
|
36
|
-
authorization.attributes = {
|
37
|
-
unique_id: handler.unique_id,
|
38
|
-
metadata: handler.metadata
|
39
|
-
}
|
40
|
-
|
41
|
-
authorization.save!
|
42
|
-
end
|
43
|
-
|
44
|
-
def unique?
|
45
|
-
return true if handler.unique_id.nil?
|
46
|
-
|
47
|
-
duplicates = Authorization.where(
|
48
|
-
user: User.where.not(id: handler.user.id).where(organization: handler.user.organization.id),
|
49
|
-
name: handler.handler_name,
|
50
|
-
unique_id: handler.unique_id
|
51
|
-
)
|
52
|
-
|
53
|
-
return true unless duplicates.any?
|
54
|
-
|
55
|
-
handler.errors.add(:base, I18n.t("decidim.authorization_handlers.errors.duplicate_authorization"))
|
56
|
-
false
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Decidim
|
4
|
-
# This controller allows users to create and destroy their authorizations. It
|
5
|
-
# shouldn't be necessary to expand it to add new authorization schemes.
|
6
|
-
class AuthorizationsController < Decidim::ApplicationController
|
7
|
-
helper_method :handler, :handlers
|
8
|
-
before_action :valid_handler, only: [:new, :create]
|
9
|
-
|
10
|
-
include Decidim::UserProfile
|
11
|
-
helper Decidim::DecidimFormHelper
|
12
|
-
helper Decidim::CtaButtonHelper
|
13
|
-
helper Decidim::AuthorizationFormHelper
|
14
|
-
|
15
|
-
layout "layouts/decidim/user_profile", only: [:index]
|
16
|
-
|
17
|
-
def new; end
|
18
|
-
|
19
|
-
def index
|
20
|
-
@authorizations = current_user.authorizations
|
21
|
-
end
|
22
|
-
|
23
|
-
def first_login
|
24
|
-
if handlers.length == 1
|
25
|
-
redirect_to(
|
26
|
-
action: :new,
|
27
|
-
handler: handlers.first.handler_name,
|
28
|
-
redirect_url: account_path
|
29
|
-
)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def create
|
34
|
-
AuthorizeUser.call(handler) do
|
35
|
-
on(:ok) do
|
36
|
-
flash[:notice] = t("authorizations.create.success", scope: "decidim")
|
37
|
-
redirect_to params[:redirect_url] || authorizations_path
|
38
|
-
end
|
39
|
-
|
40
|
-
on(:invalid) do
|
41
|
-
flash[:alert] = t("authorizations.create.error", scope: "decidim")
|
42
|
-
render action: :new
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
protected
|
48
|
-
|
49
|
-
def handler
|
50
|
-
@handler ||= AuthorizationHandler.handler_for(handler_name, handler_params)
|
51
|
-
end
|
52
|
-
|
53
|
-
def handler_params
|
54
|
-
(params[:authorization_handler] || {}).merge(user: current_user)
|
55
|
-
end
|
56
|
-
|
57
|
-
def handler_name
|
58
|
-
params[:handler] || params.dig(:authorization_handler, :handler_name)
|
59
|
-
end
|
60
|
-
|
61
|
-
def valid_handler
|
62
|
-
return true if handler
|
63
|
-
|
64
|
-
logger.warn "Invalid authorization handler given: #{handler_name} doesn't"\
|
65
|
-
"exist or you haven't added it to `Decidim.authorization_handlers`"
|
66
|
-
|
67
|
-
redirect_to(authorizations_path) && (return false)
|
68
|
-
end
|
69
|
-
|
70
|
-
def handlers
|
71
|
-
@handlers ||= available_authorization_handlers.reject do |handler|
|
72
|
-
authorized_handlers.include?(handler.handler_name)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def authorized_handlers
|
77
|
-
current_user.authorizations.map(&:name)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Decidim
|
4
|
-
# This is the base class for authorization handlers, all implementations
|
5
|
-
# should inherit from it.
|
6
|
-
# Each AuthorizationHandler is a form that will be used to check if the
|
7
|
-
# authorization is valid or not. When it is valid a new authorization will
|
8
|
-
# be created for the user.
|
9
|
-
#
|
10
|
-
# Feel free to use validations to assert fields against a remote API,
|
11
|
-
# local database, or whatever.
|
12
|
-
#
|
13
|
-
# It also sets two default attributes, `user` and `handler_name`.
|
14
|
-
class AuthorizationHandler < Form
|
15
|
-
# The user that is trying to authorize, it's initialized with the
|
16
|
-
# `current_user` from the controller.
|
17
|
-
attribute :user, Decidim::User
|
18
|
-
# The String name of the handler, should not be modified since it's used to
|
19
|
-
# infer the class name of the authorization handler.
|
20
|
-
attribute :handler_name, String
|
21
|
-
|
22
|
-
# A unique ID to be implemented by the authorization handler that ensures
|
23
|
-
# no duplicates are created. This uniqueness check will be skipped if
|
24
|
-
# unique_id returns nil.
|
25
|
-
def unique_id
|
26
|
-
nil
|
27
|
-
end
|
28
|
-
|
29
|
-
# THe attributes of the handler that should be exposed as form input when
|
30
|
-
# rendering the handler in a form.
|
31
|
-
#
|
32
|
-
# Returns an Array of Strings.
|
33
|
-
def form_attributes
|
34
|
-
attributes.except(:id, :user).keys
|
35
|
-
end
|
36
|
-
|
37
|
-
# The String partial path so Rails can render the handler as a form. This
|
38
|
-
# is useful if you want to have a custom view to render the form instead of
|
39
|
-
# the default view.
|
40
|
-
#
|
41
|
-
# Example:
|
42
|
-
#
|
43
|
-
# A handler named Decidim::CensusHandler would look for its partial in:
|
44
|
-
# decidim/census/form
|
45
|
-
#
|
46
|
-
# Returns a String.
|
47
|
-
def to_partial_path
|
48
|
-
handler_name.sub!(/_handler$/, "") + "/form"
|
49
|
-
end
|
50
|
-
|
51
|
-
# Any data that the developer would like to inject to the `metadata` field
|
52
|
-
# of an authorization when it's created. Can be useful if some of the
|
53
|
-
# params the user sent with the authorization form want to be persisted for
|
54
|
-
# future use.
|
55
|
-
#
|
56
|
-
# Returns a Hash.
|
57
|
-
def metadata
|
58
|
-
{}
|
59
|
-
end
|
60
|
-
|
61
|
-
# A serialized version of the handler's name.
|
62
|
-
#
|
63
|
-
# Returns a String.
|
64
|
-
def self.handler_name
|
65
|
-
name.underscore
|
66
|
-
end
|
67
|
-
|
68
|
-
# Same as the class method but accessible from the instance.
|
69
|
-
#
|
70
|
-
# Returns a String.
|
71
|
-
def handler_name
|
72
|
-
self.class.handler_name
|
73
|
-
end
|
74
|
-
|
75
|
-
# Finds a handler class from a String. This is necessary when processing
|
76
|
-
# the form data. It will only look for valid handlers that have also been
|
77
|
-
# configured in `Decidim.authorization_handlers`.
|
78
|
-
#
|
79
|
-
# name - The String name of the class to find, usually in the same shape as
|
80
|
-
# the one returned by `handler_name`.
|
81
|
-
# params - An optional Hash with params to initialize the handler.
|
82
|
-
#
|
83
|
-
# Returns an AuthorizationHandler descendant.
|
84
|
-
# Returns nil when no handlers could be found.
|
85
|
-
def self.handler_for(name, params = {})
|
86
|
-
return unless active_handler?(name)
|
87
|
-
|
88
|
-
name.classify.constantize.from_params(params || {})
|
89
|
-
end
|
90
|
-
|
91
|
-
def self.active_handler?(name)
|
92
|
-
name && Decidim.authorization_handlers.include?(name.classify)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
<main class="wrapper">
|
2
|
-
<div class="row collapse">
|
3
|
-
<div class="row collapse">
|
4
|
-
<div class="columns large-8 large-centered text-center">
|
5
|
-
<h1 class="heading1 page-title"><%= t(".title") %></h1>
|
6
|
-
<p class="heading5"><%= t(".verify_with_these_options") %></p>
|
7
|
-
</div>
|
8
|
-
</div>
|
9
|
-
<div class="row">
|
10
|
-
<div class="columns medium-7 large-5 medium-centered">
|
11
|
-
<div class="card">
|
12
|
-
<div class="card__content">
|
13
|
-
<% handlers.each do |handler| %>
|
14
|
-
<%= link_to t("authorizations.first_login.actions.#{handler.handler_name}", scope: "decidim"), new_authorization_path(handler: handler.handler_name), class: "button expanded" %>
|
15
|
-
<% end %>
|
16
|
-
<p class="text-center skip"><%= t("decidim.authorizations.skip_verification", link: link_to(t("decidim.authorizations.start_exploring"), cta_button_path).html_safe).html_safe %>.</p>
|
17
|
-
</div>
|
18
|
-
</div>
|
19
|
-
</div>
|
20
|
-
</div>
|
21
|
-
</div>
|
22
|
-
</main>
|
@@ -1,49 +0,0 @@
|
|
1
|
-
<div class="row column authorizations-list">
|
2
|
-
<% if @authorizations.any? %>
|
3
|
-
<section class="section">
|
4
|
-
<div class="card card--list">
|
5
|
-
<% @authorizations.each do |authorization| %>
|
6
|
-
<div class="card--list__item">
|
7
|
-
<div class="card--list__text">
|
8
|
-
<%= icon "lock-unlocked", class: "card--list__icon" %>
|
9
|
-
<div>
|
10
|
-
<h5 class="card--list__heading">
|
11
|
-
<%= t("#{authorization.name}.name", scope: "decidim.authorization_handlers") %>
|
12
|
-
</h5>
|
13
|
-
<span class="text-small"><%= l(authorization.updated_at, format: :long) %></span>
|
14
|
-
</div>
|
15
|
-
</div>
|
16
|
-
<div class="card--list__data">
|
17
|
-
<%= link_to new_authorization_path(handler: authorization.name), class: "card--list__data__icon" do %>
|
18
|
-
<%= icon "reload" %>
|
19
|
-
<% end %>
|
20
|
-
</div>
|
21
|
-
</div>
|
22
|
-
<% end %>
|
23
|
-
</div>
|
24
|
-
<% end %>
|
25
|
-
<% if handlers.any? %>
|
26
|
-
<div class="card card--list">
|
27
|
-
<% handlers.each do |handler| %>
|
28
|
-
<div class="card--list__item">
|
29
|
-
<div class="card--list__text">
|
30
|
-
<a href="#">
|
31
|
-
<%= icon "lock-locked", class: "card--list__icon" %>
|
32
|
-
</a>
|
33
|
-
<div>
|
34
|
-
<h5 class="card--list__heading">
|
35
|
-
<%= link_to t("#{handler.handler_name}.name", scope: "decidim.authorization_handlers"), new_authorization_path(handler: handler.handler_name) %>
|
36
|
-
</h5>
|
37
|
-
</div>
|
38
|
-
</div>
|
39
|
-
<div class="card--list__data">
|
40
|
-
<%= link_to new_authorization_path(handler: handler.handler_name), class: "card--list__data__icon" do %>
|
41
|
-
<%= icon "chevron-right" %>
|
42
|
-
<% end %>
|
43
|
-
</div>
|
44
|
-
</div>
|
45
|
-
<% end %>
|
46
|
-
</div>
|
47
|
-
</section>
|
48
|
-
<% end %>
|
49
|
-
</div>
|
@@ -1,33 +0,0 @@
|
|
1
|
-
<main class="wrapper">
|
2
|
-
<div class="row collapse">
|
3
|
-
<div class="row collapse">
|
4
|
-
<div class="columns large-8 large-centered text-center page-title">
|
5
|
-
<h1><%= t(".authorize_with", authorizer: t("#{handler.handler_name}.name", scope: "decidim.authorization_handlers")) %></h1>
|
6
|
-
</div>
|
7
|
-
</div>
|
8
|
-
|
9
|
-
<div class="row">
|
10
|
-
<div class="columns large-6 medium-centered">
|
11
|
-
<div class="card">
|
12
|
-
<div class="card__content">
|
13
|
-
<%= authorization_form_for(handler, url: authorizations_path(redirect_url: params[:redirect_url])) do |form| %>
|
14
|
-
<%= form.error_for(:base) %>
|
15
|
-
|
16
|
-
<% if lookup_context.exists?(handler.to_partial_path, [], true) %>
|
17
|
-
<%= render partial: handler.to_partial_path, locals: { handler: handler, form: form } %>
|
18
|
-
<% else %>
|
19
|
-
<%= form.all_fields %>
|
20
|
-
<div class="actions">
|
21
|
-
<%= form.submit t(".authorize"), class: "button expanded" %>
|
22
|
-
</div>
|
23
|
-
<% end %>
|
24
|
-
<% end %>
|
25
|
-
<p class="text-center skip">
|
26
|
-
<%= t("decidim.authorizations.skip_verification", link: link_to(t("decidim.authorizations.start_exploring"), cta_button_path).html_safe).html_safe %>.
|
27
|
-
</p>
|
28
|
-
</div>
|
29
|
-
</div>
|
30
|
-
</div>
|
31
|
-
</div>
|
32
|
-
</div>
|
33
|
-
</main>
|