Skip to content

Commit

Permalink
Move protect-status into it's own package (#37894)
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottprogrammer authored Jun 25, 2024
1 parent 1f1cc10 commit d95fd21
Show file tree
Hide file tree
Showing 23 changed files with 2,382 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions projects/packages/protect-status/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Files not needed to be distributed in the package.
.gitattributes export-ignore
.github/ export-ignore
package.json export-ignore

# Files to include in the mirror repo, but excluded via gitignore
# Remember to end all directories with `/**` to properly tag every file.
# /src/js/example.min.js production-include

# Files to exclude from the mirror repo, but included in the monorepo.
# Remember to end all directories with `/**` to properly tag every file.
.gitignore production-exclude
changelog/** production-exclude
phpunit.xml.dist production-exclude
.phpcs.dir.xml production-exclude
tests/** production-exclude
.phpcsignore production-exclude
3 changes: 3 additions & 0 deletions projects/packages/protect-status/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
vendor/
node_modules/
wordpress/
33 changes: 33 additions & 0 deletions projects/packages/protect-status/.phan/baseline.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* This is an automatically generated baseline for Phan issues.
* When Phan is invoked with --load-baseline=path/to/baseline.php,
* The pre-existing issues listed in this file won't be emitted.
*
* This file can be updated by invoking Phan with --save-baseline=path/to/baseline.php
* (can be combined with --load-baseline)
*/
return [
// # Issue statistics:
// PhanPluginDuplicateConditionalNullCoalescing : 45+ occurrences
// PhanParamTooMany : 6 occurrences
// PhanTypeMismatchArgument : 5 occurrences
// PhanTypeMismatchProperty : 2 occurrences
// PhanTypeMismatchReturnProbablyReal : 2 occurrences
// PhanNoopNew : 1 occurrence
// PhanPluginSimplifyExpressionBool : 1 occurrence
// PhanRedundantCondition : 1 occurrence

// Currently, file_suppressions and directory_suppressions are the only supported suppressions
'file_suppressions' => [
'src/class-plan.php' => ['PhanTypeMismatchReturnProbablyReal'],
'src/class-protect-status.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
'src/class-rest-controller.php' => ['PhanParamTooMany'],
'src/class-scan-status.php' => ['PhanParamTooMany', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanRedundantCondition', 'PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'],
'src/class-status.php' => ['PhanPluginSimplifyExpressionBool', 'PhanTypeMismatchArgument'],
'tests/php/test-scan-status.php' => ['PhanTypeMismatchArgument'],
'tests/php/test-status.php' => ['PhanTypeMismatchArgument'],
],
// 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed.
// (directory_suppressions will currently be ignored by subsequent calls to --save-baseline, but may be preserved in future Phan releases)
];
13 changes: 13 additions & 0 deletions projects/packages/protect-status/.phan/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
/**
* This configuration will be read and overlaid on top of the
* default configuration. Command-line arguments will be applied
* after this file is read.
*
* @package automattic/jetpack-protect-status
*/

// Require base config.
require __DIR__ . '/../../../../.phan/config.base.php';

return make_phan_config( dirname( __DIR__ ) );
24 changes: 24 additions & 0 deletions projects/packages/protect-status/.phpcs.dir.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<ruleset>

<rule ref="WordPress.WP.I18n">
<properties>
<property name="text_domain" type="array">
<element value="jetpack-protect-status" />
</property>
</properties>
</rule>
<rule ref="Jetpack.Functions.I18n">
<properties>
<property name="text_domain" value="jetpack-protect-status" />
</properties>
</rule>

<rule ref="WordPress.Utils.I18nTextDomainFixer">
<properties>
<property name="old_text_domain" type="array" />
<property name="new_text_domain" value="jetpack-protect-status" />
</properties>
</rule>

</ruleset>
7 changes: 7 additions & 0 deletions projects/packages/protect-status/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

36 changes: 36 additions & 0 deletions projects/packages/protect-status/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# protect-status

This package contains the Protect Status API functionality to retrieve a site's scan status (WordPress, Themes, and Plugins threats).

## Get Started
Build and install the package:

```sh
jetpack build packages/protect-status && jetpack install packages/protect-status
```

From the plugin folder, require the package using composer:

```sh
composer require automattic/jetpack-protect-status
```

Then use it: (Example)

```php
use Automattic\Jetpack\Protect_Status\Status;

$protect_status = Status::get_status();

## Using this package in your WordPress plugin

If you plan on using this package in your WordPress plugin, we would recommend that you use [Jetpack Autoloader](https://packagist.org/packages/automattic/jetpack-autoloader) as your autoloader. This will allow for maximum interoperability with other plugins that use this package as well.

## Security

Need to report a security vulnerability? Go to [https://automattic.com/security/](https://automattic.com/security/) or directly to our security bug bounty site [https://hackerone.com/automattic](https://hackerone.com/automattic).

## License

protect-status is licensed under [GNU General Public License v2 (or later)](./LICENSE.txt)

Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Updated package dependencies.
4 changes: 4 additions & 0 deletions projects/packages/protect-status/changelog/initial-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Initial version.
69 changes: 69 additions & 0 deletions projects/packages/protect-status/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"name": "automattic/jetpack-protect-status",
"description": "This package contains the Protect Status API functionality to retrieve a site's scan status (WordPress, Themes, and Plugins threats).",
"type": "jetpack-library",
"license": "GPL-2.0-or-later",
"require": {
"php": ">=7.0",
"automattic/jetpack-connection": "@dev",
"automattic/jetpack-plugins-installer": "@dev",
"automattic/jetpack-sync": "@dev",
"automattic/jetpack-protect-models": "@dev",
"automattic/jetpack-plans": "@dev"
},
"require-dev": {
"yoast/phpunit-polyfills": "1.1.0",
"automattic/jetpack-changelogger": "@dev",
"automattic/wordbless": "dev-master"
},
"autoload": {
"classmap": [
"src/"
]
},
"scripts": {
"build-development": "echo 'Add your build step to composer.json, please!'",
"build-production": "echo 'Add your build step to composer.json, please!'",
"phpunit": [
"./vendor/phpunit/phpunit/phpunit --colors=always"
],
"post-install-cmd": "WorDBless\\Composer\\InstallDropin::copy",
"post-update-cmd": "WorDBless\\Composer\\InstallDropin::copy",
"test-php": [
"@composer phpunit"
]
},
"repositories": [
{
"type": "path",
"url": "../../packages/*",
"options": {
"monorepo": true
}
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"allow-plugins": {
"roots/wordpress-core-installer": true
}
},
"extra": {
"autotagger": true,
"branch-alias": {
"dev-trunk": "0.1.x-dev"
},
"changelogger": {
"link-template": "https://github.com/Automattic/jetpack-protect-status/compare/v${old}...v${new}"
},
"mirror-repo": "Automattic/jetpack-protect-status",
"textdomain": "jetpack-protect-status",
"version-constants": {
"::PACKAGE_VERSION": "src/class-status.php"
}
},
"suggest": {
"automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package."
}
}
25 changes: 25 additions & 0 deletions projects/packages/protect-status/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"private": true,
"name": "@automattic/jetpack-protect-status",
"version": "0.1.0-alpha",
"description": "This package contains the Protect Status API functionality to retrieve a site's scan status (WordPress, Themes, and Plugins threats).",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/packages/protect-status/#readme",
"bugs": {
"url": "https://github.com/Automattic/jetpack/labels/[Package] Protect Status"
},
"repository": {
"type": "git",
"url": "https://github.com/Automattic/jetpack.git",
"directory": "projects/packages/protect-status"
},
"license": "GPL-2.0-or-later",
"author": "Automattic",
"scripts": {
"build": "echo 'Not implemented.'",
"build-js": "echo 'Not implemented.'",
"build-production": "echo 'Not implemented.'",
"build-production-js": "echo 'Not implemented.'",
"clean": "true"
},
"devDependencies": {}
}
14 changes: 14 additions & 0 deletions projects/packages/protect-status/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<phpunit bootstrap="tests/php/bootstrap.php" backupGlobals="false" colors="true" convertDeprecationsToExceptions="true">
<testsuites>
<testsuite name="main">
<directory prefix="test" suffix=".php">tests/php</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="false">
<!-- Better to only include "src" than to add "." and then exclude "tests", "vendor", and so on, as PHPUnit still scans the excluded directories. -->
<!-- Add additional lines for any files or directories outside of src/ that need coverage. -->
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
111 changes: 111 additions & 0 deletions projects/packages/protect-status/src/class-plan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php
/**
* Class to handle the Protect plan
*
* @package automattic/jetpack-protect-status
*/

namespace Automattic\Jetpack\Protect_Status;

use Automattic\Jetpack\Current_Plan;

/**
* The Plan class.
*/
class Plan {
/**
* The meta name used to store the cache date
*
* @var string
*/
const CACHE_DATE_META_NAME = 'protect-cache-date';

/**
* Valid pediord for the cache: One week.
*/
const CACHE_VALIDITY_PERIOD = 7 * DAY_IN_SECONDS;

/**
* The meta name used to store the cache
*
* @var string
*/
const CACHE_META_NAME = 'protect-cache';

/**
* Checks if the cache is old, meaning we need to fetch new data from WPCOM
*/
private static function is_cache_old() {
if ( empty( self::get_product_from_cache() ) ) {
return true;
}

$cache_date = get_user_meta( get_current_user_id(), self::CACHE_DATE_META_NAME, true );
return time() - (int) $cache_date > ( self::CACHE_VALIDITY_PERIOD );
}

/**
* Gets the product list from the user cache
*/
private static function get_product_from_cache() {
return get_user_meta( get_current_user_id(), self::CACHE_META_NAME, true );
}

/**
* Gets the product data
*
* @param string $wpcom_product The product slug.
* @return array
*/
public static function get_product( $wpcom_product = 'jetpack_scan' ) {
if ( ! self::is_cache_old() ) {
return self::get_product_from_cache();
}

$request_url = 'https://public-api.wordpress.com/rest/v1.1/products?locale=' . get_user_locale() . '&type=jetpack';
$wpcom_request = wp_remote_get( esc_url_raw( $request_url ) );
$response_code = wp_remote_retrieve_response_code( $wpcom_request );

if ( 200 === $response_code ) {
$products = json_decode( wp_remote_retrieve_body( $wpcom_request ) );

// Pick the desired product...
$product = $products->{$wpcom_product};

// ... and store it into the cache.
update_user_meta( get_current_user_id(), self::CACHE_DATE_META_NAME, time() );
update_user_meta( get_current_user_id(), self::CACHE_META_NAME, $product );

return $product;
}

return new \WP_Error(
'failed_to_fetch_data',
esc_html__( 'Unable to fetch the requested data.', 'jetpack-protect-status' ),
array(
'status' => $response_code,
'request' => $wpcom_request,
)
);
}

/**
* Has Required Plan
*
* @param bool $force_refresh Refresh the local plan cache from wpcom.
* @return bool True when the site has a plan or product that supports the paid Protect tier.
*/
public static function has_required_plan( $force_refresh = false ) {
static $has_scan = null;
if ( null === $has_scan || $force_refresh ) {
$products = array_column( Current_Plan::get_products(), 'product_slug' );

// Check for a plan or product that enables scan.
$plan_supports_scan = Current_Plan::supports( 'scan', true );
$has_scan_product = count( array_intersect( array( 'jetpack_scan', 'jetpack_scan_monthly' ), $products ) ) > 0;
$has_scan = $plan_supports_scan || $has_scan_product;
}

return $has_scan;
}
}
Loading

0 comments on commit d95fd21

Please sign in to comment.