/**
   * Metodo que obtiene los ids de los grupos a los que pertenece el usuario
   *
   * @param conn
   * @param attributesUser
   * @param ldapDef
   * @param attributes
   * @param entidad
   * @return
   * @throws SecurityException
   */
  public List getListGroupOfUser(
      LdapConnection conn,
      LDAPAuthenticationUser attributesUser,
      LDAPDef ldapDef,
      String attributes[],
      String entidad)
      throws SecurityException {
    List result = new ArrayList();
    String attr[] = {attributes[0]};
    try {
      String group = null;
      String filter = null;
      LdapSearch search = null;
      LDAPAuthenticationUser attributesGroup = null;
      List groups = null;
      int scope =
          new Integer(
                  LDAPRBUtil.getInstance(null)
                      .getProperty(LDAP_SCOPEGROUP + ldapDef.getLdapEngine()))
              .intValue();
      groups = attributesUser.getGroupList();
      if (log.isDebugEnabled()) {
        log.debug("groups [" + groups + "] con el log [" + log + "]");
      }
      for (int i = 0; i < groups.size(); i++) {
        group = (String) groups.get(i);
        filter =
            LDAPRBUtil.getInstance(null)
                .getProperty(LDAP_SCOPE_BASESUBTREE_GROUP + ldapDef.getLdapEngine());
        search = new LdapSearch();
        search.initialize(conn, group, scope, filter, attr);
        search.execute();
        if (search.next()) {
          attributesGroup = getUserAttributes(search, attributes);
          attributesGroup.setGuidStringFormat(
              LdapBasicFns.formatGuid(conn, attributesGroup.getGuid()));

          Integer idGroup = getIdGroup(attributesGroup.getGuidStringFormat(), entidad);

          if (idGroup != null) {
            result.add(idGroup);
          }
        }
      }
    } catch (SecurityException e) {
      throw new SecurityException(SecurityException.ERROR_PASSWORD_INCORRECT);
    } catch (Exception e) {
      throw new SecurityException(SecurityException.ERROR_PASSWORD_INCORRECT);
    } finally {
      try {
        conn.close();
      } catch (Exception e) {
      }
    }
    return result;
  }
  public List connectionVerification(
      LDAPAuthenticationUser attributesUser,
      String password,
      LDAPDef ldapDef,
      String attributes[],
      String entidad)
      throws SecurityException {

    Integer deptId = null;
    List deptList = new ArrayList();
    String attr[] = {attributes[0]};
    LdapConnection conn = null;
    try {
      String group = null;
      String filter = null;
      LdapSearch search = null;
      LDAPAuthenticationUser attributesGroup = null;
      if (log.isDebugEnabled()) {
        log.debug("dn [" + attributesUser.getDn() + "] con el log [" + log + "]");
      }
      conn = new LdapConnection();
      LdapConnCfg ldapConfig = LdapConfigUtils.createLdapConnConfig(ldapDef);
      ldapConfig.setProvider(1);
      // conn.open(ldapConfig, ldapDef.getLdapUser(), password, 1);
      conn.open(ldapConfig, ldapConfig.getUser(), password);

      List groups = null;
      int scope =
          new Integer(
                  LDAPRBUtil.getInstance(null)
                      .getProperty(LDAP_SCOPEGROUP + ldapDef.getLdapEngine()))
              .intValue();
      if (ldapDef.getLdapEngine() == 1) {
        groups = attributesUser.getGroupList();
        if (log.isDebugEnabled()) {
          log.debug(" groups [" + groups + "] con el log [" + log + "]");
        }

        filter =
            LDAPRBUtil.getInstance(null)
                .getProperty(LDAP_SCOPE_BASESUBTREE_GROUP + ldapDef.getLdapEngine());
        if (log.isDebugEnabled()) {
          log.debug(" filter [" + filter + "] con el log [" + log + "]");
        }

        for (int i = 0; i < groups.size(); i++) {

          group = (String) groups.get(i);

          search = new LdapSearch();
          search.initialize(conn, group, scope, filter, attr);
          search.execute();
          if (search.next()) {
            attributesGroup = getUserAttributes(search, attributes);
            attributesGroup.setGuidStringFormat(
                LdapBasicFns.formatGuid(conn, attributesGroup.getGuid()));
            deptId = getRegisterDeptOfic(attributesGroup.getGuidStringFormat(), entidad);

            if (deptId != null) {
              deptList.add(deptId);
              if (log.isDebugEnabled()) {
                log.debug(" deptId [" + deptId + "] con el log [" + log + "]");
              }
              // break;
            }
          }
        }
      } else {
        filter =
            MessageFormat.format(
                LDAPRBUtil.getInstance(null)
                    .getProperty(LDAP_SCOPE_BASESUBTREE_GROUP + ldapDef.getLdapEngine()),
                new String[] {attributesUser.getDn()});
        if (log.isDebugEnabled()) {
          log.debug(" filter [" + filter + "] con el log [" + log + "]");
        }
        List list = new ArrayList();
        list = getUserGroupGuidsIp(conn, ldapDef.getLdapRoot(), scope, filter, attr);
        if (log.isDebugEnabled()) {
          log.debug(" groups [" + list + "] con el log [" + log + "]");
        }

        String groupGuid = null;
        for (int i = 0; i < list.size(); i++) {
          groupGuid = (String) list.get(i);
          deptId = getRegisterDeptOfic(groupGuid, entidad);

          if (deptId != null) {
            if (log.isDebugEnabled()) {
              log.debug(" deptId [" + deptId + "] con el log [" + log + "]");
            }
            deptList.add(deptId);
            // break;
          }
        }
      }
    } catch (SecurityException e) {
      throw new SecurityException(SecurityException.ERROR_PASSWORD_INCORRECT);
    } catch (Exception e) {
      throw new SecurityException(SecurityException.ERROR_PASSWORD_INCORRECT);
    } finally {
      try {
        conn.close();
      } catch (Exception e) {
      }
    }
    return deptList;
  }
  public List connectionVerification(
      LdapConnection conn,
      LDAPAuthenticationUser attributesUser,
      LDAPDef ldapDef,
      String attributes[],
      String entidad,
      List groupList)
      throws SecurityException {
    Integer deptId = null;
    List deptList = new ArrayList();
    String attr[] = {attributes[0]};
    try {
      String group = null;
      String filter = null;
      LdapSearch search = null;
      LDAPAuthenticationUser attributesGroup = null;
      List groups = null;
      int scope =
          new Integer(
                  LDAPRBUtil.getInstance(null)
                      .getProperty(LDAP_SCOPEGROUP + ldapDef.getLdapEngine()))
              .intValue();
      groups = attributesUser.getGroupList();
      if (log.isDebugEnabled()) {
        log.debug("groups [" + groups + "] con el log [" + log + "]");
      }
      for (int i = 0; i < groups.size(); i++) {
        group = (String) groups.get(i);
        filter =
            LDAPRBUtil.getInstance(null)
                .getProperty(LDAP_SCOPE_BASESUBTREE_GROUP + ldapDef.getLdapEngine());
        search = new LdapSearch();
        search.initialize(conn, group, scope, filter, attr);
        search.execute();
        if (search.next()) {
          attributesGroup = getUserAttributes(search, attributes);
          attributesGroup.setGuidStringFormat(
              LdapBasicFns.formatGuid(conn, attributesGroup.getGuid()));

          // obtiene los grupos
          Integer idGroup = getIdGroup(attributesGroup.getGuidStringFormat(), entidad);

          if (idGroup != null) {
            groupList.add(idGroup);
          }

          deptId = getRegisterDeptOfic(attributesGroup.getGuidStringFormat(), entidad);

          if (deptId != null) {
            deptList.add(deptId);
          }
        }
      }
    } catch (SecurityException e) {
      log.error("Error connectionVerification: " + e.getMessage(), e);
      throw new SecurityException(SecurityException.ERROR_PASSWORD_INCORRECT);
    } catch (Exception e) {
      log.error("Error connectionVerification: " + e.getMessage(), e);
      throw new SecurityException(SecurityException.ERROR_PASSWORD_INCORRECT);
    }
    return deptList;
  }
  public AuthenticationUser validate(String login, String password, String entidad)
      throws SecurityException, ValidationException {
    AuthenticationUser user = null;
    validateParameters(login, password);
    LDAPAuthenticationUser attributesUser = null;

    try {
      LDAPDef ldapDef = RepositoryLDAP.getInstance(entidad).getLDAPInfo();
      if (log.isDebugEnabled()) {
        log.debug("LDAPDef [" + ldapDef + "] con el log [" + log + "]");
      }
      if (ldapDef.getLdapEngine() == 0) {
        throw new SecurityException(SecurityException.ERROR_AUTHENTICATION_POLICY_NOTFOUND);
      }

      // String dn = ldapDef.getLdapUser();
      String attrID =
          LDAPRBUtil.getInstance(null).getProperty(LDAP_ATTRIBUTES + ldapDef.getLdapEngine());
      String attributes[] = parseAttributes(attrID);
      String passwordDecrypt = CryptoUtils.decryptPasswordLDAP(ldapDef.getLdapPassword());
      LdapConnection conn = new LdapConnection();
      LdapConnCfg ldapConfig = LdapConfigUtils.createLdapConnConfig(ldapDef);
      ldapConfig.setProvider(1);
      String dn = ldapConfig.getUser();
      conn.open(ldapConfig, dn, passwordDecrypt);

      LdapSearch search = getSearch(login, conn, ldapDef, attributes);
      attributesUser = getUserAttributes(search, attributes);
      attributesUser.setGuidStringFormat(LdapBasicFns.formatGuid(conn, attributesUser.getGuid()));
      if (log.isDebugEnabled()) {
        log.debug("attributesUser [" + attributesUser + "] con el log [" + log + "]");
      }

      conn.close();

      // se valida al usuario logueado y su contraseña
      validateUserPassword(ldapDef, attributesUser.getDn(), password);

      Integer userId = userVerification(attributesUser, entidad);
      //			Integer deptId = connectionVerification(attributesUser, passwordDecrypt,
      //					ldapDef, attributes, entidad);

      Integer deptId = null;

      // List deptList = connectionVerification(attributesUser, passwordDecrypt, ldapDef,
      // attributes, entidad);
      // obtiene los departamentos del usuario
      List deptListLDAP =
          connectionVerification(attributesUser, passwordDecrypt, ldapDef, attributes, entidad);
      // obtenemos las oficinas del usuario
      List deptList = getUserDeptList(userId, entidad, deptListLDAP);
      // obtenemos los ids de los grupos a los que pertenece el usuario
      List groupList =
          getListGroupOfUser(attributesUser, passwordDecrypt, ldapDef, attributes, entidad);

      user = new AuthenticationUser();

      if (deptList != null && deptList.size() > 0) {
        deptId = (Integer) deptList.get(0);
        user.setDeptList(deptList);
      }

      user.setId(userId);
      user.setName(attributesUser.getFullName());
      user.setDeptid(deptId);
      user.setDeptIdOriginal(deptId);
      user.setGroupList(groupList);

    } catch (NamingException e) {
      throw new SecurityException(SecurityException.ERROR_USER_NOTFOUND);
    } catch (SecurityException e) {
      throw e;
    } catch (Exception e) {
      throw new SecurityException(SecurityException.ERROR_USER_NOTFOUND);
    }

    return user;
  }
  public LdapSearch getSearch(
      String login, LdapConnection conn, LDAPDef ldapDef, String[] attributes)
      throws SecurityException {
    String filter = null;
    LdapSearch search = null;
    try {
      // busqueda por dn
      filter =
          MessageFormat.format(
              LDAPRBUtil.getInstance(null).getProperty(LDAP_SCOPE_BASE + ldapDef.getLdapEngine()),
              new String[] {login});
      if (log.isDebugEnabled()) {
        log.debug("filter [" + filter + "] con el log [" + log + "]");
        log.debug("dn [" + login + "] con el log [" + log + "]");
      }
      search = new LdapSearch();
      search.initialize(
          conn, ldapDef.getLdapRoot(), SearchControls.OBJECT_SCOPE, filter, attributes);
      search.execute();
      if (!search.next()) {
        // Busqueda por UniqueName
        filter =
            MessageFormat.format(
                LDAPRBUtil.getInstance(null)
                    .getProperty(LDAP_SCOPE_SUBTREE1 + ldapDef.getLdapEngine()),
                new String[] {login});
        if (log.isDebugEnabled()) {
          log.debug("filter [" + filter + "] con el log [" + log + "]");
          log.debug("UniqueName [" + login + "] con el log [" + log + "]");
        }
        search = new LdapSearch();
        search.initialize(
            conn, ldapDef.getLdapRoot(), SearchControls.SUBTREE_SCOPE, filter, attributes);
        search.execute();
        if (!search.next()) {
          // Busqueda por número de cuenta sAMAccountName
          filter =
              MessageFormat.format(
                  LDAPRBUtil.getInstance(null)
                      .getProperty(LDAP_SCOPE_SUBTREE2 + ldapDef.getLdapEngine()),
                  new String[] {login});
          if (log.isDebugEnabled()) {
            log.debug("filter [" + filter + "] con el log [" + log + "]");
            log.debug("sAMAccountName [" + login + "] con el log [" + log + "]");
          }
          if (!filter.equals("")) {
            search = new LdapSearch();
            search.initialize(
                conn, ldapDef.getLdapRoot(), SearchControls.SUBTREE_SCOPE, filter, attributes);
            search.execute();
            if (!search.next()) {
              throw new SecurityException(SecurityException.ERROR_NAME_INCORRECT);
            }
          }
        }
      }
      if (search.getM_srAttrs() == null) {
        throw new SecurityException(SecurityException.ERROR_NAME_INCORRECT);
      }
    } catch (SecurityException e) {
      throw e;
    } catch (Exception e) {
      throw new SecurityException(SecurityException.ERROR_CAN_NOT_FIND_USER_ATTRIBUTES_LDAP);
    }

    return search;
  }
  public AuthenticationUser validate(String userDn, String entidad)
      throws SecurityException, ValidationException {
    AuthenticationUser user = null;
    LDAPAuthenticationUser attributesUser = null;

    LdapConnection conn = new LdapConnection();
    try {
      // String decodedDn = CryptoUtils.getDecodeDn(userDn);
      String decodedDn = userDn;
      LDAPDef ldapDef = RepositoryLDAP.getInstance(entidad).getLDAPInfo();
      if (log.isDebugEnabled()) {
        log.debug("LDAPDef [" + ldapDef + "] con el log [" + log + "]");
      }
      if (ldapDef.getLdapEngine() == 0) {
        throw new SecurityException(SecurityException.ERROR_AUTHENTICATION_POLICY_NOTFOUND);
      }

      // String dn = ldapDef.getLdapUser();
      String attrID =
          LDAPRBUtil.getInstance(null).getProperty(LDAP_ATTRIBUTES + ldapDef.getLdapEngine());
      String attributes[] = parseAttributes(attrID);
      String passwordDecrypt = CryptoUtils.decryptPasswordLDAP(ldapDef.getLdapPassword());
      LdapConnCfg ldapConfig = LdapConfigUtils.createLdapConnConfig(ldapDef);
      String dn = ldapConfig.getUser();
      ldapConfig.setProvider(1);
      conn.open(ldapConfig, dn, passwordDecrypt);

      LdapSearch search = getSearchSSO(decodedDn, conn, ldapDef, attributes);
      attributesUser = getUserAttributes(search, attributes);
      attributesUser.setGuidStringFormat(LdapBasicFns.formatGuid(conn, attributesUser.getGuid()));
      if (log.isDebugEnabled()) {
        log.debug("attributesUser [" + attributesUser + "] con el log [" + log + "]");
      }

      Integer userId = userVerification(attributesUser, entidad);
      //			Integer deptId = connectionVerification(conn, attributesUser, ldapDef, attributes,
      // entidad);

      Integer deptId = null;

      List groupList = new ArrayList();
      List deptList =
          connectionVerification(conn, attributesUser, ldapDef, attributes, entidad, groupList);
      // se deja comentado este punto porque es nuevo y soluciona el error detectado con el boton
      // cambiar oficina por SSO

      deptList = getUserDeptList(userId, entidad, deptList);

      user = new AuthenticationUser();

      if (deptList != null && deptList.size() > 0) {
        deptId = (Integer) deptList.get(0);
        user.setDeptList(deptList);
      }

      user.setId(userId);
      user.setName(attributesUser.getFullName());
      user.setDeptid(deptId);
      user.setGroupList(groupList);

      return user;

    } catch (NamingException e) {
      throw new SecurityException(SecurityException.ERROR_USER_NOTFOUND);
    } catch (SecurityException e) {
      throw e;
    } catch (Exception e) {
      throw new SecurityException(SecurityException.ERROR_USER_NOTFOUND);
    } finally {
      try {
        conn.close();
      } catch (Exception e) {
        if (log.isDebugEnabled()) {
          log.debug("Error al cerrar conexión LDAP", e);
        }
      }
    }
  }