-
Notifications
You must be signed in to change notification settings - Fork 153
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
Implement singleton pattern for OpenID_Connect_Generic class #190
Implement singleton pattern for OpenID_Connect_Generic class #190
Conversation
Hi @RobjS, I've thought about this PR a number of times and ultimately don't want to turn the main plugin class into a singleton. The point of the main plugin class is to hook the rest of the plugin into WP, and nothing more. If there are some methods on this class that a developer may want access to, then it makes more sense to move those methods to another class that is either a stateless service/utility thing, or if the method is closely related to the client or client wrapper, maybe move it there. Do you have a use-case that needs access to someone methods on the main plugin class? That would help think through what other changes might be needed. |
Hi @daggerhart, Thanks for responding and merging the other two PRs. Hopefully it'll be useful if I provide some context around the issue we're having and what I was hoping to achieve with this PR. We're seeing a small but sustained number of missing state errors. These have persisted even after applying the fix for the race condition (#171) and increasing the state time limit from a few minutes to several hours. I think one possible cause of these is people clicking the OpenID Login button after the provided state token has expired (even given our increased state time limit). One potential fix for this could be to start the countdown on the state token validity when the login button is clicked, rather than when the page containing the login button is served. Rather than open a PR making that (potentially quite substantial) change within the plugin, I was aiming to use the new However, that method would only be available by new-ing up the client wrapper and its dependencies (and their dependencies in turn), which feels unnecessarily clunky. Instead, I was hoping this change would allow me to do something like:
My hope was that the change in this PR was self-contained enough that it would enable this level of customisation, without having any impact on other plugin users. But if you have a preferred approach, I'm happy to amend the PR accordingly 👍 |
Hi @daggerhart, do you have any more thoughts on the above? |
@RobjS Yes! Thanks for asking. I don't mind making a singleton (or global variable) out of the plugin class for this version 3.x, but I wouldn't want people to use it directly. I'd rather that be paired with some simple functions for getting the specific thing people might want. For example:
This way, we aren't stuck with the singleton pattern forever just for the sake of backwards compatibility. I imagine that the 4.x version of this module would be significantly different in architecture, and I wouldn't want people to start relying on the actual singleton within their site. Same applies to the client_wrapper, and other classes. Atm, the client wrapper is doing Waaaay too much work and needs to be split up into different services. If people start relying directly on that class for its methods, then we're a little bit stuck with that going forward. What do you think? |
@daggerhart I would agree that it would be much better to provide global functions that we can have documented as the supported what of providing this functionality. This will allow us to adjust them, as needed, when/if the plugin structure changes. |
I thought about this more over the long weekend, and think we can move forward with this PR with a few changes.
|
19b13c3
to
932ded9
Compare
6c71ba4
to
864185c
Compare
Thanks @daggerhart, that all sounds good to me. I've made those changes to the PR. It's just the one function in |
@RobjS please ensure you are using the local development environment provided by the plugin to ensure that your PR meets coding standards and code quality requirements. Right now your PR has failed some of the code quality checks. When setting up the local plugin development environment things are setup to ensure that your code is checked on your local machine before you are even able to commit code changes. Thanks! |
This will allow developers who want to be able to call methods belonging to this class (or methods belonging to any of this class's properties) to do so, without having to create a new instance, and therefore repeat all the bootstrapping. Instead, they will just be able to call OpenID_Connect_Generic::instance() to retrieve the singleton.
These will act as wrappers for methods you would otherwise call by getting the Open_ID_Connect_Generic singleton and then calling the appropriate method.
864185c
to
91e1574
Compare
This allows us to access client_wrapper methods via the singleton of Open_ID_Connect_Generic.
Thanks @timnolte. Sorry about that, it looks like a lot of tests & CI have been added since I originally started on the PR 👍 Everything should be passing now. |
@RobjS since we don't currently have unit testing in place, I'm assuming that you've tested these changes fully on your own development environment and have confirmed the plugin is still working as expected? |
Why not simply to rename boostrap() to instance(), make constructor private and modify instance() like followed:
It is better to avoid publishing $instance variable. class should be accessible only with static instance() method |
it would be nice to add the next function:
we could read settings (for our plugins) but not change them. For example I need Register User Endpoint and in my case that would be:
|
@gassan the plugin uses standard WordPress core methods for settings, I don't see a need to expose our own method when you can just get this using core WordPress functionality. |
@timnolte Of course we can read settings from db. Nevertheless, I would like to ask @daggerhart to check whether the $settings can be public. |
@gassan you do realize that I'm also a maintainer of the plugin? My point is that what methods are made public need to be carefully considered and should only be done where there is not already a method for accomplishing this. That is also why the plugin already supports so many hooks and generally provides what is needed through those means, but in some cases there is a need that can't be accomplished without a code change. My stance is that there is no sense adding additional code to maintain, and develop tests for, that already have a working solution. From my standpoint the primary focus of changes right now need to be those that fix real issues that are preventing people from using the plugin, or requests that, if implemented, will enhance the security and the usability with existing IDPs. |
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.
@daggerhart I'm going to approve these changes.
@RobjS FYI, would you be able to get this branch updated with the latest changes in the |
Thanks @timnolte - done. |
@RobjS my apologies, I'm actually getting PRs merged in ready for a new release, I know it's been a long time coming. For some reason GitHub isn't allowing my to rebase your branch to bring it up-to-date. Would you be able to get your branch up-to-date with the latest in our |
@RobjS never mind on my last comment. I made some updates to the repository configuration and that appears to have resolved the issues I was seeing. |
This will allow developers who want to be able to call methods belonging to this class (or methods belonging to any of this class's properties) to do so, without having to create a new instance, and therefore repeat all the bootstrapping.
Instead, they will just be able to call OpenID_Connect_Generic::get() to retrieve the singleton.