Skip to content

Commit

Permalink
Add private sites module (#10333)
Browse files Browse the repository at this point in the history
* add private sites module

* remove unneccessary code

* fix linting issues

* move fuctions to a class

* Disable sharing, publicize and subcription modules on private sites

* prevent site visibility change when the private site module is enbabled

* only show an error when the error function exists

* make a site private when the module is enabled

* Update the message when changing blog_public

* fixes based on feedback

* changes based on feedback

* copy update

* hide visibility settings

* copy update

* remove extra text

* Add an error code to the REST API blocking code

* Update wording

* Move to the security section

* Rename function for consistency

* update release number

* remove unnecessary file check

* remove unused  variable

* rebsase from master

* remove bloginfo filter when syncing

* Update blog_public option when private module activates or deactivates.

* Removing a stray debug line

* Hide OPML for private sites

* prevent all ajax requests on private sites

* Replacing global  with WP functions

* Prevent requests to admin-post.php for private sites

* removing inadvertently introduced stray spaces

* Move blog_public update_option out of init
Instead of updating blog_public option in init, we now update it when the private module is activated.

* Replace /traffic links with /security

* 1. Add 403 response code 2. For OPML, exit with 403 and don't display private site page

* 403 response code for OPML

* Remove inadvertent log line

* Replace get_blog_info() with get_blog_details(), since the former only exists on WPCOM

* Add private sites message to Site Visibility option in Reading settings

* Replacing hide_opml() with static function

* 1. Remove blog_public modifications 2. Hide sitemap for private sites 3. Rename Protected to Private

* Disable sitemap for private sites (refactored)

* Bump priority for preprocess_comment so that it runs before Akismet

* add an explanation for this line

* Removed the jetpack_get_available_modules filter since it doesn't save state for disabled modules; instead we're moving to use jetpack_get_available_modules filter

* fixing merge conflict

* 1. Removed global wpdb 2. Copy change 3. Using set_url_scheme() for the private page URL

* Remove is_super_admin() checks and instead utilize the check for read capability in is_private_blog_user()

* Fixing lint errors

* 1. Stricter checking for  type 2. Updated versions

* 1. Bug fix (missing parenthesis) 2. For is_private_blog_user(), removed  function param and instead made its value the current user's value 3. Removed protected for functions that don't need them

* Now using current_user_can_for_blog(), a core function which would be better than using for_site

* Changing milestone

* Adding the p2 reference in comment

* Reverted the change to printf that removes wp_kses. Reinstated wp_kses per feedback. Also, fixed a docblock comment

* 1. Copy change 2. Added jetpack_ prefix to priv_notice_privacy_selector() fn name

* 1. Copy change 2. Added jetpack_ prefix to priv_notice_privacy_selector() fn name

* Lint fixes, and merged back changes lost in b2913ad

* The last attemp at fixing yarn.lock conflict didn't work, trying again by running yarn build

* rebuilding yarn.lock

* Update modules/private/class-jetpack-private.php

Copy change.

Co-Authored-By: niranjan-uma-shankar <niranjan.u@gmail.com>

* Adding error messages

* Fixes issue of module states not being restored

This revision fixes the issue originally reported by @mdawaffe in #10333 (review).
The following changes are effected: (1) update_active_modules() was incorrectly saving the filtered modules to options. This has been fixed by making the function save only the newly activated modules to options. (2) deactivate_module() was incorrectly saving the filtered modules to options. This has been fixed by not passing the modules through filters (3) We now load the private module(if it has been activated) before loading any other module. This makes the other modules respect the actions and filters defined in the private module.

* 1. Removing stray whitespace as a result of bad merge 2. Rebuild yarn.lock

* Undo changes to deactivate_module(). This change has no effect and is unnecessary.

* Renamed variable for better clarity

* Copy change

* Add private/public status to the At a glance widget

* Added learn more link

* Revised the target milestone

* Minor change in doc block

* Styling changes: adding font color

* Update _inc/client/security/private.jsx

Remove the constant since we're using the value in only one place.

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update _inc/client/security/private.jsx

Remove the constant.

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update class.jetpack.php

The entire URL is brought inside `admin_url`

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update class.jetpack.php

Fixing docblock

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update modules/module-extras.php

Moving the entire URL inside `admin_url`

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update modules/private/class-jetpack-private.php

Moving the entire url inside `admin_url`

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update modules/private/class-jetpack-private.php

Minor change in the milestone -> 7.4 to 7.4.0

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update modules/private/class-jetpack-private.php

Moving the entire url inside `admin_url`

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* Update modules/private/class-jetpack-private.php

Moving the entire url inside `admin_url`

Co-Authored-By: Jeremy Herve <jeremy@tagada.hu>

* 1. Minor fix in milestone (7.4 to 7.4.0) 2. Added phpcs ignore for wp_kses 3. Copy change

* 1. Removed FEATURE_PRIVATE_JETPACK constant since it's only used for paid features

* Readability change

* 1. Moved css to file 2. Added doc block for at a glance callback

* Moved the css styling from the css file to inline style; deleted the css file.

* Post rebase, fixing conflicts

* Rebase

* Add inline css only in the main admin page

* 1. Replace esc_attr with esc_url 2. Copy change 3. Added 'status' key to WP_Error error code

* 1. For a private site, removes the 'Search engines are discouraged' message from At a glance dashboard 2. Adds a line break preceeding the 'Search engines are discouraged message'


Co-authored-by:  <niranjan.uma.shankar@automattic.com>
Co-authored-by: Jeremy Herve <jeremy@tagada.hu>
  • Loading branch information
scruffian and jeherve committed May 27, 2019
1 parent 343f990 commit 2316b87
Show file tree
Hide file tree
Showing 12 changed files with 627 additions and 15 deletions.
7 changes: 5 additions & 2 deletions _inc/client/security/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import BackupsScan from './backups-scan';
import Antispam from './antispam';
import { ManagePlugins } from './manage-plugins';
import { Monitor } from './monitor';
import { Private } from './private';
import { Protect } from './protect';
import { SSO } from './sso';

Expand Down Expand Up @@ -72,13 +73,14 @@ export class Security extends Component {
foundAkismet = this.isAkismetFound(),
rewindActive = 'active' === get( this.props.rewindStatus, [ 'state' ], false ),
foundBackups = this.props.isModuleFound( 'vaultpress' ) || rewindActive,
foundMonitor = this.props.isModuleFound( 'monitor' );
foundMonitor = this.props.isModuleFound( 'monitor' ),
foundPrivateSites = this.props.isModuleFound( 'private' );

if ( ! this.props.searchTerm && ! this.props.active ) {
return null;
}

if ( ! foundSso && ! foundProtect && ! foundAkismet && ! foundBackups && ! foundMonitor ) {
if ( ! foundSso && ! foundProtect && ! foundAkismet && ! foundBackups && ! foundMonitor && ! foundPrivateSites ) {
return null;
}

Expand Down Expand Up @@ -106,6 +108,7 @@ export class Security extends Component {
<ManagePlugins { ...commonProps } />
{ foundProtect && <Protect { ...commonProps } /> }
{ foundSso && <SSO { ...commonProps } /> }
{ foundPrivateSites && <Private { ...commonProps } /> }
</div>
);
}
Expand Down
52 changes: 52 additions & 0 deletions _inc/client/security/private.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* External dependencies
*/
import React, { Component } from 'react';
import { translate as __ } from 'i18n-calypso';

/**
* Internal dependencies
*/
import { ModuleToggle } from 'components/module-toggle';
import SettingsCard from 'components/settings-card';
import SettingsGroup from 'components/settings-group';
import { withModuleSettingsFormHelpers } from 'components/module-settings/with-module-settings-form-helpers';

export const Private = withModuleSettingsFormHelpers(
class extends Component {
render() {
return (
<SettingsCard { ...this.props } module="private" hideButton>
<SettingsGroup
hasChild
module={ { module: 'private' } }
support={ {
text: __(
"This option is great if you're still working on your site " +
" and aren't quite ready to show it off to the rest of the internet yet."
),
link: 'https://jetpack.com/support/private',
} }
>
<p>
{ __(
'Private sites can only be seen by you ' +
'and other users who are members of this site.'
) }
</p>

<ModuleToggle
slug="private"
compact
activated={ this.props.getOptionValue( 'private' ) }
toggling={ this.props.isSavingAnyOption( 'private' ) }
toggleModule={ this.props.toggleModuleNow }
>
{ __( 'Make your site private' ) }
</ModuleToggle>
</SettingsGroup>
</SettingsCard>
);
}
}
);
2 changes: 2 additions & 0 deletions bin/phpcs-whitelist.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ module.exports = [
'modules/verification-tools.php',
'modules/wpcom-block-editor/class-jetpack-wpcom-block-editor.php',
'packages',
'modules/private.php',
'modules/private/',
];
97 changes: 87 additions & 10 deletions class.jetpack.php
Original file line number Diff line number Diff line change
Expand Up @@ -1809,9 +1809,80 @@ function user_role_change( $user_id ) {
}

/**
* Loads the currently active modules.
* Loads the private module if it has been activated.
* Else, updates the admin dashboard with the site's private status.
*/
public static function load_modules() {
public static function load_private() {
if ( self::is_module_active( 'private' ) ) {
self::load_modules( array( 'private' ) );
} else {
add_action( 'update_right_now_text', array( __CLASS__, 'add_public_dashboard_glance_items' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'wp_admin_glance_dashboard_style' ) );
add_filter( 'privacy_on_link_text', array( __CLASS__, 'private_site_privacy_on_link_text' ) );
}
}

/**
* Adds a line break for the 'Search Engines Discouraged' message
* displayed in the 'At a Glance' dashboard widget.
*
* @param string $content Content of 'At A Glance' wp-admin dashboard widget.
* @return string The modified content of the 'At a Glance' dashboard widget.
*/

public static function private_site_privacy_on_link_text( $content ) {
return '<br>' . $content;
}

/**
* Basic styling for the wp-admin 'At a Glance' dashboard widget.
* This is applied when the private module is inactive.
*
* @param string $hook Page Hook Suffix for the current page.
*/
public static function wp_admin_glance_dashboard_style( $hook ) {
if ( 'index.php' !== $hook ) {
return;
}

$custom_css = '
.jp-at-a-glance__site-public {
color: #46B450;
}
';
wp_add_inline_style( 'dashboard', $custom_css );
}

/**
* Adds a message to the 'At a Glance' dashboard widget.
*
* @param string $content Content of 'At A Glance' wp-admin dashboard widget.
* @return string The modified content of the 'At a Glance' dashboard widget.
*/
public static function add_public_dashboard_glance_items( $content ) {
return
$content .
'<br><br>' .
wp_kses(
sprintf(
/* translators: URL for Jetpack dashboard. */
__( '<span class="%1$1s">This site is set to public.</span> <a href="%2$2s">Make private</a>.', 'jetpack' ),
esc_attr( 'jp-at-a-glance__site-public' ),
esc_url( admin_url( 'admin.php?page=jetpack#/security?term=private' ) )
),
array(
'a' => array( 'href' => true ),
'span' => array( 'class' => true ),
)
);
}

/**
* Loads modules from given array, otherwise all the currently active modules.
*
* @param array $modules Specific modules to be loaded.
*/
public static function load_modules( $modules = array() ) {
if (
! self::is_active()
&& ! self::is_development_mode()
Expand All @@ -1831,9 +1902,13 @@ public static function load_modules() {
do_action( 'updating_jetpack_version', $version, false );
Jetpack_Options::update_options( compact( 'version', 'old_version' ) );
}
list( $version ) = explode( ':', $version );
list( $version ) = explode( ':', $version );
$fetched_all_active_modules = false;

$modules = array_filter( Jetpack::get_active_modules(), array( 'Jetpack', 'is_module' ) );
if ( empty( $modules ) ) {
$modules = array_filter( Jetpack::get_active_modules(), array( 'Jetpack', 'is_module' ) );
$fetched_all_active_modules = true;
}

$modules_data = array();

Expand Down Expand Up @@ -1890,12 +1965,14 @@ public static function load_modules() {
do_action( 'jetpack_module_loaded_' . $module );
}

/**
* Fires when all the modules are loaded.
*
* @since 1.1.0
*/
do_action( 'jetpack_modules_loaded' );
if ( $fetched_all_active_modules ) {
/**
* Fires when all the modules are loaded.
*
* @since 1.1.0
*/
do_action( 'jetpack_modules_loaded' );
}

// Load module-specific code that is needed even when a module isn't active. Loaded here because code contained therein may need actions such as setup_theme.
require_once( JETPACK__PLUGIN_DIR . 'modules/module-extras.php' );
Expand Down
1 change: 1 addition & 0 deletions jetpack.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ function jetpack_admin_missing_autoloader() { ?>
add_action( 'updating_jetpack_version', array( 'Jetpack', 'do_version_bump' ), 10, 2 );
add_action( 'init', array( 'Jetpack', 'init' ) );
add_action( 'plugins_loaded', array( 'Jetpack', 'plugin_textdomain' ), 99 );
add_action( 'plugins_loaded', array( 'Jetpack', 'load_private' ), 99 );
add_action( 'plugins_loaded', array( 'Jetpack', 'load_modules' ), 100 );
add_filter( 'jetpack_static_url', array( 'Jetpack', 'staticize_subdomain' ) );
add_filter( 'is_jetpack_site', '__return_true' );
Expand Down
25 changes: 25 additions & 0 deletions modules/module-extras.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,28 @@ function jetpack_widgets_add_suffix( $widget_name ) {
);
}
add_filter( 'jetpack_widget_name', 'jetpack_widgets_add_suffix' );

add_action( 'blog_privacy_selector', 'jetpack_priv_notice_privacy_selector' );

/**
* Echos notice directing site owners to Jetpack's Private Site feature.
*/
function jetpack_priv_notice_privacy_selector() {
?>
<p>
<?php

wp_kses(
printf(
/* translators: URL to the Jetpack dashboard. */
__( 'You can also make your site completely private by allowing only registered users to see it. <a href="%s">Go to Private Site settings</a>.', 'jetpack' ),
esc_url( admin_url( 'admin.php?page=jetpack#/security?term=private' ) )
),
array( 'a' => array( 'href' => true ) )
);
?>
</p>

<?php
}

9 changes: 9 additions & 0 deletions modules/module-headings.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ function jetpack_get_module_i18n( $key ) {
'description' => _x( 'Publish posts by sending an email', 'Module Description', 'jetpack' ),
),

'private' => array(
'name' => _x( 'Private site', 'Module Name', 'jetpack' ),
'description' => _x( 'Make your site only visible to you and users you approve.', 'Module Description', 'jetpack' ),
),

'protect' => array(
'name' => _x( 'Protect', 'Module Name', 'jetpack' ),
'description' => _x( 'Protect yourself from brute force and distributed brute force attacks, which are the most common way for hackers to get into your site.', 'Module Description', 'jetpack' ),
Expand Down Expand Up @@ -328,6 +333,10 @@ function jetpack_get_module_i18n_tag( $key ) {
// - modules/minileven.php
'Mobile' =>_x( 'Mobile', 'Module Tag', 'jetpack' ),

// Modules with `Private` tag:
// - modules/private.php
'Private' =>_x( 'Private', 'Module Tag', 'jetpack' ),

// Modules with `Traffic` tag:
// - modules/sitemaps.php
// - modules/wordads.php
Expand Down
19 changes: 19 additions & 0 deletions modules/module-info.php
Original file line number Diff line number Diff line change
Expand Up @@ -912,3 +912,22 @@ function jetpack_more_info_copy_post() {
esc_html_e( 'Create a new post based on an existing post.', 'jetpack' );
}
add_action( 'jetpack_module_more_info_copy-post', 'jetpack_more_info_copy_post' );

/**
* Private sites support link.
*/
function jetpack_private_more_link() {
echo 'https://jetpack.com/support/private';
}
add_action( 'jetpack_learn_more_button_private', 'jetpack_private_more_link' );

/**
* Private sites description.
*/
function jetpack_private_more_info() {
esc_html_e(
'Make your site private. It will only be visible to registered users.',
'jetpack'
);
}
add_action( 'jetpack_module_more_info_private', 'jetpack_private_more_info' );
19 changes: 19 additions & 0 deletions modules/private.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/**
* Module Name: Private site
* Module Description: Make your site only visible to you and users you approve.
* Sort Order: 9
* First Introduced: 7.4.0
* Requires Connection: No
* Auto Activate: No
* Module Tags: Private
* Feature: Security
* Additional Search Queries: private, sandbox, launch, unlaunched, maintenance, coming soon
*
* @package Jetpack
*/

/* Private Site Class */
require_once 'private/class-jetpack-private.php';

Jetpack_Private::init();
Loading

0 comments on commit 2316b87

Please sign in to comment.