001/*
002 * Copyright 2008-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2008-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) 2008-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.Collections;
042import java.util.Date;
043import java.util.LinkedHashMap;
044import java.util.List;
045import java.util.Map;
046
047import com.unboundid.ldap.sdk.Attribute;
048import com.unboundid.ldap.sdk.Entry;
049import com.unboundid.util.NotMutable;
050import com.unboundid.util.NotNull;
051import com.unboundid.util.Nullable;
052import com.unboundid.util.StaticUtils;
053import com.unboundid.util.ThreadSafety;
054import com.unboundid.util.ThreadSafetyLevel;
055
056import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
057
058
059
060/**
061 * This class defines a Directory Server task that can be used to cause the
062 * server to enter lockdown mode, in which case it will only allow requests
063 * from users with the lockdown-mode privilege.  Lockdown mode is intended to
064 * allow administrators to perform operations with the server online but without
065 * worrying about the impact that those operations may have on other users.  In
066 * In some special cases, the server may place itself in lockdown mode as a
067 * defense mechanism rather than risking the exposure of sensitive information.
068 * For example, if the server detects any malformed access control rules at
069 * startup, then it will place itself in lockdown mode rather than attempt to
070 * run without that rule in effect since it could have been intended to prevent
071 * unauthorized users from accessing certain data.
072 * <BR>
073 * <BLOCKQUOTE>
074 *   <B>NOTE:</B>  This class, and other classes within the
075 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
076 *   supported for use against Ping Identity, UnboundID, and
077 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
078 *   for proprietary functionality or for external specifications that are not
079 *   considered stable or mature enough to be guaranteed to work in an
080 *   interoperable way with other types of LDAP servers.
081 * </BLOCKQUOTE>
082 * <BR>
083 * The enter lockdown mode task does not have any task-specific properties.  See
084 * the {@link LeaveLockdownModeTask} class for the corresponding mechanism to
085 * bring the server out of lockdown mode.
086 */
087@NotMutable()
088@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
089public final class EnterLockdownModeTask
090       extends Task
091{
092  /**
093   * The fully-qualified name of the Java class that is used for the enter
094   * lockdown mode task.
095   */
096  @NotNull static final String ENTER_LOCKDOWN_MODE_TASK_CLASS =
097       "com.unboundid.directory.server.tasks.EnterLockdownModeTask";
098
099
100
101  /**
102   * The name of the attribute used to specify the reason for putting the server
103   * into lockdown mode.
104   */
105  @NotNull private static final String ATTR_ENTER_LOCKDOWN_REASON =
106       "ds-task-enter-lockdown-reason";
107
108
109
110  /**
111   * The task property for the enter-lockdown reason.
112   */
113  @NotNull private static final TaskProperty PROPERTY_ENTER_LOCKDOWN_REASON =
114       new TaskProperty(ATTR_ENTER_LOCKDOWN_REASON,
115                        INFO_DISPLAY_NAME_ENTER_LOCKDOWN_REASON.get(),
116                        INFO_DESCRIPTION_ENTER_LOCKDOWN_REASON.get(),
117                        String.class, false, false, false);
118
119
120
121  /**
122   * The name of the object class used in enter-lockdown-mode task entries.
123   */
124  @NotNull private static final String OC_ENTER_LOCKDOWN_MODE_TASK =
125      "ds-task-enter-lockdown-mode";
126
127
128
129  /**
130   * The serial version UID for this serializable class.
131   */
132  private static final long serialVersionUID = -4104020769734351458L;
133
134
135
136  // The reason for entering lockdown mode.
137  @Nullable private final String reason;
138
139
140
141  /**
142   * Creates a new uninitialized enter lockdown mode task instance which should
143   * only be used for obtaining general information about this task, including
144   * the task name, description, and supported properties.  Attempts to use a
145   * task created with this constructor for any other reason will likely fail.
146   */
147  public EnterLockdownModeTask()
148  {
149    reason = null;
150  }
151
152
153
154  /**
155   * Creates a new enter lockdown mode task with the specified task ID.
156   *
157   * @param  taskID  The task ID to use for this task.  If it is {@code null}
158   *                 then a UUID will be generated for use as the task ID.
159   */
160  public EnterLockdownModeTask(@Nullable final String taskID)
161  {
162    this(taskID, null);
163  }
164
165
166
167  /**
168   * Creates a new enter lockdown mode task with the specified task ID.
169   *
170   * @param  taskID  The task ID to use for this task.  If it is {@code null}
171   *                 then a UUID will be generated for use as the task ID.
172   * @param  reason  The user-specified reason for entering lockdown mode. This
173   *                 may be {@code null}.
174   */
175  public EnterLockdownModeTask(@Nullable final String taskID,
176                               @Nullable final String reason)
177  {
178    this(taskID, reason, null, null, null, null, null);
179  }
180
181
182
183  /**
184   * Creates a new enter lockdown mode task with the provided information.
185   *
186   * @param  taskID                  The task ID to use for this task.  If it is
187   *                                 {@code null} then a UUID will be generated
188   *                                 for use as the task ID.
189   * @param  scheduledStartTime      The time that this task should start
190   *                                 running.
191   * @param  dependencyIDs           The list of task IDs that will be required
192   *                                 to complete before this task will be
193   *                                 eligible to start.
194   * @param  failedDependencyAction  Indicates what action should be taken if
195   *                                 any of the dependencies for this task do
196   *                                 not complete successfully.
197   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
198   *                                 that should be notified when this task
199   *                                 completes.
200   * @param  notifyOnError           The list of e-mail addresses of individuals
201   *                                 that should be notified if this task does
202   *                                 not complete successfully.
203   */
204  public EnterLockdownModeTask(@Nullable final String taskID,
205              @Nullable final Date scheduledStartTime,
206              @Nullable final List<String> dependencyIDs,
207              @Nullable final FailedDependencyAction failedDependencyAction,
208              @Nullable final List<String> notifyOnCompletion,
209              @Nullable final List<String> notifyOnError)
210  {
211    this(taskID, null, scheduledStartTime, dependencyIDs,
212         failedDependencyAction, notifyOnCompletion, notifyOnError);
213  }
214
215
216
217  /**
218   * Creates a new enter lockdown mode task with the provided information.
219   *
220   * @param  taskID                  The task ID to use for this task.  If it is
221   *                                 {@code null} then a UUID will be generated
222   *                                 for use as the task ID.
223   * @param  reason                  The user-specified reason for entering
224   *                                 lockdown mode. This may be {@code null}.
225   * @param  scheduledStartTime      The time that this task should start
226   *                                 running.
227   * @param  dependencyIDs           The list of task IDs that will be required
228   *                                 to complete before this task will be
229   *                                 eligible to start.
230   * @param  failedDependencyAction  Indicates what action should be taken if
231   *                                 any of the dependencies for this task do
232   *                                 not complete successfully.
233   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
234   *                                 that should be notified when this task
235   *                                 completes.
236   * @param  notifyOnError           The list of e-mail addresses of individuals
237   *                                 that should be notified if this task does
238   *                                 not complete successfully.
239   */
240  public EnterLockdownModeTask(@Nullable final String taskID,
241              @Nullable final String reason,
242              @Nullable final Date scheduledStartTime,
243              @Nullable final List<String> dependencyIDs,
244              @Nullable final FailedDependencyAction failedDependencyAction,
245              @Nullable final List<String> notifyOnCompletion,
246              @Nullable final List<String> notifyOnError)
247  {
248    this(taskID, reason, scheduledStartTime, dependencyIDs,
249         failedDependencyAction, null, notifyOnCompletion, null,
250         notifyOnError, null, null, null);
251  }
252
253
254
255  /**
256   * Creates a new enter lockdown mode task with the provided information.
257   *
258   * @param  taskID                  The task ID to use for this task.  If it is
259   *                                 {@code null} then a UUID will be generated
260   *                                 for use as the task ID.
261   * @param  reason                  The user-specified reason for entering
262   *                                 lockdown mode. This may be {@code null}.
263   * @param  scheduledStartTime      The time that this task should start
264   *                                 running.
265   * @param  dependencyIDs           The list of task IDs that will be required
266   *                                 to complete before this task will be
267   *                                 eligible to start.
268   * @param  failedDependencyAction  Indicates what action should be taken if
269   *                                 any of the dependencies for this task do
270   *                                 not complete successfully.
271   * @param  notifyOnStart           The list of e-mail addresses of individuals
272   *                                 that should be notified when this task
273   *                                 starts running.
274   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
275   *                                 that should be notified when this task
276   *                                 completes.
277   * @param  notifyOnSuccess         The list of e-mail addresses of individuals
278   *                                 that should be notified if this task
279   *                                 completes successfully.
280   * @param  notifyOnError           The list of e-mail addresses of individuals
281   *                                 that should be notified if this task does
282   *                                 not complete successfully.
283   * @param  alertOnStart            Indicates whether the server should send an
284   *                                 alert notification when this task starts.
285   * @param  alertOnSuccess          Indicates whether the server should send an
286   *                                 alert notification if this task completes
287   *                                 successfully.
288   * @param  alertOnError            Indicates whether the server should send an
289   *                                 alert notification if this task fails to
290   *                                 complete successfully.
291   */
292  public EnterLockdownModeTask(@Nullable final String taskID,
293              @Nullable final String reason,
294              @Nullable final Date scheduledStartTime,
295              @Nullable final List<String> dependencyIDs,
296              @Nullable final FailedDependencyAction failedDependencyAction,
297              @Nullable final List<String> notifyOnStart,
298              @Nullable final List<String> notifyOnCompletion,
299              @Nullable final List<String> notifyOnSuccess,
300              @Nullable final List<String> notifyOnError,
301              @Nullable final Boolean alertOnStart,
302              @Nullable final Boolean alertOnSuccess,
303              @Nullable final Boolean alertOnError)
304  {
305    super(taskID, ENTER_LOCKDOWN_MODE_TASK_CLASS, scheduledStartTime,
306          dependencyIDs, failedDependencyAction, notifyOnStart,
307         notifyOnCompletion, notifyOnSuccess,  notifyOnError, alertOnStart,
308         alertOnSuccess, alertOnError);
309
310    this.reason = reason;
311  }
312
313
314
315  /**
316   * Creates a new enter lockdown mode task from the provided entry.
317   *
318   * @param  entry  The entry to use to create this enter lockdown mode task.
319   *
320   * @throws  TaskException  If the provided entry cannot be parsed as an enter
321   *                         lockdown mode task entry.
322   */
323  public EnterLockdownModeTask(@NotNull final Entry entry)
324         throws TaskException
325  {
326    super(entry);
327
328    // Get the "reason" string if it is present.
329    reason = entry.getAttributeValue(ATTR_ENTER_LOCKDOWN_REASON);
330  }
331
332
333
334  /**
335   * Creates a new enter lockdown mode task from the provided set of task
336   * properties.
337   *
338   * @param  properties  The set of task properties and their corresponding
339   *                     values to use for the task.  It must not be
340   *                     {@code null}.
341   *
342   * @throws  TaskException  If the provided set of properties cannot be used to
343   *                         create a valid enter lockdown mode task.
344   */
345  public EnterLockdownModeTask(
346              @NotNull final Map<TaskProperty,List<Object>> properties)
347         throws TaskException
348  {
349    super(ENTER_LOCKDOWN_MODE_TASK_CLASS, properties);
350
351    String r = null;
352    for (final Map.Entry<TaskProperty,List<Object>> entry :
353            properties.entrySet())
354    {
355      final TaskProperty p = entry.getKey();
356      final String attrName = p.getAttributeName();
357      final List<Object> values = entry.getValue();
358
359      if (attrName.equalsIgnoreCase(ATTR_ENTER_LOCKDOWN_REASON))
360      {
361        r = parseString(p, values, null);
362        break;
363      }
364    }
365
366    reason = r;
367  }
368
369
370
371  /**
372   * Retrieves the user-specified reason why the server is entering lockdown
373   * mode.
374   *
375   * @return  The reason the server is entering lockdown mode, or {@code null}
376   *          if none was specified.
377   */
378  @Nullable()
379  public String getReason()
380  {
381    return reason;
382  }
383
384
385
386  /**
387   * {@inheritDoc}
388   */
389  @Override()
390  @NotNull()
391  public String getTaskName()
392  {
393    return INFO_TASK_NAME_ENTER_LOCKDOWN_MODE.get();
394  }
395
396
397
398  /**
399   * {@inheritDoc}
400   */
401  @Override()
402  @NotNull()
403  public String getTaskDescription()
404  {
405    return INFO_TASK_DESCRIPTION_ENTER_LOCKDOWN_MODE.get();
406  }
407
408
409
410  /**
411   * {@inheritDoc}
412   */
413  @Override()
414  @NotNull()
415  protected List<String> getAdditionalObjectClasses()
416  {
417    return Collections.singletonList(OC_ENTER_LOCKDOWN_MODE_TASK);
418  }
419
420
421
422  /**
423   * {@inheritDoc}
424   */
425  @Override()
426  @NotNull()
427  protected List<Attribute> getAdditionalAttributes()
428  {
429    final ArrayList<Attribute> attrs = new ArrayList<>(1);
430    if (reason != null)
431    {
432      attrs.add(new Attribute(ATTR_ENTER_LOCKDOWN_REASON, reason));
433    }
434    return attrs;
435  }
436
437
438
439  /**
440   * {@inheritDoc}
441   */
442  @Override()
443  @NotNull()
444  public List<TaskProperty> getTaskSpecificProperties()
445  {
446    final List<TaskProperty> propList =
447              Collections.singletonList(PROPERTY_ENTER_LOCKDOWN_REASON);
448
449    return Collections.unmodifiableList(propList);
450  }
451
452
453
454  /**
455   * {@inheritDoc}
456   */
457  @Override()
458  @NotNull()
459  public Map<TaskProperty,List<Object>> getTaskPropertyValues()
460  {
461    final LinkedHashMap<TaskProperty,List<Object>> props =
462         new LinkedHashMap<>(StaticUtils.computeMapCapacity(10));
463
464    if (reason != null)
465    {
466      props.put(PROPERTY_ENTER_LOCKDOWN_REASON,
467              Collections.<Object>singletonList(reason));
468    }
469
470    props.putAll(super.getTaskPropertyValues());
471    return Collections.unmodifiableMap(props);
472  }
473}