api_wrapper = $api_wrapper; $this->user_storage = $storage->get_user_storage(); $this->authentication_storage = $storage->get_authentication_storage(); $this->browser = $browser; $this->session = $session; $this->request = $request; } /** * @param IntegrationUser $integration_user * @param string $manual_transition * * @throws Authentication_Expired_Exception * @throws Authentication_Limit_Reached_Exception * @throws API_Exception * @throws User_Not_Found_Exception */ public function open_authentication( IntegrationUser $integration_user, $manual_transition ) { if ( $this->can_open_totp_authentication( $manual_transition ) ) { $this->open_totp_authentication( $integration_user ); } elseif ( $this->can_open_sms_authentication( $manual_transition ) ) { $this->open_sms_authentication( $integration_user ); } elseif ( $this->can_open_call_authentication( $manual_transition ) ) { $this->open_call_authentication( $integration_user ); } } /** * @throws User_Not_Found_Exception */ public function close_authentication() { $this->authentication_storage->close_authentication(); } /** * @param bool $manual_transition * * @return bool * * @throws Authentication_Expired_Exception * @throws User_Not_Found_Exception */ private function can_open_totp_authentication( $manual_transition ) { return $this->user_storage->is_totp_enabled() && $this->can_open_authentication( $manual_transition ); } /** * @param bool $manual_transition * * @return bool * * @throws Authentication_Expired_Exception * @throws Authentication_Limit_Reached_Exception * @throws User_Not_Found_Exception */ private function can_open_sms_authentication( $manual_transition ) { return $this->can_open_phone_authentication( $manual_transition, $this->is_sms_action_sent() ); } /** * @param bool $manual_transition * * @return bool * * @throws Authentication_Expired_Exception * @throws Authentication_Limit_Reached_Exception * @throws User_Not_Found_Exception */ private function can_open_call_authentication( $manual_transition ) { return $this->can_open_phone_authentication( $manual_transition, $this->is_call_action_sent() ); } /** * @param bool $manual_transition * @param bool $is_action_sent * * @return bool * * @throws Authentication_Expired_Exception * @throws Authentication_Limit_Reached_Exception * @throws User_Not_Found_Exception */ private function can_open_phone_authentication( $manual_transition, $is_action_sent ) { return $this->user_storage->is_sms_enabled() && $this->can_open_authentication( $manual_transition, $is_action_sent ); } /** * @param bool $manual_transition * @param bool $reopen * * @return bool * * @throws Authentication_Expired_Exception * @throws Authentication_Limit_Reached_Exception * @throws User_Not_Found_Exception */ private function can_open_authentication( $manual_transition, $reopen = false ) { if ( ! $this->authentication_storage->has_open_authentication() ) { return true; } if ( $this->authentication_storage->is_authentication_expired() ) { if ( ! $manual_transition ) { throw new Authentication_Expired_Exception(); } $this->close_authentication(); return true; } if ( $manual_transition || $reopen ) { if ( $this->is_authentications_limit_reached() ) { throw new Authentication_Limit_Reached_Exception( 'Open authentication limit is ' . self::OPEN_AUTHENTICATIONS_LIMIT ); } return true; } return false; } /** * @return bool * * @throws User_Not_Found_Exception */ private function is_authentications_limit_reached() { $authentications = $this->authentication_storage->get_authentications_as_array(); return count( $authentications ) >= self::OPEN_AUTHENTICATIONS_LIMIT; } /** * @return bool */ private function is_sms_action_sent() { return $this->request->is_login_action_equal_to( Login_Action::OPEN_NEW_SMS_AUTHENTICATION ); } /** * @return bool */ private function is_call_action_sent() { return $this->request->is_login_action_equal_to( Login_Action::OPEN_NEW_CALL_AUTHENTICATION ); } /** * @param IntegrationUser $integration_user * * @throws API_Exception * * @throws User_Not_Found_Exception */ private function open_totp_authentication( IntegrationUser $integration_user ) { if ( $integration_user->hasMobileUser() ) { $authentication = $this->open_totp_authentication_with_mobile_support( $integration_user ); } else { $authentication = $this->api_wrapper->request_auth_via_totp( $integration_user->getTotpSecret() ); } $this->authentication_storage->open_authentication( $authentication ); } /** * @param IntegrationUser $integration_user * * @return Authentication * * @throws API_Exception */ private function open_totp_authentication_with_mobile_support( IntegrationUser $integration_user ) { return $this->api_wrapper->request_auth_via_totp_with_mobile_support( $integration_user->getTotpSecret(), $integration_user->getMobileSecret(), $this->get_pusher_session_id(), $this->browser->describe() ); } /** * @return string */ private function get_pusher_session_id() { $pusher_session_id = $this->session->get( Authenticate_Filter::PUSHER_SESSION_ID_KEY ); if ( is_null( $pusher_session_id ) ) { $pusher_session_id = Hash::get_pusher_session_id(); $this->session->set( Authenticate_Filter::PUSHER_SESSION_ID_KEY, $pusher_session_id ); } return $pusher_session_id; } /** * @param IntegrationUser $integration_user * * @throws API_Exception * @throws User_Not_Found_Exception */ private function open_sms_authentication( IntegrationUser $integration_user ) { $authentication = $this->api_wrapper->request_auth_via_sms( $integration_user->getPhoneNumber()->phoneNumber() ); $this->authentication_storage->open_authentication( $authentication ); } /** * @param IntegrationUser $integration_user * * @throws API_Exception * @throws User_Not_Found_Exception */ private function open_call_authentication( IntegrationUser $integration_user ) { $authentication = $this->api_wrapper->request_auth_via_call( $integration_user->getPhoneNumber()->phoneNumber() ); $this->authentication_storage->open_authentication( $authentication ); } }