/**
   * Blocks an external component from connecting to the local server. If the component was
   *
   * <p>connected when the permission was revoked then the connection of the entity will be closed.
   *
   * @param subdomain the subdomain of the external component that is not allowed to connect.
   */
  public static void blockAccess(String subdomain) {

    // Remove any previous configuration for this external component

    deleteConfiguration(subdomain);

    // Update the database with the new revoked permission

    ExternalComponentConfiguration config = new ExternalComponentConfiguration(subdomain);

    config.setPermission(Permission.blocked);

    addConfiguration(config);

    // Check if the component was connected and proceed to close the connection

    String domain = subdomain + "." + XMPPServer.getInstance().getServerInfo().getDefaultName();

    Session session = SessionManager.getInstance().getComponentSession(domain);

    if (session != null) {

      session.getConnection().close();
    }
  }
  private static Collection<ExternalComponentConfiguration> getConfigurations(
      Permission permission) {

    Collection<ExternalComponentConfiguration> answer =
        new ArrayList<ExternalComponentConfiguration>();

    java.sql.Connection con = null;

    PreparedStatement pstmt = null;

    try {

      con = DbConnectionManager.getConnection();

      pstmt = con.prepareStatement(LOAD_CONFIGURATIONS);

      pstmt.setString(1, permission.toString());

      ResultSet rs = pstmt.executeQuery();

      ExternalComponentConfiguration configuration;

      while (rs.next()) {

        configuration = new ExternalComponentConfiguration(rs.getString(1));

        configuration.setSecret(rs.getString(2));

        configuration.setPermission(permission);

        answer.add(configuration);
      }

      rs.close();

    } catch (SQLException sqle) {

      Log.error(sqle);

    } finally {

      try {
        if (pstmt != null) pstmt.close();
      } catch (Exception e) {
        Log.error(e);
      }

      try {
        if (con != null) con.close();
      } catch (Exception e) {
        Log.error(e);
      }
    }

    return answer;
  }
  /**
   * Allows an external component to connect to the local server with the specified configuration.
   *
   * @param configuration the configuration for the external component.
   */
  public static void allowAccess(ExternalComponentConfiguration configuration) {

    // Remove any previous configuration for this external component

    deleteConfiguration(configuration.getSubdomain());

    // Update the database with the new granted permission and configuration

    configuration.setPermission(Permission.allowed);

    addConfiguration(configuration);
  }
  /**
   * Returns the configuration for an external component.
   *
   * @param subdomain the subdomain of the external component.
   * @return the configuration for an external component.
   */
  public static ExternalComponentConfiguration getConfiguration(String subdomain) {

    ExternalComponentConfiguration configuration = null;

    java.sql.Connection con = null;

    PreparedStatement pstmt = null;

    try {

      con = DbConnectionManager.getConnection();

      pstmt = con.prepareStatement(LOAD_CONFIGURATION);

      pstmt.setString(1, subdomain);

      ResultSet rs = pstmt.executeQuery();

      while (rs.next()) {

        configuration = new ExternalComponentConfiguration(subdomain);

        configuration.setSecret(rs.getString(1));

        configuration.setPermission(Permission.valueOf(rs.getString(2)));
      }

      rs.close();

    } catch (SQLException sqle) {

      Log.error(sqle);

    } finally {

      try {
        if (pstmt != null) pstmt.close();
      } catch (Exception e) {
        Log.error(e);
      }

      try {
        if (con != null) con.close();
      } catch (Exception e) {
        Log.error(e);
      }
    }

    return configuration;
  }
  /** Adds a new permission for the specified external component. */
  private static void addConfiguration(ExternalComponentConfiguration configuration) {

    // Remove the permission for the entity from the database

    java.sql.Connection con = null;

    PreparedStatement pstmt = null;

    try {

      con = DbConnectionManager.getConnection();

      pstmt = con.prepareStatement(ADD_CONFIGURATION);

      pstmt.setString(1, configuration.getSubdomain());

      pstmt.setString(2, configuration.getSecret());

      pstmt.setString(3, configuration.getPermission().toString());

      pstmt.executeUpdate();

    } catch (SQLException sqle) {

      Log.error(sqle);

    } finally {

      try {
        if (pstmt != null) pstmt.close();
      } catch (Exception e) {
        Log.error(e);
      }

      try {
        if (con != null) con.close();
      } catch (Exception e) {
        Log.error(e);
      }
    }
  }
  /**
   * Returns true if the external component with the specified subdomain can connect to the
   *
   * <p>local server.
   *
   * @param subdomain the subdomain of the external component.
   * @return true if the external component with the specified subdomain can connect to the
   *     <p>local server.
   */
  public static boolean canAccess(String subdomain) {

    // By default there is no permission defined for the XMPP entity

    Permission permission = null;

    ExternalComponentConfiguration config = getConfiguration(subdomain);

    if (config != null) {

      permission = config.getPermission();
    }

    if (PermissionPolicy.blacklist == getPermissionPolicy()) {

      // Anyone can access except those entities listed in the blacklist

      if (Permission.blocked == permission) {

        return false;

      } else {

        return true;
      }

    } else {

      // Access is limited to those present in the whitelist

      if (Permission.allowed == permission) {

        return true;

      } else {

        return false;
      }
    }
  }
  /**
   * Returns the shared secret with the specified external component. If no shared secret was
   *
   * <p>defined then use the default shared secret.
   *
   * @param subdomain the subdomain of the external component to get his shared secret.
   *     <p>(e.g. conference)
   * @return the shared secret with the specified external component or the default shared secret.
   */
  public static String getSecretForComponent(String subdomain) {

    // By default there is no shared secret defined for the XMPP entity

    String secret = null;

    ExternalComponentConfiguration config = getConfiguration(subdomain);

    if (config != null) {

      secret = config.getSecret();
    }

    secret = (secret == null ? getDefaultSecret() : secret);

    if (secret == null) {

      Log.error(
          "Setup for external components is incomplete. Property "
              + "xmpp.component.defaultSecret does not exist.");
    }

    return secret;
  }
 public void componentAllowed(String subdomain, ExternalComponentConfiguration configuration)
     throws ModificationNotAllowedException {
   if (subdomain.startsWith("clearspace")) {
     updateClearspaceSharedSecret(configuration.getSecret());
   }
 }