WIP
This commit is contained in:
parent
689abfb49c
commit
5564644306
12 changed files with 363 additions and 339 deletions
|
|
@ -1,64 +0,0 @@
|
||||||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
|
||||||
# licensed under the Affero General Public License version 3 or later. See
|
|
||||||
# the COPYRIGHT file.
|
|
||||||
|
|
||||||
class RelayableRetraction < SignedRetraction
|
|
||||||
xml_name :relayable_retraction
|
|
||||||
xml_attr :parent_author_signature
|
|
||||||
|
|
||||||
attr_accessor :parent_author_signature
|
|
||||||
|
|
||||||
delegate :parent, :parent_author, to: :target, allow_nil: true
|
|
||||||
|
|
||||||
def signable_accessors
|
|
||||||
super - ['parent_author_signature']
|
|
||||||
end
|
|
||||||
|
|
||||||
# @param sender [User]
|
|
||||||
# @param target [Object]
|
|
||||||
def self.build(sender, target)
|
|
||||||
retraction = super
|
|
||||||
retraction.parent_author_signature = retraction.sign_with_key(sender.encryption_key) if defined?(target.parent) && sender.person == target.parent.author
|
|
||||||
retraction
|
|
||||||
end
|
|
||||||
|
|
||||||
def diaspora_handle
|
|
||||||
self.sender_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
def relayable?
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def perform receiving_user
|
|
||||||
Rails.logger.debug "Performing relayable retraction for #{target_guid}"
|
|
||||||
if not self.parent_author_signature.nil? or self.parent.author.remote?
|
|
||||||
# Don't destroy a relayable unless the top-level owner has received it, otherwise it may not get relayed
|
|
||||||
self.target.destroy
|
|
||||||
Rails.logger.info("event=relayable_retraction status =complete target_type=#{self.target_type} guid =#{self.target_guid}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def receive(recipient, sender)
|
|
||||||
if self.target.nil?
|
|
||||||
Rails.logger.info("event=retraction status=abort reason='no post found' sender=#{sender.diaspora_handle} target_guid=#{target_guid}")
|
|
||||||
return
|
|
||||||
elsif self.parent.author == recipient.person && self.target_author_signature_valid?
|
|
||||||
#this is a retraction from the downstream object creator, and the recipient is the upstream owner
|
|
||||||
self.parent_author_signature = self.sign_with_key(recipient.encryption_key)
|
|
||||||
Postzord::Dispatcher.build(recipient, self).post
|
|
||||||
self.perform(recipient)
|
|
||||||
elsif self.parent_author_signature_valid?
|
|
||||||
#this is a retraction from the upstream owner
|
|
||||||
self.perform(recipient)
|
|
||||||
else
|
|
||||||
Rails.logger.info("event=receive status=abort reason='object signature not valid' recipient=#{recipient.diaspora_handle} sender=#{self.parent.author.diaspora_handle} payload_type=#{self.class} parent_id=#{self.parent.id}")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def parent_author_signature_valid?
|
|
||||||
verify_signature(self.parent_author_signature, self.parent.author)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
69
lib/diaspora/federated/messages/relayable_retraction.rb
Normal file
69
lib/diaspora/federated/messages/relayable_retraction.rb
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
module Diaspora
|
||||||
|
module Federated
|
||||||
|
module Messages
|
||||||
|
class RelayableRetraction < SignedRetraction
|
||||||
|
xml_name :relayable_retraction
|
||||||
|
xml_attr :parent_author_signature
|
||||||
|
|
||||||
|
attr_accessor :parent_author_signature
|
||||||
|
|
||||||
|
delegate :parent, :parent_author, to: :target, allow_nil: true
|
||||||
|
|
||||||
|
def signable_accessors
|
||||||
|
super - ['parent_author_signature']
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param sender [User]
|
||||||
|
# @param target [Object]
|
||||||
|
def self.build(sender, target)
|
||||||
|
retraction = super
|
||||||
|
retraction.parent_author_signature = retraction.sign_with_key(sender.encryption_key) if defined?(target.parent) && sender.person == target.parent.author
|
||||||
|
retraction
|
||||||
|
end
|
||||||
|
|
||||||
|
def diaspora_handle
|
||||||
|
self.sender_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
def relayable?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform receiving_user
|
||||||
|
Rails.logger.debug "Performing relayable retraction for #{target_guid}"
|
||||||
|
if not self.parent_author_signature.nil? or self.parent.author.remote?
|
||||||
|
# Don't destroy a relayable unless the top-level owner has received it, otherwise it may not get relayed
|
||||||
|
self.target.destroy
|
||||||
|
Rails.logger.info("event=relayable_retraction status =complete target_type=#{self.target_type} guid =#{self.target_guid}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def receive(recipient, sender)
|
||||||
|
if self.target.nil?
|
||||||
|
Rails.logger.info("event=retraction status=abort reason='no post found' sender=#{sender.diaspora_handle} target_guid=#{target_guid}")
|
||||||
|
return
|
||||||
|
elsif self.parent.author == recipient.person && self.target_author_signature_valid?
|
||||||
|
#this is a retraction from the downstream object creator, and the recipient is the upstream owner
|
||||||
|
self.parent_author_signature = self.sign_with_key(recipient.encryption_key)
|
||||||
|
Postzord::Dispatcher.build(recipient, self).post
|
||||||
|
self.perform(recipient)
|
||||||
|
elsif self.parent_author_signature_valid?
|
||||||
|
#this is a retraction from the upstream owner
|
||||||
|
self.perform(recipient)
|
||||||
|
else
|
||||||
|
Rails.logger.info("event=receive status=abort reason='object signature not valid' recipient=#{recipient.diaspora_handle} sender=#{self.parent.author.diaspora_handle} payload_type=#{self.class} parent_id=#{self.parent.id}")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def parent_author_signature_valid?
|
||||||
|
verify_signature(self.parent_author_signature, self.parent.author)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
107
lib/diaspora/federated/messages/request.rb
Normal file
107
lib/diaspora/federated/messages/request.rb
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# t
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
module Diaspora
|
||||||
|
module Federated
|
||||||
|
module Messages
|
||||||
|
class Request
|
||||||
|
include Diaspora::Federated::Base
|
||||||
|
include ActiveModel::Validations
|
||||||
|
|
||||||
|
attr_accessor :sender, :recipient, :aspect
|
||||||
|
|
||||||
|
xml_accessor :sender_handle
|
||||||
|
xml_accessor :recipient_handle
|
||||||
|
|
||||||
|
validates :sender, :presence => true
|
||||||
|
validates :recipient, :presence => true
|
||||||
|
|
||||||
|
validate :not_already_connected
|
||||||
|
validate :not_friending_yourself
|
||||||
|
|
||||||
|
# Initalize variables
|
||||||
|
# @note we should be using ActiveModel::Serialization for this
|
||||||
|
# @return [Request]
|
||||||
|
def self.diaspora_initialize(opts = {})
|
||||||
|
req = self.new
|
||||||
|
req.sender = opts[:from]
|
||||||
|
req.recipient = opts[:to]
|
||||||
|
req.aspect = opts[:into]
|
||||||
|
req
|
||||||
|
end
|
||||||
|
|
||||||
|
# Alias of sender_handle
|
||||||
|
# @return [String]
|
||||||
|
def diaspora_handle
|
||||||
|
sender_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
# @note Used for XML marshalling
|
||||||
|
# @return [String]
|
||||||
|
def sender_handle
|
||||||
|
sender.diaspora_handle
|
||||||
|
end
|
||||||
|
def sender_handle= sender_handle
|
||||||
|
self.sender = Person.where(:diaspora_handle => sender_handle).first
|
||||||
|
end
|
||||||
|
|
||||||
|
# @note Used for XML marshalling
|
||||||
|
# @return [String]
|
||||||
|
def recipient_handle
|
||||||
|
recipient.diaspora_handle
|
||||||
|
end
|
||||||
|
def recipient_handle= recipient_handle
|
||||||
|
self.recipient = Person.where(:diaspora_handle => recipient_handle).first
|
||||||
|
end
|
||||||
|
|
||||||
|
# Defines the abstract interface used in sending a corresponding [Notification] given the [Request]
|
||||||
|
# @param user [User]
|
||||||
|
# @param person [Person]
|
||||||
|
# @return [Notifications::StartedSharing]
|
||||||
|
def notification_type(user, person)
|
||||||
|
Notifications::StartedSharing
|
||||||
|
end
|
||||||
|
|
||||||
|
# Defines the abstract interface used in sending the [Request]
|
||||||
|
# @param user [User]
|
||||||
|
# @return [Array<Person>] The recipient of the request
|
||||||
|
def subscribers(user)
|
||||||
|
[self.recipient]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Finds or initializes a corresponding [Contact], and will set Contact#sharing to true
|
||||||
|
# Follows back if user setting is set so
|
||||||
|
# @note A [Contact] may already exist if the [Request]'s recipient is sharing with the sender
|
||||||
|
# @return [Request]
|
||||||
|
def receive(user, person)
|
||||||
|
Rails.logger.info("event=receive payload_type=request sender=#{self.sender} to=#{self.recipient}")
|
||||||
|
|
||||||
|
contact = user.contacts.find_or_initialize_by_person_id(self.sender.id)
|
||||||
|
contact.sharing = true
|
||||||
|
contact.save
|
||||||
|
|
||||||
|
user.share_with(person, user.auto_follow_back_aspect) if user.auto_follow_back && !contact.receiving
|
||||||
|
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Checks if a [Contact] does not already exist between the requesting [User] and receiving [Person]
|
||||||
|
def not_already_connected
|
||||||
|
if sender && recipient && Contact.where(:user_id => self.recipient.owner_id, :person_id => self.sender.id).exists?
|
||||||
|
errors[:base] << 'You have already connected to this person'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks to see that the requesting [User] is not sending a request to himself
|
||||||
|
def not_friending_yourself
|
||||||
|
if self.recipient == self.sender
|
||||||
|
errors[:base] << 'You can not friend yourself'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
69
lib/diaspora/federated/messages/retraction.rb
Normal file
69
lib/diaspora/federated/messages/retraction.rb
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
module Diaspora
|
||||||
|
module Federated
|
||||||
|
module Messages
|
||||||
|
class Retraction
|
||||||
|
include Diaspora::Federated::Base
|
||||||
|
|
||||||
|
xml_accessor :post_guid
|
||||||
|
xml_accessor :diaspora_handle
|
||||||
|
xml_accessor :type
|
||||||
|
|
||||||
|
attr_accessor :person, :object, :subscribers
|
||||||
|
|
||||||
|
def subscribers(user)
|
||||||
|
unless self.type == 'Person'
|
||||||
|
@subscribers ||= self.object.subscribers(user)
|
||||||
|
@subscribers -= self.object.resharers unless self.object.is_a?(Photo)
|
||||||
|
@subscribers
|
||||||
|
else
|
||||||
|
raise 'HAX: you must set the subscribers manaully before unfriending' if @subscribers.nil?
|
||||||
|
@subscribers
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.for(object)
|
||||||
|
retraction = self.new
|
||||||
|
if object.is_a? User
|
||||||
|
retraction.post_guid = object.person.guid
|
||||||
|
retraction.type = object.person.class.to_s
|
||||||
|
else
|
||||||
|
retraction.post_guid = object.guid
|
||||||
|
retraction.type = object.class.to_s
|
||||||
|
retraction.object = object
|
||||||
|
end
|
||||||
|
retraction.diaspora_handle = object.diaspora_handle
|
||||||
|
retraction
|
||||||
|
end
|
||||||
|
|
||||||
|
def target
|
||||||
|
@target ||= self.type.constantize.where(:guid => post_guid).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform receiving_user
|
||||||
|
Rails.logger.debug "Performing retraction for #{post_guid}"
|
||||||
|
|
||||||
|
self.target.destroy if self.target
|
||||||
|
Rails.logger.info("event=retraction status=complete type=#{self.type} guid=#{self.post_guid}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def receive(user, person)
|
||||||
|
if self.type == 'Person'
|
||||||
|
unless self.person.guid.to_s == self.post_guid.to_s
|
||||||
|
Rails.logger.info("event=receive status=abort reason='sender is not the person he is trying to retract' recipient=#{self.diaspora_handle} sender=#{self.person.diaspora_handle} payload_type=#{self.class} retraction_type=person")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
user.disconnected_by(self.target)
|
||||||
|
elsif self.target.nil? || self.target.author != self.person
|
||||||
|
Rails.logger.info("event=retraction status=abort reason='no post found authored by retractor' sender=#{person.diaspora_handle} post_guid=#{post_guid}")
|
||||||
|
else
|
||||||
|
self.perform(user)
|
||||||
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
110
lib/diaspora/federated/messages/signed_retraction.rb
Normal file
110
lib/diaspora/federated/messages/signed_retraction.rb
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
module Diaspora
|
||||||
|
module Federated
|
||||||
|
module Messages
|
||||||
|
class SignedRetraction
|
||||||
|
include Diaspora::Federated::Base
|
||||||
|
|
||||||
|
include Diaspora::Encryptable
|
||||||
|
|
||||||
|
xml_name :signed_retraction
|
||||||
|
xml_attr :target_guid
|
||||||
|
xml_attr :target_type
|
||||||
|
xml_attr :sender_handle
|
||||||
|
xml_attr :target_author_signature
|
||||||
|
|
||||||
|
attr_accessor :target_guid,
|
||||||
|
:target_type,
|
||||||
|
:target_author_signature,
|
||||||
|
:sender
|
||||||
|
|
||||||
|
#NOTE(fix this hack -- go through the app and make sure we only call RelayableRetraction in a unified way)
|
||||||
|
def author
|
||||||
|
if sender.is_a?(User)
|
||||||
|
sender.person
|
||||||
|
else
|
||||||
|
sender
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def signable_accessors
|
||||||
|
accessors = self.class.roxml_attrs.collect do |definition|
|
||||||
|
definition.accessor
|
||||||
|
end
|
||||||
|
accessors - ['target_author_signature', 'sender_handle']
|
||||||
|
end
|
||||||
|
|
||||||
|
def sender_handle= new_sender_handle
|
||||||
|
@sender = Person.where(:diaspora_handle => new_sender_handle).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def sender_handle
|
||||||
|
@sender.diaspora_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
def diaspora_handle
|
||||||
|
self.sender_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
def subscribers(user)
|
||||||
|
self.target.subscribers(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.build(sender, target)
|
||||||
|
retraction = self.new
|
||||||
|
retraction.sender = sender
|
||||||
|
retraction.target = target
|
||||||
|
retraction.target_author_signature = retraction.sign_with_key(sender.encryption_key) if sender.person == target.author
|
||||||
|
retraction
|
||||||
|
end
|
||||||
|
|
||||||
|
def target
|
||||||
|
@target ||= self.target_type.constantize.where(:guid => target_guid).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def guid
|
||||||
|
target_guid
|
||||||
|
end
|
||||||
|
def target= new_target
|
||||||
|
@target = new_target
|
||||||
|
@target_type = new_target.class.to_s
|
||||||
|
@target_guid = new_target.guid
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform receiving_user
|
||||||
|
Rails.logger.debug "Performing retraction for #{target_guid}"
|
||||||
|
if reshare = Reshare.where(:author_id => receiving_user.person.id, :root_guid => target_guid).first
|
||||||
|
onward_retraction = self.dup
|
||||||
|
onward_retraction.sender = receiving_user.person
|
||||||
|
Postzord::Dispatcher.build(receiving_user, onward_retraction).post
|
||||||
|
end
|
||||||
|
if target
|
||||||
|
self.target.destroy
|
||||||
|
end
|
||||||
|
Rails.logger.info("event=retraction status =complete target_type=#{self.target_type} guid =#{self.target_guid}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def receive(recipient, sender)
|
||||||
|
if self.target.nil?
|
||||||
|
Rails.logger.info("event=retraction status=abort reason='no post found' sender=#{sender.diaspora_handle} target_guid=#{target_guid}")
|
||||||
|
return
|
||||||
|
elsif self.target_author_signature_valid?
|
||||||
|
#this is a retraction from the upstream owner
|
||||||
|
self.perform(recipient)
|
||||||
|
else
|
||||||
|
Rails.logger.info("event=receive status=abort reason='object signature not valid' recipient=#{recipient.diaspora_handle} sender=#{self.sender_handle} payload_type=#{self.class}")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def target_author_signature_valid?
|
||||||
|
verify_signature(self.target_author_signature, self.target.author)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
102
lib/request.rb
102
lib/request.rb
|
|
@ -1,102 +0,0 @@
|
||||||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
|
||||||
# t
|
|
||||||
# licensed under the Affero General Public License version 3 or later. See
|
|
||||||
# the COPYRIGHT file.
|
|
||||||
|
|
||||||
class Request
|
|
||||||
include Diaspora::Federated::Base
|
|
||||||
include ActiveModel::Validations
|
|
||||||
|
|
||||||
attr_accessor :sender, :recipient, :aspect
|
|
||||||
|
|
||||||
xml_accessor :sender_handle
|
|
||||||
xml_accessor :recipient_handle
|
|
||||||
|
|
||||||
validates :sender, :presence => true
|
|
||||||
validates :recipient, :presence => true
|
|
||||||
|
|
||||||
validate :not_already_connected
|
|
||||||
validate :not_friending_yourself
|
|
||||||
|
|
||||||
# Initalize variables
|
|
||||||
# @note we should be using ActiveModel::Serialization for this
|
|
||||||
# @return [Request]
|
|
||||||
def self.diaspora_initialize(opts = {})
|
|
||||||
req = self.new
|
|
||||||
req.sender = opts[:from]
|
|
||||||
req.recipient = opts[:to]
|
|
||||||
req.aspect = opts[:into]
|
|
||||||
req
|
|
||||||
end
|
|
||||||
|
|
||||||
# Alias of sender_handle
|
|
||||||
# @return [String]
|
|
||||||
def diaspora_handle
|
|
||||||
sender_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
# @note Used for XML marshalling
|
|
||||||
# @return [String]
|
|
||||||
def sender_handle
|
|
||||||
sender.diaspora_handle
|
|
||||||
end
|
|
||||||
def sender_handle= sender_handle
|
|
||||||
self.sender = Person.where(:diaspora_handle => sender_handle).first
|
|
||||||
end
|
|
||||||
|
|
||||||
# @note Used for XML marshalling
|
|
||||||
# @return [String]
|
|
||||||
def recipient_handle
|
|
||||||
recipient.diaspora_handle
|
|
||||||
end
|
|
||||||
def recipient_handle= recipient_handle
|
|
||||||
self.recipient = Person.where(:diaspora_handle => recipient_handle).first
|
|
||||||
end
|
|
||||||
|
|
||||||
# Defines the abstract interface used in sending a corresponding [Notification] given the [Request]
|
|
||||||
# @param user [User]
|
|
||||||
# @param person [Person]
|
|
||||||
# @return [Notifications::StartedSharing]
|
|
||||||
def notification_type(user, person)
|
|
||||||
Notifications::StartedSharing
|
|
||||||
end
|
|
||||||
|
|
||||||
# Defines the abstract interface used in sending the [Request]
|
|
||||||
# @param user [User]
|
|
||||||
# @return [Array<Person>] The recipient of the request
|
|
||||||
def subscribers(user)
|
|
||||||
[self.recipient]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Finds or initializes a corresponding [Contact], and will set Contact#sharing to true
|
|
||||||
# Follows back if user setting is set so
|
|
||||||
# @note A [Contact] may already exist if the [Request]'s recipient is sharing with the sender
|
|
||||||
# @return [Request]
|
|
||||||
def receive(user, person)
|
|
||||||
Rails.logger.info("event=receive payload_type=request sender=#{self.sender} to=#{self.recipient}")
|
|
||||||
|
|
||||||
contact = user.contacts.find_or_initialize_by_person_id(self.sender.id)
|
|
||||||
contact.sharing = true
|
|
||||||
contact.save
|
|
||||||
|
|
||||||
user.share_with(person, user.auto_follow_back_aspect) if user.auto_follow_back && !contact.receiving
|
|
||||||
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Checks if a [Contact] does not already exist between the requesting [User] and receiving [Person]
|
|
||||||
def not_already_connected
|
|
||||||
if sender && recipient && Contact.where(:user_id => self.recipient.owner_id, :person_id => self.sender.id).exists?
|
|
||||||
errors[:base] << 'You have already connected to this person'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checks to see that the requesting [User] is not sending a request to himself
|
|
||||||
def not_friending_yourself
|
|
||||||
if self.recipient == self.sender
|
|
||||||
errors[:base] << 'You can not friend yourself'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
|
||||||
# licensed under the Affero General Public License version 3 or later. See
|
|
||||||
# the COPYRIGHT file.
|
|
||||||
|
|
||||||
class Retraction
|
|
||||||
include Diaspora::Federated::Base
|
|
||||||
|
|
||||||
xml_accessor :post_guid
|
|
||||||
xml_accessor :diaspora_handle
|
|
||||||
xml_accessor :type
|
|
||||||
|
|
||||||
attr_accessor :person, :object, :subscribers
|
|
||||||
|
|
||||||
def subscribers(user)
|
|
||||||
unless self.type == 'Person'
|
|
||||||
@subscribers ||= self.object.subscribers(user)
|
|
||||||
@subscribers -= self.object.resharers unless self.object.is_a?(Photo)
|
|
||||||
@subscribers
|
|
||||||
else
|
|
||||||
raise 'HAX: you must set the subscribers manaully before unfriending' if @subscribers.nil?
|
|
||||||
@subscribers
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.for(object)
|
|
||||||
retraction = self.new
|
|
||||||
if object.is_a? User
|
|
||||||
retraction.post_guid = object.person.guid
|
|
||||||
retraction.type = object.person.class.to_s
|
|
||||||
else
|
|
||||||
retraction.post_guid = object.guid
|
|
||||||
retraction.type = object.class.to_s
|
|
||||||
retraction.object = object
|
|
||||||
end
|
|
||||||
retraction.diaspora_handle = object.diaspora_handle
|
|
||||||
retraction
|
|
||||||
end
|
|
||||||
|
|
||||||
def target
|
|
||||||
@target ||= self.type.constantize.where(:guid => post_guid).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def perform receiving_user
|
|
||||||
Rails.logger.debug "Performing retraction for #{post_guid}"
|
|
||||||
|
|
||||||
self.target.destroy if self.target
|
|
||||||
Rails.logger.info("event=retraction status=complete type=#{self.type} guid=#{self.post_guid}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def receive(user, person)
|
|
||||||
if self.type == 'Person'
|
|
||||||
unless self.person.guid.to_s == self.post_guid.to_s
|
|
||||||
Rails.logger.info("event=receive status=abort reason='sender is not the person he is trying to retract' recipient=#{self.diaspora_handle} sender=#{self.person.diaspora_handle} payload_type=#{self.class} retraction_type=person")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
user.disconnected_by(self.target)
|
|
||||||
elsif self.target.nil? || self.target.author != self.person
|
|
||||||
Rails.logger.info("event=retraction status=abort reason='no post found authored by retractor' sender=#{person.diaspora_handle} post_guid=#{post_guid}")
|
|
||||||
else
|
|
||||||
self.perform(user)
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
|
||||||
# licensed under the Affero General Public License version 3 or later. See
|
|
||||||
# the COPYRIGHT file.
|
|
||||||
|
|
||||||
class SignedRetraction
|
|
||||||
include Diaspora::Federated::Base
|
|
||||||
|
|
||||||
include Diaspora::Encryptable
|
|
||||||
|
|
||||||
xml_name :signed_retraction
|
|
||||||
xml_attr :target_guid
|
|
||||||
xml_attr :target_type
|
|
||||||
xml_attr :sender_handle
|
|
||||||
xml_attr :target_author_signature
|
|
||||||
|
|
||||||
attr_accessor :target_guid,
|
|
||||||
:target_type,
|
|
||||||
:target_author_signature,
|
|
||||||
:sender
|
|
||||||
|
|
||||||
#NOTE(fix this hack -- go through the app and make sure we only call RelayableRetraction in a unified way)
|
|
||||||
def author
|
|
||||||
if sender.is_a?(User)
|
|
||||||
sender.person
|
|
||||||
else
|
|
||||||
sender
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def signable_accessors
|
|
||||||
accessors = self.class.roxml_attrs.collect do |definition|
|
|
||||||
definition.accessor
|
|
||||||
end
|
|
||||||
accessors - ['target_author_signature', 'sender_handle']
|
|
||||||
end
|
|
||||||
|
|
||||||
def sender_handle= new_sender_handle
|
|
||||||
@sender = Person.where(:diaspora_handle => new_sender_handle).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def sender_handle
|
|
||||||
@sender.diaspora_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
def diaspora_handle
|
|
||||||
self.sender_handle
|
|
||||||
end
|
|
||||||
|
|
||||||
def subscribers(user)
|
|
||||||
self.target.subscribers(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.build(sender, target)
|
|
||||||
retraction = self.new
|
|
||||||
retraction.sender = sender
|
|
||||||
retraction.target = target
|
|
||||||
retraction.target_author_signature = retraction.sign_with_key(sender.encryption_key) if sender.person == target.author
|
|
||||||
retraction
|
|
||||||
end
|
|
||||||
|
|
||||||
def target
|
|
||||||
@target ||= self.target_type.constantize.where(:guid => target_guid).first
|
|
||||||
end
|
|
||||||
|
|
||||||
def guid
|
|
||||||
target_guid
|
|
||||||
end
|
|
||||||
def target= new_target
|
|
||||||
@target = new_target
|
|
||||||
@target_type = new_target.class.to_s
|
|
||||||
@target_guid = new_target.guid
|
|
||||||
end
|
|
||||||
|
|
||||||
def perform receiving_user
|
|
||||||
Rails.logger.debug "Performing retraction for #{target_guid}"
|
|
||||||
if reshare = Reshare.where(:author_id => receiving_user.person.id, :root_guid => target_guid).first
|
|
||||||
onward_retraction = self.dup
|
|
||||||
onward_retraction.sender = receiving_user.person
|
|
||||||
Postzord::Dispatcher.build(receiving_user, onward_retraction).post
|
|
||||||
end
|
|
||||||
if target
|
|
||||||
self.target.destroy
|
|
||||||
end
|
|
||||||
Rails.logger.info("event=retraction status =complete target_type=#{self.target_type} guid =#{self.target_guid}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def receive(recipient, sender)
|
|
||||||
if self.target.nil?
|
|
||||||
Rails.logger.info("event=retraction status=abort reason='no post found' sender=#{sender.diaspora_handle} target_guid=#{target_guid}")
|
|
||||||
return
|
|
||||||
elsif self.target_author_signature_valid?
|
|
||||||
#this is a retraction from the upstream owner
|
|
||||||
self.perform(recipient)
|
|
||||||
else
|
|
||||||
Rails.logger.info("event=receive status=abort reason='object signature not valid' recipient=#{recipient.diaspora_handle} sender=#{self.sender_handle} payload_type=#{self.class}")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self
|
|
||||||
end
|
|
||||||
|
|
||||||
def target_author_signature_valid?
|
|
||||||
verify_signature(self.target_author_signature, self.target.author)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
@ -4,8 +4,9 @@
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require Rails.root.join("spec", "shared_behaviors", "relayable")
|
require Rails.root.join("spec", "shared_behaviors", "relayable")
|
||||||
|
require Rails.root.join('lib', 'diaspora', 'federated', 'messages')
|
||||||
|
|
||||||
describe RelayableRetraction do
|
describe Diaspora::Federated::Messages::RelayableRetraction do
|
||||||
before do
|
before do
|
||||||
@local_luke, @local_leia, @remote_raphael = set_up_friends
|
@local_luke, @local_leia, @remote_raphael = set_up_friends
|
||||||
@remote_parent = FactoryGirl.build(:status_message, :author => @remote_raphael)
|
@remote_parent = FactoryGirl.build(:status_message, :author => @remote_raphael)
|
||||||
|
|
@ -3,8 +3,9 @@
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require Rails.root.join('lib', 'diaspora', 'federated', 'messages')
|
||||||
|
|
||||||
describe Request do
|
describe Diaspora::Federated::Messages::Request do
|
||||||
before do
|
before do
|
||||||
@aspect = alice.aspects.first
|
@aspect = alice.aspects.first
|
||||||
end
|
end
|
||||||
|
|
@ -3,8 +3,9 @@
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require Rails.root.join('lib', 'diaspora', 'federated', 'messages')
|
||||||
|
|
||||||
describe Retraction do
|
describe Diaspora::Federated::Messages::Retraction do
|
||||||
before do
|
before do
|
||||||
@aspect = alice.aspects.first
|
@aspect = alice.aspects.first
|
||||||
alice.contacts.create(:person => eve.person, :aspects => [@aspect])
|
alice.contacts.create(:person => eve.person, :aspects => [@aspect])
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require Rails.root.join('lib', 'diaspora', 'federated', 'messages')
|
||||||
|
|
||||||
describe SignedRetraction do
|
describe Diaspora::Federated::Messages::SignedRetraction do
|
||||||
before do
|
before do
|
||||||
@post = FactoryGirl.create(:status_message, :author => bob.person, :public => true)
|
@post = FactoryGirl.create(:status_message, :author => bob.person, :public => true)
|
||||||
@resharer = FactoryGirl.create(:user)
|
@resharer = FactoryGirl.create(:user)
|
||||||
Loading…
Reference in a new issue