loops/organize/util.py

147 lines
5.4 KiB
Python

#
# Copyright (c) 2013 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Utilities for the loops.organize package.
"""
from zope import interface, component, schema
from zope.app.authentication.interfaces import IPluggableAuthentication
from zope.app.authentication.interfaces import IAuthenticatorPlugin
from zope.app.authentication.groupfolder import GroupFolder
from zope.app.security.interfaces import IAuthentication, PrincipalLookupError
from zope.app.security.settings import Allow, Deny, Unset
from zope.securitypolicy.interfaces import IPrincipalRoleManager
from zope.traversing.api import getParents
from loops.common import adapted
from loops.security.common import getCurrentPrincipal
from loops.type import getOptionsDict
defaultAuthPluginId = 'loops'
def getPrincipalFolder(context=None, authPluginId=None, ignoreErrors=False):
pau = component.getUtility(IAuthentication, context=context)
if not IPluggableAuthentication.providedBy(pau):
if ignoreErrors:
return None
raise ValueError(u'There is no pluggable authentication '
'utility available.')
if authPluginId is None and context is not None:
person = context.getLoopsRoot().getConceptManager()['person']
od = getOptionsDict(adapted(person).options)
authPluginId = od.get('principalfolder', defaultAuthPluginId)
if authPluginId is None:
authPluginId = defaultAuthPluginId
if authPluginId not in pau.authenticatorPlugins:
if ignoreErrors:
return None
raise ValueError(u"There is no loops authenticator "
"plugin '%s' available." % authPluginId)
for name, plugin in pau.getAuthenticatorPlugins():
if name == authPluginId:
return plugin
def getGroupsFolder(context=None, name='gloops', create=False):
gf = getPrincipalFolder(authPluginId=name, ignoreErrors=True)
if gf is None and create:
pau = component.getUtility(IAuthentication, context=context)
gf = pau[name] = GroupFolder(name + '.')
pau.authenticatorPlugins = tuple(
list(pau.authenticatorPlugins) + [name])
return gf
def getGroupId(group):
gf = group.__parent__
return ''.join((gf.__parent__.prefix, gf._groupid(group)))
def getInternalPrincipal(id, context=None, pau=None):
if pau is None:
pau = component.getUtility(IAuthentication, context=context)
if not IPluggableAuthentication.providedBy(pau):
raise ValueError(u'There is no pluggable authentication '
u'utility available.')
if not id.startswith(pau.prefix):
next = queryNextUtility(pau, IAuthentication)
if next is None:
raise PrincipalLookupError(id)
#return next.getPrincipal(id)
return getInternalPrincipal(id, context, pau=next)
id = id[len(pau.prefix):]
for name, authplugin in pau.getAuthenticatorPlugins():
if not id.startswith(authplugin.prefix):
continue
principal = authplugin.get(id[len(authplugin.prefix):])
if principal is None:
continue
return principal
next = queryNextUtility(pau, IAuthentication)
if next is not None:
#return next.getPrincipal(pau.prefix + id)
return getInternalPrincipal(id, context, pau=next)
raise PrincipalLookupError(id)
def getPrincipalForUserId(id, context=None):
auth = component.getUtility(IAuthentication, context=context)
try:
return auth.getPrincipal(id)
except PrincipalLookupError:
return None
def getRolesForPrincipal(id, context):
prinrole = IPrincipalRoleManager(context, None)
if prinrole is None:
return []
result = []
denied = []
for role, setting in prinrole.getRolesForPrincipal(id):
if setting == Allow:
result.append(role)
elif setting == Deny:
denied.append(role)
for obj in getParents(context):
prinrole = IPrincipalRoleManager(obj, None)
if prinrole is not None:
for role, setting in prinrole.getRolesForPrincipal(id):
if setting == Allow and role not in denied and role not in result:
result.append(role)
elif setting == Deny and role not in denied:
denied.append(role)
return result
def getGroupsForPrincipal(principal=None):
if principal is None:
principal = getCurrentPrincipal()
gf = getGroupsFolder()
prefix = 'gloops.'
return [(g.startswith(prefix) and g[len(prefix):] or g)
for g in gf.getGroupsForPrincipal(principal.id)]
def getTrackingStorage(obj, name):
records = obj.getLoopsRoot().getRecordManager()
if records is not None:
return records.get(name)
return None