camaleon_cms 2.9.2 → 2.9.4
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 +4 -4
- data/README.md +17 -4
- data/Rakefile +3 -16
- data/app/apps/plugins/attack/admin_controller.rb +9 -6
- data/app/apps/plugins/attack/attack_helper.rb +35 -25
- data/app/apps/plugins/authoring_post/authoring_post_helper.rb +23 -16
- data/app/apps/plugins/front_cache/admin_controller.rb +14 -10
- data/app/apps/plugins/front_cache/config/initializer.rb +1 -1
- data/app/apps/plugins/front_cache/config/locales/translation.yml +0 -7
- data/app/apps/plugins/front_cache/front_cache_helper.rb +109 -37
- data/app/apps/plugins/front_cache/views/admin/settings.html.erb +0 -5
- data/app/apps/plugins/visibility_post/config/config.json +1 -0
- data/app/apps/plugins/visibility_post/config/routes_front.txt +1 -0
- data/app/apps/plugins/visibility_post/front_controller.rb +23 -0
- data/app/apps/plugins/visibility_post/visibility_post_helper.rb +141 -70
- data/app/apps/themes/camaleon_first/main_helper.rb +18 -12
- data/app/apps/themes/default/assets/css/style.css.scss +24 -0
- data/app/apps/themes/default/assets/genericons/genericons.css +3 -8
- data/app/apps/themes/default/default_helper.rb +2 -1
- data/app/apps/themes/default/views/layouts/index.html.erb +3 -1
- data/app/apps/themes/new/assets/css/styles.css.scss +24 -0
- data/app/apps/themes/new/custom_helper.rb +5 -9
- data/app/apps/themes/new/views/layouts/_header.html.erb +3 -1
- data/app/assets/javascripts/camaleon_cms/admin/_data.js +16 -0
- data/app/assets/javascripts/camaleon_cms/admin/_post.js +5 -2
- data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js +14 -3
- data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js +5 -0
- data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +8 -6
- data/app/controllers/camaleon_cms/admin/appearances/themes_controller.rb +8 -5
- data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +7 -2
- data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +2 -1
- data/app/controllers/camaleon_cms/admin/categories_controller.rb +19 -4
- data/app/controllers/camaleon_cms/admin/comments_controller.rb +0 -1
- data/app/controllers/camaleon_cms/admin/installers_controller.rb +32 -1
- data/app/controllers/camaleon_cms/admin/media_controller.rb +66 -14
- data/app/controllers/camaleon_cms/admin/plugins_controller.rb +1 -3
- data/app/controllers/camaleon_cms/admin/post_tags_controller.rb +10 -4
- data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +40 -11
- data/app/controllers/camaleon_cms/admin/posts_controller.rb +55 -22
- data/app/controllers/camaleon_cms/admin/sessions_controller.rb +237 -44
- data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +80 -13
- data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +5 -2
- data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +26 -3
- data/app/controllers/camaleon_cms/admin/settings_controller.rb +5 -3
- data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +7 -5
- data/app/controllers/camaleon_cms/admin/users_controller.rb +78 -11
- data/app/controllers/camaleon_cms/admin_controller.rb +136 -26
- data/app/controllers/camaleon_cms/camaleon_controller.rb +37 -92
- data/app/controllers/camaleon_cms/frontend_controller.rb +146 -74
- data/app/controllers/concerns/camaleon_cms/admin/custom_fields_concern.rb +20 -5
- data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +46 -17
- data/app/controllers/concerns/camaleon_cms/frontend_visited_state_concern.rb +72 -0
- data/app/controllers/concerns/camaleon_cms/hook_lifecycle_concern.rb +104 -0
- data/app/controllers/concerns/camaleon_cms/request_context_concern.rb +113 -0
- data/app/controllers/concerns/camaleon_cms/runtime_admin_menu_concern.rb +237 -0
- data/app/controllers/concerns/camaleon_cms/runtime_captcha_image_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_html_content_concern.rb +143 -0
- data/app/controllers/concerns/camaleon_cms/runtime_shortcode_theme_concern.rb +246 -0
- data/app/controllers/concerns/camaleon_cms/runtime_state_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_uploader_concern.rb +54 -0
- data/app/controllers/concerns/camaleon_cms/session_captcha_runtime_concern.rb +19 -0
- data/app/controllers/concerns/camaleon_cms/session_runtime_concern.rb +40 -0
- data/app/decorators/camaleon_cms/application_decorator.rb +11 -8
- data/app/decorators/camaleon_cms/category_decorator.rb +3 -2
- data/app/decorators/camaleon_cms/post_comment_decorator.rb +13 -5
- data/app/decorators/camaleon_cms/post_decorator.rb +68 -50
- data/app/decorators/camaleon_cms/post_type_decorator.rb +1 -1
- data/app/decorators/camaleon_cms/site_decorator.rb +33 -25
- data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +21 -10
- data/app/decorators/camaleon_cms/theme_decorator.rb +3 -3
- data/app/decorators/camaleon_cms/user_decorator.rb +26 -5
- data/app/helpers/camaleon_cms/admin/application_helper.rb +5 -8
- data/app/helpers/camaleon_cms/admin/breadcrumb_helper.rb +1 -1
- data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +24 -23
- data/app/helpers/camaleon_cms/admin/menus_helper.rb +249 -139
- data/app/helpers/camaleon_cms/admin/post_type_helper.rb +34 -17
- data/app/helpers/camaleon_cms/camaleon_helper.rb +31 -39
- data/app/helpers/camaleon_cms/captcha_helper.rb +73 -53
- data/app/helpers/camaleon_cms/comment_helper.rb +19 -7
- data/app/helpers/camaleon_cms/content_helper.rb +13 -6
- data/app/helpers/camaleon_cms/email_helper.rb +7 -3
- data/app/helpers/camaleon_cms/frontend/application_helper.rb +6 -1
- data/app/helpers/camaleon_cms/frontend/content_select_helper.rb +34 -20
- data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +143 -66
- data/app/helpers/camaleon_cms/frontend/seo_helper.rb +39 -28
- data/app/helpers/camaleon_cms/frontend/site_helper.rb +32 -12
- data/app/helpers/camaleon_cms/hooks_helper.rb +14 -4
- data/app/helpers/camaleon_cms/html_helper.rb +58 -37
- data/app/helpers/camaleon_cms/plugins_helper.rb +23 -24
- data/app/helpers/camaleon_cms/session_helper.rb +188 -44
- data/app/helpers/camaleon_cms/short_code_helper.rb +181 -85
- data/app/helpers/camaleon_cms/site_helper.rb +34 -13
- data/app/helpers/camaleon_cms/theme_helper.rb +35 -19
- data/app/helpers/camaleon_cms/uploader_helper.rb +19 -473
- data/app/helpers/camaleon_cms/user_roles_helper.rb +5 -4
- data/app/mailers/camaleon_cms/html_mailer.rb +4 -4
- data/app/models/camaleon_cms/ability.rb +15 -7
- data/app/models/camaleon_cms/category.rb +6 -6
- data/app/models/camaleon_cms/custom_field.rb +15 -6
- data/app/models/camaleon_cms/custom_field_group.rb +39 -22
- data/app/models/camaleon_cms/custom_fields_relationship.rb +140 -2
- data/app/models/camaleon_cms/media.rb +8 -2
- data/app/models/camaleon_cms/meta.rb +2 -2
- data/app/models/camaleon_cms/nav_menu.rb +5 -3
- data/app/models/camaleon_cms/nav_menu_item.rb +16 -8
- data/app/models/camaleon_cms/plugin.rb +3 -4
- data/app/models/camaleon_cms/post.rb +137 -27
- data/app/models/camaleon_cms/post_comment.rb +10 -6
- data/app/models/camaleon_cms/post_default.rb +42 -12
- data/app/models/camaleon_cms/post_relationship.rb +6 -4
- data/app/models/camaleon_cms/post_tag.rb +4 -5
- data/app/models/camaleon_cms/post_type.rb +21 -13
- data/app/models/camaleon_cms/site.rb +39 -29
- data/app/models/camaleon_cms/term_relationship.rb +10 -7
- data/app/models/camaleon_cms/term_taxonomy.rb +58 -4
- data/app/models/camaleon_cms/theme.rb +2 -4
- data/app/models/camaleon_cms/user.rb +17 -5
- data/app/models/camaleon_cms/user_role.rb +81 -6
- data/app/models/camaleon_cms/widget/assigned.rb +11 -6
- data/app/models/camaleon_cms/widget/main.rb +12 -8
- data/app/models/camaleon_cms/widget/sidebar.rb +3 -8
- data/app/models/camaleon_record.rb +89 -5
- data/app/models/concerns/camaleon_cms/categories_tags_for_posts.rb +36 -42
- data/app/models/concerns/camaleon_cms/common_relationships.rb +18 -5
- data/app/models/concerns/camaleon_cms/content_shortcode_gate.rb +73 -0
- data/app/models/concerns/camaleon_cms/custom_fields_read.rb +111 -54
- data/app/models/concerns/camaleon_cms/metas.rb +31 -6
- data/app/models/concerns/camaleon_cms/normalize_attrs.rb +2 -8
- data/app/models/concerns/camaleon_cms/site_default_settings.rb +120 -16
- data/app/models/concerns/camaleon_cms/user_methods.rb +44 -19
- data/app/models/current_request.rb +8 -1
- data/app/uploaders/camaleon_cms_aws_uploader.rb +31 -10
- data/app/uploaders/camaleon_cms_local_uploader.rb +76 -19
- data/app/uploaders/camaleon_cms_uploader.rb +23 -10
- data/app/validators/camaleon_cms/post_uniq_validator.rb +5 -4
- data/app/validators/camaleon_cms/uniq_validator.rb +1 -1
- data/app/validators/camaleon_cms/user_url_validator.rb +215 -36
- data/app/views/camaleon_cms/admin/categories/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/installers/form.html.erb +5 -0
- data/app/views/camaleon_cms/admin/installers/welcome.html.erb +30 -6
- data/app/views/camaleon_cms/admin/plugins/_plugins_list.html.erb +2 -2
- data/app/views/camaleon_cms/admin/post_tags/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +1 -1
- data/app/views/camaleon_cms/admin/posts/form.html.erb +3 -2
- data/app/views/camaleon_cms/admin/posts/index.html.erb +5 -5
- data/app/views/camaleon_cms/admin/sessions/back_to_parent.html.erb +39 -0
- data/app/views/camaleon_cms/admin/sessions/logout_confirm.html.erb +27 -0
- data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +4 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +19 -4
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render_category_simple.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +4 -3
- data/app/views/camaleon_cms/admin/settings/shortcodes.html.erb +4 -4
- data/app/views/camaleon_cms/admin/settings/site.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/sites/form.html.erb +1 -1
- data/app/views/camaleon_cms/admin/user_roles/form.html.erb +24 -3
- data/app/views/camaleon_cms/admin/users/form.html.erb +8 -4
- data/app/views/camaleon_cms/admin/users/index.html.erb +1 -1
- data/app/views/camaleon_cms/default_theme/partials/_render_custom_field.html.erb +8 -2
- data/app/views/camaleon_cms/default_theme/sitemap.html.erb +1 -1
- data/app/views/camaleon_cms/default_theme/sitemap.xml.builder +1 -1
- data/app/views/layouts/camaleon_cms/admin/_header.html.erb +1 -1
- data/config/initializers/action_view.rb +42 -5
- data/config/initializers/active_record_extension.rb +13 -27
- data/config/initializers/assets.rb +52 -23
- data/config/initializers/custom_initializers.rb +1 -1
- data/config/locales/camaleon_cms/admin/ar.yml +1 -0
- data/config/locales/camaleon_cms/admin/de.yml +1 -0
- data/config/locales/camaleon_cms/admin/en.yml +36 -0
- data/config/locales/camaleon_cms/admin/es.yml +1 -0
- data/config/locales/camaleon_cms/admin/fr.yml +1 -0
- data/config/locales/camaleon_cms/admin/it.yml +1 -0
- data/config/locales/camaleon_cms/admin/nl.yml +1 -0
- data/config/locales/camaleon_cms/admin/pt-BR.yml +1 -0
- data/config/locales/camaleon_cms/admin/pt.yml +1 -0
- data/config/locales/camaleon_cms/admin/ru.yml +1 -0
- data/config/locales/camaleon_cms/admin/uk.yml +1 -0
- data/config/locales/camaleon_cms/admin/zh-CH.yml +1 -0
- data/config/routes/admin.rb +33 -15
- data/config/routes/frontend.rb +21 -15
- data/lib/camaleon_cms/assets_precompile.rb +86 -0
- data/lib/camaleon_cms/captcha_image_generation.rb +65 -0
- data/lib/camaleon_cms/content_security.rb +158 -0
- data/lib/camaleon_cms/engine.rb +45 -21
- data/lib/camaleon_cms/media_security_headers.rb +27 -0
- data/lib/camaleon_cms/setup_token.rb +69 -0
- data/lib/camaleon_cms/shortcode_registry.rb +102 -0
- data/lib/camaleon_cms/svg_content_checker.rb +123 -0
- data/lib/camaleon_cms/task_reporter.rb +14 -0
- data/lib/camaleon_cms/unsafe_markup.rb +207 -0
- data/lib/camaleon_cms/uploader_content_security.rb +248 -0
- data/lib/camaleon_cms/uploader_image_processing.rb +166 -0
- data/lib/camaleon_cms/uploader_path_security.rb +146 -0
- data/lib/camaleon_cms/uploader_pipeline.rb +350 -0
- data/lib/camaleon_cms/uploader_support.rb +86 -0
- data/lib/camaleon_cms/version.rb +1 -1
- data/lib/camaleon_cms.rb +23 -0
- data/lib/ext/hash.rb +28 -2
- data/lib/ext/string.rb +10 -5
- data/lib/ext/translator.rb +10 -2
- data/lib/generators/camaleon_cms/gem_plugin_template/app/controllers/plugins/my_plugin/admin_controller.rb +5 -1
- data/lib/generators/camaleon_cms/install_generator.rb +7 -4
- data/lib/generators/camaleon_cms/install_template/plugin_routes.rb +5 -12
- data/lib/generators/camaleon_cms/theme_generator.rb +5 -10
- data/lib/generators/camaleon_cms/theme_template/views/layouts/index.html.erb +3 -1
- data/lib/plugin_routes.rb +412 -368
- data/lib/tasks/camaleon_cms/camaleon_tasks.rake +2 -1
- data/lib/tasks/cross_site_field_groups.rake +74 -0
- data/lib/tasks/custom_fields_roles.rake +15 -13
- data/lib/tasks/orphaned_comments.rake +42 -0
- data/lib/tasks/private_upload_acls.rake +31 -0
- data/lib/tasks/site_custom_field_groups.rake +36 -0
- data/lib/tasks/unsafe_stored_content.rake +42 -0
- data/lib/tasks/unsafe_stored_uploads.rake +70 -0
- data/lib/tasks/user_field_groups.rake +27 -0
- metadata +125 -4
|
@@ -10,7 +10,8 @@ namespace :camaleon_cms do
|
|
|
10
10
|
include Rails.application.routes.url_helpers
|
|
11
11
|
$current_site = CamaleonCms::Site.find(ENV['site_id'].to_i)
|
|
12
12
|
cama_uploader_init_connection
|
|
13
|
-
|
|
13
|
+
# TODO: The `fog` gem isn't used anymore - this whole task should be refactored
|
|
14
|
+
@fog_connection_bucket_dir.files.all.each do |file| # rubocop:disable Rails/FindEach
|
|
14
15
|
puts file.inspect
|
|
15
16
|
cama_uploader_generate_thumbnail(file.key, file.key, '')
|
|
16
17
|
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
namespace :camaleon_cms do
|
|
2
|
+
# A custom field group carries tenancy in `parent_id` (which site owns and administers it) and
|
|
3
|
+
# placement in `object_class` + `objectid` (which record's admin page displays it). Placement reads
|
|
4
|
+
# are not scoped by site, so a group whose two disagree renders on the site owning the placement
|
|
5
|
+
# target while staying invisible in that site's own field group list, which is tenancy-scoped.
|
|
6
|
+
#
|
|
7
|
+
# Re-home rather than delete: a mismatch is not proof of an injection -- a plugin stamping
|
|
8
|
+
# parent_id from the wrong site produces the same shape -- and deleting would take the group's
|
|
9
|
+
# field definitions and their values with it. Setting parent_id to the site that already renders
|
|
10
|
+
# the group restores the invariant and surfaces it where an administrator can judge and remove it.
|
|
11
|
+
desc 'Re-home custom field groups whose owning site differs from the site owning their placement'
|
|
12
|
+
task rehome_cross_site_field_groups: :environment do
|
|
13
|
+
report = CamaleonCms::TaskReporter
|
|
14
|
+
report.call 'Re-homing cross-site custom field groups...'
|
|
15
|
+
rehomed_count = 0
|
|
16
|
+
skipped_count = 0
|
|
17
|
+
|
|
18
|
+
CamaleonCms::CustomFieldGroup.unscoped.where.not(object_class: '_fields').find_each do |group|
|
|
19
|
+
site_id = cama_placement_site_id(group)
|
|
20
|
+
|
|
21
|
+
if site_id.blank?
|
|
22
|
+
report.call " Skipped group id=#{group.id} slug=#{group.slug} " \
|
|
23
|
+
"(#{group.object_class}/#{group.objectid} does not resolve to a site)"
|
|
24
|
+
skipped_count += 1
|
|
25
|
+
next
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
next if site_id == group.parent_id
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
report.call "✓ Re-homed group id=#{group.id} slug=#{group.slug} " \
|
|
32
|
+
"from site_id=#{group.parent_id} to site_id=#{site_id} " \
|
|
33
|
+
"(placement #{group.object_class}/#{group.objectid})"
|
|
34
|
+
group.update_column(:parent_id, site_id) # rubocop:disable Rails/SkipsModelValidations
|
|
35
|
+
rehomed_count += 1
|
|
36
|
+
rescue StandardError => e
|
|
37
|
+
report.call "✗ Failed to re-home group id=#{group.id}: #{e.message}"
|
|
38
|
+
skipped_count += 1
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
report.call "\nSummary:"
|
|
43
|
+
report.call " Re-homed: #{rehomed_count} field groups"
|
|
44
|
+
report.call " Skipped: #{skipped_count} field groups"
|
|
45
|
+
report.call "\nDone. Review the field group list of any site that gained a group."
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Resolve the site owning a group's placement target, or nil when it cannot be determined.
|
|
50
|
+
# Best-effort by design: a placement naming a record that no longer exists is left alone rather
|
|
51
|
+
# than guessed at or deleted.
|
|
52
|
+
def cama_placement_site_id(group)
|
|
53
|
+
objectid = group.objectid
|
|
54
|
+
return nil if objectid.blank?
|
|
55
|
+
|
|
56
|
+
case group.object_class
|
|
57
|
+
when 'PostType', 'PostType_Post', 'PostType_Category', 'PostType_PostTag'
|
|
58
|
+
CamaleonCms::PostType.find_by(id: objectid)&.parent_id
|
|
59
|
+
when 'Theme' then CamaleonCms::Theme.find_by(id: objectid)&.parent_id
|
|
60
|
+
when 'Plugin' then CamaleonCms::Plugin.find_by(id: objectid)&.parent_id
|
|
61
|
+
when 'NavMenu' then CamaleonCms::NavMenu.find_by(id: objectid)&.parent_id
|
|
62
|
+
when 'Widget::Main' then CamaleonCms::Widget::Main.find_by(id: objectid)&.parent_id
|
|
63
|
+
when 'Post' then CamaleonCms::Post.find_by(id: objectid)&.post_type&.parent_id
|
|
64
|
+
when 'Category', 'Category_Post' then CamaleonCms::Category.find_by(id: objectid)&.post_type_parent&.parent_id
|
|
65
|
+
when 'PostTag' then CamaleonCms::PostTag.find_by(id: objectid)&.post_type&.parent_id
|
|
66
|
+
else
|
|
67
|
+
# Site, the configured user model, and models registered through the custom_field_custom_models
|
|
68
|
+
# hook are all placed with the site's own id, so the placement target is the site itself.
|
|
69
|
+
CamaleonCms::Site.find_by(id: objectid)&.id
|
|
70
|
+
end
|
|
71
|
+
rescue StandardError => e
|
|
72
|
+
CamaleonCms::TaskReporter.call " Could not resolve placement for group id=#{group.id}: #{e.message}"
|
|
73
|
+
nil
|
|
74
|
+
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
namespace :camaleon_cms do
|
|
2
2
|
desc 'Backfill user roles to include custom_fields manager permission'
|
|
3
3
|
task backfill_custom_fields_permission: :environment do
|
|
4
|
-
|
|
4
|
+
report = CamaleonCms::TaskReporter
|
|
5
|
+
report.call 'Backfilling custom_fields manager permission for existing user roles...'
|
|
5
6
|
CamaleonCms::UserRole.find_each do |role|
|
|
6
7
|
key = "_manager_#{role.parent_id}"
|
|
7
8
|
begin
|
|
@@ -10,20 +11,21 @@ namespace :camaleon_cms do
|
|
|
10
11
|
if current_role.blank? || (!current_role.is_a?(Hash) || current_role['custom_fields'].blank?)
|
|
11
12
|
current_role = (current_role.is_a?(Hash) ? current_role : {}).merge!('custom_fields' => 1)
|
|
12
13
|
role.set_meta(key, current_role)
|
|
13
|
-
|
|
14
|
+
report.call "Updated role=#{role.slug} site_id=#{role.parent_id}"
|
|
14
15
|
else
|
|
15
|
-
|
|
16
|
+
report.call "Skipped role=#{role.slug} site_id=#{role.parent_id} (already has custom_fields)"
|
|
16
17
|
end
|
|
17
18
|
rescue StandardError => e
|
|
18
|
-
|
|
19
|
+
report.call "Failed to update role=#{role.slug}: #{e.message}"
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
|
-
|
|
22
|
+
report.call 'Done.'
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
desc 'Backfill admin user roles to include select_eval permission'
|
|
25
26
|
task backfill_select_eval_permission: :environment do
|
|
26
|
-
|
|
27
|
+
report = CamaleonCms::TaskReporter
|
|
28
|
+
report.call 'Backfilling select_eval permission for admin roles...'
|
|
27
29
|
updated_count = 0
|
|
28
30
|
skipped_count = 0
|
|
29
31
|
|
|
@@ -37,20 +39,20 @@ namespace :camaleon_cms do
|
|
|
37
39
|
if !current_meta[:select_eval]
|
|
38
40
|
updated_meta = current_meta.merge(select_eval: 1)
|
|
39
41
|
role.set_meta(key, updated_meta)
|
|
40
|
-
|
|
42
|
+
report.call "✓ Updated admin role site_id=#{site_id}"
|
|
41
43
|
updated_count += 1
|
|
42
44
|
else
|
|
43
|
-
|
|
45
|
+
report.call " Skipped admin role site_id=#{site_id} (already has select_eval)"
|
|
44
46
|
skipped_count += 1
|
|
45
47
|
end
|
|
46
48
|
rescue StandardError => e
|
|
47
|
-
|
|
49
|
+
report.call "✗ Failed to update admin role site_id=#{site_id}: #{e.message}"
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
report.call "\nSummary:"
|
|
54
|
+
report.call " Updated: #{updated_count} admin roles"
|
|
55
|
+
report.call " Skipped: #{skipped_count} admin roles"
|
|
56
|
+
report.call "\nDone! All admin roles now have select_eval permission."
|
|
55
57
|
end
|
|
56
58
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :camaleon_cms do
|
|
4
|
+
desc 'Reassign comments whose user no longer exists to the owning site\'s anonymous user'
|
|
5
|
+
task reassign_orphaned_comments: :environment do
|
|
6
|
+
user_table = CamaManager.get_user_class_name.constantize.table_name
|
|
7
|
+
comment_table = CamaleonCms::PostComment.table_name
|
|
8
|
+
|
|
9
|
+
# `user_id IS NULL` on its own does not mean "orphaned": guest comments are a first-class
|
|
10
|
+
# shape — user_id is nullable and the row carries author/author_email/author_url instead —
|
|
11
|
+
# and they have always had a null user_id. The regression nulled the user_id of *registered*
|
|
12
|
+
# users' comments, and those never carry an author string, which is exactly why
|
|
13
|
+
# PostCommentDecorator#the_author_name falls back to the user's name. Requiring a blank
|
|
14
|
+
# author therefore separates the rows this task exists to repair from the ones it must not
|
|
15
|
+
# touch. Rows with a dangling (non-null, non-existent) user_id are repaired regardless.
|
|
16
|
+
orphans = CamaleonCms::PostComment
|
|
17
|
+
.where("(#{comment_table}.user_id IS NULL AND " \
|
|
18
|
+
"(#{comment_table}.author IS NULL OR #{comment_table}.author = '')) " \
|
|
19
|
+
"OR (#{comment_table}.user_id IS NOT NULL AND #{comment_table}.user_id NOT IN " \
|
|
20
|
+
"(SELECT id FROM #{user_table}))")
|
|
21
|
+
reassigned = 0
|
|
22
|
+
skipped = 0
|
|
23
|
+
|
|
24
|
+
orphans.find_each do |comment|
|
|
25
|
+
site = comment.post&.post_type&.site
|
|
26
|
+
if site.nil?
|
|
27
|
+
skipped += 1
|
|
28
|
+
next
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
comment.update_column(:user_id, site.get_anonymous_user.id) # rubocop:disable Rails/SkipsModelValidations
|
|
32
|
+
reassigned += 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
summary = "camaleon_cms:reassign_orphaned_comments reassigned #{reassigned} comment(s)" \
|
|
36
|
+
"#{skipped > 0 ? ", skipped #{skipped} without a resolvable site" : ''}"
|
|
37
|
+
Rails.logger.info(summary)
|
|
38
|
+
# An operator runs this from a terminal, where Rails.logger writes to a file they are not
|
|
39
|
+
# watching. Without this the task looks like it did nothing.
|
|
40
|
+
puts summary
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :camaleon_cms do
|
|
4
|
+
desc 'Re-apply the owner-only ACL to S3 objects under each AWS site\'s private upload prefix ' \
|
|
5
|
+
'(uploads stored before the private-ACL fix were world-readable). ' \
|
|
6
|
+
'Set CAMA_S3_INNER_FOLDER for setups whose uploader hook configures an inner_folder.'
|
|
7
|
+
task repair_private_upload_acls: :environment do
|
|
8
|
+
inner_folder = ENV['CAMA_S3_INNER_FOLDER'].to_s
|
|
9
|
+
repaired_total = 0
|
|
10
|
+
swept_sites = 0
|
|
11
|
+
|
|
12
|
+
CamaleonCms::Site.find_each do |site_record|
|
|
13
|
+
site = site_record.decorate
|
|
14
|
+
next unless %w[aws s3].include?(site.get_option('filesystem_type', 'local').to_s.downcase)
|
|
15
|
+
|
|
16
|
+
uploader = CamaleonCmsAwsUploader.new({ current_site: site,
|
|
17
|
+
aws_settings: { 'inner_folder' => inner_folder } }, nil)
|
|
18
|
+
repaired = uploader.repair_private_acls!
|
|
19
|
+
swept_sites += 1
|
|
20
|
+
repaired_total += repaired
|
|
21
|
+
puts " #{site.the_slug}: #{repaired} object(s) re-ACLed"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
summary = "camaleon_cms:repair_private_upload_acls re-ACLed #{repaired_total} object(s) " \
|
|
25
|
+
"across #{swept_sites} AWS site(s)"
|
|
26
|
+
Rails.logger.info(summary)
|
|
27
|
+
# An operator runs this from a terminal, where Rails.logger writes to a file they are not
|
|
28
|
+
# watching. Without this the task looks like it did nothing.
|
|
29
|
+
puts summary
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
namespace :camaleon_cms do
|
|
2
|
+
# Site#get_field_groups matches a group's placement (object_class + objectid) instead of its
|
|
3
|
+
# tenancy (parent_id). `objectid` has no presence validation, so a group could be persisted with
|
|
4
|
+
# object_class 'Site' and a NULL objectid by bypassing add_custom_field_group. Those rows are
|
|
5
|
+
# invisible on the site settings page under the placement-scoped read, so give them the objectid
|
|
6
|
+
# they should always have had: the site that owns them.
|
|
7
|
+
desc 'Backfill objectid for site custom field groups that were saved without one'
|
|
8
|
+
task backfill_site_field_group_objectid: :environment do
|
|
9
|
+
report = CamaleonCms::TaskReporter
|
|
10
|
+
report.call 'Backfilling objectid for site custom field groups...'
|
|
11
|
+
updated_count = 0
|
|
12
|
+
skipped_count = 0
|
|
13
|
+
|
|
14
|
+
CamaleonCms::CustomField.unscoped.where(object_class: 'Site', objectid: nil).find_each do |group|
|
|
15
|
+
if group.parent_id.blank?
|
|
16
|
+
report.call " Skipped group id=#{group.id} slug=#{group.slug} (no owning site)"
|
|
17
|
+
skipped_count += 1
|
|
18
|
+
next
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
group.update_column(:objectid, group.parent_id) # rubocop:disable Rails/SkipsModelValidations
|
|
23
|
+
report.call "✓ Updated group id=#{group.id} slug=#{group.slug} site_id=#{group.parent_id}"
|
|
24
|
+
updated_count += 1
|
|
25
|
+
rescue StandardError => e
|
|
26
|
+
report.call "✗ Failed to update group id=#{group.id}: #{e.message}"
|
|
27
|
+
skipped_count += 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
report.call "\nSummary:"
|
|
32
|
+
report.call " Updated: #{updated_count} field groups"
|
|
33
|
+
report.call " Skipped: #{skipped_count} field groups"
|
|
34
|
+
report.call "\nDone."
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :camaleon_cms do
|
|
4
|
+
namespace :security do
|
|
5
|
+
# The scan-and-reject gates refuse dangerous content at save time but never rewrite what is
|
|
6
|
+
# already stored (nothing is ever rewritten under this model). This task lists the stored
|
|
7
|
+
# content that would fail today's gates -- post content and gated custom-field values -- so an
|
|
8
|
+
# operator can review and clean it up by hand. Read-only: it changes nothing.
|
|
9
|
+
desc 'List stored post content and custom-field values that would fail the scan-and-reject gates'
|
|
10
|
+
task scan_content: :environment do
|
|
11
|
+
report = CamaleonCms::TaskReporter
|
|
12
|
+
report.call 'Scanning stored content against the scan-and-reject gates (read-only)...'
|
|
13
|
+
flagged = 0
|
|
14
|
+
|
|
15
|
+
CamaleonCms::Post.unscoped.where.not(content: [nil, '']).find_each do |post|
|
|
16
|
+
next unless CamaleonCms::UnsafeMarkup.unsafe_html?(
|
|
17
|
+
post.content, tags: CamaleonCms::Post::CONTENT_ALLOWED_TAGS,
|
|
18
|
+
attributes: CamaleonCms::Post::CONTENT_ALLOWED_ATTRIBUTES
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
flagged += 1
|
|
22
|
+
report.call "✗ Post id=#{post.id} (#{post.post_class}) '#{post.slug.to_s.truncate(60)}': " \
|
|
23
|
+
'content would be rejected'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Reuse the model's own gate dispatch (which covers editor, field_attrs and URI field types),
|
|
27
|
+
# so the scan can never diverge from what the save-time validation would refuse.
|
|
28
|
+
CamaleonCms::CustomFieldsRelationship.unscoped.where.not(value: [nil, ''])
|
|
29
|
+
.includes(:custom_field).find_each do |row|
|
|
30
|
+
field_key = row.custom_field&.options&.[](:field_key).to_s
|
|
31
|
+
next unless CamaleonCms::CustomFieldsRelationship.gate_rejection_reason(field_key, row.value)
|
|
32
|
+
|
|
33
|
+
flagged += 1
|
|
34
|
+
report.call "✗ Custom-field value id=#{row.id} field='#{row.custom_field_slug}' " \
|
|
35
|
+
"(#{field_key}) on #{row.object_class} ##{row.objectid}: value would be rejected"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
report.call "Done. #{flagged} stored item(s) would be rejected by today's gates."
|
|
39
|
+
report.call 'Nothing was modified; review and clean up the listed items by hand.'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :camaleon_cms do
|
|
4
|
+
namespace :security do
|
|
5
|
+
# The upload rules refuse dangerous content at upload time but never re-examine what is already
|
|
6
|
+
# stored (nothing is ever rewritten under this model). This task lists the stored files today's
|
|
7
|
+
# rules would refuse, so an operator can review them by hand. Read-only: it changes nothing.
|
|
8
|
+
#
|
|
9
|
+
# The companion for authored content is camaleon_cms:security:scan_content.
|
|
10
|
+
desc 'List stored media files that would fail the upload scan rules'
|
|
11
|
+
task scan_uploads: :environment do
|
|
12
|
+
report = CamaleonCms::TaskReporter
|
|
13
|
+
# Reuse the real scanner rather than reimplementing its rules, so the report can never
|
|
14
|
+
# disagree with what an upload of the same bytes would be told today.
|
|
15
|
+
scanner = Class.new { include CamaleonCms::UploaderContentSecurity }.new
|
|
16
|
+
flagged = 0
|
|
17
|
+
scanned = 0
|
|
18
|
+
|
|
19
|
+
report.call 'Scanning stored media against the upload scan rules (read-only)...'
|
|
20
|
+
|
|
21
|
+
# Scans every file under `root`, reporting those today's rules would refuse. `label` names the
|
|
22
|
+
# location and `base` anchors the reported path. Closes over the counters so the public and
|
|
23
|
+
# private roots share one pass rather than duplicating the scan logic (and risking drift).
|
|
24
|
+
# FNM_DOTMATCH so dotfiles are scanned: a basename that is entirely an extension (`.svg`, `.js`)
|
|
25
|
+
# is exactly what the scanner fail-closes on. `.`/`..` are directory entries File.file? drops.
|
|
26
|
+
scan_tree = lambda do |root, base, label|
|
|
27
|
+
next unless root.directory?
|
|
28
|
+
|
|
29
|
+
Dir.glob(root.join('**', '*'), File::FNM_DOTMATCH).sort.each do |path|
|
|
30
|
+
next unless File.file?(path)
|
|
31
|
+
|
|
32
|
+
scanned += 1
|
|
33
|
+
relative = Pathname.new(path).relative_path_from(base)
|
|
34
|
+
reason = begin
|
|
35
|
+
scanner.content_unsafe?(File.binread(path), filename: File.basename(path))
|
|
36
|
+
rescue StandardError => e
|
|
37
|
+
# A file the scan cannot read at all is reported rather than skipped: an unreadable
|
|
38
|
+
# entry is exactly what an operator wants to know about, and swallowing it would hand
|
|
39
|
+
# them a false all-clear.
|
|
40
|
+
"unreadable (#{e.class})"
|
|
41
|
+
end
|
|
42
|
+
next unless reason
|
|
43
|
+
|
|
44
|
+
flagged += 1
|
|
45
|
+
report.call "✗ #{label} /#{relative}: would be rejected (#{reason})"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
CamaleonCms::Site.unscoped.find_each do |site|
|
|
50
|
+
# Site#upload_directory honours the `media_slug_folder` config, which stores uploads under
|
|
51
|
+
# media/<slug> instead of media/<id>. Hardcoding the id scanned nothing on a slug-configured
|
|
52
|
+
# install and printed a clean "0 would be rejected" -- a false all-clear.
|
|
53
|
+
scan_tree.call(Pathname.new(site.upload_directory), Rails.public_path, "Site #{site.id}")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Private media is scanned at upload time exactly like public media, so files stored before
|
|
57
|
+
# these rules apply are equally worth surfacing. It lives outside the public root, under its
|
|
58
|
+
# own directory, so it is scanned separately and reported relative to the app root.
|
|
59
|
+
scan_tree.call(Rails.root.join(CamaleonCmsUploader::PRIVATE_DIRECTORY), Rails.root, 'Private media')
|
|
60
|
+
|
|
61
|
+
report.call "Done. #{scanned} stored file(s) scanned, #{flagged} would be rejected by today's rules."
|
|
62
|
+
report.call 'Nothing was modified.'
|
|
63
|
+
if flagged > 0
|
|
64
|
+
report.call 'A finding is not by itself evidence of compromise: these rules are newer than ' \
|
|
65
|
+
'the files, so content uploaded legitimately under the previous rules is ' \
|
|
66
|
+
'listed too. Review each one before acting.'
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :camaleon_cms do
|
|
4
|
+
# Through 2.9.2 the custom-fields settings form emitted the raw `user_model` config string as
|
|
5
|
+
# the users placement option, so a namespaced host user model (e.g. 'Admin::User') stored its
|
|
6
|
+
# user field groups under the qualified name — which the demodulized association scope and the
|
|
7
|
+
# 2.9.2 allowed-slugs save filter cannot see. Re-key those group placements to the demodulized
|
|
8
|
+
# contract. Only the group rows move: their fields hang off parent_id under '_fields', group
|
|
9
|
+
# metas key off 'CustomFieldGroup', and value rows were always written under the demodulized
|
|
10
|
+
# name. Keyed to the current config: a host that renamed its user model after writing groups
|
|
11
|
+
# should temporarily restore the historical value while running the task.
|
|
12
|
+
desc 'Re-key user custom field groups stored under a namespaced user_model name'
|
|
13
|
+
task demodulize_user_field_groups: :environment do
|
|
14
|
+
configured = PluginRoutes.static_system_info['user_model'].presence.to_s
|
|
15
|
+
demodulized = configured.demodulize
|
|
16
|
+
|
|
17
|
+
if configured.blank? || configured == demodulized
|
|
18
|
+
puts 'Nothing to re-key: the configured user model is not namespaced.'
|
|
19
|
+
next
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
count = CamaleonCms::CustomField.unscoped
|
|
23
|
+
.where(object_class: configured)
|
|
24
|
+
.update_all(object_class: demodulized) # rubocop:disable Rails/SkipsModelValidations
|
|
25
|
+
puts "Re-keyed #{count} user field group(s) from '#{configured}' to '#{demodulized}'."
|
|
26
|
+
end
|
|
27
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: camaleon_cms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.9.
|
|
4
|
+
version: 2.9.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Owen Peredo Diaz
|
|
@@ -57,14 +57,14 @@ dependencies:
|
|
|
57
57
|
requirements:
|
|
58
58
|
- - "~>"
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 0.1.
|
|
60
|
+
version: 0.1.13
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 0.1.
|
|
67
|
+
version: 0.1.13
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: cama_meta_tag
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -449,6 +449,76 @@ dependencies:
|
|
|
449
449
|
- - ">="
|
|
450
450
|
- !ruby/object:Gem::Version
|
|
451
451
|
version: '0'
|
|
452
|
+
- !ruby/object:Gem::Dependency
|
|
453
|
+
name: rubocop-capybara
|
|
454
|
+
requirement: !ruby/object:Gem::Requirement
|
|
455
|
+
requirements:
|
|
456
|
+
- - ">="
|
|
457
|
+
- !ruby/object:Gem::Version
|
|
458
|
+
version: '0'
|
|
459
|
+
type: :development
|
|
460
|
+
prerelease: false
|
|
461
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
462
|
+
requirements:
|
|
463
|
+
- - ">="
|
|
464
|
+
- !ruby/object:Gem::Version
|
|
465
|
+
version: '0'
|
|
466
|
+
- !ruby/object:Gem::Dependency
|
|
467
|
+
name: rubocop-factory_bot
|
|
468
|
+
requirement: !ruby/object:Gem::Requirement
|
|
469
|
+
requirements:
|
|
470
|
+
- - ">="
|
|
471
|
+
- !ruby/object:Gem::Version
|
|
472
|
+
version: '0'
|
|
473
|
+
type: :development
|
|
474
|
+
prerelease: false
|
|
475
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
476
|
+
requirements:
|
|
477
|
+
- - ">="
|
|
478
|
+
- !ruby/object:Gem::Version
|
|
479
|
+
version: '0'
|
|
480
|
+
- !ruby/object:Gem::Dependency
|
|
481
|
+
name: rubocop-performance
|
|
482
|
+
requirement: !ruby/object:Gem::Requirement
|
|
483
|
+
requirements:
|
|
484
|
+
- - ">="
|
|
485
|
+
- !ruby/object:Gem::Version
|
|
486
|
+
version: '0'
|
|
487
|
+
type: :development
|
|
488
|
+
prerelease: false
|
|
489
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
490
|
+
requirements:
|
|
491
|
+
- - ">="
|
|
492
|
+
- !ruby/object:Gem::Version
|
|
493
|
+
version: '0'
|
|
494
|
+
- !ruby/object:Gem::Dependency
|
|
495
|
+
name: rubocop-rails
|
|
496
|
+
requirement: !ruby/object:Gem::Requirement
|
|
497
|
+
requirements:
|
|
498
|
+
- - ">="
|
|
499
|
+
- !ruby/object:Gem::Version
|
|
500
|
+
version: '0'
|
|
501
|
+
type: :development
|
|
502
|
+
prerelease: false
|
|
503
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
504
|
+
requirements:
|
|
505
|
+
- - ">="
|
|
506
|
+
- !ruby/object:Gem::Version
|
|
507
|
+
version: '0'
|
|
508
|
+
- !ruby/object:Gem::Dependency
|
|
509
|
+
name: rubocop-rake
|
|
510
|
+
requirement: !ruby/object:Gem::Requirement
|
|
511
|
+
requirements:
|
|
512
|
+
- - ">="
|
|
513
|
+
- !ruby/object:Gem::Version
|
|
514
|
+
version: '0'
|
|
515
|
+
type: :development
|
|
516
|
+
prerelease: false
|
|
517
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
518
|
+
requirements:
|
|
519
|
+
- - ">="
|
|
520
|
+
- !ruby/object:Gem::Version
|
|
521
|
+
version: '0'
|
|
452
522
|
- !ruby/object:Gem::Dependency
|
|
453
523
|
name: rubocop-rspec
|
|
454
524
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -463,6 +533,20 @@ dependencies:
|
|
|
463
533
|
- - ">="
|
|
464
534
|
- !ruby/object:Gem::Version
|
|
465
535
|
version: '0'
|
|
536
|
+
- !ruby/object:Gem::Dependency
|
|
537
|
+
name: rubocop-rspec_rails
|
|
538
|
+
requirement: !ruby/object:Gem::Requirement
|
|
539
|
+
requirements:
|
|
540
|
+
- - ">="
|
|
541
|
+
- !ruby/object:Gem::Version
|
|
542
|
+
version: '0'
|
|
543
|
+
type: :development
|
|
544
|
+
prerelease: false
|
|
545
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
546
|
+
requirements:
|
|
547
|
+
- - ">="
|
|
548
|
+
- !ruby/object:Gem::Version
|
|
549
|
+
version: '0'
|
|
466
550
|
- !ruby/object:Gem::Dependency
|
|
467
551
|
name: sqlite3
|
|
468
552
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -509,6 +593,8 @@ files:
|
|
|
509
593
|
- app/apps/plugins/front_cache/views/admin/settings.html.erb
|
|
510
594
|
- app/apps/plugins/visibility_post/assets/js/form.js
|
|
511
595
|
- app/apps/plugins/visibility_post/config/config.json
|
|
596
|
+
- app/apps/plugins/visibility_post/config/routes_front.txt
|
|
597
|
+
- app/apps/plugins/visibility_post/front_controller.rb
|
|
512
598
|
- app/apps/plugins/visibility_post/visibility_post_helper.rb
|
|
513
599
|
- app/apps/themes/camaleon_first/assets/css/magnific-ver.css
|
|
514
600
|
- app/apps/themes/camaleon_first/assets/css/main.css
|
|
@@ -787,6 +873,17 @@ files:
|
|
|
787
873
|
- app/controllers/camaleon_cms/frontend_controller.rb
|
|
788
874
|
- app/controllers/concerns/camaleon_cms/admin/custom_fields_concern.rb
|
|
789
875
|
- app/controllers/concerns/camaleon_cms/frontend_concern.rb
|
|
876
|
+
- app/controllers/concerns/camaleon_cms/frontend_visited_state_concern.rb
|
|
877
|
+
- app/controllers/concerns/camaleon_cms/hook_lifecycle_concern.rb
|
|
878
|
+
- app/controllers/concerns/camaleon_cms/request_context_concern.rb
|
|
879
|
+
- app/controllers/concerns/camaleon_cms/runtime_admin_menu_concern.rb
|
|
880
|
+
- app/controllers/concerns/camaleon_cms/runtime_captcha_image_concern.rb
|
|
881
|
+
- app/controllers/concerns/camaleon_cms/runtime_html_content_concern.rb
|
|
882
|
+
- app/controllers/concerns/camaleon_cms/runtime_shortcode_theme_concern.rb
|
|
883
|
+
- app/controllers/concerns/camaleon_cms/runtime_state_concern.rb
|
|
884
|
+
- app/controllers/concerns/camaleon_cms/runtime_uploader_concern.rb
|
|
885
|
+
- app/controllers/concerns/camaleon_cms/session_captcha_runtime_concern.rb
|
|
886
|
+
- app/controllers/concerns/camaleon_cms/session_runtime_concern.rb
|
|
790
887
|
- app/decorators/camaleon_cms/application_decorator.rb
|
|
791
888
|
- app/decorators/camaleon_cms/category_decorator.rb
|
|
792
889
|
- app/decorators/camaleon_cms/custom_field_decorator.rb
|
|
@@ -859,6 +956,7 @@ files:
|
|
|
859
956
|
- app/models/camaleon_record.rb
|
|
860
957
|
- app/models/concerns/camaleon_cms/categories_tags_for_posts.rb
|
|
861
958
|
- app/models/concerns/camaleon_cms/common_relationships.rb
|
|
959
|
+
- app/models/concerns/camaleon_cms/content_shortcode_gate.rb
|
|
862
960
|
- app/models/concerns/camaleon_cms/custom_fields_read.rb
|
|
863
961
|
- app/models/concerns/camaleon_cms/metas.rb
|
|
864
962
|
- app/models/concerns/camaleon_cms/normalize_attrs.rb
|
|
@@ -916,8 +1014,10 @@ files:
|
|
|
916
1014
|
- app/views/camaleon_cms/admin/posts/index.html.erb
|
|
917
1015
|
- app/views/camaleon_cms/admin/posts/show.html.erb
|
|
918
1016
|
- app/views/camaleon_cms/admin/search.html.erb
|
|
1017
|
+
- app/views/camaleon_cms/admin/sessions/back_to_parent.html.erb
|
|
919
1018
|
- app/views/camaleon_cms/admin/sessions/forgot.html.erb
|
|
920
1019
|
- app/views/camaleon_cms/admin/sessions/login.html.erb
|
|
1020
|
+
- app/views/camaleon_cms/admin/sessions/logout_confirm.html.erb
|
|
921
1021
|
- app/views/camaleon_cms/admin/sessions/register.html.erb
|
|
922
1022
|
- app/views/camaleon_cms/admin/settings/_configuration_settings.html.erb
|
|
923
1023
|
- app/views/camaleon_cms/admin/settings/_email_settings.html.erb
|
|
@@ -1141,7 +1241,21 @@ files:
|
|
|
1141
1241
|
- db/migrate/20180124132318_create_media.rb
|
|
1142
1242
|
- db/migrate/20180704211100_adjust_field_length.rb
|
|
1143
1243
|
- lib/camaleon_cms.rb
|
|
1244
|
+
- lib/camaleon_cms/assets_precompile.rb
|
|
1245
|
+
- lib/camaleon_cms/captcha_image_generation.rb
|
|
1246
|
+
- lib/camaleon_cms/content_security.rb
|
|
1144
1247
|
- lib/camaleon_cms/engine.rb
|
|
1248
|
+
- lib/camaleon_cms/media_security_headers.rb
|
|
1249
|
+
- lib/camaleon_cms/setup_token.rb
|
|
1250
|
+
- lib/camaleon_cms/shortcode_registry.rb
|
|
1251
|
+
- lib/camaleon_cms/svg_content_checker.rb
|
|
1252
|
+
- lib/camaleon_cms/task_reporter.rb
|
|
1253
|
+
- lib/camaleon_cms/unsafe_markup.rb
|
|
1254
|
+
- lib/camaleon_cms/uploader_content_security.rb
|
|
1255
|
+
- lib/camaleon_cms/uploader_image_processing.rb
|
|
1256
|
+
- lib/camaleon_cms/uploader_path_security.rb
|
|
1257
|
+
- lib/camaleon_cms/uploader_pipeline.rb
|
|
1258
|
+
- lib/camaleon_cms/uploader_support.rb
|
|
1145
1259
|
- lib/camaleon_cms/version.rb
|
|
1146
1260
|
- lib/captcha/bumpyroad.ttf
|
|
1147
1261
|
- lib/captcha/captcha_0.jpg
|
|
@@ -1188,7 +1302,14 @@ files:
|
|
|
1188
1302
|
- lib/plugin_routes.rb
|
|
1189
1303
|
- lib/tasks/camaleon_cms/camaleon_tasks.rake
|
|
1190
1304
|
- lib/tasks/camaleon_cms/rspec_test.rake
|
|
1305
|
+
- lib/tasks/cross_site_field_groups.rake
|
|
1191
1306
|
- lib/tasks/custom_fields_roles.rake
|
|
1307
|
+
- lib/tasks/orphaned_comments.rake
|
|
1308
|
+
- lib/tasks/private_upload_acls.rake
|
|
1309
|
+
- lib/tasks/site_custom_field_groups.rake
|
|
1310
|
+
- lib/tasks/unsafe_stored_content.rake
|
|
1311
|
+
- lib/tasks/unsafe_stored_uploads.rake
|
|
1312
|
+
- lib/tasks/user_field_groups.rake
|
|
1192
1313
|
homepage: https://camaleon.website
|
|
1193
1314
|
licenses:
|
|
1194
1315
|
- MIT
|
|
@@ -1210,7 +1331,7 @@ requirements:
|
|
|
1210
1331
|
- rails >= 6.1
|
|
1211
1332
|
- ruby >= 3.0
|
|
1212
1333
|
- imagemagick
|
|
1213
|
-
rubygems_version:
|
|
1334
|
+
rubygems_version: 4.0.17
|
|
1214
1335
|
specification_version: 4
|
|
1215
1336
|
summary: Camaleon is a CMS for Ruby on Rails as an alternative to Wordpress.
|
|
1216
1337
|
test_files: []
|