Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: multisite token logic #51

Draft
wants to merge 117 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
639f785
Fix HTTP mocks not working after base url was renamed.
defunctl Dec 1, 2023
98a4bfb
Clean up test
defunctl Dec 1, 2023
550dc15
Add ability to mock a plugin is activated
defunctl Dec 1, 2023
c59a64c
WIP: refactor token auth for multisite using plugin
defunctl Dec 1, 2023
ce82145
Include slug in token disconnect logic
defunctl Dec 1, 2023
3346f9c
Refactor Authorized
defunctl Dec 2, 2023
a65371d
WIP: conditional token storage
defunctl Dec 4, 2023
d14edea
WIP: multisite logic refactor
defunctl Dec 6, 2023
46f3eb4
Add get_license_key function
defunctl Dec 6, 2023
521a8a0
Reset multisite config to original state after each test
defunctl Dec 6, 2023
0270487
Refactor get_domain() to take into consideration unique subsites when…
defunctl Dec 6, 2023
1e2f595
Remove token check, replace with main site check
defunctl Dec 6, 2023
4438ee2
Add Config::allows_network_licenses() and update Multisite_Main_Site.php
defunctl Dec 6, 2023
16ef300
Add a hash suffix to the main site URL when on multisite with network…
defunctl Dec 6, 2023
8d27445
Delete old pipeline steps
defunctl Dec 6, 2023
a9b95be
Add more helper functions
defunctl Dec 6, 2023
86325a0
Rename get_domain function
defunctl Dec 6, 2023
5a267e8
Move disconnect URL into its own method, add helper function
defunctl Dec 6, 2023
f1fad44
Allow getting the original domain name
defunctl Dec 6, 2023
92f883c
Get original domain for download args
defunctl Dec 6, 2023
a12acd1
Remove get_token, update get_authorization_token
defunctl Dec 6, 2023
7840ed2
Delete unneeded Authorized class
defunctl Dec 6, 2023
bb1b85d
Fix license manager caching
defunctl Dec 7, 2023
d558d26
Clean up functions, add is_user_authorized()
defunctl Dec 7, 2023
77e0e48
Add and adjust functions, first pass at multisite licensing documenta…
defunctl Dec 7, 2023
8e233f1
Rollback is_authorized() change, add a new function instead
defunctl Dec 7, 2023
5a5aee0
Fix warning
defunctl Dec 7, 2023
0f7e720
Refactor allows_multisite_license() to accept an already made resource
defunctl Dec 7, 2023
7dc8c71
Fix comment
defunctl Dec 7, 2023
2cef62a
Add set_license_key example
defunctl Dec 7, 2023
f334ac1
Fix set_license_key function
defunctl Dec 7, 2023
f4b9d9a
Remove stray ampersand
defunctl Dec 7, 2023
075bbe0
formatting
defunctl Dec 7, 2023
ba8721b
Attempt to allow network validation
defunctl Dec 7, 2023
eb95d51
Show the correct message based on network validation
defunctl Dec 7, 2023
158dff9
submit to network settings if on the network_admin
defunctl Dec 7, 2023
d6cbf16
Add is_license_valid() function
defunctl Dec 7, 2023
a0a528e
rename to validate_license, return entire response
defunctl Dec 7, 2023
aafab54
Don't return null on empty license, validate allows a null key
defunctl Dec 8, 2023
d204a79
Remove unused container property, add types
defunctl Dec 8, 2023
fe207d0
Add nullable type
defunctl Dec 8, 2023
a2e9b87
Use dependency injection for Ajax
defunctl Dec 8, 2023
019e264
ensure we are multisite aware when fetching the license key for the s…
defunctl Dec 8, 2023
b028d36
Fix bad return type
defunctl Dec 8, 2023
200afd4
Show default licensing messages if coming from the network admin
defunctl Dec 8, 2023
10abc3a
Store key status in network if required
defunctl Dec 8, 2023
c5d2d58
Update the license key valid cache after updating key locally
defunctl Dec 8, 2023
1b34a0a
Ensure key is network at network/local level when validating
defunctl Dec 8, 2023
9a161d7
Don't register settings during ajax requests
defunctl Dec 8, 2023
3ee1c73
Ensure to validate license key before storing when callback connecting
defunctl Dec 8, 2023
835c01e
Ensure key being checked is network aware during license validation
defunctl Dec 8, 2023
ae65a26
set_license_key() will properly update the validation state of the li…
defunctl Dec 8, 2023
e07e4b0
Merge branch 'feature/authorization-caching' into bugfix/multisite-to…
defunctl Jan 4, 2024
6093e45
Update base testcase to fix merge issue and use config::reset()
defunctl Jan 4, 2024
32a67b1
Merge branch 'fix/ESM-70-fatal-error-on-ticket-transfer' into bugfix/…
defunctl Jan 4, 2024
95006d7
Merge branch 'main' into bugfix/multisite-token-logic
defunctl Jan 4, 2024
deeda32
Merge branch 'feat/enable-auto-updates' into bugfix/multisite-token-l…
kadencewp Jan 8, 2024
6e17901
Use unique actions for each resource slug for token connect/disconnect
defunctl Jan 9, 2024
282fca3
Remove prefix from token connect/disconnect actions, we don't have th…
defunctl Jan 9, 2024
062fa1f
Bugfix: Ensure download_url property is not null before attempting to…
defunctl Jan 9, 2024
373f6a5
Add action to disconnect controller
defunctl Jan 9, 2024
4d8d99c
Properly fix Undefined property: stdClass::$download_url
defunctl Jan 9, 2024
6bd55c1
Merge branch 'bugfix/multisite-token-logic' into bugfix/token-connect…
defunctl Jan 9, 2024
93426a9
Refactor to use uplink_slug and no longer use WordPress's action quer…
defunctl Jan 9, 2024
20616d7
Formatting
defunctl Jan 9, 2024
3f2a0e6
Use a constant for the auth action
defunctl Jan 9, 2024
f77ede3
Add ActionManagerTest.php
defunctl Jan 9, 2024
fb9c439
Move assertion into single loop
defunctl Jan 9, 2024
da935ee
Use standard action format with prefix
defunctl Jan 9, 2024
3e5df6b
Update connect/disconnect hook name
defunctl Jan 9, 2024
00e750a
Fix action docblocks
defunctl Jan 9, 2024
15a41bc
call correct action in tests
defunctl Jan 9, 2024
a1fd036
Formatting
defunctl Jan 9, 2024
b70ad24
Fix spelling
defunctl Jan 9, 2024
95f44c9
Formatting
defunctl Jan 9, 2024
fd7a2c0
Merge pull request #59 from stellarwp/bugfix/token-connect-disconnect…
defunctl Jan 9, 2024
4557d04
Merge remote-tracking branch 'origin/bugfix/prevent-empty-class' into…
defunctl Jan 17, 2024
bf9880a
Merge remote-tracking branch 'origin/feat/allow-disabling-updates' in…
defunctl Jan 17, 2024
cf87f7c
Make authorized checks require a plugin slug
defunctl Jan 22, 2024
24445ff
Fix missing variable, update README.md
defunctl Jan 22, 2024
f24a385
Don't use slug for transient cache key
defunctl Jan 23, 2024
a6ceefa
Only use the token to make the cache key
defunctl Jan 23, 2024
bfebca6
Refactor token disconnect logic to also delete the authorization cache
defunctl Jan 23, 2024
138a834
Properly build a cache hash with just a token, don't use prefix in qu…
defunctl Jan 23, 2024
1c7e27d
Merge pull request #64 from stellarwp/feature/ms/authorized-check-to-…
defunctl Jan 23, 2024
f367e86
Merge branch 'main' into bugfix/multisite-token-logic
defunctl Feb 29, 2024
66d9b5e
Show WP info
defunctl Feb 29, 2024
c5f5461
use the correct env var to call slic
defunctl Feb 29, 2024
ec95ca3
Fix tests failing due to Unexpected incorrect usage notice for wp_add…
defunctl Feb 29, 2024
6a1ecc4
Bump actions/checkout versions, fix composer cache dir
defunctl Feb 29, 2024
213a1d7
Manually bring in updated tests matrix
defunctl Feb 29, 2024
d3374a8
Fix type error in filter_upgrader_pre_download
defunctl Mar 1, 2024
19dcdfa
Merge branch 'main' into bugfix/KAD-2308/updater-type-error
defunctl Mar 1, 2024
e84dc60
Merge branch 'bugfix/KAD-2308/updater-type-error' into bugfix/multisi…
defunctl Mar 1, 2024
1f8c277
Fix typo
defunctl Mar 1, 2024
6aa9ebe
Merge branch 'bugfix/KAD-2308/updater-type-error' into bugfix/multisi…
defunctl Mar 1, 2024
0d69fe0
Force type for delete_transient kadence zendesk ticket 610295
defunctl Jun 24, 2024
775b54f
Force set_transient type for good measure
defunctl Jun 24, 2024
d8b9855
Allow some HTML tags in notices, show error if nonce failed and lites…
defunctl Jun 24, 2024
d37e2bb
Fix allowed tags
defunctl Jun 24, 2024
81e6cb1
add filter
kadencewp Dec 2, 2024
0b471da
fix test
kadencewp Dec 2, 2024
370bd50
updates with more escaping and not showing a button unless it's TEC o…
kadencewp Dec 3, 2024
0e03db7
test update
kadencewp Dec 3, 2024
5c6e94d
Use require_once as a statement
defunctl Dec 3, 2024
64eda1e
Remove deprecated config, ignore require_once errors
defunctl Dec 3, 2024
8458885
Bump action versions
defunctl Dec 3, 2024
ac42ee4
Merge pull request #90 from stellarwp/chore/phpstan-updates
defunctl Dec 3, 2024
b7553a7
Merge branch 'bugfix/multisite-token-logic' into bugfix/missing-filter
defunctl Dec 3, 2024
0f8f4b8
Fix array
kadencewp Dec 3, 2024
007ca4b
Add test
kadencewp Dec 3, 2024
6983bea
fix string
kadencewp Dec 3, 2024
bb787f2
target..
kadencewp Dec 3, 2024
301a5d4
Merge pull request #89 from stellarwp/bugfix/missing-filter
kadencewp Dec 4, 2024
d134ede
Account for an empty siteurl in the database
kadencewp Dec 11, 2024
82d3e19
apply change
kadencewp Dec 11, 2024
f33e2d3
Merge pull request #93 from stellarwp/bugfix/empty-domain
kadencewp Dec 12, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Configure PHP environment
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
extensions: mbstring, intl
coverage: none
- uses: ramsey/composer-install@v2
- uses: ramsey/composer-install@v3
with:
composer-options: "--ignore-platform-reqs --optimize-autoloader"
- name: Run PHPStan static analysis
Expand Down
55 changes: 29 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ add_action( 'plugins_loaded', function() {
}, 0 );
```

> 💡 See [multisite license documentation](./docs/features.md#multisite-licenses) to enable
> network licensing features.

## Translation

Package is using `__( 'Invalid request: nonce field is expired. Please try again.', '%TEXTDOMAIN%' )` function for translation. In order to change domain placeholder `'%TEXTDOMAIN%'` to your plugin translation domain run
Expand Down Expand Up @@ -92,11 +95,12 @@ src/Uplink/Helper.php
The file should match the following - keeping the `KEY` constant set to a blank string, or, if you want a default license key, set it to that.:

```php
<?php
<?php declare( strict_types=1 );

namespace Whatever\Namespace\Uplink;

class Helper {
const KEY = '';
final class Helper {
public const KEY = '';
}
```

Expand Down Expand Up @@ -155,7 +159,7 @@ In order to render license key form just add the following to your settings page
```php
use StellarWP\Uplink\Config;

$fields = Config::get_container()->get( License_Field::class );
$fields = \StellarWP\Uplink\get_license_field();

// Do one of the following:
$fields->render(); // Render the fields, titles, and submit button.
Expand All @@ -168,7 +172,7 @@ To render a single product's license key, use the following:
```php
use StellarWP\Uplink\Config;

$fields = Config::get_container()->get( License_Field::class );
$fields = \StellarWP\Uplink\get_license_field();

// Do one of the following:
$fields->render_single( 'my-plugin' ); // Render the fields, titles, and submit button.
Expand Down Expand Up @@ -200,7 +204,7 @@ use StellarWP\Uplink\Config;
function render_settings_page() {
// ...

$fields = Config::get_container()->get( License_Field::class );
$fields = \StellarWP\Uplink\get_license_field();
$fields->render(); // or $fields->render_single( 'my-plugin' ); to render a single plugin

//....
Expand Down Expand Up @@ -239,14 +243,14 @@ functionality:

```php
// Call the namespaced function with your plugin slug.
\StellarWP\Uplink\render_authorize_button( 'kadence-blocks-pro' );
\StellarWP\Uplink\render_authorize_button( 'my-plugin-slug' );
```

You can also pass in a custom license domain, which can be fetched on the Uplink Origin side from the `uplink_domain` query variable:

```php
// Call the namespaced function with your plugin slug and license domain.
\StellarWP\Uplink\render_authorize_button( 'kadence-blocks-pro', 'customer-site.com' );
\StellarWP\Uplink\render_authorize_button( 'my-plugin-slug', \StellarWP\Uplink\get_license_domain() );
```

> 💡 The button is very customizable with filters, see [Authorize_Button_Controller.php](src/Uplink/Components/Admin/Authorize_Button_Controller.php).
Expand All @@ -256,15 +260,23 @@ You can also pass in a custom license domain, which can be fetched on the Uplink
This connects to the licensing server to check in real time if the license is authorized. Use sparingly.

```php
$container = \StellarWP\Uplink\Config::get_container();
$token_manager = $container->get( \StellarWP\Uplink\Auth\Token\Contracts\Token_Manager::class );
$token = $token_manager->get();
$is_authorized = \StellarWP\Uplink\is_authorized_by_resource( 'my-plugin-slug' );

echo $is_authorized ? esc_html__( 'authorized' ) : esc_html__( 'not authorized' );
```

Or, if you have more complex licensing needs, you can provide specific data:

```php
$token = \StellarWP\Uplink\get_authorization_token( 'my-plugin-slug' );
$license_key = \StellarWP\Uplink\get_license_key( 'my-plugin-slug' );
$domain = \StellarWP\Uplink\get_license_domain();

if ( ! $token ) {
return;
if ( ! $token || ! $license_key || ! $domain ) {
return; // or, log/show errors.
}

$is_authorized = \StellarWP\Uplink\is_authorized( 'customer_license_key', $token, 'customer_domain' );
$is_authorized = \StellarWP\Uplink\is_authorized( $license_key, 'my-plugin-slug', $token, $domain );

echo $is_authorized ? esc_html__( 'authorized' ) : esc_html__( 'not authorized' );
```
Expand All @@ -274,18 +286,11 @@ echo $is_authorized ? esc_html__( 'authorized' ) : esc_html__( 'not authorized'
If for some reason you need to fetch your `auth_url` manually, you can do so by:

```php
$container = \StellarWP\Uplink\Config::get_container();
$auth_url_manager = $container->get( \StellarWP\Uplink\API\V3\Auth\Contracts\Auth_Url::class );

// Pass your product or service slug.
$auth_url = $auth_url_manager->get( 'kadence-blocks-pro' );

echo $auth_url;
echo esc_url( \StellarWP\Uplink\get_auth_url( 'my-plugin-slug' ) );
```

> 💡 Auth URL connections are cached for one day using transients.


### Callback Redirect

The Callback Redirect generated by the Origin looks something like this, where `uplinksample.lndo.site` is your
Expand All @@ -304,7 +309,5 @@ The following Query Variables are available for reference:

1. `uplink_token` - The unique UUIDv4 token generated by StellarWP Licensing.
2. `_uplink_nonce` - The original nonce sent with the callback URL, as part of the "Connect" button.
3. `uplink_license` (optional) - Whether we should also update or set a License Key.
4. `uplink_slug` (optional) - The Product or Service Slug that we're updating the license for.

> ⚠️ `uplink_slug` MUST be supplied if `uplink_license` is!
3. `uplink_slug` The Product or Service Slug that we're updating the license for.
4. `uplink_license` (optional) - Whether we should also update or set a License Key.
109 changes: 103 additions & 6 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ The goals of this library are to provide a simple way to register one or more pl

Registration of plugins and services should happen programmatically and the intended API is documented in this repository's [README](/README.md).


### License keys & validation

The Uplink library should communicate with the Stellar Licensing system at specific moments. Those moments are:
Expand Down Expand Up @@ -80,15 +79,113 @@ Uplink should provide a UI for entering license keys. Ideally, Uplink should hav
When a license field is rendered, manipulated, or saved, a validation request should be triggered (see the diagram above).


##### Site & Network-level

When a plugin that includes the Uplink library is activated at the network level, License keys should be able to be entered at both the network and the site level.


### Product updates

The Uplink library should mark a registered plugin as needing an update when a validation response comes back from the Stellar Licensing system with a version number greater than the version number that is currently installed. You can see a reference implementation in [`tribe-common`](https://github.com/the-events-calendar/tribe-common/blob/master/src/Tribe/PUE/Checker.php#L1537).

#### Plugin page

On the _Plugins_ page in the WP Dashboard, any plugin that has an update available should display the update similar to how WordPress core does it. If a user click on `Update`, the zip files should be fetched from the Stellar Licensing system and installed if their license key is valid.

### Multisite Licenses

Out of the box, Uplink treats all sub-sites as their _own independent site_, storing license keys and authorization tokens
in the options table of that sub-site.

If your product supports multisite level licenses, you can configure Uplink to allow one license key/auth token for the entire
multisite network across multiple situations.

> 💡 To operate at the network level, your plugin **must be network activated** and the proper configuration options enabled.

| Install Type | Network Activated? | Clause | Uplink Config Option (default is false) | License & Token Storage Location |
|----------------------------|--------------------|--------|-----------------------------------------------------|----------------------------------|
| Standard | – | – | – | Site level |
| Multisite (subfolders) | Yes | AND | `Config::set_network_subfolder_license(true)` | Network level |
| Multisite (subfolders) | No | OR | `Config::set_network_subfolder_license(false)` | Site Level |
| Multisite (subdomains) | Yes | AND | `Config::set_network_subdomain_license(true)` | Network level |
| Multisite (subdomains) | No | OR | `Config::set_network_subdomain_license(false)` | Site Level |
| Multisite (domain mapping) | Yes | AND | `Config::set_network_domain_mapping_license(true)` | Network level |
| Multisite (domain mapping) | No | OR | `Config::set_network_domain_mapping_license(false)` | Site Level |


#### Examples

After [library initialization](../README.md#initialize-the-library), the above config options can be set, e.g.

```php
use StellarWP\Uplink\Uplink;

// ...other config above

// Allow a single network license for multisite subfolders.
Config::set_network_subfolder_license( true );

// Allow a single network license for multisite using subdomains.
Config::set_network_subdomain_license( true );

// Allow a single network license for custom domains/mapped domains.
Config::set_network_domain_mapping_license( true );

Uplink::init();
```

> 🚨 Consider moving your plugin UI and the Uplink License Field settings to the WordPress network UI to prevent
> sub-sites being able to control licensing and token authorization for the entire multisite network if you enable
> any of the multisite config options.

Each config option can also be filtered at runtime, assuming your plugin's slug is registered as `my-plugin-slug`:

```php
add_action( 'init', static function(): void {
// Replace with a call to your own plugin's config/option to check whether it should be managed in the network.
$network_enabled = true;

add_filter( 'stellarwp/uplink/my-plugin-slug/allows_network_subfolder_license',
static function () use ( $network_enabled ): bool {
return $network_enabled;
}, 10 );

add_filter( 'stellarwp/uplink/my-plugin-slug/allows_network_subdomain_license',
static function () use ( $network_enabled ): bool {
return $network_enabled;
}, 10 );

add_filter( 'stellarwp/uplink/my-plugin-slug/allows_network_domain_mapping_license',
static function () use ( $network_enabled ): bool {
return $network_enabled;
}, 10 );
} );
```

#### Functions

Uplink provides some handy functions that include automated support for fetching or storing data from
the correct location.

```php
// Checks if the current WordPress user is authorized to make license/token changes (is_super_admin() out of the box).
\StellarWP\Uplink\is_user_authorized();

// Get a stored license key, will fetch from the current site's options or network, depending on your config.
\StellarWP\Uplink\get_license_key( 'my-plugin-slug' );

// Store a license key, will store in the current site's options or network, depending on your config.
\StellarWP\Uplink\set_license_key( 'my-plugin-slug', 'new_license_key' );

// Get the domain associated with a license.
// Note that if any of the multisite options are enabled, the root multisite domain contains a unique suffix
// so that it doesn't override the license key/token for the entire multisite network if it's converted back
// to single site.
// Depending on your configuration, this may the multisite domain with suffix, e.g. example.com/2626gsg
// or, it could be the sub-site domain with path, e.g. example.com/sub1, example.com/sub2 etc...
\StellarWP\Uplink\get_license_domain();

// This will get the license domain without any added suffixes.
\StellarWP\Uplink\get_original_domain();

// Gets the local URL to disconnect a token (delete it locally).
\StellarWP\Uplink\get_disconnect_url( 'my-plugin-slug' );

// Checks if the current site (e.g. the sub-site on multisite) would support multisite licensing.
\StellarWP\Uplink\allows_multisite_license( 'my-plugin-slug' );
```
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ parameters:
level: 5
inferPrivatePropertyTypeFromConstructor: true
reportUnmatchedIgnoredErrors: false
checkGenericClassInNonGenericObjectType: false

# Paths to be analyzed.
paths:
Expand All @@ -26,3 +25,4 @@ parameters:
- '#^Function add_query_arg invoked with [123] parameters?, 0 required\.$#'
# Uses func_get_args()
- '#^Function apply_filters(_ref_array)? invoked with [34567] parameters, 2 required\.$#'
- '#Path in require_once\(\).+is not a file or it does not exist#'
12 changes: 7 additions & 5 deletions src/Uplink/API/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,16 @@ protected function request( $method, $endpoint, $args ) {
*
* @since 1.0.0
*
* @param Resource $resource Resource to validate.
* @param string|null $key License key.
* @param string $validation_type Validation type (local or network).
* @param bool $force Force the validation.
* @param Resource $resource Resource to validate.
* @param string|null $key License key.
* @param string $validation_type Validation type (local or network).
* @param bool $force Force the validation.
*
* @throws \RuntimeException
*
* @return mixed
*/
public function validate_license( Resource $resource, string $key = null, string $validation_type = 'local', bool $force = false ) {
public function validate_license( Resource $resource, ?string $key = null, string $validation_type = 'local', bool $force = false ) {
/** @var Data */
$site_data = $this->container->get( Data::class );
$args = $resource->get_validation_args();
Expand Down
3 changes: 2 additions & 1 deletion src/Uplink/API/V3/Auth/Contracts/Token_Authorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ interface Token_Authorizer {
* @see \StellarWP\Uplink\API\V3\Auth\Token_Authorizer
*
* @param string $license The license key.
* @param string $slug The plugin/service slug.
* @param string $token The stored token.
* @param string $domain The user's domain.
*
* @return bool
*/
public function is_authorized( string $license, string $token, string $domain ): bool;
public function is_authorized( string $license, string $slug, string $token, string $domain ): bool;

}
12 changes: 7 additions & 5 deletions src/Uplink/API/V3/Auth/Token_Authorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@ public function __construct( Client_V3 $client ) {
/**
* Manually check if a license is authorized.
*
* @see is_authorized()
*
* @param string $license The license key.
* @param string $token The stored token.
* @param string $domain The user's domain.
* @param string $slug The plugin/service slug.
* @param string $token The stored token.
* @param string $domain The user's domain.
*
* @return bool
*
* @see is_authorized()
*/
public function is_authorized( string $license, string $token, string $domain ): bool {
public function is_authorized( string $license, string $slug, string $token, string $domain ): bool {
$response = $this->client->get( 'tokens/auth', [
'license' => $license,
'slug' => $slug,
'token' => $token,
'domain' => $domain,
] );
Expand Down
24 changes: 18 additions & 6 deletions src/Uplink/API/V3/Auth/Token_Authorizer_Cache_Decorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,21 @@ public function __construct(
* @see Token_Authorizer
*
* @param string $license The license key.
* @param string $slug The plugin/service slug.
* @param string $token The stored token.
* @param string $domain The user's domain.
*
* @return bool
*/
public function is_authorized( string $license, string $token, string $domain ): bool {
$transient = $this->build_transient( [ $license, $token, $domain ] );
public function is_authorized( string $license, string $slug, string $token, string $domain ): bool {
$transient = $this->build_transient( [ $token ] );
$is_authorized = get_transient( $transient );

if ( $is_authorized === true ) {
return true;
}

$is_authorized = $this->authorizer->is_authorized( $license, $token, $domain );
$is_authorized = $this->authorizer->is_authorized( $license, $slug, $token, $domain );

// Only cache successful responses.
if ( $is_authorized ) {
Expand All @@ -75,12 +76,23 @@ public function is_authorized( string $license, string $token, string $domain ):
/**
* Build a transient key.
*
* @param array<int, string> ...$args
* @param array<int, string> $args
*
* @return string
*/
public function build_transient( array ...$args ): string {
return self::TRANSIENT_PREFIX . hash( 'sha256', json_encode( $args ) );
public function build_transient( array $args ): string {
return self::TRANSIENT_PREFIX . $this->build_transient_no_prefix( $args );
}

/**
* Build a transient key without the prefix.
*
* @param array $args
*
* @return string
*/
public function build_transient_no_prefix( array $args ): string {
return hash( 'sha256', json_encode( $args ) );
}

}
Loading
Loading