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

feat(setup): Zope root cookie login form profile #66

Merged
merged 7 commits into from
Mar 8, 2022

Conversation

rpatterson
Copy link
Member

Add separate GenericSetup profile to switch the Zope root /acl_users to use a simple
cookie login form. Useful when Zope root login and logout need to synchronize
authentication state between multiple plugins, which is not possible with HTTP Basic ... authentication.

The use case for which I built this is Volto, specifically in the JWT token plugin from
plone.restapi
,
but I think I've generalized things correctly to be useful in other such situations.

Improve the Zope root ZMI login UX, avoid all the HTTP `Authorization: Basic ...` edge
cases and hassles. Switch the default authentication challenge for the Zope root
`/acl_users` from HTTP `Authorization: Basic ...` to the cookie auth plugins basic login
form.

This should be a much better UX overall and shouldn't cause any fundamental issues.  One
can still use HTTP `Authorization: Basic ...` manually by adding credentials to the URL:

    http://admin:secret@localhost:8080/manage_main

But may cause issues where tests expect the HTTP `Authorization: Basic ...` challenge
response or existing uses where new Zope instances are created as a part of normal
use (SAAS?).

We could also consider adding an upgrade step to make this change to existing
installations but that would be disruptive to any existing installations that require
HTTP `Authorization: Basic ...`.  I can't imagine why that would be, but we should
probably expect those use cases to come out of the woodwork once an upgrade step is
released.
These are linters that my editor uses by default because they are common linters, so
might as well fix what we can and ignore the rest.  As much as possible, I placed
ignores that should apply across the code base in the appropriate configuration file
rather than inline comments.
@rpatterson
Copy link
Member Author

Hmm, it doesn't look like any actions ran, including the prompt to run the Jenkins jobs. Might something have been broken in this repo since my last PR? I've re-reviewed the 4 commits here and don't see anything that could have affected that. CC: @jensens @thet

@rpatterson
Copy link
Member Author

@jenkins-plone-org please run jobs

@rpatterson
Copy link
Member Author

@jenkins-plone-org please run jobs

This didn't seem to work. I ran the same Jenkins jobs that were run for my last PR manually:

But they all failed with the same error that seems unrelated to any code changes:

...
[EnvInject] - Injecting environment variables from a build step.
[EnvInject] - [ERROR] - The given properties file path 'vars.properties' doesn't exist.
[EnvInject] - [ERROR] - Missing file path was resolved from pattern 'vars.properties' .
[EnvInject] - [ERROR] - Problems occurs on injecting env vars as a build step: java.io.IOException: The given properties file path 'vars.properties' doesn't exist.
Build step 'Inject environment variables' changed build result to FAILURE
Build step 'Inject environment variables' marked build as failure
Recording test results
ERROR: Step ‘Publish JUnit test result report’ failed: No test report files were found. Configuration error?
...

So I'm guessing that there's something broken in the Plone CI world ATM and that's why the checks have been disabled. LMK if I've got that wrong or there's anything I can do to get this reviewed.

@rpatterson
Copy link
Member Author

@jenkins-plone-org please run jobs

This didn't seem to work. I ran the same Jenkins jobs that were run for my last PR manually:

Is Jenkins broken, @ericof ?

@ericof
Copy link
Member

ericof commented Feb 15, 2022

@plone/ai-team, @fredvd: Do you know anything about it?

@mauritsvanrees
Copy link
Member

Yes, Jenkins is broken since this weekend. :-(
I created an issue yesterday: plone/jenkins.plone.org#292

@rpatterson
Copy link
Member Author

Yes, Jenkins is broken since this weekend. :-( I created an issue yesterday: plone/jenkins.plone.org#292

Thanks for reaching out with the update, @mauritsvanrees @ericof, I'm sure you're way too busy!

@fredvd
Copy link
Member

fredvd commented Feb 15, 2022

@rpatterson Jenkins is up and running again. The plugin configuration of jenkins somehow got borked after a Jenkins update this weekend. We're still looking into how that could happen, but all tests/jobs are active again.

@fredvd fredvd closed this Feb 15, 2022
@fredvd fredvd reopened this Feb 15, 2022
@mister-roboto
Copy link

@rpatterson thanks for creating this Pull Request and helping to improve Plone!

TL;DR: Finish pushing changes, pass all other checks, then paste a comment:

@jenkins-plone-org please run jobs

To ensure that these changes do not break other parts of Plone, the Plone test suite matrix needs to pass, but it takes 30-60 min. Other CI checks are usually much faster and the Plone Jenkins resources are limited, so when done pushing changes and all other checks pass either start all Jenkins PR jobs yourself, or simply add the comment above in this PR to start all the jobs automatically.

Happy hacking!

@fredvd
Copy link
Member

fredvd commented Feb 15, 2022

Sorry, shouldn't close the PR. :-$ Thought this was the other issue on jenkins.plone.org repo.

@fredvd
Copy link
Member

fredvd commented Feb 15, 2022

@jenkins-plone-org please run jobs

@rpatterson
Copy link
Member Author

Alright, @jensens, @thet or anyone else, I think this is ready fore review! LMK if you need anything more from me.

rpatterson added a commit to plone/volto that referenced this pull request Feb 16, 2022
Also run the `Products.PlonePAS` tests while [that PR is in
review](plone/Products.PlonePAS#66 (comment)) and
other auth work depends on it.
rpatterson added a commit to plone/volto that referenced this pull request Feb 16, 2022
Also run the `Products.PlonePAS` tests while [that PR is in
review](plone/Products.PlonePAS#66 (comment)) and
other auth work depends on it.
rpatterson added a commit to plone/volto that referenced this pull request Feb 16, 2022
Also run the `Products.PlonePAS` tests while [that PR is in
review](plone/Products.PlonePAS#66 (comment)) and
other auth work depends on it.
Copy link
Member

@jensens jensens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and well thought.

@rpatterson
Copy link
Member Author

Alright, all checks are passing, so I think this is ready for merge, @jensens or whoever.

@mauritsvanrees
Copy link
Member

I tried it out on an existing Plone 6 database where several Plone Sites exist already. I added a new Plone Site. Then go to portal_setup and install the Products.PlonePAS:root-cookie profile. Then as anonymous user go to http://localhost:8080/manage_main. This raises an Unauhtorized, which kicks in the challenge plugin. But this fails with a traceback:

2022-02-16 16:34:44,995 ERROR   [Zope.SiteErrorLog:252][waitress-2] 1645025684.9947740.3392464506199683 http://localhost:8080/acl_users/credentials_cookie_auth/login_form
Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 167, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 376, in publish_module
  Module ZPublisher.WSGIPublisher, line 255, in publish
  Module ZPublisher.BaseRequest, line 529, in traverse
  Module ZPublisher.HTTPResponse, line 976, in debugError
zExceptions.NotFound: Cannot locate object at: http://localhost:8080/acl_users/credentials_cookie_auth/login_form

So a login form is missing.

Move the change of the default Zope root configuration from HTTP Basic auth to the
cookie login form [into a separate GenericSetup upgrade step to make the change
optional](plone/plone.restapi#1304 (comment)).

This reverts commit 132c2c390801ff16393f214c1501252b240cb62a.
[A previous PR fixed the broken Zope root cookie plugin for new
installs](17deb97)
but didn't include an upgrade step for existing Zope instances/ZODBs.  The issue is only
revealed when `IChallengePlugin` is activated for the broken plugins, such as when the
`Products.PlonePAS:root-cookie` profile is installed, and [a `Manager` tries to login
to](#66 (comment)) the
[Zope root ZMI](http://localhost:8080/manage_main).

Add an upgrade step that fixes the issue for existing instances/ZODBs.
[Per
feedback](#66 (comment)), use
the new (to me) `post_handler` feature provided by `GenericSetup` as it is much better
than littering the import step registry with one-off, profile-specific import steps.
@rpatterson rpatterson force-pushed the feat-zope-root-cookie-challenge branch from beeb79d to 22ba99f Compare February 25, 2022 10:00
@rpatterson
Copy link
Member Author

@jenkins-plone-org please run jobs

@rpatterson
Copy link
Member Author

Hmm, I swear I had coverage for that, but yeah, I just checked an existing ZODB and I am able to reproduce this. Digging ino it and thanks for the catch, @mauritsvanrees!

I didn't have test coverage for this after all as this is an upgrade step issue. So I rigged up a semi-manual test bed for reproducing upgrade/migration issues, and used that to reproduce this issue and add a Products.PlonePAS:PlonePAS upgrade step. It's now working for me. Can you resume testing, @mauritsvanrees, and run that upgrade step before trying out the new Products.PlonePAS:root-cookie profile?

And with that I'm back to a place where I think we're ready to finish reviews and merge. LMK what else anyone needs from me!

rpatterson added a commit to plone/volto that referenced this pull request Feb 25, 2022
Also run the `Products.PlonePAS` tests while [that PR is in
review](plone/Products.PlonePAS#66 (comment)) and
other auth work depends on it.
@rpatterson
Copy link
Member Author

Is anyone able to finish reviewing this or help me draw attention to this to help finish review? CC: @avoinea, @thet, @jensens, @fredvd, @mauritsvanrees

Copy link
Member

@jensens jensens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. There is some code for Python 2.7 compat left, but that is probably inherited and not part of this PR. Anyway, it would be nice to have it cleaned up along the way. OTOH it should not be a blocker for a merge here.

src/Products/PlonePAS/plugins/ufactory.py Outdated Show resolved Hide resolved
src/Products/PlonePAS/sheet.py Outdated Show resolved Hide resolved
[Per
feedback](#66 (comment)),
back out the changes that are related to Python 2 compatibility since we no longer
support versions before Python 3.6.  I briefly evaluated actually removing the Python 2
compatibility for these lines, but I note that `six` is still in `install_requires` for
the package/dist dependency metadata so I think there's significant work to be done to
cleanup no longer needed compatibility code and I don't want to hold up this PR.
Copy link
Member

@mauritsvanrees mauritsvanrees left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it on a completely fresh database:

  • create a Plone Site
  • via portal_setup install the root-cookie profile
  • it works

Existing database:

  • go to a Plone site
  • run the PlonePAS upgrade
  • apply the root-cookie profile
  • it works

So this is merge-worthy.

The only thing I wonder is: why is there an upgrade step for the default profile? I would think it is the responsibility of the root-cookie profile to make it work both in a completely fresh database and in an existing database and existing site. The way you have it now works, but I don't completely see the logic.
Does my reservation make sense?
Minor point, since it works, but still.

@rpatterson
Copy link
Member Author

rpatterson commented Mar 8, 2022

So this is merge-worthy.

Woot! Thanks for double checking the existing ZODB cases.

The only thing I wonder is: why is there an upgrade step for the default profile? I would think it is the responsibility of the root-cookie profile to make it work both in a completely fresh database and in an existing database and existing site.

That particular upgrade step fixes broken Zope root /acl_users plugins created by the default profile, so I think it's more correct to have it registered to the profile that created the broken plugins. Make sense, @mauritsvanrees?

@rpatterson
Copy link
Member Author

@jenkins-plone-org please run jobs

@mauritsvanrees
Copy link
Member

That particular upgrade step fixes broken Zope root /acl_users plugins created by the default profile, so I think it's more correct to have it registered to the profile that created the broken plugins. Make sense, @mauritsvanrees?

Ah, I see. I missed that the setup was already fixed in a previous PR.

Fine to merge when green.

@rpatterson
Copy link
Member Author

Fine to merge when green.

K, everything is green. Should I merge? If not, who should? CC: @mauritsvanrees @jensens

@mauritsvanrees
Copy link
Member

I will merge.
Thanks a lot for your work!

@mauritsvanrees mauritsvanrees merged commit bd1bcf0 into master Mar 8, 2022
@mauritsvanrees mauritsvanrees deleted the feat-zope-root-cookie-challenge branch March 8, 2022 23:03
mister-roboto pushed a commit to plone/buildout.coredev that referenced this pull request Mar 8, 2022
Branch: refs/heads/master
Date: 2022-02-13T16:01:07-08:00
Author: Ross Patterson (rpatterson) <me@rpatterson.net>
Commit: plone/Products.PlonePAS@7e6d9d5

feat(setup): Zope root Basic -&gt; cookie login form

Improve the Zope root ZMI login UX, avoid all the HTTP `Authorization: Basic ...` edge
cases and hassles. Switch the default authentication challenge for the Zope root
`/acl_users` from HTTP `Authorization: Basic ...` to the cookie auth plugins basic login
form.

This should be a much better UX overall and shouldn't cause any fundamental issues.  One
can still use HTTP `Authorization: Basic ...` manually by adding credentials to the URL:

    http://admin:secret@localhost:8080/manage_main

But may cause issues where tests expect the HTTP `Authorization: Basic ...` challenge
response or existing uses where new Zope instances are created as a part of normal
use (SAAS?).

We could also consider adding an upgrade step to make this change to existing
installations but that would be disruptive to any existing installations that require
HTTP `Authorization: Basic ...`.  I can't imagine why that would be, but we should
probably expect those use cases to come out of the woodwork once an upgrade step is
released.

Files changed:
M src/Products/PlonePAS/setuphandlers.py
M src/Products/PlonePAS/tests/test_setup.py
Repository: Products.PlonePAS

Branch: refs/heads/master
Date: 2022-02-13T16:01:07-08:00
Author: Ross Patterson (rpatterson) <me@rpatterson.net>
Commit: plone/Products.PlonePAS@660343d

style(lint): Cleanup/ignore common linter errors

These are linters that my editor uses by default because they are common linters, so
might as well fix what we can and ignore the rest.  As much as possible, I placed
ignores that should apply across the code base in the appropriate configuration file
rather than inline comments.

Files changed:
A mypy.ini
M pyproject.toml
M setup.cfg
M src/Products/PlonePAS/interfaces/memberdata.py
M src/Products/PlonePAS/interfaces/membership.py
M src/Products/PlonePAS/patch.py
M src/Products/PlonePAS/plugins/ufactory.py
M src/Products/PlonePAS/sheet.py
M src/Products/PlonePAS/tests/test_setup.py
M src/Products/PlonePAS/tools/membership.py
Repository: Products.PlonePAS

Branch: refs/heads/master
Date: 2022-02-13T16:01:07-08:00
Author: Ross Patterson (rpatterson) <me@rpatterson.net>
Commit: plone/Products.PlonePAS@955a276

refactor(setup): More sensible import step define

Files changed:
M src/Products/PlonePAS/configure.zcml
M src/Products/PlonePAS/profiles.zcml
Repository: Products.PlonePAS

Branch: refs/heads/master
Date: 2022-02-25T01:24:34-08:00
Author: Ross Patterson (rpatterson) <me@rpatterson.net>
Commit: plone/Products.PlonePAS@13c1766

feat(setup): Zope root cookie login form profile

Move the change of the default Zope root configuration from HTTP Basic auth to the
cookie login form [into a separate GenericSetup upgrade step to make the change
optional](plone/plone.restapi#1304 (comment)).

This reverts commit 132c2c390801ff16393f214c1501252b240cb62a.

Files changed:
A news/zope-root-cookie.feature
A src/Products/PlonePAS/profiles/root-cookie/metadata.xml
A src/Products/PlonePAS/profiles/root-cookie/plone-pas-zope-root-cookie.txt
M src/Products/PlonePAS/profiles.zcml
M src/Products/PlonePAS/setuphandlers.py
M src/Products/PlonePAS/tests/test_setup.py
Repository: Products.PlonePAS

Branch: refs/heads/master
Date: 2022-02-25T01:24:34-08:00
Author: Ross Patterson (rpatterson) <me@rpatterson.net>
Commit: plone/Products.PlonePAS@1e9cd05

fix(setup): Existing broken Zope root cookie

[A previous PR fixed the broken Zope root cookie plugin for new
installs](plone/Products.PlonePAS@17deb97)
but didn't include an upgrade step for existing Zope instances/ZODBs.  The issue is only
revealed when `IChallengePlugin` is activated for the broken plugins, such as when the
`Products.PlonePAS:root-cookie` profile is installed, and [a `Manager` tries to login
to](plone/Products.PlonePAS#66 (comment)) the
[Zope root ZMI](http://localhost:8080/manage_main).

Add an upgrade step that fixes the issue for existing instances/ZODBs.

Files changed:
A src/Products/PlonePAS/upgrades.py
M src/Products/PlonePAS/profiles.zcml
M src/Products/PlonePAS/profiles/default/metadata.xml
Repository: Products.PlonePAS

Branch: refs/heads/master
Date: 2022-02-25T01:57:21-08:00
Author: Ross Patterson (rpatterson) <me@rpatterson.net>
Commit: plone/Products.PlonePAS@22ba99f

fix(setup): Use new pre/post profile handlers

[Per
feedback](plone/Products.PlonePAS#66 (comment)), use
the new (to me) `post_handler` feature provided by `GenericSetup` as it is much better
than littering the import step registry with one-off, profile-specific import steps.

Files changed:
M src/Products/PlonePAS/profiles.zcml
M src/Products/PlonePAS/setuphandlers.py
Repository: Products.PlonePAS

Branch: refs/heads/master
Date: 2022-03-08T12:53:01-08:00
Author: Ross Patterson (rpatterson) <me@rpatterson.net>
Commit: plone/Products.PlonePAS@9810cde

style(lint): Backout Python 2 compat lint cleanup

[Per
feedback](plone/Products.PlonePAS#66 (comment)),
back out the changes that are related to Python 2 compatibility since we no longer
support versions before Python 3.6.  I briefly evaluated actually removing the Python 2
compatibility for these lines, but I note that `six` is still in `install_requires` for
the package/dist dependency metadata so I think there's significant work to be done to
cleanup no longer needed compatibility code and I don't want to hold up this PR.

Files changed:
M src/Products/PlonePAS/plugins/ufactory.py
M src/Products/PlonePAS/sheet.py
Repository: Products.PlonePAS

Branch: refs/heads/master
Date: 2022-03-09T00:03:21+01:00
Author: Maurits van Rees (mauritsvanrees) <maurits@vanrees.org>
Commit: plone/Products.PlonePAS@bd1bcf0

Merge pull request #66 from plone/feat-zope-root-cookie-challenge

feat(setup): Zope root cookie login form profile

Files changed:
A mypy.ini
A news/zope-root-cookie.feature
A src/Products/PlonePAS/profiles/root-cookie/metadata.xml
A src/Products/PlonePAS/profiles/root-cookie/plone-pas-zope-root-cookie.txt
A src/Products/PlonePAS/upgrades.py
M pyproject.toml
M setup.cfg
M src/Products/PlonePAS/configure.zcml
M src/Products/PlonePAS/interfaces/memberdata.py
M src/Products/PlonePAS/interfaces/membership.py
M src/Products/PlonePAS/patch.py
M src/Products/PlonePAS/profiles.zcml
M src/Products/PlonePAS/profiles/default/metadata.xml
M src/Products/PlonePAS/setuphandlers.py
M src/Products/PlonePAS/sheet.py
M src/Products/PlonePAS/tests/test_setup.py
M src/Products/PlonePAS/tools/membership.py
@rpatterson
Copy link
Member Author

I will merge. Thanks a lot for your work!

Thanks for merging! May I ask what the process is for release, @mauritsvanrees. I have another PR in another repo that depends on this so I just want to know what to track so I can move that other PR forward once this is released.

@mauritsvanrees
Copy link
Member

The process is:

  • Once merged, Products.PlonePAS is automatically added to the coredev checkouts by mr.roboto in a fake commit.
  • When I am preparing a Plone release, I look in checkouts.cfg and make releases of those packages.

Or indeed you ask, if you need it sooner. :-)
I have released Products.PlonePAS 7.0.0a3.

@mauritsvanrees
Copy link
Member

Wait, I am making some mistakes here. Hold on.

@mauritsvanrees
Copy link
Member

Ah no, it is fine. I did get an error at first on install:

Getting distribution for 'Products.PlonePAS==7.0.0a3'.
ERROR: Directory '/Users/maurits/community/plone-coredev/6.0/src/Products.PlonePAS/src' is not installable. Neither 'setup.py' nor 'pyproject.toml' found.

Strange. But second time it works. It should not have been using the src checkout anymore anyway. But it works now.

@rpatterson
Copy link
Member Author

Or indeed you ask, if you need it sooner. :-) I have released Products.PlonePAS 7.0.0a3.

Hehe, awesome and thanks much!

Strange. But second time it works. It should not have been using the src checkout anymore anyway. But it works now.

Odd indeed. Did you have any inkling that this could be related to my changes?

@mauritsvanrees
Copy link
Member

Odd indeed. Did you have any inkling that this could be related to my changes?

No. For a moment I thought the creation of the release had somehow failed, and for another moment I thought I had forgotten to pull your changes before creating a release. But all was well after all.

rpatterson added a commit to plone/plone.restapi that referenced this pull request Mar 9, 2022
@avoinea
Copy link
Member

avoinea commented Mar 11, 2022

@mauritsvanrees @rpatterson Should we add the upgrade step also to plone.app.upgrade?

@mauritsvanrees
Copy link
Member

@mauritsvanrees @rpatterson Should we add the upgrade step also to plone.app.upgrade?

In the MigrationTool we have a list of add-ons. A different name may have been better: it is really a list of Plone core profiles, although technically a community add-on could register itself in this with some Python code. Anyway, at the end of running @@plone-upgrade, all profiles in this list get upgraded.

We should add the Products.PlonePAS profile to this list. In my opinion, all core packages that provide their own upgrade steps, should be in this list. That is what I intended it for. Obviously, the list is missing a few profiles now. I can have a look at updating it. It is on my list to have a look at anyway, for this issue: plone/Products.CMFPlone#3346.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants