File "TwoFactorApiClient.php"
Full Path: /home/amervokv/ecomlive.net/wp-content/mu-plugins/vendor/wpsec/wp-2fa-plugin/src/API/TwoFactorApiClient.php
File size: 6.74 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace Wpsec\twofa\API;
use WP_Error;
use WPaaS\Plugin;
class TwoFactorApiClient {
/** @var string host */
private $host = '';
/** @var string qr_endpoint_path */
private $qr_code_endpoint_path = '/api/v1/twoFactors/authenticatorApps/';
/** @var string otp_endpoint_path */
private $otp_endpoint_path = '/api/v1/twoFactors/yubikeys/';
/** @var string email_endpoint_path */
private $email_endpoint_path = '/api/v1/twoFactors/emails/';
/** @var string remove_method_endpoint_path */
private $remove_endpoint_path = '/api/v1/twoFactors/removeMethod/';
/** @var array $host_per_env */
private $host_per_env = array(
'local' => 'http://host.docker.internal:8080',
'dev' => 'https://wp-api.wpsecurity.dev-godaddy.com',
'test' => 'https://wp-api.wpsecurity.test-godaddy.com',
'myh.test' => 'https://wp-api.wpsecurity.test-godaddy.com',
'prod' => 'https://wp-api.wpsecurity.godaddy.com',
);
/** @var array $default_request_options */
private $default_request_options = array(
'body' => '',
'headers' => array(
'Content-Type' => 'application/json',
),
'method' => 'POST',
'timeout' => 3,
'blocking' => true,
);
/**
* Documentation for cURL errors: https://curl.se/libcurl/c/libcurl-errors.html
*
* @var array $timeout_curl_errors
*/
private static $timeout_curl_errors = array(
'cURL error 6', // CURL_COULDNT_RESOLVE_HOST
'cURL error 7', // CURL_COULDNT_CONNECT
'cURL error 28', // CURL_OPERATION_TIMEDOUT
);
/**
* Define the Two Factor Api Client.
*
* @since 1.0.0
*/
public function __construct() {
$current_env = class_exists( '\WPaaS\Plugin' ) ? Plugin::get_env() : 'prod';
if ( ! array_key_exists( $current_env, $this->host_per_env ) ) {
$current_env = 'prod';
}
$this->host = $this->host_per_env[ $current_env ];
}
/**
* Generate QR code API request
*
* @param string $origin
* @param integer $user_id
* @param string $username
*
* @return array|WP_Error
*
* @since 1.0.0
*/
public function generate_qr_code( $origin, $user_id, $username ) {
$endpoint = sprintf( '%s%s%s', $this->host, $this->qr_code_endpoint_path, 'generateCode' );
$options = $this->default_request_options;
$options['body'] = wp_json_encode(
array(
'origin' => $origin,
'userId' => $user_id,
'username' => $username,
)
);
return $this->sign_and_send_request( $options, $endpoint );
}
/**
* Validate QR code api request
*
* @param string $origin
* @param integer $user_id
* @param string $code
*
* @return array|WP_Error
*
* @since 1.0.0
*/
public function validate_qr_code( $origin, $user_id, $code ) {
$endpoint = sprintf( '%s%s%s', $this->host, $this->qr_code_endpoint_path, 'verify' );
$options = $this->default_request_options;
$options['body'] = wp_json_encode(
array(
'origin' => $origin,
'userId' => $user_id,
'code' => $code,
)
);
return $this->sign_and_send_request( $options, $endpoint );
}
/**
* Save yubikey code API request
*
* @param string $origin
* @param integer $user_id
* @param string $otp
*
* @return array|WP_Error
*
* @since 1.0.0
*/
public function save_otp_code( $origin, $user_id, $otp ) {
$endpoint = sprintf( '%s%s', $this->host, $this->otp_endpoint_path );
$options = $this->default_request_options;
$options['body'] = wp_json_encode(
array(
'origin' => $origin,
'userId' => $user_id,
'yubikeyCode' => $otp,
)
);
return $this->sign_and_send_request( $options, $endpoint );
}
/**
* Validate yubikey code API request
*
* @param string $origin
* @param integer $user_id
* @param string $otp
*
* @return array|WP_Error
*
* @since 1.0.0
*/
public function validate_otp_code( $origin, $user_id, $otp ) {
$endpoint = sprintf( '%s%s%s', $this->host, $this->otp_endpoint_path, 'verify' );
$options = $this->default_request_options;
$options['body'] = wp_json_encode(
array(
'origin' => $origin,
'userId' => $user_id,
'yubikeyCode' => $otp,
)
);
return $this->sign_and_send_request( $options, $endpoint );
}
/**
* Send email verification code to API with metadata
*
* @param string $origin
* @param integer $user_id
* @param string $secret
*
* @return array|WP_Error
*
* @since 1.0.0
*/
public function save_mail_code( $origin, $user_id, $secret ) {
$endpoint = sprintf( '%s%s', $this->host, $this->email_endpoint_path );
$options = $this->default_request_options;
$options['body'] = wp_json_encode(
array(
'origin' => $origin,
'userId' => $user_id,
'emailCode' => $secret,
)
);
return $this->sign_and_send_request( $options, $endpoint );
}
/**
* Remove Two Factor method API request
*
* @param string $origin
* @param integer $user_id
* @param string $method_name
* @param integer[] $user_ids
* @param string $code
*
* @return array|WP_Error
*
* @since 1.0.0
*/
public function remove_method( $origin, $user_id, $method_name, $user_ids, $code ) {
$endpoint = sprintf( '%s%s', $this->host, $this->remove_endpoint_path );
$options = $this->default_request_options;
$options['body'] = wp_json_encode(
array(
'origin' => $origin,
'adminId' => $user_id,
'method' => $method_name,
'code' => $code,
'userIds' => $user_ids,
)
);
return $this->sign_and_send_request( $options, $endpoint );
}
/**
* Check if request response is timeout
* Since WordPress does not have any built in functionality, we are checking this manually
*
* @param object $response
*
* @return bool
* @since 1.0.0
*
*/
private function is_timeout( $response ) {
if ( ! is_wp_error( $response ) || ! isset( $response->errors['http_request_failed'] ) ) {
return false;
}
$response_error = substr( $response->errors['http_request_failed'][0], 0, 13 );
foreach ( self::$timeout_curl_errors as $curl_error ) {
if ( false !== strpos( $response_error, $curl_error ) ) {
return true;
}
}
return false;
}
/**
* Signs API request with needed headers
* @param array $options
* @param string $endpoint
*
* @return array|WP_Error
*/
private function sign_and_send_request( $options, $endpoint ) {
$signed_request_headers = Plugin::sign_http_request( $options['body'] );
if ( empty( $signed_request_headers ) ) {
return array( 'response' => array( 'code' => 504 ) );
}
$options['headers'] = array_merge( $options['headers'], $signed_request_headers );
$response = wp_remote_post( $endpoint, $options );
if ( $this->is_timeout( $response ) ) {
return array( 'response' => array( 'code' => 504 ) );
}
return $response;
}
}