Skip to content
Open
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
7 changes: 7 additions & 0 deletions admin/class-convertkit-admin-bulk-edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ public function bulk_edit_save() {

// Iterate through each Post, updating its settings.
foreach ( $post_ids as $post_id ) {
// Skip Posts the current user cannot edit.
// The post type's edit_posts capability checked above does not grant
// permission to edit every Post of that type.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
continue;
}

WP_ConvertKit()->get_class( 'admin_post' )->save_post_settings( $post_id, wp_unslash( $_REQUEST['wp-convertkit'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
}

Expand Down
5 changes: 5 additions & 0 deletions admin/class-convertkit-admin-cache-plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public function __construct() {
*/
public function maybe_configure_cache_plugins() {

// Only allow Administrators to update third party Plugin settings.
if ( ! current_user_can( 'manage_options' ) ) {
return;
}

// If no Pages, Posts or CPTs are configured to use Restrict Content, don't
// configure any caching plugins.
if ( ! WP_ConvertKit()->get_class( 'admin_restrict_content' )->restrict_content_enabled() ) {
Expand Down
5 changes: 5 additions & 0 deletions admin/class-convertkit-admin-category.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ public function edit_category_form_fields( $term ) {
*/
public function save_category_fields( $term_id ) {

// Bail if the current user cannot edit this Category.
if ( ! current_user_can( 'edit_term', $term_id ) ) {
return;
}

// Bail if no nonce field exists.
if ( ! isset( $_POST['wp-convertkit-save-meta-nonce'] ) ) {
return;
Expand Down
5 changes: 5 additions & 0 deletions admin/class-convertkit-admin-landing-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public function register_add_new_button( $buttons, $post_type ) {
return $buttons;
}

// Don't show the button if the user cannot create and publish Pages.
if ( ! convertkit_user_can_create_published_post_type( $post_type ) ) {
return $buttons;
}

// Register button.
$buttons['convertkit_landing_page_setup'] = array(
'url' => add_query_arg(
Expand Down
5 changes: 5 additions & 0 deletions admin/class-convertkit-admin-post.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ public function save_post_meta( $post_id ) {
return;
}

// Bail if the current user cannot edit this Post.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}

// Bail if no nonce field exists.
if ( ! isset( $_POST['wp-convertkit-save-meta-nonce'] ) ) {
return;
Expand Down
5 changes: 5 additions & 0 deletions admin/class-convertkit-admin-restrict-content.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ public function register_add_new_button( $buttons, $post_type ) {
return $buttons;
}

// Don't show the button if the user cannot create and publish this Post Type.
if ( ! convertkit_user_can_create_published_post_type( $post_type ) ) {
return $buttons;
}

// Register button.
$buttons['convertkit_restrict_content_setup'] = array(
'url' => add_query_arg(
Expand Down
34 changes: 34 additions & 0 deletions admin/class-convertkit-admin-setup-wizard.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ class ConvertKit_Admin_Setup_Wizard {
*/
public $error = false;

/**
* Holds the Post Type to generate.
*
* @since 3.3.9
*
* @var string
*/
public $post_type = 'page';

/**
* The required user capability to access the setup wizard.
*
Expand Down Expand Up @@ -507,4 +516,29 @@ public function user_has_access() {

}

/**
* Sets the Post Type from the request, ensuring it is supported by the Plugin.
*
* @since 3.3.9
*/
protected function set_post_type() {

$this->post_type = ( filter_has_var( INPUT_GET, 'ck_post_type' ) ? filter_input( INPUT_GET, 'ck_post_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : 'page' );

if ( ! in_array( $this->post_type, convertkit_get_supported_post_types(), true ) ) {
wp_die(
sprintf(
/* translators: Post Type */
esc_html__( 'The post type `%s` is not supported for Member Content.', 'convertkit' ),
esc_html( $this->post_type )
),
esc_html__( 'WordPress Error', 'convertkit' ),
array(
'back_link' => true,
)
);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@
*/
class ConvertKit_Admin_Setup_Wizard_Landing_Page extends ConvertKit_Admin_Setup_Wizard {

/**
* Holds the Post Type to generate.
*
* @since 2.5.5
*
* @var string
*/
public $post_type = 'page';

/**
* Holds the ConvertKit Products resource class.
*
Expand Down Expand Up @@ -128,6 +119,13 @@ public function define_steps( $steps ) {
*/
public function process_form( $step ) {

// Set and authorize the Post Type before processing data.
$this->set_post_type();
if ( ! convertkit_user_can_create_published_post_type( $this->post_type ) ) {
$this->error = __( 'You are not allowed to create and publish this type of content.', 'convertkit' );
return;
}

// Run security checks.
if ( ! isset( $_REQUEST['_wpnonce'] ) ) {
return;
Expand Down Expand Up @@ -181,26 +179,10 @@ public function load_screen_data( $step ) {
wp_die( esc_html__( 'Connect your Kit account in the Kit Plugin\'s settings to get started', 'convertkit' ) );
}

// Get Post Type.
if ( filter_has_var( INPUT_GET, 'ck_post_type' ) ) {
$this->post_type = filter_input( INPUT_GET, 'ck_post_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
} else {
$this->post_type = 'page';
}

// Bail if the Post Type isn't supported.
if ( ! in_array( $this->post_type, convertkit_get_supported_post_types(), true ) ) {
wp_die(
sprintf(
/* translators: Post Type */
esc_html__( 'The post type `%s` is not supported for Member Content.', 'convertkit' ),
esc_html( $this->post_type )
),
esc_html__( 'WordPress Error', 'convertkit' ),
array(
'back_link' => true,
)
);
// Set and authorize the Post Type.
$this->set_post_type();
if ( ! convertkit_user_can_create_published_post_type( $this->post_type ) ) {
wp_die( esc_html__( 'Sorry, you are not allowed to create and publish this type of content.', 'convertkit' ) );
}

// Define Exit URL to take the user back to the WP_List_Table for the Post Type they were viewing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class ConvertKit_Admin_Setup_Wizard_Plugin extends ConvertKit_Admin_Setup_Wizard
*
* @var string
*/
public $required_capability = 'edit_posts';
public $required_capability = 'manage_options';

/**
* The programmatic name for this wizard.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@
*/
class ConvertKit_Admin_Setup_Wizard_Restrict_Content extends ConvertKit_Admin_Setup_Wizard {

/**
* Holds the Post Type to generate Members Content for.
*
* @since 2.1.0
*
* @var string
*/
public $post_type = 'page';

/**
* Holds the type of Member's Content to generate (course|download).
*
Expand Down Expand Up @@ -185,6 +176,13 @@ public function define_steps( $steps ) {
*/
public function process_form( $step ) {

// Set and authorize the Post Type before processing data.
$this->set_post_type();
if ( ! convertkit_user_can_create_published_post_type( $this->post_type ) ) {
$this->error = __( 'You are not allowed to create and publish this type of content.', 'convertkit' );
return;
}

// Run security checks.
if ( ! isset( $_REQUEST['_wpnonce'] ) ) {
return;
Expand Down Expand Up @@ -256,26 +254,10 @@ public function load_screen_data( $step ) {
wp_die( esc_html__( 'Connect your ConvertKit account in the ConvertKit Plugin\'s settings to get started', 'convertkit' ) );
}

// Get the Post Type.
if ( filter_has_var( INPUT_GET, 'ck_post_type' ) ) {
$this->post_type = filter_input( INPUT_GET, 'ck_post_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
} else {
$this->post_type = 'page';
}

// Bail if the Post Type isn't supported.
if ( ! in_array( $this->post_type, convertkit_get_supported_post_types(), true ) ) {
wp_die(
sprintf(
/* translators: Post Type */
esc_html__( 'The post type `%s` is not supported for Member Content.', 'convertkit' ),
esc_html( $this->post_type )
),
esc_html__( 'WordPress Error', 'convertkit' ),
array(
'back_link' => true,
)
);
// Set and authorize the Post Type.
$this->set_post_type();
if ( ! convertkit_user_can_create_published_post_type( $this->post_type ) ) {
wp_die( esc_html__( 'Sorry, you are not allowed to create and publish this type of content.', 'convertkit' ) );
}

// Define Exit URL to take the user back to the WP_List_Table for the Post Type they were viewing.
Expand Down
5 changes: 5 additions & 0 deletions includes/class-convertkit-broadcasts-exporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ public function run_row_action() {
return;
}

// Bail if the current user cannot edit the Post being exported.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
wp_die( esc_html__( 'Sorry, you are not allowed to export this Post.', 'convertkit' ) );
}

// Export Post to a draft ConvertKit Broadcast.
$result = $this->export_post_to_broadcast( $post_id );

Expand Down
20 changes: 20 additions & 0 deletions includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,26 @@ function convertkit_get_supported_post_types() {

}

/**
* Determines whether the current user can create and publish the given Post Type.
*
* @since 3.3.9
*
* @param string $post_type Post Type.
* @return bool User can create and publish Post Type.
*/
function convertkit_user_can_create_published_post_type( $post_type ) {

$post_type_object = get_post_type_object( $post_type );

if ( ! $post_type_object ) {
return false;
}

return current_user_can( $post_type_object->cap->create_posts ) && current_user_can( $post_type_object->cap->publish_posts );

}

/**
* Helper method to get supported Post Types for Restricted Content (Member's Content)
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ public function save_post_meta( $post_id ) {
return;
}

// Bail if the current user cannot edit this Post.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}

// Bail if no nonce field exists.
if ( ! isset( $_POST['wp-convertkit-pre-publish-actions-nonce'] ) ) {
return;
Expand Down
65 changes: 65 additions & 0 deletions tests/EndToEnd/forms/post-types/BulkQuickEditFormCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,71 @@ public function testBulkEditUsingDefaultForm(EndToEndTester $I)
}
}

/**
* Test that Bulk Edit does not save Kit settings for a Post the current user cannot edit.
*
* @since 3.3.9
*
* @param EndToEndTester $I Tester.
*/
public function testBulkEditDoesNotSaveSettingsForPostUserCannotEdit(EndToEndTester $I)
{
// Create an Author and a Post that they own.
$authorID = $I->haveUserInDatabase('convertkit_bulk_edit_author', 'author');
$postID = $I->havePostInDatabase(
[
'post_author' => $authorID,
'post_type' => 'post',
'post_title' => 'Kit: Bulk Edit: Author Post',
]
);

// Create a Post owned by the Administrator.
$administratorID = $I->grabUserIdFromDatabase($_ENV['WORDPRESS_ADMIN_USER']);
$otherPostID = $I->havePostInDatabase(
[
'post_author' => $administratorID,
'post_type' => 'post',
'post_title' => 'Kit: Bulk Edit: Administrator Post',
]
);

// Login as the Author.
$I->logOut();
$I->loginAs('convertkit_bulk_edit_author', 'convertkit_bulk_edit_author');

// Open Bulk Edit for the Author's Post.
$I->openBulkEdit($I, 'post', [ $postID ]);

// Add an Administrator-owned Post ID to the submitted request.
$I->executeJS(
'
var postID = document.createElement("input");
postID.setAttribute("type", "hidden");
postID.setAttribute("name", "post[]");
postID.setAttribute("value", "' . $otherPostID . '");
document.querySelector("#bulk-edit").appendChild(postID);
'
);

// Set a Kit Form and save the Bulk Edit request.
$I->selectOption('#convertkit-bulk-edit #wp-convertkit-bulk-edit-form', $_ENV['CONVERTKIT_API_FORM_NAME']);
$I->click('#bulk_edit');
$I->waitForElementVisible('div.updated');

// Confirm no settings were saved against the Administrator-owned Post.
$I->dontSeePostMetaInDatabase(
[
'post_id' => $otherPostID,
'meta_key' => '_wp_convertkit_post_meta',
]
);

// Login as the Administrator so the test suite can deactivate the Plugin.
$I->logOut();
$I->doLoginAsAdmin($I);
}

/**
* Test that the defined form displays when chosen via
* WordPress' Bulk Edit functionality.
Expand Down
Loading