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
c839078a
Verified
Commit
c839078a
authored
Jun 09, 2021
by
Haelwenn
Browse files
ObjectValidators.{Announce,EmojiReact,Like}: Fix context, actor & addressing
parent
53cf801c
Pipeline
#36518
passed with stages
in 11 minutes and 1 second
Changes
8
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
lib/pleroma/web/activity_pub/object_validators/announce_validator.ex
View file @
c839078a
...
...
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
alias
Pleroma
.
EctoType
.
ActivityPub
.
ObjectValidators
alias
Pleroma
.
Object
alias
Pleroma
.
User
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
CommonFixes
alias
Pleroma
.
Web
.
ActivityPub
.
Utils
alias
Pleroma
.
Web
.
ActivityPub
.
Visibility
...
...
@@ -23,7 +24,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator do
field
(
:type
,
:string
)
field
(
:object
,
ObjectValidators
.
ObjectID
)
field
(
:actor
,
ObjectValidators
.
ObjectID
)
field
(
:context
,
:string
,
autogenerate:
{
Utils
,
:generate_context_id
,
[]}
)
field
(
:context
,
:string
)
field
(
:to
,
ObjectValidators
.
Recipients
,
default:
[])
field
(
:cc
,
ObjectValidators
.
Recipients
,
default:
[])
field
(
:published
,
ObjectValidators
.
DateTime
)
...
...
@@ -36,6 +37,10 @@ def cast_and_validate(data) do
end
def
cast_data
(
data
)
do
data
=
data
|>
fix
()
%
__MODULE__
{}
|>
changeset
(
data
)
end
...
...
@@ -43,11 +48,21 @@ def cast_data(data) do
def
changeset
(
struct
,
data
)
do
struct
|>
cast
(
data
,
__schema__
(
:fields
))
|>
fix_after_cast
()
end
def
fix_after_cast
(
cng
)
do
cng
defp
fix
(
data
)
do
data
=
data
|>
CommonFixes
.
fix_actor
()
|>
CommonFixes
.
fix_activity_addressing
()
with
%
Object
{}
=
object
<-
Object
.
normalize
(
data
[
"object"
])
do
data
|>
CommonFixes
.
fix_activity_context
(
object
)
|>
CommonFixes
.
fix_object_action_recipients
(
object
)
else
_
->
data
end
end
defp
validate_data
(
data_cng
)
do
...
...
@@ -60,7 +75,7 @@ defp validate_data(data_cng) do
|>
validate_announcable
()
end
def
validate_announcable
(
cng
)
do
def
p
validate_announcable
(
cng
)
do
with
actor
when
is_binary
(
actor
)
<-
get_field
(
cng
,
:actor
),
object
when
is_binary
(
object
)
<-
get_field
(
cng
,
:object
),
%
User
{}
=
actor
<-
User
.
get_cached_by_ap_id
(
actor
),
...
...
@@ -91,7 +106,7 @@ def validate_announcable(cng) do
end
end
def
validate_existing_announce
(
cng
)
do
def
p
validate_existing_announce
(
cng
)
do
actor
=
get_field
(
cng
,
:actor
)
object
=
get_field
(
cng
,
:object
)
...
...
lib/pleroma/web/activity_pub/object_validators/common_fixes.ex
View file @
c839078a
...
...
@@ -4,6 +4,7 @@
defmodule
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
CommonFixes
do
alias
Pleroma
.
EctoType
.
ActivityPub
.
ObjectValidators
alias
Pleroma
.
Object
alias
Pleroma
.
Object
.
Containment
alias
Pleroma
.
User
alias
Pleroma
.
Web
.
ActivityPub
.
Transmogrifier
...
...
@@ -36,7 +37,7 @@ def fix_object_defaults(data) do
|>
Transmogrifier
.
fix_implicit_addressing
(
follower_collection
)
end
def
fix_activity_addressing
(
activity
,
_meta
)
do
def
fix_activity_addressing
(
activity
)
do
%
User
{
follower_address:
follower_collection
}
=
User
.
get_cached_by_ap_id
(
activity
[
"actor"
])
activity
...
...
@@ -57,4 +58,21 @@ def fix_actor(data) do
|>
Map
.
put
(
"actor"
,
actor
)
|>
Map
.
put
(
"attributedTo"
,
actor
)
end
def
fix_activity_context
(
data
,
%
Object
{
data:
%{
"context"
=>
object_context
}})
do
data
|>
Map
.
put
(
"context"
,
object_context
)
end
def
fix_object_action_recipients
(%{
"actor"
=>
actor
}
=
data
,
%
Object
{
data:
%{
"actor"
=>
actor
}})
do
to
=
((
data
[
"to"
]
||
[])
--
[
actor
])
|>
Enum
.
uniq
()
Map
.
put
(
data
,
"to"
,
to
)
end
def
fix_object_action_recipients
(
data
,
%
Object
{
data:
%{
"actor"
=>
actor
}})
do
to
=
((
data
[
"to"
]
||
[])
++
[
actor
])
|>
Enum
.
uniq
()
Map
.
put
(
data
,
"to"
,
to
)
end
end
lib/pleroma/web/activity_pub/object_validators/emoji_react_validator.ex
View file @
c839078a
...
...
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
alias
Pleroma
.
EctoType
.
ActivityPub
.
ObjectValidators
alias
Pleroma
.
Object
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
CommonFixes
import
Ecto
.
Changeset
import
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
CommonValidations
...
...
@@ -31,6 +32,10 @@ def cast_and_validate(data) do
end
def
cast_data
(
data
)
do
data
=
data
|>
fix
()
%
__MODULE__
{}
|>
changeset
(
data
)
end
...
...
@@ -38,28 +43,24 @@ def cast_data(data) do
def
changeset
(
struct
,
data
)
do
struct
|>
cast
(
data
,
__schema__
(
:fields
))
|>
fix_after_cast
()
end
def
fix_after_cast
(
cng
)
do
cng
|>
fix_context
()
end
def
fix_context
(
cng
)
do
object
=
get_field
(
cng
,
:object
)
defp
fix
(
data
)
do
data
=
data
|>
CommonFixes
.
fix_actor
()
|>
CommonFixes
.
fix_activity_addressing
()
with
nil
<-
get_field
(
cng
,
:context
),
%
Object
{
data:
%{
"context"
=>
context
}}
<-
Object
.
get_cached_by_ap_id
(
object
)
do
cng
|>
put_change
(
:context
,
contex
t
)
with
%
Object
{}
=
object
<-
Object
.
normalize
(
data
[
"object"
])
do
data
|>
CommonFixes
.
fix_activity_context
(
object
)
|>
CommonFixes
.
fix_object_action_recipients
(
objec
t
)
else
_
->
cng
_
->
data
end
end
def
validate_emoji
(
cng
)
do
def
p
validate_emoji
(
cng
)
do
content
=
get_field
(
cng
,
:content
)
if
Pleroma
.
Emoji
.
is_unicode_emoji?
(
content
)
do
...
...
lib/pleroma/web/activity_pub/object_validators/like_validator.ex
View file @
c839078a
...
...
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
alias
Pleroma
.
EctoType
.
ActivityPub
.
ObjectValidators
alias
Pleroma
.
Object
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
CommonFixes
alias
Pleroma
.
Web
.
ActivityPub
.
Utils
import
Ecto
.
Changeset
...
...
@@ -31,6 +32,10 @@ def cast_and_validate(data) do
end
def
cast_data
(
data
)
do
data
=
data
|>
fix
()
%
__MODULE__
{}
|>
changeset
(
data
)
end
...
...
@@ -38,41 +43,20 @@ def cast_data(data) do
def
changeset
(
struct
,
data
)
do
struct
|>
cast
(
data
,
__schema__
(
:fields
))
|>
fix_after_cast
()
end
def
fix_after_cast
(
cng
)
do
cng
|>
fix_recipients
()
|>
fix_context
()
end
def
fix_context
(
cng
)
do
object
=
get_field
(
cng
,
:object
)
with
nil
<-
get_field
(
cng
,
:context
),
%
Object
{
data:
%{
"context"
=>
context
}}
<-
Object
.
get_cached_by_ap_id
(
object
)
do
cng
|>
put_change
(
:context
,
context
)
else
_
->
cng
end
end
def
fix_recipients
(
cng
)
do
to
=
get_field
(
cng
,
:to
)
cc
=
get_field
(
cng
,
:cc
)
object
=
get_field
(
cng
,
:object
)
defp
fix
(
data
)
do
data
=
data
|>
CommonFixes
.
fix_actor
()
|>
CommonFixes
.
fix_activity_addressing
()
with
{[],
[]}
<-
{
to
,
cc
},
%
Object
{
data:
%{
"actor"
=>
actor
}}
<-
Object
.
get_cached_by_ap_id
(
object
),
{
:ok
,
actor
}
<-
ObjectValidators
.
ObjectID
.
cast
(
actor
)
do
cng
|>
put_change
(
:to
,
[
actor
])
with
%
Object
{}
=
object
<-
Object
.
normalize
(
data
[
"object"
])
do
data
|>
CommonFixes
.
fix_activity_context
(
object
)
|>
CommonFixes
.
fix_object_action_recipients
(
object
)
else
_
->
cng
_
->
data
end
end
...
...
@@ -85,7 +69,7 @@ defp validate_data(data_cng) do
|>
validate_existing_like
()
end
def
validate_existing_like
(%{
changes:
%{
actor:
actor
,
object:
object
}}
=
cng
)
do
def
p
validate_existing_like
(%{
changes:
%{
actor:
actor
,
object:
object
}}
=
cng
)
do
if
Utils
.
get_existing_like
(
actor
,
%{
data:
%{
"id"
=>
object
}})
do
cng
|>
add_error
(
:actor
,
"already liked this object"
)
...
...
@@ -95,5 +79,5 @@ def validate_existing_like(%{changes: %{actor: actor, object: object}} = cng) do
end
end
def
validate_existing_like
(
cng
),
do
:
cng
def
p
validate_existing_like
(
cng
),
do
:
cng
end
test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs
View file @
c839078a
...
...
@@ -33,6 +33,18 @@ test "returns ok for a valid announce", %{valid_announce: valid_announce} do
assert
{
:ok
,
_object
,
_meta
}
=
ObjectValidator
.
validate
(
valid_announce
,
[])
end
test
"keeps announced object context"
,
%{
valid_announce:
valid_announce
}
do
assert
%
Object
{
data:
%{
"context"
=>
object_context
}}
=
Object
.
get_cached_by_ap_id
(
valid_announce
[
"object"
])
{
:ok
,
%{
"context"
=>
context
},
_
}
=
valid_announce
|>
Map
.
put
(
"context"
,
"https://example.org/invalid_context_id"
)
|>
ObjectValidator
.
validate
([])
assert
context
==
object_context
end
test
"returns an error if the object can't be found"
,
%{
valid_announce:
valid_announce
}
do
without_object
=
valid_announce
...
...
@@ -51,16 +63,6 @@ test "returns an error if the object can't be found", %{valid_announce: valid_an
assert
{
:object
,
{
"can't find object"
,
[]}}
in
cng
.
errors
end
test
"returns an error if we don't have the actor"
,
%{
valid_announce:
valid_announce
}
do
nonexisting_actor
=
valid_announce
|>
Map
.
put
(
"actor"
,
"https://gensokyo.2hu/users/raymoo"
)
{
:error
,
cng
}
=
ObjectValidator
.
validate
(
nonexisting_actor
,
[])
assert
{
:actor
,
{
"can't find user"
,
[]}}
in
cng
.
errors
end
test
"returns an error if the actor already announced the object"
,
%{
valid_announce:
valid_announce
,
announcer:
announcer
,
...
...
test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
View file @
c839078a
...
...
@@ -40,17 +40,30 @@ test "is valid for a valid object", %{valid_like: valid_like} do
assert
LikeValidator
.
cast_and_validate
(
valid_like
)
.
valid?
end
test
"sets the 'to' field to the object actor if no recipients are given"
,
%{
test
"Add object actor from 'to' field if it doesn't owns the like"
,
%{
valid_like:
valid_like
}
do
user
=
insert
(
:user
)
object_actor
=
valid_like
[
"actor"
]
valid_like
=
valid_like
|>
Map
.
put
(
"actor"
,
user
.
ap_id
)
|>
Map
.
put
(
"to"
,
[])
{
:ok
,
object
,
_meta
}
=
ObjectValidator
.
validate
(
valid_like
,
[])
assert
object_actor
in
object
[
"to"
]
end
test
"Removes object actor from 'to' field if it owns the like"
,
%{
valid_like:
valid_like
,
user:
user
}
do
without_recipients
=
valid_like
=
valid_like
|>
Map
.
delete
(
"to"
)
|>
Map
.
put
(
"to"
,
[
user
.
ap_id
]
)
{
:ok
,
object
,
_meta
}
=
ObjectValidator
.
validate
(
without_recipients
,
[])
assert
object
[
"to"
]
==
[
user
.
ap_id
]
{
:ok
,
object
,
_meta
}
=
ObjectValidator
.
validate
(
valid_like
,
[])
refute
user
.
ap_id
in
object
[
"to"
]
end
test
"sets the context field to the context of the object if no context is given"
,
%{
...
...
@@ -66,16 +79,6 @@ test "sets the context field to the context of the object if no context is given
assert
object
[
"context"
]
==
post_activity
.
data
[
"context"
]
end
test
"it errors when the actor is missing or not known"
,
%{
valid_like:
valid_like
}
do
without_actor
=
Map
.
delete
(
valid_like
,
"actor"
)
refute
LikeValidator
.
cast_and_validate
(
without_actor
)
.
valid?
with_invalid_actor
=
Map
.
put
(
valid_like
,
"actor"
,
"invalidactor"
)
refute
LikeValidator
.
cast_and_validate
(
with_invalid_actor
)
.
valid?
end
test
"it errors when the object is missing or not known"
,
%{
valid_like:
valid_like
}
do
without_object
=
Map
.
delete
(
valid_like
,
"object"
)
...
...
test/pleroma/web/activity_pub/relay_test.exs
View file @
c839078a
...
...
@@ -148,7 +148,7 @@ test "returns error when object is unknown" do
assert
{
:ok
,
%
Activity
{}
=
activity
}
=
Relay
.
publish
(
note
)
assert
activity
.
data
[
"type"
]
==
"Announce"
assert
activity
.
data
[
"actor"
]
==
service_actor
.
ap_id
assert
activity
.
data
[
"to"
]
==
[
service_actor
.
follower_address
]
assert
service_actor
.
follower_address
in
activity
.
data
[
"to"
]
assert
called
(
Pleroma
.
Web
.
Federator
.
publish
(
activity
))
end
...
...
test/pleroma/web/activity_pub/transmogrifier/announce_handling_test.exs
View file @
c839078a
...
...
@@ -150,27 +150,4 @@ test "it rejects incoming announces with an inlined activity from another origin
assert
{
:error
,
_e
}
=
Transmogrifier
.
handle_incoming
(
data
)
end
test
"it does not clobber the addressing on announce activities"
do
user
=
insert
(
:user
)
{
:ok
,
activity
}
=
CommonAPI
.
post
(
user
,
%{
status:
"hey"
})
data
=
File
.
read!
(
"test/fixtures/mastodon-announce.json"
)
|>
Jason
.
decode!
()
|>
Map
.
put
(
"object"
,
Object
.
normalize
(
activity
,
fetch:
false
)
.
data
[
"id"
])
|>
Map
.
put
(
"to"
,
[
"http://mastodon.example.org/users/admin/followers"
])
|>
Map
.
put
(
"cc"
,
[])
_user
=
insert
(
:user
,
local:
false
,
ap_id:
data
[
"actor"
],
follower_address:
"http://mastodon.example.org/users/admin/followers"
)
{
:ok
,
%
Activity
{
data:
data
,
local:
false
}}
=
Transmogrifier
.
handle_incoming
(
data
)
assert
data
[
"to"
]
==
[
"http://mastodon.example.org/users/admin/followers"
]
end
end
Write
Preview
Supports
Markdown
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