Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pleroma
pleroma
Commits
68437558
Commit
68437558
authored
May 01, 2017
by
lain
Browse files
Make outgoing salmons work.
parent
bed0b398
Changes
8
Hide whitespace changes
Inline
Side-by-side
TODO.txt
View file @
68437558
- Add cache for user fetching / representing. (mostly in TwitterAPI.activity_to_status)
Unliking:
- Add a proper undo activity, find out how to ignore those in twitter api.
WEBSUB:
- Add unsubscription
- Add periodical renewal
lib/pleroma/user.ex
View file @
68437558
...
...
@@ -121,7 +121,7 @@ def get_cached_by_ap_id(ap_id) do
def
get_cached_by_nickname
(
nickname
)
do
key
=
"nickname:
#{
nickname
}
"
Cachex
.
get!
(
:user_cache
,
key
,
fallback:
fn
(
_
)
->
Repo
.
get_by
(
User
,
nickname
:
nickname
)
end
)
Cachex
.
get!
(
:user_cache
,
key
,
fallback:
fn
(
_
)
->
get_or_fetch_by_
nickname
(
nickname
)
end
)
end
def
get_by_nickname
(
nickname
)
do
...
...
@@ -137,7 +137,8 @@ def get_or_fetch_by_nickname(nickname) do
with
%
User
{}
=
user
<-
get_by_nickname
(
nickname
)
do
user
else
_e
->
with
{
:ok
,
user
}
<-
OStatus
.
make_user
(
nickname
)
do
with
[
nick
,
domain
]
<-
String
.
split
(
nickname
,
"@"
),
{
:ok
,
user
}
<-
OStatus
.
make_user
(
nickname
)
do
user
else
_e
->
nil
end
...
...
lib/pleroma/web/federator/federator.ex
View file @
68437558
...
...
@@ -7,7 +7,11 @@ defmodule Pleroma.Web.Federator do
def
handle
(
:publish
,
activity
)
do
Logger
.
debug
(
"Running publish for
#{
activity
.
data
[
"id"
]
}
"
)
with
actor
when
not
is_nil
(
actor
)
<-
User
.
get_cached_by_ap_id
(
activity
.
data
[
"actor"
])
do
Logger
.
debug
(
"Sending
#{
activity
.
data
[
"id"
]
}
out via websub"
)
Pleroma
.
Web
.
Websub
.
publish
(
Pleroma
.
Web
.
OStatus
.
feed_path
(
actor
),
actor
,
activity
)
Logger
.
debug
(
"Sending
#{
activity
.
data
[
"id"
]
}
out via salmon"
)
Pleroma
.
Web
.
Salmon
.
publish
(
actor
,
activity
)
end
end
...
...
lib/pleroma/web/ostatus/activity_representer.ex
View file @
68437558
defmodule
Pleroma
.
Web
.
OStatus
.
ActivityRepresenter
do
alias
Pleroma
.
Activity
alias
Pleroma
.
Web
.
OStatus
.
UserRepresenter
require
Logger
defp
get_in_reply_to
(%{
"object"
=>
%{
"inReplyTo"
=>
in_reply_to
}})
do
...
...
@@ -8,7 +9,17 @@ defp get_in_reply_to(%{"object" => %{ "inReplyTo" => in_reply_to}}) do
defp
get_in_reply_to
(
_
),
do
:
[]
def
to_simple_form
(%{
data:
%{
"object"
=>
%{
"type"
=>
"Note"
}}}
=
activity
,
user
)
do
defp
get_mentions
(
to
)
do
Enum
.
map
(
to
,
fn
(
"https://www.w3.org/ns/activitystreams#Public"
)
->
{
:link
,
[
rel:
"mentioned"
,
"ostatus:object-type"
:
"http://activitystrea.ms/schema/1.0/collection"
,
href:
"http://activityschema.org/collection/public"
],
[]}
(
id
)
->
{
:link
,
[
rel:
"mentioned"
,
"ostatus:object-type"
:
"http://activitystrea.ms/schema/1.0/person"
,
href:
id
],
[]}
end
)
end
def
to_simple_form
(
activity
,
user
,
with_author
\\
false
)
def
to_simple_form
(%{
data:
%{
"object"
=>
%{
"type"
=>
"Note"
}}}
=
activity
,
user
,
with_author
)
do
h
=
fn
(
str
)
->
[
to_charlist
(
str
)]
end
updated_at
=
activity
.
updated_at
...
...
@@ -22,6 +33,8 @@ def to_simple_form(%{data: %{"object" => %{"type" => "Note"}}} = activity, user)
end
)
in_reply_to
=
get_in_reply_to
(
activity
.
data
)
author
=
if
with_author
,
do
:
[{
:author
,
UserRepresenter
.
to_simple_form
(
user
)}],
else
:
[]
mentions
=
activity
.
data
[
"to"
]
|>
get_mentions
[
{
:"activity:object-type"
,
[
'http://activitystrea.ms/schema/1.0/note'
]},
...
...
@@ -33,8 +46,20 @@ def to_simple_form(%{data: %{"object" => %{"type" => "Note"}}} = activity, user)
{
:updated
,
h
.
(
updated_at
)},
{
:"ostatus:conversation"
,
[],
h
.
(
activity
.
data
[
"context"
])},
{
:link
,
[
href:
h
.
(
activity
.
data
[
"context"
]),
rel:
'ostatus:conversation'
],
[]}
]
++
attachments
++
in_reply_to
]
++
attachments
++
in_reply_to
++
author
++
mentions
end
def
wrap_with_entry
(
simple_form
)
do
[{
:entry
,
[
xmlns:
'http://www.w3.org/2005/Atom'
,
"xmlns:thr"
:
'http://purl.org/syndication/thread/1.0'
,
"xmlns:activity"
:
'http://activitystrea.ms/spec/1.0/'
,
"xmlns:poco"
:
'http://portablecontacts.net/spec/1.0'
,
"xmlns:ostatus"
:
'http://ostatus.org/schema/1.0'
],
simple_form
}]
end
def
to_simple_form
(
_
,
_
),
do
:
nil
def
to_simple_form
(
_
,
_
,
_
),
do
:
nil
end
lib/pleroma/web/salmon/salmon.ex
View file @
68437558
defmodule
Pleroma
.
Web
.
Salmon
do
use
Bitwise
alias
Pleroma
.
Web
.
XML
alias
Pleroma
.
Web
.
OStatus
.
ActivityRepresenter
alias
Pleroma
.
User
require
Logger
def
decode
(
salmon
)
do
doc
=
XML
.
parse_document
(
salmon
)
...
...
@@ -118,4 +121,37 @@ def encode(private_key, doc) do
{
:ok
,
salmon
}
end
def
remote_users
(%{
data:
%{
"to"
=>
to
}})
do
to
|>
Enum
.
map
(
fn
(
id
)
->
User
.
get_cached_by_ap_id
(
id
)
end
)
|>
Enum
.
filter
(
fn
(
user
)
->
user
&&
!user
.
local
end
)
end
defp
send_to_user
(%{
info:
%{
"salmon"
=>
salmon
}},
feed
,
poster
)
do
poster
.
(
salmon
,
feed
,
[{
"Content-Type"
,
"application/magic-envelope+xml"
}])
end
defp
send_to_user
(
_
,
_
,
_
),
do
:
nil
def
publish
(
user
,
activity
,
poster
\\
&
HTTPoison
.
post
/
3
)
def
publish
(%{
info:
%{
"keys"
=>
keys
}}
=
user
,
activity
,
poster
)
do
feed
=
ActivityRepresenter
.
to_simple_form
(
activity
,
user
,
true
)
|>
ActivityRepresenter
.
wrap_with_entry
|>
:xmerl
.
export_simple
(
:xmerl_xml
)
|>
to_string
if
feed
do
{
:ok
,
private
,
_
}
=
keys_from_pem
(
keys
)
{
:ok
,
feed
}
=
encode
(
private
,
feed
)
remote_users
(
activity
)
|>
Enum
.
each
(
fn
(
remote_user
)
->
Logger
.
debug
(
"sending salmon to
#{
remote_user
.
ap_id
}
"
)
send_to_user
(
remote_user
,
feed
,
poster
)
end
)
end
end
def
publish
(%{
id:
id
},
_
,
_
),
do
:
Logger
.
debug
(
"Keys missing for user
#{
id
}
"
)
end
test/user_test.exs
View file @
68437558
...
...
@@ -95,6 +95,7 @@ test "gets an existing user" do
assert
user
==
fetched_user
end
# TODO: Make the test local.
test
"fetches an external user via ostatus if no user exists"
do
fetched_user
=
User
.
get_or_fetch_by_nickname
(
"shp@social.heldscal.la"
)
assert
fetched_user
.
nickname
==
"shp@social.heldscal.la"
...
...
@@ -104,6 +105,11 @@ test "returns nil if no user could be fetched" do
fetched_user
=
User
.
get_or_fetch_by_nickname
(
"nonexistant@social.heldscal.la"
)
assert
fetched_user
==
nil
end
test
"returns nil for nonexistant local user"
do
fetched_user
=
User
.
get_or_fetch_by_nickname
(
"nonexistant"
)
assert
fetched_user
==
nil
end
end
end
test/web/ostatus/activity_representer_test.exs
View file @
68437558
...
...
@@ -25,6 +25,7 @@ test "a note activity" do
<updated>#{updated_at}</updated>
<ostatus:conversation>#{note_activity.data["context"]}</ostatus:conversation>
<link href="#{note_activity.data["context"]}" rel="ostatus:conversation" />
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
"""
tuple
=
ActivityRepresenter
.
to_simple_form
(
note_activity
,
user
)
...
...
@@ -61,6 +62,7 @@ test "a reply note" do
<ostatus:conversation>#{answer.data["context"]}</ostatus:conversation>
<link href="#{answer.data["context"]}" rel="ostatus:conversation" />
<thr:in-reply-to ref="#{note.data["object"]["id"]}" />
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
"""
tuple
=
ActivityRepresenter
.
to_simple_form
(
answer
,
user
)
...
...
test/web/salmon/salmon_test.exs
View file @
68437558
defmodule
Pleroma
.
Web
.
Salmon
.
SalmonTest
do
use
Pleroma
.
DataCase
alias
Pleroma
.
Web
.
Salmon
alias
Pleroma
.
{
Repo
,
Activity
,
User
}
import
Pleroma
.
Factory
@magickey
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwQhh-1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
...
...
@@ -57,4 +59,34 @@ test "it gets a magic key" do
assert
key
==
"RSA.uzg6r1peZU0vXGADWxGJ0PE34WvmhjUmydbX5YYdOiXfODVLwCMi1umGoqUDm-mRu4vNEdFBVJU1CpFA7dKzWgIsqsa501i2XqElmEveXRLvNRWFB6nG03Q5OUY2as8eE54BJm0p20GkMfIJGwP6TSFb-ICp3QjzbatuSPJ6xCE=.AQAB"
end
test
"it pushes an activity to remote accounts it's addressed to"
do
user_data
=
%{
info:
%{
"salmon"
=>
"http://example.org/salmon"
},
local:
false
}
mentioned_user
=
insert
(
:user
,
user_data
)
note
=
insert
(
:note
)
activity_data
=
%{
"id"
=>
Pleroma
.
Web
.
ActivityPub
.
ActivityPub
.
generate_activity_id
,
"type"
=>
"Create"
,
"actor"
=>
note
.
data
[
"actor"
],
"to"
=>
note
.
data
[
"to"
]
++
[
mentioned_user
.
ap_id
],
"object"
=>
note
.
data
,
"published_at"
=>
DateTime
.
utc_now
()
|>
DateTime
.
to_iso8601
,
"context"
=>
note
.
data
[
"context"
]
}
{
:ok
,
activity
}
=
Repo
.
insert
(%
Activity
{
data:
activity_data
})
user
=
Repo
.
get_by
(
User
,
ap_id:
activity
.
data
[
"actor"
])
{
:ok
,
user
}
=
Pleroma
.
Web
.
WebFinger
.
ensure_keys_present
(
user
)
poster
=
fn
(
url
,
data
,
headers
)
->
assert
url
==
"http://example.org/salmon"
end
Salmon
.
publish
(
user
,
activity
,
poster
)
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment