public static function instance() { if ( is_null(self::$_instance) ) self::$_instance = new self(); return self::$_instance; }
/** * @param string $method login|autologin * @param array $input The input to parse to get the entry data, typically $_POST data */ public function __construct( $method, $input = null ) { if ( is_null( $input ) ) { $input = $_POST; } $this->_method = $method; $this->_input = array(); $this->_isAutologin = ( $method == self::ESB_METHOD_AUTOLOGIN ); if ( isset( $input['context'] ) ) { $this->_input['context'] = $input['context']; } $params = array(); UserLog::instance()->action( $this->_method )->step( 'received' ); if ( isset($input['format']) && $input['format'] == 'json' ) { $this->redirectMode(self::LOGIN_REDIRECT_MODE_JSON); } switch ( $this->_method ) { case self::ESB_METHOD_RELOG: $this->_input = $input; return $this->relog(); break; case self::ESB_METHOD_LOGIN: $userID = isset( $input['userID'] ) ? $input['userID'] : null; $password = isset( $input['password'] ) ? $input['password'] : null; $rememberme = isset( $input['rememberme'] ) ? $input['rememberme'] == 'on' : null; if ( $userID && $password ) { $params = array( $this->getBusinessNameMapping('identifier') => $userID, $this->getBusinessNameMapping('password') => $password, ); // Brute force prevention if ( SolrSafeOperatorHelper::featureIsActive('PreventBruteForce') ) { $freeLoginAttempts = SolrSafeOperatorHelper::feature('PreventBruteForce', 'FreeLoginAttempts'); $loginAttemptsDelay = SolrSafeOperatorHelper::feature('PreventBruteForce', 'LoginAttemptsDelay'); $maxLoginAttempts = SolrSafeOperatorHelper::feature('PreventBruteForce', 'MaxLoginAttempts'); $maxLoginAttemptsPageUrl = SolrSafeOperatorHelper::feature('PreventBruteForce', 'MaxLoginAttemptsPageUrl'); if ( empty($freeLoginAttempts) ) $freeLoginAttempts = 5; if ( empty($loginAttemptsDelay) ) $loginAttemptsDelay = 60; if ( empty($maxLoginAttempts) ) $maxLoginAttempts = 10; if ( empty($maxLoginAttemptsPageUrl) ) $maxLoginAttemptsPageUrl = eZINI::instance('merck.ini')->variable('LoginSettings', 'MaxLoginAttemptsPageUrl'); $memcacheKey = 'msd_login_attempts_'.$userID; $attempts = MemcacheTool::instance()->get( $memcacheKey ); if ( $attempts === false ) $attempts = 0; $attempts++; if ( $attempts > $maxLoginAttempts ) { switch( $this->redirectMode() ) { case self::LOGIN_REDIRECT_MODE_JS: case self::LOGIN_REDIRECT_MODE_JSON: echo json_encode(array( 'status' => 1, 'LoginRedirect' => $maxLoginAttemptsPageUrl, )); eZExecution::cleanExit(); break; default: header( 'Location: '.$maxLoginAttemptsPageUrl ); eZExecution::cleanExit(); break; } } $waitingAttempts = max(0, ($attempts - $freeLoginAttempts)); $timeToSleep = $waitingAttempts > 0 ? pow(2, ($waitingAttempts - 1)) : 0; sleep( $timeToSleep ); MemcacheTool::instance()->set( $memcacheKey, $attempts, $loginAttemptsDelay ); if( ContextTool::instance()->environment() != ContextTool::ENVIRONMENT_PROD ) header("X-login-attempts: $attempts - waiting $timeToSleep s"); } if ( $rememberme ) { $params['rememberme'] = $input['rememberme']; } } break; case self::ESB_METHOD_AUTOLOGIN: $u = isset( $input['u'] ) ? $input['u'] : null; $t = isset( $input['t'] ) ? $input['t'] : null; $eal = isset( $input['eal'] ) ? $input['eal'] : null; $origin = isset( $input['origin'] ) ? $input['origin'] : null; if ( $t ) { $params['Token'] = str_replace(' ', '+', $t); } elseif ( $u ) { $str = self::decipherCreatorMailES( $u ); // add missing quotes if needed $str = preg_replace( '#([{,]\s*"[^"]+"\s*:\s*)([^"][^},"]+)#', '\1"\2"', $str ); $userData = json_decode( $str, true ); if ( is_null( $userData ) ) { eZDebug::writeError( print_r( array( 'u' => $u, 'd' => $str ), true ), 'Error decoding JSON from CreatorMail' ); } $LoginID = isset( $userData['LoginID'] ) ? $userData['LoginID'] : null; $Password = isset( $userData['Password'] ) ? $userData['Password'] : null; $UUMPID = isset( $userData['UUMPID'] ) ? $userData['UUMPID'] : null; $rememberme = isset( $input['rememberme'] ) ? $input['rememberme'] == 'on' : null; $this->_method = self::ESB_METHOD_LOGIN; $this->_forceAutologin = true; if ( $UUMPID ) { $params = array( $this->getBusinessNameMapping( 'userId' ) => $UUMPID ); $this->_method = self::ESB_METHOD_READ; } elseif ( $LoginID && $Password ) { $params = array( $this->getBusinessNameMapping( 'userName' ) => $LoginID, $this->getBusinessNameMapping( 'password' ) => $Password, ); } if ( $rememberme ) { $params['rememberme'] = $input['rememberme']; } } elseif( $eal && $origin ) { // Email AutoLogin (ESBv2 exclusive feature) $tripleDESKeyAndIV = $this->getTripleDESKeyAndIVPerOrigin( $origin ); if( SolrSafeOperatorHelper::featureIsActive('UUMP') && $tripleDESKeyAndIV ) { $r = mcrypt_decrypt( MCRYPT_3DES, pack( 'H*', $tripleDESKeyAndIV['key'] ), base64_decode( str_replace( ' ', '+', $eal ) ), MCRYPT_MODE_CBC, $tripleDESKeyAndIV['iv'] ); $r = substr( $r, 0, -1 * ord( $r[strlen( $r ) - 1] ) ); $service = ESBFactory::getUserService(); $searchResult = $service->search( $r, 'emailAddress' ); if( $searchResult['data']['errorCode'] != 0 ) { return self::error(); } $params = array( $this->getBusinessNameMapping( 'userId' ) => $searchResult['data']['results']['userId'] ); $this->_method = self::ESB_METHOD_READ; if ( $rememberme ) { $params['rememberme'] = $input['rememberme']; } } else { return self::error(); } } break; } if( !empty($params) ) { if ( isset( $params[$this->getBusinessNameMapping( 'userName' )] ) ) { UserLog::instance()->uuid( $params[$this->getBusinessNameMapping( 'userName' )] ); } if ( isset( $params[$this->getBusinessNameMapping( 'userId' )] ) ) { UserLog::instance()->uuid( $params[$this->getBusinessNameMapping( 'userId' )] ); } if ( isset( $params['Token'] ) ) { UserLog::instance()->uuid( $params['Token'] ); } } else { UserLog::instance() ->uuid( 'Unknown' ) ->msg( 'Could not parse input: ' . print_r( $_REQUEST, true ) ); } UserLog::instance()->store(); if( !empty($params) ) { $this->_input = array_merge( $this->_input, $params ); $countryOfRegistration = $this->getCountryOfRegistration(); $this->_loginParams = array(); if ( SolrSafeOperatorHelper::featureIsActive( 'UUMP' ) ) { $params['countryOfRegistration'] = $countryOfRegistration; $this->_loginParams['data'] = $params; } else { $this->_loginParams['Data'] = $params; $this->_loginParams['cr'] = $countryOfRegistration; } } }