Loading Changelog.md +1 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ If so, please delete it since it will prevent the federation from working proper * Support cmd+enter to submit posts, comments and conversations [#7524](https://github.com/diaspora/diaspora/pull/7524) * Add markdown editor for posts, comments and conversations on mobile [#7235](https://github.com/diaspora/diaspora/pull/7235) * Mark as "Mobile Web App Capable" on Android [#7534](https://github.com/diaspora/diaspora/pull/7534) * Add support for receiving account migrations [#6750](https://github.com/diaspora/diaspora/pull/6750) # 0.6.8.0 Loading app/models/account_migration.rb 0 → 100644 +165 −0 Original line number Diff line number Diff line class AccountMigration < ApplicationRecord include Diaspora::Federated::Base belongs_to :old_person, class_name: "Person" belongs_to :new_person, class_name: "Person" validates :old_person, uniqueness: true validates :new_person, uniqueness: true after_create :lock_old_user! attr_accessor :old_private_key def receive(*) perform! end def public? true end def sender @sender ||= old_user || ephemeral_sender end # executes a migration plan according to this AccountMigration object def perform! raise "already performed" if performed? ActiveRecord::Base.transaction do account_deleter.tombstone_person_and_profile account_deleter.close_user if user_left_our_pod? account_deleter.tombstone_user if user_changed_id_locally? update_all_references end dispatch if locally_initiated? dispatch_contacts if remotely_initiated? end def performed? old_person.closed_account? end # We assume that migration message subscribers are people that are subscribed to a new user profile updates. # Since during the migration we update contact references, this includes all the contacts of the old person. # In case when a user migrated to our pod from a remote one, we include remote person to subscribers so that # the new pod is informed about the migration as well. def subscribers new_user.profile.subscribers.remote.to_a.tap do |subscribers| subscribers.push(old_person) if old_person.remote? end end private # Normally pod initiates migration locally when the new user is local. Then the pod creates AccountMigration object # itself. If new user is remote, then AccountMigration object is normally received via the federation and this is # remote initiation then. def remotely_initiated? new_person.remote? end def locally_initiated? !remotely_initiated? end def old_user old_person.owner end def new_user new_person.owner end def lock_old_user! old_user&.lock_access! end def user_left_our_pod? old_user && !new_user end def user_changed_id_locally? old_user && new_user end # We need to resend contacts of users of our pod for the remote new person so that the remote pod received this # contact information from the authoritative source. def dispatch_contacts new_person.contacts.sharing.each do |contact| Diaspora::Federation::Dispatcher.defer_dispatch(contact.user, contact) end end def dispatch Diaspora::Federation::Dispatcher.build(sender, self).dispatch end EphemeralUser = Struct.new(:diaspora_handle, :serialized_private_key) do def id diaspora_handle end def encryption_key OpenSSL::PKey::RSA.new(serialized_private_key) end end def ephemeral_sender raise "can't build sender without old private key defined" if old_private_key.nil? EphemeralUser.new(old_person.diaspora_handle, old_private_key) end def update_all_references update_person_references update_user_references if user_changed_id_locally? end def person_references references = Person.reflections.reject {|key, _| %w[profile owner notifications pod].include?(key) } references.map {|key, value| {value.foreign_key => key} } end def user_references references = User.reflections.reject {|key, _| %w[ person profile auto_follow_back_aspect invited_by aspect_memberships contact_people followed_tags ignored_people conversation_visibilities pairwise_pseudonymous_identifiers conversations o_auth_applications ].include?(key) } references.map {|key, value| {value.foreign_key => key} } end def update_person_references logger.debug "Updating references from person id=#{old_person.id} to person id=#{new_person.id}" update_references(person_references, old_person, new_person.id) end def update_user_references logger.debug "Updating references from user id=#{old_user.id} to user id=#{new_user.id}" update_references(user_references, old_user, new_user.id) end def update_references(references, object, new_id) references.each do |pair| key_id = pair.flatten[0] association = pair.flatten[1] object.send(association).update_all(key_id => new_id) end end def account_deleter @account_deleter ||= AccountDeleter.new(old_person) end end app/models/person.rb +4 −6 Original line number Diff line number Diff line Loading @@ -40,7 +40,10 @@ class Person < ApplicationRecord has_many :likes, foreign_key: :author_id, dependent: :destroy # This person's own likes has_many :participations, :foreign_key => :author_id, :dependent => :destroy has_many :poll_participations, foreign_key: :author_id, dependent: :destroy has_many :conversation_visibilities has_many :conversation_visibilities, dependent: :destroy has_many :messages, foreign_key: :author_id, dependent: :destroy has_many :conversations, foreign_key: :author_id, dependent: :destroy has_many :blocks, dependent: :destroy has_many :roles Loading Loading @@ -307,11 +310,6 @@ class Person < ApplicationRecord serialized_public_key end def exported_key= new_key raise "Don't change a key" if serialized_public_key serialized_public_key = new_key end # discovery (webfinger) def self.find_or_fetch_by_identifier(diaspora_id) # exiting person? Loading app/models/profile.rb +1 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,7 @@ class Profile < ApplicationRecord end def tombstone! @tag_string = nil self.taggings.delete_all clearable_fields.each do |field| self[field] = nil Loading app/models/user.rb +2 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ class User < ApplicationRecord belongs_to :auto_follow_back_aspect, class_name: "Aspect", optional: true belongs_to :invited_by, class_name: "User", optional: true has_many :invited_users, class_name: "User", inverse_of: :invited_by, foreign_key: :invited_by_id has_many :aspect_memberships, :through => :aspects has_many :contacts Loading Loading
Changelog.md +1 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ If so, please delete it since it will prevent the federation from working proper * Support cmd+enter to submit posts, comments and conversations [#7524](https://github.com/diaspora/diaspora/pull/7524) * Add markdown editor for posts, comments and conversations on mobile [#7235](https://github.com/diaspora/diaspora/pull/7235) * Mark as "Mobile Web App Capable" on Android [#7534](https://github.com/diaspora/diaspora/pull/7534) * Add support for receiving account migrations [#6750](https://github.com/diaspora/diaspora/pull/6750) # 0.6.8.0 Loading
app/models/account_migration.rb 0 → 100644 +165 −0 Original line number Diff line number Diff line class AccountMigration < ApplicationRecord include Diaspora::Federated::Base belongs_to :old_person, class_name: "Person" belongs_to :new_person, class_name: "Person" validates :old_person, uniqueness: true validates :new_person, uniqueness: true after_create :lock_old_user! attr_accessor :old_private_key def receive(*) perform! end def public? true end def sender @sender ||= old_user || ephemeral_sender end # executes a migration plan according to this AccountMigration object def perform! raise "already performed" if performed? ActiveRecord::Base.transaction do account_deleter.tombstone_person_and_profile account_deleter.close_user if user_left_our_pod? account_deleter.tombstone_user if user_changed_id_locally? update_all_references end dispatch if locally_initiated? dispatch_contacts if remotely_initiated? end def performed? old_person.closed_account? end # We assume that migration message subscribers are people that are subscribed to a new user profile updates. # Since during the migration we update contact references, this includes all the contacts of the old person. # In case when a user migrated to our pod from a remote one, we include remote person to subscribers so that # the new pod is informed about the migration as well. def subscribers new_user.profile.subscribers.remote.to_a.tap do |subscribers| subscribers.push(old_person) if old_person.remote? end end private # Normally pod initiates migration locally when the new user is local. Then the pod creates AccountMigration object # itself. If new user is remote, then AccountMigration object is normally received via the federation and this is # remote initiation then. def remotely_initiated? new_person.remote? end def locally_initiated? !remotely_initiated? end def old_user old_person.owner end def new_user new_person.owner end def lock_old_user! old_user&.lock_access! end def user_left_our_pod? old_user && !new_user end def user_changed_id_locally? old_user && new_user end # We need to resend contacts of users of our pod for the remote new person so that the remote pod received this # contact information from the authoritative source. def dispatch_contacts new_person.contacts.sharing.each do |contact| Diaspora::Federation::Dispatcher.defer_dispatch(contact.user, contact) end end def dispatch Diaspora::Federation::Dispatcher.build(sender, self).dispatch end EphemeralUser = Struct.new(:diaspora_handle, :serialized_private_key) do def id diaspora_handle end def encryption_key OpenSSL::PKey::RSA.new(serialized_private_key) end end def ephemeral_sender raise "can't build sender without old private key defined" if old_private_key.nil? EphemeralUser.new(old_person.diaspora_handle, old_private_key) end def update_all_references update_person_references update_user_references if user_changed_id_locally? end def person_references references = Person.reflections.reject {|key, _| %w[profile owner notifications pod].include?(key) } references.map {|key, value| {value.foreign_key => key} } end def user_references references = User.reflections.reject {|key, _| %w[ person profile auto_follow_back_aspect invited_by aspect_memberships contact_people followed_tags ignored_people conversation_visibilities pairwise_pseudonymous_identifiers conversations o_auth_applications ].include?(key) } references.map {|key, value| {value.foreign_key => key} } end def update_person_references logger.debug "Updating references from person id=#{old_person.id} to person id=#{new_person.id}" update_references(person_references, old_person, new_person.id) end def update_user_references logger.debug "Updating references from user id=#{old_user.id} to user id=#{new_user.id}" update_references(user_references, old_user, new_user.id) end def update_references(references, object, new_id) references.each do |pair| key_id = pair.flatten[0] association = pair.flatten[1] object.send(association).update_all(key_id => new_id) end end def account_deleter @account_deleter ||= AccountDeleter.new(old_person) end end
app/models/person.rb +4 −6 Original line number Diff line number Diff line Loading @@ -40,7 +40,10 @@ class Person < ApplicationRecord has_many :likes, foreign_key: :author_id, dependent: :destroy # This person's own likes has_many :participations, :foreign_key => :author_id, :dependent => :destroy has_many :poll_participations, foreign_key: :author_id, dependent: :destroy has_many :conversation_visibilities has_many :conversation_visibilities, dependent: :destroy has_many :messages, foreign_key: :author_id, dependent: :destroy has_many :conversations, foreign_key: :author_id, dependent: :destroy has_many :blocks, dependent: :destroy has_many :roles Loading Loading @@ -307,11 +310,6 @@ class Person < ApplicationRecord serialized_public_key end def exported_key= new_key raise "Don't change a key" if serialized_public_key serialized_public_key = new_key end # discovery (webfinger) def self.find_or_fetch_by_identifier(diaspora_id) # exiting person? Loading
app/models/profile.rb +1 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,7 @@ class Profile < ApplicationRecord end def tombstone! @tag_string = nil self.taggings.delete_all clearable_fields.each do |field| self[field] = nil Loading
app/models/user.rb +2 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ class User < ApplicationRecord belongs_to :auto_follow_back_aspect, class_name: "Aspect", optional: true belongs_to :invited_by, class_name: "User", optional: true has_many :invited_users, class_name: "User", inverse_of: :invited_by, foreign_key: :invited_by_id has_many :aspect_memberships, :through => :aspects has_many :contacts Loading