The WP Remote WordPress Plugin - Version 2.6

Version Description

Download this release

Release Info

Developer joehoyle
Plugin Icon 128x128 The WP Remote WordPress Plugin
Version 2.6
Comparing to
See all releases

Code changes from version 2.5 to 2.6

Files changed (6) hide show
  1. plugin.php +2 -2
  2. readme.txt +6 -1
  3. wprp.api.php +66 -16
  4. wprp.backups.php +21 -19
  5. wprp.compatability.php +1 -1
  6. wprp.plugins.php +5 -6
plugin.php CHANGED
@@ -3,7 +3,7 @@
3
  /*
4
  Plugin Name: WP Remote
5
  Description: Manage your WordPress site with <a href="https://wpremote.com/">WP Remote</a>. <strong>Deactivate to clear your API Key.</strong>
6
- Version: 2.5
7
  Author: Human Made Limited
8
  Author URI: http://hmn.md/
9
  */
@@ -136,7 +136,7 @@ endif;
136
  */
137
  function wprp_catch_api_call() {
138
 
139
- if ( empty( $_GET['wpr_api_key'] ) || ! urldecode( $_GET['wpr_api_key'] ) || ! isset( $_GET['actions'] ) )
140
  return;
141
 
142
  require_once( WPRP_PLUGIN_PATH . '/wprp.plugins.php' );
3
  /*
4
  Plugin Name: WP Remote
5
  Description: Manage your WordPress site with <a href="https://wpremote.com/">WP Remote</a>. <strong>Deactivate to clear your API Key.</strong>
6
+ Version: 2.6
7
  Author: Human Made Limited
8
  Author URI: http://hmn.md/
9
  */
136
  */
137
  function wprp_catch_api_call() {
138
 
139
+ if ( empty( $_POST['wpr_verify_key'] ) )
140
  return;
141
 
142
  require_once( WPRP_PLUGIN_PATH . '/wprp.plugins.php' );
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: humanmade, joehoyle, mattheu, tcrsavage, willmot
3
  Tags: wpremote, remote administration, multiple wordpress
4
  Requires at least: 2.9
5
  Tested up to: 3.5
6
- Stable tag: 2.5
7
 
8
  WP Remote is a free web app that enables you to easily manage all of your WordPress powered sites from one place.
9
 
@@ -31,6 +31,11 @@ You can email us at support@wpremote.com for support.
31
 
32
  == Changelog ==
33
 
 
 
 
 
 
34
  #### 2.5
35
 
36
  * Remove BackUpWordPress, backups are now handled by the `HM Backup` class.
3
  Tags: wpremote, remote administration, multiple wordpress
4
  Requires at least: 2.9
5
  Tested up to: 3.5
6
+ Stable tag: 2.6
7
 
8
  WP Remote is a free web app that enables you to easily manage all of your WordPress powered sites from one place.
9
 
31
 
32
  == Changelog ==
33
 
34
+ #### 2.6
35
+
36
+ * Change to using better hmac style authentication
37
+ * Fix error for sites running =< WordPress 3.1
38
+
39
  #### 2.5
40
 
41
  * Remove BackUpWordPress, backups are now handled by the `HM Backup` class.
wprp.api.php CHANGED
@@ -1,20 +1,68 @@
1
  <?php
2
 
3
- // Check the API Key
4
- if ( ! get_option( 'wpr_api_key' ) ) {
5
 
6
- echo json_encode( 'blank-api-key' );
7
- exit;
8
 
9
- } elseif ( ! isset( $_GET['wpr_api_key'] ) || urldecode( $_GET['wpr_api_key'] ) !== get_option( 'wpr_api_key' ) || ! isset( $_GET['actions'] ) ) {
10
 
11
- echo json_encode( 'bad-api-key' );
12
- exit;
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
 
16
- $actions = explode( ',', sanitize_text_field( $_GET['actions'] ) );
17
- $actions = array_flip( $actions );
18
 
19
  // Disable error_reporting so they don't break the json request
20
  if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG )
@@ -24,7 +72,9 @@ if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG )
24
  // TODO what about if admin use doesn't exists?
25
  wp_set_current_user( 1 );
26
 
27
- foreach( $actions as $action => $value ) {
 
 
28
 
29
  // TODO Instead should just fire actions which we hook into.
30
  // TODO should namespace api methods?
@@ -80,13 +130,13 @@ foreach( $actions as $action => $value ) {
80
 
81
  case 'upgrade_plugin' :
82
 
83
- $actions[$action] = _wprp_upgrade_plugin( (string) sanitize_text_field( $_GET['plugin'] ) );
84
 
85
  break;
86
 
87
  case 'activate_plugin' :
88
 
89
- $actions[$action] = _wprp_activate_plugin( (string) sanitize_text_field( $_GET['plugin'] ) );
90
 
91
  break;
92
 
@@ -98,7 +148,7 @@ foreach( $actions as $action => $value ) {
98
 
99
  case 'upgrade_theme' :
100
 
101
- $actions[$action] = _wprp_upgrade_theme( (string) sanitize_text_field( $_GET['theme'] ) );
102
 
103
  break;
104
 
@@ -106,7 +156,7 @@ foreach( $actions as $action => $value ) {
106
  case 'delete_backup' :
107
  case 'supports_backups' :
108
  case 'get_backup' :
109
- $actions[$action] = _wprp_backups_api_call( $action );
110
 
111
  break;
112
 
@@ -116,7 +166,7 @@ foreach( $actions as $action => $value ) {
116
  'site_url' => get_site_url(),
117
  'home_url' => get_home_url(),
118
  'admin_url' => get_admin_url(),
119
- 'backups' => _wprp_get_backups_info()
120
  );
121
 
122
  break;
@@ -133,4 +183,4 @@ foreach( $actions as $action => $value ) {
133
 
134
  echo json_encode( $actions );
135
 
136
- exit;
1
  <?php
2
 
3
+ class WPR_API_Request {
 
4
 
5
+ static $actions = array();
6
+ static $args = array();
7
 
8
+ static function verify_request() {
9
 
10
+ // Check the API Key
11
+ if ( ! get_option( 'wpr_api_key' ) ) {
12
 
13
+ echo json_encode( 'blank-api-key' );
14
+ exit;
15
+
16
+ } elseif ( isset( $_POST['wpr_verify_key'] ) ) {
17
+
18
+ $verify = $_POST['wpr_verify_key'];
19
+ unset( $_POST['wpr_verify_key'] );
20
+
21
+ $hash = self::generate_hash( $_POST );
22
+
23
+ if ( $hash !== $verify ) {
24
+ echo json_encode( 'bad-verify-key' );
25
+ exit;
26
+ }
27
+
28
+ if ( (int) $_POST['timestamp'] > time() + 360 || (int) $_POST['timestamp'] < time() - 360 ) {
29
+ echo json_encode( 'bad-timstamp' );
30
+ exit;
31
+ }
32
+
33
+ self::$actions = $_POST['actions'];
34
+ self::$args = $_POST;
35
+
36
+
37
+ } else {
38
+ exit;
39
+ }
40
+
41
+ return true;
42
+
43
+ }
44
+
45
+ static function generate_hash( $vars ) {
46
+
47
+ $hash = hash_hmac( 'sha256', serialize( $vars ), get_option( 'wpr_api_key' ) );
48
+ return $hash;
49
+
50
+ }
51
+
52
+ static function get_actions() {
53
+ return self::$actions;
54
+ }
55
+
56
+ static function get_args() {
57
+ return self::$args;
58
+ }
59
+
60
+ static function get_arg( $arg ) {
61
+ return self::$args[$arg];
62
+ }
63
  }
64
 
65
+ WPR_API_Request::verify_request();
 
66
 
67
  // Disable error_reporting so they don't break the json request
68
  if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG )
72
  // TODO what about if admin use doesn't exists?
73
  wp_set_current_user( 1 );
74
 
75
+ $actions = array();
76
+
77
+ foreach( WPR_API_Request::get_actions() as $action ) {
78
 
79
  // TODO Instead should just fire actions which we hook into.
80
  // TODO should namespace api methods?
130
 
131
  case 'upgrade_plugin' :
132
 
133
+ $actions[$action] = _wprp_upgrade_plugin( (string) sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ) );
134
 
135
  break;
136
 
137
  case 'activate_plugin' :
138
 
139
+ $actions[$action] = _wprp_activate_plugin( (string) sanitize_text_field( WPR_API_Request::get_arg( 'plugin' ) ) );
140
 
141
  break;
142
 
148
 
149
  case 'upgrade_theme' :
150
 
151
+ $actions[$action] = _wprp_upgrade_theme( (string) sanitize_text_field( WPR_API_Request::get_arg( 'theme' ) ) );
152
 
153
  break;
154
 
156
  case 'delete_backup' :
157
  case 'supports_backups' :
158
  case 'get_backup' :
159
+ $actions[$action] = function_exists( '_wprp_get_backups_info' ) ? _wprp_backups_api_call( $action ) : 'not-implemented';
160
 
161
  break;
162
 
166
  'site_url' => get_site_url(),
167
  'home_url' => get_home_url(),
168
  'admin_url' => get_admin_url(),
169
+ 'backups' => function_exists( '_wprp_get_backups_info' ) ? _wprp_get_backups_info() : array()
170
  );
171
 
172
  break;
183
 
184
  echo json_encode( $actions );
185
 
186
+ exit;
wprp.backups.php CHANGED
@@ -27,7 +27,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
27
  self::$instance = new WPRP_Backups();
28
 
29
  return self::$instance;
30
-
31
  }
32
 
33
  /**
@@ -61,7 +61,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
61
  @rmdir( $dir );
62
 
63
  }
64
-
65
  /**
66
  * Setup HM Backup
67
  *
@@ -74,10 +74,12 @@ class WPRP_Backups extends WPRP_HM_Backup {
74
  $this->set_path( $this->path() );
75
 
76
  // Set the excludes
77
- if ( ! empty( $_GET['backup_excludes'] ) )
78
- $this->set_excludes( array_map( 'urldecode', $_GET['backup_excludes'] ), true );
 
 
79
 
80
- $this->filesize_transient = 'wprp_' . '_' . $this->get_type() . '_' . md5( $this->exclude_string() ) . '_filesize';
81
 
82
  }
83
 
@@ -87,7 +89,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
87
  * @return true|WP_Error
88
  */
89
  public function do_backup() {
90
-
91
  @ignore_user_abort( true );
92
 
93
  $this->set_status( 'Starting backup...' );
@@ -98,7 +100,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
98
  return new WP_Error( 'backup-failed', implode( ', ', $this->get_errors() ) );
99
 
100
  return true;
101
-
102
  }
103
 
104
  /**
@@ -136,7 +138,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
136
  }
137
 
138
  return new WP_Error( 'backup-failed', 'No backup was found' );
139
-
140
  }
141
 
142
  /**
@@ -155,19 +157,19 @@ class WPRP_Backups extends WPRP_HM_Backup {
155
 
156
  if ( file_exists( trailingslashit( $this->get_path() ) . 'index.html' ) )
157
  unlink( trailingslashit( $this->get_path() ) . 'index.html' );
158
-
159
  if ( file_exists( trailingslashit( $this->get_path() ) . '.htaccess' ) )
160
  unlink( trailingslashit( $this->get_path() ) . '.htaccess' );
161
 
162
  rmdir( $this->get_path() );
163
 
164
  delete_option( 'wprp_backup_path' );
165
-
166
  }
167
 
168
  /**
169
  * Get the estimated size of the sites files and database
170
- *
171
  * If the size hasn't been calculated yet then it fires an API request
172
  * to calculate the size and returns string 'Calculating'
173
  *
@@ -178,7 +180,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
178
 
179
  // Check the cache
180
  if ( $size = get_transient( $this->filesize_transient ) ) {
181
-
182
  // If we have a number, format it and return
183
  if ( is_numeric( $size ) )
184
  return size_format( $size, null, '%01u %s' );
@@ -257,7 +259,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
257
 
258
  break;
259
 
260
- case 'hmbkp_warning' :
261
 
262
  if ( $this->get_warnings() ) {
263
 
@@ -280,7 +282,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
280
  endswitch;
281
 
282
  }
283
-
284
  /**
285
  * Get the path to the backups directory
286
  *
@@ -376,7 +378,7 @@ class WPRP_Backups extends WPRP_HM_Backup {
376
  $key[] = $constant;
377
 
378
  return md5( shuffle( $key ) );
379
-
380
  }
381
 
382
  /**
@@ -503,7 +505,7 @@ function _wprp_backups_api_call( $action ) {
503
 
504
  case 'get_backup' :
505
  return WPRP_Backups::get_instance()->get_backup();
506
-
507
  case 'delete_backup' :
508
  return WPRP_Backups::get_instance()->cleanup();
509
 
@@ -534,9 +536,9 @@ function _wprp_get_backups_info() {
534
  * The calculated size is stored in a transient
535
  */
536
  function wprp_ajax_calculate_backup_size() {
537
-
538
  WPRP_Backups::get_instance()->get_filesize();
539
-
540
  exit;
541
  }
542
- add_action( 'wp_ajax_nopriv_wprp_calculate_backup_size', 'wprp_ajax_calculate_backup_size' );
27
  self::$instance = new WPRP_Backups();
28
 
29
  return self::$instance;
30
+
31
  }
32
 
33
  /**
61
  @rmdir( $dir );
62
 
63
  }
64
+
65
  /**
66
  * Setup HM Backup
67
  *
74
  $this->set_path( $this->path() );
75
 
76
  // Set the excludes
77
+ if ( class_exists( 'WPR_API_Request' ) && WPR_API_Request::get_arg( 'backup_excludes' ) )
78
+ $this->set_excludes( WPR_API_Request::get_arg( 'backup_excludes' ) );
79
+ else if ( isset( $_GET['backup_excludes'] ) )
80
+ $this->set_excludes( $_GET['backup_excludes'] );
81
 
82
+ $this->filesize_transient = 'wprp_' . '_' . $this->get_type() . '_' . substr( md5( $this->exclude_string() ), 20 ) . '_filesize';
83
 
84
  }
85
 
89
  * @return true|WP_Error
90
  */
91
  public function do_backup() {
92
+
93
  @ignore_user_abort( true );
94
 
95
  $this->set_status( 'Starting backup...' );
100
  return new WP_Error( 'backup-failed', implode( ', ', $this->get_errors() ) );
101
 
102
  return true;
103
+
104
  }
105
 
106
  /**
138
  }
139
 
140
  return new WP_Error( 'backup-failed', 'No backup was found' );
141
+
142
  }
143
 
144
  /**
157
 
158
  if ( file_exists( trailingslashit( $this->get_path() ) . 'index.html' ) )
159
  unlink( trailingslashit( $this->get_path() ) . 'index.html' );
160
+
161
  if ( file_exists( trailingslashit( $this->get_path() ) . '.htaccess' ) )
162
  unlink( trailingslashit( $this->get_path() ) . '.htaccess' );
163
 
164
  rmdir( $this->get_path() );
165
 
166
  delete_option( 'wprp_backup_path' );
167
+
168
  }
169
 
170
  /**
171
  * Get the estimated size of the sites files and database
172
+ *
173
  * If the size hasn't been calculated yet then it fires an API request
174
  * to calculate the size and returns string 'Calculating'
175
  *
180
 
181
  // Check the cache
182
  if ( $size = get_transient( $this->filesize_transient ) ) {
183
+
184
  // If we have a number, format it and return
185
  if ( is_numeric( $size ) )
186
  return size_format( $size, null, '%01u %s' );
259
 
260
  break;
261
 
262
+ case 'hmbkp_warning' :
263
 
264
  if ( $this->get_warnings() ) {
265
 
282
  endswitch;
283
 
284
  }
285
+
286
  /**
287
  * Get the path to the backups directory
288
  *
378
  $key[] = $constant;
379
 
380
  return md5( shuffle( $key ) );
381
+
382
  }
383
 
384
  /**
505
 
506
  case 'get_backup' :
507
  return WPRP_Backups::get_instance()->get_backup();
508
+
509
  case 'delete_backup' :
510
  return WPRP_Backups::get_instance()->cleanup();
511
 
536
  * The calculated size is stored in a transient
537
  */
538
  function wprp_ajax_calculate_backup_size() {
539
+
540
  WPRP_Backups::get_instance()->get_filesize();
541
+
542
  exit;
543
  }
544
+ add_action( 'wp_ajax_nopriv_wprp_calculate_backup_size', 'wprp_ajax_calculate_backup_size' );
wprp.compatability.php CHANGED
@@ -50,7 +50,7 @@ function wprp_security_admin_notice() {
50
 
51
  The plugin <strong><?php echo esc_attr( $plugin_name ); ?></strong> may cause issues with WP Remote.
52
 
53
- <a href="https://wpremote.com/faq/#<?php echo esc_attr( $plugin_name ); ?>" alt="WPRemote FAQ"> Click here for instructions on how to resolve this issue </a>
54
 
55
  </p>
56
 
50
 
51
  The plugin <strong><?php echo esc_attr( $plugin_name ); ?></strong> may cause issues with WP Remote.
52
 
53
+ <a href="https://wpremote.com/support-center/troubleshooting/my-site-is-showing-up-as-red/#<?php echo esc_attr( $plugin_name ); ?>" alt="WPRemote Support Center"> Click here for instructions on how to resolve this issue </a>
54
 
55
  </p>
56
 
wprp.plugins.php CHANGED
@@ -114,13 +114,13 @@ function _wprp_upgrade_plugin( $plugin ) {
114
  return array( 'status' => 'success' );
115
  }
116
 
 
 
 
117
 
118
- // we do a remote request to activate, as we don;t want to kill any installs
119
- $url = add_query_arg( 'wpr_api_key', $_GET['wpr_api_key'], get_bloginfo( 'url' ) );
120
- $url = add_query_arg( 'actions', 'activate_plugin', $url );
121
- $url = add_query_arg( 'plugin', $plugin, $url );
122
 
123
- $request = wp_remote_get( $url );
124
 
125
  if ( is_wp_error( $request ) ) {
126
  return array( 'status' => 'error', 'error' => $request->get_error_code() );
@@ -128,7 +128,6 @@ function _wprp_upgrade_plugin( $plugin ) {
128
 
129
  $body = wp_remote_retrieve_body( $request );
130
 
131
-
132
  if ( ! $json = @json_decode( $body ) )
133
  return array( 'status' => 'error', 'error' => 'The plugin was updated, but failed to re-activate.' );
134
 
114
  return array( 'status' => 'success' );
115
  }
116
 
117
+ // we do a remote request to activate, as we don't want to kill any installs
118
+ $data = array( 'actions' => array( 'activate_plugin' ), 'plugin' => $plugin, 'timestamp' => (string) time() );
119
+ $data['wpr_verify_key'] = WPR_API_Request::generate_hash( $data );
120
 
121
+ $args = array( 'body' => $data );
 
 
 
122
 
123
+ $request = wp_remote_post( get_bloginfo( 'url' ), $args );
124
 
125
  if ( is_wp_error( $request ) ) {
126
  return array( 'status' => 'error', 'error' => $request->get_error_code() );
128
 
129
  $body = wp_remote_retrieve_body( $request );
130
 
 
131
  if ( ! $json = @json_decode( $body ) )
132
  return array( 'status' => 'error', 'error' => 'The plugin was updated, but failed to re-activate.' );
133