Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 80 additions & 50 deletions includes/Classifai/Providers/AWS/AmazonPolly.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,68 +198,98 @@ public function get_default_provider_settings(): array {
* @return array
*/
public function sanitize_settings( array $new_settings ): array {
$settings = $this->feature_instance->get_settings();
$is_credentials_changed = false;
$settings = $this->feature_instance->get_settings();
$authenticated = $this->authenticate_credentials( $new_settings );

$new_settings[ static::ID ]['authenticated'] = $settings[ static::ID ]['authenticated'];
$new_settings[ static::ID ]['voices'] = $settings[ static::ID ]['voices'];

if (
! empty( $new_settings[ static::ID ]['access_key_id'] ) &&
! empty( $new_settings[ static::ID ]['secret_access_key'] ) &&
! empty( $new_settings[ static::ID ]['aws_region'] )
) {
$new_access_key_id = sanitize_text_field( $new_settings[ static::ID ]['access_key_id'] );
$new_secret_access_key = sanitize_text_field( $new_settings[ static::ID ]['secret_access_key'] );
$new_aws_region = sanitize_text_field( $new_settings[ static::ID ]['aws_region'] );

if (
$new_access_key_id !== $settings[ static::ID ]['access_key_id'] ||
$new_secret_access_key !== $settings[ static::ID ]['secret_access_key'] ||
$new_aws_region !== $settings[ static::ID ]['aws_region']
) {
$is_credentials_changed = true;
}

if ( $is_credentials_changed ) {
$new_settings[ static::ID ]['access_key_id'] = $new_access_key_id;
$new_settings[ static::ID ]['secret_access_key'] = $new_secret_access_key;
$new_settings[ static::ID ]['aws_region'] = $new_aws_region;

// Connect to the service and get voices.
$new_settings[ static::ID ]['voices'] = $this->connect_to_service(
array(
'access_key_id' => $new_access_key_id,
'secret_access_key' => $new_secret_access_key,
'aws_region' => $new_aws_region,
)
);

if ( ! empty( $new_settings[ static::ID ]['voices'] ) ) {
$new_settings[ static::ID ]['authenticated'] = true;
} else {
$new_settings[ static::ID ]['voices'] = [];
$new_settings[ static::ID ]['authenticated'] = false;
}
}
} else {
$new_settings[ static::ID ]['access_key_id'] = $settings[ static::ID ]['access_key_id'];
$new_settings[ static::ID ]['secret_access_key'] = $settings[ static::ID ]['secret_access_key'];
$new_settings[ static::ID ]['aws_region'] = $settings[ static::ID ]['aws_region'];
if ( is_wp_error( $authenticated ) ) {
$new_settings[ static::ID ]['authenticated'] = false;

add_settings_error(
$this->feature_instance->get_option_name(),
'classifai-ams-polly-auth-empty',
esc_html__( 'One or more credentials required to connect to the Amazon Polly service is empty.', 'classifai' ),
'api_key',
'classifai-auth',
$authenticated->get_error_message(),
'error'
);
} else {
$new_settings[ static::ID ]['authenticated'] = true;
}

$new_access_key_id = sanitize_text_field( $new_settings[ static::ID ]['access_key_id'] ?? $settings[ static::ID ]['access_key_id'] );
$new_secret_access_key = sanitize_text_field( $new_settings[ static::ID ]['secret_access_key'] ?? $settings[ static::ID ]['secret_access_key'] );
$new_aws_region = sanitize_text_field( $new_settings[ static::ID ]['aws_region'] ?? $settings[ static::ID ]['aws_region'] );

$new_settings[ static::ID ]['access_key_id'] = $new_access_key_id;
$new_settings[ static::ID ]['secret_access_key'] = $new_secret_access_key;
$new_settings[ static::ID ]['aws_region'] = $new_aws_region;

// Connect to the service and get voices.
$new_settings[ static::ID ]['voices'] = $this->connect_to_service(
array(
'access_key_id' => $new_access_key_id,
'secret_access_key' => $new_secret_access_key,
'aws_region' => $new_aws_region,
)
);

if ( ! empty( $new_settings[ static::ID ]['voices'] ) ) {
$new_settings[ static::ID ]['authenticated'] = true;
} else {
$new_settings[ static::ID ]['voices'] = [];
$new_settings[ static::ID ]['authenticated'] = false;
}

$new_settings[ static::ID ]['voice'] = sanitize_text_field( $new_settings[ static::ID ]['voice'] ?? $settings[ static::ID ]['voice'] );

return $new_settings;
}

/**
* Authenticate our credentials.
*
* @param array $settings Settings being saved.
* @return bool|WP_Error
*/
protected function authenticate_credentials( array $settings = [] ) {
$response = false;

try {
/**
* Filters the return value of the connect to services function.
*
* Returning a non-false value from the filter will short-circuit
* the describe voices request and return early with that value.
* This filter is useful for E2E tests.
*
* @since 3.1.0
* @hook classifai_aws_polly_pre_connect_to_service
*
* @param bool $pre The value of pre connect to service. Default false. A non-false value will short-circuit the describe voices request.
*
* @return bool|mixed The filtered value of connect to service.
*/
$pre = apply_filters( 'classifai_' . self::ID . '_pre_connect_to_service', false );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add this filter to the other providers?

Unrelated to this ticket/PR, not a merge consideration.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this was added specifically to help mock API responses for AWS Polly in our E2E tests. All other requests we mock using the pre_http_request filter but because we're using the AWS SDK here, these requests don't filter through the WordPress HTTP API and thus that filter never fires.

That said, I'm not opposed to more standard hooks here though I think worth thinking through once we look to standardize on using the PHP AI Client to make our requests (where possible)


if ( false !== $pre ) {
return $pre;
}

$polly_client = $this->get_polly_client( $settings[ static::ID ] );

if ( $polly_client ) {
$polly_voices = $polly_client->describeVoices();
$polly_voices = $polly_voices->get( 'Voices' );
} else {
$polly_voices = [];
}

$response = ! empty( $polly_voices ) ? true : new WP_Error( 'auth', esc_html__( 'Connection to Amazon Polly failed.', 'classifai' ) );
} catch ( \Exception $e ) {
$response = new WP_Error( 'auth', esc_html__( 'Connection to Amazon Polly failed.', 'classifai' ) );
}

return ! is_wp_error( $response ) ? true : $response;
}

/**
* Connects to the Amazon Polly service.
*
Expand Down
46 changes: 15 additions & 31 deletions includes/Classifai/Providers/Azure/ComputerVision.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,47 +204,31 @@ public function get_default_provider_settings(): array {
}

/**
* Sanitization
* Sanitize the settings for this Provider.
*
* @param array $new_settings The settings being saved.
* @return array|mixed
*/
public function sanitize_settings( array $new_settings ) {
$settings = $this->feature_instance->get_settings();
$settings = $this->feature_instance->get_settings();
$authenticated = $this->authenticate_credentials( $new_settings );

if ( ! empty( $new_settings[ static::ID ]['endpoint_url'] ) && ! empty( $new_settings[ static::ID ]['api_key'] ) ) {
$new_settings[ static::ID ]['authenticated'] = $settings[ static::ID ]['authenticated'];
$new_settings[ static::ID ]['endpoint_url'] = esc_url_raw( $new_settings[ static::ID ]['endpoint_url'] ?? $settings[ static::ID ]['endpoint_url'] );
$new_settings[ static::ID ]['api_key'] = sanitize_text_field( $new_settings[ static::ID ]['api_key'] ?? $settings[ static::ID ]['api_key'] );
if ( is_wp_error( $authenticated ) ) {
$new_settings[ static::ID ]['authenticated'] = false;

$is_authenticated = $new_settings[ static::ID ]['authenticated'];
$is_endpoint_same = $new_settings[ static::ID ]['endpoint_url'] === $settings[ static::ID ]['endpoint_url'];
$is_api_key_same = $new_settings[ static::ID ]['api_key'] === $settings[ static::ID ]['api_key'];

if ( ! ( $is_authenticated && $is_endpoint_same && $is_api_key_same ) ) {
$auth_check = $this->authenticate_credentials( $new_settings );

if ( is_wp_error( $auth_check ) ) {
$new_settings[ static::ID ]['authenticated'] = false;

$error_message = $auth_check->get_error_message();

// Add an error message.
add_settings_error(
'api_key',
'classifai-auth',
$error_message,
'error'
);
} else {
$new_settings[ static::ID ]['authenticated'] = true;
}
}
add_settings_error(
'api_key',
'classifai-auth',
$authenticated->get_error_message(),
'error'
);
} else {
$new_settings[ static::ID ]['endpoint_url'] = $settings[ static::ID ]['endpoint_url'];
$new_settings[ static::ID ]['api_key'] = $settings[ static::ID ]['api_key'];
$new_settings[ static::ID ]['authenticated'] = true;
}

$new_settings[ static::ID ]['endpoint_url'] = esc_url_raw( $new_settings[ static::ID ]['endpoint_url'] ?? $settings[ static::ID ]['endpoint_url'] );
$new_settings[ static::ID ]['api_key'] = sanitize_text_field( $new_settings[ static::ID ]['api_key'] ?? $settings[ static::ID ]['api_key'] );

if ( $this->feature_instance instanceof DescriptiveTextGenerator ) {
$new_settings[ static::ID ]['descriptive_confidence_threshold'] = floatval( $new_settings[ static::ID ]['descriptive_confidence_threshold'] ?? $settings[ static::ID ]['descriptive_confidence_threshold'] );
}
Expand Down
55 changes: 17 additions & 38 deletions includes/Classifai/Providers/Azure/OpenAI.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,47 +200,26 @@ public function get_default_provider_settings(): array {
* @return array
*/
public function sanitize_settings( array $new_settings ): array {
$settings = $this->feature_instance->get_settings();

if (
! empty( $new_settings[ static::ID ]['endpoint_url'] ) &&
! empty( $new_settings[ static::ID ]['api_key'] ) &&
! empty( $new_settings[ static::ID ]['deployment'] )
) {
$new_settings[ static::ID ]['authenticated'] = $settings[ static::ID ]['authenticated'];
$new_settings[ static::ID ]['endpoint_url'] = esc_url_raw( $new_settings[ static::ID ]['endpoint_url'] ?? $settings[ static::ID ]['endpoint_url'] );
$new_settings[ static::ID ]['api_key'] = sanitize_text_field( $new_settings[ static::ID ]['api_key'] ?? $settings[ static::ID ]['api_key'] );
$new_settings[ static::ID ]['deployment'] = sanitize_text_field( $new_settings[ static::ID ]['deployment'] ?? $settings[ static::ID ]['deployment'] );

$is_authenticated = $new_settings[ static::ID ]['authenticated'];
$is_endpoint_same = $new_settings[ static::ID ]['endpoint_url'] === $settings[ static::ID ]['endpoint_url'];
$is_api_key_same = $new_settings[ static::ID ]['api_key'] === $settings[ static::ID ]['api_key'];
$is_deployment_same = $new_settings[ static::ID ]['deployment'] === $settings[ static::ID ]['deployment'];

if ( ! ( $is_authenticated && $is_endpoint_same && $is_api_key_same && $is_deployment_same ) ) {
$auth_check = $this->authenticate_credentials( $new_settings );

if ( is_wp_error( $auth_check ) ) {
$new_settings[ static::ID ]['authenticated'] = false;
$error_message = $auth_check->get_error_message();

// Add an error message.
add_settings_error(
'api_key',
'classifai-auth',
$error_message,
'error'
);
} else {
$new_settings[ static::ID ]['authenticated'] = true;
}
}
$settings = $this->feature_instance->get_settings();
$authenticated = $this->authenticate_credentials( $new_settings );

if ( is_wp_error( $authenticated ) ) {
$new_settings[ static::ID ]['authenticated'] = false;

add_settings_error(
'api_key',
'classifai-auth',
$authenticated->get_error_message(),
'error'
);
} else {
$new_settings[ static::ID ]['endpoint_url'] = $settings[ static::ID ]['endpoint_url'];
$new_settings[ static::ID ]['api_key'] = $settings[ static::ID ]['api_key'];
$new_settings[ static::ID ]['deployment'] = $settings[ static::ID ]['deployment'];
$new_settings[ static::ID ]['authenticated'] = true;
}

$new_settings[ static::ID ]['endpoint_url'] = esc_url_raw( $new_settings[ static::ID ]['endpoint_url'] ?? $settings[ static::ID ]['endpoint_url'] );
$new_settings[ static::ID ]['api_key'] = sanitize_text_field( $new_settings[ static::ID ]['api_key'] ?? $settings[ static::ID ]['api_key'] );
$new_settings[ static::ID ]['deployment'] = sanitize_text_field( $new_settings[ static::ID ]['deployment'] ?? $settings[ static::ID ]['deployment'] );

switch ( $this->feature_instance::ID ) {
case ContentResizing::ID:
case TitleGeneration::ID:
Expand Down
Loading