diff --git a/docs/_entities/profile.md b/docs/_entities/profile.md
index bb93118..433e9dd 100644
--- a/docs/_entities/profile.md
+++ b/docs/_entities/profile.md
@@ -4,6 +4,21 @@ title: Profile
This entity contains all the profile data of a person.
+The profile consists of two parts. The first is the base profile with the name,
+the avatar and the tags of the person. This part is always public and visible to
+everyone. The boolean flags (`searchable`, `public` and `nsfw`) are metadata and
+public too.
+
+The second part is the extended profile consisting of `bio`, `birthday`, `gender`
+and `location` is not public by default (and only visible to contacts the person
+shares with). The owner of the profile can decide if this information should be
+public (that's what the `public` flag is for) and then the extended profile is
+visible to non-contacts too.
+
+Because of that there is a special case where the `public`-flag is `false`, but
+the profile was received via the public route. In this case the profile should
+only contain the base profile.
+
## Properties
| Property | Type | Description |
@@ -19,9 +34,9 @@ This entity contains all the profile data of a person.
| `image_url` | [URL][url] (255) | The URL to the big avatar (300x300) of the person. |
| `image_url_medium` | [URL][url] (255) | The URL to the medium avatar (100x100) of the person. |
| `image_url_small` | [URL][url] (255) | The URL to the small avatar (50x50) of the person. |
+| `bio` | [Markdown][markdown] (65535) | The description of the person. This field can contain markdown. |
| `birthday` | [Date][date] | The birthday of the person. The year may be `1004` or less, if the person specifies only day and month. |
| `gender` | [String][string] (255) | The gender of the person. |
-| `bio` | [Markdown][markdown] (65535) | The description of the person. This field can contain markdown. |
| `location` | [String][string] (255) | The location of the person. |
| `searchable` | [Boolean][boolean] | `false` if the person doesn't want to be searchable by name. |
| `public` | [Boolean][boolean] | `true` if the profile is visible to everyone. |
@@ -38,9 +53,9 @@ This entity contains all the profile data of a person.
https://example.org/images/thumb_large_a795f872c93309597345.jpg
https://example.org/images/thumb_medium_a795f872c93309597345.jpg
https://example.org/images/thumb_small_a795f872c93309597345.jpg
+ some text about me
1988-07-15
Male
- some text about me
github
true
false
diff --git a/lib/diaspora_federation/federation/receiver/public.rb b/lib/diaspora_federation/federation/receiver/public.rb
index c4d1a8b..7711088 100644
--- a/lib/diaspora_federation/federation/receiver/public.rb
+++ b/lib/diaspora_federation/federation/receiver/public.rb
@@ -7,11 +7,18 @@ module DiasporaFederation
def validate
super
- raise NotPublic if entity_can_be_public_but_it_is_not?
+ validate_public_flag
end
- def entity_can_be_public_but_it_is_not?
- entity.respond_to?(:public) && !entity.public
+ def validate_public_flag
+ return if !entity.respond_to?(:public) || entity.public
+
+ if entity.is_a?(Entities::Profile) &&
+ %i[bio birthday gender location].all? {|prop| entity.public_send(prop).nil? }
+ return
+ end
+
+ raise NotPublic, "received entity #{entity} should be public!"
end
end
end
diff --git a/spec/lib/diaspora_federation/federation/receiver/public_spec.rb b/spec/lib/diaspora_federation/federation/receiver/public_spec.rb
index 0096120..9815490 100644
--- a/spec/lib/diaspora_federation/federation/receiver/public_spec.rb
+++ b/spec/lib/diaspora_federation/federation/receiver/public_spec.rb
@@ -116,7 +116,7 @@ module DiasporaFederation
described_class.new(magic_env).receive
end
- it "does not allow non-public entities" do
+ it "doesn't allow non-public entities" do
private_post = Fabricate(:status_message_entity, public: false)
magic_env = Salmon::MagicEnvelope.new(private_post, private_post.author)
@@ -133,6 +133,24 @@ module DiasporaFederation
described_class.new(magic_env).receive
end
+
+ it "allows profiles flagged as private if they don't contain private information" do
+ profile = Fabricate(:profile_entity, public: false, bio: nil, birthday: nil, gender: nil, location: nil)
+ magic_env = Salmon::MagicEnvelope.new(profile, profile.author)
+
+ expect_callback(:receive_entity, profile, profile.author, nil)
+
+ described_class.new(magic_env).receive
+ end
+
+ it "doesn't allow profiles flagged as private if they contain private information" do
+ profile = Fabricate(:profile_entity, public: false)
+ magic_env = Salmon::MagicEnvelope.new(profile, profile.author)
+
+ expect {
+ described_class.new(magic_env).receive
+ }.to raise_error Federation::Receiver::NotPublic
+ end
end
context "with text" do