decidim-voca 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +661 -0
  3. data/README.md +153 -0
  4. data/Rakefile +86 -0
  5. data/app/assets/config/voca_manifest.js +0 -0
  6. data/app/assets/images/decidim/voca/icon.svg +1 -0
  7. data/app/commands/decidim/voca/organization/command.rb +16 -0
  8. data/app/commands/decidim/voca/organization/organization_command.rb +17 -0
  9. data/app/commands/decidim/voca/organization/update_color_command.rb +35 -0
  10. data/app/commands/decidim/voca/organization/update_environment_command.rb +23 -0
  11. data/app/commands/decidim/voca/organization/update_feature_command.rb +32 -0
  12. data/app/commands/decidim/voca/organization/update_file_upload_command.rb +45 -0
  13. data/app/commands/decidim/voca/organization/update_locale_command.rb +53 -0
  14. data/app/commands/decidim/voca/organization/update_naming_command.rb +30 -0
  15. data/app/commands/decidim/voca/organization/update_permission_command.rb +31 -0
  16. data/app/commands/decidim/voca/organization/update_smtp_command.rb +51 -0
  17. data/app/controllers/decidim/voca/admin/application_controller.rb +15 -0
  18. data/app/controllers/decidim/voca/application_controller.rb +13 -0
  19. data/app/jobs/decidim/voca/command_job.rb +36 -0
  20. data/app/jobs/decidim/voca/webhook_notifier_job.rb +57 -0
  21. data/app/rpc/decidim/voca/decidim_service_controller.rb +68 -0
  22. data/app/rpc/decidim/voca/rpc/enum_casting.rb +58 -0
  23. data/app/rpc/decidim/voca/rpc/get_settings.rb +144 -0
  24. data/app/rpc/decidim/voca/rpc/health.rb +18 -0
  25. data/app/rpc/decidim/voca/rpc/seed_admin.rb +75 -0
  26. data/app/rpc/decidim/voca/rpc/set_settings.rb +56 -0
  27. data/app/rpc/decidim/voca/rpc/setup_db.rb +38 -0
  28. data/config/environments/development.rb +6 -0
  29. data/config/i18n-tasks.yml +9 -0
  30. data/config/locales/en.yml +6 -0
  31. data/config/spring.rb +2 -0
  32. data/lib/decidim/voca/admin.rb +10 -0
  33. data/lib/decidim/voca/admin_engine.rb +27 -0
  34. data/lib/decidim/voca/backup/app_backup.rb +169 -0
  35. data/lib/decidim/voca/backup/app_decrypt_backup_file.rb +50 -0
  36. data/lib/decidim/voca/backup/app_encrypt_backup_file.rb +49 -0
  37. data/lib/decidim/voca/backup/app_upload_to_s3.rb +49 -0
  38. data/lib/decidim/voca/engine.rb +31 -0
  39. data/lib/decidim/voca/middleware/dynamic_config_middleware.rb +42 -0
  40. data/lib/decidim/voca/rpc/decidim_pb.rb +134 -0
  41. data/lib/decidim/voca/rpc/decidim_services_pb.rb +30 -0
  42. data/lib/decidim/voca/test/factories.rb +9 -0
  43. data/lib/decidim/voca/updater.rb +50 -0
  44. data/lib/decidim/voca/version.rb +13 -0
  45. data/lib/decidim/voca.rb +22 -0
  46. data/lib/tasks/voca.rake +88 -0
  47. metadata +124 -0
data/README.md ADDED
@@ -0,0 +1,153 @@
1
+ [![coverage](https://git.octree.ch/decidim/vocacity/tasks/badges/main/coverage.svg?job=coverage-024)](https://github.com/octree-gva/voca-tasks)
2
+
3
+ [![release](https://git.octree.ch/decidim/vocacity/tasks/badges/main/release.svg)](https://github.com/octree-gva/voca-tasks)
4
+
5
+ # Voca
6
+
7
+ Create&Manage Decidim instances on-the-fly, deploy all its ecosystem.
8
+ Voca focuses on Decidim, released on [APGL-3 open-source license](LICENSE.md) and all the ecosystem around the platform. As _Decidim is not a tool, but a framework for digital democratic participation, many tools gravitates around Decidim._
9
+
10
+ # RPC private API for Decidim
11
+ This gem add internal functionalities to Decidim in order to be managed remotly. We do mostly:
12
+
13
+ - Setup [gruf](https://github.com/bigcommerce/gruf) to run a gRPC server
14
+ - Implement the [decidim.proto](https://raw.githubusercontent.com/octree-gva/voca-system/main/backend/contrib/rpc-protos/decidim/decidim.proto) spec
15
+ - Add a middleware two dynamically set config data.
16
+
17
+
18
+ ## RPC
19
+ From the .proto file, two files are generated, lib/decidim/voca/rpc/decidim_pb.rb and lib/decidim/voca/rpc/decidim_services_pb.rb. These files describe the skeletton of the input and response we need to comply.
20
+
21
+ In the controller `Decidim::Voca::DecidimServiceController`, we bind its method to these services and execute Commands for each methods.
22
+ For example, a compile method is implemented this way:
23
+
24
+ ```
25
+ ## Compile assets.
26
+ def compile_assets
27
+ `bundle exec rails assets:precompile`
28
+ ::Google::Protobuf::Empty.new
29
+ end
30
+ ```
31
+
32
+ When the code to resolves a RPC methods take more than 2 lines, we do a Command to isolate the code in one class. This is the case for most of the code. You can find the in the [rpc directory](./app/rpc/decidim/voca/rpc).
33
+
34
+ ### Casting
35
+ As RPC is a generic way to build APIs, we have to translate constants in appropriate string for the application.
36
+
37
+ For example, `SETTINGS_REGISTER_MODE_OPTION::SETTINGS_REGISTER_MODE_REGISTER_AND_LOGIN` is actually just `enable` for the user_register_mode Decidim settings. To do so,
38
+ we have an utility class `Decidim::Voca::Rpc::EnumCaster`.
39
+
40
+ ## Middleware
41
+ We get inspiration on [this article](https://pawelurbanek.com/rails-dynamic-config) to setup a middleware that retrieve config values from redis and then inject it into the code.
42
+
43
+ For every query, we do a small step of getting data from our Redis store,
44
+ and inject the configuration object in Decidim. Like this:
45
+ ```
46
+ # ./lib/decidim/voca/middleware/dynamic_config_middleware.rb
47
+ if config_data["currency_unit"].present?
48
+ Decidim.currency_unit = config_data["currency_unit"]
49
+ end
50
+ ```
51
+
52
+ This is particularly usefull as it allows us to include Decidim configurations in our `decidim.proto` file, and set the redis value when needed.
53
+
54
+ ```
55
+ # ./app/commands/decidim/voca/organization/update_locale_command.rb
56
+ global_configuration = locale_settings.select do |key|
57
+ "#{key}" == "currency_unit" || "#{key}" == "timezone"
58
+ end.delete_if { |_k, v| v.blank? }
59
+ unless global_configuration.empty?
60
+ redis_client = Redis.new(
61
+ url: ENV.fetch("REDIS_CONFIG_URL", "redis://127.0.0.1:6379/2"),
62
+ );
63
+ global_configuration.each do |key, value|
64
+ # Update the Redis hash values
65
+ redis_client.hset("config", "#{key}", "#{value}")
66
+ end
67
+ # Close the Redis connection
68
+ redis_client.quit
69
+ end
70
+ ```
71
+ ## Repositories
72
+
73
+ | repo | info | stable version |
74
+ | -------------------------------------------------------- | --------------------------------------------------------------------------- | -------------- |
75
+ | [voca-system](https://github.com/octree-gva/voca-system) | Install and manage decidim instances through a Dashboard | v0.1.0 |
76
+ | [voca-tasks](https://github.com/octree-gva/voca-tasks) | Gem embedded in our Decidim image. Manipulate and manage decidim instances. | v0.1.0 |
77
+ | [voca-jps](https://github.com/octree-gva/voca-jps) | Jelastic Manifest to deploy Decidim images | v0.1.0 |
78
+ | [voca-docker](https://github.com/octree-gva/voca-docker) | Build Decidim docker images for Voca | v0.1.0 |
79
+ | [voca-protos](https://github.com/octree-gva/voca-protos) | RPC prototypes for voca | v0.1.0 |
80
+
81
+ # Decidim::Voca
82
+
83
+ This Gem allows configuring a Decidim instance with gRPC. This is a domain-specific gem, which is useful only if you host your own Voca system.
84
+
85
+ ## Readings before starting
86
+
87
+ * [gruf, a RPC gem for rails](https://github.com/bigcommerce/gruf)
88
+ * [GRPC for ruby](https://grpc.io/docs/languages/ruby/)
89
+ * [proto3 Styleguide](https://developers.google.com/protocol-buffers/docs/style)
90
+
91
+ ## Repository structure
92
+
93
+ ### Generated client
94
+ The client is generated with `bundle exec rails update_voca_proto`, and
95
+ save the client and service in [`/lib/decidim/voca/rpc`](./lib/decidim/voca/rpc)
96
+
97
+ ### RPC Decidim Service
98
+ The entry point for RPC Decidim Service is in [`/app/rpc/decidim/voca/decidim_service_controller.rb`](./app/rpc/decidim/voca/decidim_service_controller.rb).
99
+ This controller have a method per registered message, and will call some concerns in the `/app/rpc/decidim/voca/rpc` folder.
100
+
101
+ ### Updating commands
102
+ We use Rectify::Command in `/app/commmands/decidim/voca` for all update-related command.
103
+
104
+
105
+ ## Installation
106
+
107
+ Add this line to your application's Gemfile:
108
+
109
+ ```ruby
110
+ gem "decidim-voca"
111
+ ```
112
+
113
+ And then execute:
114
+
115
+ ```sh
116
+ bundle install
117
+ ```
118
+
119
+ ## Development
120
+
121
+ We suppose you have docker installed in your environment.
122
+
123
+ ```sh
124
+ docker-compose up -d
125
+ docker-compose run --rm app bash -c "cd $RAILS_ROOT && rails db:migrate"
126
+ ```
127
+
128
+ Your development app with the gem is ready on `http://localhost:3000`
129
+
130
+ ### Run tests
131
+
132
+ `test_app` will create a `spec/dummy` app, and will run a local PostGres container.
133
+ This command has to be done before executing tests.
134
+
135
+ ```sh
136
+ bundle && bundle exec rails test_app
137
+ ```
138
+
139
+ Once this command pass, execute:
140
+
141
+ ```sh
142
+ bundle exec rspec spec
143
+ ```
144
+
145
+ to run the unit tests.
146
+
147
+ ## Contributing
148
+
149
+ See [Contributing](CONTRIBUTING.md).
150
+
151
+ ## License
152
+
153
+ See [License](LICENSE.md).
data/Rakefile ADDED
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/common_rake"
4
+
5
+ def install_module(path)
6
+ Dir.chdir(path) do
7
+ # system("bundle exec rake decidim_voca:install:migrations")
8
+ end
9
+ end
10
+
11
+ def seed_db(path)
12
+ Dir.chdir(path) do
13
+ system("bundle exec rails db:seed")
14
+ end
15
+ end
16
+
17
+ desc "Prepare for testing"
18
+ task :prepare_tests do
19
+ # Remove previous existing db, and recreate one.
20
+ disable_docker_compose = ENV.fetch("DISABLED_DOCKER_COMPOSE", "false") == "true"
21
+ unless disable_docker_compose
22
+ system("docker-compose -f docker-compose.yml down -v")
23
+ system("docker-compose -f docker-compose.yml up -d --remove-orphans")
24
+ end
25
+ ENV["RAILS_ENV"] = "test"
26
+ databaseYml = {
27
+ "test" => {
28
+ "adapter" => "postgresql",
29
+ "encoding" => "unicode",
30
+ "host" => ENV.fetch("DATABASE_HOST", "localhost"),
31
+ "port" => ENV.fetch("DATABASE_PORT", "5432").to_i,
32
+ "username" => ENV.fetch("DATABASE_USERNAME", "decidim"),
33
+ "password" => ENV.fetch("DATABASE_PASSWORD", "TEST-baeGhi4Ohtahcee5eejoaxaiwaezaiGo"),
34
+ "database" => "decidim_test"
35
+ }
36
+ }
37
+
38
+ config_file = File.expand_path("spec/dummy/config/database.yml", __dir__)
39
+ File.open(config_file, "w") { |f| YAML.dump(databaseYml, f) }
40
+ Dir.chdir("spec/dummy") do
41
+ system("bundle exec rails db:migrate")
42
+ end
43
+ end
44
+
45
+ desc "Generates a dummy app for testing"
46
+ task :test_app do
47
+ Bundler.with_original_env do
48
+ generate_decidim_app(
49
+ "spec/dummy",
50
+ "--app_name",
51
+ "decidim_test",
52
+ "--path",
53
+ "../..",
54
+ "--skip_spring",
55
+ "--demo",
56
+ "--force_ssl",
57
+ "false",
58
+ "--locales",
59
+ "en,fr,es"
60
+ )
61
+ end
62
+ install_module("spec/dummy")
63
+ Rake::Task["prepare_tests"].invoke
64
+ end
65
+
66
+ desc "Generates a development app"
67
+ task :development_app do
68
+ Bundler.with_original_env do
69
+ generate_decidim_app(
70
+ "development_app",
71
+ "--app_name",
72
+ "#{base_app_name}_development_app",
73
+ "--path",
74
+ "..",
75
+ "--recreate_db",
76
+ "--demo"
77
+ )
78
+ end
79
+ end
80
+
81
+ desc "Update protos for voca"
82
+ task :update_voca_proto do
83
+ %x(rm -rf ./lib/decidim/voca/rpc && mkdir -p ./lib/decidim/voca/rpc)
84
+ %x(curl -H 'Cache-Control: no-cache, no-store' -H 'Pragma: no-cache' https://raw.githubusercontent.com/octree-gva/voca-protos/main/clients/decidim-ruby-client.tar.gz | tar -xz -C ./lib/decidim/voca/rpc)
85
+ puts "✅ /lib/decidim/voca/rpc udpated"
86
+ end
File without changes
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35"><path d="M17.5 35A17.5 17.5 0 1 1 35 17.5 17.52 17.52 0 0 1 17.5 35zm0-33.06A15.56 15.56 0 1 0 33.06 17.5 15.57 15.57 0 0 0 17.5 1.94zm9.5 13.7H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zm0 3.68H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zM22.26 23H8a1 1 0 0 1 0-1.94h14.26a1 1 0 0 1 0 1.94z"/></svg>
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Voca
5
+ module Organization
6
+ # maintains compatibility with v0.26 which uses Rectify
7
+ if defined? ::Decidim::Command
8
+ class Command < ::Decidim::Command
9
+ end
10
+ else
11
+ class Command < ::Rectify::Command
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class OrganizationCommand < ::Command
5
+ def organization
6
+ @organization ||= ::Decidim::Organization.first
7
+ end
8
+ def self.command_name
9
+ name.demodulize.camelize.stub(/_command/, "")
10
+ end
11
+ def command_name
12
+ self.command_name
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdateColorCommand < OrganizationCommand
5
+ attr_reader :color_settings
6
+ def initialize(color_settings)
7
+ @color_settings = with_defaults(color_settings.to_h.with_indifferent_access)
8
+ end
9
+
10
+ def call
11
+ organization.update!(
12
+ colors: (organization.colors || []).merge(color_settings.delete_if { |_k, v| v.blank? })
13
+ )
14
+ broadcast(:ok)
15
+ rescue e
16
+ Rails.logger.error(e)
17
+ broadcast(:fail)
18
+ end
19
+
20
+ private
21
+ def with_defaults(colors)
22
+ {
23
+ "alert": "#ec5840",
24
+ "primary": "#cb3c29",
25
+ "success": "#57d685",
26
+ "warning": "#ffae00",
27
+ "highlight": "#be6400",
28
+ "secondary": "#39747f",
29
+ "highlight-alternative": "#be6400"
30
+ }.merge(colors)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdateEnvironmentCommand < OrganizationCommand
5
+ attr_reader :config
6
+ def initialize(config)
7
+ @config = config.to_h.with_indifferent_access
8
+ end
9
+
10
+ def call
11
+ redis = Redis.new(url: ENV["REDIS_CONFIG_URL"])
12
+ config.each do |key, value|
13
+ redis.hset("config",key,value)
14
+ end
15
+ broadcast(:ok)
16
+ rescue
17
+ Rails.logger.error("ERROR")
18
+ broadcast(:fail)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdateFeatureCommand < OrganizationCommand
5
+ attr_reader :feature_settings
6
+ def initialize(feature_settings)
7
+ @feature_settings = with_enums(
8
+ feature_settings.to_h.with_indifferent_access
9
+ )
10
+ end
11
+
12
+ def call
13
+ organization.update!(
14
+ feature_settings.delete_if { |_k, v| v.blank? }
15
+ )
16
+ broadcast(:ok)
17
+ rescue e
18
+ Rails.logger.error(e)
19
+ broadcast(:fail)
20
+ end
21
+
22
+ private
23
+ def with_enums(settings)
24
+ settings["machine_translation_display_priority"] = Decidim::Voca::Rpc::EnumCasting.machine_translation_display_priority.rpc_to_decidim(
25
+ settings["machine_translation_display_priority"]
26
+ )
27
+ settings
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdateFileUploadCommand < OrganizationCommand
5
+ attr_reader :file_upload_settings
6
+ def initialize(file_upload_settings)
7
+ @file_upload_settings = with_defaults(
8
+ file_upload_settings.to_h.with_indifferent_access
9
+ )
10
+ end
11
+
12
+ def call
13
+ organization.update!(
14
+ file_upload_settings: file_upload_settings
15
+ )
16
+ broadcast(:ok)
17
+ rescue e
18
+ Rails.logger.error(e)
19
+ broadcast(:fail)
20
+ end
21
+
22
+ private
23
+ def with_defaults(settings)
24
+ uploads = ::Decidim::OrganizationSettings.for(
25
+ organization
26
+ ).upload
27
+ uploads.to_h.merge({
28
+ maximum_file_size: uploads.maximum_file_size.to_h.merge({
29
+ avatar: settings[:maximum_file_size_avatar].to_i,
30
+ default: settings[:maximum_file_size_default].to_i,
31
+ }.delete_if { |_k, v| v == 0.0}),
32
+ allowed_content_types: uploads.allowed_content_types.to_h.merge({
33
+ admin: settings[:allowed_content_types_admin],
34
+ default: settings[:allowed_content_types_default],
35
+ }.delete_if { |_k, v| v.blank?}),
36
+ allowed_file_extensions: uploads.allowed_file_extensions.to_h.merge({
37
+ admin: settings[:allowed_file_extensions_admin],
38
+ default: settings[:allowed_file_extensions_default],
39
+ }.delete_if { |_k, v| v.blank?}),
40
+ }.delete_if { |_k, v| v.blank?})
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,53 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdateLocaleCommand < OrganizationCommand
5
+ attr_reader :locale_settings
6
+ def initialize(locale_settings)
7
+ @locale_settings = locale_settings.to_h
8
+ end
9
+
10
+ def call
11
+ # update languages
12
+ organization_configuration = locale_settings.select do |key|
13
+ "#{key}" == "available_locales" || "#{key}" == "default_locale"
14
+ end.delete_if { |_k, v| v.blank? }
15
+ organization.update!(organization_configuration)
16
+ after_updating_languages
17
+ # update localization settings (currency, timezone)
18
+ global_configuration = locale_settings.select do |key|
19
+ "#{key}" == "currency_unit" || "#{key}" == "timezone"
20
+ end.delete_if { |_k, v| v.blank? }
21
+ unless global_configuration.empty?
22
+ redis_client = Redis.new(
23
+ url: ENV.fetch("REDIS_CONFIG_URL", "redis://127.0.0.1:6379/2"),
24
+ );
25
+ global_configuration.each do |key, value|
26
+ # Update the Redis hash values
27
+ redis_client.hset("config", "#{key}", "#{value}")
28
+ end
29
+ # Close the Redis connection
30
+ redis_client.quit
31
+ end
32
+ broadcast(:ok)
33
+ rescue StandardError => e
34
+ Rails.logger.error(e)
35
+ broadcast(:fail)
36
+ end
37
+
38
+ private
39
+ def after_updating_languages
40
+ # Rebuild locales
41
+ `bundle exec rails decidim:locales:sync_all`
42
+ # Rebuild search tree
43
+ `bundle exec rails decidim:locales:rebuild_search`
44
+ org = organization.reload
45
+ # Update user locales (they might not have a locale that is now supported)
46
+ ::Decidim::User.where.not(locale: org.available_locales).each do |user|
47
+ user.update(locale: org.default_locale)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,30 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdateNamingCommand < OrganizationCommand
5
+ attr_reader :naming_settings
6
+ def initialize(naming_settings)
7
+ @naming_settings = naming_settings.to_h
8
+ end
9
+
10
+ def call
11
+ organization.update!(naming_settings.delete_if { |_k, v| v.blank? })
12
+ broadcast(:ok)
13
+ rescue e
14
+ Rails.logger.error(e)
15
+ broadcast(:fail)
16
+ end
17
+
18
+ private
19
+
20
+ def update_host
21
+ # Todo call Voca system to update the redirection
22
+ end
23
+
24
+ def update_subdomain
25
+ # Todo call Voca system to update aliases
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdatePermissionCommand < OrganizationCommand
5
+ attr_reader :permission_settings
6
+ def initialize(permission_settings)
7
+ @permission_settings = cast_permission_settings(permission_settings.to_h)
8
+ end
9
+
10
+ def call
11
+ organization.update!(permission_settings.delete_if { |_k, v| v.blank? })
12
+ broadcast(:ok)
13
+ rescue e
14
+ Rails.logger.error(e)
15
+ broadcast(:fail)
16
+ end
17
+
18
+ private
19
+
20
+ def cast_permission_settings(permission_settings)
21
+ # Convert enums
22
+ casting = ::Decidim::Voca::Rpc::EnumCasting.users_registration_mode
23
+ permission_settings[:users_registration_mode] = casting.rpc_to_decidim(
24
+ permission_settings[:users_registration_mode]
25
+ )
26
+ permission_settings
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,51 @@
1
+ module Decidim
2
+ module Voca
3
+ module Organization
4
+ class UpdateSmtpCommand < OrganizationCommand
5
+ attr_reader :smtp_settings
6
+ def initialize(smtp_settings)
7
+ @smtp_settings = transform_settings(smtp_settings.to_h.with_indifferent_access)
8
+ end
9
+
10
+ def call
11
+ organization.update!(
12
+ smtp_settings: smtp_settings.delete_if { |_k, v| v.blank? }
13
+ )
14
+ broadcast(:ok)
15
+ rescue => e
16
+ Rails.logger.error(e)
17
+ broadcast(:fail)
18
+ end
19
+
20
+ private
21
+
22
+ def transform_settings(settings)
23
+ from_label = settings.delete("from_label")
24
+ from_email = settings.delete("from_email")
25
+ username = settings.delete("username")
26
+ settings["openssl_verify_mode"] = Decidim::Voca::Rpc::EnumCasting.smtp_openssl_verify_mode.rpc_to_decidim(
27
+ settings["openssl_verify_mode"]
28
+ )
29
+ settings["authentication"] = Decidim::Voca::Rpc::EnumCasting.smtp_authentication.rpc_to_decidim(
30
+ settings["authentication"]
31
+ )
32
+ settings["user_name"] = username unless username.blank?
33
+ if from_email.blank? && !from_label.blank?
34
+ active_mailer_config = Rails.configuration.action_mailer.smtp_settings || {}
35
+ current = organization.smtp_settings || {}
36
+ mail = Mail::Address.new(
37
+ current.fetch("from", active_mailer_config.fetch(:from, "example@decidim.org"))
38
+ )
39
+ mail.display_name = from_label
40
+ settings[:from] = mail.to_s
41
+ elsif !from_email.blank?
42
+ mail = Mail::Address.new(from_email)
43
+ mail.display_name = from_label unless from_label.nil?
44
+ settings[:from] = mail.to_s
45
+ end
46
+ settings
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Voca
5
+ module Admin
6
+ # This controller is the abstract class from which all other controllers of
7
+ # this engine inherit.
8
+ #
9
+ # Note that it inherits from `Decidim::Admin::Components::BaseController`, which
10
+ # override its layout and provide all kinds of useful methods.
11
+ class ApplicationController < Decidim::Admin::Components::BaseController
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Voca
5
+ # This controller is the abstract class from which all other controllers of
6
+ # this engine inherit.
7
+ #
8
+ # Note that it inherits from `Decidim::Components::BaseController`, which
9
+ # override its layout and provide all kinds of useful methods.
10
+ class ApplicationController < Decidim::Components::BaseController
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake"
4
+ module Decidim
5
+ module Voca
6
+ class CommandJob < ApplicationJob
7
+ attr_reader :logger, :variables, :command_name
8
+ def perform(command_name, variables = {}, logger = Rails.logger)
9
+ @command_name = command_name
10
+ @variables = variables
11
+ @logger = logger
12
+ invoke!
13
+ end
14
+
15
+ private
16
+
17
+ def invoke!
18
+ raise ::Decidim::Voca::Error unless valid?
19
+ ::Rake::Task["voca:#{command_name}"].invoke(task_args)
20
+ end
21
+
22
+ def task_args
23
+ variables.reduce([]) do |acc, (key, value)|
24
+ acc << "#{key}=\"#{value}\""
25
+ end.join(" ") unless variables.empty?
26
+ end
27
+
28
+ def valid?
29
+ Rake::Task["voca:#{command_name}"]
30
+ true
31
+ rescue RuntimeError
32
+ false
33
+ end
34
+ end
35
+ end
36
+ end