예제 #1
0
    def getPathPermissions(self, lfns, credDict):
        """Get permissions for the given user/group to manipulate the given lfns"""
        res = checkArgumentFormat(lfns)
        if not res["OK"]:
            return res
        lfns = res["Value"]

        return self.securityManager.getPathPermissions(list(lfns), credDict)
예제 #2
0
  def getPathPermissions(self, lfns, credDict):
    """ Get permissions for the given user/group to manipulate the given lfns
    """
    res = checkArgumentFormat( lfns )
    if not res['OK']:
      return res
    lfns = res['Value']

    return self.securityManager.getPathPermissions( lfns.keys(), credDict )
예제 #3
0
    def hasAccess(self, opType, paths, credDict):
        """ Get permissions for the given user/group to execute the given operation
        on the given paths

        returns Successful dict with True/False
    """
        res = checkArgumentFormat(paths)
        if not res['OK']:
            return res
        paths = res['Value']

        return self.securityManager.hasAccess(opType, paths, credDict)
예제 #4
0
  def hasAccess( self, opType, paths, credDict ):
    """ Get permissions for the given user/group to execute the given operation
        on the given paths

        returns Successful dict with True/False
    """
    res = checkArgumentFormat( paths )
    if not res['OK']:
      return res
    paths = res['Value']

    return self.securityManager.hasAccess( opType, paths, credDict )
예제 #5
0
    def _checkPathPermissions(self, operation, lfns, credDict):

        res = checkArgumentFormat(lfns)
        if not res['OK']:
            return res
        lfns = res['Value']

        res = self.securityManager.hasAccess(operation, lfns.keys(), credDict)
        if not res['OK']:
            return res
        # Do not consider those paths for which we failed to determine access
        failed = res['Value']['Failed']
        for lfn in failed.keys():
            lfns.pop(lfn)
        # Do not consider those paths for which access is denied
        successful = {}
        for lfn, access in res['Value']['Successful'].items():
            if not access:
                failed[lfn] = 'Permission denied'
            else:
                successful[lfn] = lfns[lfn]
        return S_OK({'Successful': successful, 'Failed': failed})
예제 #6
0
    def _checkPathPermissions(self, operation, lfns, credDict):

        res = checkArgumentFormat(lfns)
        if not res["OK"]:
            return res
        lfns = res["Value"]

        res = self.securityManager.hasAccess(operation, list(lfns), credDict)
        if not res["OK"]:
            return res
        # Do not consider those paths for which we failed to determine access
        failed = res["Value"]["Failed"]
        for lfn in failed:
            lfns.pop(lfn)
        # Do not consider those paths for which access is denied
        successful = {}
        for lfn, access in res["Value"]["Successful"].items():
            if not access:
                failed[lfn] = "Permission denied"
            else:
                successful[lfn] = lfns[lfn]
        return S_OK({"Successful": successful, "Failed": failed})
예제 #7
0
  def _checkPathPermissions( self, operation, lfns, credDict ):

    res = checkArgumentFormat( lfns )
    if not res['OK']:
      return res
    lfns = res['Value']

    res = self.securityManager.hasAccess( operation, lfns.keys(), credDict )
    if not res['OK']:
      return res
    # Do not consider those paths for which we failed to determine access
    failed = res['Value']['Failed']
    for lfn in failed.keys():
      lfns.pop( lfn )
    # Do not consider those paths for which access is denied
    successful = {}
    for lfn, access in res['Value']['Successful'].items():
      if not access:
        failed[lfn] = 'Permission denied'
      else:
        successful[lfn] = lfns[lfn]
    return S_OK( {'Successful':successful, 'Failed':failed} )
예제 #8
0
파일: FileCatalog.py 프로젝트: ahaupt/DIRAC
  def w_execute( self, *parms, **kws ):
    """ Write method executor.

      If one of the LFNs given as input does not pass a condition defined for the
      master catalog, we return S_ERROR without trying anything else

      :param fcConditions: either a dict or a string, to be propagated to the FCConditionParser
                           If it is a string, it is given for all catalogs
                           If it is a dict, it has to be { catalogName: condition}, and only
                                the specific condition for the catalog will be given

      CAUTION !!! If the method is a write no_lfn method, then the return value are completely different
                  We only return the result of the master catalog


    """
    successful = {}
    failed = {}
    failedCatalogs = {}
    successfulCatalogs = {}


    specialConditions = kws.pop( 'fcConditions' ) if 'fcConditions' in kws else None

    allLfns = []
    lfnMapDict = {}
    masterResult = {}
    parms1 = []
    if self.call not in self.no_lfn_methods:
      fileInfo = parms[0]
      result = checkArgumentFormat( fileInfo, generateMap = True )
      if not result['OK']:
        return result
      fileInfo, lfnMapDict = result['Value']
      # No need to check the LFNs again in the clients
      kws['LFNChecking'] = False
      allLfns = fileInfo.keys()
      parms1 = parms[1:]

    for catalogName, oCatalog, master in self.writeCatalogs:

      # Skip if the method is not implemented in this catalog
      # NOTE: it is impossible for the master since the write method list is populated
      # only from the master catalog, and if the method is not there, __getattr__
      # would raise an exception
      if not oCatalog.hasCatalogMethod( self.call ):
        continue

      method = getattr( oCatalog, self.call )

      if self.call in self.no_lfn_methods:
        result = method( *parms, **kws )
      else:
        if isinstance( specialConditions, dict ):
          condition = specialConditions.get( catalogName )
        else:
          condition = specialConditions
        # Check whether this catalog should be used for this method
        res = self.condParser( catalogName, self.call, fileInfo, condition = condition )
        # condParser never returns S_ERROR
        condEvals = res['Value']['Successful']
        # For a master catalog, ALL the lfns should be valid
        if master:
          if any([not valid for valid in condEvals.values()]):
            gLogger.error( "The master catalog is not valid for some LFNS", condEvals )
            return S_ERROR( "The master catalog is not valid for some LFNS %s" % condEvals )

        validLFNs = dict( ( lfn, fileInfo[lfn] ) for lfn in condEvals if condEvals[lfn] )
        invalidLFNs = [lfn for lfn in condEvals if not condEvals[lfn]]
        if invalidLFNs:
          gLogger.debug( "Some LFNs are not valid for operation '%s' on catalog '%s' : %s" % ( self.call, catalogName,
                                                                                               invalidLFNs ) )
        result = method( validLFNs, *parms1, **kws )


      if master:
        masterResult = result

      if not result['OK']:
        if master:
          # If this is the master catalog and it fails we don't want to continue with the other catalogs
          self.log.error( "Failed to execute call on master catalog",
                          "%s on %s: %s" % ( self.call, catalogName, result['Message'] ) )
          return result
        else:
          # Otherwise we keep the failed catalogs so we can update their state later
          failedCatalogs[catalogName] = result['Message']
      else:
        successfulCatalogs[catalogName] = result['Value']

      if allLfns:
        if result['OK']:
          for lfn, message in result['Value']['Failed'].items():
            # Save the error message for the failed operations
            failed.setdefault( lfn, {} )[catalogName] = message
            if master:
              # If this is the master catalog then we should not attempt the operation on other catalogs
              fileInfo.pop( lfn, None )
          for lfn, result in result['Value']['Successful'].items():
            # Save the result return for each file for the successful operations
            successful.setdefault( lfn, {} )[catalogName] = result

    if allLfns:
      # This recovers the states of the files that completely failed i.e. when S_ERROR is returned by a catalog
      for catalogName, errorMessage in failedCatalogs.items():
        for lfn in allLfns:
          failed.setdefault( lfn, {} )[catalogName] = errorMessage
      # Restore original lfns if they were changed by normalization
      if lfnMapDict:
        for lfn in failed.keys():
          failed[lfnMapDict.get( lfn, lfn )] = failed.pop( lfn )
        for lfn in successful.keys():
          successful[lfnMapDict.get( lfn, lfn )] = successful.pop( lfn )
      resDict = {'Failed':failed, 'Successful':successful}
      return S_OK( resDict )
    else:
      # FIXME: Return just master result here. This is temporary as more detailed
      # per catalog result needs multiple fixes in various client calls
      return masterResult
예제 #9
0
    def w_execute(self, *parms, **kws):
        """Write method executor.

        If one of the LFNs given as input does not pass a condition defined for the
        master catalog, we return S_ERROR without trying anything else

        :param fcConditions: either a dict or a string, to be propagated to the FCConditionParser

                             * If it is a string, it is given for all catalogs
                             * If it is a dict, it has to be { catalogName: condition}, and only
                                  the specific condition for the catalog will be given

        .. warning ::

          If the method is a write no_lfn method, then the return value are completely different.
          We only return the result of the master catalog


        """
        successful = {}
        failed = {}
        failedCatalogs = {}
        successfulCatalogs = {}

        specialConditions = kws.pop("fcConditions") if "fcConditions" in kws else None

        allLfns = []
        lfnMapDict = {}
        masterResult = {}
        parms1 = []
        if self.call not in self.no_lfn_methods:
            fileInfo = parms[0]
            result = checkArgumentFormat(fileInfo, generateMap=True)
            if not result["OK"]:
                return result
            fileInfo, lfnMapDict = result["Value"]
            # No need to check the LFNs again in the clients
            kws["LFNChecking"] = False
            allLfns = list(fileInfo)
            parms1 = parms[1:]

        for catalogName, oCatalog, master in self.writeCatalogs:

            # Skip if the method is not implemented in this catalog
            # NOTE: it is impossible for the master since the write method list is populated
            # only from the master catalog, and if the method is not there, __getattr__
            # would raise an exception
            if not oCatalog.hasCatalogMethod(self.call):
                continue

            method = getattr(oCatalog, self.call)

            if self.call in self.no_lfn_methods:
                result = method(*parms, **kws)
            else:
                if isinstance(specialConditions, dict):
                    condition = specialConditions.get(catalogName)
                else:
                    condition = specialConditions
                # Check whether this catalog should be used for this method
                res = self.condParser(catalogName, self.call, fileInfo, condition=condition)
                # condParser never returns S_ERROR
                condEvals = res["Value"]["Successful"]
                # For a master catalog, ALL the lfns should be valid
                if master:
                    if any([not valid for valid in condEvals.values()]):
                        gLogger.error("The master catalog is not valid for some LFNS", condEvals)
                        return S_ERROR("The master catalog is not valid for some LFNS %s" % condEvals)

                validLFNs = dict((lfn, fileInfo[lfn]) for lfn in condEvals if condEvals[lfn])

                # We can skip the execution without worry,
                # since at this level it is for sure not a master catalog
                if not validLFNs:
                    gLogger.debug("No valid LFN, skipping the call")
                    continue

                invalidLFNs = [lfn for lfn in condEvals if not condEvals[lfn]]

                if invalidLFNs:
                    gLogger.debug(
                        "Some LFNs are not valid for operation '%s' on catalog '%s' : %s"
                        % (self.call, catalogName, invalidLFNs)
                    )

                result = method(validLFNs, *parms1, **kws)

            if master:
                masterResult = result

            if not result["OK"]:
                if master:
                    # If this is the master catalog and it fails we don't want to continue with the other catalogs
                    self.log.error(
                        "Failed to execute call on master catalog",
                        "%s on %s: %s" % (self.call, catalogName, result["Message"]),
                    )
                    return result
                else:
                    # Otherwise we keep the failed catalogs so we can update their state later
                    failedCatalogs[catalogName] = result["Message"]
            else:
                successfulCatalogs[catalogName] = result["Value"]

            if allLfns:
                if result["OK"]:
                    for lfn, message in result["Value"]["Failed"].items():
                        # Save the error message for the failed operations
                        failed.setdefault(lfn, {})[catalogName] = message
                        if master:
                            # If this is the master catalog then we should not attempt the operation on other catalogs
                            fileInfo.pop(lfn, None)
                    for lfn, result in result["Value"]["Successful"].items():
                        # Save the result return for each file for the successful operations
                        successful.setdefault(lfn, {})[catalogName] = result

        if allLfns:
            # This recovers the states of the files that completely failed i.e. when S_ERROR is returned by a catalog
            for catalogName, errorMessage in failedCatalogs.items():
                for lfn in allLfns:
                    failed.setdefault(lfn, {})[catalogName] = errorMessage
            # Restore original lfns if they were changed by normalization
            if lfnMapDict:
                for lfn in list(failed):
                    failed[lfnMapDict.get(lfn, lfn)] = failed.pop(lfn)
                for lfn in list(successful):
                    successful[lfnMapDict.get(lfn, lfn)] = successful.pop(lfn)
            resDict = {"Failed": failed, "Successful": successful}
            return S_OK(resDict)
        else:
            # FIXME: Return just master result here. This is temporary as more detailed
            # per catalog result needs multiple fixes in various client calls
            return masterResult