Fixed reply Re: [Zope-dev] Trouble setting LoginManager default user class
Oops, my reply of yesterday was missing the actual error I get using manage_setStorage. It's an AttributeError for aq_acquire! I can't see how I could be getting this since PersistentUserSource singly inherits from BasicUserSource which inherits from Rack. What happened to my aq_acquire? Does it have to do with some mistake in the way I'm calling manage_addLoginManager? Phillip J. Eby writes:
At 10:01 PM 5/17/00 +0100, Steve Alexander wrote:
The _defaultClass only needs to become DemoPortal.LoginMember before a Portal's LoginManager instance is created.
Therefore, you can leave the _defaultClass as LoginUser until the "install" method of DemoPortalBase is called (PTKDemo/Portal.py).
In the "install" method, after creating a MembersClass(), set its _defaultClass to LoginMember.
It would be better to call manage_setStorage(zclass='meta type') rather than tinkering with attributes directly, as manage_setStorage should always be forward-compatible.
Ah yes, forgot about this problem -- it was yesterday... Here's my current code from DemoPortalBase.install: elif db == 'LoginManager': from Products.LoginManager.LoginManager import \ LoginManager, manage_addLoginManager from PersistentUserSource import PersistentUserSource self.MembersClass = LoginManager # maybe not needed anymore manage_addLoginManager(self, 'Persistent User Source', ['Basic Auth Login'], 0, 0, 0) #self.acl_users.manage_setStorage('DemoPortal/LoginMember') for us in self.acl_users.UserSourcesGroup.objectValues(): if us.meta_type == 'Persistent User Source': us.manage_setStorage('DemoPortal/LoginMember') The commented out line fails because it doesn't have a manage_setStorage. The uncommented out code causes the following traceback. It was after I hit this that I started hacking on _defaultClass... Probably I should have yelled for help then, but I have this bad habit of digging myself in as far a possible first :-) Traceback (innermost last): File /home/zope/lib/python/ZPublisher/Publish.py, line 214, in publish_module File /home/zope/lib/python/ZPublisher/Publish.py, line 179, in publish File /home/zope/lib/python/Zope/__init__.py, line 202, in zpublisher_exception_hook File /home/zope/lib/python/ZPublisher/Publish.py, line 165, in publish File /home/zope/lib/python/ZPublisher/mapply.py, line 160, in mapply (Object: Portal_add) File /home/zope/lib/python/ZPublisher/Publish.py, line 102, in call_object (Object: Portal_add) File /home/zope/lib/python/OFS/DTMLMethod.py, line 150, in __call__ (Object: Portal_add) File /home/zope/lib/python/DocumentTemplate/DT_String.py, line 502, in __call__ (Object: Portal_add) File /home/zope/lib/python/DocumentTemplate/DT_With.py, line 148, in render (Object: Portal.createInObjectManager(REQUEST['id'], REQUEST)) File /home/zope/lib/python/Products/PTKDemo/Portal.py, line 71, in install (Object: DemoPortalBase) File /home/dan/src/Zope-2.1.6-src/lib/python/Products/ZPatterns/Rack.py, line 348, in manage_setStorage (Object: AttributeProviderContainer) File /home/dan/src/Zope-2.1.6-src/lib/python/Products/ZPatterns/Rack.py, line 225, in _unifiedZClassRegistry (Object: AttributeProviderContainer) AttributeError: (see above)
At 01:49 PM 5/18/00 -0400, Dan L. Pierson wrote:
Oops, my reply of yesterday was missing the actual error I get using manage_setStorage. It's an AttributeError for aq_acquire! I can't see how I could be getting this since PersistentUserSource singly inherits from BasicUserSource which inherits from Rack. What happened to my aq_acquire? Does it have to do with some mistake in the way I'm calling manage_addLoginManager?
Um, no. You've found a bug in PlugInGroup.objectValues(). :( It doesn't wrap the returned objects in the context of the PlugInContainer (LoginManager in this case). As a workaround, you can say us.__of__(self.acl_users).manage_setStorage(). Sorry; I'm fixing this in the code right now.
Phillip J. Eby writes:
Um, no. You've found a bug in PlugInGroup.objectValues(). :( It doesn't wrap the returned objects in the context of the PlugInContainer (LoginManager in this case). As a workaround, you can say us.__of__(self.acl_users).manage_setStorage(). Sorry; I'm fixing this in the code right now.
Hurray! That got me to the next bug :-) The portal now gets created, but I can't login to the initial account. I also can't display the members roster by clicking on Members (AttributeError for getUsers), but can write a DTML method in the UserSource that lists all one user. The code in DemoPortalBase that trys to display the roster follows, I suspect it's this bug again, but don't know where to put the __of__: def getRoster(self, REQUEST): """ Return a list of the usernames of those users who have made themselves "listed". If Manager, return a list of all usernames. """ # Consider changing this to check for a permission rather than a role if REQUEST.AUTHENTICATED_USER.has_role('Manager'): return self.acl_users.getUserNames() names = [] for user in self.acl_users.getUsers(): if user.listed: names.append(user.getUserName()) return names Thanks for all the help, Dan Pierson
At 04:04 PM 5/18/00 -0400, Dan L. Pierson wrote:
The portal now gets created, but I can't login to the initial account. I also can't display the members roster by clicking on Members (AttributeError for getUsers), but can write a DTML method in the UserSource that lists all one user. The code in DemoPortalBase that trys to display the roster follows, I suspect it's this bug again, but don't know where to put the __of__:
Actually, the problem is probably that, as a DTML method, it expects to be passed its containing object as the first parameter. You might try using a PythonMethod, DTML Document, or an ExternalMethod instead.
Phillip J. Eby writes:
At 04:04 PM 5/18/00 -0400, Dan L. Pierson wrote:
The portal now gets created, but I can't login to the initial account. I also can't display the members roster by clicking on Members (AttributeError for getUsers), but can write a DTML method in the UserSource that lists all one user. The code in DemoPortalBase that trys to display the roster follows, I suspect it's this bug again, but don't know where to put the __of__:
Actually, the problem is probably that, as a DTML method, it expects to be passed its containing object as the first parameter. You might try using a PythonMethod, DTML Document, or an ExternalMethod instead.
I must not have been clear. The DTML method works. It's the Python code in the previous message that doesn't.
[reported to Collector; posted as FYI] Under certain circumstances, Zope transaction objects will have their abort() method called more than once for the same transaction, which leads to jar.abort() operations being called twice. This occurs any time that the zpublisher_exception_hook reraises the original exception, such as if the exception is an 'unauthorized' or 'redirect', or if a standard_error_message handler can't be found, or the transaction is being executed by XML-RPC or some other non-HTML protocol. Under "normal" circumstances (most other errors), the transaction's abort() method is *still* called twice, but with different arguments that lead to registered objects being aborted only once. This is a mess, because to write objects which can be registered with a transaction, one must consider the possibility of being aborted twice during the same transaction. It appears that the Zope exception hook uses get_transaction.begin() in order to do an abort. If it first did an abort(), this would at least make the double-abort behavior consistent. :) In practice, it seems as though it would be better to avoid double aborts by always having the abort method clear/reset self._objects. (The second abort takes place as a result of the __del__ method being called while there are still registered objects, following the free_transaction() called in the first execution of abort(). (Are you confused yet?) To add to the interestingness of this situation, there is a method which releases cached connection objects associated with the transaction, in collaboration with ZODB.DB.open(). This collaborating pair looks completely broken, as it assumes only a single DB exists, and also the method only ends up called by aborts, not commits. It does not appear as though anything in Zope uses this mechanism currently, but it should probably be fixed or removed before somebody hurts themselves with it. :)
participants (2)
-
Dan L. Pierson -
Phillip J. Eby