Changeset 1240463
- Timestamp:
- 09/08/2015 09:31:08 AM (11 years ago)
- Location:
- angry-creative-logger/trunk
- Files:
-
- 3 edited
-
plugin.php (modified) (1 diff)
-
readme.txt (modified) (3 diffs)
-
routines/file_permissions.php (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
angry-creative-logger/trunk/plugin.php
r1235366 r1240463 4 4 Plugin URI: http://angrycreative.se 5 5 Description: Inspects and logs possible issues with your Wordpress installation. 6 Version: 0.8. 36 Version: 0.8.4 7 7 Author: Robin Björklund, Sammy Nordström, Angry Creative AB 8 8 */ 9 9 10 define( 'ACI_PLUGIN_VERSION', '0.8. 3' );10 define( 'ACI_PLUGIN_VERSION', '0.8.4' ); 11 11 12 12 define( 'ACI_PLUGIN_DIR', dirname( __FILE__ ) ); -
angry-creative-logger/trunk/readme.txt
r1235366 r1240463 4 4 Requires at least: 4.0 5 5 Tested up to: 4.2.4 6 Stable tag: 0.8. 36 Stable tag: 0.8.4 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html 9 9 10 Inspects, logs and with the aid of WP-CLI it may even repair possible issues with your Wordpress installation.10 Inspects, logs and with the aid of WP-CLI, it may even repair possible issues with your WordPress installation. 11 11 12 12 == Description == 13 13 14 Inspects, logs and with the aid of WP-CLI it may even repair possible issues with your Wordpress installation. 15 16 TO-DO: Documentation :) 14 The *Angry Creative Inspector*, or Angry Inspector for short, will weigh, measure and find possible issues with your WordPress installation. This plugin is especially recommended to maintainers of WordPress installations that needs to continously monitor the health of their sites. Got WP-CLI? Then you may even be able to repair what's wrong with your WordPress. Read on to learn more. 15 16 The inspector has two basic types of inspection routines; regularly repeating inspections run once every 24 hours and inspections triggered by a WordPress hook or user action. Currently, the following regularly running inspection routines are supported out of the box: 17 18 * File permissions check - You didn't do a chmod 777 on all files, right? 19 * Git modifications check - Is your WordPress revisioned by Git? Then we log uncomitted file changes. 20 * Database collation check - Does your tables have the proper character set and collations? 21 * Site visibility check - Is your website blocking search engines? 22 23 Then there's the following WordPress hook or otherwise user action triggered routines: 24 25 * Plugin enabling/disabling - Who disabled or enabled that plugin? 26 * User registrations - Logs all user registrations. No more, no less. 27 * User profile updates - Logs all user profile updates, even password changes. 28 * User capabilitiy changes - Who promoted or demoted that user? 29 * Site registrations - Who created that site in your site network? 30 * Site enabling/disabling - Who disabled or enabled that site in your site network? 31 * Javascript error logging - Keep track of javascript errors, even the ones that appears in your visitor's browsers. 32 33 A little configuration is needed to take full advantage of the file permissions and site visibility routines, see installation instructions. 34 35 = Doing inspections and viewing inspection logs = 36 37 Login to your WordPress site with an administrator account and navigate to the Angry Inspector page under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite). In here you should see the inspection log and may trigger the scheduled inspection routines manually by clicking the "Inspect now" button. Also take note of the "Inspection routines" and "Action routines" tabs where you among other things may change the log level for each routine. Set log level to 'ignore' to completely disable a routine. 38 39 = Inspect and repair using WP-CLI = 40 41 First make sure you have WP-CLI installed, see http://wp-cli.org for instructions. Then navigate your commandline shell to your WordPress install directory and issue the following command: 42 43 wp angry-inspector inspect 44 45 You may also call a specific inspection routine like this (use all lowercase name of class or function without "ACI_Routine_"-prefix and replace underscores with dashes): 46 47 wp angry-inspector inspect file-permissions 48 49 Any inspection remarks while inspecting with WP-CLI will cause the inspector to look for a possible repair method and prompt you with the question wether you would like to make an attempt at repairing if one is found. Want to skip inspection and go directly for repairing? Here's how: 50 51 wp angry-inspector repair 52 53 To call a repair method for a specific inspection routine: 54 55 wp angry-inspector repair site-visibility 56 57 Please note that for utilizing a repair method like the one for file permissions, you need to run the command as super-user (root) and add --allow-root to your WP-CLI commands, like this: 58 59 sudo wp angry-inspector repair file-permissions --allow-root 60 61 That's all there is to it, really. Note that the given log_level option is just a default and may be overridden in the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite) like all the other registered inspection routines. 62 63 = Creating your own inspection routines = 64 65 Are you skilled in the arts of WordPress development and have a need for a check not covered by the above? Then you should extend the inspector with your own inspection routine! It's really simple. Here's an example you can put in your theme's functions.php or in a plugin (after plugins loaded): 66 67 if ( function_exists( 'aci_register_routine' ) ) { 68 69 $options = array( 'description' => 'My awesome inspection routine!', 70 'log_level' => 'warning' ); // Possible values: notice, warning, fatal, ignore 71 72 $action = 'ac_inspection'; // Default inspection action run once every 24 hrs 73 74 aci_register_routine( 'my_inspection_routine', $options, $action ); 75 76 function my_inspection_routine() { 77 78 $inspection_passed = false; 79 80 // Put your inspection code here, 81 // then log your results like so: 82 83 if ( !$inspection_passed ) { 84 AC_Inspector::log( 'Your WordPress-install did not pass your inspection routine.', __FUNCTION__ ); 85 } 86 87 // No need to return anything... 88 return; 89 90 } 91 92 } 93 94 For a bit more advanced developers, you may also register a class as an inspection routine. The syntax and function used is the same, it's just a matter of passing the class name instead of a function name. The inspector will by default look for a class function called 'inspect' to register as inspection method, otherwise you may add 'inspection_method' => 'your_inspection_function' to the options array to use any class function you like as your inspection method. 95 96 The reason why you would want to register a class instead of just a function is that it gives you the ability to extend the settings for your routine beyond just the log level and maybe even add a repair method to call if the inspection fails (WP-CLI only). 97 98 First off, here's how you extend the settings for your routine (inside your inspection routine class): 99 100 public static function settings_field( $options, $args = array() ) { 101 102 $routine = $args["routine"]; 103 104 /** 105 * 106 * Input field name convention: aci_options[<?php echo $routine; ?>][field_name] 107 * Input field id convention: aci_options_<?php echo $routine; ?>_field_name 108 * 109 **/ 110 111 ?> 112 113 <tr valign="top"> 114 <td scope="row" valign="top" style="vertical-align: top;">Example setting field</td> 115 <td> 116 <p class="description">Here be extra settings field :)</p> 117 </td> 118 </tr> 119 120 <?php 121 122 } 123 124 public static function settings( $options ) { 125 126 // Here be code that parses and validates submitted values 127 128 return $options; 129 130 } 131 132 Then when you register your routine: 133 134 $default_options = array( 'log_level' => 'warning', 135 'description' => 'My awesome inspection routine!' ); 136 137 aci_register_routine( 'my_inspection_routine_class', $default_options ); 138 139 // Optional extra settings fields 140 add_action( 'my_inspection_routine_class_settings_field', array( 'my_inspection_routine_class', 'settings_field' ), 10, 2 ); 141 add_filter( 'my_inspection_routine_class_settings', array( 'my_inspection_routine_class', 'settings' ), 10, 1 ); 142 143 Your extra settings fields should now be visible in either the Inspection or the Action routines tab under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite). 144 145 For a complete example routine class, checkout the routines/wp_mail.php file in the plugin directory. 146 147 As for registering a repair function, it works the same as when registering a class with an inspection method. The inspector looks for a class function called 'repair' by default. Override with any class function you like by defining 'repair_method' => 'your_repair_function' in the options array. However, a repair method will never be called automatically. You need WP-CLI ( http://wp-cli.org/ ) installed and issue the appropriate commands, see "Inspect and repair using WP-CLI" above. 148 149 Happy... no wait, angry inspecting! :) 17 150 18 151 == Installation == … … 20 153 1. Download, unzip and upload the plugin folder to the `/wp-content/plugins/` directory 21 154 2. Activate the plugin through the 'Plugins' menu in WordPress (activate for network if multisite) 22 3. Make sure the right log file path is set under the 'Settings/AC Inspector' menu in Wordpress 155 3. Make sure the right log file path is set under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite) 156 157 To get the file permissions and site visibility routines working properly, edit wp-config.php and add the following (before "That's all, stop editing!"): 158 159 //define("FS_METHOD", "direct"); // Recommended: Enable this for dev/stage-environments 160 define("DISALLOW_FILE_MODS", true); // Recommended: Enable this for production-evironments 161 162 define("HTTPD_USER", "www-data"); // The user of your HTTP-daemon (Apache/Nginx/Lighttpd/etc) 163 define("FS_USER", "my-user"); // The username/accountname you login and maintain your WordPress install with 164 define("SITE_RELEASE_TIER", "production"); // Possible values: 'local', 'development', 'integration', 'test', 'stage', 'production' 165 166 Setting FS_METHOD to 'direct' will ensure write permissions in your entire WordPress-directory for FS_USER as well as HTTPD_USER, while enabling DISALLOW_FILE_MODS will restrict the HTTPD_USER to only having write permissions as configured under the 'Settings/AC Inspector' menu in the WP admin panel (in network admin if multisite). Default allowed dirs: 167 168 wp-content/uploads/* 169 wp-content/blogs.dir/* 170 wp-content/cache/* 171 wp-content/avatars/* 172 wp-content/*/LC_MESSAGES/* 173 174 Setting SITE_RELEASE_TIER helps the inspector determine wether the site should allow search engine indexing or not. Forgetting to block search engines in a development or staging site can have terrible results on your search engine ranking. 23 175 24 176 == Changelog == … … 33 185 * Added repair method to site visibility routine using SITE_RELEASE_TIER for making the site public or private 34 186 * Added the abiltity to define HIDDEN_SITES to prevent specific sites from being made public by the site visibility repair method 187 * Finally added a bit of useful documentation and user instructions to this readme, please start asking questions if you want an FAQ :) 35 188 36 189 = 0.7.x = -
angry-creative-logger/trunk/routines/file_permissions.php
r1235366 r1240463 171 171 172 172 return true; 173 174 } 175 176 private static function file_user_may( $file_op, $file, $user = '' ) { 177 178 if ( empty( $file_op ) ) { 179 return false; 180 } 181 182 if ( empty( $file ) ) { 183 return false; 184 } 185 186 if ( empty( $user ) ) { 187 if ( defined( 'FS_USER' ) ) { 188 $user = FS_USER; 189 } else if ( defined( 'FTP_USER' ) ) { 190 $user = FTP_USER; 191 } else { 192 $process_user_info = posix_getpwuid(posix_geteuid()); 193 $user = $process_user_info['name']; 194 } 195 } 196 197 $file_ops = array( 'r' => 'read', 'w' => 'write', 'x' => 'execute' ); 198 199 if ( in_array( $file_op, $file_ops ) ) { 200 $req_perm_bit = array_search( $file_op, $file_ops ); 201 } else if ( in_array( $file_op, array_keys( $file_ops ) ) ) { 202 $req_perm_bit = $file_op; 203 } else { 204 return false; 205 } 206 207 clearstatcache(); 208 209 $file_owner_info = posix_getpwuid( fileowner( $file ) ); 210 $file_group_info = posix_getgrgid( filegroup( $file ) ); 211 $file_perms = fileperms( $file ); 212 213 $file_perm_bits = ''; 214 215 if ( $user == $file_owner_info['name'] ) { 216 217 $file_perm_bits .= (($file_perms & 0x0100) ? 'r' : '-'); 218 $file_perm_bits .= (($file_perms & 0x0080) ? 'w' : '-'); 219 $file_perm_bits .= (($file_perms & 0x0040) ? 'x' : '-'); 220 221 } else if ( in_array( $user, $file_group_info['members'] ) ) { 222 223 $file_perm_bits .= (($file_perms & 0x0020) ? 'r' : '-'); 224 $file_perm_bits .= (($file_perms & 0x0010) ? 'w' : '-'); 225 $file_perm_bits .= (($file_perms & 0x0008) ? 'x' : '-'); 226 227 } else { 228 229 $file_perm_bits .= (($file_perms & 0x0004) ? 'r' : '-'); 230 $file_perm_bits .= (($file_perms & 0x0002) ? 'w' : '-'); 231 $file_perm_bits .= (($file_perms & 0x0001) ? 'x' : '-'); 232 233 } 234 235 if ( false !== strpos( $file_perm_bits, $req_perm_bit ) ) { 236 return true; 237 } 238 239 return false; 173 240 174 241 } … … 283 350 $file = str_replace('//', '/', $file); 284 351 285 if ( !$allowed_dir && @touch($file, date('U', filemtime($file)), time()) ) {352 if ( !$allowed_dir && self::file_user_may( 'w', $file ) ) { 286 353 $bad_file_perm = true; 287 354 AC_Inspector::log( "Writable file `$file` is in a file directory that should not be writeable. Check your file permissions.", __CLASS__ ); 288 } else if ( $allowed_dir && ! @touch($file, date('U', filemtime($file)), time()) ) {355 } else if ( $allowed_dir && !self::file_user_may( 'w', $file ) ) { 289 356 $bad_file_perm = true; 290 357 AC_Inspector::log( "Unwritable file `$file` is in a file directory that should be writeable. Check your file permissions.", __CLASS__ ); … … 362 429 363 430 if ( is_dir( $path ) ) { 431 432 if ( !empty( $group ) ) { 433 try { 434 $chowned = @chgrp( $path, $group ); 435 if ( !$chowned ) { 436 throw new Exception( "Failed changing group ownership of directory '$path' to '$group'" ); 437 } else if ( $verbose ) { 438 AC_Inspector::log( "Changed group ownership of directory '$path' to '$group'", __CLASS__, array( 'success' => true ) ); 439 } 440 } catch ( Exception $e ) { 441 AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) ); 442 $group = ''; 443 } 444 } 364 445 365 446 if ( !empty( $owner ) ) { … … 374 455 AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) ); 375 456 $owner = ''; 376 }377 }378 379 if ( !empty( $group ) ) {380 try {381 $chowned = @chgrp( $path, $group );382 if ( !$chowned ) {383 throw new Exception( "Failed changing group ownership of directory '$path' to '$group'" );384 } else if ( $verbose ) {385 AC_Inspector::log( "Changed group ownership of directory '$path' to '$group'", __CLASS__, array( 'success' => true ) );386 }387 } catch ( Exception $e ) {388 AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );389 $group = '';390 457 } 391 458 } … … 431 498 } else { 432 499 500 if ( !empty( $group ) ) { 501 try { 502 $chowned = @chown( $path, $group ); 503 if ( !$chowned ) { 504 throw new Exception( "Failed changing group ownership of file '$path' to '$group'" ); 505 } 506 } catch ( Exception $e ) { 507 AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) ); 508 $group = ''; 509 } 510 } 511 433 512 if ( !empty( $owner ) ) { 434 513 try { … … 440 519 AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) ); 441 520 $owner = ''; 442 }443 }444 445 if ( !empty( $group ) ) {446 try {447 $chowned = @chown( $path, $group );448 if ( !$chowned ) {449 throw new Exception( "Failed changing group ownership of file '$path' to '$group'" );450 }451 } catch ( Exception $e ) {452 AC_Inspector::log( $e->getMessage(), __CLASS__, array( 'error' => true ) );453 $group = '';454 521 } 455 522 }
Note: See TracChangeset
for help on using the changeset viewer.