forked from e621ng/e621ng
[Security] Implement read only mode (#821)
This commit is contained in:
parent
5c345528e4
commit
4883912e93
@ -346,7 +346,6 @@ Layout/SpaceAfterComma:
|
||||
- 'app/logical/storage_manager/local.rb'
|
||||
- 'app/presenters/post_presenter.rb'
|
||||
- 'app/serializers/post_serializer.rb'
|
||||
- 'app/views/admin/danger_zone/index.html.erb'
|
||||
- 'app/views/mod_actions/_search.html.erb'
|
||||
- 'app/views/post_events/_search.html.erb'
|
||||
- 'app/views/post_events/index.html.erb'
|
||||
@ -475,7 +474,6 @@ Layout/SpaceInsideBlockBraces:
|
||||
- 'app/models/wiki_page.rb'
|
||||
- 'app/presenters/tag_set_presenter.rb'
|
||||
- 'app/presenters/user_presenter.rb'
|
||||
- 'app/views/admin/danger_zone/index.html.erb'
|
||||
- 'app/views/comments/_index_by_post.html.erb'
|
||||
- 'app/views/forum_topics/index.html.erb'
|
||||
- 'app/views/mod_actions/_search.html.erb'
|
||||
@ -877,7 +875,6 @@ Lint/UnusedBlockArgument:
|
||||
- 'app/controllers/posts_controller.rb'
|
||||
- 'app/indexes/post_index.rb'
|
||||
- 'app/models/post.rb'
|
||||
- 'app/views/admin/danger_zone/index.html.erb'
|
||||
- 'config/application.rb'
|
||||
- 'config/initializers/content_security_policy.rb'
|
||||
- 'config/routes.rb'
|
||||
@ -1483,7 +1480,6 @@ Style/ClassAndModuleChildren:
|
||||
- 'app/logical/storage_manager/local.rb'
|
||||
- 'app/logical/storage_manager/match.rb'
|
||||
- 'app/logical/storage_manager/null.rb'
|
||||
- 'test/functional/admin/danger_zone_controller_test.rb'
|
||||
- 'test/functional/admin/dashboards_controller_test.rb'
|
||||
- 'test/functional/admin/users_controller_test.rb'
|
||||
- 'test/test_helper.rb'
|
||||
|
@ -1,29 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class DangerZoneController < ApplicationController
|
||||
before_action :admin_only
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def uploading_limits
|
||||
new_level = params[:uploading_limits][:min_level].to_i
|
||||
raise ArgumentError, "#{new_level} is not valid" unless User.level_hash.values.include? new_level
|
||||
if new_level != DangerZone.min_upload_level
|
||||
DangerZone.min_upload_level = new_level
|
||||
StaffAuditLog.log(:min_upload_level, CurrentUser.user, { level: new_level })
|
||||
end
|
||||
redirect_to admin_danger_zone_index_path
|
||||
end
|
||||
|
||||
def hide_pending_posts
|
||||
duration = params[:hide_pending_posts][:duration].to_f
|
||||
if duration >= 0 && duration != DangerZone.hide_pending_posts_for
|
||||
DangerZone.hide_pending_posts_for = duration
|
||||
StaffAuditLog.log(:hide_pending_posts_for, CurrentUser.user, { duration: duration })
|
||||
end
|
||||
redirect_to admin_danger_zone_index_path
|
||||
end
|
||||
end
|
||||
end
|
@ -3,9 +3,10 @@
|
||||
class BlipsController < ApplicationController
|
||||
class BlipTooOld < Exception ; end
|
||||
respond_to :html, :json
|
||||
before_action :member_only, only: [:create, :new, :update, :edit, :hide]
|
||||
before_action :moderator_only, only: [:unhide, :warning]
|
||||
before_action :member_only, only: %i[create new update edit hide]
|
||||
before_action :moderator_only, only: %i[unhide warning]
|
||||
before_action :admin_only, only: [:destroy]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index show]
|
||||
|
||||
rescue_from BlipTooOld, with: :blip_too_old
|
||||
|
||||
@ -123,4 +124,8 @@ class BlipsController < ApplicationController
|
||||
raise BlipTooOld if blip.created_at < 5.minutes.ago && !CurrentUser.is_admin?
|
||||
raise User::PrivilegeError unless blip.can_edit?(CurrentUser.user)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.blips_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -2,9 +2,10 @@
|
||||
|
||||
class BulkUpdateRequestsController < ApplicationController
|
||||
respond_to :html, :json
|
||||
before_action :member_only, except: [:index, :show]
|
||||
before_action :member_only, except: %i[index show]
|
||||
before_action :admin_only, only: [:approve]
|
||||
before_action :load_bulk_update_request, except: [:new, :create, :index]
|
||||
before_action :load_bulk_update_request, except: %i[new create index]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index show]
|
||||
|
||||
def new
|
||||
@bulk_update_request = BulkUpdateRequest.new
|
||||
@ -74,4 +75,8 @@ class BulkUpdateRequestsController < ApplicationController
|
||||
|
||||
params.require(:bulk_update_request).permit(permitted_params)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.aiburs_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -4,8 +4,9 @@ class CommentVotesController < ApplicationController
|
||||
respond_to :json
|
||||
respond_to :html, only: [:index]
|
||||
before_action :member_only
|
||||
before_action :moderator_only, only: [:index, :lock]
|
||||
before_action :moderator_only, only: %i[index lock]
|
||||
before_action :admin_only, only: [:delete]
|
||||
before_action :ensure_lockdown_disabled
|
||||
skip_before_action :api_check
|
||||
|
||||
def create
|
||||
@ -54,4 +55,8 @@ class CommentVotesController < ApplicationController
|
||||
permitted_params += %i[user_ip_addr duplicates_only order] if CurrentUser.is_admin?
|
||||
permit_search_params permitted_params
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.votes_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -3,8 +3,9 @@
|
||||
class CommentsController < ApplicationController
|
||||
respond_to :html, :json
|
||||
before_action :member_only, except: %i[index search show for_post]
|
||||
before_action :moderator_only, only: [:unhide, :warning]
|
||||
before_action :admin_only, only: [:destroy]
|
||||
before_action :moderator_only, only: %i[unhide warning]
|
||||
before_action :admin_only, only: %i[destroy]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index search show for_post]
|
||||
skip_before_action :api_check
|
||||
|
||||
def index
|
||||
@ -140,4 +141,8 @@ private
|
||||
|
||||
params.fetch(:comment, {}).permit(permitted_params)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.comments_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
class FavoritesController < ApplicationController
|
||||
before_action :member_only, except: [:index]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index]
|
||||
respond_to :html, :json
|
||||
skip_before_action :api_check
|
||||
|
||||
@ -44,4 +45,8 @@ class FavoritesController < ApplicationController
|
||||
rescue Favorite::Error => x
|
||||
render_expected_error(422, x.message)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.favorites_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -7,6 +7,7 @@ class ForumPostVotesController < ApplicationController
|
||||
before_action :validate_forum_post
|
||||
before_action :validate_no_vote_on_own_post, only: [:create]
|
||||
before_action :load_vote, only: [:destroy]
|
||||
before_action :ensure_lockdown_disabled
|
||||
|
||||
def create
|
||||
@forum_post_vote = @forum_post.votes.create(forum_post_vote_params)
|
||||
@ -46,4 +47,8 @@ private
|
||||
def forum_post_vote_params
|
||||
params.fetch(:forum_post_vote, {}).permit(:score)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.votes_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -2,11 +2,12 @@
|
||||
|
||||
class ForumPostsController < ApplicationController
|
||||
respond_to :html, :json
|
||||
before_action :member_only, :except => [:index, :show, :search]
|
||||
before_action :moderator_only, only: [:unhide, :warning]
|
||||
before_action :member_only, except: %i[index show search]
|
||||
before_action :moderator_only, only: %i[unhide warning]
|
||||
before_action :admin_only, only: [:destroy]
|
||||
before_action :load_post, :only => [:edit, :show, :update, :destroy, :hide, :unhide, :warning]
|
||||
before_action :check_min_level, :only => [:edit, :show, :update, :destroy, :hide, :unhide]
|
||||
before_action :load_post, only: %i[edit show update destroy hide unhide warning]
|
||||
before_action :check_min_level, only: %i[edit show update destroy hide unhide]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index show search]
|
||||
skip_before_action :api_check
|
||||
|
||||
def new
|
||||
@ -109,4 +110,8 @@ class ForumPostsController < ApplicationController
|
||||
|
||||
params.fetch(:forum_post, {}).permit(permitted_params)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.forums_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
class ForumTopicsController < ApplicationController
|
||||
respond_to :html, :json
|
||||
before_action :member_only, :except => [:index, :show]
|
||||
before_action :moderator_only, :only => [:unhide]
|
||||
before_action :member_only, except: %i[index show]
|
||||
before_action :moderator_only, only: [:unhide]
|
||||
before_action :admin_only, only: [:destroy]
|
||||
before_action :normalize_search, :only => :index
|
||||
before_action :load_topic, :only => [:edit, :show, :update, :destroy, :hide, :unhide, :subscribe, :unsubscribe]
|
||||
before_action :check_min_level, :only => [:show, :edit, :update, :destroy, :hide, :unhide, :subscribe, :unsubscribe]
|
||||
before_action :normalize_search, only: :index
|
||||
before_action :load_topic, only: %i[edit show update destroy hide unhide subscribe unsubscribe]
|
||||
before_action :check_min_level, only: %i[show edit update destroy hide unhide subscribe unsubscribe]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index show]
|
||||
skip_before_action :api_check
|
||||
|
||||
def new
|
||||
@ -143,4 +144,8 @@ private
|
||||
|
||||
params.fetch(:forum_topic, {}).permit(permitted_params)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.forums_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
class PoolsController < ApplicationController
|
||||
respond_to :html, :json
|
||||
before_action :member_only, :except => [:index, :show, :gallery]
|
||||
before_action :janitor_only, :only => [:destroy]
|
||||
before_action :member_only, except: %i[index show gallery]
|
||||
before_action :janitor_only, only: %i[destroy]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index show gallery]
|
||||
|
||||
def new
|
||||
@pool = Pool.new
|
||||
@ -82,4 +83,8 @@ class PoolsController < ApplicationController
|
||||
permitted_params = %i[name description category is_active post_ids post_ids_string]
|
||||
params.require(:pool).permit(*permitted_params, post_ids: [])
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.pools_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -109,8 +109,6 @@ class PostReplacementsController < ApplicationController
|
||||
end
|
||||
|
||||
def ensure_uploads_enabled
|
||||
if DangerZone.uploads_disabled?(CurrentUser.user)
|
||||
access_denied "Uploads are disabled"
|
||||
end
|
||||
access_denied if Security::Lockdown.uploads_disabled? || CurrentUser.user.level < Security::Lockdown.uploads_min_level
|
||||
end
|
||||
end
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
class PostSetsController < ApplicationController
|
||||
respond_to :html, :json
|
||||
before_action :member_only, except: [:index, :show]
|
||||
before_action :member_only, except: %i[index show]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index show]
|
||||
|
||||
def index
|
||||
if !params[:post_id].blank?
|
||||
@ -161,4 +162,8 @@ class PostSetsController < ApplicationController
|
||||
permitted_params += %i[is_public] if CurrentUser.is_moderator?
|
||||
permit_search_params permitted_params
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.post_sets_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
class PostVotesController < ApplicationController
|
||||
before_action :member_only
|
||||
before_action :moderator_only, only: [:index, :lock]
|
||||
before_action :moderator_only, only: %i[index lock]
|
||||
before_action :admin_only, only: [:delete]
|
||||
before_action :ensure_lockdown_disabled
|
||||
skip_before_action :api_check
|
||||
|
||||
def create
|
||||
@ -51,4 +52,8 @@ class PostVotesController < ApplicationController
|
||||
permitted_params += %i[user_ip_addr duplicates_only order] if CurrentUser.is_admin?
|
||||
permit_search_params permitted_params
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.votes_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -3,6 +3,7 @@
|
||||
class PostsController < ApplicationController
|
||||
before_action :member_only, except: %i[show show_seq index random]
|
||||
before_action :admin_only, only: [:update_iqdb]
|
||||
before_action :ensure_lockdown_disabled, except: %i[index show show_seq random]
|
||||
respond_to :html, :json
|
||||
|
||||
def index
|
||||
@ -26,7 +27,7 @@ class PostsController < ApplicationController
|
||||
def show
|
||||
@post = Post.find(params[:id])
|
||||
|
||||
raise User::PrivilegeError.new("Post unavailable") unless DangerZone.post_visible?(@post, CurrentUser.user)
|
||||
raise User::PrivilegeError, "Post unavailable" unless Security::Lockdown.post_visible?(@post, CurrentUser.user)
|
||||
|
||||
include_deleted = @post.is_deleted? || (@post.parent_id.present? && @post.parent.is_deleted?) || CurrentUser.is_approver?
|
||||
@parent_post_set = PostSets::PostRelationship.new(@post.parent_id, :include_deleted => include_deleted, want_parent: true)
|
||||
@ -164,6 +165,10 @@ class PostsController < ApplicationController
|
||||
raise User::PrivilegeError.new("Updater #{User.throttle_reason(can_edit)}") unless can_edit == true
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.uploads_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
|
||||
def post_params
|
||||
permitted_params = %i[
|
||||
tag_string old_tag_string
|
||||
|
11
app/controllers/security/dashboard_controller.rb
Normal file
11
app/controllers/security/dashboard_controller.rb
Normal file
@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Security
|
||||
class DashboardController < ApplicationController
|
||||
respond_to :html
|
||||
before_action :admin_only
|
||||
|
||||
def index
|
||||
end
|
||||
end
|
||||
end
|
71
app/controllers/security/lockdown_controller.rb
Normal file
71
app/controllers/security/lockdown_controller.rb
Normal file
@ -0,0 +1,71 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Security
|
||||
class LockdownController < ApplicationController
|
||||
before_action :admin_only
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def panic
|
||||
Security::Lockdown.uploads_disabled = "1"
|
||||
Security::Lockdown.pools_disabled = "1"
|
||||
Security::Lockdown.post_sets_disabled = "1"
|
||||
|
||||
Security::Lockdown.comments_disabled = "1"
|
||||
Security::Lockdown.forums_disabled = "1"
|
||||
Security::Lockdown.blips_disabled = "1"
|
||||
|
||||
Security::Lockdown.aiburs_disabled = "1"
|
||||
Security::Lockdown.favorites_disabled = "1"
|
||||
Security::Lockdown.votes_disabled = "1"
|
||||
|
||||
StaffAuditLog.log(:lockdown_panic, CurrentUser.user)
|
||||
redirect_to security_root_path
|
||||
end
|
||||
|
||||
def enact
|
||||
params = lockdown_params
|
||||
|
||||
Security::Lockdown.uploads_disabled = params[:uploads] if params[:uploads].present?
|
||||
Security::Lockdown.pools_disabled = params[:pools] if params[:pools].present?
|
||||
Security::Lockdown.post_sets_disabled = params[:post_sets] if params[:post_sets].present?
|
||||
|
||||
Security::Lockdown.comments_disabled = params[:comments] if params[:comments].present?
|
||||
Security::Lockdown.forums_disabled = params[:forums] if params[:forums].present?
|
||||
Security::Lockdown.blips_disabled = params[:blips] if params[:blips].present?
|
||||
|
||||
Security::Lockdown.aiburs_disabled = params[:aiburs] if params[:aiburs].present?
|
||||
Security::Lockdown.favorites_disabled = params[:favorites] if params[:favorites].present?
|
||||
Security::Lockdown.votes_disabled = params[:votes] if params[:votes].present?
|
||||
|
||||
StaffAuditLog.log(:lockdown_uploads, CurrentUser.user, { params: params })
|
||||
redirect_to security_root_path
|
||||
end
|
||||
|
||||
def uploads_min_level
|
||||
new_level = params[:uploads_min_level][:min_level].to_i
|
||||
raise ArgumentError, "#{new_level} is not valid" unless User.level_hash.values.include? new_level
|
||||
if new_level != Lockdown.uploads_min_level
|
||||
Security::Lockdown.uploads_min_level = new_level
|
||||
StaffAuditLog.log(:min_upload_level, CurrentUser.user, { level: new_level })
|
||||
end
|
||||
redirect_to security_root_path
|
||||
end
|
||||
|
||||
def uploads_hide_pending
|
||||
duration = params[:uploads_hide_pending][:duration].to_f
|
||||
if duration >= 0 && duration != Security::Lockdown.hide_pending_posts_for
|
||||
Security::Lockdown.hide_pending_posts_for = duration
|
||||
StaffAuditLog.log(:hide_pending_posts_for, CurrentUser.user, { duration: duration })
|
||||
end
|
||||
redirect_to security_root_path
|
||||
end
|
||||
|
||||
def lockdown_params
|
||||
permitted_params = %i[uploads pools post_sets comments forums blips aiburs favorites votes]
|
||||
|
||||
params.fetch(:lockdown, {}).permit(permitted_params)
|
||||
end
|
||||
end
|
||||
end
|
@ -2,6 +2,7 @@
|
||||
|
||||
class TagAliasRequestsController < ApplicationController
|
||||
before_action :member_only
|
||||
before_action :ensure_lockdown_disabled
|
||||
|
||||
def new
|
||||
end
|
||||
@ -19,11 +20,15 @@ class TagAliasRequestsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def tar_params
|
||||
permitted = %i{antecedent_name consequent_name reason}
|
||||
permitted = %i[antecedent_name consequent_name reason]
|
||||
permitted += [:skip_forum] if CurrentUser.is_admin?
|
||||
params.require(:tag_alias_request).permit(permitted)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.aiburs_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
class TagImplicationRequestsController < ApplicationController
|
||||
before_action :member_only
|
||||
before_action :ensure_lockdown_disabled
|
||||
|
||||
def new
|
||||
end
|
||||
@ -19,11 +20,15 @@ class TagImplicationRequestsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def tir_params
|
||||
permitted = %i{antecedent_name consequent_name reason}
|
||||
permitted = %i[antecedent_name consequent_name reason]
|
||||
permitted += [:skip_forum] if CurrentUser.is_admin?
|
||||
params.require(:tag_implication_request).permit(permitted)
|
||||
end
|
||||
|
||||
def ensure_lockdown_disabled
|
||||
access_denied if Security::Lockdown.aiburs_disabled? && !CurrentUser.is_staff?
|
||||
end
|
||||
end
|
||||
|
@ -3,7 +3,7 @@
|
||||
class UploadsController < ApplicationController
|
||||
before_action :member_only
|
||||
before_action :janitor_only, only: [:index, :show]
|
||||
before_action :ensure_uploads_enabled, only: [:new, :create]
|
||||
before_action :ensure_uploads_enabled, only: %i[new create]
|
||||
respond_to :html, :json
|
||||
content_security_policy only: [:new] do |p|
|
||||
p.img_src :self, :data, :blob, "*"
|
||||
@ -82,8 +82,6 @@ class UploadsController < ApplicationController
|
||||
end
|
||||
|
||||
def ensure_uploads_enabled
|
||||
if DangerZone.uploads_disabled?(CurrentUser.user)
|
||||
access_denied "Uploads are disabled"
|
||||
end
|
||||
access_denied if Security::Lockdown.uploads_disabled? || CurrentUser.user.level < Security::Lockdown.uploads_min_level
|
||||
end
|
||||
end
|
||||
|
@ -53,6 +53,7 @@
|
||||
@import "specific/guest_warning.scss";
|
||||
@import "specific/iqdb_queries.scss";
|
||||
@import "specific/keyboard_shortcuts.scss";
|
||||
@import "specific/lockdown.scss";
|
||||
@import "specific/maintenance.scss";
|
||||
@import "specific/meta_searches.scss";
|
||||
@import "specific/moderator_dashboard.scss";
|
||||
|
23
app/javascript/src/styles/specific/lockdown.scss
Normal file
23
app/javascript/src/styles/specific/lockdown.scss
Normal file
@ -0,0 +1,23 @@
|
||||
.settings-section {
|
||||
background-color: themed("color-section");
|
||||
border-radius: $border-radius-half;
|
||||
padding: 0.5em 0.75em;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
.simple_form {
|
||||
background-color: unset !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
form.lockdown-form {
|
||||
div.input {
|
||||
display: flex;
|
||||
gap: 0.75em;
|
||||
margin-bottom: 0.25em;
|
||||
|
||||
input[type="checkbox"] {
|
||||
order: -1;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module DangerZone
|
||||
def self.uploads_disabled?(user)
|
||||
user.level < min_upload_level
|
||||
end
|
||||
|
||||
def self.post_visible?(post, user)
|
||||
if hide_pending_posts_for <= 0
|
||||
return true
|
||||
end
|
||||
|
||||
post.uploader_id == user.id || user.is_staff? || !post.is_pending? || post.created_at.before?(hide_pending_posts_for.hours.ago)
|
||||
end
|
||||
|
||||
def self.min_upload_level
|
||||
(Cache.redis.get("min_upload_level") || User::Levels::MEMBER).to_i
|
||||
rescue Redis::CannotConnectError
|
||||
User::Levels::ADMIN + 1
|
||||
end
|
||||
|
||||
def self.min_upload_level=(min_upload_level)
|
||||
Cache.redis.set("min_upload_level", min_upload_level)
|
||||
end
|
||||
|
||||
def self.hide_pending_posts_for
|
||||
Cache.redis.get("hide_pending_posts_for").to_f || 0
|
||||
rescue Redis::CannotConnectError
|
||||
PostPruner::DELETION_WINDOW * 24
|
||||
end
|
||||
|
||||
def self.hide_pending_posts_for=(duration)
|
||||
Cache.redis.set("hide_pending_posts_for", duration)
|
||||
end
|
||||
end
|
@ -315,12 +315,12 @@ class ElasticPostQueryBuilder < ElasticQueryBuilder
|
||||
order.push({id: :desc})
|
||||
end
|
||||
|
||||
if !CurrentUser.user.is_staff? && DangerZone.hide_pending_posts_for > 0
|
||||
if !CurrentUser.user.is_staff? && Security::Lockdown.hide_pending_posts_for > 0
|
||||
should = [
|
||||
{
|
||||
range: {
|
||||
created_at: {
|
||||
lte: DangerZone.hide_pending_posts_for.hours.ago,
|
||||
lte: Security::Lockdown.hide_pending_posts_for.hours.ago,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
126
app/logical/security/lockdown.rb
Normal file
126
app/logical/security/lockdown.rb
Normal file
@ -0,0 +1,126 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Security
|
||||
module Lockdown
|
||||
# Panic
|
||||
def self.uploads_disabled?
|
||||
Cache.redis.get("uploads_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.uploads_disabled=(state)
|
||||
Cache.redis.set("uploads_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.pools_disabled?
|
||||
Cache.redis.get("pools_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.pools_disabled=(state)
|
||||
Cache.redis.set("pools_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.post_sets_disabled?
|
||||
Cache.redis.get("post_sets_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.post_sets_disabled=(state)
|
||||
Cache.redis.set("post_sets_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.comments_disabled?
|
||||
Cache.redis.get("comments_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.comments_disabled=(state)
|
||||
Cache.redis.set("comments_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.forums_disabled?
|
||||
Cache.redis.get("forums_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.forums_disabled=(state)
|
||||
Cache.redis.set("forums_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.blips_disabled?
|
||||
Cache.redis.get("blips_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.blips_disabled=(state)
|
||||
Cache.redis.set("blips_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.aiburs_disabled?
|
||||
Cache.redis.get("aiburs_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.aiburs_disabled=(state)
|
||||
Cache.redis.set("aiburs_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.favorites_disabled?
|
||||
Cache.redis.get("favorites_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.favorites_disabled=(state)
|
||||
Cache.redis.set("favorites_disabled", state == "1")
|
||||
end
|
||||
|
||||
def self.votes_disabled?
|
||||
Cache.redis.get("votes_disabled") == "true"
|
||||
rescue Redis::CannotConnectError
|
||||
true
|
||||
end
|
||||
|
||||
def self.votes_disabled=(state)
|
||||
Cache.redis.set("votes_disabled", state == "1")
|
||||
end
|
||||
|
||||
# Uploader level override
|
||||
def self.uploads_min_level
|
||||
(Cache.redis.get("min_upload_level") || User::Levels::MEMBER).to_i
|
||||
rescue Redis::CannotConnectError
|
||||
User::Levels::ADMIN + 1
|
||||
end
|
||||
|
||||
def self.uploads_min_level=(min_upload_level)
|
||||
Cache.redis.set("min_upload_level", min_upload_level)
|
||||
end
|
||||
|
||||
# Hiding pending posts
|
||||
def self.hide_pending_posts_for
|
||||
Cache.redis.get("hide_pending_posts_for").to_f || 0
|
||||
rescue Redis::CannotConnectError
|
||||
PostPruner::DELETION_WINDOW * 24
|
||||
end
|
||||
|
||||
def self.hide_pending_posts_for=(duration)
|
||||
Cache.redis.set("hide_pending_posts_for", duration)
|
||||
end
|
||||
|
||||
def self.post_visible?(post, user)
|
||||
if hide_pending_posts_for <= 0
|
||||
return true
|
||||
end
|
||||
|
||||
post.uploader_id == user.id || user.is_staff? || !post.is_pending? || post.created_at.before?(hide_pending_posts_for.hours.ago)
|
||||
end
|
||||
end
|
||||
end
|
@ -1,25 +0,0 @@
|
||||
<div id="c-danger-zone">
|
||||
<div id="a-index">
|
||||
<h1>Danger Zone</h1>
|
||||
<h2>Uploads</h2>
|
||||
Uploads are currently permitted for <b><%= User.level_string(DangerZone.min_upload_level) %></b> and up.
|
||||
<%= custom_form_for(:uploading_limits, url: uploading_limits_admin_danger_zone_index_path, method: :put) do |f| %>
|
||||
<%= f.input :min_level, collection: User.level_hash.select {|k,v| v >= User::Levels::MEMBER }.to_a, selected: DangerZone.min_upload_level %>
|
||||
<%= f.button :submit, value: "Submit" %>
|
||||
<% end %>
|
||||
<h2>Pending Posts</h2>
|
||||
<% if DangerZone.hide_pending_posts_for > 0 %>
|
||||
Unapproved posts are currently only visible to staff for <b><%= DangerZone.hide_pending_posts_for %></b> hours.
|
||||
<% else %>
|
||||
Unapproved posts are currently not hidden.
|
||||
<% end %>
|
||||
<%= custom_form_for(:hide_pending_posts, url: hide_pending_posts_admin_danger_zone_index_path, method: :put) do |f| %>
|
||||
<%= f.input :duration, as: :float, hint: "in hours", input_html: { value: DangerZone.hide_pending_posts_for } %>
|
||||
<%= f.button :submit, value: "Submit" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% content_for(:page_title) do %>
|
||||
Danger Zone
|
||||
<% end %>
|
53
app/views/security/dashboard/index.html.erb
Normal file
53
app/views/security/dashboard/index.html.erb
Normal file
@ -0,0 +1,53 @@
|
||||
<div id="c-security">
|
||||
<div id="a-index">
|
||||
|
||||
<h1>Security</h1>
|
||||
|
||||
<section class="settings-section">
|
||||
<h2>Lockdown</h2>
|
||||
<%= custom_form_for(:panic, url: panic_security_lockdown_index_path, method: :put, html: { class: "lockdown-form" }) do |f| %>
|
||||
<%= f.button :submit, value: "Enable Read-Only Mode" %>
|
||||
<% end %>
|
||||
|
||||
<%= custom_form_for(:lockdown, url: enact_security_lockdown_index_path, method: :put, html: { class: "lockdown-form" }) do |f| %>
|
||||
<%= f.input :uploads, as: :boolean, label: "Uploads", input_html: { checked: Security::Lockdown.uploads_disabled? ? "checked" : "" } %>
|
||||
<%= f.input :pools, as: :boolean, label: "Pools", input_html: { checked: Security::Lockdown.pools_disabled? ? "checked" : "" } %>
|
||||
<%= f.input :post_sets, as: :boolean, label: "Post Sets", input_html: { checked: Security::Lockdown.post_sets_disabled? ? "checked" : "" } %>
|
||||
<br />
|
||||
<%= f.input :comments, as: :boolean, label: "Comments", input_html: { checked: Security::Lockdown.comments_disabled? ? "checked" : "" } %>
|
||||
<%= f.input :forums, as: :boolean, label: "Forums", input_html: { checked: Security::Lockdown.forums_disabled? ? "checked" : "" } %>
|
||||
<%= f.input :blips, as: :boolean, label: "Blips", input_html: { checked: Security::Lockdown.blips_disabled? ? "checked" : "" } %>
|
||||
<br />
|
||||
<%= f.input :aiburs, as: :boolean, label: "AIBURs", input_html: { checked: Security::Lockdown.aiburs_disabled? ? "checked" : "" } %>
|
||||
<%= f.input :favorites, as: :boolean, label: "Favorites", input_html: { checked: Security::Lockdown.favorites_disabled? ? "checked" : "" } %>
|
||||
<%= f.input :votes, as: :boolean, label: "Votes", input_html: { checked: Security::Lockdown.votes_disabled? ? "checked" : "" } %>
|
||||
<br />
|
||||
<%= f.button :submit, value: "Submit" %>
|
||||
<% end %>
|
||||
</section>
|
||||
|
||||
<section class="settings-section">
|
||||
<h2>Uploads</h2>
|
||||
Uploads are currently permitted for <b><%= User.level_string(Security::Lockdown.uploads_min_level) %></b> and up.
|
||||
<%= custom_form_for(:uploads_min_level, url: uploads_min_level_security_lockdown_index_path, method: :put) do |f| %>
|
||||
<%= f.input :min_level, collection: User.level_hash.select { |_k, v| v >= User::Levels::MEMBER }.to_a, selected: Security::Lockdown.uploads_min_level %>
|
||||
<%= f.button :submit, value: "Submit" %>
|
||||
<% end %>
|
||||
|
||||
<h2>Pending Posts</h2>
|
||||
<% if Security::Lockdown.hide_pending_posts_for > 0 %>
|
||||
Unapproved posts are currently only visible to staff for <b><%= Security::Lockdown.hide_pending_posts_for %></b> hours.
|
||||
<% else %>
|
||||
Unapproved posts are currently not hidden.
|
||||
<% end %>
|
||||
<%= custom_form_for(:uploads_hide_pending, url: uploads_hide_pending_security_lockdown_index_path, method: :put) do |f| %>
|
||||
<%= f.input :duration, as: :float, hint: "in hours", input_html: { value: Security::Lockdown.hide_pending_posts_for } %>
|
||||
<%= f.button :submit, value: "Submit" %>
|
||||
<% end %>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% content_for(:page_title) do %>
|
||||
Security
|
||||
<% end %>
|
@ -113,7 +113,7 @@
|
||||
<li><%= link_to("Admin Dashboard", admin_dashboard_path) %></li>
|
||||
<li><%= link_to("Email Blacklist", email_blacklists_path) %></li>
|
||||
<li><%= link_to("Post Report Reasons", post_report_reasons_path) %></li>
|
||||
<li><%= link_to("Danger Zone", admin_danger_zone_index_path) %></li>
|
||||
<li><%= link_to("Security", security_root_path) %></li>
|
||||
<li><%= link_to("IP Bans", ip_bans_path) %></li>
|
||||
<li><%= link_to("Alt list", alt_list_admin_users_path) %></li>
|
||||
<li><%= link_to("Stuck DNP tags", new_admin_stuck_dnp_path) %></li>
|
||||
|
@ -26,13 +26,21 @@ Rails.application.routes.draw do
|
||||
resource :stuck_dnp, controller: "stuck_dnp", only: %i[new create]
|
||||
resources :destroyed_posts, only: %i[index show update]
|
||||
resources :staff_notes, only: [:index]
|
||||
resources :danger_zone, only: [:index] do
|
||||
end
|
||||
|
||||
namespace :security do
|
||||
root to: "dashboard#index"
|
||||
resource :dashboard, only: [:index]
|
||||
resources :lockdown, only: [:index] do
|
||||
collection do
|
||||
put :uploading_limits
|
||||
put :hide_pending_posts
|
||||
put :panic
|
||||
put :enact
|
||||
put :uploads_min_level
|
||||
put :uploads_hide_pending
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
resources :edit_histories
|
||||
namespace :moderator do
|
||||
resource :dashboard, :only => [:show]
|
||||
|
@ -1,37 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "test_helper"
|
||||
|
||||
class Admin::DangerZoneControllerTest < ActionDispatch::IntegrationTest
|
||||
context "The danger zone controller" do
|
||||
setup do
|
||||
@admin = create(:admin_user)
|
||||
end
|
||||
|
||||
teardown do
|
||||
DangerZone.min_upload_level = User::Levels::MEMBER
|
||||
DangerZone.hide_pending_posts_for = 0
|
||||
end
|
||||
|
||||
context "index action" do
|
||||
should "render" do
|
||||
get_auth admin_danger_zone_index_path, @admin
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
context "uploading limits action" do
|
||||
should "work" do
|
||||
put_auth uploading_limits_admin_danger_zone_index_path, @admin, params: { uploading_limits: { min_level: User::Levels::PRIVILEGED } }
|
||||
assert_equal DangerZone.min_upload_level, User::Levels::PRIVILEGED
|
||||
end
|
||||
end
|
||||
|
||||
context "hide pending posts action" do
|
||||
should "work" do
|
||||
put_auth hide_pending_posts_admin_danger_zone_index_path, @admin, params: { hide_pending_posts: { duration: 24 } }
|
||||
assert_equal DangerZone.hide_pending_posts_for, 24
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
39
test/functional/security/lockdown_controller_test.rb
Normal file
39
test/functional/security/lockdown_controller_test.rb
Normal file
@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "test_helper"
|
||||
|
||||
module Security
|
||||
class LockdownControllerTest < ActionDispatch::IntegrationTest
|
||||
context "The lockdown controller" do
|
||||
setup do
|
||||
@admin = create(:admin_user)
|
||||
end
|
||||
|
||||
teardown do
|
||||
Security::Lockdown.uploads_min_level = User::Levels::MEMBER
|
||||
Security::Lockdown.hide_pending_posts_for = 0
|
||||
end
|
||||
|
||||
context "index action" do
|
||||
should "render" do
|
||||
get_auth security_root_path, @admin
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
context "uploading limits action" do
|
||||
should "work" do
|
||||
put_auth uploads_min_level_security_lockdown_index_path, @admin, params: { uploads_min_level: { min_level: User::Levels::PRIVILEGED } }
|
||||
assert_equal Security::Lockdown.uploads_min_level, User::Levels::PRIVILEGED
|
||||
end
|
||||
end
|
||||
|
||||
context "hide pending posts action" do
|
||||
should "work" do
|
||||
put_auth uploads_hide_pending_security_lockdown_index_path, @admin, params: { uploads_hide_pending: { duration: 24 } }
|
||||
assert_equal Security::Lockdown.hide_pending_posts_for, 24
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -43,11 +43,11 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
context "when uploads are disabled" do
|
||||
setup do
|
||||
DangerZone.min_upload_level = User::Levels::PRIVILEGED
|
||||
Security::Lockdown.uploads_min_level = User::Levels::PRIVILEGED
|
||||
end
|
||||
|
||||
teardown do
|
||||
DangerZone.min_upload_level = User::Levels::MEMBER
|
||||
Security::Lockdown.uploads_min_level = User::Levels::MEMBER
|
||||
end
|
||||
|
||||
should "prevent uploads" do
|
||||
|
Loading…
Reference in New Issue
Block a user