Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
REST_Connection_Log
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 4
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
2
 create_item_permissions_check
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 create_item
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * REST API endpoint for logging PingHub connection events to Logstash.
4 *
5 * Only registered on Simple sites where log2logstash() is available.
6 *
7 * @package automattic/jetpack-rtc
8 */
9
10namespace Automattic\Jetpack\RTC;
11
12use WP_Error;
13use WP_REST_Controller;
14use WP_REST_Request;
15use WP_REST_Response;
16use WP_REST_Server;
17
18/**
19 * REST controller that receives PingHub connection lifecycle events from
20 * the browser and forwards them to Logstash for debugging.
21 */
22class REST_Connection_Log extends WP_REST_Controller {
23
24    /**
25     * Constructor.
26     */
27    public function __construct() {
28        $this->namespace = 'wpcom/v2';
29        $this->rest_base = 'rtc/connection-log';
30    }
31
32    /**
33     * Register routes.
34     */
35    public function register_routes() {
36        register_rest_route(
37            $this->namespace,
38            '/' . $this->rest_base,
39            array(
40                array(
41                    'methods'             => WP_REST_Server::CREATABLE,
42                    'callback'            => array( $this, 'create_item' ),
43                    'permission_callback' => array( $this, 'create_item_permissions_check' ),
44                    'args'                => array(
45                        'event'      => array(
46                            'required' => true,
47                            'type'     => 'string',
48                            'enum'     => array( 'connected', 'disconnected', 'reconnecting', 'jwt_fetch_error' ),
49                        ),
50                        'properties' => array(
51                            'required' => false,
52                            'type'     => 'object',
53                            'default'  => array(),
54                        ),
55                    ),
56                ),
57            )
58        );
59    }
60
61    /**
62     * Permission check: current user must be a member of the blog.
63     *
64     * @param WP_REST_Request $request Full details about the request.
65     * @return true|WP_Error
66     */
67    public function create_item_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
68        if ( ! is_user_member_of_blog() ) {
69            return new WP_Error(
70                'rest_forbidden',
71                __( 'You are not allowed to access this endpoint.', 'jetpack-rtc' ),
72                array( 'status' => 403 )
73            );
74        }
75
76        return true;
77    }
78
79    /**
80     * Log a PingHub connection event to Logstash.
81     *
82     * @param WP_REST_Request $request Full details about the request.
83     * @return WP_REST_Response
84     */
85    public function create_item( $request ) {
86        $event      = $request['event'];
87        $properties = $request['properties'];
88
89        // Sanitize properties to scalar values only.
90        $sanitized = array();
91        if ( is_array( $properties ) ) {
92            foreach ( $properties as $key => $value ) {
93                if ( is_scalar( $value ) ) {
94                    $sanitized[ sanitize_key( $key ) ] = $value;
95                }
96            }
97        }
98
99        log2logstash(
100            array(
101                'feature' => 'rtc',
102                'message' => 'pinghub_' . $event,
103                'blog_id' => get_current_blog_id(),
104                'user_id' => get_current_user_id(),
105                'extra'   => wp_json_encode( $sanitized, JSON_UNESCAPED_SLASHES ),
106            )
107        );
108
109        return rest_ensure_response( array( 'success' => true ) );
110    }
111}