[Zope-dev] ZPatterns, Transactions, _register/_unregister
Bob Pepin
bpe@iee.lu
Mon, 14 Aug 2000 11:13:50 +0200
--HcAYCG3uE/tztfnV
Content-Type: text/plain; charset=us-ascii
Hi,
I've encountered some weird behaviour in the ZPatterns Transactional class when
I was trying to write a User Source for the Login Manager Product.
I'm using Zope 2.2.0 with LoginManager 0.8.7a1 and ZPatterns 0.4.1snap1
The problem is that _unregister seems to be trying to delete the _v_registered
attribute of an object that doesn't have it set whenever I return None from
authenticateUser(). The weird thing is that the object seems to be
_register()ed and _v_registered appears to be set to 1 in _register(), but when
_unregister() is called it has the value 'None' again.
I've attached my code that's trying to implement the UserSource.
here is what my modified _register and _unregister functions look like:
def _register(self):
f=open('/tmp/zopelog', 'a', 0)
f.write('Register %s(%s)\n' % (self.id, str(self)))
f.write('Before: %s._v_registered=%s\n' % (self.id, getattr(self, '_v_registered', 'N/A')))
for i in traceback.format_stack():
f.write(i)
if self._v_registered: return
get_transaction().register(Reporter(self))
self._v_registered = 1
f.write('After: %s._v_registered=%s\n' % (self.id, getattr(self, '_v_registered', 'N/A')))
f.close()
def _unregister(self):
f=open('/tmp/zopelog', 'a', 0)
f.write('Unregister %s(%s)\nBefore: %s._v_registered=%s\n' \
% (self.id, str(self), self.id, getattr(self, '_v_registered', 'N/A')))
f.close()
del self._v_registered
and this is a sample log:
Register UserSource(<NisUserSource instance at 85ab2e8>)
Before: UserSource._v_registered=None
File "/home/picard/bpe/Zope-2.2.0-src/ZServer/PubCore/ZServerPublisher.py", line 95, in __init__
response=response)
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/ZPublisher/Publish.py", line 222, in publish_module
response = publish(request, module_name, after_list, debug=debug)
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/ZPublisher/Publish.py", line 162, in publish
object=request.traverse(path, validated_hook=validated_hook)
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/ZPublisher/BaseRequest.py", line 427, in traverse
else: user=v(request, auth, roles)
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/Products/LoginManager/LoginManager.py", line 110, in validate
user = _DefaultAuth.findLogin(self, request, auth, user, roles)
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/Products/LoginManager/LoginMethods.py", line 147, in findLogin
user = manager.getItem(name)
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/Products/LoginManager/LoginManager.py", line 65, in getItem
user = source.__of__(self).getItem(name)
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/Products/ZPatterns/Rack.py", line 61, in getItem
self._registerCanonical(k,item) # XXX Should we cache non-existence?
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/Products/ZPatterns/DataManagers.py", line 52, in _registerCanonical
self._register()
File "/home/picard/bpe/Zope-2.2.0-src/lib/python/Products/ZPatterns/Transactions.py", line 47, in _register
for i in traceback.format_stack():
After: UserSource._v_registered=1
Unregister UserSource(<NisUserSource instance at 85ab2e8>)
Before: UserSource._v_registered=None
--HcAYCG3uE/tztfnV
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="NisLogin.py"
from Products.ZPatterns.PlugIns import PlugIn
from Products.LoginManager.UserSources import BasicUserSource,LoginUser
from Products.LoginManager.LoginMethods import LoginMethod
from Products.LoginManager import LoginManager
import nis, string, crypt
from Products.ZPatterns.PlugIns import defaultConstructors
class NisUserSource(BasicUserSource, PlugIn):
__plugin_kind__ = "User Source"
meta_type = "NIS User Source"
f=open('/tmp/zopelog', 'a', 0)
i=0
def dbg(self, str):
self.f.write('[%03d] %s\n' % (self.i, str))
self.i = self.i + 1
def retrieveItem(self, name):
self.dbg('retrieveItem: %s' % name)
try: passwd=nis.match(name, 'passwd.byname')
except nis.error: return None
user=LoginUser(name)
user._setRack(self)
self.dbg('retrieveItem: %s ok.' % user.getUserName())
return user
def authenticateUser(self, user, password, REQUEST=None):
self.dbg('authenticateUser: %s %s' % (user, 'password'))
name=user.getUserName()
if name is None: return None
try: passwd=nis.match(name, 'passwd.byname')
except nis.error: return None
crypted=string.split(passwd, ':')[1]
test=crypt.crypt(password, crypted)
self.dbg('%s == %s: %d' % (crypted, test, crypted==test))
return crypted==test
def rolesForUser(self, user):
if user.getUserName() == 'bpe':
return ['Write Access']
else:
return ['Read Access']
def domainsForUser(self, user):
return []
def initialize(context):
context.registerPlugInClass(
NisUserSource,
permission = 'Add NIS User Source',
constructors = defaultConstructors(NisUserSource, globals()),
)
--HcAYCG3uE/tztfnV--