Basic User Folder vs PAS - using getUserNames()

In old Zope 2.10.6:

Our application was using a Basic User Folder for acl_users.
There were technical reasons we had to upgrade acl_users to a PAS.

Our application has a syncUsers script which is used to update acl_users whenever our application updates its users, which are stored separately in SQL.

The syncUsers python script calls getUserNames() on the container.acl_users object.
Since upgrading acl_users from Basic to PAS, the call to getUserNames does not return any users. It also does not log any exceptions in the instance error_log.

I have a "User Manager" plugin with the Authentication, User_Enumeration, User_Adder plugins all activated. I don't understand why getUserNames is failing.

Hi Christoph, did you try to put a debugger into the the getUserNames() function to see what actually happens?

Christopher Biessener via Plone Community wrote at 2022-6-21 20:48 +0000:

Our application was using a Basic User Folder for acl_users.
There were technical reasons we had to upgrade acl_users to a PAS.
...
The syncUsers python script calls getUserNames() on the container.acl_users object.
Since upgrading acl_users from Basic to PAS, the call to getUserNames does not return any users. It also does not log any exceptions in the instance error_log.

A PAS does not have a getUserNames method; I suppose that
in your case the method is acquired (and therefore gives
results you do not expect).

You could try searchUsers as a replacement for getUserNames.

1 Like

The documentation could be more clear...

interface Products.PluggableAuthService.interfaces.authservice.IUserFolder:

N.B: ā€œenumerationā€ methods (ā€˜getUserNamesā€™, ā€˜getUsersā€™) are not
part of the contract! See IEnumerableUserFolder.

OK, so you need a User Enumerator, right? That's what I understand from the above documentation.
Nowhere does it say that PAS cannot use the enumeration methods. This is so frustrating! A Basic User Folder is just a neutered PAS, if the object hierarchy is to be believed.
The designers of PAS should be ashamed of themselves for this gross inconsistency.

Anyway, thanks for the reply.

Hopefully my code to detect Basic vs PAS works so I can call getUserNames or searchUsers depending on type of folder.

topic/15372/52486.7fb5a12a4706fdbdbdfe8c33@community.plone.org
X-Mailer: VM 8.0.12-devo-585 under 21.4 (patch 24) "Standard C" XEmacs Lucid (x86_64-linux-gnu)
FCC: ~/Mail/Sent-22-06
--text follows this line--
Christopher Biessener via Plone Community wrote at 2022-6-22 13:49 +0000:

The documentation could be more clear...
interface Products.PluggableAuthService.interfaces.authservice.IUserFolder:

N.B: ā€œenumerationā€ methods (ā€˜getUserNamesā€™, ā€˜getUsersā€™) are not
part of the contract! See IEnumerableUserFolder.

It clearly says "getUserNames does not belong to IUserFolder".
If you look at the code, you see that PluggableAuthService
implements IUserFolder.

Nowhere does it say that PAS cannot use the enumeration methods.

The PAS method that uses the enumeration methods is
searchUsers (and not getUserNames).

OK, so I looked in the source code. The only mention of IMutableUserFolder is in PluggableAuthService/interfaces/authservice.py.
In there, there is a comment:

# The IMutableUserFolder and IEnumerableUserFolder are not supported
# out-of-the-box by the pluggable authentication service. These
# interfaces describe contracts that other standard Zope user folders
# implement.

OK... So we can get/validate/search/update users in a PAS, but I see no User Folder API outside of IMutableUserFolder that can add or delete users in a PAS. (a PAS plugin can Add, but again, there is no delete)

How do I Add/Delete users to/from a PAS from a user script?

I fail to see the logic in splitting the PAS implementation with such a hard line between BasicUserFolder and PAS. Why on Earth should a PAS not be able to capitalize on the same methods a BasicUserFolder does?

Christopher Biessener via Plone Community wrote at 2022-6-23 14:33 +0000:

...
I fail to see the logic in splitting the PAS implementation with such a hard line between BasicUserFolder and PAS. Why on Earth should a PAS not be able to capitalize on the same methods a BasicUserFolder does?

PAS has a method to add users: _doAddUser.
I agree with you, that it should use the same method name as
BasicUserFolder.
But in your case (you likely have a single plugin that
manages users), it is likely best to use the user management
plugin directly (and not go through the integrating "PAS").

PAS targets (among others) the use case "very large user base".
For this use case, some methods (such as getUserNames) will
have very bad timing characteristics. I suppose that this has been
an important reason to replace such methods which variants
that allow in principle to restrict the result (such as
searchUsers for getUserNames).

Plone Foundation Code of Conduct