package com.l7tech.gateway.common.admin;

import com.l7tech.gateway.common.security.rbac.MethodStereotype;
import com.l7tech.gateway.common.security.rbac.Secured;
import com.l7tech.identity.AuthenticationException;
import com.l7tech.identity.Group;
import com.l7tech.identity.IdentityProviderConfig;
import com.l7tech.identity.IdentityProviderPasswordPolicy;
import com.l7tech.identity.InvalidIdProviderCfgException;
import com.l7tech.identity.User;
import com.l7tech.identity.LogonInfo.State;
import com.l7tech.identity.ldap.LdapIdentityProviderConfig;
import com.l7tech.objectmodel.DeleteException;
import com.l7tech.objectmodel.EntityHeader;
import com.l7tech.objectmodel.EntityHeaderSet;
import com.l7tech.objectmodel.EntityType;
import com.l7tech.objectmodel.FindException;
import com.l7tech.objectmodel.Goid;
import com.l7tech.objectmodel.IdentityHeader;
import com.l7tech.objectmodel.InvalidPasswordException;
import com.l7tech.objectmodel.ObjectModelException;
import com.l7tech.objectmodel.ObjectNotFoundException;
import com.l7tech.objectmodel.SaveException;
import com.l7tech.objectmodel.UpdateException;
import com.l7tech.util.DeserializeSafe;
import java.io.Serializable;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
@Secured
@Administrative
@DeserializeSafe
public interface IdentityAdmin {
   String ROLE_NAME_TYPE_SUFFIX = "Identity Provider";
   String ROLE_NAME_PATTERN = "Manage {0} Identity Provider (#{1})";

   @Transactional(readOnly = true)
   @Secured(types = EntityType.ID_PROVIDER_CONFIG, stereotype = MethodStereotype.FIND_HEADERS)
   @Administrative(licensed = false)
   EntityHeader[] findAllIdentityProviderConfig() throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.ID_PROVIDER_CONFIG, stereotype = MethodStereotype.FIND_ENTITY)
   @Administrative(licensed = false)
   IdentityProviderConfig findIdentityProviderConfigByID(Goid var1) throws FindException;

   @Transactional(propagation = Propagation.SUPPORTS)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   LdapIdentityProviderConfig[] getLdapTemplates() throws FindException;

   @Secured(types = EntityType.ID_PROVIDER_CONFIG, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   Goid saveIdentityProviderConfig(IdentityProviderConfig var1) throws SaveException, UpdateException;

   @Secured(types = EntityType.ID_PROVIDER_CONFIG, stereotype = MethodStereotype.DELETE_BY_ID)
   void deleteIdentityProviderConfig(Goid var1) throws DeleteException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.USER, stereotype = MethodStereotype.FIND_HEADERS)
   EntityHeaderSet<IdentityHeader> findAllUsers(Goid var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = {EntityType.USER, EntityType.GROUP}, stereotype = MethodStereotype.FIND_HEADERS)
   EntityHeaderSet<IdentityHeader> searchIdentities(Goid var1, EntityType[] var2, String var3) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.USER, stereotype = MethodStereotype.FIND_ENTITY, relevantArg = 1)
   User findUserByID(Goid var1, String var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.USER, stereotype = MethodStereotype.FIND_ENTITY)
   User findUserByLogin(Goid var1, String var2) throws FindException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.DELETE_IDENTITY_BY_ID, relevantArg = 1)
   void deleteUser(Goid var1, String var2) throws DeleteException, ObjectNotFoundException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 1)
   String saveUser(Goid var1, User var2, Set<IdentityHeader> var3, String var4) throws SaveException, UpdateException, ObjectNotFoundException, InvalidPasswordException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 1)
   String saveUser(Goid var1, User var2, Set<IdentityHeader> var3) throws SaveException, UpdateException, ObjectNotFoundException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 0)
   void changeUsersPassword(User var1, String var2) throws FindException, UpdateException, InvalidPasswordException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.GROUP, stereotype = MethodStereotype.FIND_HEADERS)
   EntityHeaderSet<IdentityHeader> findAllGroups(Goid var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.GROUP, stereotype = MethodStereotype.FIND_ENTITY, relevantArg = 1)
   Group findGroupByID(Goid var1, String var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.GROUP, stereotype = MethodStereotype.FIND_ENTITY)
   Group findGroupByName(Goid var1, String var2) throws FindException;

   @Secured(types = EntityType.GROUP, stereotype = MethodStereotype.DELETE_IDENTITY_BY_ID, relevantArg = 1)
   void deleteGroup(Goid var1, String var2) throws DeleteException, ObjectNotFoundException;

   @Secured(types = EntityType.GROUP, stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 1)
   String saveGroup(Goid var1, Group var2, Set<IdentityHeader> var3) throws SaveException, UpdateException, ObjectNotFoundException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.USER, stereotype = MethodStereotype.GET_PROPERTY_OF_ENTITY)
   String getUserCert(User var1) throws FindException, CertificateEncodingException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   boolean doesCurrentUserHaveCert() throws FindException, AuthenticationException;

   @Transactional(readOnly = true)
   @Administrative(licensed = false)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   boolean currentUsersPasswordCanBeChanged() throws AuthenticationException, FindException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.SET_PROPERTY_OF_ENTITY)
   void revokeCert(User var1) throws UpdateException, ObjectNotFoundException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.DELETE_MULTI)
   int revokeCertificates() throws UpdateException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.SET_PROPERTY_OF_ENTITY, relevantArg = 0)
   void recordNewUserCert(User var1, Certificate var2) throws UpdateException;

   @Secured(types = EntityType.ID_PROVIDER_CONFIG, stereotype = MethodStereotype.TEST_CONFIGURATION, relevantArg = 0)
   void testIdProviderConfig(IdentityProviderConfig var1, String var2, char[] var3) throws InvalidIdProviderCfgException;

   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   void testNtlmConfig(Map<String, String> var1) throws InvalidIdProviderCfgException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.USER, stereotype = MethodStereotype.GET_IDENTITY_PROPERTY_BY_ID, relevantArg = 1)
   Set<IdentityHeader> getGroupHeaders(Goid var1, String var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.GROUP, stereotype = MethodStereotype.GET_IDENTITY_PROPERTY_BY_ID, relevantArg = 1)
   Set<IdentityHeader> getGroupHeadersForGroup(Goid var1, @NotNull String var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.GROUP, stereotype = MethodStereotype.GET_IDENTITY_PROPERTY_BY_ID, relevantArg = 1)
   Set<IdentityHeader> getUserHeaders(Goid var1, String var2) throws FindException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.PASSWORD_POLICY, stereotype = MethodStereotype.FIND_ENTITY)
   IdentityProviderPasswordPolicy getPasswordPolicyForIdentityProvider(Goid var1) throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   @Administrative(licensed = false)
   String getPasswordPolicyDescriptionForIdentityProvider() throws FindException;

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   IdentityAdmin.AccountMinimums getAccountMinimums();

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   Map<String, IdentityAdmin.AccountMinimums> getAccountMinimumsMap();

   @Transactional(readOnly = true)
   @Secured(stereotype = MethodStereotype.UNCHECKED_WIDE_OPEN)
   Map<String, IdentityProviderPasswordPolicy> getPasswordPolicyMinimums();

   @Secured(types = EntityType.PASSWORD_POLICY, stereotype = MethodStereotype.SAVE_OR_UPDATE, relevantArg = 1)
   String updatePasswordPolicy(Goid var1, IdentityProviderPasswordPolicy var2) throws SaveException, UpdateException, ObjectNotFoundException;

   @Secured(types = EntityType.ID_PROVIDER_CONFIG, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   void forceAdminUsersResetPassword(Goid var1) throws ObjectModelException;

   @Secured(types = EntityType.USER, stereotype = MethodStereotype.SAVE_OR_UPDATE)
   void activateUser(User var1) throws FindException, UpdateException;

   @Transactional(readOnly = true)
   @Secured(types = EntityType.USER, stereotype = MethodStereotype.GET_PROPERTY_OF_ENTITY)
   State getLogonState(User var1) throws FindException;

   class AccountMinimums implements Serializable {
      private final String name;
      private final int attempts;
      private final int lockout;
      private final int expiry;
      private final int inactivity;
      static final long serialVersionUID = -7778876590255888945L;

      public AccountMinimums(String var1, int var2, int var3, int var4, int var5) {
         this.name = var1;
         this.attempts = var2;
         this.lockout = var3;
         this.expiry = var4;
         this.inactivity = var5;
      }

      public String getName() {
         return this.name;
      }

      public int getAttempts() {
         return this.attempts;
      }

      public int getExpiry() {
         return this.expiry;
      }

      public int getInactivity() {
         return this.inactivity;
      }

      public int getLockout() {
         return this.lockout;
      }
   }
}
