mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-10 14:11:58 +00:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6c68658476 | ||
|
1bd439e0ec | ||
|
72f84ee50b | ||
|
50f26b9137 | ||
|
b6b1cc3ea0 | ||
|
0f1c1cdba1 | ||
|
841bc6844e | ||
|
a5bdf47f00 | ||
|
a0b279d1ff | ||
|
fb967dfa9e | ||
|
f0a51e1347 | ||
|
42d56f9d20 | ||
|
3f31e4b1a2 | ||
|
787a331869 | ||
|
5ce3a3ddd6 | ||
|
9ed96ec593 | ||
|
03b1fa8b09 | ||
|
d69f9b52c3 |
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
6
pom.xml
6
pom.xml
@@ -2,7 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<dependency.jackson-databind.version>2.12.4</dependency.jackson-databind.version>
|
||||
<dependency.cxf.version>3.4.4</dependency.cxf.version>
|
||||
<dependency.opencmis.version>1.0.0</dependency.opencmis.version>
|
||||
<dependency.webscripts.version>8.23</dependency.webscripts.version>
|
||||
<dependency.webscripts.version>8.26</dependency.webscripts.version>
|
||||
<dependency.bouncycastle.version>1.69</dependency.bouncycastle.version>
|
||||
<dependency.mockito-core.version>3.11.2</dependency.mockito-core.version>
|
||||
<dependency.mockito-all.version>1.10.19</dependency.mockito-all.version>
|
||||
@@ -142,7 +142,7 @@
|
||||
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
||||
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
||||
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
||||
<tag>12.2</tag>
|
||||
<tag>12.8</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 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%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 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.web.scripts.quickshare;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -31,10 +31,12 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.QuickShareModel;
|
||||
import org.alfresco.repo.tenant.TenantUtil;
|
||||
import org.alfresco.service.cmr.quickshare.InvalidSharedIdException;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.webscripts.Cache;
|
||||
@@ -82,14 +84,15 @@ public class UnshareContentDelete extends AbstractQuickShareContent
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
Pair<String, NodeRef> pair = quickShareService.getTenantNodeRefFromSharedId(sharedId);
|
||||
String networkTenantDomain = pair.getFirst();
|
||||
|
||||
String sharedBy = (String) nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedBy))
|
||||
TenantUtil.runAsSystemTenant(() ->
|
||||
{
|
||||
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
quickShareService.unshareContent(sharedId);
|
||||
checkIfCanDeleteSharedLink(sharedId);
|
||||
quickShareService.unshareContent(sharedId);
|
||||
return null;
|
||||
}, networkTenantDomain);
|
||||
|
||||
Map<String, Object> model = new HashMap<>(1);
|
||||
model.put("success", Boolean.TRUE);
|
||||
@@ -106,4 +109,14 @@ public class UnshareContentDelete extends AbstractQuickShareContent
|
||||
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find: " + sharedId);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIfCanDeleteSharedLink(String sharedId) {
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
|
||||
String sharedBy = (String) nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedBy))
|
||||
{
|
||||
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
}
|
||||
}
|
@@ -274,15 +274,15 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
Pair<String, NodeRef> pair = quickShareService.getTenantNodeRefFromSharedId(sharedId);
|
||||
String networkTenantDomain = pair.getFirst();
|
||||
|
||||
String sharedByUserId = (String)nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedByUserId))
|
||||
TenantUtil.runAsSystemTenant(() ->
|
||||
{
|
||||
throw new PermissionDeniedException("Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
|
||||
quickShareService.unshareContent(sharedId);
|
||||
checkIfCanDeleteSharedLink(sharedId);
|
||||
quickShareService.unshareContent(sharedId);
|
||||
return null;
|
||||
}, networkTenantDomain);
|
||||
}
|
||||
catch (InvalidSharedIdException ex)
|
||||
{
|
||||
@@ -698,4 +698,14 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
|
||||
throw new InvalidArgumentException("A valid recipientEmail must be specified.");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIfCanDeleteSharedLink(String sharedId) {
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
|
||||
String sharedByUserId = (String)nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedByUserId))
|
||||
{
|
||||
throw new PermissionDeniedException("Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1070,7 +1070,7 @@
|
||||
<property name="enabled" value="${system.api.discovery.enabled}" />
|
||||
<property name="thumbnailService" ref="ThumbnailService" />
|
||||
<property name="restApiDirectUrlConfig" ref="restApiDirectUrlConfig" />
|
||||
<property name="contentService" ref="ContentService" />
|
||||
<property name="contentService" ref="contentService" />
|
||||
</bean>
|
||||
|
||||
<bean id="org.alfresco.rest.api.probes.ProbeEntityResource.get" class="org.alfresco.rest.api.probes.ProbeEntityResource">
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>12.2</version>
|
||||
<version>12.8</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -415,12 +415,13 @@ implements TenantDeployer, DictionaryListener, /*TenantDictionaryListener, */Mes
|
||||
|
||||
for (NodeRef messageResource : nodeRefs)
|
||||
{
|
||||
String resourceName = (String) nodeService.getProperty(messageResource, ContentModel.PROP_NAME);
|
||||
|
||||
String bundleBaseName = messageService.getBaseBundleName(resourceName);
|
||||
String messageResourcePath = nodeService.getPath(messageResource).toPrefixString(namespaceService);
|
||||
String bundleBasePrefixedName = messageResourcePath.substring(messageResourcePath.lastIndexOf("/"));
|
||||
String bundleBaseName = messageService.getBaseBundleName(bundleBasePrefixedName);
|
||||
|
||||
if (!resourceBundleBaseNames.contains(bundleBaseName))
|
||||
{
|
||||
messageService.registerResourceBundle(storeRef.toString() + repositoryLocation.getPath() + bundleBaseName);
|
||||
resourceBundleBaseNames.add(bundleBaseName);
|
||||
}
|
||||
}
|
||||
|
@@ -1,30 +1,33 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 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%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 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.security.permissions.impl.acegi;
|
||||
|
||||
import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.getNodeRef;
|
||||
import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.shouldAbstainOrDeny;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
@@ -46,8 +49,6 @@ import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.OwnableService;
|
||||
@@ -59,6 +60,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
|
||||
/**
|
||||
* @author andyh
|
||||
*/
|
||||
@@ -395,61 +397,53 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
{
|
||||
throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef");
|
||||
}
|
||||
else if (StoreRef.class.isAssignableFrom(params[cad.parameter[0]]))
|
||||
|
||||
if (List.class.isAssignableFrom(params[cad.parameter[0]]))
|
||||
{
|
||||
StoreRef storeRef = getArgument(invocation, cad.parameter[0]);
|
||||
if (storeRef != null)
|
||||
List<?> listArgument = getArgument(invocation, cad.parameter[0]);
|
||||
if (listArgument != null)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
NodeRef listNodeRef;
|
||||
Integer accessAbstainOrDeny = null;
|
||||
for (Object listElement : listArgument)
|
||||
{
|
||||
log.debug("\tPermission test against the store - using permissions on the root node");
|
||||
}
|
||||
if (nodeService.exists(storeRef))
|
||||
{
|
||||
testNodeRef = nodeService.getRootNode(storeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (NodeRef.class.isAssignableFrom(params[cad.parameter[0]]))
|
||||
{
|
||||
testNodeRef = getArgument(invocation, cad.parameter[0]);
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
if (testNodeRef != null)
|
||||
{
|
||||
if (nodeService.exists(testNodeRef))
|
||||
listNodeRef = getNodeRef(listElement, nodeService);
|
||||
Integer currentValue = shouldAbstainOrDeny(cad.required, listNodeRef, abstainForClassQNames, nodeService, permissionService);
|
||||
|
||||
if (currentValue != null)
|
||||
{
|
||||
log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef));
|
||||
if (currentValue == AccessDecisionVoter.ACCESS_DENIED)
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
accessAbstainOrDeny = currentValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("\tPermission test on non-existing node " +testNodeRef);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ChildAssociationRef.class.isAssignableFrom(params[cad.parameter[0]]))
|
||||
{
|
||||
ChildAssociationRef testChildRef = getArgument(invocation, cad.parameter[0]);
|
||||
if (testChildRef != null)
|
||||
{
|
||||
testNodeRef = testChildRef.getChildRef();
|
||||
if (log.isDebugEnabled())
|
||||
|
||||
if (accessAbstainOrDeny != null)
|
||||
{
|
||||
if (nodeService.exists(testNodeRef))
|
||||
{
|
||||
log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef));
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("\tPermission test on non-existing node " + testNodeRef);
|
||||
}
|
||||
return accessAbstainOrDeny;
|
||||
}
|
||||
if((hasMethodEntry == null) || (hasMethodEntry.booleanValue()))
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef");
|
||||
Object testObject = getArgument(invocation, cad.parameter[0]);
|
||||
//If the execution reaches here, then testNodeRef is always null
|
||||
testNodeRef = getNodeRef(testObject, nodeService);
|
||||
}
|
||||
}
|
||||
else if (cad.typeString.equals(ACL_ITEM))
|
||||
@@ -584,44 +578,10 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
|
||||
}
|
||||
}
|
||||
|
||||
if (testNodeRef != null)
|
||||
Integer accessAbstainOrDeny = shouldAbstainOrDeny(cad.required, testNodeRef, abstainForClassQNames, nodeService, permissionService);
|
||||
if (accessAbstainOrDeny != null)
|
||||
{
|
||||
// now we know the node - we can abstain for certain types and aspects (eg. RM)
|
||||
if(abstainForClassQNames.size() > 0)
|
||||
{
|
||||
// check node exists
|
||||
if (nodeService.exists(testNodeRef))
|
||||
{
|
||||
QName typeQName = nodeService.getType(testNodeRef);
|
||||
if(abstainForClassQNames.contains(typeQName))
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
}
|
||||
|
||||
Set<QName> aspectQNames = nodeService.getAspects(testNodeRef);
|
||||
for(QName abstain : abstainForClassQNames)
|
||||
{
|
||||
if(aspectQNames.contains(abstain))
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("\t\tNode ref is not null");
|
||||
}
|
||||
if (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("\t\tPermission is denied");
|
||||
Thread.dumpStack();
|
||||
}
|
||||
return AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
return accessAbstainOrDeny;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 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.security.permissions.impl.acegi;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
||||
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Utility methods extracted from AclEntryVoter
|
||||
*
|
||||
* @author Lev Belava
|
||||
*/
|
||||
final class ACLEntryVoterUtils
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ACLEntryVoterUtils.class);
|
||||
|
||||
private ACLEntryVoterUtils()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets NodeRef for testObject based on inferred type
|
||||
*
|
||||
* @param testObject Tested object to work on
|
||||
* @param nodeService Node service to perform checks on refs
|
||||
* @return NodeRef for testObject or null if (testObject is null or StoreRef from testObject does not exist in the provided NodeService)
|
||||
* @throws ACLEntryVoterException if testObject is not null and not one of a NodeRef or ChildAssociationRef types
|
||||
*/
|
||||
static NodeRef getNodeRef(Object testObject, NodeService nodeService)
|
||||
{
|
||||
if (testObject == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (StoreRef.class.isAssignableFrom(testObject.getClass()))
|
||||
{
|
||||
LOG.debug("Permission test against the store - using permissions on the root node");
|
||||
StoreRef storeRef = (StoreRef) testObject;
|
||||
if (nodeService.exists(storeRef))
|
||||
{
|
||||
return nodeService.getRootNode(storeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("StoreRef does not exist");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (NodeRef.class.isAssignableFrom(testObject.getClass()))
|
||||
{
|
||||
NodeRef result = (NodeRef) testObject;
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
if (nodeService.exists(result))
|
||||
{
|
||||
LOG.debug("Permission test on node {}", nodeService.getPath(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("Permission test on non-existing node {}", result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (ChildAssociationRef.class.isAssignableFrom(testObject.getClass()))
|
||||
{
|
||||
ChildAssociationRef testChildRef = (ChildAssociationRef) testObject;
|
||||
NodeRef result = testChildRef.getChildRef();
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
if (nodeService.exists(result))
|
||||
{
|
||||
LOG.debug("Permission test on node {}", nodeService.getPath(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.debug("Permission test on non-existing node {}", result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if tested NodeRef instance is abstained or denied based on set of QNames to abstain and
|
||||
*
|
||||
* @param requiredPermissionReference Required permissions
|
||||
* @param testNodeRef NodeRef to be verified
|
||||
* @param abstainForClassQNames Set of QNames to abstain
|
||||
* @param nodeService Node service to perform checks on tested NodeRef
|
||||
* @param permissionService Permission service to check for required permissions
|
||||
* @return null if testNodeRef is not abstained or denied, otherwise returns appropriate status.
|
||||
*/
|
||||
static Integer shouldAbstainOrDeny(SimplePermissionReference requiredPermissionReference, NodeRef testNodeRef, Set<QName> abstainForClassQNames,
|
||||
NodeService nodeService, PermissionService permissionService)
|
||||
{
|
||||
if (testNodeRef == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
LOG.debug("Node ref is not null");
|
||||
|
||||
if (abstainForClassQNames.size() > 0 && nodeService.exists(testNodeRef))
|
||||
{
|
||||
if (abstainForClassQNames.contains(nodeService.getType(testNodeRef)))
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
}
|
||||
Set<QName> testNodeRefAspects = nodeService.getAspects(testNodeRef);
|
||||
for (QName abstain : abstainForClassQNames)
|
||||
{
|
||||
if (testNodeRefAspects.contains(abstain))
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AccessStatus.DENIED == permissionService.hasPermission(testNodeRef, requiredPermissionReference.toString()))
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
{
|
||||
LOG.debug("Permission is denied");
|
||||
Thread.dumpStack();
|
||||
}
|
||||
return AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -209,6 +209,7 @@ import org.junit.runners.Suite;
|
||||
org.alfresco.repo.security.authentication.AuthorizationTest.class,
|
||||
org.alfresco.repo.security.permissions.PermissionCheckedCollectionTest.class,
|
||||
org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSetTest.class,
|
||||
org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtilsTest.class,
|
||||
org.alfresco.repo.security.authentication.ChainingAuthenticationServiceTest.class,
|
||||
org.alfresco.repo.security.authentication.NameBasedUserNameGeneratorTest.class,
|
||||
org.alfresco.repo.version.common.VersionImplTest.class,
|
||||
|
@@ -31,17 +31,18 @@ import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||
import org.alfresco.repo.dictionary.NamespaceDAO;
|
||||
import org.alfresco.repo.i18n.MessageService;
|
||||
import org.alfresco.repo.node.db.DbNodeServiceImpl;
|
||||
import org.alfresco.repo.policy.BehaviourFilter;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
@@ -50,6 +51,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti
|
||||
import org.alfresco.service.cmr.admin.RepoAdminService;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -67,6 +69,8 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @see RepoAdminServiceImpl
|
||||
*
|
||||
@@ -88,6 +92,7 @@ public class RepoAdminServiceImplTest extends TestCase
|
||||
private NamespaceService namespaceService;
|
||||
private BehaviourFilter behaviourFilter;
|
||||
private DictionaryDAO dictionaryDAO;
|
||||
private MessageService messageService;
|
||||
|
||||
final String modelPrefix = "model-";
|
||||
final static String MKR = "{MKR}";
|
||||
@@ -140,6 +145,7 @@ public class RepoAdminServiceImplTest extends TestCase
|
||||
namespaceService = (NamespaceService) ctx.getBean("NamespaceService");
|
||||
behaviourFilter = (BehaviourFilter)ctx.getBean("policyBehaviourFilter");
|
||||
dictionaryDAO = (DictionaryDAO) ctx.getBean("dictionaryDAO");
|
||||
messageService = (MessageService) ctx.getBean("MessageService");
|
||||
|
||||
DbNodeServiceImpl dbNodeService = (DbNodeServiceImpl)ctx.getBean("dbNodeService");
|
||||
dbNodeService.setEnableTimestampPropagation(false);
|
||||
@@ -865,8 +871,182 @@ public class RepoAdminServiceImplTest extends TestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TODO - Test custom message management
|
||||
//
|
||||
|
||||
// Test deploy bundle from classpath
|
||||
public void testDeployMessageBundleFromClasspath() throws Exception
|
||||
{
|
||||
String bundleBaseName = "mycustommessages";
|
||||
String resourceClasspath = "alfresco/extension/messages/" + bundleBaseName;
|
||||
|
||||
final String message_key = "mycustommessages.key1";
|
||||
final String message_value_default = "This is a custom message";
|
||||
final String message_value_fr = "Ceci est un message personnalis\\u00e9";
|
||||
final String message_value_de = "Dies ist eine benutzerdefinierte Nachricht";
|
||||
|
||||
// Undeploy the bundle
|
||||
if (repoAdminService.getMessageBundles().contains(bundleBaseName))
|
||||
{
|
||||
repoAdminService.undeployMessageBundle(bundleBaseName);
|
||||
}
|
||||
|
||||
// Verify the custom bundle is registered
|
||||
assertFalse("The custom bundle should not be deployed", repoAdminService.getMessageBundles().contains(bundleBaseName));
|
||||
|
||||
// Depoly the message bundle
|
||||
repoAdminService.deployMessageBundle(resourceClasspath);
|
||||
|
||||
// Reload the messages
|
||||
repoAdminService.reloadMessageBundle(bundleBaseName);
|
||||
|
||||
// Verify the custom bundle is registered
|
||||
assertTrue("The custom bundle should be deployed", repoAdminService.getMessageBundles().contains(bundleBaseName));
|
||||
|
||||
// Verify we have the messages for each locale
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
|
||||
assertMessageValue("Cannot retrieve default message value", message_value_default, message_key, Locale.getDefault());
|
||||
assertMessageValue("Cannot retrieve french message value", message_value_fr, message_key, Locale.FRANCE);
|
||||
assertMessageValue("Cannot retrieve german message value", message_value_de, message_key, Locale.GERMANY);
|
||||
|
||||
// Test deploy a non existent bundle
|
||||
try
|
||||
{
|
||||
repoAdminService.deployMessageBundle("alfresco/extension/messages/inexistentbundle");
|
||||
fail("Bundle was not supposed to be deployed");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Expected to fail
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test deploy bundle from repo and reload bundles
|
||||
public void testDeployMessageBundleFromRepo() throws Exception
|
||||
{
|
||||
final String bundleBaseName = "repoBundle";
|
||||
final String message_key = "repoBundle.key1";
|
||||
final String message_value = "Value 1";
|
||||
final String message_value_fr = "Value FR";
|
||||
final String message_value_de = "Value DE";
|
||||
final String message_value_new = "New Value 1";
|
||||
|
||||
// Set location
|
||||
NodeRef rootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
List<NodeRef> nodeRefs = searchService.selectNodes(rootNodeRef, "/app:company_home/app:dictionary/app:messages", null,
|
||||
namespaceService, false);
|
||||
assertEquals(1, nodeRefs.size());
|
||||
NodeRef messagesNodeRef = nodeRefs.get(0);
|
||||
|
||||
// Clear messages of this bundle if they exist and are registered
|
||||
clearRepoBundles(messagesNodeRef);
|
||||
|
||||
assertEquals(0, repoAdminService.getMessageBundles().size());
|
||||
|
||||
// Create and upload the message files
|
||||
NodeRef messageNode_default = createMessagesNodeWithSingleKey(messagesNodeRef, bundleBaseName, message_key, null,
|
||||
message_value);
|
||||
createMessagesNodeWithSingleKey(messagesNodeRef, bundleBaseName, message_key, Locale.FRANCE.toString(), message_value_fr);
|
||||
createMessagesNodeWithSingleKey(messagesNodeRef, bundleBaseName, message_key, Locale.GERMANY.toString(),
|
||||
message_value_de);
|
||||
|
||||
// Reload the messages
|
||||
repoAdminService.reloadMessageBundle(bundleBaseName);
|
||||
|
||||
// Verify we have the messages for each locale
|
||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||
|
||||
assertMessageValue("Cannot retrieve default message value", message_value, message_key, Locale.getDefault());
|
||||
assertMessageValue("Cannot retrieve french message value", message_value_fr, message_key, Locale.FRANCE);
|
||||
assertMessageValue("Cannot retrieve german message value", message_value_de, message_key, Locale.GERMANY);
|
||||
|
||||
// Change the values
|
||||
putContentInMessageNode(messageNode_default, message_key, message_value_new);
|
||||
|
||||
// Verify we still have the old value
|
||||
assertMessageValue("Unexpected change of message value", message_value, message_key, Locale.getDefault());
|
||||
|
||||
// Reload the messages
|
||||
repoAdminService.reloadMessageBundle(bundleBaseName);
|
||||
|
||||
// Verify new values
|
||||
assertMessageValue("Change of message value not reflected", message_value_new, message_key, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create messages node
|
||||
*/
|
||||
private NodeRef createMessagesNodeWithSingleKey(NodeRef parentNode, String bundleName, String key, String locale,
|
||||
String localeValue)
|
||||
{
|
||||
String msg_extension = ".properties";
|
||||
String filename = bundleName + msg_extension;
|
||||
String messageValue = localeValue;
|
||||
|
||||
if (locale != null)
|
||||
{
|
||||
filename = bundleName + "_" + locale + msg_extension;
|
||||
}
|
||||
// Create a model node
|
||||
NodeRef messageNode = this.nodeService.createNode(
|
||||
parentNode,
|
||||
ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, filename),
|
||||
ContentModel.TYPE_CONTENT,
|
||||
Collections.<QName, Serializable> singletonMap(ContentModel.PROP_NAME, filename)
|
||||
).getChildRef();
|
||||
|
||||
putContentInMessageNode(messageNode, key, messageValue);
|
||||
|
||||
return messageNode;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Write content of message node
|
||||
*/
|
||||
private void putContentInMessageNode(NodeRef nodeRef, String key, String value)
|
||||
{
|
||||
ContentWriter contentWriter = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||
contentWriter.setEncoding("UTF-8");
|
||||
contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
String messagesString = key + "=" + value;
|
||||
contentWriter.putContent(messagesString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Repo Bundle
|
||||
*/
|
||||
private void clearRepoBundles(NodeRef parentNode)
|
||||
{
|
||||
List<String> repoBundles = repoAdminService.getMessageBundles();
|
||||
for (String repoBundle : repoBundles)
|
||||
{
|
||||
repoAdminService.undeployMessageBundle(repoBundle);
|
||||
}
|
||||
|
||||
List<ChildAssociationRef> messageNodes = nodeService.getChildAssocs(parentNode);
|
||||
for (ChildAssociationRef messageChildRef : messageNodes)
|
||||
{
|
||||
NodeRef messageNode = messageChildRef.getChildRef();
|
||||
nodeService.deleteNode(messageNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Repo Bundle
|
||||
*/
|
||||
private void assertMessageValue(String errorMessage, String expectedValue, String key, Locale locale)
|
||||
{
|
||||
transactionService.getRetryingTransactionHelper()
|
||||
.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
assertEquals(errorMessage, expectedValue, messageService.getMessage(key, locale));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -25,9 +25,14 @@
|
||||
*/
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
@@ -53,8 +58,6 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
import javax.transaction.UserTransaction;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Category(BaseSpringTestsCategory.class)
|
||||
@@ -94,6 +97,14 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
|
||||
"</model>";
|
||||
|
||||
public static final String MESSAGES_KEY = "my_bootstrap_test";
|
||||
public static final String MESSAGES_VALUE = "My Message";
|
||||
public static final String MESSAGES_VALUE_FR = "Mon message";
|
||||
public static final String FOLDERNAME_MODELS = "models";
|
||||
public static final String FOLDERNAME_MESSAGES = "messages";
|
||||
public static final String BUNDLENAME_MESSAGES = "testBootstap";
|
||||
public static final String FILENAME_MESSAGES_EXT = ".properties";
|
||||
|
||||
/** Behaviour filter */
|
||||
private BehaviourFilter behaviourFilter;
|
||||
|
||||
@@ -123,7 +134,8 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
|
||||
private UserTransaction txn;
|
||||
private StoreRef storeRef;
|
||||
private NodeRef rootNodeRef;
|
||||
private NodeRef rootModelsNodeRef;
|
||||
private NodeRef rootMessagesNodeRef;
|
||||
|
||||
@Before
|
||||
public void before() throws Exception
|
||||
@@ -151,7 +163,17 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
|
||||
// Create the store and get the root node
|
||||
this.storeRef = this.nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
|
||||
this.rootNodeRef = this.nodeService.getRootNode(this.storeRef);
|
||||
|
||||
NodeRef rootNodeRef = this.nodeService.getRootNode(this.storeRef);
|
||||
this.rootModelsNodeRef = this.nodeService
|
||||
.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, FOLDERNAME_MODELS), ContentModel.TYPE_FOLDER)
|
||||
.getChildRef();
|
||||
|
||||
this.rootMessagesNodeRef = this.nodeService
|
||||
.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, FOLDERNAME_MESSAGES), ContentModel.TYPE_FOLDER)
|
||||
.getChildRef();
|
||||
|
||||
txn.commit();
|
||||
|
||||
@@ -167,18 +189,20 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
this.bootstrap.setNamespaceService(this.namespaceService);
|
||||
this.bootstrap.setMessageService(this.messageService);
|
||||
this.bootstrap.setPolicyComponent(this.policyComponent);
|
||||
|
||||
RepositoryLocation location = new RepositoryLocation();
|
||||
location.setStoreProtocol(this.storeRef.getProtocol());
|
||||
location.setStoreId(this.storeRef.getIdentifier());
|
||||
location.setQueryLanguage(RepositoryLocation.LANGUAGE_PATH);
|
||||
// NOTE: we are not setting the path for now .. in doing so we are searching the root node only
|
||||
|
||||
List<RepositoryLocation> locations = new ArrayList<RepositoryLocation>();
|
||||
locations.add(location);
|
||||
|
||||
this.bootstrap.setRepositoryModelsLocations(locations);
|
||||
|
||||
|
||||
RepositoryLocation modelsLocation = new RepositoryLocation(this.storeRef,
|
||||
this.nodeService.getPath(rootModelsNodeRef).toPrefixString(namespaceService), RepositoryLocation.LANGUAGE_PATH);
|
||||
RepositoryLocation messagesLocation = new RepositoryLocation(this.storeRef,
|
||||
this.nodeService.getPath(rootMessagesNodeRef).toPrefixString(namespaceService), RepositoryLocation.LANGUAGE_PATH);
|
||||
|
||||
List<RepositoryLocation> modelsLocations = new ArrayList<RepositoryLocation>();
|
||||
modelsLocations.add(modelsLocation);
|
||||
List<RepositoryLocation> messagesLocations = new ArrayList<RepositoryLocation>();
|
||||
messagesLocations.add(messagesLocation);
|
||||
|
||||
this.bootstrap.setRepositoryModelsLocations(modelsLocations);
|
||||
this.bootstrap.setRepositoryMessagesLocations(messagesLocations);
|
||||
|
||||
// register with dictionary service
|
||||
this.bootstrap.register();
|
||||
txn.commit();
|
||||
@@ -224,7 +248,15 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
"Test model one",
|
||||
"base1",
|
||||
"prop1");
|
||||
|
||||
|
||||
// Create a message file for the default locale
|
||||
NodeRef messageNodeDefaultLoc = createMessagesNode(null, null);
|
||||
// Create a message file for the french locale
|
||||
createMessagesNode(Locale.FRANCE.toString(), MESSAGES_VALUE_FR);
|
||||
// Construct baseBundleName for validation
|
||||
String baseBundleName = storeRef.toString()
|
||||
+ messageService.getBaseBundleName(nodeService.getPath(messageNodeDefaultLoc).toPrefixString(namespaceService));
|
||||
|
||||
// Check that the model is not in the dictionary yet
|
||||
try
|
||||
{
|
||||
@@ -251,6 +283,12 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
QName.createQName("http://www.alfresco.org/model/test3DictionaryBootstrapFromRepo/1.0", "testModel3"));
|
||||
assertNotNull(modelDefinition3);
|
||||
|
||||
// Check if the messages were registered correctly
|
||||
assertTrue("The message bundle should be registered", messageService.getRegisteredBundles().contains(baseBundleName));
|
||||
assertEquals("The default message value is not as expected", MESSAGES_VALUE, messageService.getMessage(MESSAGES_KEY));
|
||||
assertEquals("The message value in french is not as expected", MESSAGES_VALUE_FR,
|
||||
messageService.getMessage(MESSAGES_KEY, Locale.FRANCE));
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@@ -277,7 +315,7 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
{
|
||||
// Create a model node
|
||||
NodeRef model = this.nodeService.createNode(
|
||||
this.rootNodeRef,
|
||||
this.rootModelsNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName("{test}models"),
|
||||
ContentModel.TYPE_DICTIONARY_MODEL).getChildRef();
|
||||
@@ -300,6 +338,39 @@ public class DictionaryRepositoryBootstrapTest extends BaseSpringTest
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create messages node
|
||||
*
|
||||
* @return NodeRef
|
||||
*/
|
||||
private NodeRef createMessagesNode(String locale, String localeValue)
|
||||
{
|
||||
String filename = BUNDLENAME_MESSAGES + FILENAME_MESSAGES_EXT;
|
||||
String messageValue = MESSAGES_VALUE;
|
||||
|
||||
if (locale != null)
|
||||
{
|
||||
filename = BUNDLENAME_MESSAGES + "_" + locale + FILENAME_MESSAGES_EXT;
|
||||
messageValue = localeValue;
|
||||
}
|
||||
// Create a model node
|
||||
NodeRef messageNode = this.nodeService.createNode(
|
||||
this.rootMessagesNodeRef,
|
||||
ContentModel.ASSOC_CHILDREN,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, filename),
|
||||
ContentModel.TYPE_CONTENT,
|
||||
Collections.<QName, Serializable> singletonMap(ContentModel.PROP_NAME, filename)
|
||||
).getChildRef();
|
||||
|
||||
ContentWriter contentWriter = this.contentService.getWriter(messageNode, ContentModel.PROP_CONTENT, true);
|
||||
contentWriter.setEncoding("UTF-8");
|
||||
contentWriter.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
String messagesString = MESSAGES_KEY + "=" + messageValue;
|
||||
contentWriter.putContent(messagesString);
|
||||
|
||||
return messageNode;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the model string
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -96,6 +96,8 @@ public abstract class AbstractPermissionTest extends TestCase
|
||||
|
||||
protected NodeRef systemNodeRef;
|
||||
|
||||
protected NodeRef abstainedNode;
|
||||
|
||||
protected AuthenticationComponent authenticationComponent;
|
||||
|
||||
protected ModelDAO permissionModelDAO;
|
||||
@@ -186,6 +188,8 @@ public abstract class AbstractPermissionTest extends TestCase
|
||||
props = createPersonProperties(USER2_LEMUR);
|
||||
nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef();
|
||||
|
||||
abstainedNode= nodeService.createNode(rootNodeRef, ContentModel.ASSOC_FAILED_THUMBNAIL, system, ContentModel.TYPE_FAILED_THUMBNAIL).getChildRef();
|
||||
|
||||
// create an authentication object e.g. the user
|
||||
if(authenticationDAO.userExists(USER1_ANDY))
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 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.security.permissions.impl.acegi;
|
||||
|
||||
import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.getNodeRef;
|
||||
import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.shouldAbstainOrDeny;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
||||
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ACLEntryVoterUtilsTest
|
||||
{
|
||||
private final NodeRef testNodeRef = new NodeRef("workspace://testNodeRef/testNodeRef");
|
||||
private final NodeRef rootNodeRef = new NodeRef("workspace://rootNodeRef/rootNodeRef");
|
||||
private final NodeRef refNodeForTestObject = new NodeRef("workspace://refNodeForTestObject/refNodeForTestObject");
|
||||
private final NodeRef childRefNode = new NodeRef("workspace://childRefNode/childRefNode");
|
||||
private final StoreRef testStoreNodeRef = new StoreRef("system://testStoreRefMock/testStoreRefMock");
|
||||
private final SimplePermissionReference simplePermissionReference = SimplePermissionReference.getPermissionReference(QName.createQName("uri", "local"), "Write");
|
||||
private final QName qNameToAbstain1 = QName.createQName("{test}testnode1");
|
||||
private final QName qNameToAbstain2 = QName.createQName("{test}testnode2");
|
||||
private final QName qNameToAbstain3 = QName.createQName("{test}testnode3");
|
||||
private final QName qNameNotFromTheAbstainSet = QName.createQName("{test}testnodeAbstain");
|
||||
private final Set<QName> qNamesToAbstain = Set.of(qNameToAbstain1, qNameToAbstain2, qNameToAbstain3);
|
||||
@Mock
|
||||
private PermissionService permissionServiceMock;
|
||||
@Mock
|
||||
private NodeService nodeServiceMock;
|
||||
@Mock
|
||||
private ChildAssociationRef childAssocRefMock;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
when(nodeServiceMock.exists(testStoreNodeRef)).thenReturn(Boolean.TRUE);
|
||||
when(nodeServiceMock.exists(testNodeRef)).thenReturn(Boolean.TRUE);
|
||||
when(nodeServiceMock.getRootNode(testStoreNodeRef)).thenReturn(rootNodeRef);
|
||||
when(nodeServiceMock.getType(testNodeRef)).thenReturn(qNameNotFromTheAbstainSet);
|
||||
when(nodeServiceMock.getAspects(testNodeRef)).thenReturn(Set.of(qNameNotFromTheAbstainSet));
|
||||
when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.DENIED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsAccessDeniedFromPermissionService()
|
||||
{
|
||||
assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock),
|
||||
is(AccessDecisionVoter.ACCESS_DENIED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsNullOnNullTestObject()
|
||||
{
|
||||
assertThat(getNodeRef(null, nodeServiceMock), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test(expected = ACLEntryVoterException.class)
|
||||
public void throwsExceptionWhenParameterIsNotNodeRefOrChildAssociationRef()
|
||||
{
|
||||
getNodeRef("TEST", nodeServiceMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsGivenTestNodeRefWhenStoreRefDoesNotExist()
|
||||
{
|
||||
when(nodeServiceMock.exists(testStoreNodeRef)).thenReturn(Boolean.FALSE);
|
||||
assertThat(getNodeRef(testStoreNodeRef, nodeServiceMock), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsRootNode()
|
||||
{
|
||||
assertThat(getNodeRef(testStoreNodeRef, nodeServiceMock), is(rootNodeRef));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsNodeRefFromTestObject()
|
||||
{
|
||||
assertThat(getNodeRef(refNodeForTestObject, nodeServiceMock), is(refNodeForTestObject));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsChildRefFromChildAssocRef()
|
||||
{
|
||||
when(childAssocRefMock.getChildRef()).thenReturn(childRefNode);
|
||||
assertThat(getNodeRef(childAssocRefMock, nodeServiceMock), is(childRefNode));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsNullOnNullTestNodeRef()
|
||||
{
|
||||
assertThat(shouldAbstainOrDeny(simplePermissionReference, null, qNamesToAbstain, nodeServiceMock, permissionServiceMock),
|
||||
is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsNullOnAbstainClassQnamesIsEmptyAndThereAreNoDeniedPermissions()
|
||||
{
|
||||
when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.ALLOWED);
|
||||
assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, Collections.emptySet(), nodeServiceMock, permissionServiceMock),
|
||||
is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsNullOnTestNodeRefDoesNotExistAndThereAreNoDeniedPermissions()
|
||||
{
|
||||
when(nodeServiceMock.exists(testNodeRef)).thenReturn(Boolean.FALSE);
|
||||
when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.ALLOWED);
|
||||
assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock),
|
||||
is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsNullOnNodeTypeAndNodeAspectsAreNotInSetToAbstainAndThereAreNoDeniedPermissions()
|
||||
{
|
||||
when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.ALLOWED);
|
||||
assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock),
|
||||
is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsAbstainWhenNodeRefTypeIsInSetToAbstain()
|
||||
{
|
||||
when(nodeServiceMock.getType(testNodeRef)).thenReturn(qNameToAbstain2);
|
||||
assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock),
|
||||
is(AccessDecisionVoter.ACCESS_ABSTAIN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsAbstainWhenAtLeastOneAspectIsInSetToAbstain()
|
||||
{
|
||||
when(nodeServiceMock.getAspects(testNodeRef)).thenReturn(Set.of(qNameNotFromTheAbstainSet, qNameToAbstain3));
|
||||
assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock),
|
||||
is(AccessDecisionVoter.ACCESS_ABSTAIN));
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1 @@
|
||||
mycustommessages.key1=This is a custom message
|
@@ -0,0 +1 @@
|
||||
mycustommessages.key1=Dies ist eine benutzerdefinierte Nachricht
|
@@ -0,0 +1 @@
|
||||
mycustommessages.key1=Ceci est un message personnalis\u00e9
|
Reference in New Issue
Block a user