Ignore:
Timestamp:
Dec 12, 2010 9:33:44 AM (13 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master
Children:
2627eb3
Parents:
c65b7e4
Message:

Move common GetRequest/ReleaseAccess? implementations to the base class

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/federation/access.py

    rc65b7e4 r9973d57  
    770770        except EnvironmentError, e:
    771771            self.log.error("Error deleting directory tree in %s" % e);
     772
     773    def RequestAccess(self, req, fid):
     774        """
     775        Handle an access request.  Success here maps the requester into the
     776        local access control space and establishes state about that user keyed
     777        to a fedid.  We also save a copy of the certificate underlying that
     778        fedid so this allocation can access configuration information and
     779        shared parameters on the experiment controller.
     780        """
     781
     782        # The dance to get into the request body
     783        if req.has_key('RequestAccessRequestBody'):
     784            req = req['RequestAccessRequestBody']
     785        else:
     786            raise service_error(service_error.req, "No request!?")
     787
     788        # Base class lookup routine.  If this fails, it throws a service
     789        # exception denying access that triggers a fault response back to the
     790        # caller.
     791        found, match, owners = self.lookup_access(req, fid)
     792        self.log.info(
     793                "[RequestAccess] Access granted to %s with local creds %s" % \
     794                (match, found))
     795        # Make a fedid for this allocation
     796        allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log)
     797        aid = unicode(allocID)
     798
     799        # Store the data about this allocation:
     800        self.state_lock.acquire()
     801        self.state[aid] = { }
     802        self.state[aid]['user'] = found
     803        self.state[aid]['owners'] = owners
     804        self.state[aid]['auth'] = set()
     805        # Authorize the creating fedid and the principal representing the
     806        # allocation to manipulate it.
     807        self.append_allocation_authorization(aid,
     808                ((fid, allocID), (allocID, allocID)))
     809        self.write_state()
     810        self.state_lock.release()
     811
     812        # Create a directory to stash the certificate in, ans stash it.
     813        try:
     814            f = open("%s/%s.pem" % (self.certdir, aid), "w")
     815            print >>f, alloc_cert
     816            f.close()
     817        except EnvironmentError, e:
     818            raise service_error(service_error.internal,
     819                    "Can't open %s/%s : %s" % (self.certdir, aid, e))
     820        self.log.debug('[RequestAccess] Returning allocation ID: %s' % allocID)
     821        return { 'allocID': { 'fedid': allocID } }
     822
     823    def ReleaseAccess(self, req, fid):
     824        """
     825        Release the allocation granted earlier.  Access to the allocation is
     826        checked and if valid, the state and cached certificate are destroyed.
     827        """
     828        # The dance to get into the request body
     829        if req.has_key('ReleaseAccessRequestBody'):
     830            req = req['ReleaseAccessRequestBody']
     831        else:
     832            raise service_error(service_error.req, "No request!?")
     833
     834        # Pull a key out of the request.  One can request to delete an
     835        # allocation by a local human readable name or by a fedid.  This finds
     836        # both choices.
     837        try:
     838            if 'localname' in req['allocID']:
     839                auth_attr = aid = req['allocID']['localname']
     840            elif 'fedid' in req['allocID']:
     841                aid = unicode(req['allocID']['fedid'])
     842                auth_attr = req['allocID']['fedid']
     843            else:
     844                raise service_error(service_error.req,
     845                        "Only localnames and fedids are understood")
     846        except KeyError:
     847            raise service_error(service_error.req, "Badly formed request")
     848
     849        self.log.debug("[ReleaseAccess] deallocation requested for %s", aid)
     850        #  Confirm access
     851        if not self.auth.check_attribute(fid, auth_attr):
     852            self.log.debug("[ReleaseAccess] deallocation denied for %s", aid)
     853            raise service_error(service_error.access, "Access Denied")
     854
     855        # If there is an allocation in the state, delete it.  Note the locking.
     856        self.state_lock.acquire()
     857        if aid in self.state:
     858            self.log.debug("[ReleaseAccess] Found allocation for %s" %aid)
     859            self.clear_allocation_authorization(aid)
     860            del self.state[aid]
     861            self.write_state()
     862            self.state_lock.release()
     863            # And remove the access cert
     864            cf = "%s/%s.pem" % (self.certdir, aid)
     865            self.log.debug("[ReleaseAccess] Removing %s" % cf)
     866            os.remove(cf)
     867            return { 'allocID': req['allocID'] }
     868        else:
     869            self.state_lock.release()
     870            raise service_error(service_error.req, "No such allocation")
Note: See TracChangeset for help on using the changeset viewer.