From 9b97b90c77daa7c02491be3894b3ccdd51c974cd Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Wed, 18 Apr 2007 12:08:18 +0000
Subject: [PATCH] Issue 1483 fix (use new admin framework for Access control configuration)

---
 opends/src/server/org/opends/server/core/AccessControlConfigManager.java |  243 +++++++++++++++++++++++-------------------------
 1 files changed, 118 insertions(+), 125 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/AccessControlConfigManager.java b/opends/src/server/org/opends/server/core/AccessControlConfigManager.java
index 40325b0..36261b2 100644
--- a/opends/src/server/org/opends/server/core/AccessControlConfigManager.java
+++ b/opends/src/server/org/opends/server/core/AccessControlConfigManager.java
@@ -26,7 +26,6 @@
  */
 package org.opends.server.core;
 
-import static org.opends.server.config.ConfigConstants.*;
 import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
 import org.opends.server.types.DebugLogLevel;
@@ -36,18 +35,22 @@
 import static org.opends.server.util.ServerConstants.*;
 import static org.opends.server.util.StaticUtils.*;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.opends.server.admin.ClassPropertyDefinition;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.server.ServerManagementContext;
+import org.opends.server.admin.std.meta.AccessControlHandlerCfgDefn;
+import org.opends.server.admin.std.server.AccessControlHandlerCfg;
+import org.opends.server.admin.std.server.RootCfg;
 import org.opends.server.api.AccessControlHandler;
 import org.opends.server.api.AccessControlProvider;
 import org.opends.server.api.AlertGenerator;
-import org.opends.server.api.ConfigChangeListener;
-import org.opends.server.config.BooleanConfigAttribute;
-import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.StringConfigAttribute;
 import org.opends.server.types.ConfigChangeResult;
 import org.opends.server.types.DN;
 import org.opends.server.types.ErrorLogCategory;
@@ -76,7 +79,7 @@
   private AtomicReference<AccessControlProvider> accessControlProvider;
 
   // The current configuration.
-  private Configuration currentConfiguration;
+  private PrivateACLConfiguration currentConfiguration;
 
   /**
    * Get the single application-wide access control manager instance.
@@ -132,37 +135,26 @@
   void initializeAccessControl() throws ConfigException,
       InitializationException {
 
-    // Get the access control handler configuration entry.
-    ConfigEntry configEntry;
-    try {
-      DN configEntryDN = DN.decode(DN_AUTHZ_HANDLER_CONFIG);
-      configEntry = DirectoryServer.getConfigEntry(configEntryDN);
-    } catch (Exception e) {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
+    // Get the root configuration object.
+    ServerManagementContext managementContext =
+         ServerManagementContext.getInstance();
+    RootCfg rootConfiguration =
+         managementContext.getRootConfiguration();
 
-      int msgID = MSGID_CONFIG_AUTHZ_CANNOT_GET_ENTRY;
-      String message = getMessage(msgID,
-          stackTraceToSingleLineString(e));
-      throw new ConfigException(msgID, message, e);
-    }
+    // Don't register as an add and delete listener with the root configuration
+    // as we can have only one object at a given time.
 
-    // The access control handler entry must exist.
-    if (configEntry == null) {
-      int msgID = MSGID_CONFIG_AUTHZ_ENTRY_DOES_NOT_EXIST;
-      String message = getMessage(msgID);
-      throw new ConfigException(msgID, message);
-    }
+    // //Initialize the current Access control.
+    AccessControlHandlerCfg accessControlConfiguration =
+           rootConfiguration.getAccessControlHandler();
 
     // Parse the configuration entry.
-    Configuration configuration = Configuration
-        .readConfiguration(configEntry);
+    PrivateACLConfiguration configuration = PrivateACLConfiguration
+        .readConfiguration(accessControlConfiguration);
 
     // We have a valid usable entry, so register a change listener in
     // order to handle configuration changes.
-    configEntry.registerChangeListener(new ChangeListener());
+    accessControlConfiguration.addChangeListener(new ChangeListener());
 
     // The configuration looks valid, so install it.
     updateConfiguration(configuration);
@@ -191,10 +183,10 @@
    *           If the access control handler provider could not be
    *           instantiated.
    */
-  private void updateConfiguration(Configuration newConfiguration)
+  private void updateConfiguration(PrivateACLConfiguration newConfiguration)
       throws ConfigException, InitializationException {
 
-    DN configEntryDN = newConfiguration.getConfigEntry().getDN();
+    DN configEntryDN = newConfiguration.getConfiguration().dn();
     Class<? extends AccessControlProvider> newHandlerClass = null;
 
     if (currentConfiguration == null) {
@@ -227,9 +219,10 @@
     // finalize the old
     // one and instantiate the new.
     if (newHandlerClass != null) {
-      AccessControlProvider newHandler;
+      AccessControlProvider<? extends AccessControlHandlerCfg> newHandler ;
       try {
-        newHandler = newHandlerClass.newInstance();
+          newHandler = loadProvider(newHandlerClass.getName(), newConfiguration
+            .getConfiguration());
       } catch (Exception e) {
         if (debugEnabled())
         {
@@ -244,9 +237,6 @@
       }
 
       // Switch the handlers without interfering with other threads.
-      newHandler.initializeAccessControlHandler(newConfiguration
-          .getConfigEntry());
-
       AccessControlProvider oldHandler = accessControlProvider
           .getAndSet(newHandler);
 
@@ -289,19 +279,22 @@
   /**
    * Internal class implementing the change listener interface.
    */
-  private class ChangeListener implements ConfigChangeListener {
+  private class ChangeListener implements
+      ConfigurationChangeListener<AccessControlHandlerCfg>
+  {
 
     /**
      * {@inheritDoc}
      */
-    public boolean configChangeIsAcceptable(ConfigEntry configEntry,
-        StringBuilder unacceptableReason) {
-
+    public boolean isConfigurationChangeAcceptable(
+        AccessControlHandlerCfg configuration,
+        List<String> unacceptableReasons)
+    {
       try {
         // Parse the configuration entry.
-        Configuration.readConfiguration(configEntry);
+        PrivateACLConfiguration.readConfiguration(configuration);
       } catch (ConfigException e) {
-        unacceptableReason.append(e.getMessage());
+        unacceptableReasons.add(e.getMessage());
         return false;
       }
 
@@ -312,15 +305,16 @@
      * {@inheritDoc}
      */
     public ConfigChangeResult applyConfigurationChange(
-        ConfigEntry configEntry) {
+        AccessControlHandlerCfg configuration)
+    {
 
       ResultCode resultCode = ResultCode.SUCCESS;
       ArrayList<String> messages = new ArrayList<String>();
 
       try {
         // Parse the configuration entry.
-        Configuration newConfiguration = Configuration
-            .readConfiguration(configEntry);
+        PrivateACLConfiguration newConfiguration = PrivateACLConfiguration
+            .readConfiguration(configuration);
 
         // The configuration looks valid, so install it.
         updateConfiguration(newConfiguration);
@@ -339,7 +333,7 @@
   /**
    * Internal class used to represent the parsed configuration entry.
    */
-  private static class Configuration {
+  private static class PrivateACLConfiguration {
 
     // Flag indicating whether or not access control is enabled.
     private boolean enabled;
@@ -349,35 +343,36 @@
     private Class<? extends AccessControlProvider> providerClass;
 
     // The entry that this object is mapped to.
-    private ConfigEntry configEntry;
+    private AccessControlHandlerCfg configuration;
 
     /**
      * Parses a configuration entry and, if it is valid, returns an
      * object representation of it.
      *
-     * @param configEntry
+     * @param configuration
      *          The access control configuration entry.
      * @return An object representation of the parsed configuration.
      * @throws ConfigException
      *           If a the access control configuration is invalid.
      */
-    public static Configuration readConfiguration(
-        ConfigEntry configEntry) throws ConfigException {
+    public static PrivateACLConfiguration readConfiguration(
+        AccessControlHandlerCfg configuration) throws ConfigException {
 
       // The access control configuration entry must have the correct
       // object class.
-      if (configEntry.hasObjectClass(OC_AUTHZ_HANDLER_CONFIG) == false) {
+      if (configuration.getAclHandlerClass() == null) {
         int msgID = MSGID_CONFIG_AUTHZ_ENTRY_DOES_NOT_HAVE_OBJECT_CLASS;
-        String message = getMessage(msgID, configEntry.toString());
+        String message = getMessage(msgID, configuration.toString());
         throw new ConfigException(msgID, message);
       }
 
       // Parse the attributes.
-      boolean enabled = getEnabledAttribute(configEntry);
-      Class<? extends AccessControlProvider> providerClass =
-        getClassAttribute(configEntry);
+      boolean enabled = configuration.isEnabled() ;
 
-      return new Configuration(configEntry, enabled, providerClass);
+      Class<? extends AccessControlProvider> providerClass =
+        getClassAttribute(configuration);
+
+      return new PrivateACLConfiguration(configuration, enabled, providerClass);
     }
 
     /**
@@ -407,105 +402,51 @@
      *
      * @return Returns the configuration entry.
      */
-    public ConfigEntry getConfigEntry() {
-      return configEntry;
+    public AccessControlHandlerCfg getConfiguration() {
+      return configuration;
     }
 
     /**
      * Construct a new configuration object with the specified parsed
      * attribute values.
      *
-     * @param configEntry
+     * @param configuration
      *          The associated access control configuration entry.
      * @param enabled
      *          The value of the enabled attribute.
      * @param providerClass
      *          The access control provider class.
      */
-    private Configuration(ConfigEntry configEntry, boolean enabled,
+    private PrivateACLConfiguration(
+        AccessControlHandlerCfg configuration, boolean enabled,
         Class<? extends AccessControlProvider> providerClass) {
 
-      this.configEntry = configEntry;
+      this.configuration = configuration;
       this.enabled = enabled;
       this.providerClass = providerClass;
     }
 
-    /**
-     * Read the value of the attribute which indicates whether or not
-     * access control is enabled.
-     *
-     * @param configEntry
-     *          The access control configuration entry.
-     * @return The boolean value of the enabled attribute.
-     * @throws ConfigException
-     *           If the enabled attribute could not be read or if it
-     *           contains an invalid value.
-     */
-    private static boolean getEnabledAttribute(ConfigEntry configEntry)
-        throws ConfigException {
-
-      // See if the entry contains an attribute that indicates whether
-      // or not access control should be enabled.
-      try {
-        BooleanConfigAttribute enabledAttrStub = new BooleanConfigAttribute(
-            ATTR_AUTHZ_HANDLER_ENABLED,
-            getMessage(MSGID_CONFIG_AUTHZ_DESCRIPTION_ENABLED), false);
-
-        BooleanConfigAttribute enabledAttr = (BooleanConfigAttribute)
-          configEntry.getConfigAttribute(enabledAttrStub);
-
-        if (enabledAttr == null) {
-          int msgID = MSGID_CONFIG_AUTHZ_NO_ENABLED_ATTR;
-          String message = getMessage(msgID, configEntry.getDN()
-              .toString());
-          throw new ConfigException(msgID, message);
-        } else {
-          // We have a valid attribute - return it.
-          return enabledAttr.activeValue();
-        }
-      } catch (ConfigException e) {
-        int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_DETERMINE_ENABLED_STATE;
-        String message = getMessage(msgID, configEntry.getDN()
-            .toString(), stackTraceToSingleLineString(e));
-        throw new ConfigException(msgID, message, e);
-      }
-    }
 
     /**
      * Read the value of the attribute which indicates which access
      * control implementation class to use. This method checks the
      * validity of the class name.
      *
-     * @param configEntry
-     *          The access control configuration entry.
+     * @param configuration
+     *          The access control configuration.
      * @return The access control provider class.
      * @throws ConfigException
      *           If the class attribute could not be read or if it
      *           contains an invalid class name.
      */
     private static Class<? extends AccessControlProvider> getClassAttribute(
-        ConfigEntry configEntry) throws ConfigException {
+        AccessControlHandlerCfg configuration) throws ConfigException {
 
       // If access control is enabled then make sure that the class
       // attribute is present.
       try {
-        StringConfigAttribute classAttrStub = new StringConfigAttribute(
-            ATTR_AUTHZ_HANDLER_CLASS,
-            getMessage(MSGID_CONFIG_AUTHZ_DESCRIPTION_CLASS), true,
-            false, false);
-
-        StringConfigAttribute classAttr = (StringConfigAttribute) configEntry
-            .getConfigAttribute(classAttrStub);
-
-        if (classAttr == null) {
-          int msgID = MSGID_CONFIG_AUTHZ_NO_CLASS_ATTR;
-          String message = getMessage(msgID, configEntry.getDN()
-              .toString());
-          throw new ConfigException(msgID, message);
-        }
-
         // Load the access control implementation class.
-        String className = classAttr.activeValue();
+        String className = configuration.getAclHandlerClass();
         try {
           return DirectoryServer.loadClass(className).asSubclass(
               AccessControlProvider.class);
@@ -517,7 +458,7 @@
 
           int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_LOAD_CLASS;
           String message = getMessage(msgID, className, String
-              .valueOf(configEntry.getDN().toString()),
+              .valueOf(configuration.dn().toString()),
               stackTraceToSingleLineString(e));
           throw new ConfigException(msgID, message, e);
         } catch (ClassCastException e) {
@@ -528,14 +469,14 @@
 
           int msgID = MSGID_CONFIG_AUTHZ_BAD_CLASS;
           String message = getMessage(msgID, className, String
-              .valueOf(configEntry.getDN().toString()),
+              .valueOf(configuration.dn().toString()),
               AccessControlProvider.class.getName(),
               stackTraceToSingleLineString(e));
           throw new ConfigException(msgID, message, e);
         }
       } catch (ConfigException e) {
         int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_DETERMINE_CLASS;
-        String message = getMessage(msgID, configEntry.getDN()
+        String message = getMessage(msgID, configuration.dn()
             .toString(), stackTraceToSingleLineString(e));
         throw new ConfigException(msgID, message, e);
       }
@@ -553,7 +494,7 @@
    */
   public DN getComponentEntryDN()
   {
-    return currentConfiguration.getConfigEntry().getDN();
+    return currentConfiguration.getConfiguration().dn();
   }
 
 
@@ -594,5 +535,57 @@
 
     return alerts;
   }
+
+  /**
+   * Loads the specified class, instantiates it as a AccessControlProvider, and
+   * optionally initializes that instance.
+   *
+   * @param  className      The fully-qualified name of the Access Control
+   *                        provider class to load, instantiate, and initialize.
+   * @param  configuration  The configuration to use to initialize the
+   *                        Access Control Provider, or {@code null} if the
+   *                        Access Control Provider should not be initialized.
+   *
+   * @return  The possibly initialized Access Control Provider.
+   *
+   * @throws  InitializationException  If a problem occurred while attempting to
+   *                                   initialize the Access Control Provider.
+   */
+  private AccessControlProvider<? extends AccessControlHandlerCfg>
+               loadProvider(String className,
+                             AccessControlHandlerCfg configuration)
+          throws InitializationException
+  {
+    try
+    {
+      AccessControlHandlerCfgDefn definition =
+        AccessControlHandlerCfgDefn.getInstance();
+      ClassPropertyDefinition propertyDefinition =
+           definition.getAclHandlerClassPropertyDefinition();
+      Class<? extends AccessControlProvider> providerClass =
+           propertyDefinition.loadClass(className, AccessControlProvider.class);
+      AccessControlProvider<? extends AccessControlHandlerCfg> provider =
+           (AccessControlProvider<? extends AccessControlHandlerCfg>)
+           providerClass.newInstance();
+
+      if (configuration != null)
+      {
+        Method method =
+          provider.getClass().getMethod("initializeAccessControlHandler",
+                  configuration.definition().getServerConfigurationClass());
+        method.invoke(provider, configuration);
+      }
+
+      return provider;
+    }
+    catch (Exception e)
+    {
+      int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_INSTANTIATE_HANDLER;
+      String message = getMessage(msgID, className,
+                                  String.valueOf(configuration.dn()),
+                                  stackTraceToSingleLineString(e));
+      throw new InitializationException(msgID, message, e);
+    }
+  }
 }
 

--
Gitblit v1.10.0