Browse Source

fix copy configuration profile functionality

Jason Rivard 5 years ago
parent
commit
76990f3535

+ 73 - 74
server/src/main/java/password/pwm/config/PwmSettingCategory.java

@@ -22,6 +22,7 @@ package password.pwm.config;
 
 import password.pwm.i18n.Config;
 import password.pwm.util.i18n.LocaleHelper;
+import password.pwm.util.java.LazySupplier;
 import password.pwm.util.java.XmlElement;
 
 import java.util.ArrayList;
@@ -189,10 +190,10 @@ public enum PwmSettingCategory
 
     private final PwmSettingCategory parent;
 
-    private transient Supplier<PwmSetting> profileSetting;
-    private transient Supplier<Integer> level;
-    private transient Supplier<Boolean> hidden;
-    private transient Supplier<Boolean> isTopLevelProfile;
+    private transient Supplier<Optional<PwmSetting>> profileSetting = new LazySupplier<>( () -> XmlReader.readProfileSettingFromXml( this, true ) );
+    private transient Supplier<Integer> level = new LazySupplier<>( () -> XmlReader.readLevel( this ) );
+    private transient Supplier<Boolean> hidden = new LazySupplier<>( () -> XmlReader.readHidden( this ) );
+    private transient Supplier<Boolean> isTopLevelProfile = new LazySupplier<>( () -> XmlReader.readIsTopLevelProfile( this ) );
 
 
     PwmSettingCategory( final PwmSettingCategory parent )
@@ -210,28 +211,18 @@ public enum PwmSettingCategory
         return this.toString();
     }
 
-    public password.pwm.config.PwmSetting getProfileSetting( )
+    public Optional<PwmSetting> getProfileSetting( )
     {
-        if ( profileSetting == null )
-        {
-            final PwmSetting setting = readProfileSettingFromXml( true );
-            profileSetting = ( ) -> setting;
-        }
         return profileSetting.get();
     }
 
     public boolean hasProfiles( )
     {
-        return getProfileSetting() != null;
+        return getProfileSetting().isPresent();
     }
 
     public boolean isTopLevelProfile( )
     {
-        if ( isTopLevelProfile == null )
-        {
-            final boolean output = readProfileSettingFromXml( false ) != null;
-            isTopLevelProfile = ( ) -> output;
-        }
         return isTopLevelProfile.get();
     }
 
@@ -249,41 +240,12 @@ public enum PwmSettingCategory
 
     public int getLevel( )
     {
-        if ( level == null )
-        {
-            final XmlElement settingElement = PwmSettingXml.readCategoryXml( this );
-            final String levelAttribute = settingElement.getAttributeValue( "level" );
-            final int output = levelAttribute != null ? Integer.parseInt( levelAttribute ) : 0;
-            level = ( ) -> output;
-        }
         return level.get();
     }
 
+
     public boolean isHidden( )
     {
-        if ( hidden == null )
-        {
-            final XmlElement settingElement = PwmSettingXml.readCategoryXml( this );
-            final String hiddenElement = settingElement.getAttributeValue( "hidden" );
-            if ( hiddenElement != null && "true".equalsIgnoreCase( hiddenElement ) )
-            {
-                hidden = () -> true;
-            }
-            else
-            {
-                for ( final PwmSettingCategory parentCategory : getParents() )
-                {
-                    if ( parentCategory.isHidden() )
-                    {
-                        hidden = () -> true;
-                    }
-                }
-            }
-            if ( hidden == null )
-            {
-                hidden = () -> false;
-            }
-        }
         return hidden.get();
     }
 
@@ -317,34 +279,6 @@ public enum PwmSettingCategory
         return returnObj;
     }
 
-    private password.pwm.config.PwmSetting readProfileSettingFromXml( final boolean nested )
-    {
-        PwmSettingCategory nextCategory = this;
-        while ( nextCategory != null )
-        {
-            final XmlElement categoryElement = PwmSettingXml.readCategoryXml( nextCategory );
-            final Optional<XmlElement> profileElement = categoryElement.getChild( "profile" );
-            if ( profileElement.isPresent() )
-            {
-                final String settingKey = profileElement.get().getAttributeValue( "setting" );
-                if ( settingKey != null )
-                {
-                    return password.pwm.config.PwmSetting.forKey( settingKey );
-                }
-            }
-            if ( nested )
-            {
-                nextCategory = nextCategory.getParent();
-            }
-            else
-            {
-                nextCategory = null;
-            }
-        }
-
-        return null;
-    }
-
     public List<PwmSetting> getSettings( )
     {
         final List<password.pwm.config.PwmSetting> returnList = new ArrayList<>();
@@ -464,4 +398,69 @@ public enum PwmSettingCategory
                 .findFirst()
                 .orElse( null );
     }
+
+    private static class XmlReader
+    {
+
+        private static Optional<PwmSetting> readProfileSettingFromXml( final PwmSettingCategory category, final boolean nested )
+        {
+            PwmSettingCategory nextCategory = category;
+            while ( nextCategory != null )
+            {
+                final XmlElement categoryElement = PwmSettingXml.readCategoryXml( nextCategory );
+                final Optional<XmlElement> profileElement = categoryElement.getChild( "profile" );
+                if ( profileElement.isPresent() )
+                {
+                    final String settingKey = profileElement.get().getAttributeValue( "setting" );
+                    if ( settingKey != null )
+                    {
+                        return Optional.of( PwmSetting.forKey( settingKey ) );
+                    }
+                }
+                if ( nested )
+                {
+                    nextCategory = nextCategory.getParent();
+                }
+                else
+                {
+                    nextCategory = null;
+                }
+            }
+
+            return Optional.empty();
+        }
+
+        private static int readLevel( final PwmSettingCategory category )
+        {
+            final XmlElement settingElement = PwmSettingXml.readCategoryXml( category );
+            final String levelAttribute = settingElement.getAttributeValue( "level" );
+            return levelAttribute != null ? Integer.parseInt( levelAttribute ) : 0;
+        }
+
+        private static boolean readHidden( final PwmSettingCategory category )
+        {
+            final XmlElement settingElement = PwmSettingXml.readCategoryXml( category );
+            final String hiddenElement = settingElement.getAttributeValue( "hidden" );
+            if ( hiddenElement != null && "true".equalsIgnoreCase( hiddenElement ) )
+            {
+                return true;
+            }
+            else
+            {
+                for ( final PwmSettingCategory parentCategory : category.getParents() )
+                {
+                    if ( parentCategory.isHidden() )
+                    {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        private static boolean readIsTopLevelProfile( final PwmSettingCategory category )
+        {
+            return readProfileSettingFromXml( category, false ).isPresent();
+        }
+    }
 }

+ 1 - 1
server/src/main/java/password/pwm/config/profile/ProfileUtility.java

@@ -93,7 +93,7 @@ public class ProfileUtility
 
     public static List<String> profileIDsForCategory( final Configuration configuration, final PwmSettingCategory pwmSettingCategory )
     {
-        final PwmSetting profileSetting = pwmSettingCategory.getProfileSetting();
+        final PwmSetting profileSetting = pwmSettingCategory.getProfileSetting().orElseThrow( IllegalStateException::new );
         return configuration.readSettingAsStringArray( profileSetting );
     }
 

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigurationFactory.java

@@ -250,7 +250,7 @@ public class StoredConfigurationFactory
             }
             else
             {
-                profileSetting = pwmSetting.getCategory().getProfileSetting();
+                profileSetting = pwmSetting.getCategory().getProfileSetting().orElseThrow( IllegalStateException::new );
             }
 
             final StoredValue effectiveValue;

+ 17 - 7
server/src/main/java/password/pwm/config/stored/StoredConfigurationModifier.java

@@ -39,6 +39,7 @@ import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -195,7 +196,8 @@ public class StoredConfigurationModifier
         {
             final StoredConfiguration oldStoredConfiguration = new StoredConfigurationImpl( storedConfigData );
 
-            final List<String> existingProfiles = oldStoredConfiguration.profilesForSetting( category.getProfileSetting() );
+            final PwmSetting profileSetting = category.getProfileSetting().orElseThrow( IllegalStateException::new );
+            final List<String> existingProfiles = StoredConfigurationUtil.profilesForSetting( profileSetting, oldStoredConfiguration );
             if ( !existingProfiles.contains( sourceID ) )
             {
                 throw PwmUnrecoverableException.newException(
@@ -209,6 +211,8 @@ public class StoredConfigurationModifier
             }
 
             final Collection<PwmSettingCategory> interestedCategories = PwmSettingCategory.associatedProfileCategories( category );
+            final Map<StoredConfigItemKey, StoredValue> newValues = new LinkedHashMap<>();
+
             for ( final PwmSettingCategory interestedCategory : interestedCategories )
             {
                 for ( final PwmSetting pwmSetting : interestedCategory.getSettings() )
@@ -216,19 +220,25 @@ public class StoredConfigurationModifier
                     if ( !oldStoredConfiguration.isDefaultValue( pwmSetting, sourceID ) )
                     {
                         final StoredValue value = oldStoredConfiguration.readSetting( pwmSetting, sourceID );
-                        writeSetting( pwmSetting, destinationID, value, userIdentity );
+                        final StoredConfigItemKey key = StoredConfigItemKey.fromSetting( pwmSetting, destinationID );
+                        newValues.put( key, value );
                     }
                 }
             }
-            final List<String> newProfileIDList = new ArrayList<>( existingProfiles );
-            newProfileIDList.add( destinationID );
 
-            final StoredValue value = new StringArrayValue( newProfileIDList );
-            final StoredConfigItemKey key = StoredConfigItemKey.fromSetting( category.getProfileSetting(), null );
+            {
+                final List<String> newProfileIDList = new ArrayList<>( existingProfiles );
+                newProfileIDList.add( destinationID );
+                final StoredConfigItemKey key = StoredConfigItemKey.fromSetting( profileSetting, null );
+                final StoredValue value = new StringArrayValue( newProfileIDList );
+                newValues.put( key, value );
+            }
+
+            final StoredConfigItemKey key = StoredConfigItemKey.fromSetting( category.getProfileSetting().orElseThrow( IllegalStateException::new ), null );
             final ValueMetaData valueMetaData = new ValueMetaData( Instant.now(), userIdentity );
 
             return storedConfigData.toBuilder()
-                    .storedValue( key, value )
+                    .storedValues( newValues )
                     .metaData( key, valueMetaData )
                     .build();
 

+ 4 - 19
server/src/main/java/password/pwm/config/stored/StoredConfigurationUtil.java

@@ -76,7 +76,7 @@ public abstract class StoredConfigurationUtil
         }
         else
         {
-            profileSetting = pwmSetting.getCategory().getProfileSetting();
+            profileSetting = pwmSetting.getCategory().getProfileSetting().orElseThrow( IllegalStateException::new );
         }
 
         return profilesForProfileSetting( profileSetting, storedConfiguration );
@@ -87,35 +87,20 @@ public abstract class StoredConfigurationUtil
             final StoredConfiguration storedConfiguration
     )
     {
-        final PwmSetting profileSetting = category.getProfileSetting();
+        final PwmSetting profileSetting = category.getProfileSetting().orElseThrow( IllegalStateException::new );
 
         return profilesForProfileSetting( profileSetting, storedConfiguration );
     }
 
     private static List<String> profilesForProfileSetting(
-            final PwmSetting pwmSetting,
+            final PwmSetting profileSetting,
             final StoredConfiguration storedConfiguration
     )
     {
-        if ( !pwmSetting.getCategory().hasProfiles() && pwmSetting.getSyntax() != PwmSettingSyntax.PROFILE )
-        {
-            throw new IllegalArgumentException( "cannot build profile list for non-profile setting " + pwmSetting.toString() );
-        }
-
-        final PwmSetting profileSetting;
-        if ( pwmSetting.getSyntax() == PwmSettingSyntax.PROFILE )
-        {
-            profileSetting = pwmSetting;
-        }
-        else
-        {
-            profileSetting = pwmSetting.getCategory().getProfileSetting();
-        }
-
         final Object nativeObject = storedConfiguration.readSetting( profileSetting, null ).toNativeObject();
         final List<String> settingValues = ( List<String> ) nativeObject;
         final LinkedList<String> profiles = new LinkedList<>( settingValues );
-        profiles.removeIf( profile -> StringUtil.isEmpty( profile ) );
+        profiles.removeIf( StringUtil::isEmpty );
         return Collections.unmodifiableList( profiles );
 
     }

+ 7 - 2
server/src/main/java/password/pwm/http/auth/HttpAuthenticationUtilities.java

@@ -88,6 +88,11 @@ public abstract class HttpAuthenticationUtilities
                             return ProcessStatus.Halt;
                         }
 
+                        if ( pwmRequest.isAuthenticated() )
+                        {
+                            return ProcessStatus.Continue;
+                        }
+
                     }
                     catch ( final Exception e )
                     {
@@ -96,13 +101,13 @@ public abstract class HttpAuthenticationUtilities
                         {
                             final String errorMsg = "error during " + authenticationMethod + " authentication attempt: " + e.getMessage();
                             errorInformation = new ErrorInformation( ( ( PwmException ) e ).getError(), errorMsg );
+                            LOGGER.error( pwmRequest, errorInformation );
                         }
                         else
                         {
                             errorInformation = new ErrorInformation( PwmError.ERROR_INTERNAL, e.getMessage() );
-
+                            LOGGER.error( pwmRequest.getLabel(), errorInformation, e );
                         }
-                        LOGGER.error( pwmRequest, errorInformation );
                         pwmRequest.respondWithError( errorInformation );
                         return ProcessStatus.Halt;
                     }

+ 9 - 1
server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java

@@ -100,6 +100,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.StringTokenizer;
@@ -1061,7 +1062,8 @@ public class ConfigEditorServlet extends ControlledPwmServlet
         {
             if ( loopCategory.hasProfiles() )
             {
-                if ( loopCategory.getProfileSetting() == setting )
+                final Optional<PwmSetting> profileSetting = loopCategory.getProfileSetting();
+                if ( profileSetting.isPresent() && profileSetting.get() == setting )
                 {
                     category = loopCategory;
                 }
@@ -1070,6 +1072,12 @@ public class ConfigEditorServlet extends ControlledPwmServlet
 
         final String sourceID = inputMap.get( "sourceID" );
         final String destinationID = inputMap.get( "destinationID" );
+
+        if ( category == null )
+        {
+            throw new IllegalStateException();
+        }
+
         try
         {
             modifier.copyProfileID( category, sourceID, destinationID, pwmRequest.getUserInfoIfLoggedIn() );

+ 6 - 2
server/src/main/java/password/pwm/http/servlet/configeditor/NavTreeHelper.java

@@ -106,11 +106,14 @@ class NavTreeHelper
 
         if ( category.hasProfiles() )
         {
-            final List<String> profileIDs = storedConfiguration.profilesForSetting( category.getProfileSetting() );
+            final List<String> profileIDs = storedConfiguration.profilesForSetting(
+                    category.getProfileSetting().orElseThrow( IllegalStateException::new ) );
+
             if ( profileIDs == null || profileIDs.isEmpty() )
             {
                 return true;
             }
+
             for ( final String profileID : profileIDs )
             {
                 for ( final PwmSetting setting : category.getSettings() )
@@ -199,7 +202,8 @@ class NavTreeHelper
                         final String editItemName = LocaleHelper.getLocalizedMessage( locale, Config.Label_ProfileListEditMenuItem, null );
                         profileEditorInfo.setName( editItemName );
                         profileEditorInfo.setType( NavTreeHelper.NavItemType.profileDefinition );
-                        profileEditorInfo.setProfileSetting( loopCategory.getProfileSetting().getKey() );
+                        final PwmSetting profileSetting = loopCategory.getProfileSetting().orElseThrow( IllegalStateException::new );
+                        profileEditorInfo.setProfileSetting( profileSetting.getKey() );
                         profileEditorInfo.setParent( loopCategory.getKey() );
                         navigationData.add( profileEditorInfo );
                     }

+ 1 - 1
server/src/main/java/password/pwm/http/state/CryptoCookieLoginImpl.java

@@ -128,7 +128,7 @@ class CryptoCookieLoginImpl implements SessionLoginProvider
 
                 if ( remoteLoginCookie.getType() == AuthenticationType.AUTH_WITHOUT_PASSWORD && remoteLoginCookie.getUserCurrentPassword() == null )
                 {
-                    LOGGER.debug( () -> "remote session has authType " + AuthenticationType.AUTH_WITHOUT_PASSWORD.name()
+                    LOGGER.debug( pwmRequest, () -> "remote session has authType " + AuthenticationType.AUTH_WITHOUT_PASSWORD.name()
                             + " and does not contain password, thus ignoring authentication so SSO process can repeat" );
                     return;
                 }

+ 0 - 1
server/src/main/java/password/pwm/util/logging/PwmLogger.java

@@ -244,7 +244,6 @@ public class PwmLogger
         }
     }
 
-
     private static String convertErrorInformation( final ErrorInformation info )
     {
         return info.toDebugStr();

+ 1 - 1
server/src/test/java/password/pwm/config/PwmSettingCategoryTest.java

@@ -66,7 +66,7 @@ public class PwmSettingCategoryTest
         {
             if ( category.hasProfiles() )
             {
-                final PwmSetting pwmSetting = category.getProfileSetting();
+                final PwmSetting pwmSetting = category.getProfileSetting().orElseThrow( IllegalStateException::new );
                 Assert.assertEquals( pwmSetting.getSyntax(), PwmSettingSyntax.PROFILE );
             }
         }

+ 68 - 0
server/src/test/java/password/pwm/config/stored/StoredConfigurationModifierTest.java

@@ -0,0 +1,68 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2019 The PWM Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package password.pwm.config.stored;
+
+import org.junit.Assert;
+import org.junit.Test;
+import password.pwm.config.PwmSetting;
+import password.pwm.config.value.NumericValue;
+import password.pwm.config.value.StringValue;
+import password.pwm.error.PwmUnrecoverableException;
+
+import java.util.List;
+
+public class StoredConfigurationModifierTest
+{
+
+    @Test
+    public void testWriteSetting() throws PwmUnrecoverableException
+    {
+        final StoredConfiguration storedConfiguration = StoredConfigurationFactory.newConfig();
+        final StoredConfigurationModifier modifier = StoredConfigurationModifier.newModifier( storedConfiguration );
+
+        modifier.writeSetting( PwmSetting.NOTES, null, new StringValue( "notes test" ), null );
+
+        final StoredConfiguration newConfig = modifier.newStoredConfiguration();
+
+        final String notesText = ( ( String ) newConfig.readSetting( PwmSetting.NOTES, null ).toNativeObject() );
+        Assert.assertEquals( notesText, "notes test" );
+    }
+
+    @Test
+    public void testCopyProfileID() throws PwmUnrecoverableException
+    {
+        final StoredConfiguration storedConfiguration = StoredConfigurationFactory.newConfig();
+        final StoredConfigurationModifier modifier = StoredConfigurationModifier.newModifier( storedConfiguration );
+
+        modifier.writeSetting( PwmSetting.HELPDESK_RESULT_LIMIT, "default", new NumericValue( 19 ), null );
+        modifier.copyProfileID( PwmSetting.HELPDESK_RESULT_LIMIT.getCategory(), "default", "newProfile", null );
+
+        final StoredConfiguration newConfig = modifier.newStoredConfiguration();
+
+        final List<String> profileNames = newConfig.profilesForSetting( PwmSetting.HELPDESK_RESULT_LIMIT );
+        Assert.assertEquals( profileNames.size(), 2 );
+        Assert.assertTrue( profileNames.contains( "default" ) );
+        Assert.assertTrue( profileNames.contains( "newProfile" ) );
+
+        final long copiedResultLimit = ( ( long ) newConfig.readSetting( PwmSetting.HELPDESK_RESULT_LIMIT, "default" ).toNativeObject() );
+        Assert.assertEquals( copiedResultLimit, 19 );
+    }
+}

+ 57 - 0
server/src/test/java/password/pwm/config/stored/StoredConfigurationUtilTest.java

@@ -0,0 +1,57 @@
+/*
+ * Password Management Servlets (PWM)
+ * http://www.pwm-project.org
+ *
+ * Copyright (c) 2006-2009 Novell, Inc.
+ * Copyright (c) 2009-2019 The PWM Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package password.pwm.config.stored;
+
+import org.junit.Assert;
+import org.junit.Test;
+import password.pwm.config.PwmSetting;
+import password.pwm.config.value.StringValue;
+import password.pwm.error.PwmUnrecoverableException;
+
+import java.util.Set;
+
+public class StoredConfigurationUtilTest
+{
+
+    @Test
+    public void testChangedValues() throws PwmUnrecoverableException
+    {
+        final StoredConfiguration storedConfiguration = StoredConfigurationFactory.newConfig();
+        final StoredConfigurationModifier modifier = StoredConfigurationModifier.newModifier( storedConfiguration );
+
+        modifier.writeSetting( PwmSetting.NOTES, null, new StringValue( "notes test" ), null );
+
+        final StoredConfiguration newConfig = modifier.newStoredConfiguration();
+
+        final Set<StoredConfigItemKey> modifiedKeys = StoredConfigurationUtil.changedValues( storedConfiguration, newConfig );
+        Assert.assertEquals( modifiedKeys.size(), 1 );
+        Assert.assertEquals( modifiedKeys.iterator().next(), StoredConfigItemKey.fromSetting( PwmSetting.NOTES, null ) );
+
+
+        final StoredConfigurationModifier modifier2 = StoredConfigurationModifier.newModifier( newConfig );
+        modifier2.resetSetting( PwmSetting.NOTES, null, null );
+        final StoredConfiguration resetConfig = modifier2.newStoredConfiguration();
+        final Set<StoredConfigItemKey> resetKeys = StoredConfigurationUtil.changedValues( newConfig, resetConfig );
+        Assert.assertEquals( resetKeys.size(), 1 );
+        Assert.assertEquals( resetKeys.iterator().next(), StoredConfigItemKey.fromSetting( PwmSetting.NOTES, null ) );
+
+    }
+}