Skip to content

Commit

Permalink
Add push subscription block feature
Browse files Browse the repository at this point in the history
  • Loading branch information
noellabo authored and atsu1125 committed Mar 13, 2023
1 parent 9867a28 commit 07dfad6
Show file tree
Hide file tree
Showing 19 changed files with 283 additions and 3 deletions.
72 changes: 72 additions & 0 deletions app/controllers/admin/push_subscription_blocks_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true

module Admin
class PushSubscriptionBlocksController < BaseController
before_action :set_push_subscription_block, except: [:index, :new, :create]

def index
authorize :push_subscription_block, :update?
@push_subscription_blocks = PushSubscriptionBlock.all
end

def new
authorize :push_subscription_block, :update?
@push_subscription_block = PushSubscriptionBlock.new
end

def create
authorize :push_subscription_block, :update?

@push_subscription_block = PushSubscriptionBlock.new(resource_params)

if @push_subscription_block.save
@push_subscription_block.enable!
redirect_to admin_push_subscription_blocks_path
else
render action: :new
end
end

def edit
authorize :push_subscription_block, :update?
end

def update
authorize :push_subscription_block, :update?

if @push_subscription_block.update(resource_params)
redirect_to admin_push_subscription_blocks_path
else
render action: :edit
end
end

def destroy
authorize :push_subscription_block, :update?
@push_subscription_block.destroy
redirect_to admin_push_subscription_blocks_path
end

def enable
authorize :push_subscription_block, :update?
@push_subscription_block.enable!
redirect_to admin_push_subscription_blocks_path
end

def disable
authorize :push_subscription_block, :update?
@push_subscription_block.disable!
redirect_to admin_push_subscription_blocks_path
end

private

def set_push_subscription_block
@push_subscription_block = PushSubscriptionBlock.find(params[:id])
end

def resource_params
params.require(:push_subscription_block).permit(:name, :endpoint)
end
end
end
5 changes: 5 additions & 0 deletions app/javascript/styles/mastodon/tables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
}
}

th.wrap,
td.wrap {
overflow-wrap: anywhere;
}

&.inline-table {
& > tbody > tr:nth-child(odd) {
& > td,
Expand Down
44 changes: 44 additions & 0 deletions app/models/push_subscription_block.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: push_subscription_blocks
#
# id :bigint(8) not null, primary key
# name :string default(""), not null
# endpoint :string not null
# enable :boolean default(TRUE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class PushSubscriptionBlock < ApplicationRecord
CACHE_KEY = 'push_subscription_blocks'

validates :endpoint, presence: true, uniqueness: true, url: true, if: :will_save_change_to_endpoint?

after_commit :reset_cache

def enable!
update!(enable: true)
end

def disable!
update!(enable: false)
end

class << self
def allow?(url)
!deny?(url)
end

def deny?(url)
blocks = Rails.cache.fetch(CACHE_KEY) { Regexp.union(PushSubscriptionBlock.where(enable: true).pluck(:endpoint).map { |pattern| Regexp.new("^#{Regexp.escape(pattern)}", Regexp::IGNORECASE) }) }
blocks.match?(url)
end
end

private

def reset_cache
Rails.cache.delete(CACHE_KEY)
end
end
2 changes: 1 addition & 1 deletion app/models/web/push_subscription.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def authorization_header
end

def pushable?(notification)
policy_allows_notification?(notification) && alert_enabled_for_notification_type?(notification)
policy_allows_notification?(notification) && alert_enabled_for_notification_type?(notification) && PushSubscriptionBlock.allow?(endpoint)
end

def associated_user
Expand Down
7 changes: 7 additions & 0 deletions app/policies/push_subscription_block_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class PushSubscriptionBlockPolicy < ApplicationPolicy
def update?
admin?
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
%tr
%td.nowrap
%samp= push_subscription_block.name
%td.wrap
%samp= push_subscription_block.endpoint
%td.nowrap
- if push_subscription_block.enable?
%span.positive-hint
= fa_icon('check')
= ' '
= t 'admin.push_subscription_blocks.enabled'
- else
%span.negative-hint
= fa_icon('times')
= ' '
= t 'admin.push_subscription_blocks.disabled'
%td.nowrap
- if push_subscription_block.enable?
= table_link_to 'power-off', t('admin.push_subscription_blocks.disable'), disable_admin_push_subscription_block_path(push_subscription_block), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
- else
= table_link_to 'power-off', t('admin.push_subscription_blocks.enable'), enable_admin_push_subscription_block_path(push_subscription_block), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }

= table_link_to 'pencil', t('admin.push_subscription_blocks.edit.title'), edit_admin_push_subscription_block_path(push_subscription_block)
= table_link_to 'times', t('admin.push_subscription_blocks.delete'), admin_push_subscription_block_path(push_subscription_block), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
16 changes: 16 additions & 0 deletions app/views/admin/push_subscription_blocks/edit.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- content_for :page_title do
= t('admin.push_subscription_blocks.edit.title')

= simple_form_for @push_subscription_block, url: admin_push_subscription_block_path(@push_subscription_block), method: :put do |f|
= render 'shared/error_messages', object: @push_subscription_block

%p.hint= t('admin.push_subscription_blocks.enable_hint')

.field-group
= f.input :name, as: :string, wrapper: :with_block_label

.field-group
= f.input :endpoint, as: :string, wrapper: :with_block_label

.actions
= f.button :button, t('admin.push_subscription_blocks.save'), type: :submit
21 changes: 21 additions & 0 deletions app/views/admin/push_subscription_blocks/index.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
- content_for :page_title do
= t('admin.push_subscription_blocks.title')

.simple_form
%p.hint= t('admin.push_subscription_blocks.description_html')
= link_to @push_subscription_blocks.empty? ? t('admin.push_subscription_blocks.setup') : t('admin.push_subscription_blocks.add_new'), new_admin_push_subscription_block_path, class: 'block-button'

- unless @push_subscription_blocks.empty?
%hr.spacer

.table-wrapper
%table.table
%thead
%tr
%th= t('admin.push_subscription_blocks.name')
%th= t('admin.push_subscription_blocks.endpoint')
%th= t('admin.push_subscription_blocks.enable')
%th
%tbody
= render @push_subscription_blocks

16 changes: 16 additions & 0 deletions app/views/admin/push_subscription_blocks/new.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- content_for :page_title do
= t('admin.push_subscription_blocks.add_new')

= simple_form_for @push_subscription_block, url: admin_push_subscription_blocks_path do |f|
= render 'shared/error_messages', object: @push_subscription_block

%p.hint= t('admin.push_subscription_blocks.enable_hint')

.field-group
= f.input :name, as: :string, wrapper: :with_block_label

.field-group
= f.input :endpoint, as: :string, wrapper: :with_block_label

.actions
= f.button :button, t('admin.push_subscription_blocks.save'), type: :submit
16 changes: 16 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,22 @@ en:
title: Create new IP rule
no_ip_block_selected: No IP rules were changed as none were selected
title: IP rules
push_subscription_blocks:
add_new: Add new block
delete: Delete
disable: Disable
disabled: Disabled
description_html: Block dead/delayed push notification servers.
edit:
title: Edit
enable: Enable
enabled: Enabled
enable_hint: Refer to Sidekiq's dead job and specify the non-functioning endpoint. Since it matches with a prefix match, specify it without user-specific parts such as ID. A meaningful name is recommended, but not required.
endpoint: End point
name: Name
save: Save
setup: Setup a push subscription block
title: Push subscription block
relationships:
title: "%{acct}'s relationships"
relays:
Expand Down
16 changes: 16 additions & 0 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,22 @@ ja:
title: 新規IPルール
no_ip_block_selected: 何も選択されていないためIPルールを変更しませんでした
title: IPルール
push_subscription_blocks:
add_new: プッシュ通知ブロックを追加
delete: 削除
disable: 無効化
disabled: 無効
description_html: 停止・遅延しているプッシュ通知サーバーの利用をブロックします。
edit:
title: 編集
enable: 有効化
enabled: 有効
enable_hint: Sidekiqのデッドジョブを参考に、機能していないエンドポイントを指定します。前方一致でマッチするので、IDなどのユーザー固有部分を除いて指定してください。わかりやすい名前をつけておくことをおすすめしますが、必須ではありません。
endpoint: エンドポイント
name: 名前
save: 保存
setup: プッシュ通知ブロックを設定する
title: プッシュ通知ブロック
relationships:
title: "%{acct} さんのフォロー・フォロワー"
relays:
Expand Down
7 changes: 5 additions & 2 deletions config/locales/simple_form.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,11 @@ en:
mention: Someone mentioned you
pending_account: New account needs review
reblog: Someone boosted your post
report: A new report is submitted
trending_tag: A new trend requires approval
report: New report is submitted
trending_tag: An unreviewed hashtag is trending
push_subscription_blocks:
endpoint: End point
name: Name
rule:
text: Rule
tag:
Expand Down
3 changes: 3 additions & 0 deletions config/locales/simple_form.ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ ja:
reblog: 投稿がブーストされた時
report: 通報を受けた時
trending_tag: 未審査のハッシュタグが人気の時
push_subscription_block:
endpoint: エンドポイント
name: 名前
rule:
text: ルール
tag:
Expand Down
1 change: 1 addition & 0 deletions config/navigation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
s.item :announcements, safe_join([fa_icon('bullhorn fw'), t('admin.announcements.title')]), admin_announcements_path, highlights_on: %r{/admin/announcements}
s.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis}
s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_url, if: -> { current_user.staff? && !whitelist_mode? }, highlights_on: %r{/admin/relays}
s.item :push_subscription_blocks, safe_join([fa_icon('ban fw'), t('admin.push_subscription_blocks.title')]), admin_push_subscription_blocks_url, if: -> { current_user.admin? && !whitelist_mode? }, highlights_on: %r{/admin/push_subscription_blocks}
s.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? }
s.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? }
end
Expand Down
7 changes: 7 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,13 @@
end
end
end

resources :push_subscription_blocks, except: [:show] do
member do
post :enable
post :disable
end
end
end

get '/admin', to: redirect('/admin/dashboard', status: 302)
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20221215211405_create_push_subscription_blocks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreatePushSubscriptionBlocks < ActiveRecord::Migration[6.1]
def change
create_table :push_subscription_blocks do |t|
t.string :name, null: false, default: ''
t.string :endpoint, null: false
t.boolean :enable, null: false, default: true

t.timestamps
end
end
end
8 changes: 8 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,14 @@
t.index ["status_id", "preview_card_id"], name: "index_preview_cards_statuses_on_status_id_and_preview_card_id"
end

create_table "push_subscription_blocks", force: :cascade do |t|
t.string "name", default: "", null: false
t.string "endpoint", null: false
t.boolean "enable", default: true, null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end

create_table "relays", force: :cascade do |t|
t.string "inbox_url", default: "", null: false
t.string "follow_activity_id"
Expand Down
5 changes: 5 additions & 0 deletions spec/fabricators/push_subscription_block_fabricator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Fabricator(:push_subscription_block) do
name 'tootle'
endpoint 'https://tootleformastodon.appspot.com/api/v1/notifications/callback/'
enable true
end
5 changes: 5 additions & 0 deletions spec/models/push_subscription_block_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe PushSubscriptionBlock, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

0 comments on commit 07dfad6

Please sign in to comment.