This is a pre-production deployment of Warehouse, however changes made here WILL affect the production instance of PyPI.
Latest Version Dependencies status unknown Test status unknown Test coverage unknown
Project Description

This is an AuthenticatorPlugin that implements a read-only GroupFolder reflecting the groups as defined on an LDAP server. It relies on the registration as a named ILDAPAuthentation utility of an ldappas plugin. It works in tandem with ldappas: ldappas authenticates users, while ldapgroups looks up their groups and adds the users to the groups

Setup

>>> from ldappas.authentication import LDAPAuthentication
>>> from zope import component
>>> from ldappas.interfaces import ILDAPAuthentication
>>> users = LDAPAuthentication()
>>> component.provideUtility(users, ILDAPAuthentication, 'ldap-users')

LDAPAuthentication needs an LDAP adapter, registered as a named ILDAPAdapter utility. There’s a fake one in the tests module.

>>> from ldapgroups.tests.fakeadapter import FakeLDAPAdapter
>>> adapter = FakeLDAPAdapter()
>>> from ldapadapter.interfaces import ILDAPAdapter
>>> component.provideUtility(adapter, ILDAPAdapter, 'ldap-adapter')

Let’s configure the LDAPAuthentication plugin:

>>> users.adapterName = u'ldap-adapter'
>>> users.searchBase = u'ou=users,dc=test'
>>> users.searchScope = u'sub'
>>> users.loginAttribute = u'cn'
>>> users.principalIdPrefix = u'ldap.'
>>> users.titleAttribute = u'sn'

There’s no need to fill in the group-related attributes on the LDAPAuthentication plugin, as LDAPGroups uses its own. For the idAttribute, you should use the attribute that yields the Distinguished Name of the user, as LDAP uses this to link users to groups:

>>> users.idAttribute = u'dn'

(For ActiveDirectory, this apparently is ‘distinguishedName’, so use an LDAP browser to check) There may be a way around this restriction with advanced queries, but is not (yet?) implemented.

Let’s get our LDAP GroupFolder up and running

>>> from ldapgroups.groupfolder import LDAPGroups
>>> groups = LDAPGroups(u'ldap-users', u'group.ldap.')
>>> groups.groupsSearchBase = u'ou=groups,dc=test'
>>> groups.groupsSearchScope = u'sub'
>>> groups.groupTitleAttribute = u'cn'
>>> groups.groupIdAttribute = u'dn'
>>> groups.groupDescriptionAttribute = u'description'

Do some registration tests

>>> groups.getLDAPAuthenticator() == users
True
>>> users.getLDAPAdapter() == adapter
True

Groups can’t authenticate

>>> groups.authenticateCredentials({'login':u'Domain Users','password':u'pwd'}) is None
True

We can lookup groups as principals

>>> principal = groups.principalInfo(u'group.ldap.cn=Domain Users,ou=groups,dc=test')
>>> principal
LDAPGroupInformation(u'group.ldap.cn=Domain Users,ou=groups,dc=test')
>>> from zope.pluggableauth.interfaces import IPrincipalInfo
>>> IPrincipalInfo.providedBy(principal)
True

It also provides IReadGroupInformation, which can be used to get the principals

>>> from ldapgroups.interfaces import IReadGroupInformation
>>> IReadGroupInformation.providedBy(principal)
True
>>> principal.principals
[u'ldap.cn=Andr\xe9 de Chimpansee,ou=users,dc=test', u'ldap.cn=Louis Kolibri,ou=users,dc=test']

Container behaviour

>>> len(groups)
2
>>> groups.keys()
[u'Administrators', u'Domain Users']
>>> 'Administrators' in groups
True
>>> groups.has_key('Administrators')
True
>>> groups.values()
[LDAPGroupInformation(u'group.ldap.cn=Administrators,ou=groups,dc=test'), LDAPGroupInformation(u'group.ldap.cn=Domain Users,ou=groups,dc=test')]
>>> groups.items() == zip(groups.keys(),  groups.values())
True
>>> group = groups['Domain Users']
>>> group
LDAPGroupInformation(u'group.ldap.cn=Domain Users,ou=groups,dc=test')
>>> group.description
u'Users with a domain account'
>>> group == groups.get('Domain Users')
True
>>> groups.get('grupo sportivo') is None
True
>>> groups['grupo sportivo'] # doctest: +ELLIPSIS
Traceback (most recent call last):
  ...
KeyError

Searching

>>> groups.search({'cn':'Domain Users'})
[u'group.ldap.cn=Domain Users,ou=groups,dc=test']
>>> groups.search({'cn':'Users'})
[]

PAU integration:

Registers them all to the PAU

>>> from zope.pluggableauth.interfaces import IAuthenticatorPlugin
>>> component.provideUtility(users, provides=IAuthenticatorPlugin, name='ldap-users')
>>> component.provideUtility(groups, provides=IAuthenticatorPlugin, name='ldap-groups')

We also need a credentials plugin that will extract the credentials from the request:

>>> import zope.interface
>>> from zope.pluggableauth.interfaces import ICredentialsPlugin
>>> class MyCredentialsPlugin:
...
...     zope.interface.implements(ICredentialsPlugin)
...
...     def extractCredentials(self, request):
...         return request.get('credentials')
...
...     def challenge(self, request):
...         pass # challenge is a no-op for this plugin
...
...     def logout(request):
...         pass # logout is a no-op for this plugin
>>> creds = MyCredentialsPlugin()
>>> component.provideUtility(creds, name='simple-creds')

Register the principalFactory

>>> import zope.component.event
>>> from zope.pluggableauth import factories
>>> component.provideAdapter(factories.AuthenticatedPrincipalFactory)
>>> component.provideAdapter(factories.FoundPrincipalFactory)

We are finally ready to create a pluggable authentication utility and register the two plugins with it:

>>> from zope.pluggableauth import PluggableAuthentication
>>> pau = PluggableAuthentication()
>>> pau['ldap-users'] = users
>>> pau['ldap-groups'] = groups
>>> pau['simple-creds'] = creds
>>> pau.credentialsPlugins = ('simple-creds', )
>>> pau.authenticatorPlugins = ('ldap-users', 'ldap-groups')

Let’s authenticate some users

>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest(credentials={'login': 'Louis Kolibri', 'password': 'louis2000'})
>>> louis = pau.authenticate(request)
>>> louis
Principal(u'ldap.cn=Louis Kolibri,ou=users,dc=test')

Groups are set by the setGroupsForPrincipal event subscriber

>>> louis.groups
[]
>>> class PrincipalCreatedEvent:
...     def __init__(self, authentication, principal):
...         self.authentication = authentication
...         self.principal = principal
>>> from ldapgroups.groupfolder import setGroupsForPrincipal
>>> setGroupsForPrincipal(PrincipalCreatedEvent(pau, louis))
>>> louis.groups
[u'group.ldap.cn=Domain Users,ou=groups,dc=test']
>>> component.provideHandler(setGroupsForPrincipal)
>>> request = TestRequest(credentials={'login': u'Andr\xe9 de Chimpansee', 'password': 'dreten'})
>>> andre = pau.authenticate(request)
>>> andre
Principal(u'ldap.cn=Andr\xe9 de Chimpansee,ou=users,dc=test')
>>> andre.groups
[u'group.ldap.cn=Administrators,ou=groups,dc=test', u'group.ldap.cn=Domain Users,ou=groups,dc=test']

Browser views

There’s an ISized adapter available for the zmi view.

>>> from ldapgroups.groupfolder import LDAPGroupSize
>>> from zope.size.interfaces import ISized
>>> component.provideAdapter(LDAPGroupSize)
>>> ISized(group).sizeForSorting()
('item', 2)

The view’s iteminfos function gathers all info about the goups in a groupfolder

>>> from ldapgroups.browser.contents import LDAPGroupFolderContents
>>> view = LDAPGroupFolderContents(groups, request)
>>> view.iteminfos()
[{'url': 'Administrators', 'name': u'Administrators', 'size': u'${items} items'}, {'url': 'Domain%20Users', 'name': u'Domain Users', 'size': u'${items} items'}]

Download

Release History

Release History

0.2

This version

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1.1

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1a3

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1a2

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1a1

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.1dev

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

Download Files

Download Files

TODO: Brief introduction on what you do with files - including link to relevant help section.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
ldapgroups-0.2.zip (18.7 kB) Copy SHA256 Checksum SHA256 Source May 10, 2011

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS HPE HPE Development Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting