-
Notifications
You must be signed in to change notification settings - Fork 1
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
Support Multiple tokens #73
Support Multiple tokens #73
Conversation
Support Multiple Tokens - Tests
/** | ||
* @test | ||
*/ | ||
public function it_should_have_backwards_compatibility_with_single_and_multiple_tokens(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this backwards compatibility test check that this works with existing site tokens?
It seems like it's only checking that the token option can be updated with a single token vs multiple tokens.
We want to make sure that the Token_Manager
is able to retrieve the old tokens right?
i.e.
update_network_option( get_current_network_id(), 'custom_uplink_auth_token', 'single-token');
// Token_Manager::get() without slug.
$this->assertSame( 'single-token', $this->token_manager->get() );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, I'll either add in another test or alter the above to add in this logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is being covered by existing tests though. see for example test_it_stores_and_retrieves_a_token_from_the_network
in tests/wpunit/Auth/Token/CustomDomainMultisiteTokenMangerTest.php
and test_it_stores_and_retrieves_a_token
in tests/wpunit/Auth/Token/SingleSiteTokenMangerTest.php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added one more set of tests in this PR #75
…ckwards-compat-tests Additional Backwards Compatability Test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this!
I have an older PR Kadence is using right now where this might affect some things: #51
I wonder if this should be adjusted to pass around a Resource instance instead, that way we get access to everything on that resource without having to add additional parameters to methods.
e.g.
- My Connect Controller: https://github.com/stellarwp/uplink/pull/51/files#diff-2e3f301aebd5969dffb8de7ff6884dd1ea1d52547c53465beff122ccf2bad276R121
- To the Connector: https://github.com/stellarwp/uplink/pull/51/files#diff-b079829dc4be105a4544cf7ce80219d8d1e914ae770b5ac2c0e19ba67261f86eR27
Of course, this means the Token Manager should be taking in a nullable Resource instance where we can then use $resource->slug
if not null and still provided that backwards compatibility.
Let me know if you have any questions or want to discuss.
* @test | ||
*/ | ||
public function it_should_have_backwards_compatibility_with_single_and_multiple_tokens(): void { | ||
$collection = Config::get_container()->get( Collection::class ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is used anywhere in this test.
* | ||
* @return null|string|array | ||
*/ | ||
public function get_all() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trying to think about what to do about this. On one hand, we've already modified the existing Token_Manager Contract, but in a backwards compatible way.
So, rather than just adding this to the contract, I think we're going to need a new Multiple_Token_Manager
interface that extends the existing Token_Manager Contract and the container bindings updated and pass around that new interface instead so anyone asking for the original contract externally shouldn't be affected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @defunctl ! First of all thank you so much for your detailed review.
Have a question about this. The reason i didn't add this in the existing interface (or any other interface) in the first place, is that this method is acting in a way that serves both installations storing a single token or multiple tokens.
So it could return
null
when no option stored
string
when still in the schema of storing a single token only
array
when storing multiple tokens in the same option.
In the interface i cant declare mixed
as the return type since 7.X version of php don't support it.
I could still create an interface but without type hinting the return value. Let me know what do you think please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also i don't think we should update the binding in the container. Rather i would update Token_Manager to implement the new interface instead.
Since Token_Manager is a final class i am thinking there shouldn't be any dangers doing that.
* @return string | ||
*/ | ||
protected function validate_slug( string $slug = '' ): string { | ||
return $slug && Config::get_container()->get( Collection::class )->offsetExists( $slug ) ? $slug : ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should utilize dependency injection instead of a service locator anti-pattern, pass Collection
to the constructor of this class instead.
Update the container bindings to fetch the singleton instance.
return $slug && Config::get_container()->get( Collection::class )->offsetExists( $slug ) ? $slug : ''; | |
return $slug && $this->collection->offsetExists( $slug ) ? $slug : ''; |
/** | ||
* @before | ||
*/ | ||
protected function multiple_tokens_setup(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given my DI suggestion for the Token Manager, this entire method should be replaced with the following so we are using the correct container instance that all tests are using:
/**
* @var Collection
*/
private $collection;
protected function setUp(): void {
parent::setUp();
Config::set_token_auth_prefix( 'custom_' );
// Run init again to reload the Token/Provider.
Uplink::init();
$this->collection = $this->container->get( Collection::class );
$this->token_manager = $this->container->get( Token_Manager::class );
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The protected function multiple_tokens_setup(): void
method can be completely removed now.
* @return mixed | ||
*/ | ||
public function setup_container_get_slug( array $resource ) { | ||
$collection = Config::get_container()->get( Collection::class ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$collection = Config::get_container()->get( Collection::class ); |
@@ -48,7 +48,7 @@ public function test_it_stores_and_retrieves_a_token_from_the_network(): void { | |||
|
|||
$this->assertSame( $token, $this->token_manager->get() ); | |||
|
|||
$this->assertSame( $token, get_network_option( get_current_network_id(), $this->token_manager->option_name() ) ); | |||
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )['0'] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )['0'] ); | |
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )[0] ); |
@@ -48,7 +48,7 @@ public function test_it_stores_and_retrieves_a_token_from_the_network(): void { | |||
|
|||
$this->assertSame( $token, $this->token_manager->get() ); | |||
|
|||
$this->assertSame( $token, get_network_option( get_current_network_id(), $this->token_manager->option_name() ) ); | |||
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )['0'] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )['0'] ); | |
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )[0] ); |
@@ -48,7 +48,7 @@ public function test_it_stores_and_retrieves_a_token_from_the_network(): void { | |||
|
|||
$this->assertSame( $token, $this->token_manager->get() ); | |||
|
|||
$this->assertSame( $token, get_network_option( get_current_network_id(), $this->token_manager->option_name() ) ); | |||
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )['0'] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )['0'] ); | |
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $this->token_manager->option_name() ) )[0] ); |
tests/wpunit/Auth/AuthorizerTest.php
Outdated
@@ -73,7 +73,7 @@ public function test_it_does_not_authorize_a_subsite_with_an_existing_network_to | |||
// Store a token while on the main site. | |||
$this->assertTrue( $token_manager->store( '695be4b3-ad6e-4863-9287-3052f597b1f6' ) ); | |||
|
|||
$this->assertSame( $token, get_network_option( get_current_network_id(), $token_manager->option_name() ) ); | |||
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $token_manager->option_name() ) )['0'] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $token_manager->option_name() ) )['0'] ); | |
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $token_manager->option_name() ) )[0] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed this one.
$slug = $this->validate_slug( $slug ); | ||
|
||
if ( ! $slug ) { | ||
return delete_network_option( get_current_network_id(), $this->option_name ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this saying that if we don't have the slug in the resource collection, we delete all the data?
Wouldn't that delete other slug data as well or am I missing something?
Fix/multiple tokens issues
…iple-tokens/storage-strategy
…rategy Storage System to replace Transients
tests/wpunit/Auth/AuthorizerTest.php
Outdated
@@ -73,7 +73,7 @@ public function test_it_does_not_authorize_a_subsite_with_an_existing_network_to | |||
// Store a token while on the main site. | |||
$this->assertTrue( $token_manager->store( '695be4b3-ad6e-4863-9287-3052f597b1f6' ) ); | |||
|
|||
$this->assertSame( $token, get_network_option( get_current_network_id(), $token_manager->option_name() ) ); | |||
$this->assertSame( $token, array_values( get_network_option( get_current_network_id(), $token_manager->option_name() ) )['0'] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed this one.
/** | ||
* @before | ||
*/ | ||
protected function multiple_tokens_setup(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The protected function multiple_tokens_setup(): void
method can be completely removed now.
Co-authored-by: Justin <[email protected]>
Co-authored-by: Justin <[email protected]>
Co-authored-by: Justin <[email protected]>
Amend CR comments for field/form APIs
Modify library in order to be able to support multiple oAuth Tokens.
Current implementation would assume always ONE oAuth field per instance of the Uplink Library, which for the case of TEC for example can be problematic since every next auth would overwrite every previous.