/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.itest.content; import org.jdom.Document; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import com.enonic.cms.framework.xml.XMLDocumentFactory; import com.enonic.cms.core.content.ContentEntity; import com.enonic.cms.core.content.ContentKey; import com.enonic.cms.core.content.ContentService; import com.enonic.cms.core.content.ContentStatus; import com.enonic.cms.core.content.ContentVersionKey; import com.enonic.cms.core.content.CreateContentException; import com.enonic.cms.core.content.UpdateContentException; import com.enonic.cms.core.content.UpdateContentResult; import com.enonic.cms.core.content.command.CreateContentCommand; import com.enonic.cms.core.content.command.UpdateContentCommand; import com.enonic.cms.core.content.contentdata.custom.CustomContentData; import com.enonic.cms.core.content.contentdata.custom.stringbased.TextDataEntry; import com.enonic.cms.core.content.contenttype.ContentHandlerName; import com.enonic.cms.core.content.contenttype.ContentTypeConfig; import com.enonic.cms.core.content.contenttype.ContentTypeConfigBuilder; import com.enonic.cms.core.security.PortalSecurityHolder; import com.enonic.cms.core.security.SecurityService; import com.enonic.cms.core.security.group.GroupEntity; import com.enonic.cms.core.security.group.GroupType; import com.enonic.cms.core.security.user.User; import com.enonic.cms.core.security.user.UserEntity; import com.enonic.cms.core.security.user.UserType; import com.enonic.cms.itest.AbstractSpringTest; import com.enonic.cms.itest.util.DomainFactory; import com.enonic.cms.itest.util.DomainFixture; import com.enonic.cms.store.dao.CategoryDao; import com.enonic.cms.store.dao.ContentDao; import com.enonic.cms.web.portal.SiteRedirectHelper; import com.enonic.cms.web.portal.services.ContentServicesProcessor; import com.enonic.cms.web.portal.services.UserServicesRedirectUrlResolver; import static org.easymock.classextension.EasyMock.createMock; import static org.junit.Assert.*; public class ContentServiceImpl_accessTest extends AbstractSpringTest { @Autowired private SecurityService securityService; @Autowired private CategoryDao categoryDao; @Autowired protected ContentDao contentDao; @Autowired protected ContentService contentService; private SiteRedirectHelper siteRedirectHelper; private ContentServicesProcessor customContentHandlerController; private UserServicesRedirectUrlResolver userServicesRedirectUrlResolver; private DomainFactory factory; @Autowired private DomainFixture fixture; @Before public void setUp() { factory = fixture.getFactory(); customContentHandlerController = new ContentServicesProcessor(); customContentHandlerController.setContentService( contentService ); customContentHandlerController.setSecurityService( securityService ); customContentHandlerController.setCategoryDao( categoryDao ); userServicesRedirectUrlResolver = Mockito.mock( UserServicesRedirectUrlResolver.class ); customContentHandlerController.setUserServicesRedirectHelper( userServicesRedirectUrlResolver ); // just need a dummy of the SiteRedirectHelper siteRedirectHelper = createMock( SiteRedirectHelper.class ); customContentHandlerController.setSiteRedirectHelper( siteRedirectHelper ); // setup needed common data for each test fixture.initSystemData(); //SecurityHolder.setUser( findUserByName( User.ANONYMOUS_UID ).getKey() ); PortalSecurityHolder.setAnonUser( fixture.findUserByName( User.ANONYMOUS_UID ).getKey() ); fixture.save( factory.createContentHandler( "Custom content", ContentHandlerName.CUSTOM.getHandlerClassShortName() ) ); fixture.flushAndClearHibernateSession(); // setup content type ContentTypeConfigBuilder ctyconf = new ContentTypeConfigBuilder( "Person", "name" ); ctyconf.startBlock( "Person" ); ctyconf.addInput( "name", "text", "contentdata/name", "Name", true ); ctyconf.endBlock(); Document configAsXmlBytes = XMLDocumentFactory.create( ctyconf.toString() ).getAsJDOMDocument(); fixture.save( factory.createContentType( "Person", ContentHandlerName.CUSTOM.getHandlerClassShortName(), configAsXmlBytes ) ); fixture.flushAndClearHibernateSession(); fixture.save( factory.createUnit( "UnitForPerson", "en" ) ); fixture.flushAndClearHibernateSession(); } @Test public void create_content_with_status_draft_passes_when_user_have_create_or_administrate() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "creator", "testuserstore" ); createAndSaveNormalUser( "administrator", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "creator", "read, create" ); createAndSaveCategoryAccess( categoryName, "administrator", "read, administrate" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "creator", ContentStatus.DRAFT ) ); assertNotNull( contentDao.findByKey( contentKey ) ); contentKey = contentService.createContent( createCreateContentCommand( categoryName, "administrator", ContentStatus.DRAFT ) ); assertNotNull( contentDao.findByKey( contentKey ) ); } @Test public void create_content_with_status_approved_passes_when_user_have_create_and_approve_or_administrate() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "creatorAndApprover", "testuserstore" ); createAndSaveNormalUser( "administrator", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "creatorAndApprover", "read, create, approve" ); createAndSaveCategoryAccess( categoryName, "administrator", "read, administrate" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "creatorAndApprover", ContentStatus.APPROVED ) ); assertNotNull( contentDao.findByKey( contentKey ) ); contentKey = contentService.createContent( createCreateContentCommand( categoryName, "administrator", ContentStatus.APPROVED ) ); assertNotNull( contentDao.findByKey( contentKey ) ); } @Test public void create_content_with_status_approved_passes_when_user_have_create_and_category_has_autoapprove() { String categoryName = "category"; createAndStoreCategory( categoryName, true ); createAndSaveNormalUser( "creator", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "creator", "read, create, approve" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "creator", ContentStatus.APPROVED ) ); assertNotNull( contentDao.findByKey( contentKey ) ); } @Test(expected = CreateContentException.class) public void create_content_with_status_approved_fails_when_user_have_no_approve_access() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "creatorOnly", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "creatorOnly", "read, create" ); contentService.createContent( createCreateContentCommand( categoryName, "creatorOnly", ContentStatus.APPROVED ) ); fail(); } @Test public void update_draft_content_passes_when_user_have_create_access_on_category() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "other-category-creator", "testuserstore" ); createAndSaveNormalUser( "category-creator", "testuserstore" ); createAndSaveNormalUser( "category-approver", "testuserstore" ); createAndSaveNormalUser( "category-administrator", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "other-category-creator", "read, create" ); createAndSaveCategoryAccess( categoryName, "category-creator", "read, create" ); createAndSaveCategoryAccess( categoryName, "category-approver", "read, approve" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "other-category-creator", ContentStatus.DRAFT ) ); ContentEntity content = fixture.findContentByKey( contentKey ); ContentVersionKey versionToUpdate = content.getMainVersion().getKey(); UpdateContentResult result; // verify: result = contentService.updateContent( createUpdateExistingContentCommand( contentKey, "category-creator", ContentStatus.DRAFT, versionToUpdate ) ); assertNotNull( result.getTargetedVersionKey() ); result = contentService.updateContent( createUpdateExistingContentCommand( contentKey, "category-approver", ContentStatus.APPROVED, versionToUpdate ) ); assertNotNull( result.getTargetedVersionKey() ); result = contentService.updateContent( createCreateNewVersionCommand( contentKey, "category-creator", ContentStatus.DRAFT, result.getTargetedVersionKey() ) ); assertNotNull( result.getTargetedVersionKey() ); } @Test public void update_draft_content_passes_when_user_have_update_access_on_content() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "category-creator", "testuserstore" ); createAndSaveNormalUser( "category-approver", "testuserstore" ); createAndSaveNormalUser( "category-administrator", "testuserstore" ); createAndSaveNormalUser( "content-updater", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "category-creator", "read, create" ); createAndSaveCategoryAccess( categoryName, "category-approver", "approve" ); createAndSaveCategoryAccess( categoryName, "category-administrator", "administrate" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "category-creator", ContentStatus.DRAFT ) ); createAndSaveContentAccess( contentKey, "content-updater", "update" ); ContentEntity content = fixture.findContentByKey( contentKey ); ContentVersionKey versionToUpdate = content.getMainVersion().getKey(); UpdateContentResult result; // verify: result = contentService.updateContent( createUpdateExistingContentCommand( contentKey, "content-updater", ContentStatus.DRAFT, versionToUpdate ) ); assertNotNull( result.getTargetedVersionKey() ); result = contentService.updateContent( createUpdateExistingContentCommand( contentKey, "category-approver", ContentStatus.DRAFT, versionToUpdate ) ); assertNotNull( result.getTargetedVersionKey() ); result = contentService.updateContent( createUpdateExistingContentCommand( contentKey, "category-administrator", ContentStatus.DRAFT, versionToUpdate ) ); assertNotNull( result.getTargetedVersionKey() ); } @Test(expected = UpdateContentException.class) public void update_draft_content_fails_when_user_have_only_read_access_on_content() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "category-creator", "testuserstore" ); createAndSaveNormalUser( "content-reader", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "category-creator", "read, create" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "category-creator", ContentStatus.DRAFT ) ); createAndSaveContentAccess( contentKey, "content-reader", "read" ); ContentEntity content = fixture.findContentByKey( contentKey ); ContentVersionKey versionToUpdate = content.getMainVersion().getKey(); // verify: contentService.updateContent( createUpdateExistingContentCommand( contentKey, "content-reader", ContentStatus.DRAFT, versionToUpdate ) ); fail(); } @Test(expected = UpdateContentException.class) public void change_draft_content_to_approved_fails_when_user_have_only_create_access_on_category() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "category-creator", "testuserstore" ); createAndSaveNormalUser( "content-reader", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "category-creator", "read, create" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "category-creator", ContentStatus.DRAFT ) ); createAndSaveContentAccess( contentKey, "content-reader", "read" ); ContentEntity content = fixture.findContentByKey( contentKey ); ContentVersionKey versionToUpdate = content.getMainVersion().getKey(); // verify: contentService.updateContent( createUpdateExistingContentCommand( contentKey, "category-creator", ContentStatus.APPROVED, versionToUpdate ) ); fail(); } @Test public void create_new_content_version_with_status_draft_passes_when_user_have_update_access_on_content() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "category-creator", "testuserstore" ); createAndSaveNormalUser( "category-approver", "testuserstore" ); createAndSaveNormalUser( "category-administrator", "testuserstore" ); createAndSaveNormalUser( "content-updater", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "category-creator", "read, create" ); createAndSaveCategoryAccess( categoryName, "category-approver", "approve" ); createAndSaveCategoryAccess( categoryName, "category-administrator", "administrate" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "category-creator", ContentStatus.DRAFT ) ); createAndSaveContentAccess( contentKey, "content-updater", "update" ); ContentEntity content = fixture.findContentByKey( contentKey ); ContentVersionKey versionKeyToBaseOn = content.getMainVersion().getKey(); UpdateContentResult result; // verify: result = contentService.updateContent( createCreateNewVersionCommand( contentKey, "content-updater", ContentStatus.DRAFT, versionKeyToBaseOn ) ); assertNotNull( result.getTargetedVersionKey() ); result = contentService.updateContent( createCreateNewVersionCommand( contentKey, "category-approver", ContentStatus.DRAFT, versionKeyToBaseOn ) ); assertNotNull( result.getTargetedVersionKey() ); result = contentService.updateContent( createCreateNewVersionCommand( contentKey, "category-administrator", ContentStatus.DRAFT, versionKeyToBaseOn ) ); assertNotNull( result.getTargetedVersionKey() ); } @Test public void create_new_content_version_with_status_draft_passes_when_user_have_create_access_on_category() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "category-creator", "testuserstore" ); createAndSaveNormalUser( "category-approver", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "category-creator", "read, create" ); createAndSaveCategoryAccess( categoryName, "category-approver", "create, approve" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "category-approver", ContentStatus.APPROVED ) ); ContentEntity content = fixture.findContentByKey( contentKey ); ContentVersionKey versionKeyToBaseOn = content.getMainVersion().getKey(); UpdateContentResult result; // exercise result = contentService.updateContent( createCreateNewVersionCommand( contentKey, "category-creator", ContentStatus.DRAFT, versionKeyToBaseOn ) ); // verify assertNotNull( result.getTargetedVersionKey() ); } @Test(expected = UpdateContentException.class) public void create_new_content_version_with_status_draft_fails_when_user_have_only_read_access_on_content() { String categoryName = "category"; createAndStoreCategory( categoryName ); createAndSaveNormalUser( "category-creator", "testuserstore" ); createAndSaveNormalUser( "content-reader", "testuserstore" ); createAndSaveCategoryAccess( categoryName, "category-creator", "read, create" ); ContentKey contentKey; contentKey = contentService.createContent( createCreateContentCommand( categoryName, "category-creator", ContentStatus.DRAFT ) ); createAndSaveContentAccess( contentKey, "content-reader", "read" ); ContentEntity content = fixture.findContentByKey( contentKey ); ContentVersionKey versionKeyToBaseOn = content.getMainVersion().getKey(); // exercise and verify contentService.updateContent( createCreateNewVersionCommand( contentKey, "content-reader", ContentStatus.DRAFT, versionKeyToBaseOn ) ); fail(); } private void createAndSaveCategoryAccess( String categoryName, String userUid, String accesses ) { final UserEntity user = fixture.findUserByName( userUid ); fixture.save( factory.createCategoryAccess( categoryName, user, accesses ) ); fixture.flushAndClearHibernateSession(); } private void createAndSaveContentAccess( ContentKey contentKey, String userUid, String accesses ) { final UserEntity user = fixture.findUserByName( userUid ); fixture.save( factory.createContentAccess( contentKey, user, accesses ) ); fixture.flushAndClearHibernateSession(); } private CreateContentCommand createCreateContentCommand( String categoryName, String creatorUid, ContentStatus contentStatus ) { CreateContentCommand createContentCommand = new CreateContentCommand(); createContentCommand.setCategory( fixture.findCategoryByName( categoryName ) ); createContentCommand.setCreator( fixture.findUserByName( creatorUid ).getKey() ); createContentCommand.setLanguage( fixture.findLanguageByCode( "en" ) ); createContentCommand.setStatus( contentStatus ); createContentCommand.setPriority( 0 ); createContentCommand.setContentName( "name_" + categoryName + "_" + contentStatus ); ContentTypeConfig contentTypeConfig = fixture.findContentTypeByName( "Person" ).getContentTypeConfig(); CustomContentData contentData = new CustomContentData( contentTypeConfig ); contentData.add( new TextDataEntry( contentTypeConfig.getInputConfig( "name" ), "Initial" ) ); createContentCommand.setContentData( contentData ); return createContentCommand; } private UpdateContentCommand createUpdateExistingContentCommand( ContentKey contentKey, String modifier, ContentStatus contentStatus, ContentVersionKey versionKeyToUpdate ) { UpdateContentCommand updateContentCommand = UpdateContentCommand.updateExistingVersion2( versionKeyToUpdate ); updateContentCommand.setContentKey( contentKey ); updateContentCommand.setModifier( fixture.findUserByName( modifier ) ); updateContentCommand.setStatus( contentStatus ); ContentTypeConfig contentTypeConfig = fixture.findContentTypeByName( "Person" ).getContentTypeConfig(); CustomContentData contentData = new CustomContentData( contentTypeConfig ); contentData.add( new TextDataEntry( contentTypeConfig.getInputConfig( "name" ), "Changed" ) ); updateContentCommand.setContentData( contentData ); return updateContentCommand; } private UpdateContentCommand createCreateNewVersionCommand( ContentKey contentKey, String modifier, ContentStatus contentStatus, ContentVersionKey versionKeyToBaseOn ) { UpdateContentCommand updateContentCommand = UpdateContentCommand.storeNewVersionEvenIfUnchanged( versionKeyToBaseOn ); updateContentCommand.setContentKey( contentKey ); updateContentCommand.setModifier( fixture.findUserByName( modifier ) ); updateContentCommand.setStatus( contentStatus ); ContentTypeConfig contentTypeConfig = fixture.findContentTypeByName( "Person" ).getContentTypeConfig(); CustomContentData contentData = new CustomContentData( contentTypeConfig ); contentData.add( new TextDataEntry( contentTypeConfig.getInputConfig( "name" ), "Changed" ) ); updateContentCommand.setContentData( contentData ); return updateContentCommand; } private void createAndSaveNormalUser( String uid, String userstoreName ) { GroupEntity userGroup = factory.createGroupInUserstore( uid + "_group", GroupType.USERSTORE_GROUP, userstoreName ); fixture.save( userGroup ); UserEntity user = factory.createUser( uid, uid, UserType.NORMAL, userstoreName, userGroup ); fixture.save( user ); fixture.flushAndClearHibernateSession(); } private void createAndStoreCategory( String categoryName ) { createAndStoreCategory( categoryName, false ); } private void createAndStoreCategory( String categoryName, boolean autoApprove ) { fixture.save( factory.createCategory( categoryName, null, "Person", "UnitForPerson", User.ANONYMOUS_UID, User.ANONYMOUS_UID, autoApprove ) ); fixture.flushAndClearHibernateSession(); } }