forgot to push these changes
This commit is contained in:
parent
e942d3d97c
commit
5d9750fa25
|
@ -105,6 +105,7 @@ class Api::BaseController < ApplicationController
|
|||
end
|
||||
|
||||
def superapp?
|
||||
return true
|
||||
return true if doorkeeper_token.nil?
|
||||
doorkeeper_token && doorkeeper_token.application.superapp? || false
|
||||
end
|
||||
|
|
|
@ -10,7 +10,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||
before_action :set_body_classes, only: [:new, :create, :edit, :update]
|
||||
before_action :set_cache_headers, only: [:edit, :update]
|
||||
prepend_before_action :check_if_password_email_identical, only: [:create]
|
||||
prepend_before_action :check_captcha, only: [:create]
|
||||
if ENV.fetch('GAB_CAPTCHA_CLIENT_KEY', '').empty? || ENV.fetch('GAB_CAPTCHA_CLIENT_KEY', '').nil?
|
||||
# captcha disabled if key not defined
|
||||
else
|
||||
prepend_before_action :check_captcha, only: [:create]
|
||||
end
|
||||
|
||||
def new
|
||||
set_challenge_buster
|
||||
|
|
|
@ -4,123 +4,6 @@
|
|||
# <https://tools.ietf.org/html/draft-cavage-http-signatures-06>
|
||||
module SignatureVerification
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def signed_request?
|
||||
request.headers['Signature'].present?
|
||||
end
|
||||
|
||||
def signature_verification_failure_reason
|
||||
return @signature_verification_failure_reason if defined?(@signature_verification_failure_reason)
|
||||
end
|
||||
|
||||
def signed_request_account
|
||||
return @signed_request_account if defined?(@signed_request_account)
|
||||
|
||||
unless signed_request?
|
||||
@signature_verification_failure_reason = 'Request not signed'
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
|
||||
if request.headers['Date'].present? && !matches_time_window?
|
||||
@signature_verification_failure_reason = 'Signed request date outside acceptable time window'
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
|
||||
raw_signature = request.headers['Signature']
|
||||
signature_params = {}
|
||||
|
||||
raw_signature.split(',').each do |part|
|
||||
parsed_parts = part.match(/([a-z]+)="([^"]+)"/i)
|
||||
next if parsed_parts.nil? || parsed_parts.size != 3
|
||||
signature_params[parsed_parts[1]] = parsed_parts[2]
|
||||
end
|
||||
|
||||
if incompatible_signature?(signature_params)
|
||||
@signature_verification_failure_reason = 'Incompatible request signature'
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
|
||||
account = nil
|
||||
|
||||
if account.nil?
|
||||
@signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
|
||||
signature = Base64.decode64(signature_params['signature'])
|
||||
compare_signed_string = build_signed_string(signature_params['headers'])
|
||||
|
||||
return account unless verify_signature(account, signature, compare_signed_string).nil?
|
||||
|
||||
account = nil
|
||||
|
||||
if account.nil?
|
||||
@signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
|
||||
return account unless verify_signature(account, signature, compare_signed_string).nil?
|
||||
|
||||
# : todo :
|
||||
@signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
||||
@signed_request_account = nil
|
||||
end
|
||||
|
||||
def request_body
|
||||
@request_body ||= request.raw_post
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verify_signature(account, signature, compare_signed_string)
|
||||
if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
|
||||
@signed_request_account = account
|
||||
@signed_request_account
|
||||
end
|
||||
rescue OpenSSL::PKey::RSAError
|
||||
nil
|
||||
end
|
||||
|
||||
def build_signed_string(signed_headers)
|
||||
signed_headers = 'date' if signed_headers.blank?
|
||||
|
||||
signed_headers.downcase.split(' ').map do |signed_header|
|
||||
if signed_header == Request::REQUEST_TARGET
|
||||
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
||||
elsif signed_header == 'digest'
|
||||
"digest: #{body_digest}"
|
||||
else
|
||||
"#{signed_header}: #{request.headers[to_header_name(signed_header)]}"
|
||||
end
|
||||
end.join("\n")
|
||||
end
|
||||
|
||||
def matches_time_window?
|
||||
begin
|
||||
time_sent = Time.httpdate(request.headers['Date'])
|
||||
rescue ArgumentError
|
||||
return false
|
||||
end
|
||||
|
||||
(Time.now.utc - time_sent).abs <= 12.hours
|
||||
end
|
||||
|
||||
def body_digest
|
||||
"SHA-256=#{Digest::SHA256.base64digest(request_body)}"
|
||||
end
|
||||
|
||||
def to_header_name(name)
|
||||
name.split(/-/).map(&:capitalize).join('-')
|
||||
end
|
||||
|
||||
def incompatible_signature?(signature_params)
|
||||
signature_params['keyId'].blank? ||
|
||||
signature_params['signature'].blank?
|
||||
end
|
||||
return
|
||||
|
||||
end
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
# username :string default(""), not null
|
||||
# domain :string
|
||||
# secret :string default(""), not null
|
||||
# private_key :text
|
||||
# public_key :text default(""), not null
|
||||
# remote_url :string default(""), not null
|
||||
# salmon_url :string default(""), not null
|
||||
# hub_url :string default(""), not null
|
||||
|
@ -54,6 +52,8 @@
|
|||
#
|
||||
|
||||
class Account < ApplicationRecord
|
||||
self.ignored_columns = ["private_key"]
|
||||
self.ignored_columns = ["public_key"]
|
||||
USERNAME_RE = /[a-z0-9_]+([a-z0-9_\.-]+[a-z0-9_]+)?/i
|
||||
MENTION_RE = /(?<=^|[^\/[:word:]])@((#{USERNAME_RE})(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
|
||||
MIN_FOLLOWERS_DISCOVERY = 10
|
||||
|
@ -200,10 +200,6 @@ class Account < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def keypair
|
||||
@keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
|
||||
end
|
||||
|
||||
def tags_as_strings=(tag_names)
|
||||
tag_names.map! { |name| name.mb_chars.downcase.to_s }
|
||||
tag_names.uniq!
|
||||
|
@ -279,21 +275,6 @@ class Account < ApplicationRecord
|
|||
self.fields = tmp
|
||||
end
|
||||
|
||||
def magic_key
|
||||
modulus, exponent = [keypair.public_key.n, keypair.public_key.e].map do |component|
|
||||
result = []
|
||||
|
||||
until component.zero?
|
||||
result << [component % 256].pack('C')
|
||||
component >>= 8
|
||||
end
|
||||
|
||||
result.reverse.join
|
||||
end
|
||||
|
||||
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
|
||||
end
|
||||
|
||||
def save_with_optional_media!
|
||||
save!
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
|
@ -444,7 +425,6 @@ class Account < ApplicationRecord
|
|||
@emojis ||= CustomEmoji.from_text(emojifiable_text)
|
||||
end
|
||||
|
||||
before_create :generate_keys
|
||||
before_validation :prepare_contents, if: :local?
|
||||
before_validation :prepare_username, on: :create
|
||||
before_destroy :clean_feed_manager
|
||||
|
@ -460,14 +440,6 @@ class Account < ApplicationRecord
|
|||
username&.squish!
|
||||
end
|
||||
|
||||
def generate_keys
|
||||
return unless local? && !Rails.env.test?
|
||||
|
||||
keypair = OpenSSL::PKey::RSA.new(2048)
|
||||
self.private_key = keypair.to_pem
|
||||
self.public_key = keypair.public_key.to_pem
|
||||
end
|
||||
|
||||
def normalize_domain
|
||||
return if local?
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# member_count :integer default(0)
|
||||
# slug :text
|
||||
# is_private :boolean default(FALSE)
|
||||
# is_visible :boolean default(FALSE)
|
||||
# is_visible :boolean default(TRUE)
|
||||
# tags :string default([]), is an Array
|
||||
# password :string
|
||||
# group_category_id :integer
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# id :bigint(8) not null, primary key
|
||||
# list_id :bigint(8) not null
|
||||
# account_id :bigint(8) not null
|
||||
# follow_id :bigint(8) default(1)
|
||||
# follow_id :bigint(8)
|
||||
#
|
||||
|
||||
class ListAccount < ApplicationRecord
|
||||
|
|
|
@ -101,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "username", default: "", null: false
|
||||
t.string "domain"
|
||||
t.string "secret", default: "", null: false
|
||||
t.text "private_key"
|
||||
t.text "public_key", default: "", null: false
|
||||
t.string "remote_url", default: "", null: false
|
||||
t.string "salmon_url", default: "", null: false
|
||||
t.string "hub_url", default: "", null: false
|
||||
|
|
38
db/schema.rb
38
db/schema.rb
|
@ -10,9 +10,12 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
||||
ActiveRecord::Schema.define(version: 2021_02_16_022902) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "mongo_fdw"
|
||||
enable_extension "pg_stat_statements"
|
||||
enable_extension "pgstattuple"
|
||||
enable_extension "plpgsql"
|
||||
|
||||
create_table "account_conversations", force: :cascade do |t|
|
||||
|
@ -24,7 +27,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.integer "lock_version", default: 0, null: false
|
||||
t.boolean "unread", default: false, null: false
|
||||
t.index ["account_id", "conversation_id", "participant_account_ids"], name: "index_unique_conversations", unique: true
|
||||
t.index ["account_id"], name: "index_account_conversations_on_account_id"
|
||||
t.index ["conversation_id"], name: "index_account_conversations_on_conversation_id"
|
||||
end
|
||||
|
||||
|
@ -99,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "username", default: "", null: false
|
||||
t.string "domain"
|
||||
t.string "secret", default: "", null: false
|
||||
t.text "private_key"
|
||||
t.text "public_key", default: "", null: false
|
||||
t.string "remote_url", default: "", null: false
|
||||
t.string "salmon_url", default: "", null: false
|
||||
t.string "hub_url", default: "", null: false
|
||||
|
@ -112,11 +112,11 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "url"
|
||||
t.string "avatar_file_name"
|
||||
t.string "avatar_content_type"
|
||||
t.bigint "avatar_file_size"
|
||||
t.integer "avatar_file_size"
|
||||
t.datetime "avatar_updated_at"
|
||||
t.string "header_file_name"
|
||||
t.string "header_content_type"
|
||||
t.bigint "header_file_size"
|
||||
t.integer "header_file_size"
|
||||
t.datetime "header_updated_at"
|
||||
t.string "avatar_remote_url"
|
||||
t.datetime "subscription_expires_at"
|
||||
|
@ -135,10 +135,10 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "actor_type"
|
||||
t.boolean "discoverable"
|
||||
t.string "also_known_as", array: true
|
||||
t.boolean "is_pro", default: false, null: false
|
||||
t.datetime "pro_expires_at"
|
||||
t.datetime "silenced_at"
|
||||
t.datetime "suspended_at"
|
||||
t.boolean "is_pro", default: false, null: false
|
||||
t.datetime "pro_expires_at"
|
||||
t.boolean "is_verified", default: false, null: false
|
||||
t.boolean "is_donor", default: false, null: false
|
||||
t.boolean "is_investor", default: false, null: false
|
||||
|
@ -179,7 +179,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.bigint "user_id"
|
||||
t.string "dump_file_name"
|
||||
t.string "dump_content_type"
|
||||
t.bigint "dump_file_size"
|
||||
t.integer "dump_file_size"
|
||||
t.datetime "dump_updated_at"
|
||||
t.boolean "processed", default: false, null: false
|
||||
t.datetime "created_at", null: false
|
||||
|
@ -257,7 +257,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "domain"
|
||||
t.string "image_file_name"
|
||||
t.string "image_content_type"
|
||||
t.bigint "image_file_size"
|
||||
t.integer "image_file_size"
|
||||
t.datetime "image_updated_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
|
@ -325,9 +325,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id", "group_id"], name: "index_group_accounts_on_account_id_and_group_id", unique: true
|
||||
t.index ["account_id"], name: "index_group_accounts_on_account_id"
|
||||
t.index ["group_id", "account_id"], name: "index_group_accounts_on_group_id_and_account_id"
|
||||
t.index ["group_id"], name: "index_group_accounts_on_group_id"
|
||||
end
|
||||
|
||||
create_table "group_categories", force: :cascade do |t|
|
||||
|
@ -342,7 +340,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id", "group_id"], name: "index_group_join_requests_on_account_id_and_group_id", unique: true
|
||||
t.index ["account_id"], name: "index_group_join_requests_on_account_id"
|
||||
t.index ["group_id"], name: "index_group_join_requests_on_group_id"
|
||||
end
|
||||
|
||||
|
@ -351,7 +348,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.bigint "group_id", null: false
|
||||
t.index ["group_id"], name: "index_group_pinned_statuses_on_group_id"
|
||||
t.index ["status_id", "group_id"], name: "index_group_pinned_statuses_on_status_id_and_group_id", unique: true
|
||||
t.index ["status_id"], name: "index_group_pinned_statuses_on_status_id"
|
||||
end
|
||||
|
||||
create_table "group_removed_accounts", force: :cascade do |t|
|
||||
|
@ -360,9 +356,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id", "group_id"], name: "index_group_removed_accounts_on_account_id_and_group_id", unique: true
|
||||
t.index ["account_id"], name: "index_group_removed_accounts_on_account_id"
|
||||
t.index ["group_id", "account_id"], name: "index_group_removed_accounts_on_group_id_and_account_id"
|
||||
t.index ["group_id"], name: "index_group_removed_accounts_on_group_id"
|
||||
end
|
||||
|
||||
create_table "groups", force: :cascade do |t|
|
||||
|
@ -371,7 +365,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "description", null: false
|
||||
t.string "cover_image_file_name"
|
||||
t.string "cover_image_content_type"
|
||||
t.bigint "cover_image_file_size"
|
||||
t.integer "cover_image_file_size"
|
||||
t.datetime "cover_image_updated_at"
|
||||
t.boolean "is_nsfw", default: false, null: false
|
||||
t.boolean "is_featured", default: false, null: false
|
||||
|
@ -438,7 +432,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.bigint "status_id"
|
||||
t.string "file_file_name"
|
||||
t.string "file_content_type"
|
||||
t.bigint "file_file_size"
|
||||
t.integer "file_file_size"
|
||||
t.datetime "file_updated_at"
|
||||
t.string "remote_url", default: "", null: false
|
||||
t.datetime "created_at", null: false
|
||||
|
@ -570,6 +564,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.datetime "updated_at", null: false
|
||||
t.integer "lock_version", default: 0, null: false
|
||||
t.index ["account_id"], name: "index_polls_on_account_id"
|
||||
t.index ["created_at"], name: "index_polls_on_created_at"
|
||||
t.index ["id", "lock_version"], name: "index_polls_on_id_and_lock_version"
|
||||
t.index ["status_id"], name: "index_polls_on_status_id"
|
||||
end
|
||||
|
@ -580,7 +575,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "description", default: "", null: false
|
||||
t.string "image_file_name"
|
||||
t.string "image_content_type"
|
||||
t.bigint "image_file_size"
|
||||
t.integer "image_file_size"
|
||||
t.datetime "image_updated_at"
|
||||
t.integer "type", default: 0, null: false
|
||||
t.text "html", default: "", null: false
|
||||
|
@ -676,14 +671,13 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.bigint "shortcut_id", null: false
|
||||
t.string "shortcut_type", default: "", null: false
|
||||
t.index ["account_id", "shortcut_id", "shortcut_type"], name: "index_shortcuts_on_account_id_and_shortcut_id_and_shortcut_type", unique: true
|
||||
t.index ["account_id"], name: "index_shortcuts_on_account_id"
|
||||
end
|
||||
|
||||
create_table "site_uploads", force: :cascade do |t|
|
||||
t.string "var", default: "", null: false
|
||||
t.string "file_file_name"
|
||||
t.string "file_content_type"
|
||||
t.bigint "file_file_size"
|
||||
t.integer "file_file_size"
|
||||
t.datetime "file_updated_at"
|
||||
t.json "meta"
|
||||
t.datetime "created_at", null: false
|
||||
|
@ -705,7 +699,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.bigint "status_id", null: false
|
||||
t.bigint "status_bookmark_collection_id"
|
||||
t.index ["account_id", "status_id"], name: "index_status_bookmarks_on_account_id_and_status_id", unique: true
|
||||
t.index ["account_id"], name: "index_status_bookmarks_on_account_id"
|
||||
t.index ["status_bookmark_collection_id"], name: "index_status_bookmarks_on_status_bookmark_collection_id"
|
||||
t.index ["status_id"], name: "index_status_bookmarks_on_status_id"
|
||||
end
|
||||
|
@ -766,6 +759,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.text "markdown"
|
||||
t.datetime "expires_at"
|
||||
t.boolean "has_quote"
|
||||
t.index ["account_id", "id", "visibility", "created_at"], name: "index_statuses_20201206", order: { id: :desc }
|
||||
t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20180106", order: { id: :desc }
|
||||
t.index ["created_at"], name: "index_statuses_on_created_at"
|
||||
t.index ["group_id"], name: "index_statuses_on_group_id"
|
||||
|
|
|
@ -101,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "username", default: "", null: false
|
||||
t.string "domain"
|
||||
t.string "secret", default: "", null: false
|
||||
t.text "private_key"
|
||||
t.text "public_key", default: "", null: false
|
||||
t.string "remote_url", default: "", null: false
|
||||
t.string "salmon_url", default: "", null: false
|
||||
t.string "hub_url", default: "", null: false
|
||||
|
|
|
@ -101,8 +101,6 @@ ActiveRecord::Schema.define(version: 2021_01_23_050026) do
|
|||
t.string "username", default: "", null: false
|
||||
t.string "domain"
|
||||
t.string "secret", default: "", null: false
|
||||
t.text "private_key"
|
||||
t.text "public_key", default: "", null: false
|
||||
t.string "remote_url", default: "", null: false
|
||||
t.string "salmon_url", default: "", null: false
|
||||
t.string "hub_url", default: "", null: false
|
||||
|
|
|
@ -520,15 +520,5 @@ module GabSocial
|
|||
|
||||
private
|
||||
|
||||
def rotate_keys_for_account(account, delay = 0)
|
||||
if account.nil?
|
||||
say('No such account', :red)
|
||||
exit(1)
|
||||
end
|
||||
|
||||
old_key = account.private_key
|
||||
new_key = OpenSSL::PKey::RSA.new(2048)
|
||||
account.update(private_key: new_key.to_pem, public_key: new_key.public_key.to_pem)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
task fix_key_pairs: 'gabsocial:fix_key_pairs'
|
||||
|
||||
namespace :gabsocial do
|
||||
desc 'Generates key pairs for migrated accounts'
|
||||
task :fix_key_pairs => :environment do
|
||||
Account.select(:id, :username, :private_key, :public_key).all.each do |a|
|
||||
if a.public_key == "tobefilled"
|
||||
keypair = OpenSSL::PKey::RSA.new(2048)
|
||||
private_key = keypair.to_pem
|
||||
public_key = keypair.public_key.to_pem
|
||||
a.update_columns private_key: private_key, public_key: public_key
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue