Skip to content

Conversation

@obenland
Copy link
Member

@obenland obenland commented Aug 26, 2025

Fixes #2095

Proposed changes:

  • Add Actors::normalize_identifier() method for centralizing actor identifier normalization logic
  • Simplify Moderation::is_actor_blocked() to accept pre-normalized URIs with consistent int parameter
  • Refactor Following and Blocked Actors table classes to use unified normalization approach
  • Improve separation of concerns between actor normalization and blocking logic

Other information:

  • Have you written new tests for your changes, if applicable?

Testing instructions:

  • Go to 'Users > Following' or 'Settings > ActivityPub > Following'
  • Try following an account using different formats:
  • Verify that blocked actors are properly prevented from being followed
  • Go to 'Users > Blocked Actors' or 'Settings > ActivityPub > Blocked Actors'
  • Try blocking accounts using the same various formats
  • Verify all formats work correctly and error handling is appropriate

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Significance

  • Patch

Type

  • Changed - for changes in existing functionality

Message

Refactor actor blocking with unified API for better maintainability

- Add Actors::normalize_identifier() for consistent actor URI normalization
- Simplify Moderation::is_actor_blocked() to accept normalized URIs
- Refactor Following and Blocked Actors tables to use centralized logic
- Change is_actor_blocked() default user_id from null to 0 for type consistency
- Improve separation of concerns between normalization and blocking logic

Addresses PR review feedback requesting unified blocking API.
Copilot AI review requested due to automatic review settings August 26, 2025 21:22
@obenland obenland self-assigned this Aug 26, 2025
@obenland obenland requested a review from pfefferle August 26, 2025 21:22
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the actor blocking functionality by introducing a unified API for actor identifier normalization. The refactoring consolidates duplicate normalization logic across the codebase and simplifies the blocking checks.

  • Adds a new Actors::normalize_identifier() method to centralize actor URI normalization logic
  • Introduces Moderation::is_actor_blocked() method that checks both user and site-wide blocks in one call
  • Refactors Following and Blocked Actors table classes to use the new unified methods

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

File Description
includes/collection/class-actors.php Adds normalize_identifier() method for centralizing actor URI normalization
includes/class-moderation.php Adds is_actor_blocked() method for unified blocking checks
includes/wp-admin/table/class-following.php Refactored to use new normalization and blocking methods
includes/wp-admin/table/class-blocked-actors.php Refactored to use new normalization method

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Replaces the use of the normalized profile identifier with the original input in the error message when blocking an actor fails. This ensures the user sees the exact value they attempted to block.
// Check if user has blocked the account.
if ( \in_array( $profile, Moderation::get_user_blocks( $this->user_id )['actors'], true ) ) {
$original = \sanitize_text_field( \wp_unslash( $_REQUEST['activitypub-profile'] ) );
$profile = Actors::normalize_identifier( $original );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move the normalizer into the is_actor_blocked function. It reduces the preconditions for the URL you want to check and simplifies the code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It includes prepending https for host-only queries, so the table functionality depends on it, too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I understand?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does it speak against calling it directly inside of the blocked check?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it was moved into is_actor_blocked we'd break the functionality that allows users to put in a host only and still follow the blog actor. Like activitypub.blog.

The normalized identifier is a service to both is_actor_blocked() and follow() and prevents a webfinger from having to be resolved twice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: It will not be resolved twice, we cache the request. so yes, it might be a bit of overload, but might simplify the code. but I am fine with improving over time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dang, that's impressive. I'm looking forward to having the same detailed grasp of the plugin as you do, I did not know that off the top of my head

Simplifies the logic by ensuring we always work with a string after running object_to_uri() first, eliminating the need for separate object/string handling paths.
@obenland obenland requested a review from pfefferle August 27, 2025 13:24
Added type check to Actors::normalize_identifier to handle non-string inputs gracefully. Introduced comprehensive unit tests for normalization logic and edge cases in blocked actors, followers, and following tables, ensuring robust handling of various identifier formats and invalid inputs. Also improved test cleanup by removing filters after each test.
Introduced a mock for HTTP requests to fetch actor data in both Test_Followers and Test_Following test classes. This ensures tests do not make real HTTP requests and improves test reliability and isolation.
Moved removal of 'pre_get_remote_metadata_by_actor' filter to tear_down() and removed redundant filter removals from the test method to ensure proper test cleanup.
… tests

- Enhanced is_actor_blocked method to check both actor URIs and domains for site-wide and user-specific blocks
- Added comprehensive unit tests covering:
  - Site-wide actor and domain blocking
  - User-specific actor and domain blocking
  - Hierarchical priority (site-wide takes precedence)
  - Mixed blocking scenarios
  - Edge cases and URL format handling
  - Performance testing with many blocks
- Updated test mocks to properly support actor blocking functionality
- Improved test cleanup to handle actor post metadata
@obenland obenland merged commit 37b9d7f into trunk Aug 28, 2025
13 checks passed
@obenland obenland deleted the refactor/unified-actor-blocking-check branch August 28, 2025 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor: Create centralized Moderation::is_actor_blocked() method

4 participants