First draft of an Activity-Sanitizer

This commit is contained in:
Matthias Pfefferle 2023-08-07 15:47:22 +02:00
parent 48632a7e1b
commit 1397d864bb
4 changed files with 212 additions and 33 deletions

View file

@ -68,7 +68,7 @@ class Activity extends Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | null
*/
@ -82,7 +82,7 @@ class Activity extends Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-object-term
*
* @var string
* | Base_Objectr
* | Base_Object
* | Link
* | null
*/
@ -97,7 +97,7 @@ class Activity extends Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-actor
*
* @var string
* | \ActivityPhp\Type\Extended\AbstractActor
* | Actor
* | array<Actor>
* | array<Link>
* | Link
@ -116,8 +116,8 @@ class Activity extends Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-target
*
* @var string
* | ObjectType
* | array<ObjectType>
* | Base_Object
* | array<Base_Object>
* | Link
* | array<Link>
*/
@ -132,7 +132,7 @@ class Activity extends Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-result
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | null
*/
@ -149,7 +149,7 @@ class Activity extends Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-origin
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | null
*/
@ -162,7 +162,7 @@ class Activity extends Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-instrument
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | null
*/
@ -176,7 +176,7 @@ class Activity extends Base_Object {
*
* @see https://www.w3.org/TR/activitypub/#object-without-create
*
* @param string|Base_Objectr|Link|null $object
* @param string|Base_Object|Link|null $object
*
* @return void
*/

View file

@ -49,9 +49,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attachment
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -65,9 +65,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attributedto
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -80,9 +80,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audience
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -115,7 +115,7 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | null
*/
@ -210,9 +210,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-inreplyto
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -225,9 +225,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-location
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -239,7 +239,7 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-preview
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | null
*/
@ -287,7 +287,7 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | null
*/
@ -313,9 +313,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tag
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -348,9 +348,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -363,9 +363,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bto
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -378,9 +378,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-cc
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -393,9 +393,9 @@ class Base_Object {
* @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bcc
*
* @var string
* | ObjectType
* | Base_Object
* | Link
* | array<ObjectType>
* | array<Base_Object>
* | array<Link>
* | null
*/
@ -433,7 +433,7 @@ class Base_Object {
*
* @see https://www.w3.org/TR/activitypub/#source-property
*
* @var ObjectType
* @var Base_Object
*/
protected $source;

View file

@ -0,0 +1,136 @@
<?php
namespace Activitypub;
class Sanitizer {
/**
* Sanitize a multi-dimensional array
*
* @param array $array The array to sanitize.
*
* @return array The sanitized array.
*/
public static function sanitize_array( $array ) {
$sanitized_array = array();
foreach ( $array as $key => $value ) {
$key = self::sanitize_key( $key );
if (
in_array(
$key,
array(
'summary_map',
'summaryMap',
'content_map',
'contentMap',
),
true
)
) {
$sanitized_array[ $key ] = self::sanitize_map( $value );
} elseif (
in_array(
$key,
array(
'inbox',
'outbox',
'followers',
'following',
),
true
)
) {
if ( is_string( $value ) ) {
$sanitized_array[ $key ] = sanitize_url( $value );
} else {
$sanitized_array[ $key ] = '';
}
} elseif ( in_array( $key, array( 'summary', 'content' ), true ) ) {
$sanitized_array[ $key ] = self::sanitize_html( $value );
} elseif ( is_array( $value ) ) {
$sanitized_array[ $key ] = self::sanitize_array( $value );
} else {
$sanitized_array[ $key ] = self::sanitize_value( $value );
}
}
return $sanitized_array;
}
/**
* Sanitize a value.
*
* @param string $value The value to sanitize.
*
* @return string The sanitized value.
*/
public static function sanitize_value( $value ) {
if ( is_email( $value ) ) {
return sanitize_email( $value );
}
if ( filter_var( $value, FILTER_VALIDATE_URL ) ) {
return sanitize_url( $value );
}
return sanitize_text_field( $value );
}
/**
* Sanitize HTML.
*
* @param string $value The value to sanitize.
*
* @return string The sanitized value.
*/
public static function sanitize_html( $value ) {
if ( is_array( $value ) ) {
return '';
}
global $allowedtags;
$tags = array_merge(
$allowedtags,
array( 'p' => array() )
);
$value = \preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $value );
$value = \strip_shortcodes( $value );
$value = \wptexturize( $value );
$value = \wp_kses( $value, $tags );
return $value;
}
/**
* Sanitize a translation map
*
* @param array $map The map to sanitize.
*
* @return array The sanitized map.
*/
public static function sanitize_map( $map ) {
$sanitized_map = array();
foreach ( $map as $key => $value ) {
$key = self::sanitize_key( $key );
$sanitized_map[ $key ] = self::sanitize_html( $value );
}
return $sanitized_map;
}
/**
* Sanitize an array key
*
* @param string $key The key to sanitize.
*
* @return string The sanitized key.
*/
public static function sanitize_key( $key ) {
return \preg_replace( '/[^a-zA-Z0-9_\-]/', '', $key );
}
}

View file

@ -0,0 +1,43 @@
<?php
class Test_Activitypub_Sanitizer extends WP_UnitTestCase {
/**
* @dataProvider the_data_provider
*/
public function test_sanitize_array( $source, $target ) {
$sanitizer = new Activitypub\Sanitizer();
$this->assertEquals( $target, $sanitizer->sanitize_array( $source ) );
}
public function the_data_provider() {
return array(
array(
array(
'type"§$' => '<p>Create</p>',
'content' => '<p>Content</p><script>content</script>',
'contentMap' => array(
'en' => '<p>Content</p><script>content</script>',
),
'nameMap' => array(
'en' => '<div>Content</div><script>content</script>',
),
'inbox' => 'https://example.org/inbox',
'outbox' => 'example.org/outbox',
'name' => 'Gifts\'+OR+1=1--',
),
array(
'type' => 'Create',
'content' => '<p>Content</p>',
'contentMap' => array(
'en' => '<p>Content</p>',
),
'nameMap' => array(
'en' => 'Content',
),
'inbox' => 'https://example.org/inbox',
'outbox' => 'http://example.org/outbox',
'name' => 'Gifts\'+OR+1=1--',
),
),
);
}
}