/* * Password Management Servlets (PWM) * http://www.pwm-project.org * * Copyright (c) 2006-2009 Novell, Inc. * Copyright (c) 2009-2017 The PWM Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package password.pwm.http.servlet.configeditor; import password.pwm.PwmApplication; import password.pwm.PwmConstants; import password.pwm.PwmEnvironment; import password.pwm.config.Configuration; import password.pwm.config.PwmSetting; import password.pwm.config.PwmSettingCategory; import password.pwm.config.StoredValue; import password.pwm.config.stored.StoredConfigurationImpl; import password.pwm.config.stored.StoredConfigurationUtil; import password.pwm.i18n.Config; import password.pwm.i18n.PwmLocaleBundle; import password.pwm.util.LocaleHelper; import password.pwm.util.java.StringUtil; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import java.util.TreeSet; class NavTreeHelper { static Set<String> determineModifiedKeysSettings( final PwmLocaleBundle bundle, final Configuration config, final StoredConfigurationImpl storedConfiguration ) { final Set<String> modifiedKeys = new TreeSet<>(); for (final String key : bundle.getKeys()) { final Map<String,String> storedBundle = storedConfiguration.readLocaleBundleMap(bundle.getTheClass().getName(),key); if (!storedBundle.isEmpty()) { for (final Locale locale : config.getKnownLocales()) { final ResourceBundle defaultBundle = ResourceBundle.getBundle(bundle.getTheClass().getName(), locale); final String localeKeyString = PwmConstants.DEFAULT_LOCALE.toString().equals(locale.toString()) ? "" : locale.toString(); if (storedBundle.containsKey(localeKeyString)) { final String value = storedBundle.get(localeKeyString); if (value != null && !value.equals(defaultBundle.getString(key))) { modifiedKeys.add(key); } } } } } return modifiedKeys; } static boolean categoryMatcher( final PwmApplication pwmApplication, final PwmSettingCategory category, final StoredConfigurationImpl storedConfiguration, final boolean modifiedOnly, final int minLevel, final String text ) { if (category.isHidden()) { return false; } if (category == PwmSettingCategory.HTTPS_SERVER) { if (!pwmApplication.getPwmEnvironment().getFlags().contains(PwmEnvironment.ApplicationFlag.ManageHttps)) { return false; } } for (final PwmSettingCategory childCategory : category.getChildCategories()) { if (categoryMatcher(pwmApplication, childCategory, storedConfiguration, modifiedOnly, minLevel, text)) { return true; } } if (category.hasProfiles()) { final List<String> profileIDs = storedConfiguration.profilesForSetting(category.getProfileSetting()); if (profileIDs == null || profileIDs.isEmpty()) { return true; } for (final String profileID : profileIDs) { for (final PwmSetting setting : category.getSettings()) { if (settingMatches(storedConfiguration,setting,profileID,modifiedOnly,minLevel,text)) { return true; } } } } else { for (final PwmSetting setting : category.getSettings()) { if (settingMatches(storedConfiguration,setting,null,modifiedOnly,minLevel,text)) { return true; } } } return false; } static List<PwmSettingCategory> filteredCategories( final PwmApplication pwmApplication, final StoredConfigurationImpl storedConfiguration, final Locale locale, final boolean modifiedSettingsOnly, final double level, final String filterText ) { final List<PwmSettingCategory> returnList = new ArrayList<>(); for (final PwmSettingCategory loopCategory : PwmSettingCategory.sortedValues(locale)) { if (NavTreeHelper.categoryMatcher( pwmApplication, loopCategory, storedConfiguration, modifiedSettingsOnly, (int) level, filterText )) { returnList.add(loopCategory); } } return returnList; } /** * Produces a collection of {@code NavTreeItem} * @param categories * @param storedConfiguration * @param locale * @return */ static List<NavTreeItem> makeSettingNavItems( final List<PwmSettingCategory> categories, final StoredConfigurationImpl storedConfiguration, final Locale locale ) { final List<NavTreeItem> navigationData = new ArrayList<>(); for (final PwmSettingCategory loopCategory : categories) { if (!loopCategory.hasProfiles()) { // regular category, so output a standard nav tree item navigationData.add(navTreeItemForCategory(loopCategory,locale,null)); } else { final List<String> profiles = StoredConfigurationUtil.profilesForCategory(loopCategory, storedConfiguration); final boolean topLevelProfileParent = loopCategory.isTopLevelProfile(); if (topLevelProfileParent) { // edit profile option navigationData.add(navTreeItemForCategory(loopCategory,locale,null)); { final NavTreeItem profileEditorInfo = new NavTreeItem(); profileEditorInfo.setId(loopCategory.getKey() + "-EDITOR"); final String editItemName = LocaleHelper.getLocalizedMessage(locale, Config.Label_ProfileListEditMenuItem, null); profileEditorInfo.setName(editItemName); profileEditorInfo.setType(NavTreeHelper.NavItemType.profileDefinition); profileEditorInfo.setProfileSetting(loopCategory.getProfileSetting().getKey()); profileEditorInfo.setParent(loopCategory.getKey()); navigationData.add(profileEditorInfo); } for (final String profileId : profiles) { final NavTreeItem profileInfo = navTreeItemForCategory(loopCategory, locale, profileId); profileInfo.setName(profileId.isEmpty() ? "Default" : profileId); profileInfo.setId("profile-" + loopCategory.getKey() + "-" + profileId); profileInfo.setParent(loopCategory.getKey()); if (loopCategory.getChildCategories().isEmpty()) { profileInfo.setType(NavItemType.category); } else { profileInfo.setType(NavItemType.navigation); } navigationData.add(profileInfo); } } else { for (final String profileId : profiles) { navigationData.add(navTreeItemForCategory(loopCategory,locale,profileId)); } } } } return navigationData; } private static NavTreeItem navTreeItemForCategory( final PwmSettingCategory category, final Locale locale, final String profileId ) { final NavTreeItem categoryItem = new NavTreeItem(); categoryItem.setId(category.getKey() + (profileId != null ? "-" + profileId : "")); categoryItem.setName(category.getLabel(locale)); categoryItem.setCategory(category.getKey()); if (category.getParent() != null) { if (profileId != null) { categoryItem.setParent("profile-" + category.getParent().getKey() + "-" + profileId); } else { categoryItem.setParent(category.getParent().getKey()); } } else { categoryItem.setParent("ROOT"); } if (category.getChildCategories().isEmpty() && !category.isTopLevelProfile()) { categoryItem.setType(NavTreeHelper.NavItemType.category); } else { categoryItem.setType(NavTreeHelper.NavItemType.navigation); } if (profileId != null) { categoryItem.setProfile(profileId); } categoryItem.setMenuLocation(category.toMenuLocationDebug(profileId,locale)); return categoryItem; } private static boolean settingMatches( final StoredConfigurationImpl storedConfiguration, final PwmSetting setting, final String profileID, final boolean modifiedOnly, final int level, final String text ) { if (setting.isHidden()) { return false; } if (modifiedOnly) { if (storedConfiguration.isDefaultValue(setting,profileID)) { return false; } } if (level > 0 && setting.getLevel() > level) { return false; } if (text == null || text.isEmpty()) { return true; } else { final StoredValue storedValue = storedConfiguration.readSetting(setting,profileID); for (final String term : StringUtil.whitespaceSplit(text)) { if (storedConfiguration.matchSetting(setting, storedValue, term, PwmConstants.DEFAULT_LOCALE)) { return true; } } } return false; } static void moveNavItemToTopOfList(final String categoryID, final List<NavTreeItem> navigationData) { { // put templates on top NavTreeItem templateEntry = null; for (final NavTreeItem entry : navigationData) { if (categoryID.equals(entry.getId())) { templateEntry = entry; } } if (templateEntry != null) { navigationData.remove(templateEntry); navigationData.add(0, templateEntry); } } } enum NavItemType { category, navigation, displayText, profile, profileDefinition, } }