Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into 2236-no-name
This commit is contained in:
commit
9542c5d0f4
|
@ -1,11 +1,41 @@
|
||||||
# ChatMessages
|
# AP Extensions
|
||||||
|
## Actor endpoints
|
||||||
|
|
||||||
ChatMessages are the messages sent in 1-on-1 chats. They are similar to
|
The following endpoints are additionally present into our actors.
|
||||||
|
|
||||||
|
- `oauthRegistrationEndpoint` (`http://litepub.social/ns#oauthRegistrationEndpoint`)
|
||||||
|
- `uploadMedia` (`https://www.w3.org/ns/activitystreams#uploadMedia`)
|
||||||
|
|
||||||
|
### oauthRegistrationEndpoint
|
||||||
|
|
||||||
|
Points to MastodonAPI `/api/v1/apps` for now.
|
||||||
|
|
||||||
|
See <https://docs.joinmastodon.org/methods/apps/>
|
||||||
|
|
||||||
|
### uploadMedia
|
||||||
|
|
||||||
|
Inspired by <https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload>, it is part of the ActivityStreams namespace because it used to be part of the ActivityPub specification and got removed from it.
|
||||||
|
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- (required) `file`: The file being uploaded
|
||||||
|
- (optionnal) `description`: A plain-text description of the media, for accessibility purposes.
|
||||||
|
|
||||||
|
Response: HTTP 201 Created with the object into the body, no `Location` header provided as it doesn't have an `id`
|
||||||
|
|
||||||
|
The object given in the reponse should then be inserted into an Object's `attachment` field.
|
||||||
|
|
||||||
|
## ChatMessages
|
||||||
|
|
||||||
|
`ChatMessage`s are the messages sent in 1-on-1 chats. They are similar to
|
||||||
`Note`s, but the addresing is done by having a single AP actor in the `to`
|
`Note`s, but the addresing is done by having a single AP actor in the `to`
|
||||||
field. Addressing multiple actors is not allowed. These messages are always
|
field. Addressing multiple actors is not allowed. These messages are always
|
||||||
private, there is no public version of them. They are created with a `Create`
|
private, there is no public version of them. They are created with a `Create`
|
||||||
activity.
|
activity.
|
||||||
|
|
||||||
|
They are part of the `litepub` namespace as `http://litepub.social/ns#ChatMessage`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
|
@ -43,7 +43,7 @@ Other than things bundled in the OTP release Pleroma depends on:
|
||||||
|
|
||||||
### Installing optional packages
|
### Installing optional packages
|
||||||
|
|
||||||
Per [`docs/installation/optional/media_graphics_packages.md`](docs/installation/optional/media_graphics_packages.md):
|
Per [`docs/installation/optional/media_graphics_packages.md`](optional/media_graphics_packages.md):
|
||||||
* ImageMagick
|
* ImageMagick
|
||||||
* ffmpeg
|
* ffmpeg
|
||||||
* exiftool
|
* exiftool
|
||||||
|
|
|
@ -31,8 +31,6 @@ ProtectHome=true
|
||||||
ProtectSystem=full
|
ProtectSystem=full
|
||||||
; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled by default because it may not work on devices like the Raspberry Pi.
|
; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled by default because it may not work on devices like the Raspberry Pi.
|
||||||
PrivateDevices=false
|
PrivateDevices=false
|
||||||
; Ensures that the service process and all its children can never gain new privileges through execve().
|
|
||||||
NoNewPrivileges=true
|
|
||||||
; Drops the sysadmin capability from the daemon.
|
; Drops the sysadmin capability from the daemon.
|
||||||
CapabilityBoundingSet=~CAP_SYS_ADMIN
|
CapabilityBoundingSet=~CAP_SYS_ADMIN
|
||||||
|
|
||||||
|
|
|
@ -525,19 +525,6 @@ defp ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do
|
||||||
{new_user, for_user}
|
{new_user, for_user}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
|
||||||
Endpoint based on <https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload>
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
- (required) `file`: data of the media
|
|
||||||
- (optionnal) `description`: description of the media, intended for accessibility
|
|
||||||
|
|
||||||
Response:
|
|
||||||
- HTTP Code: 201 Created
|
|
||||||
- HTTP Body: ActivityPub object to be inserted into another's `attachment` field
|
|
||||||
|
|
||||||
Note: Will not point to a URL with a `Location` header because no standalone Activity has been created.
|
|
||||||
"""
|
|
||||||
def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do
|
def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do
|
||||||
with {:ok, object} <-
|
with {:ok, object} <-
|
||||||
ActivityPub.upload(
|
ActivityPub.upload(
|
||||||
|
|
|
@ -40,6 +40,7 @@ def fix_object(object, options \\ []) do
|
||||||
|> fix_in_reply_to(options)
|
|> fix_in_reply_to(options)
|
||||||
|> fix_emoji
|
|> fix_emoji
|
||||||
|> fix_tag
|
|> fix_tag
|
||||||
|
|> set_sensitive
|
||||||
|> fix_content_map
|
|> fix_content_map
|
||||||
|> fix_addressing
|
|> fix_addressing
|
||||||
|> fix_summary
|
|> fix_summary
|
||||||
|
@ -313,19 +314,21 @@ def fix_tag(%{"tag" => tag} = object) when is_list(tag) do
|
||||||
tags =
|
tags =
|
||||||
tag
|
tag
|
||||||
|> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
|
|> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
|
||||||
|> Enum.map(fn data -> String.slice(data["name"], 1..-1) end)
|
|> Enum.map(fn %{"name" => name} ->
|
||||||
|
name
|
||||||
|
|> String.slice(1..-1)
|
||||||
|
|> String.downcase()
|
||||||
|
end)
|
||||||
|
|
||||||
Map.put(object, "tag", tag ++ tags)
|
Map.put(object, "tag", tag ++ tags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fix_tag(%{"tag" => %{"type" => "Hashtag", "name" => hashtag} = tag} = object) do
|
def fix_tag(%{"tag" => %{} = tag} = object) do
|
||||||
combined = [tag, String.slice(hashtag, 1..-1)]
|
object
|
||||||
|
|> Map.put("tag", [tag])
|
||||||
Map.put(object, "tag", combined)
|
|> fix_tag
|
||||||
end
|
end
|
||||||
|
|
||||||
def fix_tag(%{"tag" => %{} = tag} = object), do: Map.put(object, "tag", [tag])
|
|
||||||
|
|
||||||
def fix_tag(object), do: object
|
def fix_tag(object), do: object
|
||||||
|
|
||||||
# content map usually only has one language so this will do for now.
|
# content map usually only has one language so this will do for now.
|
||||||
|
@ -927,7 +930,7 @@ def set_conversation(object) do
|
||||||
Map.put(object, "conversation", object["context"])
|
Map.put(object, "conversation", object["context"])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_sensitive(%{"sensitive" => true} = object) do
|
def set_sensitive(%{"sensitive" => _} = object) do
|
||||||
object
|
object
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
68
test/fixtures/mastodon-post-activity-nsfw.json
vendored
Normal file
68
test/fixtures/mastodon-post-activity-nsfw.json
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{
|
||||||
|
"Emoji": "toot:Emoji",
|
||||||
|
"Hashtag": "as:Hashtag",
|
||||||
|
"atomUri": "ostatus:atomUri",
|
||||||
|
"conversation": "ostatus:conversation",
|
||||||
|
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
|
||||||
|
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||||
|
"movedTo": "as:movedTo",
|
||||||
|
"ostatus": "http://ostatus.org#",
|
||||||
|
"toot": "http://joinmastodon.org/ns#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actor": "http://mastodon.example.org/users/admin",
|
||||||
|
"cc": [
|
||||||
|
"http://mastodon.example.org/users/admin/followers",
|
||||||
|
"http://localtesting.pleroma.lol/users/lain"
|
||||||
|
],
|
||||||
|
"id": "http://mastodon.example.org/users/admin/statuses/99512778738411822/activity",
|
||||||
|
"nickname": "lain",
|
||||||
|
"object": {
|
||||||
|
"atomUri": "http://mastodon.example.org/users/admin/statuses/99512778738411822",
|
||||||
|
"attachment": [],
|
||||||
|
"attributedTo": "http://mastodon.example.org/users/admin",
|
||||||
|
"cc": [
|
||||||
|
"http://mastodon.example.org/users/admin/followers",
|
||||||
|
"http://localtesting.pleroma.lol/users/lain"
|
||||||
|
],
|
||||||
|
"content": "<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span> #moo</p>",
|
||||||
|
"conversation": "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation",
|
||||||
|
"id": "http://mastodon.example.org/users/admin/statuses/99512778738411822",
|
||||||
|
"inReplyTo": null,
|
||||||
|
"inReplyToAtomUri": null,
|
||||||
|
"published": "2018-02-12T14:08:20Z",
|
||||||
|
"summary": "cw",
|
||||||
|
"tag": [
|
||||||
|
{
|
||||||
|
"href": "http://localtesting.pleroma.lol/users/lain",
|
||||||
|
"name": "@lain@localtesting.pleroma.lol",
|
||||||
|
"type": "Mention"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "http://mastodon.example.org/tags/nsfw",
|
||||||
|
"name": "#NSFW",
|
||||||
|
"type": "Hashtag"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"type": "Note",
|
||||||
|
"url": "http://mastodon.example.org/@admin/99512778738411822"
|
||||||
|
},
|
||||||
|
"published": "2018-02-12T14:08:20Z",
|
||||||
|
"signature": {
|
||||||
|
"created": "2018-02-12T14:08:20Z",
|
||||||
|
"creator": "http://mastodon.example.org/users/admin#main-key",
|
||||||
|
"signatureValue": "rnNfcopkc6+Ju73P806popcfwrK9wGYHaJVG1/ZvrlEbWVDzaHjkXqj9Q3/xju5l8CSn9tvSgCCtPFqZsFQwn/pFIFUcw7ZWB2xi4bDm3NZ3S4XQ8JRaaX7og5hFxAhWkGhJhAkfxVnOg2hG+w2d/7d7vRVSC1vo5ip4erUaA/PkWusZvPIpxnRWoXaxJsFmVx0gJgjpJkYDyjaXUlp+jmaoseeZ4EPQUWqHLKJ59PRG0mg8j2xAjYH9nQaN14qMRmTGPxY8gfv/CUFcatA+8VJU9KEsJkDAwLVvglydNTLGrxpAJU78a2eaht0foV43XUIZGe3DKiJPgE+UOKGCJw==",
|
||||||
|
"type": "RsaSignature2017"
|
||||||
|
},
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"type": "Create"
|
||||||
|
}
|
|
@ -206,6 +206,16 @@ test "it works for incoming notices" do
|
||||||
assert user.note_count == 1
|
assert user.note_count == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it works for incoming notices without the sensitive property but an nsfw hashtag" do
|
||||||
|
data = File.read!("test/fixtures/mastodon-post-activity-nsfw.json") |> Poison.decode!()
|
||||||
|
|
||||||
|
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||||
|
|
||||||
|
object_data = Object.normalize(data["object"], false).data
|
||||||
|
|
||||||
|
assert object_data["sensitive"] == true
|
||||||
|
end
|
||||||
|
|
||||||
test "it works for incoming notices with hashtags" do
|
test "it works for incoming notices with hashtags" do
|
||||||
data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!()
|
data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue