Changeset a31b94d


Ignore:
Timestamp:
Oct 28, 2009 6:38:52 PM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-2.00, version-3.01, version-3.02
Children:
2bc7b76
Parents:
73ded03
Message:

tweaks to the abac authorizer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/federation/authorizer.py

    r73ded03 ra31b94d  
    22
    33from fedid import fedid
    4 
    5 class authorizer:
    6     """
    7     This class keeps track of authorization attributes for the various modules
    8     running.  When it gets smarter it will be the basis for a real
    9     attribute-based authentication system.
    10     """
     4from remote_service import service_caller
     5from abac_remote_service import abac_service_caller
     6from service_error import service_error
     7
     8import sys
     9
     10class authorizer_base:
     11    """
     12    Classes based on this one keep track of authorization attributes for the
     13    various modules running.  This base class holds some utility functions that
     14    they all potentially use.
     15    """
     16
    1117    # general error exception for badly formed names. 
    1218    class bad_name(RuntimeError): pass
    13 
    14     def __init__(self, def_attr="testbed"):
    15         self.attrs = { }
    16         self.globals=set()
    1719
    1820    @staticmethod
     
    2729        else: return name
    2830
    29     def valid_name(self, name):
     31    @staticmethod
     32    def valid_name(name):
    3033        """
    3134        Ensure that the given name is valid.  A valid name can either be a
     
    4245                if n:
    4346                    if not (isinstance(n, basestring) or isinstance(n, fedid)):
    44                         raise self.bad_name("names must be either a " +\
    45                                 "triple or a fedid")
     47                        raise authorizer_base.bad_name(
     48                                "names must be either a triple or a fedid")
    4649            for n in name:
    4750                if n:
     
    4952                        return True
    5053                    else:
    51                         raise self.bad_name("Compound names must be " + \
     54                        raise authorizer_base.bad_name(
     55                                "Compound names must be " + \
    5256                                "rooted in fedids: %s" % str(name))
    5357
     
    5660            return True
    5761        else:
    58             raise self.bad_name("Names must be a triple or a fedid (%s)" % name)
     62            raise authorizer_base.bad_name(
     63                    "Names must be a triple or a fedid (%s)" % name)
     64
     65
     66class authorizer(authorizer_base):
     67    """
     68    This class keeps track of authorization attributes for the various modules
     69    running.  When it gets smarter it will be the basis for a real
     70    attribute-based authentication system.
     71    """
     72    def __init__(self, def_attr="testbed"):
     73        self.attrs = { }
     74        self.globals=set()
    5975
    6076    def set_attribute(self, name, attr):
     
    124140        self.globals.discard(attr)
    125141
     142class abac_authorizer(authorizer_base):
     143    """
     144    Use the ABAC authorization system to make attribute decisions.
     145    """
     146
     147    def __init__(self, url=None, cert_file=None, cert_pwd=None,
     148            trusted_certs=None, me=None):
     149        self.call_CreateContext = abac_service_caller('CreateContext')
     150        self.call_CredentialUpdate = abac_service_caller('CredentialUpdate')
     151        self.call_Access = abac_service_caller('Access')
     152        self.globals = set()
     153
     154        self.url = url
     155        self.cert_file = cert_file
     156        self.cert_pwd = cert_pwd
     157        self.trusted_certs = trusted_certs
     158        self.me = me
     159        self.contextID = me.get_hexstr()
     160        req = { 'contextID' : self.contextID}
     161        # May throw a service error
     162        resp = self.call_CreateContext(self.url, req, self.cert_file,
     163                self.cert_pwd, self.trusted_certs, tracefile=sys.stderr)
     164
     165        if resp.has_key('CreateContextResponseBody'):
     166            resp =  resp['CreateContextResponseBody']
     167            if resp.has_key('contextID'):
     168                self.contextID = resp['contextID']
     169            else:
     170                raise service_error(service_error.internal,
     171                        "No context ID for the new authorization context")
     172        else:
     173            raise service_error(service_error.internal,
     174                    "Bad response to creating service context")
     175
     176    def set_attribute(self, name, attr):
     177        self.valid_name(name)
     178        if isinstance(name, tuple):
     179            if not isinstance(name[0], fedid):
     180                raise service_error(service_error.internal,
     181                        "Triple not anchored in testbed")
     182            if not name[1] and not name[2]:
     183                raise service_error(service_error.internal,
     184                        "Anonymous access not yet permitted")
     185
     186            preconditions = "^".join(
     187                    [ "%s.%s" % (name[0], self.auth_name(n)) \
     188                            for n in name[1:3] if n ])
     189
     190            req = {
     191                    'credential': [ '%s.%s<--%s' % \
     192                            ( self.me, attr, preconditions) ],
     193                    'context': { 'contextID': self.contextID  }
     194                }
     195        else:
     196            req = {
     197                    'credential': [ '%s.%s<--%s' % \
     198                            ( self.me, attr, self.auth_name(name)) ],
     199                    'context': { 'contextID': self.contextID }
     200                }
     201        print req
     202        self.call_CredentialUpdate(self.url, req, self.cert_file,
     203                self.cert_pwd, self.trusted_certs, tracefile=sys.stderr)
     204
     205    def check_attribute(self, name, attr):
     206        self.valid_name(name)
     207        if attr in self.globals: return True
     208
     209        if isinstance(name, tuple):
     210            raise service_error(service_error.internal,
     211                    "Only fedids permitted here")
     212        req = {
     213                'goal': '%s:%s<<---%s' % (self.me, attr, name),
     214                'context': { 'contextID': self.contextID }
     215            }
     216        resp = self.call_Access(self.url, req, self.cert_file, self.cert_pwd,
     217                self.trusted_certs)
     218        if resp.has_key('AccessResponseBody'):
     219            resp = resp['AccessResponseBody']
     220
     221        result = resp.get('result', None)
     222        return (result and result.lower() == 'true')
     223
     224    def set_global_attribute(self, attr):
     225        """
     226        Set a global attribute.  All names, even those otherwise unknown to the
     227        authorizer have this attribute.
     228        """
     229        self.globals.add(attr)
     230
     231    def unset_global_attribute(self, attr):
     232        """
     233        Remove a global attribute
     234        """
     235
     236        self.globals.discard(attr)
     237
Note: See TracChangeset for help on using the changeset viewer.