##############################################################################
# Copyright (c) 2004-2005 Black Rock City, LLC
# Copyright (c) 2004-2005 ObjectRealms, LLC
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
##############################################################################
"""
Description:
 Security Mixin That Modifies Local Roles Structure
 Based on Team Membership.
 
Author: kapil thangavelu <k_vertigo@objectrealms.net>
Date: 4/5/2004
"""
from zope.interface import implements
from borg.localrole.interfaces import IWorkspace

from ExtensionClass import Base
from ComputedAttribute import ComputedAttribute
from relations import TeamContentTeamRelation
from interfaces.security import ITeamSecurity

DEBUG = 0


class TeamLocalRoles(object):
    """
    Adapts ITeamSecurity to IWorkspace, provides team local roles via
    the borg.localrole PAS plugin.
    """
    implements(IWorkspace)

    def __init__(self, context):
        self.context = context

    def getLocalRoles(self):
        res = {}
        for t in self.context._getTeamsForLocalRoles():
            for mship in t.getActiveMemberships():
                mship_id = mship.getId()
                roles = res.get(mship_id, tuple())
                mroles = mship.getTeamRoles()
                for mr in mroles:
                    if mr not in roles:
                        roles += (mr,)
                res[mship_id] = roles
        return res

    def getLocalRolesForPrincipal(self, principal):
        principal_id = principal.getId()
        res = tuple()
        for team in self.context._getTeamsForLocalRoles():
            mship = team.getMembershipByMemberId(principal_id, active_only=True)
            if mship is not None:
                mroles = mship.getTeamRoles()
                for mr in mroles:
                    if mr not in res:
                        res += (mr,)
        return res


class TeamSecurityMixin(object):
    """ this can be used as a mix-in for any AT content type to allow
        that type to honor the security policy of any teams that are
        referenced with the TeamContentTeamRelation reference class"""

    implements(ITeamSecurity)

    def _getTeamsForLocalRoles(self):
        """ retrieves all teams for which this content implements the
            security policy """
        return self.getRefs(relationship = TeamContentTeamRelation.relationship)
                
