[Zope3-checkins] CVS: Zope3/src/zope/app/services/pluggableauth - __init__.py:1.1.2.3 configure.zcml:1.1.2.2
Chris McDonough
chrism@zope.com
Sun, 22 Jun 2003 21:08:53 -0400
Update of /cvs-repository/Zope3/src/zope/app/services/pluggableauth
In directory cvs.zope.org:/tmp/cvs-serv27350/src/zope/app/services/pluggableauth
Modified Files:
Tag: pluggable_authentication_service-branch
__init__.py configure.zcml
Log Message:
Provide an authentication view for pluggable auth service.
Write some tests for pluggable auth service.
=== Zope3/src/zope/app/services/pluggableauth/__init__.py 1.1.2.2 => 1.1.2.3 ===
--- Zope3/src/zope/app/services/pluggableauth/__init__.py:1.1.2.2 Sun Jun 22 12:09:58 2003
+++ Zope3/src/zope/app/services/pluggableauth/__init__.py Sun Jun 22 21:08:22 2003
@@ -24,7 +24,9 @@
from zodb.btrees.IOBTree import IOBTree
from zodb.btrees.OIBTree import OIBTree
from zope.interface import implements
+from zope.component import getAdapter, queryAdapter
from zope.app.services.servicenames import Authentication
+from zope.component.interfaces import IViewFactory
from zope.app.container.btree import BTreeContainer
from zope.app.container.ordered import OrderedContainer
from zope.app.interfaces.container import IContainer
@@ -42,6 +44,7 @@
from zope.app.zapi import queryView
from zope.app.traversing import getPath
from zope.context import ContextMethod
+from zope.exceptions import NotFoundError
def gen_key():
"""Return a random int (1, MAXINT), suitable for use as a BTree key."""
@@ -67,7 +70,6 @@
def authenticate(self, request):
""" See IAuthenticationService. """
-
for ps in self.values():
loginView = queryView(ps, "login", request)
if loginView is not None:
@@ -89,35 +91,34 @@
def unauthorized(self, id, request):
""" See IAuthenticationService. """
- if len(self) > 0:
- loginView = queryView(self[0], "login", request)
- if loginView is not None:
- return loginView.unauthorized()
-
+ print "in unauthorized", id
next = queryNextService(self, Authentication, None)
if next is not None:
- return next.unauthorized(request)
+ return next.unauthorized(id, request)
return None
unauthorized = ContextMethod(unauthorized)
def getPrincipal(self, id):
""" See IAuthenticationService. """
-
+
next = None
try:
- auth_svc_earmark, principal_src, principal_id = id
- except ValueError:
+ auth_svc_earmark, principal_src_id, principal_id = id
+ except TypeError:
next = queryNextService(self, Authentication, None)
if auth_svc_earmark != self.earmark:
next = queryNextService(self, Authentication, None)
+
if next is not None:
return next.getPrincipal(id)
- source = self[principal_src]
+ source = self.get(principal_src_id)
+ if source is None:
+ raise NotFoundError
return source.getPrincipal(principal_id)
getPrincipal = ContextMethod(getPrincipal)
@@ -148,9 +149,8 @@
if not IReadPrincipalSource.isImplementedBy(principal_source):
raise TypeError("Source must implement IReadPrincipalSource")
-
self.setObject(id, principal_source)
-
+
def removePrincipalSource(self, id):
""" See IPluggableAuthenticationService.
@@ -167,7 +167,7 @@
>>> pas.keys()
['simple', 'simpler']
"""
-
+
del self[id]
class BTreePrincipalSource(Persistent):
@@ -335,6 +335,8 @@
return self._principals_by_number[number]
+ getPrincipalByLogin = get
+
def values(self):
""" See IContainer.
@@ -416,6 +418,15 @@
self.title = title
self.description = description
+ def getId(self):
+ return self.id
+
+ def getLogin(self):
+ return self.login
+
+ def getTitle(self):
+ return self.title
+
def validate(self, test_password):
""" See IReadUser.
@@ -444,6 +455,7 @@
def addPath(self, path):
""" Update the history of places this Earmark has been.
+
>>> em = Earmark()
>>> em.addPath('/was/here')
>>> em.addPath('/am/now/here')
@@ -453,3 +465,39 @@
self.paths.append(path)
self.times.append(datetime.datetime.utcnow())
+
+ def __hash__(self):
+ # use the persistent object id as the hash as opposed to
+ # using the memory address as a hash.
+ return hash(self._p_oid)
+
+class PrincipalAuthenticationView:
+ implements(IViewFactory)
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def authenticate(self):
+ for interface in (ILoginPassword,):
+ a = queryAdapter(self.request, interface, None)
+ if a is None:
+ return
+ login = a.getLogin()
+ if login is None:
+ return
+
+ p = self.context.getPrincipalByLogin(login)
+ if p is None:
+ return
+ password = a.getPassword()
+
+ if p.validate(password):
+ # XXX we may in the future get back something from getPrincipal
+ # that is not a user; we likely won't be able to call
+ # 'validate' on this object.
+ return p
+
+ def unauthorized(self):
+ return 'Unauthorized'
+
=== Zope3/src/zope/app/services/pluggableauth/configure.zcml 1.1.2.1 => 1.1.2.2 ===
--- Zope3/src/zope/app/services/pluggableauth/configure.zcml:1.1.2.1 Tue Jun 3 09:34:06 2003
+++ Zope3/src/zope/app/services/pluggableauth/configure.zcml Sun Jun 22 21:08:22 2003
@@ -65,4 +65,11 @@
/>
</content>
+<browser:view
+ name="login"
+ for="zope.app.interfaces.services.pluggableauth.IPrincipalSource"
+ class="zope.app.services.pluggableauth.PrincipalAuthenticationView"
+ permission="zope.Public"
+/> <!-- XXX why do we need a permission? -->
+
</zopeConfigure>