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

Update the user data export archive format. #6726

Merged
merged 10 commits into from Aug 10, 2017
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions Gemfile
Expand Up @@ -13,7 +13,8 @@ gem "unicorn-worker-killer", "0.4.4"

# Federation

gem "diaspora_federation-rails", "0.2.0"
gem "diaspora_federation-json_schema", "0.2.1"
gem "diaspora_federation-rails", "0.2.1"

# API and JSON

Expand Down Expand Up @@ -277,6 +278,8 @@ group :test do

gem "fixture_builder", "0.5.0"
gem "fuubar", "2.2.0"
gem "json-schema-rspec", "0.0.4"
gem "rspec-json_expectations", "~> 2.1"
gem "test_after_commit", "1.1.0"

# Cucumber (integration tests)
Expand All @@ -294,7 +297,7 @@ group :test do
gem "timecop", "0.9.1"
gem "webmock", "3.0.1", require: false

gem "diaspora_federation-test", "0.2.0"
gem "diaspora_federation-test", "0.2.1"

# Coverage
gem 'coveralls', require: false
Expand Down
26 changes: 17 additions & 9 deletions Gemfile.lock
Expand Up @@ -162,17 +162,18 @@ GEM
devise
rails (>= 3.0.4)
diaspora-prosody-config (0.0.7)
diaspora_federation (0.2.0)
diaspora_federation (0.2.1)
faraday (>= 0.9.0, < 0.13.0)
faraday_middleware (>= 0.10.0, < 0.12.0)
faraday_middleware (>= 0.10.0, < 0.13.0)
nokogiri (~> 1.6, >= 1.6.8)
typhoeus (~> 1.0)
valid (~> 1.0)
diaspora_federation-rails (0.2.0)
diaspora_federation-json_schema (0.2.1)
diaspora_federation-rails (0.2.1)
actionpack (>= 4.2, < 6)
diaspora_federation (= 0.2.0)
diaspora_federation-test (0.2.0)
diaspora_federation (= 0.2.0)
diaspora_federation (= 0.2.1)
diaspora_federation-test (0.2.1)
diaspora_federation (= 0.2.1)
fabrication (~> 2.16.0)
uuid (~> 2.3.8)
diff-lcs (1.3)
Expand All @@ -199,7 +200,7 @@ GEM
sigar (~> 0.7.3)
state_machines
thor
fabrication (2.16.1)
fabrication (2.16.2)
factory_girl (4.8.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.8.0)
Expand Down Expand Up @@ -334,6 +335,9 @@ GEM
url_safe_base64
json-schema (2.8.0)
addressable (>= 2.4)
json-schema-rspec (0.0.4)
json-schema (~> 2.5)
rspec
jsonpath (0.8.5)
multi_json
jwt (1.5.6)
Expand Down Expand Up @@ -582,6 +586,7 @@ GEM
rspec-expectations (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-json_expectations (2.1.0)
rspec-mocks (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
Expand Down Expand Up @@ -772,8 +777,9 @@ DEPENDENCIES
devise (= 4.3.0)
devise_lastseenable (= 0.0.6)
diaspora-prosody-config (= 0.0.7)
diaspora_federation-rails (= 0.2.0)
diaspora_federation-test (= 0.2.0)
diaspora_federation-json_schema (= 0.2.1)
diaspora_federation-rails (= 0.2.1)
diaspora_federation-test (= 0.2.1)
entypo-rails (= 3.0.0)
eye (= 0.9.2)
factory_girl_rails (= 4.8.0)
Expand All @@ -800,6 +806,7 @@ DEPENDENCIES
js_image_paths (= 0.1.0)
json (= 2.1.0)
json-schema (= 2.8.0)
json-schema-rspec (= 0.0.4)
leaflet-rails (= 1.1.0)
logging-rails (= 0.6.0)
markerb (= 1.1.0)
Expand Down Expand Up @@ -858,6 +865,7 @@ DEPENDENCIES
rb-inotify (= 0.9.10)
redcarpet (= 3.4.0)
responders (= 2.4.0)
rspec-json_expectations (~> 2.1)
rspec-rails (= 3.6.0)
rubocop (= 0.49.1)
ruby-oembed (= 0.12.0)
Expand Down
6 changes: 4 additions & 2 deletions app/models/person.rb
Expand Up @@ -37,7 +37,9 @@ def downcase_diaspora_handle
has_many :posts, :foreign_key => :author_id, :dependent => :destroy # This person's own posts
has_many :photos, :foreign_key => :author_id, :dependent => :destroy # This person's own photos
has_many :comments, :foreign_key => :author_id, :dependent => :destroy # This person's own comments
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 :roles
Expand Down Expand Up @@ -76,8 +78,8 @@ def downcase_diaspora_handle

#not defensive
scope :in_aspects, ->(aspect_ids) {
joins(:contacts => :aspect_memberships).
where(:aspect_memberships => {:aspect_id => aspect_ids})
joins(contacts: :aspect_memberships)
.where(aspect_memberships: {aspect_id: aspect_ids}).distinct
}

scope :profile_tagged_with, ->(tag_name) {
Expand Down
1 change: 1 addition & 0 deletions app/models/poll_participation.rb
Expand Up @@ -6,6 +6,7 @@ class PollParticipation < ActiveRecord::Base

belongs_to :poll
belongs_to :poll_answer, counter_cache: :vote_count
has_one :status_message, through: :poll

has_one :signature, class_name: "PollParticipationSignature", dependent: :delete

Expand Down
11 changes: 11 additions & 0 deletions app/models/post.rb
Expand Up @@ -54,6 +54,17 @@ class Post < ActiveRecord::Base
joins(:likes).where(:likes => {:author_id => person.id})
}

scope :subscribed_by, ->(user) {
joins(:participations).where(participations: {author_id: user.person_id})
}

scope :reshares, -> { where(type: "Reshare") }

scope :reshared_by, ->(person) {
# we join on the same table, Rails renames "posts" to "reshares_posts" for the right table
joins(:reshares).where(reshares_posts: {author_id: person.id})
}

def post_type
self.class.name
end
Expand Down
1 change: 1 addition & 0 deletions app/models/status_message.rb
Expand Up @@ -19,6 +19,7 @@ class StatusMessage < Post

has_one :location
has_one :poll, autosave: true
has_many :poll_participations, through: :poll

attr_accessor :oembed_url
attr_accessor :open_graph_url
Expand Down
11 changes: 0 additions & 11 deletions app/serializers/export/comment_serializer.rb

This file was deleted.

28 changes: 25 additions & 3 deletions app/serializers/export/contact_serializer.rb
Expand Up @@ -2,11 +2,33 @@ module Export
class ContactSerializer < ActiveModel::Serializer
attributes :sharing,
:receiving,
:following,
:followed,
:person_guid,
:person_name,
:person_first_name,
:person_diaspora_handle
:account_id,
:public_key

has_many :aspects, each_serializer: Export::AspectSerializer
has_many :contact_groups_membership

def following
object.sharing
end

def followed
object.receiving
end

def account_id
object.person_diaspora_handle
end

def contact_groups_membership
object.aspects.map(&:name)
end

def public_key
object.person.serialized_public_key
end
end
end
34 changes: 34 additions & 0 deletions app/serializers/export/others_data_serializer.rb
@@ -0,0 +1,34 @@
module Export
class OthersDataSerializer < ActiveModel::Serializer
# Relayables of other people in the archive: comments, likes, participations, poll participations where author is
# the archive owner
has_many :relayables, each_serializer: FederationEntitySerializer

# Parent posts of user's own relayables. We have to save metadata to use
# it in case when posts temporary unavailable on the target pod.
has_many :posts, each_serializer: FederationEntitySerializer

# Authors of posts where we participated and authors are not in contacts
has_many :non_contact_authors, each_serializer: PersonMetadataSerializer

private

def relayables
%i[comments likes poll_participations].map {|relayable|
others_relayables.send(relayable)
}.sum
end

def others_relayables
@others_relayables ||= Diaspora::Exporter::OthersRelayables.new(object.person_id)
end

def posts
@posts ||= Diaspora::Exporter::PostsWithActivity.new(object).query
end

def non_contact_authors
Diaspora::Exporter::NonContactAuthors.new(posts, object).query
end
end
end
33 changes: 33 additions & 0 deletions app/serializers/export/own_post_serializer.rb
@@ -0,0 +1,33 @@
module Export
# This is a serializer for the user's own posts
class OwnPostSerializer < FederationEntitySerializer
# Only for public posts.
# Includes URIs of pods which must be notified on the post updates.
# Must always include local pod URI since we will want all the updates on the post if user migrates.
has_many :subscribed_pods_uris

# Only for private posts.
# Includes diaspora* IDs of people who must be notified on post updates.
has_many :subscribed_users_ids

# Normally accepts Post as an object.
def initialize(*)
super
self.except = [excluded_subscription_key]
end

private

def subscribed_pods_uris
object.subscribed_pods_uris.push(AppConfig.pod_uri.to_s)
end

def subscribed_users_ids
object.subscribers.map(&:diaspora_handle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just saw that subscribers returns the person multiple times, when you have the person in multiple aspects.

That's because Person.in_aspects which is used in User.people_in_aspects returns the person multiple times. So we should filter that somewhere instead of adding the diaspora ID multiple times to the export. (That is also broken in the federation, we encrypt the message multiple times, but send it only once, because the target-url is used as a key)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you still able to reinsert the contact in the correct aspects if you do that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, only the diaspora ID is used here. For the contacts the aspect names are exported here, so that are two different things.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think it should be okay to add distinct to the query in the Person.in_aspects scope.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's also what I would do. I didn't check if anything breaks, but I think it should work.

end

def excluded_subscription_key
entity.public ? :subscribed_users_ids : :subscribed_pods_uris
end
end
end
13 changes: 13 additions & 0 deletions app/serializers/export/own_relayables_serializer.rb
@@ -0,0 +1,13 @@
module Export
# This is a serializer for the user's own relayables. We remove signature from the own relayables since it isn't
# useful and takes space.
class OwnRelayablesSerializer < FederationEntitySerializer
private

def modify_serializable_object(hash)
super.tap {|hash|
hash[:entity_data].delete(:author_signature)
}
end
end
end
17 changes: 17 additions & 0 deletions app/serializers/export/person_metadata_serializer.rb
@@ -0,0 +1,17 @@
module Export
class PersonMetadataSerializer < ActiveModel::Serializer
attributes :guid,
:account_id,
:public_key

private

def account_id
object.diaspora_handle
end

def public_key
object.serialized_public_key
end
end
end
13 changes: 0 additions & 13 deletions app/serializers/export/post_serializer.rb

This file was deleted.

14 changes: 0 additions & 14 deletions app/serializers/export/profile_serializer.rb

This file was deleted.