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
503de4b8
Commit
503de4b8
authored
Apr 29, 2020
by
lain
Browse files
ObjectValidator: Add validation for `Delete`s.
parent
78c864cb
Pipeline
#24996
failed with stages
in 10 minutes and 35 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
lib/pleroma/web/activity_pub/builder.ex
View file @
503de4b8
...
...
@@ -10,6 +10,22 @@ defmodule Pleroma.Web.ActivityPub.Builder do
alias
Pleroma
.
Web
.
ActivityPub
.
Utils
alias
Pleroma
.
Web
.
ActivityPub
.
Visibility
@spec
delete
(
User
.
t
(),
String
.
t
())
::
{
:ok
,
map
(),
keyword
()}
def
delete
(
actor
,
object_id
)
do
object
=
Object
.
normalize
(
object_id
)
to
=
(
object
.
data
[
"to"
]
||
[])
++
(
object
.
data
[
"cc"
]
||
[])
{
:ok
,
%{
"id"
=>
Utils
.
generate_activity_id
(),
"actor"
=>
actor
.
ap_id
,
"object"
=>
object_id
,
"to"
=>
to
,
"type"
=>
"Delete"
},
[]}
end
@spec
like
(
User
.
t
(),
Object
.
t
())
::
{
:ok
,
map
(),
keyword
()}
def
like
(
actor
,
object
)
do
object_actor
=
User
.
get_cached_by_ap_id
(
object
.
data
[
"actor"
])
...
...
lib/pleroma/web/activity_pub/object_validator.ex
View file @
503de4b8
...
...
@@ -12,10 +12,21 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
alias
Pleroma
.
Object
alias
Pleroma
.
User
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
LikeValidator
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
DeleteValidator
@spec
validate
(
map
(),
keyword
())
::
{
:ok
,
map
(),
keyword
()}
|
{
:error
,
any
()}
def
validate
(
object
,
meta
)
def
validate
(%{
"type"
=>
"Delete"
}
=
object
,
meta
)
do
with
{
:ok
,
object
}
<-
object
|>
DeleteValidator
.
cast_and_validate
()
|>
Ecto
.
Changeset
.
apply_action
(
:insert
)
do
object
=
stringify_keys
(
object
)
{
:ok
,
object
,
meta
}
end
end
def
validate
(%{
"type"
=>
"Like"
}
=
object
,
meta
)
do
with
{
:ok
,
object
}
<-
object
|>
LikeValidator
.
cast_and_validate
()
|>
Ecto
.
Changeset
.
apply_action
(
:insert
)
do
...
...
@@ -24,6 +35,12 @@ def validate(%{"type" => "Like"} = object, meta) do
end
end
def
stringify_keys
(%{
__struct__:
_
}
=
object
)
do
object
|>
Map
.
from_struct
()
|>
stringify_keys
end
def
stringify_keys
(
object
)
do
object
|>
Map
.
new
(
fn
{
key
,
val
}
->
{
to_string
(
key
),
val
}
end
)
...
...
lib/pleroma/web/activity_pub/object_validators/common_validations.ex
View file @
503de4b8
...
...
@@ -8,6 +8,26 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do
alias
Pleroma
.
Object
alias
Pleroma
.
User
def
validate_recipients_presence
(
cng
,
fields
\\
[
:to
,
:cc
])
do
non_empty
=
fields
|>
Enum
.
map
(
fn
field
->
get_field
(
cng
,
field
)
end
)
|>
Enum
.
any?
(
fn
[]
->
false
_
->
true
end
)
if
non_empty
do
cng
else
fields
|>
Enum
.
reduce
(
cng
,
fn
field
,
cng
->
cng
|>
add_error
(
field
,
"no recipients in any field"
)
end
)
end
end
def
validate_actor_presence
(
cng
,
field_name
\\
:actor
)
do
cng
|>
validate_change
(
field_name
,
fn
field_name
,
actor
->
...
...
lib/pleroma/web/activity_pub/object_validators/delete_validator.ex
0 → 100644
View file @
503de4b8
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
DeleteValidator
do
use
Ecto
.
Schema
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
Types
import
Ecto
.
Changeset
import
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
CommonValidations
@primary_key
false
embedded_schema
do
field
(
:id
,
Types
.
ObjectID
,
primary_key:
true
)
field
(
:type
,
:string
)
field
(
:actor
,
Types
.
ObjectID
)
field
(
:to
,
Types
.
Recipients
,
default:
[])
field
(
:cc
,
Types
.
Recipients
,
default:
[])
field
(
:object
,
Types
.
ObjectID
)
end
def
cast_data
(
data
)
do
%
__MODULE__
{}
|>
cast
(
data
,
__schema__
(
:fields
))
end
def
validate_data
(
cng
)
do
cng
|>
validate_required
([
:id
,
:type
,
:actor
,
:to
,
:cc
,
:object
])
|>
validate_inclusion
(
:type
,
[
"Delete"
])
|>
validate_same_domain
()
|>
validate_object_presence
()
|>
validate_recipients_presence
()
end
def
validate_same_domain
(
cng
)
do
actor_domain
=
cng
|>
get_field
(
:actor
)
|>
URI
.
parse
()
|>
(
&
&1
.
host
)
.
()
object_domain
=
cng
|>
get_field
(
:object
)
|>
URI
.
parse
()
|>
(
&
&1
.
host
)
.
()
if
object_domain
!=
actor_domain
do
cng
|>
add_error
(
:actor
,
"is not allowed to delete object"
)
else
cng
end
end
def
cast_and_validate
(
data
)
do
data
|>
cast_data
|>
validate_data
end
end
test/web/activity_pub/object_validator_test.exs
View file @
503de4b8
defmodule
Pleroma
.
Web
.
ActivityPub
.
ObjectValidatorTest
do
use
Pleroma
.
DataCase
alias
Pleroma
.
Web
.
ActivityPub
.
Builder
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidator
alias
Pleroma
.
Web
.
ActivityPub
.
ObjectValidators
.
LikeValidator
alias
Pleroma
.
Web
.
ActivityPub
.
Utils
...
...
@@ -8,6 +9,72 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
import
Pleroma
.
Factory
describe
"deletes"
do
setup
do
user
=
insert
(
:user
)
{
:ok
,
post_activity
}
=
CommonAPI
.
post
(
user
,
%{
"status"
=>
"cancel me daddy"
})
{
:ok
,
valid_post_delete
,
_
}
=
Builder
.
delete
(
user
,
post_activity
.
data
[
"object"
])
%{
user:
user
,
valid_post_delete:
valid_post_delete
}
end
test
"it is valid for a post deletion"
,
%{
valid_post_delete:
valid_post_delete
}
do
assert
match?
({
:ok
,
_
,
_
},
ObjectValidator
.
validate
(
valid_post_delete
,
[]))
end
test
"it's invalid if the id is missing"
,
%{
valid_post_delete:
valid_post_delete
}
do
no_id
=
valid_post_delete
|>
Map
.
delete
(
"id"
)
{
:error
,
cng
}
=
ObjectValidator
.
validate
(
no_id
,
[])
assert
{
:id
,
{
"can't be blank"
,
[
validation:
:required
]}}
in
cng
.
errors
end
test
"it's invalid if the object doesn't exist"
,
%{
valid_post_delete:
valid_post_delete
}
do
missing_object
=
valid_post_delete
|>
Map
.
put
(
"object"
,
"http://does.not/exist"
)
{
:error
,
cng
}
=
ObjectValidator
.
validate
(
missing_object
,
[])
assert
{
:object
,
{
"can't find object"
,
[]}}
in
cng
.
errors
end
test
"it's invalid if the actor of the object and the actor of delete are from different domains"
,
%{
valid_post_delete:
valid_post_delete
}
do
valid_other_actor
=
valid_post_delete
|>
Map
.
put
(
"actor"
,
valid_post_delete
[
"actor"
]
<>
"1"
)
assert
match?
({
:ok
,
_
,
_
},
ObjectValidator
.
validate
(
valid_other_actor
,
[]))
invalid_other_actor
=
valid_post_delete
|>
Map
.
put
(
"actor"
,
"https://gensokyo.2hu/users/raymoo"
)
{
:error
,
cng
}
=
ObjectValidator
.
validate
(
invalid_other_actor
,
[])
assert
{
:actor
,
{
"is not allowed to delete object"
,
[]}}
in
cng
.
errors
end
test
"it's invalid if all the recipient fields are empty"
,
%{
valid_post_delete:
valid_post_delete
}
do
empty_recipients
=
valid_post_delete
|>
Map
.
put
(
"to"
,
[])
|>
Map
.
put
(
"cc"
,
[])
{
:error
,
cng
}
=
ObjectValidator
.
validate
(
empty_recipients
,
[])
assert
{
:to
,
{
"no recipients in any field"
,
[]}}
in
cng
.
errors
assert
{
:cc
,
{
"no recipients in any field"
,
[]}}
in
cng
.
errors
end
end
describe
"likes"
do
setup
do
user
=
insert
(
:user
)
...
...
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