mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
[MNT-24807] Implemented PropertyReplacer that replaces values of sensitive properties (e.g. passwords) during creation of NodeResource for event2
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -50,6 +50,7 @@ import org.alfresco.repo.event.v1.model.UserInfo;
|
||||
import org.alfresco.repo.event2.filter.EventFilterRegistry;
|
||||
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
||||
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
||||
import org.alfresco.repo.event2.replacer.PropertyReplacer;
|
||||
import org.alfresco.repo.node.MLPropertyInterceptor;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
@@ -87,6 +88,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
protected EventFilterRegistry eventFilterRegistry;
|
||||
protected NamespaceService namespaceService;
|
||||
protected PermissionService permissionService;
|
||||
protected PropertyReplacer propertyReplacer;
|
||||
|
||||
private NodeAspectFilter nodeAspectFilter;
|
||||
private NodePropertyFilter nodePropertyFilter;
|
||||
@@ -100,6 +102,7 @@ public class NodeResourceHelper implements InitializingBean
|
||||
PropertyCheck.mandatory(this, "eventFilterRegistry", eventFilterRegistry);
|
||||
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
|
||||
PropertyCheck.mandatory(this, "permissionService", permissionService);
|
||||
PropertyCheck.mandatory(this, "propertyReplacer", propertyReplacer);
|
||||
|
||||
this.nodeAspectFilter = eventFilterRegistry.getNodeAspectFilter();
|
||||
this.nodePropertyFilter = eventFilterRegistry.getNodePropertyFilter();
|
||||
@@ -137,6 +140,11 @@ public class NodeResourceHelper implements InitializingBean
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
public void setPropertyReplacer(PropertyReplacer propertyReplacer)
|
||||
{
|
||||
this.propertyReplacer = propertyReplacer;
|
||||
}
|
||||
|
||||
public NodeResource.Builder createNodeResourceBuilder(NodeRef nodeRef)
|
||||
{
|
||||
final QName type = nodeService.getType(nodeRef);
|
||||
@@ -215,8 +223,8 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
v = ((MLText) v).getDefaultValue();
|
||||
}
|
||||
|
||||
filteredProps.put(getQNamePrefixString(k), v);
|
||||
Serializable replacedValue = propertyReplacer.replace(k, v);
|
||||
filteredProps.put(getQNamePrefixString(k), replacedValue);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -232,7 +240,10 @@ public class NodeResourceHelper implements InitializingBean
|
||||
{
|
||||
final MLText mlTextValue = (MLText) v;
|
||||
final HashMap<String, String> localizedValues = new HashMap<>(mlTextValue.size());
|
||||
mlTextValue.forEach((locale, text) -> localizedValues.put(locale.toString(), text));
|
||||
mlTextValue.forEach((locale, text) -> {
|
||||
Serializable replacedValue = propertyReplacer.replace(k, v);
|
||||
localizedValues.put(locale.toString(), replacedValue.toString());
|
||||
});
|
||||
filteredProps.put(getQNamePrefixString(k), localizedValues);
|
||||
}
|
||||
});
|
||||
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.replacer;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
public class PropertyReplacer
|
||||
{
|
||||
private static final Set<QName> DEFAULT_SENSITIVE_PROPERTIES = Set.of(
|
||||
ContentModel.PROP_PASSWORD,
|
||||
ContentModel.PROP_SALT,
|
||||
ContentModel.PROP_PASSWORD_HASH,
|
||||
TransferModel.PROP_PASSWORD
|
||||
);
|
||||
private static final String DEFAULT_REPLACEMENT_TEXT = "SENSITIVE_DATA_REMOVED";
|
||||
|
||||
public Serializable replace(QName propertyQName, Serializable value)
|
||||
{
|
||||
if (DEFAULT_SENSITIVE_PROPERTIES.contains(propertyQName))
|
||||
{
|
||||
return DEFAULT_REPLACEMENT_TEXT;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
@@ -31,6 +31,8 @@
|
||||
</bean>
|
||||
<!-- End of Event2 Filters -->
|
||||
|
||||
<bean id="event2PropertyReplacer" class="org.alfresco.repo.event2.replacer.PropertyReplacer"/>
|
||||
|
||||
<bean id="baseEventGeneratorV2" abstract="true">
|
||||
<property name="policyComponent" ref="policyComponent"/>
|
||||
<property name="nodeService" ref="nodeService"/>
|
||||
@@ -53,6 +55,7 @@
|
||||
<property name="eventFilterRegistry" ref="event2FilterRegistry"/>
|
||||
<property name="namespaceService" ref="namespaceService"/>
|
||||
<property name="permissionService" ref="permissionService"/>
|
||||
<property name="propertyReplacer" ref="event2PropertyReplacer"/>
|
||||
</bean>
|
||||
|
||||
<bean id="baseEventSender" abstract="true">
|
||||
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.event2.replacer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.transfer.TransferModel;
|
||||
|
||||
public class PropertyReplacerUnitTest
|
||||
{
|
||||
private final PropertyReplacer propertyReplacer = new PropertyReplacer();
|
||||
|
||||
@Test
|
||||
public void shouldReplacePropertyValueWhenItsOneOfTheDefaultSensitiveProperties()
|
||||
{
|
||||
assertEquals("SENSITIVE_DATA_REMOVED", propertyReplacer.replace(ContentModel.PROP_PASSWORD, "test_pass"));
|
||||
assertEquals("SENSITIVE_DATA_REMOVED", propertyReplacer.replace(ContentModel.PROP_SALT, UUID.randomUUID().toString()));
|
||||
assertEquals("SENSITIVE_DATA_REMOVED", propertyReplacer.replace(ContentModel.PROP_PASSWORD_HASH, "r4nD0M_h4sH"));
|
||||
assertEquals("SENSITIVE_DATA_REMOVED", propertyReplacer.replace(TransferModel.PROP_PASSWORD, "pyramid"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotReplacePropertyValueWhenItsNotOneOfTheDefaultSensitiveProperties()
|
||||
{
|
||||
assertEquals("Bob", propertyReplacer.replace(ContentModel.PROP_USERNAME, "Bob"));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user