package com.airlock.iam.publicselfservice.application.configuration.restrictions;

import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.StringListProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.List;

@Plugin(
   description = "Does not allow locked users to perform public self-services, unless the lock reason is one of the white-listed reasons (see property \"Allowed Lock Reasons\").",
   displayName = "Locked User Restriction"
)
public class LockedUserRestrictionConfig implements InternalPublicSelfServiceRestrictionConfig {
   public static final String LOCKED_USER_RESTRICTION_DISPLAY_NAME = "Locked User Restriction";
   static final String TOO_MANY_PASSWORD_ATTEMPTS_LOCK_REASON = "LockReason.TooManyAuthAtts.PASSWORD";
   @StringListProperty(
      description = "<p>List of lock reasons that still <em>allow</em> the user to perform public self-services. Locked users with any lock reason not listed here will not be allowed to perform public self-services.</p><p>Note that a user is not automatically unlocked after a successful public self-service. A \"Unlock User Step (Public Self-Service)\" step has to be configured to perform this task.</p>",
      exampleElements = "LockReason.TooManyAuthAtts.PASSWORD",
      optional = true,
      minElements = 1
   )
   private List<String> allowedLockReasons;
   static final String ALLOWED_LOCK_REASONS_DISPLAY_NAME = "Allowed Lock Reasons";
   @BooleanProperty(
      description = "<p>If enabled, the User Identification Step always returns a specific error code in case this restriction is violated.</p><p>If no restrictions are configured to provide feedback, a flow can also be started for users violating one or more restrictions and the flow will advance to the user identity verification step in stealth mode. In this mode, the initial behavior of the step is the same as for unrestricted users (e.g. an mTAN OTP is required), but all responses are rejected as if they were incorrect. This behavior prevents restricted users from ever proceeding further in the flow and thus offers protection against user enumeration. Please refer to the documentation for more details.</p><p>Irrespective of this settings, once the identity verification step is passed, restriction are always checked before and after each method call and violations are always reported.</p><p><b>Security notice:</b> Enabling this feature might allow a client to determine whether certain users exist in the system.</p>",
      optional = true,
      defaultValue = "false"
   )
   private boolean enableFeedback;

   public List<String> getAllowedLockReasons() {
      return this.allowedLockReasons;
   }

   public boolean isEnableFeedback() {
      return this.enableFeedback;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static LockedUserRestrictionConfig.LockedUserRestrictionConfigBuilder builder() {
      return new LockedUserRestrictionConfig.LockedUserRestrictionConfigBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public LockedUserRestrictionConfig() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public LockedUserRestrictionConfig(List<String> allowedLockReasons, boolean enableFeedback) {
      this.allowedLockReasons = allowedLockReasons;
      this.enableFeedback = enableFeedback;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class LockedUserRestrictionConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private List<String> allowedLockReasons;
      @SuppressFBWarnings(justification = "generated code")
      private boolean enableFeedback;

      @SuppressFBWarnings(justification = "generated code")
      LockedUserRestrictionConfigBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public LockedUserRestrictionConfig.LockedUserRestrictionConfigBuilder allowedLockReasons(List<String> allowedLockReasons) {
         this.allowedLockReasons = allowedLockReasons;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LockedUserRestrictionConfig.LockedUserRestrictionConfigBuilder enableFeedback(boolean enableFeedback) {
         this.enableFeedback = enableFeedback;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public LockedUserRestrictionConfig build() {
         return new LockedUserRestrictionConfig(this.allowedLockReasons, this.enableFeedback);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "LockedUserRestrictionConfig.LockedUserRestrictionConfigBuilder(allowedLockReasons="
            + this.allowedLockReasons
            + ", enableFeedback="
            + this.enableFeedback
            + ")";
      }
   }
}
