Beispiel #1
0
 private SystemSettings removePrivateSettings(SystemSettings settings) {
   SystemSettings cleansed = new SystemSettings(settings);
   for (SystemSetting s : SystemSetting.values()) {
     if (!s.isPublic()) {
       cleansed.remove(s);
     }
   }
   return cleansed;
 }
Beispiel #2
0
 /**
  * Call this to transform a system setting to a more appropriate value. Importantly, this
  * (de)obfuscates the password fields as they go from and to the DB. We use the @{link
  * PicketBoxObfuscator} so that people are able encode their passwords in the system settings
  * export files using the "rhq-encode-password.sh" script.
  */
 private String transformSystemConfigurationPropertyFromDb(
     SystemSetting prop, String value, boolean unobfuscate) {
   // to support Oracle (whose booleans may be 1 or 0) transform the boolean settings properly
   switch (prop) {
     case LDAP_BASED_JAAS_PROVIDER:
       if (RHQConstants.JDBCJAASProvider.equals(value)) {
         return Boolean.toString(false);
       } else if (RHQConstants.LDAPJAASProvider.equals(value)) {
         return Boolean.toString(true);
       } else {
         return value == null ? "" : value;
       }
     case USE_SSL_FOR_LDAP:
       if (RHQConstants.LDAP_PROTOCOL_SECURED.equals(value)) {
         return Boolean.toString(true);
       } else {
         return Boolean.toString(false);
       }
     default:
       switch (prop.getType()) {
         case BOOLEAN:
           if ("0".equals(value)) {
             return Boolean.FALSE.toString();
           } else if ("1".equals(value)) {
             return Boolean.TRUE.toString();
           } else {
             return value == null ? Boolean.FALSE.toString() : value;
           }
         case PASSWORD:
           if (unobfuscate && value != null && value.trim().length() > 0) {
             return PicketBoxObfuscator.decode(value);
           } else {
             return value == null ? "" : value;
           }
         default:
           if (value == null) {
             switch (prop.getType()) {
               case DOUBLE:
               case FLOAT:
               case INTEGER:
               case LONG:
                 value = "0";
                 break;
               default:
                 value = "";
             }
           }
           return value;
       }
   }
 }
Beispiel #3
0
 /**
  * Call this to transform a system setting to a more appropriate value. Importantly, this
  * (de)obfuscates the password fields as they go from and to the DB. We use the @{link
  * PicketBoxObfuscator} so that people are able encode their passwords in the system settings
  * export files using the "rhq-encode-password.sh" script.
  */
 private String transformSystemConfigurationPropertyToDb(
     SystemSetting prop, String newValue, String oldValue) {
   // the 0,1 -> true false scenario is no problem here, because the values are stored
   // as string anyway (so no conversion is done). I assume the above is a historical
   // code that could be safely eliminated.
   switch (prop) {
     case LDAP_BASED_JAAS_PROVIDER:
       if (Boolean.parseBoolean(newValue)) {
         return RHQConstants.LDAPJAASProvider;
       } else {
         return RHQConstants.JDBCJAASProvider;
       }
     case USE_SSL_FOR_LDAP:
       if (Boolean.parseBoolean(newValue)) {
         return RHQConstants.LDAP_PROTOCOL_SECURED;
       } else {
         return RHQConstants.LDAP_PROTOCOL_UNSECURED;
       }
     default:
       if (prop.getType() == PropertySimpleType.PASSWORD && newValue != null) {
         if (PropertySimple.MASKED_VALUE.equals(newValue)) {
           return oldValue;
         } else {
           return PicketBoxObfuscator.encode(newValue);
         }
       } else {
         return newValue;
       }
   }
 }
Beispiel #4
0
  private String unmask(SystemSetting prop, String newValue, String currentValue) {
    if (prop.getType() == PropertySimpleType.PASSWORD
        && PropertySimple.MASKED_VALUE.equals(newValue)) {
      newValue = currentValue;
    }

    return newValue;
  }
Beispiel #5
0
 private void transformToSystemSettingsFormat(Map<String, String> map) {
   for (Map.Entry<String, String> e : map.entrySet()) {
     SystemSetting prop = SystemSetting.getByInternalName(e.getKey());
     if (prop != null) {
       // this is a legacy method that supplies values in the DB-specific format.
       // we therefore have to transform the values as if they came from the database.
       String value = transformSystemConfigurationPropertyFromDb(prop, e.getValue(), false);
       e.setValue(value);
     }
   }
 }
Beispiel #6
0
  public void testPasswordFieldsObfuscation() {
    SystemSettings masked = systemManager.getSystemSettings(overlord);
    SystemSettings unmasked = systemManager.getUnmaskedSystemSettings(true);
    SystemSettings obfuscated = systemManager.getObfuscatedSystemSettings(true);

    for (SystemSetting setting : SystemSetting.values()) {
      if (setting.getType() == PropertySimpleType.PASSWORD) {
        if (masked.containsKey(setting) && masked.get(setting) != null) {
          assertEquals(
              "Unexpected unmasked value", PropertySimple.MASKED_VALUE, masked.get(setting));
          assertEquals(
              "Unmasked and obfuscated values don't correspond",
              obfuscated.get(setting),
              PicketBoxObfuscator.encode(unmasked.get(setting)));
        }
      }
    }

    systemManager.deobfuscate(obfuscated);

    assertEquals(unmasked, obfuscated);
  }
Beispiel #7
0
  private void checkFormats(SystemSettings settings, Properties config) {
    assert settings.size() == config.size()
        : "The old and new style system settings differ in size";

    for (String name : config.stringPropertyNames()) {
      SystemSetting setting = SystemSetting.getByInternalName(name);

      String oldStyleValue = config.getProperty(name);
      String newStyleValue = settings.get(setting);

      assert setting != null : "Could not find a system setting called '" + name + "'.";

      switch (setting) {
        case USE_SSL_FOR_LDAP:
          if (RHQConstants.LDAP_PROTOCOL_SECURED.equals(oldStyleValue)) {
            assert Boolean.valueOf(newStyleValue)
                : "Secured LDAP protocol should be represented by a 'true' in new style settings.";
          } else if (RHQConstants.LDAP_PROTOCOL_UNSECURED.equals(oldStyleValue)) {
            assert !Boolean.valueOf(newStyleValue)
                : "Unsecured LDAP protocol should be represented by a 'false' in the new style settings.";
          } else {
            assert false
                : "Unknown value for system setting '" + setting + "': [" + oldStyleValue + "].";
          }
          break;
        case LDAP_BASED_JAAS_PROVIDER:
          if (RHQConstants.LDAPJAASProvider.equals(oldStyleValue)) {
            assert Boolean.valueOf(newStyleValue)
                : "LDAP JAAS provider should be represented by a 'true' in new style settings.";
          } else if (RHQConstants.JDBCJAASProvider.equals(oldStyleValue)) {
            assert !Boolean.valueOf(newStyleValue)
                : "JDBC JAAS provider should be represented by a 'false' in the new style settings.";
          } else {
            assert false
                : "Unknown value for system setting '" + setting + "': [" + oldStyleValue + "].";
          }
          break;
        default:
          assert oldStyleValue != null
                  && newStyleValue != null
                  && oldStyleValue.equals(newStyleValue)
              : "Old and new style values unexpectedly differ for system setting '"
                  + setting
                  + "': old=["
                  + oldStyleValue
                  + "], new=["
                  + newStyleValue
                  + "].";
      }
    }
  }
Beispiel #8
0
  private void fillCache(Collection<SystemConfiguration> configs) {
    SystemSettings settings = new SystemSettings();

    for (SystemConfiguration config : configs) {
      SystemSetting prop = SystemSetting.getByInternalName(config.getPropertyKey());
      if (prop == null) {
        LOG.warn(
            "The database contains unknown system configuration setting ["
                + config.getPropertyKey()
                + "].");
        continue;
      }

      if (config.getPropertyValue() == null) {
        // for some reason, the configuration is not found in the DB, so fallback to the persisted
        // default.
        // if there isn't even a persisted default, just use an empty string.
        String defaultValue = config.getDefaultPropertyValue();
        defaultValue = transformSystemConfigurationPropertyFromDb(prop, defaultValue, true);
        settings.put(prop, defaultValue);
      } else {
        String value = config.getPropertyValue();
        value = transformSystemConfigurationPropertyFromDb(prop, value, true);
        settings.put(prop, value);
      }
    }

    settings.setDriftPlugins(getDriftServerPlugins());

    synchronized (this) {
      // only update the caches if the settings were actually changed
      if (cachedSystemSettings == null
          || !safeEquals(
              cachedSystemSettings.get(SystemSetting.LAST_SYSTEM_CONFIG_UPDATE_TIME),
              settings.get(SystemSetting.LAST_SYSTEM_CONFIG_UPDATE_TIME))) {
        cachedSystemSettings = settings;

        cachedObfuscatedSystemSettings = new SystemSettings(settings);
        for (Map.Entry<SystemSetting, String> entry : cachedObfuscatedSystemSettings.entrySet()) {
          String value = entry.getValue();
          if (value != null && entry.getKey().getType() == PropertySimpleType.PASSWORD) {
            entry.setValue(PicketBoxObfuscator.encode(value));
          }
        }
      }
    }
  }
Beispiel #9
0
  @Override
  public void setAnySystemSettings(
      SystemSettings settings, boolean skipValidation, boolean ignoreReadOnly) {
    // first, we need to get the current settings so we'll know if we need to persist or merge the
    // new ones
    @SuppressWarnings("unchecked")
    List<SystemConfiguration> configs =
        entityManager.createNamedQuery(SystemConfiguration.QUERY_FIND_ALL).getResultList();

    Map<String, SystemConfiguration> existingConfigMap = new HashMap<String, SystemConfiguration>();

    for (SystemConfiguration config : configs) {
      existingConfigMap.put(config.getPropertyKey(), config);
    }

    boolean changed = false;

    SystemConfiguration lastUpdateTime =
        existingConfigMap.get(SystemSetting.LAST_SYSTEM_CONFIG_UPDATE_TIME.getInternalName());

    // verify each new setting and persist them to the database
    // note that if a new setting is the same as the old one, we do nothing - leave the old entity
    // as is
    for (Map.Entry<SystemSetting, String> e : settings.entrySet()) {
      SystemSetting prop = e.getKey();

      String value = e.getValue();

      if (!skipValidation) {
        verifyNewSystemConfigurationProperty(prop, value, settings);
      }

      SystemConfiguration existingConfig = existingConfigMap.get(prop.getInternalName());
      if (e.getKey() == SystemSetting.LAST_SYSTEM_CONFIG_UPDATE_TIME) {
        // we don't let the user persist their own last system config update time
        // in any manner
        lastUpdateTime = existingConfig;
      } else if (existingConfig == null) {
        value = transformSystemConfigurationPropertyToDb(prop, value, null);
        existingConfig = new SystemConfiguration(prop.getInternalName(), value);
        entityManager.persist(existingConfig);
        changed = true;
        existingConfigMap.put(existingConfig.getPropertyKey(), existingConfig);
      } else {
        // make sure we compare the new value with a database-agnostic value
        // it is important to compare in the database-agnostic format instead
        // of database specific because the conversion isn't reflective.
        // Some legacy code somewhere is (or just used to) store booleans as "0"s and "1"s
        // even though they are stored as strings and thus don't suffer from Oracle's
        // lack of support for boolean data type. If we encounter such values, we convert
        // them to "false"/"true" and store that value to database. This is a one way operation
        // and therefore we need to compare the database-agnostic (i.e. "true"/"false") and
        // not database specific.
        //
        // More importantly though, we store the password fields obfuscated, so we need to compare
        // apples with
        // apples here.
        String existingValue =
            transformSystemConfigurationPropertyFromDb(
                prop, existingConfig.getPropertyValue(), true);
        // we need to unmask the new value so that we can compare for changes. only after that can
        // we transform
        // it into the DB format.
        value = unmask(prop, value, existingValue);

        // also for oracle, treat null and empty string as the same.
        if ((isEmpty(existingValue) && !isEmpty(value))
            || (null != existingValue && !existingValue.equals(value))) {
          // SystemSetting#isReadOnly should be a superset of the "fReadOnly" field in the database
          // but let's just be super paranoid here...
          if ((prop.isReadOnly()
                  || (existingConfig.getFreadOnly() != null
                      && existingConfig.getFreadOnly().booleanValue()))
              && !(isStorageSetting(prop) || ignoreReadOnly)) {
            throw new IllegalArgumentException(
                "The setting ["
                    + prop.getInternalName()
                    + "] is read-only - you cannot change its current value! Current value is ["
                    + existingConfig.getPropertyValue()
                    + "] while the new value was ["
                    + value
                    + "].");
          }

          // transform to the database-specific format
          value = transformSystemConfigurationPropertyToDb(prop, value, existingValue);

          existingConfig.setPropertyValue(value);
          entityManager.merge(existingConfig);
          changed = true;
        }
      }
    }

    if (changed) {
      if (lastUpdateTime == null) {
        lastUpdateTime =
            new SystemConfiguration(
                SystemSetting.LAST_SYSTEM_CONFIG_UPDATE_TIME.getInternalName(),
                Long.toString(System.currentTimeMillis()));
        lastUpdateTime.setFreadOnly(SystemSetting.LAST_SYSTEM_CONFIG_UPDATE_TIME.isReadOnly());
        entityManager.persist(lastUpdateTime);
      } else {
        lastUpdateTime.setPropertyValue(Long.toString(System.currentTimeMillis()));

        entityManager.merge(lastUpdateTime);
      }

      existingConfigMap.put(
          SystemSetting.LAST_SYSTEM_CONFIG_UPDATE_TIME.getInternalName(), lastUpdateTime);

      fillCache(existingConfigMap.values());
    }
  }