From e994c97f0b8727ff56c5e7efd771d144f77f0062 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Tue, 19 Jan 2010 11:50:05 +0000 Subject: [PATCH] Merged V3.2E to HEAD 17495: Changed xforms-samples name to wcm-sample 17496: Minor fixes for day and week views when rendering new events 17497: *RECORD ONLY* Added Enterprise logo local copy. 17498: ETHREEOH-2933 - User can see contents of the moderated site if user is not a member of the site - Site containers are now private and non member's can't see content. - fix only applies to new moderated sites. 17499: ETHREEOH-2322 - Office Plugin: filename overlaps the plugin UI if longer than 40 characters without spaces 17500: Temorary build fix for site visibility 17508: ETHREEOH-1268 - Pages and Components show varying degrees of success handling "site not found" errors. 17509: Fix for ETHREEOH1733 - Wrong display of multi day events in Share 17514: View In Browser action for document list and document details actions. 17515: Merged DEV-TEMPORARY to V3.2 17471: ETHREEOH-3193: 'capitalize' in output path pattern works differently for templates (vs. XSDs) 17516: Missing css file from Edit Offline changes. Also "Checked out on/by" text changed to "Editing started on/by". Tags now comma separated 17517: Merged DEV-TEMPORARY to V3.2 17474: ETHREEOH-1211: Can't See Images in TinyMCE 17518: Office add-in: ETHREEOH-3361 - Workflow name is visible only before symbol &, ETHREEOH-2735 - Total number of founded items is not shown 17519: 3.2E help links 17520: 3.2E help links, plus ETHREEOH-1536 - Incorrect "insert into current document" function work for unsupported files in MS Office Addin 17522: Fix for ETHREEOH-3257 - Event becomes All day again after editing it to not All day 17526: Fix for unreported issue when rendering an edited event after the view is filtered via tag component causes an script error 17528: Fixed ETHREEOH-3364 " Admin Console - Group Search needs to show searching message and disable further requests while search is running" - Disabling search button & message displaying "Searching..." after 2 seconds for long searches for the following components: * Admin Console: Users - search user, add group * Admin Console: Groups - search group, add group, add user * Site: Members: People - search members, add people * Site: Members: Groups - search membergroups, add group * Site: Members: Pending invites - search invites * Site: Doclib: Assign Workflow - add users * People Finder * Site Finder - All component listed above uses max search result except the following where webscript services lacks support for it: * Admin Console: Users - add group * Admin Console: Groups - search group, add group * Site: Members: Pending invites - search invites - Bugfix: When minSearchTermLength is set to 0: * Group Admin Console: switched to browse view * User Admin Console: didnt do a search - Bugfix: For some components minSearchTermLength & maxSearchResults were brought in as strings causing the global search's max result to be 1001 instead of 101 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18126 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/repo/site/SiteServiceImpl.java | 99 ++++++++++++++++--- .../repo/site/SiteServiceImplTest.java | 43 ++++++-- .../org/alfresco/repo/site/script/Site.java | 34 +++++-- .../service/cmr/site/SiteService.java | 2 +- 4 files changed, 147 insertions(+), 31 deletions(-) diff --git a/source/java/org/alfresco/repo/site/SiteServiceImpl.java b/source/java/org/alfresco/repo/site/SiteServiceImpl.java index ebe7532d6a..689463f973 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImpl.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImpl.java @@ -403,6 +403,7 @@ public class SiteServiceImpl implements SiteService, SiteModel } else if (SiteVisibility.MODERATED.equals(visibility) == true) { + // for moderated site EVERYONE has consumer access but site components do not. permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER, true); } permissionService.setPermission(siteNodeRef, @@ -504,6 +505,7 @@ public class SiteServiceImpl implements SiteService, SiteModel * * @param shortName site short name * @param permission permission name + * @param withGroupPrefix - should the name have the GROUP_ prefix? * @return String site permission group name */ public String getSiteRoleGroup(String shortName, String permission, boolean withGroupPrefix) @@ -889,7 +891,8 @@ public class SiteServiceImpl implements SiteService, SiteModel */ public void updateSite(SiteInfo siteInfo) { - NodeRef siteNodeRef = getSiteNodeRef(siteInfo.getShortName()); + String shortName = siteInfo.getShortName(); + NodeRef siteNodeRef = getSiteNodeRef(shortName); if (siteNodeRef == null) { throw new SiteServiceException(MSG_CAN_NOT_UPDATE, new Object[]{siteInfo.getShortName()}); @@ -908,6 +911,10 @@ public class SiteServiceImpl implements SiteService, SiteModel SiteVisibility updatedVisibility = siteInfo.getVisibility(); if (currentVisibility.equals(updatedVisibility) == false) { + // visibility has changed + logger.debug("site:" + shortName + " visibility has changed from: " + currentVisibility + "to: " + updatedVisibility); + + // visibility has changed. // Remove current visibility permissions if (SiteVisibility.PUBLIC.equals(currentVisibility) == true) { @@ -916,8 +923,16 @@ public class SiteServiceImpl implements SiteService, SiteModel else if (SiteVisibility.MODERATED.equals(currentVisibility) == true) { this.permissionService.deletePermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER); - //this.permissionService.deletePermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ_PROPERTIES); - // TODO update all child folders ?? ... + + /** + * update the containers + */ + List folders = fileFolderService.listFolders(siteNodeRef); + for(FileInfo folder : folders) + { + NodeRef containerNodeRef = folder.getNodeRef(); + this.permissionService.setInheritParentPermissions(containerNodeRef, true); + } } // Add new visibility permissions @@ -928,8 +943,15 @@ public class SiteServiceImpl implements SiteService, SiteModel else if (SiteVisibility.MODERATED.equals(updatedVisibility) == true) { this.permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, SITE_CONSUMER, true); - //this.permissionService.setPermission(siteNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ_PROPERTIES, true); - // TODO update all child folders ?? ... + /** + * update the containers + */ + List folders = fileFolderService.listFolders(siteNodeRef); + for(FileInfo folder : folders) + { + NodeRef containerNodeRef = folder.getNodeRef(); + setModeratedPermissions(shortName, containerNodeRef); + } } // Update the site node reference with the updated visibility value @@ -1452,6 +1474,9 @@ public class SiteServiceImpl implements SiteService, SiteModel { throw new SiteServiceException(MSG_SITE_NO_EXIST, new Object[]{shortName}); } + + // Update the isPublic flag + SiteVisibility siteVisibility = getSiteVisibility(siteNodeRef); // retrieve component folder within site NodeRef containerNodeRef = null; @@ -1492,13 +1517,41 @@ public class SiteServiceImpl implements SiteService, SiteModel aspectProps.put(SiteModel.PROP_COMPONENT_ID, componentId); this.nodeService.addAspect(containerNodeRef, ASPECT_SITE_CONTAINER, aspectProps); - + + // Set permissions on the container + if(SiteVisibility.MODERATED.equals(siteVisibility)) + { + setModeratedPermissions(shortName, containerNodeRef); + } + // Make the container a tag scope this.taggingService.addTagScope(containerNodeRef); } return containerNodeRef; } + + /** + * Moderated sites have separate ACLs on each component and don't inherit from the + * site which has consumer role for everyone. + */ + private void setModeratedPermissions(String shortName, NodeRef containerNodeRef) + { + + this.permissionService.setInheritParentPermissions(containerNodeRef, false); + + Set permissions = permissionService.getSettablePermissions(SiteModel.TYPE_SITE); + for (String permission : permissions) + { + String permissionGroup = getSiteRoleGroup(shortName, permission, true); + // Assign the group the relevant permission on the site + permissionService.setPermission(containerNodeRef, permissionGroup, permission, true); + } + permissionService.setPermission(containerNodeRef, + PermissionService.ALL_AUTHORITIES, + PermissionService.READ_PERMISSIONS, true); + } + /** * @see org.alfresco.service.cmr.site.SiteService#getContainer(java.lang.String) @@ -1531,12 +1584,12 @@ public class SiteServiceImpl implements SiteService, SiteModel /** * @see org.alfresco.service.cmr.site.SiteService#hasContainer(java.lang.String) */ - public boolean hasContainer(String shortName, String componentId) + public boolean hasContainer(final String shortName, final String componentId) { ParameterCheck.mandatoryString("componentId", componentId); // retrieve site - NodeRef siteNodeRef = getSiteNodeRef(shortName); + final NodeRef siteNodeRef = getSiteNodeRef(shortName); if (siteNodeRef == null) { throw new SiteServiceException(MSG_SITE_NO_EXIST, new Object[]{shortName}); @@ -1545,15 +1598,33 @@ public class SiteServiceImpl implements SiteService, SiteModel // retrieve component folder within site // NOTE: component id is used for folder name boolean hasContainer = false; - try + + NodeRef containerRef = AuthenticationUtil.runAs(new RunAsWork() + { + public NodeRef doWork() throws Exception + { + return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback() + { + public NodeRef execute() throws Exception + { + try + { + return findContainer(siteNodeRef, componentId); + } + catch (FileNotFoundException e) + { + return null; + } + } + }, true); + } + }, AuthenticationUtil.getSystemUserName()); + + if(containerRef != null) { - findContainer(siteNodeRef, componentId); hasContainer = true; - } - catch (FileNotFoundException e) - { } - + return hasContainer; } diff --git a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java index 6b7fc26d83..d67f2d107f 100644 --- a/source/java/org/alfresco/repo/site/SiteServiceImplTest.java +++ b/source/java/org/alfresco/repo/site/SiteServiceImplTest.java @@ -467,7 +467,7 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest assertNotNull(siteInfo); checkSiteInfo(siteInfo, TEST_SITE_PRESET, "testGetSite", TEST_TITLE, TEST_DESCRIPTION, SiteVisibility.PUBLIC); } - + public void testUpdateSite() { SiteInfo siteInfo = new SiteInfoImpl(TEST_SITE_PRESET, "testUpdateSite", "changedTitle", "changedDescription", SiteVisibility.PRIVATE, null); @@ -1031,7 +1031,7 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest siteInfo = this.siteService.getSite("testSiteVisibilityModeratedSite"); checkSiteInfo(siteInfo, TEST_SITE_PRESET, "testSiteVisibilityModeratedSite", TEST_TITLE, TEST_DESCRIPTION, SiteVisibility.MODERATED); // - are the permissions correct for non-members? - testVisibilityPermissions("Testing visibility of moderated site", USER_TWO, siteInfo, true, true); + testVisibilityPermissions("Testing visibility of moderated site", USER_TWO, siteInfo, true, false); // Create a private site siteInfo = createTestSiteWithContent("testSiteVisibilityPrivateSite", "testComp", SiteVisibility.PRIVATE); @@ -1051,7 +1051,7 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest // - check the updated sites visibility siteInfo = this.siteService.getSite("testSiteVisibilityChangeSite"); checkSiteInfo(siteInfo, TEST_SITE_PRESET, "testSiteVisibilityChangeSite", TEST_TITLE, TEST_DESCRIPTION, SiteVisibility.MODERATED); - testVisibilityPermissions("Testing visibility of moderated site", USER_TWO, siteInfo, true, true); + testVisibilityPermissions("Testing visibility of moderated site", USER_TWO, siteInfo, true, false); // Switch from moderated -> private changeSite.setVisibility(SiteVisibility.PRIVATE); @@ -1106,11 +1106,12 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest if (siteInList == true) { - // Can site content be read by the user? - NodeRef folder = this.siteService.getContainer(siteInfo.getShortName(), "testComp"); - List files = null; try { + // Can site content be read by the user? + NodeRef folder = this.siteService.getContainer(siteInfo.getShortName(), "testComp"); + List files = null; + files = this.fileFolderService.listFiles(folder); if (readSite == false) { @@ -1262,6 +1263,36 @@ public class SiteServiceImplTest extends BaseAlfrescoSpringTest } } + /** + * Create a private site. + * + * Attempt to access a private site by someone that is not a consumer of that site. + * + */ + public void testETHREEOH_1268() + { + // USER_ONE - SiteManager + // GROUP_TWO - Manager + + String siteName = "testALFCOM_XXXX"; + + // Create a site as user one + this.siteService.createSite(TEST_SITE_PRESET, siteName, TEST_TITLE, TEST_DESCRIPTION, SiteVisibility.PRIVATE); + + SiteInfo si = this.siteService.getSite(siteName); + + assertNotNull("site info is null", si); + + authenticationComponent.setCurrentUser(USER_TWO); + + si = this.siteService.getSite(siteName); + + assertNull("site info is not null", si); + + + + } + diff --git a/source/java/org/alfresco/repo/site/script/Site.java b/source/java/org/alfresco/repo/site/script/Site.java index 6e0fcf355e..99ad51f222 100644 --- a/source/java/org/alfresco/repo/site/script/Site.java +++ b/source/java/org/alfresco/repo/site/script/Site.java @@ -49,6 +49,7 @@ import org.alfresco.service.cmr.invitation.InvitationSearchCriteria; import org.alfresco.service.cmr.invitation.InvitationService; import org.alfresco.service.cmr.invitation.InvitationSearchCriteria.InvitationType; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.site.SiteInfo; @@ -372,16 +373,23 @@ public class Site implements Serializable * * @param componentId * @return node representing the "container" folder (or null, if for some reason - * the container can not be created) + * the container can not be created - probably due to permissions) */ public ScriptNode getContainer(String componentId) { ScriptNode container = null; - NodeRef containerNodeRef = this.siteService.getContainer(getShortName(), componentId); - if (containerNodeRef != null) - { - container = new ScriptNode(containerNodeRef, this.serviceRegistry, this.scope); - } + try + { + NodeRef containerNodeRef = this.siteService.getContainer(getShortName(), componentId); + if (containerNodeRef != null) + { + container = new ScriptNode(containerNodeRef, this.serviceRegistry, this.scope); + } + } + catch (AccessDeniedException ade) + { + return null; + } return container; } @@ -417,7 +425,6 @@ public class Site implements Serializable */ public ScriptNode createContainer(final String componentId, final String folderType, final Object permissions) { - ScriptNode container = null; NodeRef containerNodeRef = AuthenticationUtil.runAs(new RunAsWork() { public NodeRef doWork() throws Exception @@ -460,9 +467,16 @@ public class Site implements Serializable } }, AuthenticationUtil.SYSTEM_USER_NAME); - // Create the script node for the container - container = new ScriptNode(containerNodeRef, this.serviceRegistry, this.scope); - return container; + if (Site.this.serviceRegistry.getPermissionService().hasPermission(containerNodeRef, PermissionService.READ_PROPERTIES) == AccessStatus.ALLOWED) + { + return getContainer(componentId); + } + else + { + // current user has no access. + return null; + } + } /** diff --git a/source/java/org/alfresco/service/cmr/site/SiteService.java b/source/java/org/alfresco/service/cmr/site/SiteService.java index 6101a05bbf..c3ab68a372 100644 --- a/source/java/org/alfresco/service/cmr/site/SiteService.java +++ b/source/java/org/alfresco/service/cmr/site/SiteService.java @@ -167,7 +167,7 @@ public interface SiteService * @param componentId component id * @param containerType container type to create (can be null) * @param containerProperties container property values (can be null) - * @return + * @return noderef of container or null if a container can't be created. */ NodeRef createContainer(String shortName, String componentId, QName containerType, Map containerProperties);