adminos 1.0.0.pre.rc.2 → 1.0.0.pre.rc.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -4
- data/README.md +26 -0
- data/adminos.gemspec +4 -4
- data/app/inputs/cropp_input.rb +15 -3
- data/app/inputs/filter_inputs/boolean_input.rb +18 -0
- data/app/inputs/filter_inputs/date_range_input.rb +36 -0
- data/app/inputs/filter_inputs/numeric_input.rb +40 -0
- data/app/inputs/filter_inputs/string_input.rb +40 -0
- data/lib/adminos/configuration.rb +9 -0
- data/lib/adminos/controllers/filters.rb +20 -0
- data/lib/adminos/controllers/resource.rb +34 -14
- data/lib/adminos/extensions/simple_form.rb +12 -0
- data/lib/adminos/features/search/elastic.rb +46 -0
- data/lib/adminos/features/search/pg_search.rb +49 -0
- data/lib/adminos/filters/forms.rb +55 -0
- data/lib/adminos/form_builder.rb +11 -0
- data/lib/adminos/helpers/models/searchable.rb +9 -0
- data/lib/adminos/helpers/view.rb +35 -0
- data/lib/adminos.rb +23 -3
- data/lib/generators/adminos/adminos_generator.rb +10 -7
- data/lib/generators/adminos/feedback_generator.rb +39 -0
- data/lib/generators/adminos/i18n_generator.rb +16 -4
- data/lib/generators/adminos/install_generator.rb +22 -0
- data/lib/generators/adminos/profile_generator.rb +34 -0
- data/lib/generators/adminos/search_generator.rb +38 -0
- data/lib/generators/adminos/two_factor_auth_generator.rb +81 -0
- data/lib/generators/templates/adminos/fields.slim +1 -1
- data/lib/generators/templates/adminos/locales/locale_fields.slim +7 -4
- data/lib/generators/templates/adminos/locales/model.rb.erb +2 -3
- data/lib/generators/templates/ci/.gitlab-ci.yml +1 -1
- data/lib/generators/templates/feedback/auto/app/controllers/admin/feedbacks_controller.rb +17 -0
- data/lib/generators/templates/feedback/auto/app/controllers/feedbacks_controller.rb +11 -0
- data/lib/generators/templates/feedback/auto/app/models/feedback.rb +6 -0
- data/lib/generators/templates/feedback/auto/app/views/admin/feedbacks/_fields.slim +5 -0
- data/lib/generators/templates/feedback/auto/app/views/admin/feedbacks/index.slim +28 -0
- data/lib/generators/templates/feedback/feedbacks_migration.rb +13 -0
- data/lib/generators/templates/field/locales/locale_fields.slim +1 -1
- data/lib/generators/templates/field/locales/model.rb.erb +2 -3
- data/lib/generators/templates/i18n/Gemfile +6 -1
- data/lib/generators/templates/i18n/auto/app/validators/locale_validator.rb +5 -1
- data/lib/generators/templates/i18n/auto/app/views/admin/base/_pills.slim +1 -5
- data/lib/generators/templates/i18n/auto/app/views/admin/pages/_locale_fields.slim +5 -5
- data/lib/generators/templates/i18n/auto/config/initializers/mobility.rb +92 -0
- data/lib/generators/templates/i18n/devise/devise.ru.yml +15 -3
- data/lib/generators/templates/i18n/devise/views/mailer/confirmation_instructions.slim +3 -4
- data/lib/generators/templates/i18n/devise/views/mailer/reset_password_instructions.slim +5 -5
- data/lib/generators/templates/i18n/devise/views/mailer/unlock_instructions.slim +4 -4
- data/lib/generators/templates/i18n/page.rb +2 -2
- data/lib/generators/templates/install/Gemfile +4 -6
- data/lib/generators/templates/install/README.md +22 -0
- data/lib/generators/templates/install/admin_panel/versions/views/admin_versions/index.slim +1 -1
- data/lib/generators/templates/install/admin_panel/versions/views/admin_versions/show.slim +3 -3
- data/lib/generators/templates/install/auto/Capfile +12 -2
- data/lib/generators/templates/install/auto/app/controllers/admin/settings_controller.rb +1 -1
- data/lib/generators/templates/install/auto/app/helpers/versions_helper.rb +3 -3
- data/lib/generators/templates/install/auto/app/inputs/carrierwave_input.rb +2 -2
- data/lib/generators/templates/install/auto/app/inputs/checkbox_input.rb +1 -1
- data/lib/generators/templates/install/auto/app/services/export_xlsx.rb +6 -6
- data/lib/generators/templates/install/auto/app/views/admin/base/_form.slim +3 -3
- data/lib/generators/templates/install/auto/app/views/admin/helps/index.slim +9 -9
- data/lib/generators/templates/install/auto/app/views/admin/settings/edit.slim +2 -2
- data/lib/generators/templates/install/auto/app/views/shared/admin/_back_button.slim +1 -1
- data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_collection_header.slim +2 -0
- data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_object_link_new.slim +1 -1
- data/lib/generators/templates/install/auto/config/deploy/staging.rb +15 -10
- data/lib/generators/templates/install/auto/config/deploy/{shared → templates}/database.yml.erb +1 -1
- data/lib/generators/templates/install/auto/config/deploy/templates/nginx_conf.erb +96 -0
- data/lib/generators/templates/install/auto/config/deploy/templates/puma.rb.erb +52 -0
- data/lib/generators/templates/install/auto/config/environments/staging.rb +1 -1
- data/lib/generators/templates/install/auto/config/initializers/adminos.rb +3 -0
- data/lib/generators/templates/install/auto/config/locales/adminos.en.yml +30 -0
- data/lib/generators/templates/install/auto/config/locales/adminos.ru.yml +49 -2
- data/lib/generators/templates/install/auto/config/schedule.rb +0 -0
- data/lib/generators/templates/install/auto/config/systemd/puma.service.erb +19 -0
- data/lib/generators/templates/install/auto/config/systemd/sidekiq.service.erb +21 -0
- data/lib/generators/templates/install/auto/lib/capistrano/{template.rb → smart_templates.rb} +17 -3
- data/lib/generators/templates/install/auto/lib/capistrano/tasks/setup_config.cap +27 -20
- data/lib/generators/templates/install/deploy.rb.erb +13 -12
- data/lib/generators/templates/install/prepare_settings.rb +1 -1
- data/lib/generators/templates/profile/auto/app/controllers/admin/profiles_controller.rb +26 -0
- data/lib/generators/templates/profile/auto/app/views/admin/profiles/edit.slim +17 -0
- data/lib/generators/templates/two_facto_auth/Gemfile +1 -0
- data/lib/generators/templates/two_facto_auth/auto/app/controllers/concerns/authenticates_with_two_factor.rb +36 -0
- data/lib/generators/templates/two_facto_auth/auto/app/controllers/users/sessions_controller.rb +5 -0
- data/lib/generators/templates/two_facto_auth/auto/app/views/admin/profiles/_2fa.slim +24 -0
- data/lib/generators/templates/two_facto_auth/auto/app/views/devise/sessions/two_factor.slim +15 -0
- data/spec/lib/generators/adminos/feedback_generator_rspec.rb +50 -0
- data/spec/lib/generators/adminos/install_generator_rspec.rb +6 -7
- data/spec/lib/generators/adminos/profile_generator_rspec.rb +33 -0
- data/spec/lib/generators/adminos/search_generator.rb +20 -0
- data/spec/lib/generators/adminos/two_factor_auth_generator_rspec.rb +61 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/shared/generator.rb +1 -1
- metadata +59 -26
- data/bin/rspec +0 -29
- data/lib/adminos/extensions/globalize_actiontext.rb +0 -28
- data/lib/adminos/extensions/globalize_fields.rb +0 -19
- data/lib/generators/templates/adminos/locales/migration.rb.erb +0 -18
- data/lib/generators/templates/field/locales/migration.rb.erb +0 -13
- data/lib/generators/templates/i18n/add_translation_table_to_page.rb +0 -15
- data/lib/generators/templates/i18n/auto/config/initializers/globalize_fields.rb +0 -1
- data/lib/generators/templates/install/auto/config/deploy/shared/nginx.conf.erb +0 -28
- data/lib/generators/templates/install/auto/config/deploy/shared/unicorn.rb.erb +0 -35
- data/lib/generators/templates/install/auto/lib/capistrano/substitute_strings.rb +0 -12
- data/package-lock.json +0 -3
@@ -51,6 +51,17 @@ en:
|
|
51
51
|
file: Photo
|
52
52
|
|
53
53
|
admin:
|
54
|
+
welcome: Entrance to admin dashboard
|
55
|
+
helps:
|
56
|
+
title_html: General notes on adding and editing information
|
57
|
+
hint1_html: "Everywhere, where it is possible to add this or that entity (for example, a page), <b>in the right upper part of the page there is a 'Add' button</b>."
|
58
|
+
hint2_html: "Some types of records can be <b>published</b> (and will be displayed on the site) and <b>archived</b> (saved in the database, they can be edited, but they will not be published on the site). <b>The status of a published entry is indicated by <i class="icon-eye-open"></i> icon on the right side of the list</b> (the absence of an icon indicates that the entry has been archived)."
|
59
|
+
hint3_html: "Some lists have the ability to <b>manually sort the records</b> (the order of display on the site and in the lists). Sometimes you want to bring some record before the previous one. This is true, for example, for a list of pages. <b>To move a record up or down, simply drag it to the desired place with the mouse pointer</b> (by pressing the left mouse button first, when the pointer is above <i class="icon-move"></i> icon)."
|
60
|
+
hint4_html: "Some lists include <b>group operations</b> — publish, archive, and delete. To perform a group operation, you need to select the records with which the operation will be carried out - this can be done with checkboxes, and then selecting an operation from the list at the bottom of the page (click on the appropriate button). These operations can also be performed with individual objects in order not to enter the record editing page."
|
61
|
+
hint5_html: "If <b>editing records</b> is available, <i class="icon-edit"></i> icon appears in the list. Clicking this icon opens the edit page for the corresponding entry."
|
62
|
+
hint6_html: "All <b>specific page settings</b> are in '#{link_to I18n.t('admin.settings.actions.index.header'), edit_admin_settings_path}' section."
|
63
|
+
hint7_html: "In cases where this is provided for page layout, the text fields are equipped with a <b>WYSIWYG editor</b>. The editor has the ability to post images and insert video code (embedded video) from the YouTube service."
|
64
|
+
icons_meaning: Icons meaning
|
54
65
|
actions:
|
55
66
|
create: Create
|
56
67
|
update: Update
|
@@ -100,6 +111,11 @@ en:
|
|
100
111
|
labels:
|
101
112
|
actions:
|
102
113
|
show: Show modifications
|
114
|
+
save_table: Save table
|
115
|
+
changes: Changes
|
116
|
+
field: Field
|
117
|
+
old_value: Old value
|
118
|
+
new_value: New value
|
103
119
|
settings:
|
104
120
|
actions:
|
105
121
|
index:
|
@@ -136,6 +152,11 @@ en:
|
|
136
152
|
cancel: Cancel
|
137
153
|
destroy: Delete
|
138
154
|
edit: Edit
|
155
|
+
apply: Apply
|
156
|
+
save: Save
|
157
|
+
choose: Choose
|
158
|
+
login: Login
|
159
|
+
sign_up: Sign up
|
139
160
|
show: Show modifications
|
140
161
|
go_to_root: Home
|
141
162
|
info: Information
|
@@ -155,6 +176,10 @@ en:
|
|
155
176
|
set_nav_published_on: Add to navigation
|
156
177
|
set_published_off: Remove from publication
|
157
178
|
set_published_on: Publish
|
179
|
+
image:
|
180
|
+
width: Width
|
181
|
+
height: Height
|
182
|
+
cropped: Кадрированное изображение
|
158
183
|
|
159
184
|
sites:
|
160
185
|
holding: Holding
|
@@ -162,3 +187,8 @@ en:
|
|
162
187
|
|
163
188
|
unauthorized:
|
164
189
|
default: You must login or register.
|
190
|
+
authentication:
|
191
|
+
two_factor: Two-factor authentication
|
192
|
+
key: Key
|
193
|
+
switch_on_2fa: Switch on 2FA
|
194
|
+
switch_off_2fa: Switch off 2FA
|
@@ -159,10 +159,16 @@ ru:
|
|
159
159
|
admin:
|
160
160
|
add: Добавить
|
161
161
|
add_child: Добавить подраздел
|
162
|
+
duplication: Дублировать
|
162
163
|
back: Назад
|
163
164
|
cancel: Отменить
|
164
165
|
destroy: Удалить
|
165
166
|
edit: Редактировать
|
167
|
+
apply: Применить
|
168
|
+
save: Сохранить
|
169
|
+
choose: Выбрать
|
170
|
+
login: Логин
|
171
|
+
sign_up: Регистрация
|
166
172
|
show: Просмотр изменений
|
167
173
|
go_to_root: Перейти на сайт
|
168
174
|
info: Справка
|
@@ -173,16 +179,20 @@ ru:
|
|
173
179
|
seo: SEO
|
174
180
|
logout: Выйти
|
175
181
|
nav_published: В навигации
|
176
|
-
published:
|
182
|
+
published: Опубликовано
|
177
183
|
locked: Закреплена
|
178
184
|
server_restart: Перезагрузить сервер
|
179
|
-
unpublished: Не
|
185
|
+
unpublished: Не опубликовано
|
180
186
|
batch_actions:
|
181
187
|
destroy: Удалить
|
182
188
|
set_nav_published_off: Убрать из навигации
|
183
189
|
set_nav_published_on: Опубликовать в навигации
|
184
190
|
set_published_off: Снять с публикации
|
185
191
|
set_published_on: Опубликовать
|
192
|
+
image:
|
193
|
+
width: Ширина
|
194
|
+
height: Высота
|
195
|
+
cropped: Кадрированное изображение
|
186
196
|
|
187
197
|
confirmations:
|
188
198
|
destroy:
|
@@ -198,11 +208,21 @@ ru:
|
|
198
208
|
title: &layouts_admin_title Панель управления
|
199
209
|
|
200
210
|
admin:
|
211
|
+
welcome: Вход в систему администрирования
|
201
212
|
actions:
|
202
213
|
create: Создание
|
203
214
|
update: Обновление
|
204
215
|
destroy: Удаление
|
205
216
|
helps:
|
217
|
+
title_html: "Общие замечания по добавлению и редактированию информации:"
|
218
|
+
hint1_html: "Везде, где можно добавить ту или иную сущность (например, страницу), <b>в правой верхней части страницы есть кнопка «добавить»</b>."
|
219
|
+
hint2_html: "Некоторые типы записей могут быть <b>опубликованы</b> (и будут отображаться на сайте) и <b>заархивированы</b> (сохранятся в базе, их можно редактировать, но они не будут опубликованы на сайте). <b>Состояние опубликованной записи обозначается пиктограммой <i class="icon-eye-open"></i> в правой части списка</b> (отсутствие пиктограммы обозначает то, что запись заархивирована)."
|
220
|
+
hint3_html: "В некоторых списках есть возможность <b>ручной сортировки записей</b> (порядок отображения на сайте и в списках). Иногда требуется вывести какую-то запись раньше предыдущей. Это справедливо, например, для списка страниц. <b>Чтобы переместить запись выше или ниже, достаточно просто перетащить её в нужное место указателем мыши</b> (предварительно нажав левую кнопку мыши, когда указатель находится над пиктограммой <i class="icon-move"></i>)."
|
221
|
+
hint4_html: "В некоторых списках предусмотрены <b>групповые операции</b> — публикация, архивирование и удаление. Чтобы выполнить групповую операцию, необходимо выбрать записи, с которыми будет осуществляться операция — это можно сделать, отметив эти записи галочками в чекбоксах, — а затем выбрать операцию из списка внизу страницы (нажать на соответствующую кнопку). Эти операции можно выполнять также и с отдельными объектами (то есть по одному), чтобы не заходить на страницу редактирования записи."
|
222
|
+
hint5_html: "Если <b>редактирование записей</b> доступно, то в списке присутствует пиктограмма <i class="icon-edit"></i>. Щелчок по этой пиктограмме открывает страницу редактирования соответствующей записи."
|
223
|
+
hint6_html: "Все <b>специфичные настройки страниц</b> вынесены в раздел «#{link_to I18n.t('admin.settings.actions.index.header'), edit_admin_settings_path}»."
|
224
|
+
hint7_html: "В случаях, где это предусмотрено оформлением страниц, текстовые поля оснащены <b>WYSIWYG-редактором</b>. Редактор имеет возможность размещения изображений и вставки кода для видео (встроенное видео) с сервиса YouTube."
|
225
|
+
icons_meaning: Значение пиктограмм
|
206
226
|
actions:
|
207
227
|
index:
|
208
228
|
header: Панель управления
|
@@ -247,6 +267,28 @@ ru:
|
|
247
267
|
labels:
|
248
268
|
actions:
|
249
269
|
show: Просмотр изменений
|
270
|
+
save_table: Сохранить таблицу
|
271
|
+
changes: Изменения
|
272
|
+
field: Поле
|
273
|
+
old_value: Старое значение
|
274
|
+
new_value: Новое значение
|
275
|
+
feedbacks:
|
276
|
+
actions:
|
277
|
+
index:
|
278
|
+
header: Обратная связь
|
279
|
+
title: Обратная связь
|
280
|
+
labels:
|
281
|
+
actions:
|
282
|
+
create: Добавить feedback
|
283
|
+
edit: Сохранить feedback
|
284
|
+
edit_stay_in_place: Сохранить feedback и редактировать
|
285
|
+
new: Добавить feedback
|
286
|
+
new_stay_in_place: Добавить feedback и редактировать
|
287
|
+
update: Сохранить feedback
|
288
|
+
profile:
|
289
|
+
actions:
|
290
|
+
index:
|
291
|
+
header: Мой профиль
|
250
292
|
settings:
|
251
293
|
actions:
|
252
294
|
index:
|
@@ -290,3 +332,8 @@ ru:
|
|
290
332
|
|
291
333
|
unauthorized:
|
292
334
|
default: Необходимо войти или зарегистрироваться.
|
335
|
+
authentication:
|
336
|
+
two_factor: Двухфакторная аутентификация
|
337
|
+
key: Ключ
|
338
|
+
switch_on_2fa: Включить 2FA
|
339
|
+
switch_off_2fa: Выключить 2FA
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description = <%= fetch(:application) %> Puma Web Server
|
3
|
+
After = network.target
|
4
|
+
|
5
|
+
[Service]
|
6
|
+
Type = simple
|
7
|
+
Environment = RAILS_ENV=<%= fetch(:rails_env) %>
|
8
|
+
Environment = PWD=<%= current_path %>
|
9
|
+
WorkingDirectory = <%= current_path %>
|
10
|
+
ExecStart = /home/<%= fetch(:user) %>/.rvm/bin/rvm <%= fetch(:rvm_ruby_version) %> do <%= current_path %>/bin/puma -S <%= shared_path %>/tmp/pids/puma.state -C <%= shared_path %>/puma.rb
|
11
|
+
ExecStop = /home/<%= fetch(:user) %>/.rvm/bin/rvm <%= fetch(:rvm_ruby_version) %> do <%= current_path %>/bin/pumactl -S <%= shared_path %>/tmp/pids/puma.state -F <%= shared_path %>/puma.rb stop
|
12
|
+
ExecReload = /home/<%= fetch(:user) %>/.rvm/bin/rvm <%= fetch(:rvm_ruby_version) %> do <%= current_path %>/bin/pumactl -S <%= shared_path %>/tmp/pids/puma.state -F <%= shared_path %>/puma.rb phased-restart
|
13
|
+
User = <%= fetch(:user) %>
|
14
|
+
Group = <%= fetch(:group) || fetch(:user) %>
|
15
|
+
Restart = always
|
16
|
+
KillMode = process
|
17
|
+
|
18
|
+
[Install]
|
19
|
+
WantedBy = multi-user.target
|
@@ -0,0 +1,21 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description = <%= fetch(:application) %> Sidekiq Background Worker
|
3
|
+
After = multi-user.target
|
4
|
+
|
5
|
+
[Service]
|
6
|
+
Type = simple
|
7
|
+
Environment = RAILS_ENV=<%= fetch(:rails_env) %>
|
8
|
+
Environment = PWD=<%= current_path %>
|
9
|
+
EnvironmentFile=/etc/environment
|
10
|
+
WorkingDirectory = <%= current_path %>
|
11
|
+
ExecStart = /home/<%= fetch(:user) %>/.rvm/bin/rvm <%= fetch(:rvm_ruby_version) %> do <%= current_path %>/bin/sidekiq -e <%= fetch(:rails_env) %> -L <%= shared_path %>/log/sidekiq.log -P <%= shared_path %>/tmp/pids/sidekiq.pid
|
12
|
+
ExecStop = /home/<%= fetch(:user) %>/.rvm/bin/rvm <%= fetch(:rvm_ruby_version) %> do <%= current_path %>/bin/sidekiqctl stop <%= shared_path %>/tmp/pids/sidekiq.pid
|
13
|
+
User = <%= fetch(:user) %>
|
14
|
+
Group = <%= fetch(:group) || fetch(:user) %>
|
15
|
+
KillMode = process
|
16
|
+
UMask = 0002
|
17
|
+
RestartSec = 1
|
18
|
+
Restart = always
|
19
|
+
|
20
|
+
[Install]
|
21
|
+
WantedBy = multi-user.target
|
data/lib/generators/templates/install/auto/lib/capistrano/{template.rb → smart_templates.rb}
RENAMED
@@ -1,10 +1,10 @@
|
|
1
1
|
# will first try and copy the file:
|
2
2
|
# config/deploy/#{full_app_name}/#{from}.erb
|
3
3
|
# to:
|
4
|
-
#
|
4
|
+
# templates/config/to
|
5
5
|
# if the original source path doesn exist then it will
|
6
6
|
# search in:
|
7
|
-
# config/deploy/
|
7
|
+
# config/deploy/templates/#{from}.erb
|
8
8
|
# this allows files which are common to all enviros to
|
9
9
|
# come from a single source while allowing specific
|
10
10
|
# ones to be over-ridden
|
@@ -26,8 +26,22 @@ end
|
|
26
26
|
def template_file(name)
|
27
27
|
if File.exist?((file = "config/deploy/#{fetch(:full_app_name)}/#{name}.erb"))
|
28
28
|
return file
|
29
|
-
elsif File.exist?((file = "config/deploy/
|
29
|
+
elsif File.exist?((file = "config/deploy/templates/#{name}.erb"))
|
30
|
+
return file
|
31
|
+
elsif File.exist?((file = "config/deploy/templates/#{name}"))
|
30
32
|
return file
|
31
33
|
end
|
32
34
|
return nil
|
33
35
|
end
|
36
|
+
|
37
|
+
# we often want to refer to variables which
|
38
|
+
# are defined in subsequent stage files. This
|
39
|
+
# let's us use the {{var}} to represent fetch(:var)
|
40
|
+
# in strings which are only evaluated at runtime.
|
41
|
+
def sub_strings(input_string)
|
42
|
+
output_string = input_string
|
43
|
+
input_string.scan(/{{(\w*)}}/).each do |var|
|
44
|
+
output_string.gsub!("{{#{var[0]}}}", fetch(var[0].to_sym))
|
45
|
+
end
|
46
|
+
output_string
|
47
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
require "capistrano/smart_templates"
|
2
|
+
|
1
3
|
namespace :deploy do
|
4
|
+
desc "Set up config files"
|
2
5
|
task :setup_config do
|
3
6
|
on roles(:app) do
|
4
7
|
# make the config dir
|
5
8
|
execute :mkdir, "-p #{shared_path}/config"
|
6
|
-
full_app_name = fetch(:full_app_name)
|
7
9
|
|
8
10
|
# config files to be uploaded to shared/config, see the
|
9
11
|
# definition of smart_template for details of operation.
|
@@ -12,28 +14,33 @@ namespace :deploy do
|
|
12
14
|
# everything should be in deploy/shared with params which differ
|
13
15
|
# set in the stage files
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
# which of the above files should be marked as executable
|
22
|
-
executable_files = fetch(:executable_config_files)
|
23
|
-
|
24
|
-
#executable_files.each do |file|
|
25
|
-
# execute :chmod, "+x #{shared_path}/config/#{file}"
|
26
|
-
#end
|
17
|
+
config_files = fetch(:config_files, [])
|
18
|
+
config_files.each do |file|
|
19
|
+
smart_template file
|
20
|
+
end
|
27
21
|
|
28
|
-
|
29
|
-
|
22
|
+
# which of the above files should be marked as executable
|
23
|
+
executable_config_files = fetch(:executable_config_files, [])
|
24
|
+
executable_config_files.each do |file|
|
25
|
+
execute :chmod, "+x #{shared_path}/config/#{file}"
|
26
|
+
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
log "ERROR: #{e.to_s}"
|
28
|
+
# symlink stuff which should be... symlinked
|
29
|
+
symlinks = fetch(:symlinks, [])
|
30
|
+
symlinks.each do |symlink|
|
31
|
+
sudo "ln -nfs #{shared_path}/config/#{symlink[:source]} #{sub_strings(symlink[:link])}"
|
36
32
|
end
|
37
33
|
end
|
38
34
|
end
|
35
|
+
|
36
|
+
desc "Set up new deployment"
|
37
|
+
task setup: %i[setup_config puma:nginx_config]
|
38
|
+
|
39
|
+
desc "Set up Systemd services"
|
40
|
+
task setup_systemd: %i[systemd:puma:setup]
|
41
|
+
# task setup_systemd: %i[systemd:puma:setup systemd:sidekiq:setup]
|
42
|
+
|
43
|
+
desc "Enable Systemd services"
|
44
|
+
task enable_systemd: %i[systemd:puma:enable]
|
45
|
+
# task enable_systemd: %i[systemd:puma:enable systemd:sidekiq:enable]
|
39
46
|
end
|
@@ -1,21 +1,22 @@
|
|
1
|
-
set :application,
|
2
|
-
set :repo_url, "git@gitlab.molinos.ru:studio/#{application}.git"
|
1
|
+
set :application, '<%= application_name %>'
|
2
|
+
set :repo_url, "git@gitlab.molinos.ru:studio/#{fetch(:application)}.git"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'storage'
|
9
|
-
)
|
4
|
+
set :config_files, %w[config/database.yml .env]
|
5
|
+
append :linked_files, 'config/database.yml', '.env', 'config/master.key'
|
6
|
+
append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets',
|
7
|
+
'vendor/bundle', 'public/system', 'public/uploads', 'storage'
|
10
8
|
|
11
9
|
set :rvm_ruby_version, Pathname(__dir__).join('../.ruby-version').read.chomp
|
12
10
|
|
13
11
|
set :db_local_clean, true
|
14
12
|
set :assets_dir, %w[public/system]
|
15
13
|
|
16
|
-
|
14
|
+
set :nginx_server_name, -> { "#{fetch(:domain)} localhost #{fetch(:application)}.local" }
|
15
|
+
set :nginx_upstream_name, -> { "#{fetch(:application)}_#{fetch(:stage)}" }
|
16
|
+
set :nginx_config_name, -> { "#{fetch(:domain)}.conf" }
|
17
|
+
set :nginx_use_ssl, true
|
18
|
+
|
17
19
|
namespace :deploy do
|
18
|
-
|
19
|
-
|
20
|
-
end
|
20
|
+
# after :restart, 'systemd:sidekiq:reload-or-restart'
|
21
|
+
after :publishing, :restart
|
21
22
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Admin::ProfilesController < Admin::BaseController
|
2
|
+
load_and_authorize_resource param_method: :strong_params, class: User
|
3
|
+
|
4
|
+
def update
|
5
|
+
if resource.update_with_password(strong_params)
|
6
|
+
flash[:notice] = t 'flash.actions.update.notice'
|
7
|
+
redirect_to action: :edit
|
8
|
+
else
|
9
|
+
flash[:error] = t 'flash.actions.update.alert'
|
10
|
+
render action: :edit
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def resource
|
17
|
+
@resource ||= current_user
|
18
|
+
end
|
19
|
+
|
20
|
+
helper_method :resource
|
21
|
+
|
22
|
+
def strong_params
|
23
|
+
params.require(:user).permit :email, :password, :password_confirmation,
|
24
|
+
:current_password
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
- title 'Профиль'
|
2
|
+
= resource_header 'Профиль'
|
3
|
+
|
4
|
+
= simple_form_for [:admin, resource], url: admin_profile_path, wrapper: :admin, html: { method: :put } do |f|
|
5
|
+
.f
|
6
|
+
.f__wrapper
|
7
|
+
.f__fieldset
|
8
|
+
= f.input :email
|
9
|
+
= f.input :password, hint: 'Оставьте пустым если не хотите изменить'
|
10
|
+
= f.input :password_confirmation, hint: 'Повторите пароль'
|
11
|
+
= f.input :current_password, hint: 'Введите текущий пароль'
|
12
|
+
|
13
|
+
.f
|
14
|
+
.f__wrapper
|
15
|
+
.f-submit.f-submit--fixed
|
16
|
+
.wrapper
|
17
|
+
= f.button :submit, resource_button_value_main, class: 'btn btn-primary btn--done'
|
@@ -0,0 +1 @@
|
|
1
|
+
gem 'devise-two-factor'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module AuthenticatesWithTwoFactor
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
def authenticate_with_two_factor
|
4
|
+
devise_parameter_sanitizer.permit(:sign_in, keys: [:otp_attempt])
|
5
|
+
|
6
|
+
# remove otp_user_id if new login
|
7
|
+
cookies.delete :otp_user_id if sign_in_params[:email]
|
8
|
+
|
9
|
+
try_set_otp_user_id
|
10
|
+
try_sign_in_user
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def try_set_otp_user_id
|
16
|
+
user = User.find_by_email(sign_in_params[:email])
|
17
|
+
|
18
|
+
return unless user&.otp_required_for_login
|
19
|
+
return unless user.valid_password?(sign_in_params[:password])
|
20
|
+
|
21
|
+
cookies.signed[:otp_user_id] = { value: user.id, expires: 5.minutes.from_now }
|
22
|
+
end
|
23
|
+
|
24
|
+
def try_sign_in_user
|
25
|
+
user = User.find_by(id: cookies.signed[:otp_user_id])
|
26
|
+
|
27
|
+
return unless user
|
28
|
+
|
29
|
+
if user.current_otp == sign_in_params[:otp_attempt]
|
30
|
+
sign_in(user)
|
31
|
+
else
|
32
|
+
self.resource = User.new
|
33
|
+
render 'devise/sessions/two_factor'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
.f__fieldset
|
2
|
+
.f__legend=t('authentication.two_factor')
|
3
|
+
- if resource.otp_required_for_login
|
4
|
+
.f
|
5
|
+
.f__wrapper
|
6
|
+
.f-field
|
7
|
+
.f-field__label
|
8
|
+
label.f-label=t('authentication.key')
|
9
|
+
.f-field__container
|
10
|
+
.f-field__text =resource.otp.secret
|
11
|
+
.f-field
|
12
|
+
.f-field__label
|
13
|
+
label.f-label Google Authenticator QR
|
14
|
+
.f-field__container
|
15
|
+
= google_authenticator_qrcode(resource)
|
16
|
+
.f-field
|
17
|
+
.f-field__container
|
18
|
+
= link_to t('authentication.switch_off_2fa'), toggle_two_factor_admin_profile_path, method: :post, class: 'btn btn btn-primary'
|
19
|
+
- else
|
20
|
+
.f
|
21
|
+
.f__wrapper
|
22
|
+
.f-field
|
23
|
+
.f-field__container
|
24
|
+
= link_to t('authentication.switch_on_2fa'), toggle_two_factor_admin_profile_path, method: :post, class: 'btn btn btn-primary'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
- @body_class = "page--auth ready"
|
2
|
+
|
3
|
+
.auth
|
4
|
+
.auth__title Adminos
|
5
|
+
.auth__welcome= t('admin.welcome')
|
6
|
+
|
7
|
+
= simple_form_for resource, as: resource_name, url: session_path(resource_name), wrapper: :auth, html: { class: 'form auth__form' } do |f|
|
8
|
+
= f.input :otp_attempt, placeholder: '2FA'
|
9
|
+
|
10
|
+
.form__submit.centered
|
11
|
+
= f.submit t('admin.users.labels.form.login'), class: 'button button--rounded'
|
12
|
+
|
13
|
+
- if flash.present?
|
14
|
+
.auth__message
|
15
|
+
= show_flash_alert
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'support/generators'
|
2
|
+
|
3
|
+
RSpec.describe Adminos::Generators::FeedbackGenerator, type: :generator do
|
4
|
+
|
5
|
+
prepare_app(folder_name: 'dummy')
|
6
|
+
generate('adminos:feedback')
|
7
|
+
|
8
|
+
context 'controllers' do
|
9
|
+
describe 'app/controllers/feedbacks_controller.rb' do
|
10
|
+
subject { file('app/controllers/feedbacks_controller.rb') }
|
11
|
+
it { is_expected.to exist }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'app/controllers/admin/feedbacks_controller.rb' do
|
15
|
+
subject { file('app/controllers/admin/feedbacks_controller.rb') }
|
16
|
+
it { is_expected.to exist }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'models' do
|
21
|
+
describe 'app/models/feedback.rb' do
|
22
|
+
subject { file('app/models/feedback.rb') }
|
23
|
+
it { is_expected.to exist }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'views' do
|
28
|
+
describe 'app/views/admin/feedbacks/_fields.slim' do
|
29
|
+
subject { file('app/views/admin/feedbacks/_fields.slim') }
|
30
|
+
it { is_expected.to exist }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'app/views/admin/feedbacks/index.slim' do
|
34
|
+
subject { file('app/views/admin/feedbacks/index.slim') }
|
35
|
+
it { is_expected.to exist }
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'app/views/shared/admin/_sidebar.slim' do
|
39
|
+
subject { file('app/views/shared/admin/_sidebar.slim') }
|
40
|
+
it { is_expected.to contain /admin_feedbacks_path/ }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'config' do
|
45
|
+
describe 'config/routes.rb' do
|
46
|
+
subject { file('config/routes.rb') }
|
47
|
+
it { is_expected.to contain /resources :feedbacks, except: :show do/ }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -168,6 +168,11 @@ RSpec.describe Adminos::Generators::InstallGenerator, type: :generator do
|
|
168
168
|
it { is_expected.to exist }
|
169
169
|
end
|
170
170
|
|
171
|
+
describe 'config/initializers/adminos.rb' do
|
172
|
+
subject { file( 'config/initializers/adminos.rb') }
|
173
|
+
it { is_expected.to exist }
|
174
|
+
end
|
175
|
+
|
171
176
|
describe 'config/locales/devise.ru.yml' do
|
172
177
|
subject { file( 'config/locales/devise.ru.yml') }
|
173
178
|
it { is_expected.to exist }
|
@@ -250,7 +255,6 @@ RSpec.describe Adminos::Generators::InstallGenerator, type: :generator do
|
|
250
255
|
describe 'app/models/page.rb' do
|
251
256
|
subject { file('app/models/page.rb') }
|
252
257
|
it { is_expected.to contain /translates :name, .*/ }
|
253
|
-
it { is_expected.to contain /accepts_nested_attributes_for :translations/ }
|
254
258
|
end
|
255
259
|
end
|
256
260
|
|
@@ -295,11 +299,6 @@ RSpec.describe Adminos::Generators::InstallGenerator, type: :generator do
|
|
295
299
|
end
|
296
300
|
|
297
301
|
context 'config' do
|
298
|
-
describe 'config/initializers/globalize_fields.rb' do
|
299
|
-
subject { file('config/initializers/globalize_fields.rb') }
|
300
|
-
it { is_expected.to exist }
|
301
|
-
end
|
302
|
-
|
303
302
|
describe 'config/routes.rb' do
|
304
303
|
subject { file('config/routes.rb') }
|
305
304
|
it { is_expected.to contain /scope '\(:locale\)'/ }
|
@@ -314,7 +313,7 @@ RSpec.describe Adminos::Generators::InstallGenerator, type: :generator do
|
|
314
313
|
context 'Gemfile' do
|
315
314
|
describe 'Gemfile' do
|
316
315
|
subject { file('Gemfile') }
|
317
|
-
it { is_expected.to contain /gem '
|
316
|
+
it { is_expected.to contain /gem 'mobility'/ }
|
318
317
|
end
|
319
318
|
end
|
320
319
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'support/generators'
|
2
|
+
|
3
|
+
RSpec.describe Adminos::Generators::ProfileGenerator, type: :generator do
|
4
|
+
|
5
|
+
prepare_app(folder_name: 'dummy')
|
6
|
+
generate('adminos:profile')
|
7
|
+
|
8
|
+
context 'controllers' do
|
9
|
+
describe 'app/controllers/admin/profiles_controller.rb' do
|
10
|
+
subject { file('app/controllers/admin/profiles_controller.rb') }
|
11
|
+
it { is_expected.to exist }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'views' do
|
16
|
+
describe 'app/views/admin/profiles/edit.slim' do
|
17
|
+
subject { file('app/views/admin/profiles/edit.slim') }
|
18
|
+
it { is_expected.to exist }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'app/views/shared/admin/_sidebar.slim' do
|
22
|
+
subject { file('app/views/shared/admin/_sidebar.slim') }
|
23
|
+
it { is_expected.to contain /link_to edit_admin_profile_path/ }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'config' do
|
28
|
+
describe 'config/routes.rb' do
|
29
|
+
subject { file('config/routes.rb') }
|
30
|
+
it { is_expected.to contain /resource :profile, only: \[:edit, :update\]/ }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'support/generators'
|
2
|
+
|
3
|
+
RSpec.describe Adminos::Generators::SearchGenerator, type: :generator do
|
4
|
+
prepare_app(folder_name: 'dummy')
|
5
|
+
generate('adminos article')
|
6
|
+
generate('adminos:search Article')
|
7
|
+
|
8
|
+
describe "app/models/article.rb" do
|
9
|
+
subject { file("app/models/article.rb") }
|
10
|
+
|
11
|
+
it { is_expected.to contain /include Adminos::Searchable/ }
|
12
|
+
it { is_expected.to contain /searchable/ }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "app/views/admin/articles/index.slim" do
|
16
|
+
subject { file("app/views/admin/articles/index.slim") }
|
17
|
+
|
18
|
+
it { is_expected.to contain "= render 'shared/admin/search_form'" }
|
19
|
+
end
|
20
|
+
end
|