Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump version to 8.0 #170

Merged
merged 6 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/helpers/kmyblue_capabilities_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def capabilities_for_nodeinfo
status_reference
quote
kmyblue_quote
kmyblue_subscribable
kmyblue_translation
kmyblue_link_preview
kmyblue_emoji_reaction_policy
searchability
kmyblue_searchability
visibility_mutual
Expand All @@ -45,6 +49,8 @@ def capabilities_for_nodeinfo
kmyblue_bookmark_category
kmyblue_searchability_limited
kmyblue_circle_history
kmyblue_emoji_license
emoji_keywords
)

capabilities << :full_text_search if Chewy.enabled?
Expand Down
17 changes: 16 additions & 1 deletion app/lib/activitypub/activity/like.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
class ActivityPub::Activity::Like < ActivityPub::Activity
include Redisable
include Lockable
include JsonLdHelper

def perform
@original_status = status_from_uri(object_uri)
Expand Down Expand Up @@ -102,7 +103,7 @@ def process_emoji(tag)

return if custom_emoji_parser.shortcode.blank? || custom_emoji_parser.image_remote_url.blank?

domain = tag['domain'] || URI.split(custom_emoji_parser.uri)[2] || @account.domain
domain = URI.split(custom_emoji_parser.uri)[2] || @account.domain

if domain == Rails.configuration.x.local_domain || domain == Rails.configuration.x.web_domain
# Block overwriting remote-but-local data
Expand All @@ -118,6 +119,9 @@ def process_emoji(tag)
(custom_emoji_parser.updated_at && custom_emoji_parser.updated_at >= emoji.updated_at) ||
custom_emoji_parser.license != emoji.license

custom_emoji_parser = original_emoji_parser(custom_emoji_parser) if @account.domain != domain
return if custom_emoji_parser.nil?

begin
emoji ||= CustomEmoji.new(
domain: domain,
Expand All @@ -136,6 +140,17 @@ def process_emoji(tag)
emoji
end

def original_emoji_parser(custom_emoji_parser)
uri = custom_emoji_parser.uri
emoji = fetch_resource_without_id_validation(uri)
return nil unless emoji

parser = ActivityPub::Parser::CustomEmojiParser.new(emoji)
return nil unless parser.uri == uri && custom_emoji_parser.shortcode == parser.shortcode

parser
end

def skip_download?(domain)
DomainBlock.reject_media?(domain)
end
Expand Down
7 changes: 6 additions & 1 deletion app/lib/activitypub/activity/undo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,12 @@ def undo_like
if shortcode.present?
emoji_tag = @object['tag'].is_a?(Array) ? @object['tag']&.first : @object['tag']

emoji = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain) if emoji_tag.present? && emoji_tag['id'].present?
emoji = nil
if emoji_tag.present? && emoji_tag['id'].present?
domain = URI.split(emoji_tag['id'])[2]
domain = nil if domain == Rails.configuration.x.local_domain || domain == Rails.configuration.x.web_domain
emoji = CustomEmoji.find_by(shortcode: shortcode, domain: domain) if emoji_tag.present? && emoji_tag['id'].present?
end

emoji_reaction = @original_status.emoji_reactions.where(account: @account, name: shortcode, custom_emoji: emoji).first

Expand Down
6 changes: 1 addition & 5 deletions app/serializers/activitypub/emoji_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class ActivityPub::EmojiSerializer < ActivityPub::Serializer

context_extensions :emoji, :license, :keywords

attributes :id, :type, :domain, :name, :keywords, :is_sensitive, :updated
attributes :id, :type, :name, :keywords, :is_sensitive, :updated

attribute :license, if: -> { object.license.present? }

Expand All @@ -19,10 +19,6 @@ def type
'Emoji'
end

def domain
object.domain.presence || Rails.configuration.x.local_domain
end

def keywords
object.aliases
end
Expand Down
13 changes: 13 additions & 0 deletions db/post_migrate/20231022074913_add_statuses_quote_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

require Rails.root.join('lib', 'mastodon', 'migration_helpers')

class AddStatusesQuoteIndex < ActiveRecord::Migration[7.0]
include Mastodon::MigrationHelpers

disable_ddl_transaction!

def change
safety_assured { add_index :statuses, [:quote_of_id, :account_id], unique: false }
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_10_21_005339) do
ActiveRecord::Schema[7.0].define(version: 2023_10_22_074913) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -1228,6 +1228,7 @@
t.index ["id", "account_id"], name: "index_statuses_public_20200119", order: { id: :desc }, where: "((deleted_at IS NULL) AND (visibility = 0) AND (reblog_of_id IS NULL) AND ((NOT reply) OR (in_reply_to_account_id = account_id)))"
t.index ["in_reply_to_account_id"], name: "index_statuses_on_in_reply_to_account_id", where: "(in_reply_to_account_id IS NOT NULL)"
t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id", where: "(in_reply_to_id IS NOT NULL)"
t.index ["quote_of_id", "account_id"], name: "index_statuses_on_quote_of_id_and_account_id"
t.index ["reblog_of_id", "account_id"], name: "index_statuses_on_reblog_of_id_and_account_id"
t.index ["uri"], name: "index_statuses_on_uri", unique: true, opclass: :text_pattern_ops, where: "(uri IS NOT NULL)"
end
Expand Down
4 changes: 2 additions & 2 deletions lib/mastodon/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ module Version
module_function

def kmyblue_major
7
8
end

def kmyblue_minor
2
0
end

def kmyblue_flag
Expand Down
120 changes: 116 additions & 4 deletions spec/lib/activitypub/activity/like_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@
object: ActivityPub::TagManager.instance.uri_for(status),
}.with_indifferent_access
end
let(:original_emoji) do
{
id: 'https://example.com/aaa',
type: 'Emoji',
icon: {
url: 'http://example.com/emoji.png',
},
name: 'tinking',
license: 'This is ohagi',
}
end
let(:original_invalid_emoji) do
{
id: 'https://example.com/invalid',
type: 'Emoji',
icon: {
url: 'http://example.com/emoji.png',
},
name: 'other',
license: 'This is other ohagi',
}
end

describe '#perform' do
subject { described_class.new(json, sender) }
Expand All @@ -37,6 +59,9 @@

before do
stub_request(:get, 'http://example.com/emoji.png').to_return(body: attachment_fixture('emojo.png'))
stub_request(:get, 'http://foo.bar/emoji2.png').to_return(body: attachment_fixture('emojo.png'))
stub_request(:get, 'https://example.com/aaa').to_return(status: 200, body: Oj.dump(original_emoji))
stub_request(:get, 'https://example.com/invalid').to_return(status: 200, body: Oj.dump(original_invalid_emoji))
end

let(:json) do
Expand Down Expand Up @@ -122,31 +147,111 @@
end
end

context 'with custom emoji and custom domain' do
context 'with custom emoji from non-original server account' do
let(:content) { ':tinking:' }
let(:tag) do
{
id: 'https://example.com/aaa',
type: 'Emoji',
domain: 'post.kmycode.net',
icon: {
url: 'http://example.com/emoji.png',
},
name: 'tinking',
}
end

before do
sender.update(domain: 'ohagi.com')
Fabricate(:custom_emoji, domain: 'example.com', uri: 'https://example.com/aaa', shortcode: 'tinking')
end

it 'create emoji reaction' do
expect(subject.count).to eq 1
expect(subject.first.name).to eq 'tinking'
expect(subject.first.account).to eq sender
expect(subject.first.custom_emoji).to_not be_nil
expect(subject.first.custom_emoji.shortcode).to eq 'tinking'
expect(subject.first.custom_emoji.domain).to eq 'post.kmycode.net'
expect(subject.first.custom_emoji.domain).to eq 'example.com'
expect(sender.favourited?(status)).to be false
end
end

context 'with custom emoji and update license from non-original server account' do
let(:content) { ':tinking:' }
let(:tag) do
{
id: 'https://example.com/aaa',
type: 'Emoji',
icon: {
url: 'http://example.com/emoji.png',
},
name: 'tinking',
license: 'Old license',
}
end

before do
sender.update(domain: 'ohagi.com')
Fabricate(:custom_emoji, domain: 'example.com', uri: 'https://example.com/aaa', shortcode: 'tinking')
end

it 'create emoji reaction' do
expect(subject.count).to eq 1
expect(subject.first.custom_emoji.license).to eq 'This is ohagi'
expect(sender.favourited?(status)).to be false
end
end

context 'with custom emoji but icon url is not valid' do
let(:content) { ':tinking:' }
let(:tag) do
{
id: 'https://example.com/aaa',
type: 'Emoji',
icon: {
url: 'http://foo.bar/emoji.png',
},
name: 'tinking',
license: 'Good for using darwin',
}
end

before do
sender.update(domain: 'ohagi.com')
Fabricate(:custom_emoji, domain: 'example.com', uri: 'https://example.com/aaa', shortcode: 'tinking', image_remote_url: 'http://example.com/emoji.png')
end

it 'create emoji reaction' do
expect(subject.count).to eq 1
expect(subject.first.custom_emoji.reload.license).to eq 'This is ohagi'
expect(subject.first.custom_emoji.image_remote_url).to eq 'http://example.com/emoji.png'
end
end

context 'with custom emoji but uri is not valid' do
let(:content) { ':tinking:' }
let(:tag) do
{
id: 'https://example.com/invalid',
type: 'Emoji',
icon: {
url: 'http://foo.bar/emoji2.png',
},
name: 'tinking',
license: 'Good for using darwin',
}
end

before do
sender.update(domain: 'ohagi.com')
Fabricate(:custom_emoji, domain: 'example.com', uri: 'https://example.com/aaa', shortcode: 'tinking', image_remote_url: 'http://example.com/emoji.png')
end

it 'create emoji reaction' do
expect(subject.count).to eq 0
end
end

context 'with custom emoji but invalid id' do
let(:content) { ':tinking:' }
let(:tag) do
Expand Down Expand Up @@ -175,13 +280,14 @@
let(:content) { ':tinking:' }
let(:tag) do
{
id: 'aaa',
id: 'https://cb6e6126.ngrok.io/aaa',
type: 'Emoji',
domain: Rails.configuration.x.local_domain,
icon: {
url: 'http://example.com/emoji.png',
},
name: 'tinking',
license: 'Ohagi but everyone',
}
end

Expand All @@ -196,8 +302,14 @@
expect(subject.first.custom_emoji).to_not be_nil
expect(subject.first.custom_emoji.shortcode).to eq 'tinking'
expect(subject.first.custom_emoji.domain).to be_nil
expect(subject.first.custom_emoji.license).to eq 'Everyone but Ohagi'
expect(sender.favourited?(status)).to be false
end

it 'not change license' do
expect(subject.first.custom_emoji.reload.license).to eq 'Everyone but Ohagi'
expect(subject.first.custom_emoji.reload.uri).to be_nil
end
end

context 'with unicode emoji and reject_media enabled' do
Expand Down Expand Up @@ -315,7 +427,7 @@
subject.perform
end

it 'does not create a favourite from sender to status', pending: 'considering spec' do

Check warning on line 430 in spec/lib/activitypub/activity/like_spec.rb

View workflow job for this annotation

GitHub Actions / test (3.0, 2)

ActivityPub::Activity::Like#perform when account domain_block does not create a favourite from sender to status Failure/Error: expect(sender.favourited?(status)).to be false expected false got true

Check warning on line 430 in spec/lib/activitypub/activity/like_spec.rb

View workflow job for this annotation

GitHub Actions / test (3.1, 2)

ActivityPub::Activity::Like#perform when account domain_block does not create a favourite from sender to status Failure/Error: expect(sender.favourited?(status)).to be false expected false got true

Check warning on line 430 in spec/lib/activitypub/activity/like_spec.rb

View workflow job for this annotation

GitHub Actions / test (.ruby-version, 2)

ActivityPub::Activity::Like#perform when account domain_block does not create a favourite from sender to status Failure/Error: expect(sender.favourited?(status)).to be false expected false got true

Check warning on line 430 in spec/lib/activitypub/activity/like_spec.rb

View workflow job for this annotation

GitHub Actions / test (3.0, 2)

ActivityPub::Activity::Like#perform when account domain_block does not create a favourite from sender to status Failure/Error: expect(sender.favourited?(status)).to be false expected false got true

Check warning on line 430 in spec/lib/activitypub/activity/like_spec.rb

View workflow job for this annotation

GitHub Actions / test (3.1, 2)

ActivityPub::Activity::Like#perform when account domain_block does not create a favourite from sender to status Failure/Error: expect(sender.favourited?(status)).to be false expected false got true

Check warning on line 430 in spec/lib/activitypub/activity/like_spec.rb

View workflow job for this annotation

GitHub Actions / test (.ruby-version, 2)

ActivityPub::Activity::Like#perform when account domain_block does not create a favourite from sender to status Failure/Error: expect(sender.favourited?(status)).to be false expected false got true
expect(sender.favourited?(status)).to be false
end
end
Expand Down
Loading
Loading