Short-circuit well-known example domains

This commit is contained in:
Alex Kirk 2022-12-13 10:59:17 +01:00
parent 3db9489b5c
commit b3e71ff803
4 changed files with 60 additions and 3 deletions

View file

@ -22,7 +22,7 @@ function init() {
\defined( 'ACTIVITYPUB_EXCERPT_LENGTH' ) || \define( 'ACTIVITYPUB_EXCERPT_LENGTH', 400 );
\defined( 'ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS' ) || \define( 'ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS', 3 );
\defined( 'ACTIVITYPUB_HASHTAGS_REGEXP' ) || \define( 'ACTIVITYPUB_HASHTAGS_REGEXP', '(?:(?<=\s)|(?<=<p>)|(?<=<br>)|^)#([A-Za-z0-9_]+)(?:(?=\s|[[:punct:]]|$))' );
\defined( 'ACTIVITYPUB_USERNAME_REGEXP' ) || \define( 'ACTIVITYPUB_USERNAME_REGEXP', '(?:[A-Za-z0-9_-]+@((?:[A-Za-z0-9_-]+\.)+[A-Za-z]+))' );
\defined( 'ACTIVITYPUB_USERNAME_REGEXP' ) || \define( 'ACTIVITYPUB_USERNAME_REGEXP', '(?:([A-Za-z0-9_-]+)@((?:[A-Za-z0-9_-]+\.)+[A-Za-z]+))' );
\defined( 'ACTIVITYPUB_ALLOWED_HTML' ) || \define( 'ACTIVITYPUB_ALLOWED_HTML', '<strong><a><p><ul><ol><li><code><blockquote><pre><img>' );
\defined( 'ACTIVITYPUB_CUSTOM_POST_CONTENT' ) || \define( 'ACTIVITYPUB_CUSTOM_POST_CONTENT', "<p><strong>[ap_title]</strong></p>\n\n[ap_content]\n\n<p>[ap_hashtags]</p>\n\n<p>[ap_shortlink]</p>" );
\define( 'ACTIVITYPUB_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
@ -155,3 +155,41 @@ add_action(
$friends_feed->register_parser( Friends_Feed_Parser_ActivityPub::SLUG, new Friends_Feed_Parser_ActivityPub( $friends_feed ) );
}
);
/**
* Disable webfinger for known example domains.
*/
add_filter(
'pre_get_remote_metadata_by_actor',
function( $metadata, $actor ) {
if ( ! $metadata ) {
$username = null;
$domain = null;
if ( preg_match( '/^@?' . ACTIVITYPUB_USERNAME_REGEXP . '$/i', $actor, $m ) ) {
$username = $m[1];
$domain = $m[2];
} else {
$p = parse_url( $actor );
if ( $p ) {
if ( isset( $p['host'] ) ) {
$domain = $p['host'];
}
if ( isset( $p['path'] ) ) {
$path_parts = explode( '/', trim( $p['path'], '/' ) );
$username = array_pop( $path_parts );
}
}
}
if ( strtok( $domain, '.' ) === 'example' ) {
$metadata = array(
'url' => sprintf( 'https://%s/users/%s/', $domain, $username ),
'name' => $username,
);
}
}
return $metadata;
},
10,
2
);

View file

@ -36,7 +36,7 @@ class Mention {
*/
public static function replace_with_links( $result ) {
$metadata = \ActivityPub\get_remote_metadata_by_actor( $result[0] );
if ( ! is_wp_error( $metadata ) ) {
if ( ! is_wp_error( $metadata ) && ! empty( $metadata['url'] ) ) {
$username = ltrim( $result[0], '@' );
if ( ! empty( $metadata['name'] ) ) {
$username = $metadata['name'];

View file

@ -38,7 +38,7 @@ class Webfinger {
return $link;
}
$url = \add_query_arg( 'resource', 'acct:' . ltrim( $account, '@' ), 'https://' . $m[1] . '/.well-known/webfinger' );
$url = \add_query_arg( 'resource', 'acct:' . ltrim( $account, '@' ), 'https://' . $m[2] . '/.well-known/webfinger' );
if ( ! \wp_http_validate_url( $url ) ) {
$response = new \WP_Error( 'invalid_webfinger_url', null, $url );
\set_transient( $transient_key, $response, HOUR_IN_SECONDS ); // Cache the error for a shorter period.

View file

@ -1,9 +1,28 @@
<?php
class Test_Functions extends ActivityPub_TestCase_Cache_HTTP {
public function invalid_http_response() {
return $this->assertTrue( false ); // should not be called.
}
public function test_get_remote_metadata_by_actor() {
$metadata = \ActivityPub\get_remote_metadata_by_actor( 'pfefferle@notiz.blog' );
$this->assertEquals( 'https://notiz.blog/author/matthias-pfefferle/', $metadata['url'] );
$this->assertEquals( 'pfefferle', $metadata['preferredUsername'] );
$this->assertEquals( 'Matthias Pfefferle', $metadata['name'] );
add_filter( 'pre_http_request', array( $this, 'invalid_http_response' ), 8, 3 );
foreach ( array( 'user', 'test' ) as $username ) {
foreach ( array( 'example.org', 'example.net' ) as $domain ) {
foreach ( array( '@', '' ) as $leading_at ) {
$metadata = \ActivityPub\get_remote_metadata_by_actor( $username . '@' . $domain );
$this->assertEquals( sprintf( 'https://%s/users/%s/', $domain, $username ), $metadata['url'], $username . '@' . $domain );
$this->assertEquals( $username, $metadata['name'], $username . '@' . $domain );
}
$metadata = \ActivityPub\get_remote_metadata_by_actor( sprintf( 'https://%s/users/%s/', $domain, $username ) );
$this->assertEquals( sprintf( 'https://%s/users/%s/', $domain, $username ), $metadata['url'], $username . '@' . $domain );
$this->assertEquals( $username, $metadata['name'], $username . '@' . $domain );
}
}
remove_filter( 'pre_http_request', array( $this, 'invalid_http_response' ), 8 );
}
}