summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorTakeshi Umeda <noel.yoshiba@gmail.com>2020-11-05 04:45:01 +0900
committerGitHub <noreply@github.com>2020-11-04 20:45:01 +0100
commitd6fe0c94ca48a10d579cf5ec321c33c6124b402d (patch)
tree72d8e135bf9642a6115eb244490256d610a007f8 /app
parentf90620b2f3bb92104c8878140aa00651a255a647 (diff)
Add account sensitized (#14361)
* Add account sensitized * Fix i18n normalize * Fix description and spec * Fix spec * Fix wording
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin/accounts_controller.rb7
-rw-r--r--app/controllers/api/v1/admin/accounts_controller.rb8
-rw-r--r--app/helpers/statuses_helper.rb8
-rw-r--r--app/lib/activitypub/activity/create.rb2
-rw-r--r--app/models/account.rb14
-rw-r--r--app/models/account_warning.rb2
-rw-r--r--app/models/admin/account_action.rb9
-rw-r--r--app/models/admin/action_log_filter.rb2
-rw-r--r--app/policies/account_policy.rb8
-rw-r--r--app/serializers/activitypub/note_serializer.rb4
-rw-r--r--app/serializers/rest/status_serializer.rb8
-rw-r--r--app/views/admin/accounts/show.html.haml7
-rw-r--r--app/views/statuses/_detailed_status.html.haml6
-rw-r--r--app/views/statuses/_simple_status.html.haml6
14 files changed, 83 insertions, 8 deletions
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
index b9b75727dd9..1dd7430e098 100644
--- a/app/controllers/admin/accounts_controller.rb
+++ b/app/controllers/admin/accounts_controller.rb
@@ -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!
diff --git a/app/controllers/api/v1/admin/accounts_controller.rb b/app/controllers/api/v1/admin/accounts_controller.rb
index 3af572f25ef..63cc521ed01 100644
--- a/app/controllers/api/v1/admin/accounts_controller.rb
+++ b/app/controllers/api/v1/admin/accounts_controller.rb
@@ -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!
diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb
index a51597cf353..adb7918c53f 100644
--- a/app/helpers/statuses_helper.rb
+++ b/app/helpers/statuses_helper.rb
@@ -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)
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index f275feefc50..c77f237f9a7 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -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']),
diff --git a/app/models/account.rb b/app/models/account.rb
index 59d338f5af1..d2112a13df6 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -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
diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb
index 157e6c04d1e..5efc924d5f7 100644
--- a/app/models/account_warning.rb
+++ b/app/models/account_warning.rb
@@ -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
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
index c4ac09520ef..11ce737f3e0 100644
--- a/app/models/admin/account_action.rb
+++ b/app/models/admin/account_action.rb
@@ -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)
diff --git a/app/models/admin/action_log_filter.rb b/app/models/admin/action_log_filter.rb
index 0ba7e160944..3a1b67e0675 100644
--- a/app/models/admin/action_log_filter.rb
+++ b/app/models/admin/action_log_filter.rb
@@ -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,
diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb
index 1b105e92aa8..679119075e1 100644
--- a/app/policies/account_policy.rb
+++ b/app/policies/account_policy.rb
@@ -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
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index f26fd93a424..6f9e1ca6391 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -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
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index 0109de882bd..bb6df90b7a6 100644
--- a/app/serializers/rest/status_serializer.rb
+++ b/app/serializers/rest/status_serializer.rb
@@ -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
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index f0a216f6b8f..d5978eddd64 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -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?
diff --git a/app/views/statuses/_detailed_status.html.haml b/app/views/statuses/_detailed_status.html.haml
index b3e9c44fc8b..a4dd8534fa5 100644
--- a/app/views/statuses/_detailed_status.html.haml
+++ b/app/views/statuses/_detailed_status.html.haml
@@ -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 }
diff --git a/app/views/statuses/_simple_status.html.haml b/app/views/statuses/_simple_status.html.haml
index 7408749cca3..1921927005f 100644
--- a/app/views/statuses/_simple_status.html.haml
+++ b/app/views/statuses/_simple_status.html.haml
@@ -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