PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta
16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-publicize / src / class-keyring-helper.php
jetpack / jetpack_vendor / automattic / jetpack-publicize / src Last commit date
jetpack-social-settings 3 months ago rest-api 3 weeks ago social-image-generator 3 weeks ago class-connections.php 3 weeks ago class-focal-point.php 2 months ago class-keyring-helper.php 2 months ago class-keyring-result-handler.php 2 months ago class-message-templates-placeholders.php 3 months ago class-publicize-assets.php 2 months ago class-publicize-base.php 4 weeks ago class-publicize-script-data.php 1 month ago class-publicize-setup.php 4 weeks ago class-publicize-ui.php 4 weeks ago class-publicize-utils.php 4 weeks ago class-publicize.php 2 months ago class-services.php 3 weeks ago class-share-status.php 9 months ago class-social-admin-page.php 3 weeks ago
class-keyring-helper.php
296 lines
1 <?php
2 /**
3 * Keyring helper.
4 *
5 * @package automattic/jetpack-publicize
6 */
7
8 namespace Automattic\Jetpack\Publicize;
9
10 use Automattic\Jetpack\Connection\Secrets;
11 use Automattic\Jetpack\Paths;
12 use Jetpack_IXR_Client;
13 use Jetpack_Options;
14
15 /**
16 * A series of utilities to interact with a Keyring instance.
17 */
18 class Keyring_Helper {
19 /**
20 * Class instance
21 *
22 * @var Keyring_Helper
23 */
24 private static $instance = null;
25
26 /**
27 * Whether the `sharing` page is registered.
28 *
29 * @var bool
30 */
31 private static $is_sharing_page_registered = false;
32
33 /**
34 * Initialize instance.
35 */
36 public static function init() {
37 if ( null === self::$instance ) {
38 self::$instance = new Keyring_Helper();
39 }
40
41 return self::$instance;
42 }
43
44 const SERVICES = array(
45 'facebook' => array(
46 'for' => 'publicize',
47 ),
48 'twitter' => array(
49 'for' => 'publicize',
50 ),
51 'linkedin' => array(
52 'for' => 'publicize',
53 ),
54 'tumblr' => array(
55 'for' => 'publicize',
56 ),
57 'path' => array(
58 'for' => 'publicize',
59 ),
60 'google_plus' => array(
61 'for' => 'publicize',
62 ),
63 'google_site_verification' => array(
64 'for' => 'other',
65 ),
66 );
67
68 /**
69 * Constructor
70 */
71 private function __construct() {
72 add_action( 'admin_init', array( __CLASS__, 'intercept_request' ) );
73 }
74
75 /**
76 * Gets a URL to the public-api actions. Works like WP's admin_url.
77 * On WordPress.com this is/calls Keyring::admin_url.
78 *
79 * @param string $service Shortname of a specific service.
80 * @param array $params Parameters to append to an API connection URL.
81 *
82 * @return string URL to specific public-api process
83 */
84 private static function api_url( $service = false, $params = array() ) {
85 /**
86 * Filters the API URL used to interact with WordPress.com.
87 *
88 * @since 0.1.0
89 * @since-jetpack 2.0.0
90 *
91 * @param string https://public-api.wordpress.com/connect/?jetpack=publicize Default Publicize API URL.
92 */
93 $url = apply_filters( 'publicize_api_url', 'https://public-api.wordpress.com/connect/?jetpack=publicize' );
94
95 if ( $service ) {
96 $url = add_query_arg( array( 'service' => $service ), $url );
97 }
98
99 if ( array() !== $params ) {
100 $url = add_query_arg( $params, $url );
101 }
102
103 return $url;
104 }
105
106 /**
107 * Build a connection URL (sharing settings page with unique query args to create a connection).
108 *
109 * @param string $service_name Service name.
110 * @param string $for Feature name.
111 */
112 public static function connect_url( $service_name, $for ) {
113 return add_query_arg(
114 array(
115 'action' => 'request',
116 'service' => $service_name,
117 'kr_nonce' => wp_create_nonce( 'keyring-request' ),
118 'nonce' => wp_create_nonce( "keyring-request-$service_name" ),
119 'for' => $for,
120 'publicize_action' => 1,
121 ),
122 admin_url()
123 );
124 }
125
126 /**
127 * Build a URL to refresh a connection (sharing settings page with unique query args to refresh a connection).
128 * Similar to connect_url, but with a refresh parameter.
129 *
130 * @param string $service_name Service name.
131 * @param string $for Feature name.
132 */
133 public static function refresh_url( $service_name, $for ) {
134 return add_query_arg(
135 array(
136 'action' => 'request',
137 'service' => $service_name,
138 'kr_nonce' => wp_create_nonce( 'keyring-request' ),
139 'refresh' => 1,
140 'for' => $for,
141 'nonce' => wp_create_nonce( "keyring-request-$service_name" ),
142 'publicize_action' => 1,
143 ),
144 admin_url()
145 );
146 }
147
148 /**
149 * Build a URL to delete a connection (sharing settings page with unique query args to delete a connection).
150 *
151 * @param string $service_name Service name.
152 * @param string $id Connection ID.
153 */
154 public static function disconnect_url( $service_name, $id ) {
155 return add_query_arg(
156 array(
157 'action' => 'delete',
158 'service' => $service_name,
159 'id' => $id,
160 'kr_nonce' => wp_create_nonce( 'keyring-request' ),
161 'nonce' => wp_create_nonce( "keyring-request-$service_name" ),
162 'publicize_action' => 1,
163 ),
164 admin_url()
165 );
166 }
167
168 /**
169 * Build contents handling Keyring connection management into Sharing settings screen.
170 */
171 public static function intercept_request() {
172 if ( ! empty( $_GET['publicize_action'] ) && isset( $_GET['action'] ) ) {
173 $service_name = null;
174
175 if ( isset( $_GET['service'] ) ) {
176 $service_name = filter_var( wp_unslash( $_GET['service'] ) );
177 }
178
179 switch ( $_GET['action'] ) {
180
181 case 'request':
182 check_admin_referer( 'keyring-request', 'kr_nonce' );
183 check_admin_referer( "keyring-request-$service_name", 'nonce' );
184
185 $verification = ( new Secrets() )->generate( 'publicize' );
186 if ( ! $verification ) {
187 $url = ( new Paths() )->admin_url( 'page=jetpack#/settings' );
188 wp_die(
189 sprintf(
190 wp_kses(
191 /* Translators: placeholder is a URL to a Settings page. */
192 __( "Jetpack is not connected. Please connect Jetpack by visiting <a href='%s'>Settings</a>.", 'jetpack-publicize-pkg' ),
193 array(
194 'a' => array(
195 'href' => array(),
196 ),
197 )
198 ),
199 esc_url( $url )
200 )
201 );
202
203 }
204 $stats_options = get_option( 'stats_options' );
205 $wpcom_blog_id = Jetpack_Options::get_option( 'id' );
206 $wpcom_blog_id = ! empty( $wpcom_blog_id ) ? $wpcom_blog_id : $stats_options['blog_id'];
207
208 $for = isset( $_GET['for'] ) ? sanitize_text_field( wp_unslash( $_GET['for'] ) ) : 'publicize';
209
210 $custom_inputs = array();
211
212 // For Bluesky.
213 if ( isset( $_GET['handle'] ) && isset( $_GET['app_password'] ) ) {
214 $custom_inputs['handle'] = sanitize_text_field( wp_unslash( $_GET['handle'] ) );
215
216 $custom_inputs['app_password'] = sanitize_text_field( wp_unslash( $_GET['app_password'] ) );
217 }
218
219 // For Mastodon.
220 if ( isset( $_GET['instance'] ) ) {
221 $custom_inputs['instance'] = sanitize_text_field( wp_unslash( $_GET['instance'] ) );
222 }
223
224 $user = wp_get_current_user();
225 $redirect = self::api_url(
226 $service_name,
227 urlencode_deep(
228 $custom_inputs +
229 array(
230 'action' => 'request',
231 'redirect_uri' => add_query_arg( array( 'action' => 'done' ), menu_page_url( 'sharing', false ) ),
232 'for' => $for,
233 // required flag that says this connection is intended for publicize.
234 'siteurl' => site_url(),
235 'state' => $user->ID,
236 'blog_id' => $wpcom_blog_id,
237 'secret_1' => $verification['secret_1'],
238 'secret_2' => $verification['secret_2'],
239 'eol' => $verification['exp'],
240 )
241 )
242 );
243 wp_redirect( $redirect ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect -- The API URL is an external URL and is filterable.
244 exit( 0 );
245
246 case 'completed':
247 /*
248 * We do not use a nonce here,
249 * since we're populating a local cache of
250 * the Publicize connections that were created and stored on WordPress.com.
251 */
252 $xml = new Jetpack_IXR_Client();
253 $xml->query( 'jetpack.fetchPublicizeConnections' );
254
255 if ( ! $xml->isError() ) {
256 $response = $xml->getResponse();
257 Jetpack_Options::update_option( 'publicize_connections', $response );
258 }
259
260 break;
261
262 case 'delete':
263 $id = isset( $_GET['id'] ) ? filter_var( wp_unslash( $_GET['id'] ) ) : null;
264
265 check_admin_referer( 'keyring-request', 'kr_nonce' );
266 check_admin_referer( "keyring-request-$service_name", 'nonce' );
267
268 self::disconnect( $service_name, $id );
269
270 do_action( 'connection_disconnected', $service_name );
271 break;
272 }
273 }
274 }
275
276 /**
277 * Remove a Publicize connection
278 *
279 * @param string $service_name Service name.
280 * @param string $connection_id Connection ID.
281 * @param int|bool $_blog_id Blog ID.
282 * @param int|bool $_user_id User ID.
283 * @param bool $force_delete Force delete the connection.
284 */
285 public static function disconnect( $service_name, $connection_id, $_blog_id = false, $_user_id = false, $force_delete = false ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
286 $xml = new Jetpack_IXR_Client();
287 $xml->query( 'jetpack.deletePublicizeConnection', $connection_id );
288
289 if ( ! $xml->isError() ) {
290 Jetpack_Options::update_option( 'publicize_connections', $xml->getResponse() );
291 } else {
292 return false;
293 }
294 }
295 }
296