예제 #1
0
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public Map<String, Serializable> recordAuditValuesImpl(Map<String, Serializable> mappedValues) {
    // Group the values by root path
    Map<String, Map<String, Serializable>> mappedValuesByRootKey =
        new HashMap<String, Map<String, Serializable>>();
    for (Map.Entry<String, Serializable> entry : mappedValues.entrySet()) {
      String path = entry.getKey();
      String rootKey = AuditApplication.getRootKey(path);
      Map<String, Serializable> rootKeyMappedValues = mappedValuesByRootKey.get(rootKey);
      if (rootKeyMappedValues == null) {
        rootKeyMappedValues = new HashMap<String, Serializable>(7);
        mappedValuesByRootKey.put(rootKey, rootKeyMappedValues);
      }
      rootKeyMappedValues.put(path, entry.getValue());
    }

    Map<String, Serializable> allAuditedValues =
        new HashMap<String, Serializable>(mappedValues.size() * 2 + 1);
    // Now audit for each of the root keys
    for (Map.Entry<String, Map<String, Serializable>> entry : mappedValuesByRootKey.entrySet()) {
      String rootKey = entry.getKey();
      Map<String, Serializable> rootKeyMappedValues = entry.getValue();
      // Get the application
      AuditApplication application = auditModelRegistry.getAuditApplicationByKey(rootKey);
      if (application == null) {
        // There is no application that uses the root key
        logger.debug("There is no application for root key: " + rootKey);
        continue;
      }
      // Get the disabled paths
      Set<String> disabledPaths = getDisabledPaths(application);
      // Do a quick elimination if the root path is disabled
      if (disabledPaths.contains(AuditApplication.buildPath(rootKey))) {
        // The root key has been disabled for this application
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Audit values root path has been excluded by disabled paths: \n"
                  + "   Application: "
                  + application
                  + "\n"
                  + "   Root Path:   "
                  + AuditApplication.buildPath(rootKey));
        }
        continue;
      }
      // Do the audit
      Map<String, Serializable> rootKeyAuditValues =
          audit(application, disabledPaths, rootKeyMappedValues);
      allAuditedValues.putAll(rootKeyAuditValues);
    }
    // Done
    return allAuditedValues;
  }
예제 #2
0
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public Map<String, Serializable> recordAuditValues(
      String rootPath, Map<String, Serializable> values) {
    ParameterCheck.mandatory("rootPath", rootPath);
    AuditApplication.checkPathFormat(rootPath);

    if (values == null || values.isEmpty() || !isSourcePathMapped(rootPath)) {
      return Collections.emptyMap();
    }

    // Build the key paths using the session root path
    Map<String, Serializable> pathedValues = new HashMap<String, Serializable>(values.size() * 2);
    for (Map.Entry<String, Serializable> entry : values.entrySet()) {
      String pathElement = entry.getKey();
      String path = AuditApplication.buildPath(rootPath, pathElement);
      pathedValues.put(path, entry.getValue());
    }

    // Translate the values map
    PathMapper pathMapper = auditModelRegistry.getAuditPathMapper();
    final Map<String, Serializable> mappedValues = pathMapper.convertMap(pathedValues);
    if (mappedValues.isEmpty()) {
      return mappedValues;
    }

    // We have something to record.  Start a transaction, if necessary
    TxnReadState txnState = AlfrescoTransactionSupport.getTransactionReadState();
    switch (txnState) {
      case TXN_NONE:
      case TXN_READ_ONLY:
        // New transaction
        RetryingTransactionCallback<Map<String, Serializable>> callback =
            new RetryingTransactionCallback<Map<String, Serializable>>() {
              public Map<String, Serializable> execute() throws Throwable {
                return recordAuditValuesImpl(mappedValues);
              }
            };
        return transactionService
            .getRetryingTransactionHelper()
            .doInTransaction(callback, false, true);
      case TXN_READ_WRITE:
        return recordAuditValuesImpl(mappedValues);
      default:
        throw new IllegalStateException("Unknown txn state: " + txnState);
    }
  }
예제 #3
0
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public void resetDisabledPaths(String applicationName) {
    ParameterCheck.mandatory("applicationName", applicationName);
    AlfrescoTransactionSupport.checkTransactionReadState(true);

    AuditApplication application = auditModelRegistry.getAuditApplicationByName(applicationName);
    if (application == null) {
      if (logger.isDebugEnabled()) {
        logger.debug("No audit application named '" + applicationName + "' has been registered.");
      }
      return;
    }
    Long disabledPathsId = application.getDisabledPathsId();
    propertyValueDAO.updateProperty(disabledPathsId, (Serializable) Collections.emptySet());
    // Done
    if (logger.isDebugEnabled()) {
      logger.debug("Removed all disabled paths for application " + applicationName);
    }
  }
예제 #4
0
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public void enableAudit(String applicationName, String path) {
    ParameterCheck.mandatory("applicationName", applicationName);
    ParameterCheck.mandatory("path", path);
    AlfrescoTransactionSupport.checkTransactionReadState(true);

    AuditApplication application = auditModelRegistry.getAuditApplicationByName(applicationName);
    if (application == null) {
      if (logger.isDebugEnabled()) {
        logger.debug("No audit application named '" + applicationName + "' has been registered.");
      }
      return;
    }
    // Check the path against the application
    application.checkPath(path);

    Long disabledPathsId = application.getDisabledPathsId();
    Set<String> disabledPaths = getDisabledPaths(application);

    // Remove any paths that start with the given path
    boolean changed = false;
    Iterator<String> iterateDisabledPaths = disabledPaths.iterator();
    while (iterateDisabledPaths.hasNext()) {
      String disabledPath = iterateDisabledPaths.next();
      if (disabledPath.startsWith(path)) {
        iterateDisabledPaths.remove();
        changed = true;
      }
    }
    // Persist, if necessary
    if (changed) {
      propertyValueDAO.updateProperty(disabledPathsId, (Serializable) disabledPaths);
      if (logger.isDebugEnabled()) {
        logger.debug(
            "Audit disabled paths updated: \n"
                + "   Application: "
                + applicationName
                + "\n"
                + "   Disabled:    "
                + disabledPaths);
      }
    }
    // Done
  }
예제 #5
0
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public boolean isAuditPathEnabled(String applicationName, String path) {
    ParameterCheck.mandatory("applicationName", applicationName);
    ParameterCheck.mandatory("path", path);
    AlfrescoTransactionSupport.checkTransactionReadState(false);

    AuditApplication application = auditModelRegistry.getAuditApplicationByName(applicationName);
    if (application == null) {
      if (logger.isDebugEnabled()) {
        logger.debug("No audit application named '" + applicationName + "' has been registered.");
      }
      return false;
    }
    // Check the path against the application
    application.checkPath(path);

    Set<String> disabledPaths = getDisabledPaths(application);

    // Check if there are any entries that match or superced the given path
    String disablingPath = null;
    ;
    for (String disabledPath : disabledPaths) {
      if (path.startsWith(disabledPath)) {
        disablingPath = disabledPath;
        break;
      }
    }
    // Done
    if (logger.isDebugEnabled()) {
      logger.debug(
          "Audit path enabled check: \n"
              + "   Application:    "
              + applicationName
              + "\n"
              + "   Path:           "
              + path
              + "\n"
              + "   Disabling Path: "
              + disablingPath);
    }
    return disablingPath == null;
  }
예제 #6
0
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public void deleteAuditEntries(String applicationName, Long fromTime, Long toTime) {
    ParameterCheck.mandatory("applicationName", applicationName);
    AlfrescoTransactionSupport.checkTransactionReadState(true);

    AuditApplication application = auditModelRegistry.getAuditApplicationByName(applicationName);
    if (application == null) {
      if (logger.isDebugEnabled()) {
        logger.debug("No audit application named '" + applicationName + "' has been registered.");
      }
      return;
    }

    Long applicationId = application.getApplicationId();

    auditDAO.deleteAuditEntries(applicationId, fromTime, toTime);
    // Done
    if (logger.isDebugEnabled()) {
      logger.debug(
          "Delete audit entries for " + applicationName + " (" + fromTime + " to " + toTime);
    }
  }
예제 #7
0
 /**
  * @param application the audit application object
  * @return Returns a copy of the set of disabled paths associated with the application
  */
 @SuppressWarnings("unchecked")
 private Set<String> getDisabledPaths(AuditApplication application) {
   try {
     Long disabledPathsId = application.getDisabledPathsId();
     Set<String> disabledPaths = (Set<String>) propertyValueDAO.getPropertyById(disabledPathsId);
     return new HashSet<String>(disabledPaths);
   } catch (Throwable e) {
     // Might be an invalid ID, somehow
     auditModelRegistry.loadAuditModels();
     throw new AlfrescoRuntimeException(
         "Unabled to get AuditApplication disabled paths: " + application, e);
   }
 }
예제 #8
0
 /**
  * Extracts data from a given map using data extractors from the given application.
  *
  * @param application the application providing the data extractors
  * @param values the data values from which to generate data
  * @return Returns a map of derived data keyed by full path
  * @since 3.2
  */
 private Map<String, Serializable> extractData(
     AuditApplication application, Map<String, Serializable> values) {
   Map<String, Serializable> newData = new HashMap<String, Serializable>(values.size() + 5);
   for (Map.Entry<String, Serializable> entry : values.entrySet()) {
     String path = entry.getKey();
     Serializable value = entry.getValue();
     // Get the applicable extractor
     Map<String, DataExtractor> extractors = application.getDataExtractors(path);
     for (Map.Entry<String, DataExtractor> extractorElement : extractors.entrySet()) {
       String extractorPath = extractorElement.getKey();
       DataExtractor extractor = extractorElement.getValue();
       // Check if the extraction is supported
       if (!extractor.isSupported(value)) {
         continue;
       }
       // Use the extractor to pull the value out
       final Serializable data;
       try {
         data = extractor.extractData(value);
       } catch (Throwable e) {
         throw new AlfrescoRuntimeException(
             "Failed to extract audit data: \n"
                 + "   Path:      "
                 + path
                 + "\n"
                 + "   Raw value: "
                 + value
                 + "\n"
                 + "   Extractor: "
                 + extractor,
             e);
       }
       // Add it to the map
       newData.put(extractorPath, data);
     }
   }
   // Done
   if (logger.isDebugEnabled()) {
     logger.debug(
         "Extracted audit data: \n"
             + "   Application: "
             + application
             + "\n"
             + "   Raw values:  "
             + values
             + "\n"
             + "   Extracted: "
             + newData);
   }
   return newData;
 }
예제 #9
0
  /**
   * {@inheritDoc}
   *
   * @since 3.2
   */
  public void disableAudit(String applicationName, String path) {
    ParameterCheck.mandatory("applicationName", applicationName);
    ParameterCheck.mandatory("path", path);
    AlfrescoTransactionSupport.checkTransactionReadState(true);

    AuditApplication application = auditModelRegistry.getAuditApplicationByName(applicationName);
    if (application == null) {
      if (logger.isDebugEnabled()) {
        logger.debug("No audit application named '" + applicationName + "' has been registered.");
      }
      return;
    }
    // Check the path against the application
    application.checkPath(path);

    Long disabledPathsId = application.getDisabledPathsId();
    Set<String> disabledPaths = getDisabledPaths(application);

    // Shortcut if the disabled paths contain the exact path
    if (disabledPaths.contains(path)) {
      if (logger.isDebugEnabled()) {
        logger.debug("Audit disable path already present: \n" + "   Path:       " + path);
      }
      return;
    }

    // Bring the set up to date by stripping out unwanted paths
    Iterator<String> iterateDisabledPaths = disabledPaths.iterator();
    while (iterateDisabledPaths.hasNext()) {
      String disabledPath = iterateDisabledPaths.next();
      if (disabledPath.startsWith(path)) {
        // We will be superceding this
        iterateDisabledPaths.remove();
      } else if (path.startsWith(disabledPath)) {
        // There is already a superceding path
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Audit disable path superceded: \n"
                  + "   Path:          "
                  + path
                  + "\n"
                  + "   Superceded by: "
                  + disabledPath);
        }
        return;
      }
    }
    // Add our path in
    disabledPaths.add(path);
    // Upload the new set
    propertyValueDAO.updateProperty(disabledPathsId, (Serializable) disabledPaths);
    // Done
    if (logger.isDebugEnabled()) {
      logger.debug(
          "Audit disabled paths updated: \n"
              + "   Application: "
              + applicationName
              + "\n"
              + "   Disabled:    "
              + disabledPaths);
    }
  }
예제 #10
0
  /**
   * Audit values for a given application. No path checking is done.
   *
   * @param application the audit application to audit to
   * @param disabledPaths the application's disabled paths
   * @param values the values to store keyed by <b>full paths</b>.
   * @return Returns all values as audited
   */
  private Map<String, Serializable> audit(
      final AuditApplication application,
      Set<String> disabledPaths,
      final Map<String, Serializable> values) {
    // Get the model ID for the application
    Long applicationId = application.getApplicationId();
    if (applicationId == null) {
      throw new AuditException(
          "No persisted instance exists for audit application: " + application);
    }

    // Eliminate any paths that have been disabled
    Iterator<String> pathedValuesKeyIterator = values.keySet().iterator();
    while (pathedValuesKeyIterator.hasNext()) {
      String pathedValueKey = pathedValuesKeyIterator.next();
      for (String disabledPath : disabledPaths) {
        if (pathedValueKey.startsWith(disabledPath)) {
          // The pathed value is excluded
          pathedValuesKeyIterator.remove();
        }
      }
    }
    // Check if there is anything left
    if (values.size() == 0) {
      if (logger.isDebugEnabled()) {
        logger.debug(
            "Audit values have all been excluded by disabled paths: \n"
                + "   Application: "
                + application
                + "\n"
                + "   Values:      "
                + values);
      }
      return Collections.emptyMap();
    }

    // Generate data
    Map<String, DataGenerator> generators = application.getDataGenerators(values.keySet());
    Map<String, Serializable> auditData = generateData(generators);

    // Now extract values
    Map<String, Serializable> extractedData =
        AuthenticationUtil.runAs(
            new RunAsWork<Map<String, Serializable>>() {
              public Map<String, Serializable> doWork() throws Exception {
                return extractData(application, values);
              }
            },
            AuthenticationUtil.getSystemUserName());

    // Combine extracted and generated values (extracted data takes precedence)
    auditData.putAll(extractedData);

    // Time and username are intrinsic
    long time = System.currentTimeMillis();
    String username = AuthenticationUtil.getFullyAuthenticatedUser();

    Long entryId = null;
    if (!auditData.isEmpty()) {
      // Persist the values
      entryId = auditDAO.createAuditEntry(applicationId, time, username, auditData);
    }

    // Done
    if (logger.isDebugEnabled()) {
      logger.debug(
          "New audit entry: \n"
              + "   Application ID: "
              + applicationId
              + "\n"
              + "   Entry ID:       "
              + entryId
              + "\n"
              + "   Values:         "
              + values
              + "\n"
              + "   Audit Data:     "
              + auditData);
    }
    return auditData;
  }