Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.62% covered (warning)
84.62%
11 / 13
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Jetpack_Application_Password_Extras
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
4 / 4
9
100.00% covered (success)
100.00%
1 / 1
 init
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 application_password_extras
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
4
 is_ajax_action_allowed
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 get_abilities
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Jetpack Application Password Extras
4 *
5 * Extends WordPress Application Passwords to work with additional abilities
6 * beyond the REST API.
7 *
8 * @package jetpack
9 */
10
11if ( ! defined( 'ABSPATH' ) ) {
12    exit( 0 );
13}
14
15/**
16 * Extends Application Password functionality beyond the REST API.
17 */
18class Jetpack_Application_Password_Extras {
19
20    /**
21     * The AJAX action prefix for VideoPress actions.
22     *
23     * @var string
24     */
25    private const VIDEOPRESS_AJAX_PREFIX = 'videopress-';
26
27    /**
28     * Initialize the main hooks.
29     */
30    public static function init() {
31        add_filter( 'application_password_is_api_request', array( __CLASS__, 'application_password_extras' ) );
32    }
33
34    /**
35     * Allow Application Password access to additional abilities.
36     *
37     * NOTE: If expanding this to include more abilities, consider updating the
38     * `get_abilities` method to include new abilities.
39     *
40     * @param bool $original_value The original value of the filter.
41     * @return bool The new value of the filter.
42     */
43    public static function application_password_extras( $original_value ) {
44        if ( $original_value ) {
45            return true;
46        }
47
48        return is_admin() && wp_doing_ajax() && self::is_ajax_action_allowed();
49    }
50
51    /**
52     * Check if the current AJAX action is allowed for Application Password authentication.
53     *
54     * @return bool True if the action is allowed, false otherwise.
55     */
56    private static function is_ajax_action_allowed() {
57        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- We're only checking the action name, not processing the request.
58        $action = isset( $_REQUEST['action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) : '';
59
60        if ( empty( $action ) ) {
61            return false;
62        }
63
64        return str_starts_with( $action, self::VIDEOPRESS_AJAX_PREFIX );
65    }
66
67    /**
68     * Get the abilities that this extension provides.
69     *
70     * @return array Array of abilities with their status.
71     */
72    public static function get_abilities() {
73        return array(
74            'admin-ajax' => true,
75        );
76    }
77}