localize(); // allow other plugins to change the list of excluded (non redirected) urls self::$exclude_pagenows = apply_filters( 'authenticator_exclude_pagenows', self::$exclude_pagenows ); // allow other plugins to change the list of excluded (non redirected) urls self::$exclude_posts = apply_filters( 'authenticator_exclude_posts', self::$exclude_posts ); // allow other plugins to change the list of excluded (non redirected) ajax actions self::$exclude_ajax_actions = apply_filters( 'authenticator_exclude_ajax_actions', self::$exclude_ajax_actions ); // check if the user needs to authenticate $authenticate_method = $this->get_authenticate_method(); if ( 'redirect' === $authenticate_method ) { add_action( 'template_redirect', array( __CLASS__, $authenticate_method ) ); } elseif ( 'authenticate_ajax' === $authenticate_method ) { add_action( 'admin_init', array( __CLASS__, $authenticate_method ) ); } # set cookie lifetime add_filter( 'auth_cookie_expiration', array( $this, 'filter_cookie_lifetime' ) ); add_action( 'admin_init', array( $this, 'init_settings' ) ); add_filter( 'authenticator_get_options', array( $this, 'get_options' ) ); self::$options = get_option( self::KEY, array() ); add_action( 'init', array( $this, 'protect_upload' ) ); add_action( 'init', array( $this, 'disable_xmlrpc' ) ); add_action( 'init', array( $this, 'authenticate_rest_api') ); add_action( 'login_footer', array( $this, 'remove_back_to_blog_link' ) ); } /** * get the method to authenticate or null * if no authentication is required * * @since 1.1.0 * @global $pagenow * @return string|null */ public function get_authenticate_method() { if ( ! isset( $GLOBALS[ 'pagenow' ] ) ) { return 'redirect'; } //shorthand $p = $GLOBALS[ 'pagenow' ]; // exclude some pagenows ? if ( in_array( $p, self::$exclude_pagenows, true ) ) { return null; } if ( 'admin-ajax.php' === $p ) { if ( isset( $_REQUEST[ 'action' ] ) && in_array( $_REQUEST[ 'action' ], self::$exclude_ajax_actions ) ) { return null; } return 'authenticate_ajax'; } return 'redirect'; } /** * load the language files * * @since 1.1.0 * @return void */ public function localize() { load_plugin_textdomain( 'authenticator', FALSE, dirname( plugin_basename( __FILE__ ) ) . '/language' ); } /** * init the settings api * * @since 1.1.0 * @return void */ public function init_settings() { $this->settings = new Authenticator_Settings(); } /** * Init to protect uploads * * @since 10/11/2012 * @return void */ public function protect_upload() { $this->protect_uploads = new Authenticator_Protect_Upload(); } /** * Get redirect to login-page, if user not logged in blogs of network and single install * * @since 0.4.2 * @return void */ public static function redirect() { if ( is_feed() ) { if ( TRUE === apply_filters( 'authenticator_bypass_feed_auth', FALSE ) ) { return; } switch ( self::$options[ 'feed_authentication' ] ) { case 'http' : self::http_auth_feed(); return; break; case 'token' : if ( isset( $_GET[ self::$options[ 'auth_token' ] ] ) ) { return; } self::_exit_403(); break; case 'none' : default : # nothing to do break; } } /** * Checks if a user is logged in or has rights on the blog in multisite, * if not redirects them to the login page */ if ( ! self::authenticate_user() && ( ! is_singular() || ! in_array( get_the_title(), self::$exclude_posts, true ) ) ) { $reauth = ! current_user_can( 'read' ) && function_exists( 'is_multisite' ) && is_multisite() ? TRUE : FALSE; nocache_headers(); wp_redirect( wp_login_url( $_SERVER[ 'REQUEST_URI' ], $reauth ), $status = 302 ); exit(); } } /** * checks if the current visitor is logged in and has the * permission to 'read' this blog * * @since 1.1.0 * @return bool */ public static function authenticate_user() { # user must reauth when we are in multisite # and he has not the permission to 'read' $reauth = ! current_user_can( 'read' ) && function_exists( 'is_multisite' ) && is_multisite() ? TRUE : FALSE; return is_user_logged_in() && ! $reauth; } /** * checks for authenticated requests on the ajax-interface * * @wp_hook admin_init * @since 1.1.0 * @return void */ public static function authenticate_ajax() { if ( ! self::authenticate_user() ) { self::_exit_403(); } } /** * authenticate users requesting feeds via HTTP Basic auth * * @since 1.1.0 * @return void */ protected static function http_auth_feed() { $auth = new HTTP_Auth( 'Feed of ' . get_bloginfo( 'name' ) ); $user = $auth->get_user(); $user = wp_authenticate( $user[ 'name' ], $user[ 'pass' ] ); if ( ! is_a( $user, 'WP_User' ) || ! user_can( $user, 'read' ) ) { $auth->auth_required(); } } /** * get the cookie lifetime if set * * @wp-hook auth_cookie_expiration * * @param int $default_lifetime * * @return int */ public function filter_cookie_lifetime( $default_lifetime ) { if ( ( int ) self::$options[ 'cookie_lifetime' ] > 0 ) { return 60 * 60 * 24 * ( int ) self::$options[ 'cookie_lifetime' ]; } return $default_lifetime; } /** * disable_xmlrpc dependend to the setting * * @since 1.1.0 * @wp-hook init * @return void */ public function disable_xmlrpc() { if ( ! defined( 'XMLRPC_REQUEST' ) ) { return; } if ( ! empty( self::$options[ 'disable_xmlrpc' ] ) && '1' === self::$options[ 'disable_xmlrpc' ] ) { add_filter( 'xmlrpc_enabled', '__return_false' ); } } /** * authenticate_rest_api * @since 1.2.3 * @wp-hook rest_authentication_errors * @return WP_Error */ public function authenticate_rest_api() { if ( has_filter('rest_authentication_errors') && ! self::authenticate_user() ) { add_action( 'rest_authentication_errors', function() { return new WP_Error( 'rest_cannot_access', esc_attr__( 'Only authenticated users can access the REST API.', 'disable-json-api' ), array( 'status' => rest_authorization_required_code() ) ); }); } } /** * get the options * * @return string */ public function get_options() { return self::$options; } /** * Remove Back to Blog link * Not useful, only a loop with rewrite * * @since 1.1.0 * @return void */ public function remove_back_to_blog_link() { ?> 403 Forbidden' ); } /** * autoloader * * @since 1.1.0 * * @param string $class_name * * @return void */ public static function load_classes( $class_name ) { $file_name = dirname( __FILE__ ) . '/inc/class-' . $class_name . '.php'; if ( file_exists( $file_name ) ) { require_once $file_name; } } /** * uninstall routine * * @since 1.1.0 * @global $wpdb * @return void */ public static function uninstall() { global $wpdb; ignore_user_abort( - 1 ); if ( is_network_admin() && isset( $wpdb->blogs ) ) { $blogs = $wpdb->get_results( 'SELECT blog_id FROM ' . $wpdb->blogs, ARRAY_A ); foreach ( $blogs as $row ) { $id = ( int ) $row[ 'blog_id' ]; delete_blog_option( $id, self::KEY ); } return; } delete_option( self::KEY ); } } // end class