decidim-voca 0.0.6

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.
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