<?php

/*
Plugin Name: Secure AXS
Plugin URI: https://wordpress.org/plugins/secure-axs/
Description: Change default WordPress login URL to prevent spam login and brute force attacks, the plugin blocks access to default login url, generates a custom branded login panel (Which you can change colors and image) with the URL you define from plugin settings, plugin is also hosted @ http://mshazly.github.com/secure-axs
Version: 1.2.0
Author: Motaz Elshazly
Author URI: http://twitter.com/motaz_shazly
License: GPL2
*/
/*
Copyright 2016  Motaz Elshazly (email : mshazly@shazly.net)

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as 
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/

if(!class_exists('SecureAxs')){

Class SecureAxs{
    
    var $perma_link;      
    var $secure_axs;    
    var $actual_link; 
    
    public function __construct() {
         
        add_action( 'activated_plugin', array( $this, 'secure_axs_activate' ) );
	add_action( 'wp_enqueue_scripts', array( 'wp-color-picker' ) );
        add_action( 'admin_menu', array( $this, 'add_menu' ) );
        add_action( 'init', array( $this, 'display_login' ) ); // Display Plugin's login panel when the defined url is called.
        add_action( 'init', array( $this, 'axs_signon' ) ); // Process login information
        add_action( 'admin_enqueue_scripts', array( $this, 'register_plugin_scripts' ) ); 
        add_action( 'init', array( $this, 'block_default_login' ) ); // Block access to default WP login URLs.
        add_action( 'send_headers', 'no_cache_headers' );
        $secure_axs = $this->retrieve_settings('secure_axs');
        $perma_link = $this->retrieve_settings('permalink_structure');
        if ($secure_axs['axs-permalink'] !=  $perma_link):
            add_action( 'admin_notices', array( $this, 'axs_to_note' ) ); 
        endif;
        $secure_axs['axs-permalink'] = $perma_link;
        update_option('secure_axs', $secure_axs);
        
        // load_plugin_textdomain( 'secure-axs', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' ); // TBD        
        // Create a safety url to retrieve custom login to admin email when/if lost. '/lang' ); // TBD

 
    }

    /*
    public function register_plugin_styles() {
 
	wp_register_style( 'secure-axs', plugins_url( 'secure-axs/css/style.css' ) );
	wp_enqueue_style( 'secure-axs' );
 
    }
    * 
    */
    
    public function no_cache_headers(){
		
		$actual_link = self::current_url();
        
        $secure_axs = self::retrieve_settings('secure_axs');
        
        $perma_link = self::retrieve_settings('permalink_structure');
        
        if( $perma_link != NULL): $perma_link = NULL; else: $perma_link = '?'; endif;

        if( $actual_link == get_bloginfo('url') . '/'. $perma_link  . $secure_axs['axs_url'] . '/' || $actual_link == get_bloginfo('url') . '/' . $perma_link  . $secure_axs['axs_url'] ) {
			
            header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
			header("Cache-Control: post-check=0, pre-check=0", false);
			header("Pragma: no-cache");
		}  
		
	}
 
    public function register_plugin_scripts() {
        
        // Load the script for dashboard use only.
        if ( is_admin () ):
            
        // Add the color picker css file       
        wp_enqueue_style( 'wp-color-picker' ); 
         
        // Include our custom jQuery file with WordPress Color Picker dependency
        wp_enqueue_script( 'axs-script-handle', plugins_url( '/js/axs-scripts.js', __FILE__ ), array( 'wp-color-picker' ), false, true ); 
        
        // Load upload engine
        wp_enqueue_media();
   	wp_enqueue_script('thickbox');
    	wp_enqueue_style('thickbox');
        
        endif;
    }
    
    public function add_menu(){
        //add_options_page
           add_menu_page('Secure Access', 'Secure AXS', 1, 'secure_axs', array( $this, 'plugin_settings_page'), 'dashicons-shield' );
    }

    /**
    * Menu Callback
    */     
    public function plugin_settings_page(){
		
       $secure_axs = self::retrieve_settings('secure_axs');
       
       if( $secure_axs['allow_editors'] == 'on' ):  $axs_acl = 'publish_pages'; else:  $axs_acl ='manage_options'; endif;
       
        if(!current_user_can( $axs_acl ))
        {
            wp_die(__('You do not have sufficient permissions to access this page.', 'Secure_Axs'));
        }

        // Render the settings template
        include(sprintf("%s/settings.php", dirname(__FILE__)));
	
	
    }
    
    public function validate_settings( $fields ) { 
        
                $sanitized_fields = array();
     
                foreach($fields as $key => $val):
                    
           		if($key != "Submit"):
                            
                            if($key == 'axs_url' && empty($val) ) :
                                
                                // Set default value
                                $val = 'axs-login';
                            
                                $val = sanitize_title_with_dashes( $val );
                                // Set the error message
                                add_settings_error( 'axs_settings_options', 'axs_bg_error', 'Axs URL cannot be empty "axs-login" was applies instead.', 'error' ); // $setting, $code, $message, $type
                                
                                
                            elseif ( $key == 'bg_color' &&  FALSE === self::check_color( $val ) ) :

                                // Set default value
                                $val = '#cccccc';
                            
                                // Set the error message
                                add_settings_error( 'axs_settings_options', 'axs_bg_error', 'Insert a valid color for Background', 'error' ); // $setting, $code, $message, $type

                            elseif ( $key == 'text_color' &&  FALSE === self::check_color( $val ) ) :

                                // Set default value
                                $val = '#000000';
                            
                                // Set the error message
                                add_settings_error( 'axs_settings_options', 'axs_bg_error', 'Insert a valid color for text', 'error' ); // $setting, $code, $message, $type

                            endif;

                            // Sanitize Value
                            $val = sanitize_text_field( $val );
                                
                                
                            // Saving value to array
                            $sanitized_fields[$key] = $val;
                        
			endif;
                        
                endforeach;
                
                
                update_option('secure_axs', $sanitized_fields);
                

    }
 
    /**
    * Function that will check if value is a valid HEX color.
    */
    public function check_color( $value ) { 
     
		if ( preg_match( '/^#[a-f0-9]{6}$/i', $value ) ) { // if user insert a HEX color with #     
			return true;
		}

		return false;
    }
        
    private function retrieve_settings( $optkey ){
    
        $secure_axs = get_option( $optkey );
        
        return $secure_axs;
    }
    
    public function display_login(){
        
        $actual_link = self::current_url();
        
        $secure_axs = self::retrieve_settings('secure_axs');
        
        $perma_link = self::retrieve_settings('permalink_structure');
        
        if( $perma_link != NULL): $perma_link = NULL; else: $perma_link = '?'; endif;

        if( $actual_link == get_bloginfo('url') . '/'. $perma_link  . $secure_axs['axs_url'] . '/' || $actual_link == get_bloginfo('url') . '/' . $perma_link  . $secure_axs['axs_url'] ) {
			
            wp_die( self::render_login(), get_bloginfo('name') . ' | Secure AXS', array('response' => '404') );
	}  
    }
	
    private function render_login(){
                    
                $secure_axs = self::retrieve_settings('secure_axs');
                
                $axs_login_nonce = wp_create_nonce( '_axs-login' );
            
                include(sprintf("%s/login.php", dirname(__FILE__)));
		
		return $form_html;
		
    }
    
    public function axs_signon(){
    
    
    if( isset(  $_POST['_axs_login_nonce'] )  ):
   
    // Security Check
    
        $nonce_verification = wp_verify_nonce( $_POST['_axs_login_nonce'], '_axs-login' );



        if( ! $nonce_verification ):

            // Die
            wp_die( __('Security Check Failed. Please reload the login page and try again.', 'Secure AXS Failed'), array('response' => '500') );

        else:

            $creds = array();
            $creds['user_login'] = sanitize_user( $_POST['axs_login'] );
            $creds['user_password'] = $_POST['axs_pass'];
            $creds['remember'] = FALSE;
            $axs_user = wp_signon( $creds );

            if (! is_wp_error($axs_user)):
                     
                header("location: ". get_bloginfo('url'). "/wp-admin/") ;
                die();
            
            else:
                
                wp_die( self::render_login(), strip_tags( $axs_user->get_error_message() ), array('response' => '404') );
            
            endif;
            

        endif;

    endif;
    
    
    }
        
    public function block_default_login(){
        
    global $pagenow;
    
    $allowed_logins = array("lostpassword", "logout", "register", "rp", "postpass");
            
        if( ( 'wp-login.php' == $pagenow ) && ( !in_array($_REQUEST['action'], $allowed_logins) ) ){ 

            wp_redirect( get_bloginfo('url') ); 
            exit();
        }
        
    }
    
    public function current_url(){
        
        $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        
        return $actual_link;
    }
    
    public function axs_to_note(){
        
        echo '<div class="update-nag notice is-dismissible">
            <p>You <strong>MUST</strong> check your new Secure AXS login after permalink structure change, <a href="'.get_bloginfo('url').'">Click here to check your new login URL.</a></p>
            </div>';

    }
          
    public function axs_change_notice(){

        add_action( 'admin_notices', array( $this, 'axs_to_note' ) ); 
    }
    
    public static function secure_axs_activate(){
        
        // Set new default login page.
        $perma_link = self::retrieve_settings('permalink_structure');
        $secure_axs = self::retrieve_settings('secure_axs');
        if( $secure_axs[axs_url] == NULL ):
        $default_settings = array('axs_url' => 'axs-login', 'bg_color' => '#ffffff', 'text_color' => '#000000', 'axs-permalink' => $perma_link);
        update_option('secure_axs', $default_settings);
        endif;
    }
    

    public static function deactivate(){
        // Do nothing
    }


    } // End of class.


	$SecureAxs = new SecureAxs();

} //if class exists check.

else{

    function secure_axs_terminated(){

    echo '<div class="error">

       <p>Secure AXS terminated to avoid conflicting with another instance using the same class. <a href="mailto:motaz@madeomedia.com">Contact support.<a/></p>

    </div>';

    }

    add_action('admin_notices', 'secure_axs_terminated');


}


?>
