Add account sensitized (#14361)
* Add account sensitized * Fix i18n normalize * Fix description and spec * Fix spec * Fix wording
This commit is contained in:
parent
f90620b2f3
commit
d6fe0c94ca
24 changed files with 136 additions and 13 deletions
|
@ -53,6 +53,13 @@ module Admin
|
|||
redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.destroyed_msg', username: @account.acct)
|
||||
end
|
||||
|
||||
def unsensitive
|
||||
authorize @account, :unsensitive?
|
||||
@account.unsensitize!
|
||||
log_action :unsensitive, @account
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def unsilence
|
||||
authorize @account, :unsilence?
|
||||
@account.unsilence!
|
||||
|
|
|
@ -22,6 +22,7 @@ class Api::V1::Admin::AccountsController < Api::BaseController
|
|||
active
|
||||
pending
|
||||
disabled
|
||||
sensitized
|
||||
silenced
|
||||
suspended
|
||||
username
|
||||
|
@ -68,6 +69,13 @@ class Api::V1::Admin::AccountsController < Api::BaseController
|
|||
render json: @account, serializer: REST::Admin::AccountSerializer
|
||||
end
|
||||
|
||||
def unsensitive
|
||||
authorize @account, :unsensitive?
|
||||
@account.unsensitize!
|
||||
log_action :unsensitive, @account
|
||||
render json: @account, serializer: REST::Admin::AccountSerializer
|
||||
end
|
||||
|
||||
def unsilence
|
||||
authorize @account, :unsilence?
|
||||
@account.unsilence!
|
||||
|
|
|
@ -117,6 +117,14 @@ module StatusesHelper
|
|||
end
|
||||
end
|
||||
|
||||
def sensitized?(status, account)
|
||||
if !account.nil? && account.id == status.account_id
|
||||
status.sensitive
|
||||
else
|
||||
status.account.sensitized? || status.sensitive
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def simplified_text(text)
|
||||
|
|
|
@ -111,7 +111,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
created_at: @object['published'],
|
||||
override_timestamps: @options[:override_timestamps],
|
||||
reply: @object['inReplyTo'].present?,
|
||||
sensitive: @object['sensitive'] || false,
|
||||
sensitive: @account.sensitized? || @object['sensitive'] || false,
|
||||
visibility: visibility_from_audience,
|
||||
thread: replied_to_status,
|
||||
conversation: conversation_from_uri(@object['conversation']),
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
# avatar_storage_schema_version :integer
|
||||
# header_storage_schema_version :integer
|
||||
# devices_url :string
|
||||
# sensitized_at :datetime
|
||||
#
|
||||
|
||||
class Account < ApplicationRecord
|
||||
|
@ -92,6 +93,7 @@ class Account < ApplicationRecord
|
|||
scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) }
|
||||
scope :silenced, -> { where.not(silenced_at: nil) }
|
||||
scope :suspended, -> { where.not(suspended_at: nil) }
|
||||
scope :sensitized, -> { where.not(sensitized_at: nil) }
|
||||
scope :without_suspended, -> { where(suspended_at: nil) }
|
||||
scope :without_silenced, -> { where(silenced_at: nil) }
|
||||
scope :recent, -> { reorder(id: :desc) }
|
||||
|
@ -234,6 +236,18 @@ class Account < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def sensitized?
|
||||
sensitized_at.present?
|
||||
end
|
||||
|
||||
def sensitize!(date = Time.now.utc)
|
||||
update!(sensitized_at: date)
|
||||
end
|
||||
|
||||
def unsensitize!
|
||||
update!(sensitized_at: nil)
|
||||
end
|
||||
|
||||
def memorialize!
|
||||
update!(memorial: true)
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#
|
||||
|
||||
class AccountWarning < ApplicationRecord
|
||||
enum action: %i(none disable silence suspend), _suffix: :action
|
||||
enum action: %i(none disable sensitive silence suspend), _suffix: :action
|
||||
|
||||
belongs_to :account, inverse_of: :account_warnings
|
||||
belongs_to :target_account, class_name: 'Account', inverse_of: :targeted_account_warnings
|
||||
|
|
|
@ -8,6 +8,7 @@ class Admin::AccountAction
|
|||
TYPES = %w(
|
||||
none
|
||||
disable
|
||||
sensitive
|
||||
silence
|
||||
suspend
|
||||
).freeze
|
||||
|
@ -64,6 +65,8 @@ class Admin::AccountAction
|
|||
case type
|
||||
when 'disable'
|
||||
handle_disable!
|
||||
when 'sensitive'
|
||||
handle_sensitive!
|
||||
when 'silence'
|
||||
handle_silence!
|
||||
when 'suspend'
|
||||
|
@ -109,6 +112,12 @@ class Admin::AccountAction
|
|||
target_account.user&.disable!
|
||||
end
|
||||
|
||||
def handle_sensitive!
|
||||
authorize(target_account, :sensitive?)
|
||||
log_action(:sensitive, target_account)
|
||||
target_account.sensitize!
|
||||
end
|
||||
|
||||
def handle_silence!
|
||||
authorize(target_account, :silence?)
|
||||
log_action(:silence, target_account)
|
||||
|
|
|
@ -35,9 +35,11 @@ class Admin::ActionLogFilter
|
|||
reopen_report: { target_type: 'Report', action: 'reopen' }.freeze,
|
||||
reset_password_user: { target_type: 'User', action: 'reset_password' }.freeze,
|
||||
resolve_report: { target_type: 'Report', action: 'resolve' }.freeze,
|
||||
sensitive_account: { target_type: 'Account', action: 'sensitive' }.freeze,
|
||||
silence_account: { target_type: 'Account', action: 'silence' }.freeze,
|
||||
suspend_account: { target_type: 'Account', action: 'suspend' }.freeze,
|
||||
unassigned_report: { target_type: 'Report', action: 'unassigned' }.freeze,
|
||||
unsensitive_account: { target_type: 'Account', action: 'unsensitive' }.freeze,
|
||||
unsilence_account: { target_type: 'Account', action: 'unsilence' }.freeze,
|
||||
unsuspend_account: { target_type: 'Account', action: 'unsuspend' }.freeze,
|
||||
update_announcement: { target_type: 'Announcement', action: 'update' }.freeze,
|
||||
|
|
|
@ -25,6 +25,14 @@ class AccountPolicy < ApplicationPolicy
|
|||
staff?
|
||||
end
|
||||
|
||||
def sensitive?
|
||||
staff? && !record.user&.staff?
|
||||
end
|
||||
|
||||
def unsensitive?
|
||||
staff?
|
||||
end
|
||||
|
||||
def silence?
|
||||
staff? && !record.user&.staff?
|
||||
end
|
||||
|
|
|
@ -95,6 +95,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
|||
ActivityPub::TagManager.instance.cc(object)
|
||||
end
|
||||
|
||||
def sensitive
|
||||
object.account.sensitized? || object.sensitive
|
||||
end
|
||||
|
||||
def virtual_tags
|
||||
object.active_mentions.to_a.sort_by(&:id) + object.tags + object.emojis
|
||||
end
|
||||
|
|
|
@ -58,6 +58,14 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||
end
|
||||
end
|
||||
|
||||
def sensitive
|
||||
if current_user? && current_user.account_id == object.account_id
|
||||
object.sensitive
|
||||
else
|
||||
object.account.sensitized? || object.sensitive
|
||||
end
|
||||
end
|
||||
|
||||
def uri
|
||||
ActivityPub::TagManager.instance.uri_for(object)
|
||||
end
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
= t('admin.accounts.confirming')
|
||||
- elsif @account.local? && !@account.user_approved?
|
||||
= t('admin.accounts.pending')
|
||||
- elsif @account.sensitized?
|
||||
= t('admin.accounts.sensitive')
|
||||
- else
|
||||
= t('admin.accounts.no_limits_imposed')
|
||||
.dashboard__counters__label= t 'admin.accounts.login_status'
|
||||
|
@ -192,6 +194,11 @@
|
|||
- else
|
||||
= link_to t('admin.accounts.disable'), new_admin_account_action_path(@account.id, type: 'disable'), class: 'button' if can?(:disable, @account.user)
|
||||
|
||||
- if @account.sensitized?
|
||||
= link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsensitive, @account)
|
||||
- elsif !@account.local? || @account.user_approved?
|
||||
= link_to t('admin.accounts.sensitive'), new_admin_account_action_path(@account.id, type: 'sensitive'), class: 'button' if can?(:sensitive, @account)
|
||||
|
||||
- if @account.silenced?
|
||||
= link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsilence, @account)
|
||||
- elsif !@account.local? || @account.user_approved?
|
||||
|
|
|
@ -29,17 +29,17 @@
|
|||
- if !status.media_attachments.empty?
|
||||
- if status.media_attachments.first.video?
|
||||
- video = status.media_attachments.first
|
||||
= react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: status.sensitive?, width: 670, height: 380, detailed: true, inline: true, alt: video.description do
|
||||
= react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: sensitized?(status, current_account), width: 670, height: 380, detailed: true, inline: true, alt: video.description do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- elsif status.media_attachments.first.audio?
|
||||
- audio = status.media_attachments.first
|
||||
= react_component :audio, src: full_asset_url(audio.file.url(:original)), poster: full_asset_url(audio.thumbnail.present? ? audio.thumbnail.url : status.account.avatar_static_url), backgroundColor: audio.file.meta.dig('colors', 'background'), foregroundColor: audio.file.meta.dig('colors', 'foreground'), accentColor: audio.file.meta.dig('colors', 'accent'), width: 670, height: 380, alt: audio.description, duration: audio.file.meta.dig('original', 'duration') do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- else
|
||||
= react_component :media_gallery, height: 380, sensitive: status.sensitive?, standalone: true, autoplay: autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
|
||||
= react_component :media_gallery, height: 380, sensitive: sensitized?(status, current_account), standalone: true, autoplay: autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- elsif status.preview_card
|
||||
= react_component :card, sensitive: status.sensitive?, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json
|
||||
= react_component :card, sensitive: sensitized?(status, current_account), 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json
|
||||
|
||||
.detailed-status__meta
|
||||
%data.dt-published{ value: status.created_at.to_time.iso8601 }
|
||||
|
|
|
@ -35,17 +35,17 @@
|
|||
- if !status.media_attachments.empty?
|
||||
- if status.media_attachments.first.video?
|
||||
- video = status.media_attachments.first
|
||||
= react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: status.sensitive?, width: 610, height: 343, inline: true, alt: video.description do
|
||||
= react_component :video, src: full_asset_url(video.file.url(:original)), preview: full_asset_url(video.thumbnail.present? ? video.thumbnail.url : video.file.url(:small)), blurhash: video.blurhash, sensitive: sensitized?(status, current_account), width: 610, height: 343, inline: true, alt: video.description do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- elsif status.media_attachments.first.audio?
|
||||
- audio = status.media_attachments.first
|
||||
= react_component :audio, src: full_asset_url(audio.file.url(:original)), poster: full_asset_url(audio.thumbnail.present? ? audio.thumbnail.url : status.account.avatar_static_url), backgroundColor: audio.file.meta.dig('colors', 'background'), foregroundColor: audio.file.meta.dig('colors', 'foreground'), accentColor: audio.file.meta.dig('colors', 'accent'), width: 610, height: 343, alt: audio.description, duration: audio.file.meta.dig('original', 'duration') do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- else
|
||||
= react_component :media_gallery, height: 343, sensitive: status.sensitive?, autoplay: autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
|
||||
= react_component :media_gallery, height: 343, sensitive: sensitized?(status, current_account), autoplay: autoplay, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } do
|
||||
= render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
- elsif status.preview_card
|
||||
= react_component :card, sensitive: status.sensitive?, 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json
|
||||
= react_component :card, sensitive: sensitized?(status, current_account), 'maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_card, serializer: REST::PreviewCardSerializer).as_json
|
||||
|
||||
- if !status.in_reply_to_id.nil? && status.in_reply_to_account_id == status.account.id
|
||||
= link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__content__read-more-button', target: stream_link_target, rel: 'noopener noreferrer' do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue