Overview
HTTP requests from our CLI tool need to be authenticated at our API endpoints.
→ See: #3525571: [Meta] CLI tool for code components
Proposed resolution
Create a new submodule for authenticating HTTP requests at our API endpoints using OAuth2. Rely on Simple OAuth 6.0.x as a dependency.
Authentication provider
Implement our own authentication provider service by extending \Drupal\simple_oauth\Authentication\Provider\SimpleOauthAuthenticationProvider, or if we could simply rely on SimpleOauthAuthenticationProvider.
Scopes
Use the simple_oauth_static_scope module (also see simple_oauth_static_scope_example), and define the following OAuth scopes:
xb:javascript-components:read
xb:javascript-components:write
xb:asset-library:read
xb:asset-library:write
Enable them for the client credentials grant type, and associate with the administer code components permission.
Documentation
Write simple documentation for setting up an OAuth2 consumer (/admin/config/services/consumer) to work with our authenticated endpoints.
Issue fork experience_builder-3525572
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
balintbrewsComment #3
balintbrewsComment #6
balintbrewsComment #7
larowlanMy experience working with setting up oauth for Entity Share was not pleasant. I've written exhaustive docs for dealing with all the various error codes you can get. Despite setting it up multiple times for several sites in a distributed network of sites sharing content I still need to consult the docs and error codes every time. So I'd be pretty keen to see if we could implement another process here? If we have a cli here can't we prompt for a username and password, hit the
user.login.httproute and get a cookie then just use that to make further requests to the API? This would avoid us having to add another dependency.Comment #8
balintbrewsI completely get the appeal of avoiding the complexity, but we will need to provide OAuth2 to follow industry standards, and to account for the use case when someone wants to manage components on multiple sites.
Comment #9
balintbrewsI still would like to add tests that make actual HTTP requests.
Besides that, we need to overcome some challenges with permissions. I naïvely thought when I created the issue that administer code components will cover everything we need. That's close, but not quite the full picture. Here is an overview from the perspective of API endpoints:
js_componentxb_asset_libraryINDEXadminister themes_user_is_logged_in(route requirement)GETadminister code componentsPOSTPATCHDELETEadminister code componentsaccess administration pages_user_is_logged_inroute requirement for theexperience_builder.api.config.listroute. That will break things in an OAuth-context. Maybe there is a way to remove it dynamically for those requests, but I wonder if we could handle that requirement differently.administer themespermission for theINDEXoperation which not only is not the most intuitive choice, but it also returns all the data that can otherwise be accessed individually with aGETrequest, but for those theadminister code componentspermission is needed.access administration pagespermission also may not be intuitive either.The key to potentially rethinking our permissions is that when using them in OAuth2 scopes, we need to have 1:1 relationships. A scope can't be associated with multiple permissions. We can have umbrella scopes holding other scopes, though.
I would love to simplify this and make it nicer for the scopes we provide in config. Any thoughts on how much we could easily update our permissions?
Comment #10
penyaskitoIs this a limitation of the dependencies we are using? I don't think it's a technical limitation by oauth2 itself.
Comment #11
balintbrews#10: It is the limitation/decision of the Simple OAuth module, yes, but it doesn't change the fact that the permissions could use some love. We can always use umbrella scopes, so my ask is not necessarily to express everything with a single permission.
Let's focus on how we could:
administer themesandaccess administration pages— it doesn't feel right to map these to OAuth scopes in the context of those API operations;_user_is_logged_inroute requirement, and perhaps use a permission instead.While the first one is more about semantics, the second one is potentially a hard blocker for this issue.
Comment #13
balintbrewsThanks to @mglaman, I now understand that I was having problems with the
_user_is_logged_inaccess checker because of how my OAuth2 consumer was configured while testing. The client credentials grant type allows configuring a user to be used "as the author of all actions made".\Drupal\simple_oauth\Authentication\TokenAuthUserdecorates the user account defined here, so when the_user_is_logged_inaccess checker callsisAuthenticated, it was checking that user. So this is expected, and won't be a blocker for this implementation, I just need to make sure (and document) that the anonymous user is not configured.The
administer themespermission will be handled in #3518836: experience_builder.api.config.list route should not require 'administer themes' permission, and the access administration pages might also be going away based on some discussions.So I'm good to proceed with the current permissions. I may rethink the scopes a bit.
Comment #14
balintbrewsComment #15
wim leersThis is a beautifully precise, well-tested MR! Kudos 🤩👏
I think @larowlan left a bunch of remarks worth addressing (especially the one regarding route definitions), and I think that this removing a single
_permission: …from the "config delete" route (which technically should happen/have already happened in #3452581: [META] XB Permissions) would significantly simplify this MR — and would prevent this having to change again in the near future.Comment #16
balintbrewsComment #18
wim leersWhat a marvelous suggestion by @effulgentsia! 🤩
Comment #20
balintbrewsComment #21
wim leersSee #3529207-10: For selective reverting add DELETE auto-save endpoint — we forgot to update
CONTRIBUTING.mdhere 🙈 My bad! Will fix there.Comment #22
neha_bawankar commented