From e98833748e80275a88560155a0b912667dd2d70b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 9 Nov 2022 08:24:21 +0100 Subject: Fix being able to spoof link verification (#20217) - Change verification to happen in `default` queue - Change verification worker to only be queued if there's something to do - Add `link` tags from metadata fields to page header of profiles --- app/models/account/field.rb | 73 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 app/models/account/field.rb (limited to 'app/models/account') diff --git a/app/models/account/field.rb b/app/models/account/field.rb new file mode 100644 index 000000000..4e0fd9230 --- /dev/null +++ b/app/models/account/field.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +class Account::Field < ActiveModelSerializers::Model + MAX_CHARACTERS_LOCAL = 255 + MAX_CHARACTERS_COMPAT = 2_047 + + attributes :name, :value, :verified_at, :account + + def initialize(account, attributes) + # Keeping this as reference allows us to update the field on the account + # from methods in this class, so that changes can be saved. + @original_field = attributes + @account = account + + super( + name: sanitize(attributes['name']), + value: sanitize(attributes['value']), + verified_at: attributes['verified_at']&.to_datetime, + ) + end + + def verified? + verified_at.present? + end + + def value_for_verification + @value_for_verification ||= begin + if account.local? + value + else + extract_url_from_html + end + end + end + + def verifiable? + value_for_verification.present? && /\A#{FetchLinkCardService::URL_PATTERN}\z/.match?(value_for_verification) + end + + def requires_verification? + !verified? && verifiable? + end + + def mark_verified! + @original_field['verified_at'] = self.verified_at = Time.now.utc + end + + def to_h + { name: name, value: value, verified_at: verified_at } + end + + private + + def sanitize(str) + str.strip[0, character_limit] + end + + def character_limit + account.local? ? MAX_CHARACTERS_LOCAL : MAX_CHARACTERS_COMPAT + end + + def extract_url_from_html + doc = Nokogiri::HTML(value).at_xpath('//body') + + return if doc.children.size > 1 + + element = doc.children.first + + return if element.name != 'a' || element['href'] != element.text + + element['href'] + end +end -- cgit