Advertisement
Guest User

ASRegister

a guest
Feb 8th, 2016
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 12.27 KB | None | 0 0
  1. /**
  2.  * User registration class.
  3.  *
  4.  */
  5. class ASRegister {
  6.  
  7.     /**
  8.      * @var Instance of ASEmail class
  9.      */
  10.     private $mailer;
  11.  
  12.     /**
  13.      * @var Instance of ASDatabase class
  14.      */
  15.     private $db = null;
  16.  
  17.     /**
  18.      * Class constructor
  19.      */
  20.     function __construct() {
  21.        
  22.         //get database class instance
  23.         $this->db = ASDatabase::getInstance();
  24.  
  25.         //create new object of ASEmail class
  26.         $this->mailer = new ASEmail();
  27.     }
  28.    
  29.     /**
  30.      * Register user.
  31.      * @param array $data User details provided during the registration process.
  32.      */
  33.     public function register($data) {
  34.         $user = $data['userData'];
  35.        
  36.         //validate provided data
  37.         $errors = $this->validateUser($data);
  38.        
  39.         if(count($errors) == 0) {
  40.             //no validation errors
  41.            
  42.             //generate email confirmation key
  43.             $key = $this->_generateKey();
  44.  
  45.             MAIL_CONFIRMATION_REQUIRED === true ? $confirmed = 'N' : $confirmed = 'Y';
  46.            
  47.             //insert new user to database
  48.             $this->db->insert('as_users', array(
  49.                 "email"     => $user['email'],
  50.                 "username"  => strip_tags($user['username']),
  51.                 "password"  => $this->hashPassword($user['password']),
  52.                 "confirmed" => $confirmed,
  53.                 "confirmation_key"  => $key,
  54.                 "register_date"     => date("Y-m-d")    
  55.             ));
  56.  
  57.             $userId = $this->db->lastInsertId();
  58.  
  59.             $this->db->insert('as_user_details', array( 'user_id' => $userId ));
  60.            
  61.             //send confirmation email if needed
  62.             if ( MAIL_CONFIRMATION_REQUIRED ) {
  63.                 $this->mailer->confirmationEmail($user['email'], $key);
  64.                 $msg = ASLang::get('success_registration_with_confirm');
  65.             }
  66.             else
  67.                 $msg = ASLang::get('success_registration_no_confirm');
  68.            
  69.             //prepare and output success message
  70.             $result = array(
  71.                 "status" => "success",
  72.                 "msg"    => $msg
  73.             );
  74.            
  75.             echo json_encode($result);
  76.         }
  77.         else {
  78.             //there are validation errors
  79.            
  80.             //prepare result
  81.             $result = array(
  82.                 "status" => "error",
  83.                 "errors" => $errors
  84.             );
  85.            
  86.             //output result
  87.             echo json_encode ($result);
  88.         }
  89.     }
  90.  
  91.     /**
  92.      * Get user by email.
  93.      * @param $email User's email
  94.      * @return mixed User info if user with provided email exist, empty array otherwise.
  95.      */
  96.     public function getByEmail($email) {
  97.         $result = $this->db->select("SELECT * FROM `as_users` WHERE `email` = :e", array( 'e' => $email ));
  98.         if ( count ( $result ) > 0 )
  99.             return $result[0];
  100.         return $result;
  101.     }
  102.  
  103.  
  104.     /**
  105.      * Check if user has already logged in via specific provider and return user's data if he does.
  106.      * @param $provider oAuth provider (facebook, twitter or gmail)
  107.      * @param $id Identifier provided by provider
  108.      * @return array|mixed User info if user has already logged in via specific provider, empty array otherwise.
  109.      */
  110.     public function getBySocial($provider, $id) {
  111.         $result = $this->db->select('SELECT * FROM `as_social_logins` WHERE `provider` = :p AND `provider_id` = :id ', array(
  112.             'p'  => $provider,
  113.             'id' => $id
  114.         ));
  115.  
  116.         if ( count ( $result ) > 0 ) {
  117.             $res = $result[0];
  118.             $user = new ASUser($res['user_id']);
  119.             return $user->getInfo();
  120.         }
  121.  
  122.         else
  123.             return $result;
  124.     }
  125.  
  126.     /**
  127.      * Check if user is already registred via some social network.
  128.      * @param $provider Name of the provider ( twitter, facebook or google )
  129.      * @param $id Provider identifier
  130.      * @return bool TRUE if user exist in database (already registred), FALSE otherwise
  131.      */
  132.     public function registeredViaSocial($provider, $id) {
  133.         $result = $this->getBySocial($provider, $id);
  134.  
  135.         if ( count ( $result ) === 0 )
  136.             return false;
  137.         else
  138.             return true;
  139.     }
  140.  
  141.     /**
  142.      * Connect user's social account with his account at this system.
  143.      * @param $userId User Id on this system
  144.      * @param $provider oAuth provider (facebook, twitter or gmail)
  145.      * @param $providerId Identifier provided by provider.
  146.      */
  147.     public function addSocialAccount($userId, $provider, $providerId) {
  148.         $this->db->insert('as_social_logins', array(
  149.             'user_id' => $userId,
  150.             'provider' => $provider,
  151.             'provider_id' => $providerId,
  152.             'created_at' => date('Y-m-d H:i:s')
  153.         ));
  154.     }
  155.  
  156.     /**
  157.      * Send forgot password email.
  158.      * @param string $userEmail Provided email.
  159.      */
  160.     public function forgotPassword($userEmail) {
  161.  
  162.         $validator = new ASValidator();
  163.         $errors = array();
  164.         //we only have one field to validate here
  165.         //so we don't need id's from other fields
  166.         if($userEmail == "")
  167.             $errors[] = ASLang::get('email_required');
  168.         if( ! $validator->emailValid($userEmail) )
  169.             $errors[] = ASLang::get('email_wrong_format');
  170.        
  171.         if( ! $validator->emailExist($userEmail) )
  172.             $errors[] = ASLang::get('email_not_exist');
  173.  
  174.         $login = new ASLogin();
  175.  
  176.         if($login->_isBruteForce())
  177.             $errors[] = ASLang::get('brute_force');
  178.        
  179.         if(count($errors) == 0) {
  180.             //no validation errors
  181.            
  182.             //generate password reset key
  183.             $key = $this->_generateKey();
  184.            
  185.             //write key to db
  186.             $this->db->update(
  187.                         'as_users',
  188.                          array(
  189.                              "password_reset_key" => $key,
  190.                              "password_reset_confirmed" => 'N',
  191.                              "password_reset_timestamp" => date('Y-m-d H:i:s')
  192.                          ),
  193.                          "`email` = :email",
  194.                          array("email" => $userEmail)
  195.                     );
  196.  
  197.             $login->increaseLoginAttempts();
  198.            
  199.             //send email
  200.             $this->mailer->passwordResetEmail($userEmail, $key);
  201.         }
  202.         else
  203.             echo json_encode ($errors); //output json encoded errors
  204.     }
  205.    
  206.    
  207.     /**
  208.      * Reset user's password if password reset request has been made.
  209.      * @param string $newPass New password.
  210.      * @param string $passwordResetKey Password reset key sent to user
  211.      * in password reset email.
  212.      */
  213.     public function resetPassword($newPass, $passwordResetKey) {
  214.         $validator = new ASValidator();
  215.         if ( ! $validator->prKeyValid($passwordResetKey) ) {
  216.             echo 'Invalid password reset key!';
  217.             return;
  218.         }
  219.  
  220.         $pass = $this->hashPassword($newPass);
  221.         $this->db->update(
  222.                     'as_users',
  223.                     array("password" => $pass, 'password_reset_confirmed' => 'Y', 'password_reset_key' => ''),
  224.                     "`password_reset_key` = :prk ",
  225.                     array("prk" => $passwordResetKey)
  226.                 );
  227.     }
  228.    
  229.      
  230.     /**
  231.      * Hash given password.
  232.      * @param string $password Unhashed password.
  233.      * @return string Hashed password.
  234.      */
  235.      public function hashPassword($password) {
  236.         //this salt will be used in both algorithms
  237.         //for bcrypt it is required to look like this,
  238.         //for sha512 it is not required but it can be used
  239.         $salt = "$2a$" . PASSWORD_BCRYPT_COST . "$" . PASSWORD_SALT;
  240.        
  241.         if(PASSWORD_ENCRYPTION == "bcrypt") {
  242.             $newPassword = crypt($password, $salt);
  243.         }
  244.         else {
  245.             $newPassword = $password;
  246.             for($i=0; $i<PASSWORD_SHA512_ITERATIONS; $i++)
  247.                 $newPassword = hash('sha512',$salt.$newPassword.$salt);
  248.         }
  249.        
  250.         return $newPassword;
  251.      }
  252.    
  253.    
  254.     /**
  255.      * Generate two random numbers and store them into $_SESSION variable.
  256.      * Numbers are used during the registration to prevent bots to register.
  257.      */
  258.      public function botProtection() {
  259.         ASSession::set("bot_first_number", rand(1,9));
  260.         ASSession::set("bot_second_number", rand(1,9));
  261.     }
  262.  
  263.     /**
  264.      * Validate user provided fields.
  265.      * @param $data User provided fieds and id's of those fields that will be used for displaying error messages on client side.
  266.      * @param bool $botProtection Should bot protection be validated or not
  267.      * @return array Array with errors if there are some, empty array otherwise.
  268.      */
  269.     public function validateUser($data, $botProtection = true) {
  270.         $id     = $data['fieldId'];
  271.         $user   = $data['userData'];
  272.         $errors = array();
  273.         $validator = new ASValidator();
  274.        
  275.         //check if email is not empty
  276.         if( $validator->isEmpty($user['email']) )
  277.             $errors[] = array(
  278.                 "id"    => $id['email'],
  279.                 "msg"   => ASLang::get('email_required')
  280.             );
  281.        
  282.         //check if username is not empty
  283.         if( $validator->isEmpty($user['username']) )
  284.             $errors[] = array(
  285.                 "id"    => $id['username'],
  286.                 "msg"   => ASLang::get('username_required')
  287.             );
  288.        
  289.         //check if password is not empty
  290.         if( $validator->isEmpty($user['password']) )
  291.             $errors[] = array(
  292.                 "id"    => $id['password'],
  293.                 "msg"   => ASLang::get('password_required')
  294.             );
  295.        
  296.         //check if password and confirm password are the same
  297.         if($user['password'] != $user['confirm_password'])
  298.             $errors[] = array(
  299.                 "id"    => $id['confirm_password'],
  300.                 "msg"   => ASLang::get('passwords_dont_match')
  301.             );
  302.        
  303.         //check if email format is correct
  304.         if( ! $validator->emailValid($user['email']) )
  305.             $errors[] = array(
  306.                 "id"    => $id['email'],
  307.                 "msg"   => ASLang::get('email_wrong_format')
  308.             );
  309.        
  310.         //check if email is available
  311.         if( $validator->emailExist($user['email']) )
  312.             $errors[] = array(
  313.                 "id"    => $id['email'],
  314.                 "msg"   => ASLang::get('email_taken')
  315.             );
  316.        
  317.         //check if username is available
  318.         if( $validator->usernameExist($user['username']) )
  319.             $errors[] = array(
  320.                 "id"    => $id['username'],
  321.                 "msg"   => ASLang::get('username_taken')
  322.             );
  323.        
  324.         if ( $botProtection )
  325.         {
  326.             //bot protection
  327.             $sum = ASSession::get("bot_first_number") + ASSession::get("bot_second_number");
  328.             if($sum != intval($user['bot_sum']))
  329.                 $errors[] = array(
  330.                     "id"    => $id['bot_sum'],
  331.                     "msg"   => ASLang::get('wrong_sum')
  332.                 );
  333.         }        
  334.        
  335.         return $errors;
  336.     }
  337.  
  338.     /**
  339.      * Generates random password
  340.      * @param int $length Length of generated password
  341.      * @return string Generated password
  342.      */
  343.     public function randomPassword($length = 7) {
  344.         $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  345.         $randomString = '';
  346.         for ($i = 0; $i < $length; $i++) {
  347.             $randomString .= $characters[rand(0, strlen($characters) - 1)];
  348.         }
  349.         return $randomString;
  350.     }
  351.  
  352.     /**
  353.      * Generate random token that will be used for social authentication
  354.      * @return string Generated token.
  355.      */
  356.     public function socialToken() {
  357.         return $this->randomPassword(40);
  358.     }
  359.  
  360.  
  361.      /* PRIVATE AREA
  362.      =================================================*/
  363.  
  364.     /**
  365.      * Generate key used for confirmation and password reset.
  366.      * @return string Generated key.
  367.      */
  368.     private function _generateKey() {
  369.         return md5(time() . PASSWORD_SALT . time());
  370.     }
  371.    
  372. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement