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.
- checksums.yaml +7 -0
- data/LICENSE.md +661 -0
- data/README.md +153 -0
- data/Rakefile +86 -0
- data/app/assets/config/voca_manifest.js +0 -0
- data/app/assets/images/decidim/voca/icon.svg +1 -0
- data/app/commands/decidim/voca/organization/command.rb +16 -0
- data/app/commands/decidim/voca/organization/organization_command.rb +17 -0
- data/app/commands/decidim/voca/organization/update_color_command.rb +35 -0
- data/app/commands/decidim/voca/organization/update_environment_command.rb +23 -0
- data/app/commands/decidim/voca/organization/update_feature_command.rb +32 -0
- data/app/commands/decidim/voca/organization/update_file_upload_command.rb +45 -0
- data/app/commands/decidim/voca/organization/update_locale_command.rb +53 -0
- data/app/commands/decidim/voca/organization/update_naming_command.rb +30 -0
- data/app/commands/decidim/voca/organization/update_permission_command.rb +31 -0
- data/app/commands/decidim/voca/organization/update_smtp_command.rb +51 -0
- data/app/controllers/decidim/voca/admin/application_controller.rb +15 -0
- data/app/controllers/decidim/voca/application_controller.rb +13 -0
- data/app/jobs/decidim/voca/command_job.rb +36 -0
- data/app/jobs/decidim/voca/webhook_notifier_job.rb +57 -0
- data/app/rpc/decidim/voca/decidim_service_controller.rb +68 -0
- data/app/rpc/decidim/voca/rpc/enum_casting.rb +58 -0
- data/app/rpc/decidim/voca/rpc/get_settings.rb +144 -0
- data/app/rpc/decidim/voca/rpc/health.rb +18 -0
- data/app/rpc/decidim/voca/rpc/seed_admin.rb +75 -0
- data/app/rpc/decidim/voca/rpc/set_settings.rb +56 -0
- data/app/rpc/decidim/voca/rpc/setup_db.rb +38 -0
- data/config/environments/development.rb +6 -0
- data/config/i18n-tasks.yml +9 -0
- data/config/locales/en.yml +6 -0
- data/config/spring.rb +2 -0
- data/lib/decidim/voca/admin.rb +10 -0
- data/lib/decidim/voca/admin_engine.rb +27 -0
- data/lib/decidim/voca/backup/app_backup.rb +169 -0
- data/lib/decidim/voca/backup/app_decrypt_backup_file.rb +50 -0
- data/lib/decidim/voca/backup/app_encrypt_backup_file.rb +49 -0
- data/lib/decidim/voca/backup/app_upload_to_s3.rb +49 -0
- data/lib/decidim/voca/engine.rb +31 -0
- data/lib/decidim/voca/middleware/dynamic_config_middleware.rb +42 -0
- data/lib/decidim/voca/rpc/decidim_pb.rb +134 -0
- data/lib/decidim/voca/rpc/decidim_services_pb.rb +30 -0
- data/lib/decidim/voca/test/factories.rb +9 -0
- data/lib/decidim/voca/updater.rb +50 -0
- data/lib/decidim/voca/version.rb +13 -0
- data/lib/decidim/voca.rb +22 -0
- data/lib/tasks/voca.rake +88 -0
- metadata +124 -0
data/README.md
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
[](https://github.com/octree-gva/voca-tasks)
|
2
|
+
|
3
|
+
[](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
|