[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})'; /** * Settings repository. * * @var Repository */ private Repository $settings; /** * Log storage. * * @var LogRepository */ private LogRepository $log; /** * Constructor. * * @param Repository $settings Settings repository. * @param LogRepository $log Log storage. */ public function __construct( Repository $settings, LogRepository $log ) { $this->settings = $settings; $this->log = $log; } /** * Hook the routes. */ public function register(): void { add_action( 'rest_api_init', array( $this, 'register_routes' ) ); } /** * Register the routes. */ public function register_routes(): void { register_rest_route( self::NAMESPACE, self::ROUTE, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'summary' ), 'permission_callback' => array( $this, 'can_manage' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'save' ), 'permission_callback' => array( $this, 'can_manage' ), ), ) ); register_rest_route( self::NAMESPACE, self::RECORD, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'lookup' ), 'permission_callback' => array( $this, 'can_manage' ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete' ), 'permission_callback' => array( $this, 'can_manage' ), ), ) ); } /** * Whether the current user may manage the plugin. */ public function can_manage(): bool { return current_user_can( Capabilities::MANAGE ); } /** * Record count, retention and the trusted proxies. */ public function summary(): WP_REST_Response { $consent = (array) $this->settings->get()['consent']; return new WP_REST_Response( apply_filters( 'consentfold_log_summary', array( 'count' => $this->log->count(), 'retention_days' => (int) ( $consent['log_retention_days'] ?? 0 ), 'trusted_proxies' => array_values( (array) ( $consent['trusted_proxies'] ?? array() ) ), 'proxies_locked' => $this->proxies_locked(), 'proxy_notice' => ProxyNotice::seen(), ) ) ); } /** * Save the trusted proxies. * * @param WP_REST_Request $request Request whose JSON body holds `trusted_proxies`, a list of strings. * @return WP_REST_Response|WP_Error */ public function save( WP_REST_Request $request ) { $body = $request->get_json_params(); if ( ! is_array( $body ) || array_keys( $body ) !== array( 'trusted_proxies' ) ) { return new WP_Error( 'consentfold_invalid_body', __( 'Send the trusted proxies as a JSON object.', 'consentfold' ), array( 'status' => 400 ) ); } if ( $this->proxies_locked() ) { return new WP_Error( 'consentfold_locked', __( 'The network administrator set the trusted proxies.', 'consentfold' ), array( 'status' => 403 ) ); } $site = $this->settings->get_site(); $document = array_merge( $site, array( 'consent' => array_merge( is_array( $site['consent'] ?? null ) ? $site['consent'] : array(), $body ) ) ); unset( $document['schema_version'] ); // The repository carries it over. try { $this->settings->set( $document ); } catch ( InvalidSettingsException $e ) { return new WP_Error( 'consentfold_invalid_settings', __( 'The trusted proxies are not valid.', 'consentfold' ), array( 'status' => 400, 'errors' => $e->errors(), ) ); } ProxyNotice::clear(); return $this->summary(); } /** * Whether the network locked the trusted proxies, alone or with the whole `consent` branch. */ private function proxies_locked(): bool { foreach ( $this->settings->locked_keys() as $path ) { if ( 'consent' === $path || 0 === strpos( $path, 'consent.trusted_proxies' ) ) { return true; } } return false; } /** * The records of a consent ID. * * @param WP_REST_Request $request Request with the `uuid` of the route. */ public function lookup( WP_REST_Request $request ): WP_REST_Response { return new WP_REST_Response( array( 'records' => $this->log->history( strtolower( (string) $request['uuid'] ) ) ) ); } /** * Delete the records of a consent ID. * * @param WP_REST_Request $request Request with the `uuid` of the route. */ public function delete( WP_REST_Request $request ): WP_REST_Response { return new WP_REST_Response( array( 'deleted' => $this->log->delete_by_consent_id( strtolower( (string) $request['uuid'] ) ), 'count' => $this->log->count(), ) ); } }