001/*
002 * Copyright 2011-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2011-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2011-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk.unboundidds.tasks;
037
038
039
040import java.util.ArrayList;
041import java.util.Arrays;
042import java.util.Collections;
043import java.util.Date;
044import java.util.LinkedHashMap;
045import java.util.LinkedList;
046import java.util.List;
047import java.util.Map;
048
049import com.unboundid.ldap.sdk.Attribute;
050import com.unboundid.ldap.sdk.Entry;
051import com.unboundid.ldap.sdk.Filter;
052import com.unboundid.ldap.sdk.LDAPException;
053import com.unboundid.util.NotMutable;
054import com.unboundid.util.NotNull;
055import com.unboundid.util.Nullable;
056import com.unboundid.util.StaticUtils;
057import com.unboundid.util.ThreadSafety;
058import com.unboundid.util.ThreadSafetyLevel;
059import com.unboundid.util.Validator;
060import com.unboundid.util.args.DurationArgument;
061
062import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
063
064
065
066/**
067 * This class defines a Directory Server task that can be used to cause the
068 * server to initiate a data security audit, which can look for potential
069 * issues in the environment that can impact the security of the directory
070 * environment.
071 * <BR>
072 * <BLOCKQUOTE>
073 *   <B>NOTE:</B>  This class, and other classes within the
074 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
075 *   supported for use against Ping Identity, UnboundID, and
076 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
077 *   for proprietary functionality or for external specifications that are not
078 *   considered stable or mature enough to be guaranteed to work in an
079 *   interoperable way with other types of LDAP servers.
080 * </BLOCKQUOTE>
081 * <BR>
082 * The properties that are available for use with this type of task include:
083 * <UL>
084 *   <LI>The names of the auditors to include or exclude from the audit.  This
085 *       is optional, and if it is not provided, then all enabled auditors will
086 *       be used.</LI>
087 *   <LI>The backend IDs for the backends containing the data to be audited.
088 *       This is optional, and if it is not provided then the server will run
089 *       the audit in all backends that support this capability.</LI>
090 *   <LI>A set of filters which identify the entries that should be examined by
091 *       the audit.  This is optional, and if it is not provided, then all
092 *       entries in the selected backends will be included.</LI>
093 *   <LI>The path to the directory in which the output files should be
094 *       generated.  This is optional, and if it is not provided then the server
095 *       will use a default output directory.</LI>
096 *   <LI>The minimum number of previous reports to retain.</LI>
097 *   <LI>The minimum age of previous reports to retain.</LI>
098 * </UL>
099 */
100@NotMutable()
101@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
102public final class AuditDataSecurityTask
103       extends Task
104{
105  /**
106   * The fully-qualified name of the Java class that is used for the audit data
107   * security task.
108   */
109  @NotNull static final String AUDIT_DATA_SECURITY_TASK_CLASS =
110       "com.unboundid.directory.server.tasks.AuditDataSecurityTask";
111
112
113
114  /**
115   * The name of the attribute used to the backend IDs for the backends in which
116   * the audit should be performed.
117   */
118  @NotNull private static final String ATTR_BACKEND_ID =
119       "ds-task-audit-data-security-backend-id";
120
121
122
123  /**
124   * The name of the attribute used to specify the set of auditors that should
125   * not be used when examining the data.
126   */
127  @NotNull private static final String ATTR_EXCLUDE_AUDITOR =
128       "ds-task-audit-data-security-exclude-auditor";
129
130
131
132  /**
133   * The name of the attribute used to specify the set of auditors to use to
134   * examine the data.
135   */
136  @NotNull private static final String ATTR_INCLUDE_AUDITOR =
137       "ds-task-audit-data-security-include-auditor";
138
139
140
141  /**
142   * The name of the attribute used to specify the directory in which the report
143   * output files should be written.
144   */
145  @NotNull private static final String ATTR_OUTPUT_DIRECTORY =
146       "ds-task-audit-data-security-output-directory";
147
148
149
150  /**
151   * The name of the attribute used to specify a set of filters that should be
152   * used to identify entries to include in the audit.
153   */
154  @NotNull private static final String ATTR_REPORT_FILTER =
155       "ds-task-audit-data-security-report-filter";
156
157
158
159  /**
160   * The name of the attribute used to specify the minimum age of previous
161   * reports that should be retained.
162   */
163  @NotNull private static final String ATTR_RETAIN_AGE =
164       "ds-task-audit-data-security-retain-previous-report-age";
165
166
167
168  /**
169   * The name of the attribute used to specify the minimum number of previous
170   * reports that should be retained.
171   */
172  @NotNull private static final String ATTR_RETAIN_COUNT =
173       "ds-task-audit-data-security-retain-previous-report-count";
174
175
176
177  /**
178   * The name of the object class used in audit data security task entries.
179   */
180  @NotNull private static final String OC_AUDIT_DATA_SECURITY_TASK =
181       "ds-task-audit-data-security";
182
183
184
185  /**
186   * The task property that will be used for the backend IDs.
187   */
188  @NotNull private static final TaskProperty PROPERTY_BACKEND_ID =
189       new TaskProperty(ATTR_BACKEND_ID,
190            INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_BACKEND_ID.get(),
191            INFO_AUDIT_DATA_SECURITY_DESCRIPTION_BACKEND_ID.get(),
192            String.class, false, true, false);
193
194
195
196  /**
197   * The task property that will be used for the excluded set of auditors.
198   */
199  @NotNull private static final TaskProperty PROPERTY_EXCLUDE_AUDITOR =
200       new TaskProperty(ATTR_EXCLUDE_AUDITOR,
201            INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_EXCLUDE_AUDITOR.get(),
202            INFO_AUDIT_DATA_SECURITY_DESCRIPTION_EXCLUDE_AUDITOR.get(),
203            String.class, false, true, false);
204
205
206
207  /**
208   * The task property that will be used for the included set of auditors.
209   */
210  @NotNull private static final TaskProperty PROPERTY_INCLUDE_AUDITOR =
211       new TaskProperty(ATTR_INCLUDE_AUDITOR,
212            INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_INCLUDE_AUDITOR.get(),
213            INFO_AUDIT_DATA_SECURITY_DESCRIPTION_INCLUDE_AUDITOR.get(),
214            String.class, false, true, false);
215
216
217
218  /**
219   * The task property that will be used for the output directory.
220   */
221  @NotNull private static final TaskProperty PROPERTY_OUTPUT_DIRECTORY =
222       new TaskProperty(ATTR_OUTPUT_DIRECTORY,
223            INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_OUTPUT_DIR.get(),
224            INFO_AUDIT_DATA_SECURITY_DESCRIPTION_OUTPUT_DIR.get(),
225            String.class, false, false, false);
226
227
228
229  /**
230   * The task property that will be used for the report filters.
231   */
232  @NotNull private static final TaskProperty PROPERTY_REPORT_FILTER =
233       new TaskProperty(ATTR_REPORT_FILTER,
234            INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_REPORT_FILTER.get(),
235            INFO_AUDIT_DATA_SECURITY_DESCRIPTION_REPORT_FILTER.get(),
236            String.class, false, true, false);
237
238
239
240  /**
241   * The task property that will be used for the retain age.
242   */
243  @NotNull private static final TaskProperty PROPERTY_RETAIN_AGE =
244       new TaskProperty(ATTR_RETAIN_AGE,
245            INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_RETAIN_AGE.get(),
246            INFO_AUDIT_DATA_SECURITY_DESCRIPTION_RETAIN_AGE.get(),
247            String.class, false, false, false);
248
249
250
251  /**
252   * The task property that will be used for the retain count.
253   */
254  @NotNull private static final TaskProperty PROPERTY_RETAIN_COUNT =
255       new TaskProperty(ATTR_RETAIN_COUNT,
256            INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_RETAIN_COUNT.get(),
257            INFO_AUDIT_DATA_SECURITY_DESCRIPTION_RETAIN_COUNT.get(),
258            Long.class, false, false, false);
259
260
261
262  /**
263   * The serial version UID for this serializable class.
264   */
265  private static final long serialVersionUID = -8716946803868116214L;
266
267
268
269  // The minimum number of previous reports to retain.
270  @Nullable private final Integer retainPreviousReportCount;
271
272  // The backend IDs of the backends in which the audit should be performed.
273  @NotNull private final List<String> backendIDs;
274
275  // The names of the excluded auditors to use in the audit.
276  @NotNull private final List<String> excludeAuditors;
277
278  // The names of the included auditors to use in the audit.
279  @NotNull private final List<String> includeAuditors;
280
281  // The report filters to select entries to audit.
282  @NotNull private final List<String> reportFilters;
283
284  // The path of the output directory to use for report data files.
285  @Nullable private final String outputDirectory;
286
287  // The minimum age of previous reports to retain.
288  @Nullable private final String retainPreviousReportAge;
289
290
291
292  /**
293   * Creates a new uninitialized audit data security task instance which should
294   * only be used for obtaining general information about this task, including
295   * the task name, description, and supported properties.  Attempts to use a
296   * task created with this constructor for any other reason will likely fail.
297   */
298  public AuditDataSecurityTask()
299  {
300    excludeAuditors = null;
301    includeAuditors = null;
302    backendIDs = null;
303    reportFilters = null;
304    outputDirectory = null;
305    retainPreviousReportCount = null;
306    retainPreviousReportAge = null;
307  }
308
309
310
311  /**
312   * Creates a new audit data security task with the provided information and
313   * default settings for all general task properties.
314   *
315   * @param  includeAuditors  The names of the auditors that should be used to
316   *                          examine the data.  It may be {@code null} or empty
317   *                          if an exclude list should be provided, or if all
318   *                          enabled auditors should be invoked.  You must not
319   *                          provide both include and exclude auditors.
320   * @param  excludeAuditors  The names of the auditors that should be excluded
321   *                          when examining the data.  It may be {@code null}
322   *                          or empty if an include list should be provided, or
323   *                          if all enabled auditors should be invoked.  You
324   *                          must not provide both include and exclude
325   *                          auditors.
326   * @param  backendIDs       The backend IDs of the backends containing the
327   *                          data to examine.  It may be {@code null} or empty
328   *                          if all supported backends should be selected.
329   * @param  reportFilters    A set of filters which identify entries that
330   *                          should be examined.  It may be {@code null} or
331   *                          empty if all entries should be examined.
332   * @param  outputDirectory  The path to the output directory (on the server
333   *                          filesystem) in which report data files should be
334   *                          written.  It may be {@code null} if a default
335   *                          output directory should be used.
336   */
337  public AuditDataSecurityTask(@Nullable final List<String> includeAuditors,
338                               @Nullable final List<String> excludeAuditors,
339                               @Nullable final List<String> backendIDs,
340                               @Nullable final List<String> reportFilters,
341                               @Nullable final String outputDirectory)
342  {
343    this(null, includeAuditors, excludeAuditors, backendIDs, reportFilters,
344         outputDirectory, null, null, null, null, null);
345  }
346
347
348
349  /**
350   * Creates a new audit data security task with the provided information.
351   *
352   * @param  taskID                  The task ID to use for this task.  If it is
353   *                                 {@code null} then a UUID will be generated
354   *                                 for use as the task ID.
355   * @param  includeAuditors         The names of the auditors that should be
356   *                                 used to examine the data.  It may be
357   *                                 {@code null} or empty if an exclude list
358   *                                 should be provided, or if all enabled
359   *                                 auditors should be invoked.  You must not
360   *                                 provide both include and exclude auditors.
361   * @param  excludeAuditors         The names of the auditors that should be
362   *                                 excluded when examining the data.  It may
363   *                                 be {@code null} or empty if an include list
364   *                                 should be provided, or if all enabled
365   *                                 auditors should be invoked.  You must not
366   *                                 provide both include and exclude auditors.
367   * @param  backendIDs              The backend IDs of the backends containing
368   *                                 the data to examine.  It may be
369   *                                 {@code null} or empty if all supported
370   *                                 backends should be selected.
371   * @param  reportFilters           A set of filters which identify entries
372   *                                 that should be examined.  It may be
373   *                                 {@code null} or empty if all entries should
374   *                                 be examined.
375   * @param  outputDirectory         The path to the output directory (on the
376   *                                 server filesystem) in which report data
377   *                                 files should be written.  It may be
378   *                                 {@code null} if a default output directory
379   *                                 should be used.
380   * @param  scheduledStartTime      The time that this task should start
381   *                                 running.
382   * @param  dependencyIDs           The list of task IDs that will be required
383   *                                 to complete before this task will be
384   *                                 eligible to start.
385   * @param  failedDependencyAction  Indicates what action should be taken if
386   *                                 any of the dependencies for this task do
387   *                                 not complete successfully.
388   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
389   *                                 that should be notified when this task
390   *                                 completes.
391   * @param  notifyOnError           The list of e-mail addresses of individuals
392   *                                 that should be notified if this task does
393   *                                 not complete successfully.
394   */
395  public AuditDataSecurityTask(@Nullable final String taskID,
396              @Nullable final List<String> includeAuditors,
397              @Nullable final List<String> excludeAuditors,
398              @Nullable final List<String> backendIDs,
399              @Nullable final List<String> reportFilters,
400              @Nullable final String outputDirectory,
401              @Nullable final Date scheduledStartTime,
402              @Nullable final List<String> dependencyIDs,
403              @Nullable final FailedDependencyAction failedDependencyAction,
404              @Nullable final List<String> notifyOnCompletion,
405              @Nullable final List<String> notifyOnError)
406  {
407    this(taskID, includeAuditors, excludeAuditors, backendIDs, reportFilters,
408         outputDirectory, scheduledStartTime, dependencyIDs,
409         failedDependencyAction, null, notifyOnCompletion, null,
410         notifyOnError, null, null, null);
411  }
412
413
414
415  /**
416   * Creates a new audit data security task with the provided information.
417   *
418   * @param  taskID                  The task ID to use for this task.  If it is
419   *                                 {@code null} then a UUID will be generated
420   *                                 for use as the task ID.
421   * @param  includeAuditors         The names of the auditors that should be
422   *                                 used to examine the data.  It may be
423   *                                 {@code null} or empty if an exclude list
424   *                                 should be provided, or if all enabled
425   *                                 auditors should be invoked.  You must not
426   *                                 provide both include and exclude auditors.
427   * @param  excludeAuditors         The names of the auditors that should be
428   *                                 excluded when examining the data.  It may
429   *                                 be {@code null} or empty if an include list
430   *                                 should be provided, or if all enabled
431   *                                 auditors should be invoked.  You must not
432   *                                 provide both include and exclude auditors.
433   * @param  backendIDs              The backend IDs of the backends containing
434   *                                 the data to examine.  It may be
435   *                                 {@code null} or empty if all supported
436   *                                 backends should be selected.
437   * @param  reportFilters           A set of filters which identify entries
438   *                                 that should be examined.  It may be
439   *                                 {@code null} or empty if all entries should
440   *                                 be examined.
441   * @param  outputDirectory         The path to the output directory (on the
442   *                                 server filesystem) in which report data
443   *                                 files should be written.  It may be
444   *                                 {@code null} if a default output directory
445   *                                 should be used.
446   * @param  scheduledStartTime      The time that this task should start
447   *                                 running.
448   * @param  dependencyIDs           The list of task IDs that will be required
449   *                                 to complete before this task will be
450   *                                 eligible to start.
451   * @param  failedDependencyAction  Indicates what action should be taken if
452   *                                 any of the dependencies for this task do
453   *                                 not complete successfully.
454   * @param  notifyOnStart           The list of e-mail addresses of individuals
455   *                                 that should be notified when this task
456   *                                 starts running.
457   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
458   *                                 that should be notified when this task
459   *                                 completes.
460   * @param  notifyOnSuccess         The list of e-mail addresses of individuals
461   *                                 that should be notified if this task
462   *                                 completes successfully.
463   * @param  notifyOnError           The list of e-mail addresses of individuals
464   *                                 that should be notified if this task does
465   *                                 not complete successfully.
466   * @param  alertOnStart            Indicates whether the server should send an
467   *                                 alert notification when this task starts.
468   * @param  alertOnSuccess          Indicates whether the server should send an
469   *                                 alert notification if this task completes
470   *                                 successfully.
471   * @param  alertOnError            Indicates whether the server should send an
472   *                                 alert notification if this task fails to
473   *                                 complete successfully.
474   */
475  public AuditDataSecurityTask(@Nullable final String taskID,
476              @Nullable final List<String> includeAuditors,
477              @Nullable final List<String> excludeAuditors,
478              @Nullable final List<String> backendIDs,
479              @Nullable final List<String> reportFilters,
480              @Nullable final String outputDirectory,
481              @Nullable final Date scheduledStartTime,
482              @Nullable final List<String> dependencyIDs,
483              @Nullable final FailedDependencyAction failedDependencyAction,
484              @Nullable final List<String> notifyOnStart,
485              @Nullable final List<String> notifyOnCompletion,
486              @Nullable final List<String> notifyOnSuccess,
487              @Nullable final List<String> notifyOnError,
488              @Nullable final Boolean alertOnStart,
489              @Nullable final Boolean alertOnSuccess,
490              @Nullable final Boolean alertOnError)
491  {
492    this(taskID, includeAuditors, excludeAuditors, backendIDs, reportFilters,
493         outputDirectory, null, null, scheduledStartTime, dependencyIDs,
494         failedDependencyAction, notifyOnStart, notifyOnCompletion,
495         notifyOnSuccess, notifyOnError, alertOnStart, alertOnSuccess,
496         alertOnError);
497  }
498
499
500
501  /**
502   * Creates a new audit data security task with the provided information.
503   *
504   * @param  taskID                      The task ID to use for this task.  If
505   *                                     it is {@code null} then a UUID will be
506   *                                     generated for use as the task ID.
507   * @param  includeAuditors             The names of the auditors that should
508   *                                     be used to examine the data.  It may be
509   *                                     {@code null} or empty if an exclude
510   *                                     list should be provided, or if all
511   *                                     enabled auditors should be invoked.
512   *                                     You must not provide both include and
513   *                                     exclude auditors.
514   * @param  excludeAuditors             The names of the auditors that should
515   *                                     be excluded when examining the data.
516   *                                     It may be {@code null} or empty if an
517   *                                     include list should be provided, or if
518   *                                     all enabled auditors should be invoked.
519   *                                     You must not provide both include and
520   *                                     exclude auditors.
521   * @param  backendIDs                  The backend IDs of the backends
522   *                                     containing the data to examine.  It may
523   *                                     be {@code null} or empty if all
524   *                                     supported backends should be selected.
525   * @param  reportFilters               A set of filters which identify entries
526   *                                     that should be examined.  It may be
527   *                                     {@code null} or empty if all entries
528   *                                     should be examined.
529   * @param  outputDirectory             The path to the output directory (on
530   *                                     the server filesystem) in which report
531   *                                     data files should be written.  It may
532   *                                     be {@code null} if a default output
533   *                                     directory should be used.
534   * @param  retainPreviousReportCount   The minimum number of previous reports
535   *                                     to retain.
536   * @param  retainPreviousReportAge     A string representation of the minimum
537   *                                     age of previous reports to retain.  The
538   *                                     age should be formatted in the same way
539   *                                     as values for the
540   *                                     {@link DurationArgument} class.
541   * @param  scheduledStartTime          The time that this task should start
542   *                                     running.
543   * @param  dependencyIDs               The list of task IDs that will be
544   *                                     required to complete before this task
545   *                                     will be eligible to start.
546   * @param  failedDependencyAction      Indicates what action should be taken
547   *                                     if any of the dependencies for this
548   *                                     task do not complete successfully.
549   * @param  notifyOnStart               The list of e-mail addresses of
550   *                                     individuals that should be notified
551   *                                     when this task starts running.
552   * @param  notifyOnCompletion          The list of e-mail addresses of
553   *                                     individuals that should be notified
554   *                                     when this task completes.
555   * @param  notifyOnSuccess             The list of e-mail addresses of
556   *                                     individuals that should be notified if
557   *                                     this task completes successfully.
558   * @param  notifyOnError               The list of e-mail addresses of
559   *                                     individuals that should be notified if
560   *                                     this task does not complete
561   *                                     successfully.
562   * @param  alertOnStart                Indicates whether the server should
563   *                                     send an alert notification when this
564   *                                     task starts.
565   * @param  alertOnSuccess              Indicates whether the server should
566   *                                     send an alert notification if this task
567   *                                     completes successfully.
568   * @param  alertOnError                Indicates whether the server should
569   *                                     send an alert notification if this task
570   *                                     fails to complete successfully.
571   */
572  public AuditDataSecurityTask(@Nullable final String taskID,
573              @Nullable final List<String> includeAuditors,
574              @Nullable final List<String> excludeAuditors,
575              @Nullable final List<String> backendIDs,
576              @Nullable final List<String> reportFilters,
577              @Nullable final String outputDirectory,
578              @Nullable final Integer retainPreviousReportCount,
579              @Nullable final String retainPreviousReportAge,
580              @Nullable final Date scheduledStartTime,
581              @Nullable final List<String> dependencyIDs,
582              @Nullable final FailedDependencyAction failedDependencyAction,
583              @Nullable final List<String> notifyOnStart,
584              @Nullable final List<String> notifyOnCompletion,
585              @Nullable final List<String> notifyOnSuccess,
586              @Nullable final List<String> notifyOnError,
587              @Nullable final Boolean alertOnStart,
588              @Nullable final Boolean alertOnSuccess,
589              @Nullable final Boolean alertOnError)
590  {
591    super(taskID, AUDIT_DATA_SECURITY_TASK_CLASS, scheduledStartTime,
592         dependencyIDs, failedDependencyAction, notifyOnStart,
593         notifyOnCompletion, notifyOnSuccess, notifyOnError, alertOnStart,
594         alertOnSuccess, alertOnError);
595
596    this.includeAuditors = getStringList(includeAuditors);
597    this.excludeAuditors = getStringList(excludeAuditors);
598    this.backendIDs = getStringList(backendIDs);
599    this.reportFilters = getStringList(reportFilters);
600    this.outputDirectory = outputDirectory;
601    this.retainPreviousReportCount = retainPreviousReportCount;
602    this.retainPreviousReportAge = retainPreviousReportAge;
603
604    Validator.ensureTrue(
605         (this.includeAuditors.isEmpty() || this.excludeAuditors.isEmpty()),
606         "You cannot request both include and exclude auditors.");
607  }
608
609
610
611  /**
612   * Creates a new audit data security task from the provided entry.
613   *
614   * @param  entry  The entry to use to create this audit data security task.
615   *
616   * @throws  TaskException  If the provided entry cannot be parsed as an audit
617   *                         data security task entry.
618   */
619  public AuditDataSecurityTask(@NotNull final Entry entry)
620         throws TaskException
621  {
622    super(entry);
623
624    includeAuditors = Collections.unmodifiableList(StaticUtils.toNonNullList(
625         entry.getAttributeValues(ATTR_INCLUDE_AUDITOR)));
626    excludeAuditors = Collections.unmodifiableList(StaticUtils.toNonNullList(
627         entry.getAttributeValues(ATTR_EXCLUDE_AUDITOR)));
628    backendIDs = Collections.unmodifiableList(StaticUtils.toNonNullList(
629         entry.getAttributeValues(ATTR_BACKEND_ID)));
630    reportFilters = Collections.unmodifiableList(StaticUtils.toNonNullList(
631         entry.getAttributeValues(ATTR_REPORT_FILTER)));
632    outputDirectory = entry.getAttributeValue(ATTR_OUTPUT_DIRECTORY);
633    retainPreviousReportCount =
634         entry.getAttributeValueAsInteger(ATTR_RETAIN_COUNT);
635    retainPreviousReportAge =  entry.getAttributeValue(ATTR_RETAIN_AGE);
636  }
637
638
639
640  /**
641   * Creates a new audit data security task from the provided set of task
642   * properties.
643   *
644   * @param  properties  The set of task properties and their corresponding
645   *                     values to use for the task.  It must not be
646   *                     {@code null}.
647   *
648   * @throws  TaskException  If the provided set of properties cannot be used to
649   *                         create a valid audit data security task.
650   */
651  public AuditDataSecurityTask(
652              @NotNull final Map<TaskProperty,List<Object>> properties)
653         throws TaskException
654  {
655    super(AUDIT_DATA_SECURITY_TASK_CLASS, properties);
656
657    Integer retainCount = null;
658    String outputDir = null;
659    String retainAge = null;
660    final LinkedList<String> includeAuditorsList = new LinkedList<>();
661    final LinkedList<String> excludeAuditorsList = new LinkedList<>();
662    final LinkedList<String> backendIDList       = new LinkedList<>();
663    final LinkedList<String> reportFilterList    = new LinkedList<>();
664    for (final Map.Entry<TaskProperty,List<Object>> entry :
665         properties.entrySet())
666    {
667      final TaskProperty p = entry.getKey();
668      final String attrName = StaticUtils.toLowerCase(p.getAttributeName());
669      final List<Object> values = entry.getValue();
670
671      if (attrName.equals(ATTR_INCLUDE_AUDITOR))
672      {
673        final String[] s = parseStrings(p, values, null);
674        if (s != null)
675        {
676          includeAuditorsList.addAll(Arrays.asList(s));
677        }
678      }
679      else if (attrName.equals(ATTR_EXCLUDE_AUDITOR))
680      {
681        final String[] s = parseStrings(p, values, null);
682        if (s != null)
683        {
684          excludeAuditorsList.addAll(Arrays.asList(s));
685        }
686      }
687      else if (attrName.equals(ATTR_BACKEND_ID))
688      {
689        final String[] s = parseStrings(p, values, null);
690        if (s != null)
691        {
692          backendIDList.addAll(Arrays.asList(s));
693        }
694      }
695      else if (attrName.equals(ATTR_REPORT_FILTER))
696      {
697        final String[] s = parseStrings(p, values, null);
698        if (s != null)
699        {
700          reportFilterList.addAll(Arrays.asList(s));
701        }
702      }
703      else if (attrName.equals(ATTR_OUTPUT_DIRECTORY))
704      {
705        outputDir = parseString(p, values, null);
706      }
707      else if (attrName.equalsIgnoreCase(ATTR_RETAIN_COUNT))
708      {
709        final Long retainCountLong = parseLong(p, values, null);
710        if (retainCountLong == null)
711        {
712          retainCount = null;
713        }
714        else
715        {
716          retainCount = retainCountLong.intValue();
717        }
718      }
719      else if (attrName.equalsIgnoreCase(ATTR_RETAIN_AGE))
720      {
721        retainAge = parseString(p, values, retainAge);
722      }
723    }
724
725    includeAuditors = Collections.unmodifiableList(includeAuditorsList);
726    excludeAuditors = Collections.unmodifiableList(excludeAuditorsList);
727    backendIDs = Collections.unmodifiableList(backendIDList);
728    reportFilters = Collections.unmodifiableList(reportFilterList);
729    outputDirectory = outputDir;
730    retainPreviousReportCount = retainCount;
731    retainPreviousReportAge = retainAge;
732
733    if ((! includeAuditors.isEmpty()) && (! excludeAuditors.isEmpty()))
734    {
735      throw new TaskException(
736           ERR_AUDIT_DATA_SECURITY_BOTH_INCLUDE_AND_EXCLUDE_AUDITORS.get());
737    }
738  }
739
740
741
742  /**
743   * {@inheritDoc}
744   */
745  @Override()
746  @NotNull()
747  public String getTaskName()
748  {
749    return INFO_TASK_NAME_AUDIT_DATA_SECURITY.get();
750  }
751
752
753
754  /**
755   * {@inheritDoc}
756   */
757  @Override()
758  @NotNull()
759  public String getTaskDescription()
760  {
761    return INFO_TASK_DESCRIPTION_AUDIT_DATA_SECURITY.get();
762  }
763
764
765
766  /**
767   * Retrieves the names of the auditors that should be invoked during the
768   * data security audit.
769   *
770   * @return  The names of the include auditors that should be used for the
771   *          task, or an empty list if either an exclude list should be used or
772   *          all enabled auditors should be used.
773   */
774  @NotNull()
775  public List<String> getIncludeAuditors()
776  {
777    return includeAuditors;
778  }
779
780
781
782  /**
783   * Retrieves the names of the auditors that should not be invoked during the
784   * audit.
785   *
786   * @return  The names of the exclude auditors that should be used for the
787   *          task, or an empty list if either an include list should be used or
788   *          all enabled auditors should be used.
789   */
790  @NotNull()
791  public List<String> getExcludeAuditors()
792  {
793    return excludeAuditors;
794  }
795
796
797
798  /**
799   * Retrieves the backend IDs of the backends that should be examined during
800   * the course of the audit.
801   *
802   * @return  The backend IDs of the backends that should be examined during the
803   *          course of the audit, or an empty list if all backends that support
804   *          this capability should be used.
805   */
806  @NotNull()
807  public List<String> getBackendIDs()
808  {
809    return backendIDs;
810  }
811
812
813
814  /**
815   * Retrieves the string representations of the report filters that should be
816   * used to identify which entries should be examined during the course of the
817   * audit.
818   *
819   * @return  The string representations of the report filters that should be
820   *          used to identify which entries should be examined during the
821   *          course of the audit, or an empty list if all entries should be
822   *          examined.
823   */
824  @NotNull()
825  public List<String> getReportFilterStrings()
826  {
827    return reportFilters;
828  }
829
830
831
832  /**
833   * Retrieves the parsed report filters that should be used to identify which
834   * entries should be examined during the course of the audit.
835   *
836   * @return  The parsed report filters that should be used to identify which
837   *          entries should be examined during the course of the audit, or an
838   *          empty list if all entries should be examined.
839   *
840   * @throws  LDAPException  If any of the filter strings cannot be parsed as a
841   *                         valid filter.
842   */
843  @NotNull()
844  public List<Filter> getReportFilters()
845         throws LDAPException
846  {
847    if (reportFilters.isEmpty())
848    {
849      return Collections.emptyList();
850    }
851
852    final ArrayList<Filter> filterList = new ArrayList<>(reportFilters.size());
853    for (final String filter : reportFilters)
854    {
855      filterList.add(Filter.create(filter));
856    }
857    return Collections.unmodifiableList(filterList);
858  }
859
860
861
862  /**
863   * Retrieves the path to the directory on the server filesystem in which the
864   * report output files should be written.
865   *
866   * @return  The path to the directory on the server filesystem in which the
867   *          report output files should be written.
868   */
869  @Nullable()
870  public String getOutputDirectory()
871  {
872    return outputDirectory;
873  }
874
875
876
877  /**
878   * Retrieves the minimum number of previous audit data security reports that
879   * should be retained on the server after creating the new report, and any
880   * other reports may be candidates for removal.
881   * <BR><BR>
882   * If neither a retain count nor a retain age is specified, then no attempt
883   * will be made to remove any previous reports.  If both a retain count and a
884   * retain age are specified, then only reports that fall outside both sets of
885   * criteria will be candidates for removal.
886   * <BR><BR>
887   * Retention functionality may only be used if the output directory is named
888   * with a valid timestamp formatted in accordance with the generalized time
889   * syntax.  In such cases, any reports contained in a directory that are a
890   * peer of the specified output directory whose names are also valid
891   * timestamps will be considered.  If any previous reports are to be removed,
892   * they will be removed in chronological order from oldest to youngest.
893   *
894   * @return  The minimum number of previous audit data security reports that
895   *          should be retained after creating the new report, or {@code null}
896   *          if no retain count has been specified.
897   */
898  @Nullable()
899  public Integer getRetainPreviousReportCount()
900  {
901    return retainPreviousReportCount;
902  }
903
904
905
906  /**
907   * Retrieves the minimum age of previous audit data security reports that
908   * should be retained on the server after creating the new report, and any
909   * other reports may be candidates for removal.  The age should be specified
910   * as a duration in a format compatible with the {@link DurationArgument}
911   * class (that is, an integer followed by a time unit).
912   * <BR><BR>
913   * If neither a retain count nor a retain age is specified, then no attempt
914   * will be made to remove any previous reports.  If both a retain count and a
915   * retain age are specified, then only reports that fall outside both sets of
916   * criteria will be candidates for removal.
917   * <BR><BR>
918   * Retention functionality may only be used if the output directory is named
919   * with a valid timestamp formatted in accordance with the generalized time
920   * syntax.  In such cases, any reports contained in a directory that are a
921   * peer of the specified output directory whose names are also valid
922   * timestamps will be considered.  If any previous reports are to be removed,
923   * they will be removed in chronological order from oldest to youngest.
924   *
925   * @return  The minimum length of time to retain previous audit data security
926   *          reports after creating the new report, or {@code null} if no
927   *          retain age has been specified.
928   */
929  @Nullable()
930  public String getRetainPreviousReportAge()
931  {
932    return retainPreviousReportAge;
933  }
934
935
936
937  /**
938   * {@inheritDoc}
939   */
940  @Override()
941  @NotNull()
942  protected List<String> getAdditionalObjectClasses()
943  {
944    return Collections.singletonList(OC_AUDIT_DATA_SECURITY_TASK);
945  }
946
947
948
949  /**
950   * {@inheritDoc}
951   */
952  @Override()
953  @NotNull()
954  protected List<Attribute> getAdditionalAttributes()
955  {
956    final LinkedList<Attribute> attrList = new LinkedList<>();
957
958    if (! includeAuditors.isEmpty())
959    {
960      attrList.add(new Attribute(ATTR_INCLUDE_AUDITOR, includeAuditors));
961    }
962
963    if (! excludeAuditors.isEmpty())
964    {
965      attrList.add(new Attribute(ATTR_EXCLUDE_AUDITOR, excludeAuditors));
966    }
967
968    if (! backendIDs.isEmpty())
969    {
970      attrList.add(new Attribute(ATTR_BACKEND_ID, backendIDs));
971    }
972
973    if (! reportFilters.isEmpty())
974    {
975      attrList.add(new Attribute(ATTR_REPORT_FILTER, reportFilters));
976    }
977
978    if (outputDirectory != null)
979    {
980      attrList.add(new Attribute(ATTR_OUTPUT_DIRECTORY, outputDirectory));
981    }
982
983    if (retainPreviousReportCount != null)
984    {
985      attrList.add(new Attribute(ATTR_RETAIN_COUNT,
986           String.valueOf(retainPreviousReportCount)));
987    }
988
989    if (retainPreviousReportAge != null)
990    {
991      attrList.add(new Attribute(ATTR_RETAIN_AGE, retainPreviousReportAge));
992    }
993
994    return attrList;
995  }
996
997
998
999  /**
1000   * {@inheritDoc}
1001   */
1002  @Override()
1003  @NotNull()
1004  public List<TaskProperty> getTaskSpecificProperties()
1005  {
1006    return Collections.unmodifiableList(Arrays.asList(
1007         PROPERTY_INCLUDE_AUDITOR,
1008         PROPERTY_EXCLUDE_AUDITOR,
1009         PROPERTY_BACKEND_ID,
1010         PROPERTY_REPORT_FILTER,
1011         PROPERTY_OUTPUT_DIRECTORY,
1012         PROPERTY_RETAIN_COUNT,
1013         PROPERTY_RETAIN_AGE));
1014  }
1015
1016
1017
1018  /**
1019   * {@inheritDoc}
1020   */
1021  @Override()
1022  @NotNull()
1023  public Map<TaskProperty,List<Object>> getTaskPropertyValues()
1024  {
1025    final LinkedHashMap<TaskProperty,List<Object>> props =
1026         new LinkedHashMap<>(StaticUtils.computeMapCapacity(5));
1027
1028    if (! includeAuditors.isEmpty())
1029    {
1030      props.put(PROPERTY_INCLUDE_AUDITOR,
1031           Collections.<Object>unmodifiableList(includeAuditors));
1032    }
1033
1034    if (! excludeAuditors.isEmpty())
1035    {
1036      props.put(PROPERTY_EXCLUDE_AUDITOR,
1037           Collections.<Object>unmodifiableList(excludeAuditors));
1038    }
1039
1040    if (! backendIDs.isEmpty())
1041    {
1042      props.put(PROPERTY_BACKEND_ID,
1043           Collections.<Object>unmodifiableList(backendIDs));
1044    }
1045
1046    if (! reportFilters.isEmpty())
1047    {
1048      props.put(PROPERTY_REPORT_FILTER,
1049           Collections.<Object>unmodifiableList(reportFilters));
1050    }
1051
1052    if (outputDirectory != null)
1053    {
1054      props.put(PROPERTY_OUTPUT_DIRECTORY,
1055           Collections.<Object>singletonList(outputDirectory));
1056    }
1057
1058    if (retainPreviousReportCount != null)
1059    {
1060      props.put(PROPERTY_RETAIN_COUNT,
1061           Collections.<Object>singletonList(
1062                retainPreviousReportCount.longValue()));
1063    }
1064
1065    if (retainPreviousReportAge != null)
1066    {
1067      props.put(PROPERTY_RETAIN_AGE,
1068           Collections.<Object>singletonList(retainPreviousReportAge));
1069    }
1070
1071    return Collections.unmodifiableMap(props);
1072  }
1073
1074
1075
1076  /**
1077   * Retrieves an unmodifiable list using information from the provided list.
1078   * If the given list is {@code null}, then an empty list will be returned.
1079   * Otherwise, an unmodifiable version of the provided list will be returned.
1080   *
1081   * @param  l  The list to be processed.
1082   *
1083   * @return  The resulting string list.
1084   */
1085  @NotNull()
1086  private static List<String> getStringList(@Nullable final List<String> l)
1087  {
1088    if (l == null)
1089    {
1090      return Collections.emptyList();
1091    }
1092    else
1093    {
1094      return Collections.unmodifiableList(l);
1095    }
1096  }
1097}