Skip to content

Commit

Permalink
Merge pull request #58 from zopefoundation/issue_17
Browse files Browse the repository at this point in the history
Add events for adding/removing principals to/from groups
  • Loading branch information
dataflake committed Nov 23, 2019
1 parent 0fb94a5 commit 0146699
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 2 deletions.
6 changes: 4 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ Change Log
2.2 (unreleased)
----------------

- Nothing changed yet.

- Add new events to be able to notify when a principal is added to
or removed from a group. Notify these events when principals are
added or removed to a group in ZODBGroupManager
(`#17 <https://github.com/zopefoundation/Products.PluggableAuthService/issues/17>`_)

2.1.1 (2019-10-23)
------------------
Expand Down
20 changes: 20 additions & 0 deletions Products/PluggableAuthService/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@
from Products.PluggableAuthService.interfaces.events import IGroupCreatedEvent
from Products.PluggableAuthService.interfaces.events import IGroupDeletedEvent
from Products.PluggableAuthService.interfaces.events import IPASEvent
from Products.PluggableAuthService.interfaces.events import \
IPrincipalAddedToGroupEvent
from Products.PluggableAuthService.interfaces.events import \
IPrincipalCreatedEvent
from Products.PluggableAuthService.interfaces.events import \
IPrincipalDeletedEvent
from Products.PluggableAuthService.interfaces.events import \
IPrincipalRemovedFromGroupEvent
from Products.PluggableAuthService.interfaces.events import \
IPropertiesUpdatedEvent

Expand All @@ -38,6 +42,22 @@ def __init__(self, principal):
self.object = principal


@implementer(IPrincipalAddedToGroupEvent)
class PrincipalAddedToGroup(PASEvent):

def __init__(self, principal, group_id):
super(PrincipalAddedToGroup, self).__init__(principal)
self.group_id = group_id


@implementer(IPrincipalRemovedFromGroupEvent)
class PrincipalRemovedFromGroup(PASEvent):

def __init__(self, principal, group_id):
super(PrincipalRemovedFromGroup, self).__init__(principal)
self.group_id = group_id


@implementer(IPrincipalCreatedEvent)
class PrincipalCreated(PASEvent):
pass
Expand Down
12 changes: 12 additions & 0 deletions Products/PluggableAuthService/interfaces/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ class IPASEvent(Interface):
principal = Attribute('The subject of the event.')


class IPrincipalAddedToGroupEvent(IPASEvent):
"""A principal has been added to a group.
"""
group_id = Attribute('Group ID to which principal is being added')


class IPrincipalRemovedFromGroupEvent(IPASEvent):
"""A principal has been removed from a group.
"""
group_id = Attribute('Group ID from which principal is being removed')


class IPrincipalCreatedEvent(IPASEvent):
"""A new principal has been created.
"""
Expand Down
4 changes: 4 additions & 0 deletions Products/PluggableAuthService/plugins/ZODBGroupManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from zope.interface import Interface

from Products.PluggableAuthService.events import GroupCreated
from Products.PluggableAuthService.events import PrincipalAddedToGroup
from Products.PluggableAuthService.events import PrincipalRemovedFromGroup
from Products.PluggableAuthService.interfaces.plugins import \
IGroupEnumerationPlugin
from Products.PluggableAuthService.interfaces.plugins import IGroupsPlugin
Expand Down Expand Up @@ -273,6 +275,7 @@ def addPrincipalToGroup(self, principal_id, group_id):
if not already:
new = current + (group_id,)
self._principal_groups[principal_id] = new
notify(PrincipalAddedToGroup(principal_id, group_id))
self._invalidatePrincipalCache(principal_id)

return not already
Expand All @@ -299,6 +302,7 @@ def removePrincipalFromGroup(self, principal_id, group_id):

if already:
self._principal_groups[principal_id] = new
notify(PrincipalRemovedFromGroup(principal_id, group_id))
self._invalidatePrincipalCache(principal_id)

return already
Expand Down
61 changes: 61 additions & 0 deletions Products/PluggableAuthService/tests/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,5 +189,66 @@ def test_instance_conforms_to_IGroupDeletedEvent(self):
verifyObject(IGroupDeletedEvent, self._makeOne())


class PrincipalAddedToGroupTests(unittest.TestCase, ConformsToIPASEvent):

def _getTargetClass(self):
from Products.PluggableAuthService.events import PrincipalAddedToGroup
return PrincipalAddedToGroup

def _makeOne(self, principal=None, group_id=None):
if principal is None:
principal = DummyPrincipal()
if group_id is None:
group_id = 'testgroup'
return self._getTargetClass()(principal, group_id)

def test_class_conforms_to_IPrincipalAddedToGroupEvent(self):
from zope.interface.verify import verifyClass
from Products.PluggableAuthService.interfaces.events \
import IPrincipalAddedToGroupEvent
verifyClass(IPrincipalAddedToGroupEvent, self._getTargetClass())

def test_instance_conforms_to_IPrincipalAddedToGroupEvent(self):
from zope.interface.verify import verifyObject
from Products.PluggableAuthService.interfaces.events \
import IPrincipalAddedToGroupEvent
verifyObject(IPrincipalAddedToGroupEvent, self._makeOne())

def test_instantiation(self):
evt = self._makeOne(group_id='foo')
self.assertEqual(evt.group_id, 'foo')


class PrincipalRemovedFromGroupTests(unittest.TestCase, ConformsToIPASEvent):

def _getTargetClass(self):
from Products.PluggableAuthService.events import \
PrincipalRemovedFromGroup
return PrincipalRemovedFromGroup

def _makeOne(self, principal=None, group_id=None):
if principal is None:
principal = DummyPrincipal()
if group_id is None:
group_id = 'testgroup'
return self._getTargetClass()(principal, group_id)

def test_class_conforms_to_IPrincipalRemovedFromGroupEvent(self):
from zope.interface.verify import verifyClass
from Products.PluggableAuthService.interfaces.events \
import IPrincipalRemovedFromGroupEvent
verifyClass(IPrincipalRemovedFromGroupEvent, self._getTargetClass())

def test_instance_conforms_to_IPrincipalRemovedFromGroupEvent(self):
from zope.interface.verify import verifyObject
from Products.PluggableAuthService.interfaces.events \
import IPrincipalRemovedFromGroupEvent
verifyObject(IPrincipalRemovedFromGroupEvent, self._makeOne())

def test_instantiation(self):
evt = self._makeOne(group_id='foo')
self.assertEqual(evt.group_id, 'foo')


class DummyGroup(object):
pass

0 comments on commit 0146699

Please sign in to comment.