Skip to content

Commit

Permalink
- Feature: added support for local IUnauthenticatedPrincipal. This is…
Browse files Browse the repository at this point in the history
… usefull

  if you need to apply local roles to IUnauthenticatedPrincipal. This was not 
  possible before and is not possible in zope.app.authentication

- Feature: implemented initial grant view based on ISource widget. Note, this
  source widget terms implementation which is very complex to understand will
  get moved to z3c.from if we fixed the ITerm dependency. Which means ITerm 
  needs to get moved out of zope.app.form first.

- Feature: added support for next utility lookup in authenticate call. By 
  default the principals from the global principalregistry get involved now. 
  You can disable this feature by setting includeNextUtilityForAuthenticate to
  False.

- Feature: added PrincipalRegistryAuthenticatorPlugin which allows to  
  authenticate principals defined in global principal registry.
  • Loading branch information
projekt01 committed Nov 24, 2008
1 parent bc9e7a6 commit 297fcfc
Show file tree
Hide file tree
Showing 18 changed files with 504 additions and 203 deletions.
35 changes: 33 additions & 2 deletions CHANGES.txt
Expand Up @@ -3,14 +3,45 @@ CHANGES
=======


Version 0.5.2dev (unreleased)
Version 0.6.0dev (unreleased)
-----------------------------

- feature: implemented z3c.form prefix support in SessionCredentialsPlugin. Now
- Feature: added support for local IUnauthenticatedPrincipal. This is usefull
if you need to apply local roles to IUnauthenticatedPrincipal. This was not
possible before and is not possible in zope.app.authentication

- Feature: implemented initial grant view based on ISource widget. Note, this
source widget terms implementation which is very complex to understand will
get moved to z3c.from if we fixed the ITerm dependency. Which means ITerm
needs to get moved out of zope.app.form first.

- Feature: added support for next utility lookup in authenticate call. By
default the principals from the global principalregistry get involved now.
You can disable this feature by setting includeNextUtilityForAuthenticate to
False.

- Feature: added PrincipalRegistryAuthenticatorPlugin which allows to
authenticate principals defined in global principal registry.

- Feature: implemented z3c.form prefix support in SessionCredentialsPlugin. Now
there is an option called prefixes which can be used for define a list of
used z3c.form prefixes. This makes it simpler for supporting different forms
and adjust the credential extraction.

- Renamed IGroupPrincipal to IFoundGroup which makes it more understandable
why this adapter implementation is needed. The IFoundGroup adapter is now
also used for zope.security.interfaces.IGroup principals. This makes it
possible to use them in the new principalregistry credential. Provide
deprecation message for the old IGroupPrincipal implementation.

- Removed dependency for zapi. But it's not really gone since other packages
use zapi too.

- Removed unused InvalidPrincipalIds and InvalidGroupId exceptions

- Removed unused IMemberAwareGroup support. This interface is not used in zope
at all.


Version 0.5.1 (2008-04-16)
--------------------------
Expand Down
7 changes: 3 additions & 4 deletions setup.py
Expand Up @@ -23,7 +23,7 @@ def read(*rnames):

setup (
name='z3c.authenticator',
version='0.5.2dev',
version='0.6.0dev',
author = "Roger Ineichen and the Zope Community",
author_email = "zope3-dev@zope.org",
description = "IAuthentication implementation for for Zope3",
Expand Down Expand Up @@ -56,7 +56,6 @@ def read(*rnames):
'zope.publisher',
'zope.session',
'zope.testing',
'zope.testbrowser',
],
),
install_requires = [
Expand All @@ -66,11 +65,12 @@ def read(*rnames):
'z3c.formui',
'z3c.i18n',
'z3c.template',
'z3c.contents',
'zope.app.component',
'zope.app.container',
'zope.app.generations',
'zope.app.security',
'zope.component',
'zope.deprecation',
'zope.dublincore',
'zope.event',
'zope.i18n',
Expand All @@ -82,7 +82,6 @@ def read(*rnames):
'zope.security',
'zope.session',
'zope.traversing',

],
zip_safe = False,
)
31 changes: 31 additions & 0 deletions src/z3c/authenticator/README.txt
Expand Up @@ -81,6 +81,37 @@ data, especially groups, to the principal. Typically, if a subscriber adds
data, it should also add corresponding interface declarations.


FAQ
---

Here some usefull hints.

How should I set permission for principals -- You can apply a roles to groups
and apply permissions to roles. Or you can directly apply local permisssions
to groups or to principals. After setup this mappings you can grant roles to
groups. I always recommend a principal - group and permission - role mapping,
then this gives you the most possible abstraction which is usefullif it comes
to manage permission and principals without to invoke directly principals and
permissions itself. but of corse you can grant permissions to groups or the
worst thing directly to principals. Grant permission to principals is only
useful if it comes to selective local permission settings for selected
principals e.g. a ownership like permission setup.

How can I set permission for all principals -- You can register one
group as IEveryone utility. This IGroup utility get applied to all principals.

Can I apply local groups to unauthenticated principals -- Yes this will work.
Since the last refactoring I refactored the IGroup implementation which makes
it compatible with the principalregistry API. This means you can now register
one local group as a unnamed IUnauthenticatedGroup. You can also register one
local group as an unnamed IAuthenticatedGroup utility which will get applied
to every authenticated principal or a unnamed utility for
IUnauthenticatedGroup.

Can I apply a local group to every principal -- Yes, this is possible if
register a local unnamed utility providing IEveryoneGroup.


Principal
---------

Expand Down
65 changes: 64 additions & 1 deletion src/z3c/authenticator/authentication.py
Expand Up @@ -19,12 +19,15 @@
import zope.interface
import zope.component
import zope.event
from zope.schema.fieldproperty import FieldProperty
from zope.schema.interfaces import ISourceQueriables
from zope.location.interfaces import ILocation

from zope.app.component import queryNextUtility
from zope.app.container import btree
from zope.app.security.interfaces import IAuthentication
from zope.app.security.interfaces import PrincipalLookupError
from zope.app.security.interfaces import IUnauthenticatedPrincipal

from z3c.authenticator import interfaces
from z3c.authenticator import event
Expand All @@ -39,6 +42,9 @@ class Authenticator(btree.BTreeContainer):
authenticatorPlugins = ()
credentialsPlugins = ()

includeNextUtilityForAuthenticate = FieldProperty(
interfaces.IAuthenticator['includeNextUtilityForAuthenticate'])

def _plugins(self, names, interface):
for name in names:
plugin = self.get(name)
Expand All @@ -63,6 +69,7 @@ def authenticate(self, request):
if credentials is None:
# do not invoke the auth plugin without credentials
continue

for authplugin in authenticatorPlugins:
if authplugin is None:
continue
Expand All @@ -78,6 +85,13 @@ def authenticate(self, request):
self, authenticated, request))
return authenticated

if self.includeNextUtilityForAuthenticate:
next = queryNextUtility(self, IAuthentication, None)
if next is not None:
principal = next.authenticate(request)
if principal is not None:
return principal

return None

def getPrincipal(self, id):
Expand Down Expand Up @@ -106,7 +120,32 @@ def getQueriables(self):
yield name, queriable

def unauthenticatedPrincipal(self):
return None
"""Return unauthenticated principal or None.
This allows you to return an unauthenticated principal. This could be
usefull if you don't like to fallback to the global unauthenticated
principal usage. Why is this usefull. The reason is, if a global
principal get returned, there is no event notification involved like
we have in IPrincipalCreated which whould allow to apply groups. And
there is no way to apply local groups to global unauthenticated
principals it they get returned by the global IAuthentication or the
fallback implementation. See zope.app.security.principalregistry
Usage:
Return an unauthenticated principal within this method if you need to
apply local groups. This allows to apply local groups for the returned
unauthenticated principal if you use a custom subscriber for
IPrincipalCreated. Note, the local group must define the global
unauthenticated principals id in the principals list. Use the zcml
directive called unauthenticatedPrincipal for define the global
unauthenticated principal.
"""
principal = zope.component.queryUtility(IUnauthenticatedPrincipal)
if principal is not None:
zope.event.notify(event.UnauthenticatedPrincipalCreated(self,
principal))
return principal

def unauthorized(self, id, request):
challengeProtocol = None
Expand Down Expand Up @@ -143,4 +182,28 @@ def logout(self, request):
next.logout(request)


class QueriableAuthenticator(object):
"""Performs schema-based principal searches adapting ISearchable and
IAuthenticator.
Delegates the search to the adapted authenticator which also provides
ISearchable. See IAuthenticator.getQueriables for more infos.
"""
zope.component.adapts(interfaces.ISearchable, interfaces.IAuthenticator)

zope.interface.implements(interfaces.IQueriableAuthenticator, ILocation)

def __init__(self, authplugin, pau):
# locate them
if ILocation.providedBy(authplugin):
self.__parent__ = authplugin.__parent__
self.__name__ = authplugin.__name__
else:
self.__parent__ = pau
self.__name__ = ""
self.authplugin = authplugin
self.pau = pau

def search(self, query, start=None, batch_size=None):
for id in self.authplugin.search(query, start, batch_size):
yield id
3 changes: 2 additions & 1 deletion src/z3c/authenticator/browser/authenticator.py
Expand Up @@ -70,5 +70,6 @@ class AuthenticatorEditForm(form.EditForm):

label = _('Edit Authenticator.')

fields = field.Fields(interfaces.IAuthenticator).select('credentialsPlugins',
fields = field.Fields(interfaces.IAuthenticator).select(
'includeNextUtilityForAuthenticate', 'credentialsPlugins',
'authenticatorPlugins')
1 change: 0 additions & 1 deletion src/z3c/authenticator/browser/credential.zcml
Expand Up @@ -18,7 +18,6 @@
/>



<!-- register a loginForm.html page for your layer
<page
name="loginForm.html"
Expand Down
8 changes: 8 additions & 0 deletions src/z3c/authenticator/configure.zcml
Expand Up @@ -29,7 +29,15 @@
name="Z3CCredentialsPlugins"
/>

<adapter
for=".interfaces.ISearchable
.interfaces.IAuthenticator"
factory=".authentication.QueriableAuthenticator"
provides=".interfaces.IQueriableAuthenticator"
/>

<include file="credential.zcml" />
<include file="principalregistry.zcml" />
<include file="group.zcml" />
<include file="password.zcml" />
<include file="principal.zcml" />
Expand Down
16 changes: 16 additions & 0 deletions src/z3c/authenticator/event.py
Expand Up @@ -39,6 +39,22 @@ def __init__(self, authentication, principal, request):
self.request = request


class UnauthenticatedPrincipalCreated(object):
"""
>>> from zope.interface.verify import verifyObject
>>> event = UnauthenticatedPrincipalCreated('authentication', 'principal',
... 'request')
>>> verifyObject(interfaces.IUnauthenticatedPrincipalCreated, event)
True
"""

zope.interface.implements(interfaces.IUnauthenticatedPrincipalCreated)

def __init__(self, authentication, principal):
self.authentication = authentication
self.principal = principal


class FoundPrincipalCreated(object):
"""
>>> from zope.interface.verify import verifyObject
Expand Down

0 comments on commit 297fcfc

Please sign in to comment.