/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.itest.search;
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.google.common.collect.Lists;
import com.enonic.cms.framework.xml.XMLDocumentFactory;
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.access.ContentAccessEntity;
import com.enonic.cms.core.content.category.CategoryAccessType;
import com.enonic.cms.core.content.command.CreateContentCommand;
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.content.index.ContentIndexQuery;
import com.enonic.cms.core.content.query.OpenContentQuery;
import com.enonic.cms.core.content.resultset.ContentResultSet;
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.store.dao.CategoryDao;
import com.enonic.cms.store.dao.ContentDao;
import com.enonic.cms.store.dao.GroupDao;
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 ContentIndexServiceImpl_accessRightsTest
extends ContentIndexServiceTestHibernatedBase
{
@Autowired
private SecurityService securityService;
@Autowired
private CategoryDao categoryDao;
@Autowired
protected ContentDao contentDao;
@Autowired
protected GroupDao groupDao;
@Autowired
protected ContentService contentService;
private SiteRedirectHelper siteRedirectHelper;
private ContentServicesProcessor customContentHandlerController;
private UserServicesRedirectUrlResolver userServicesRedirectUrlResolver;
@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 user_access()
throws Exception
{
// Setup
String categoryName = "category";
createAndStoreCategory( categoryName );
createAndSaveNormalUser( "norway_user", "testuserstore" );
createAndSaveNormalUser( "europe_user", "testuserstore" );
createAndSaveNormalUser( "no_access_user", "testuserstore" );
createAndSaveCategoryAccess( categoryName, "norway_user", "create" );
final CreateContentCommand createContentCommand = createCreateContentCommand( categoryName, "norway_user", ContentStatus.DRAFT );
ContentAccessEntity rmyAccess = createContentAccess( "norway_user", true, false );
ContentAccessEntity adminAccess = createContentAccess( "europe_user", true, false );
createContentCommand.addContentAccessRights( Lists.newArrayList( rmyAccess, adminAccess ), null );
ContentKey contentKey = contentService.createContent( createContentCommand );
assertNotNull( contentDao.findByKey( contentKey ) );
fixture.flushAndClearHibernateSession();
fixture.flushIndexTransaction();
// Exercise
OpenContentQuery query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "norway_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
ContentResultSet contentResultSet = contentService.queryContent( query );
assertEquals( 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "europe_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "no_access_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( 0, contentResultSet.getKeys().size() );
}
@Test
public void group_acess()
throws Exception
{
// Setup
String categoryName = "category";
createAndStoreCategory( categoryName );
createAndSaveNormalUser( "rmy", "testuserstore" );
createAndSaveNormalUser( "administrator", "testuserstore" );
createAndSaveNormalUser( "no_access_user", "testuserstore" );
createAndSaveCategoryAccess( categoryName, "rmy", "create" );
fixture.flushAndClearHibernateSession();
final GroupEntity groupWithAccess = createAndSaveGroup( "group_with_access", "testuserstore", GroupType.USERSTORE_GROUP );
fixture.findUserByName( "rmy" ).getUserGroup().addMembership( groupWithAccess );
fixture.findUserByName( "administrator" ).getUserGroup().addMembership( groupWithAccess );
final CreateContentCommand createContentCommand = createCreateContentCommand( categoryName, "rmy", ContentStatus.DRAFT );
ContentAccessEntity groupAccess = createContentAccess( groupWithAccess, true, false );
createContentCommand.addContentAccessRights( Lists.newArrayList( groupAccess ), null );
ContentKey contentKey = contentService.createContent( createContentCommand );
assertNotNull( contentDao.findByKey( contentKey ) );
fixture.flushAndClearHibernateSession();
fixture.flushIndexTransaction();
OpenContentQuery query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "rmy" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
ContentResultSet contentResultSet = contentService.queryContent( query );
assertEquals( 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "administrator" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "no_access_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( 0, contentResultSet.getKeys().size() );
}
@Test
public void group_transitive_access()
throws Exception
{
String categoryName = "category";
createAndStoreCategory( categoryName );
createAndSaveNormalUser( "norway_user", "testuserstore" );
createAndSaveNormalUser( "europe_user", "testuserstore" );
createAndSaveNormalUser( "world_user", "testuserstore" );
createAndSaveNormalUser( "no_access_user", "testuserstore" );
createAndSaveCategoryAccess( categoryName, "norway_user", "create" );
fixture.flushAndClearHibernateSession();
final GroupEntity groupNorway = createAndSaveGroup( "norway", "testuserstore", GroupType.USERSTORE_GROUP );
final GroupEntity groupEurope = createAndSaveGroup( "europe", "testuserstore", GroupType.USERSTORE_GROUP );
final GroupEntity groupWorld = createAndSaveGroup( "world", "testuserstore", GroupType.USERSTORE_GROUP );
fixture.findUserByName( "norway_user" ).getUserGroup().addMembership( groupNorway );
fixture.findUserByName( "europe_user" ).getUserGroup().addMembership( groupEurope );
fixture.findUserByName( "world_user" ).getUserGroup().addMembership( groupWorld );
fixture.findGroupByName( "norway" ).addMembership( groupEurope );
fixture.findGroupByName( "europe" ).addMembership( groupWorld );
fixture.flushAndClearHibernateSession();
final CreateContentCommand createContentCommand = createCreateContentCommand( categoryName, "norway_user", ContentStatus.DRAFT );
// Add access rights to all in world - group
ContentAccessEntity groupAccess = createContentAccess( groupWorld, true, false );
createContentCommand.addContentAccessRights( Lists.newArrayList( groupAccess ), null );
ContentKey contentKey = contentService.createContent( createContentCommand );
assertNotNull( contentDao.findByKey( contentKey ) );
fixture.flushAndClearHibernateSession();
fixture.flushIndexTransaction();
OpenContentQuery query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "norway_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
ContentResultSet contentResultSet = contentService.queryContent( query );
assertEquals( "norway_user should have access", 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "europe_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( "europe_user should have access", 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "world_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( "world_user should have access", 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "no_access_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( 0, contentResultSet.getKeys().size() );
}
@Test
public void child_not_parent_no_access()
throws Exception
{
String categoryName = "category";
createAndStoreCategory( categoryName );
createAndSaveNormalUser( "rmy", "testuserstore" );
createAndSaveNormalUser( "administrator", "testuserstore" );
createAndSaveNormalUser( "no_access_user", "testuserstore" );
createAndSaveCategoryAccess( categoryName, "rmy", "admin_browse, read, create" );
fixture.flushAndClearHibernateSession();
final GroupEntity groupWithAccess = createAndSaveGroup( "group_with_access", "testuserstore", GroupType.USERSTORE_GROUP );
final GroupEntity groupWithAccessParent =
createAndSaveGroup( "group_with_access_parent", "testuserstore", GroupType.USERSTORE_GROUP );
fixture.findUserByName( "rmy" ).getUserGroup().addMembership( groupWithAccessParent );
fixture.findUserByName( "administrator" ).getUserGroup().addMembership( groupWithAccessParent );
final CreateContentCommand createContentCommand = createCreateContentCommand( categoryName, "rmy", ContentStatus.DRAFT );
ContentAccessEntity groupAccess = createContentAccess( groupWithAccess, true, false );
createContentCommand.addContentAccessRights( Lists.newArrayList( groupAccess ), null );
ContentKey contentKey = contentService.createContent( createContentCommand );
assertNotNull( contentDao.findByKey( contentKey ) );
fixture.flushAndClearHibernateSession();
fixture.flushIndexTransaction();
OpenContentQuery query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "rmy" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
ContentResultSet contentResultSet = contentService.queryContent( query );
assertEquals( 0, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "administrator" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( 0, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "no_access_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
contentResultSet = contentService.queryContent( query );
assertEquals( 0, contentResultSet.getKeys().size() );
}
@Test
public void category_access()
throws Exception
{
String categoryName = "category";
createAndStoreCategory( categoryName );
createAndSaveNormalUser( "norway_user", "testuserstore" );
createAndSaveNormalUser( "europe_user", "testuserstore" );
createAndSaveNormalUser( "world_user", "testuserstore" );
createAndSaveNormalUser( "no_access_user", "testuserstore" );
fixture.flushAndClearHibernateSession();
final GroupEntity groupNorway = createAndSaveGroup( "norway", "testuserstore", GroupType.USERSTORE_GROUP );
final GroupEntity groupEurope = createAndSaveGroup( "europe", "testuserstore", GroupType.USERSTORE_GROUP );
final GroupEntity groupWorld = createAndSaveGroup( "world", "testuserstore", GroupType.USERSTORE_GROUP );
fixture.findUserByName( "norway_user" ).getUserGroup().addMembership( groupNorway );
fixture.findUserByName( "europe_user" ).getUserGroup().addMembership( groupEurope );
fixture.findUserByName( "world_user" ).getUserGroup().addMembership( groupWorld );
fixture.findGroupByName( "norway" ).addMembership( groupEurope );
fixture.findGroupByName( "europe" ).addMembership( groupWorld );
fixture.flushAndClearHibernateSession();
createAndSaveCategoryAccessForGroup( categoryName, "world", "create, read, admin_browse" );
final CreateContentCommand createContentCommand = createCreateContentCommand( categoryName, "norway_user", ContentStatus.DRAFT );
createContentCommand.setAccessRightsStrategy( CreateContentCommand.AccessRightsStrategy.INHERIT_FROM_CATEGORY );
ContentKey contentKey = contentService.createContent( createContentCommand );
assertNotNull( contentDao.findByKey( contentKey ) );
fixture.flushAndClearHibernateSession();
fixture.flushIndexTransaction();
OpenContentQuery query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "norway_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
query.setCategoryAccessTypeFilter( Lists.newArrayList( CategoryAccessType.ADMIN_BROWSE, CategoryAccessType.READ ),
ContentIndexQuery.CategoryAccessTypeFilterPolicy.AND );
ContentResultSet contentResultSet = contentService.queryContent( query );
assertEquals( "norway_user should have access", 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "europe_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
query.setCategoryAccessTypeFilter( Lists.newArrayList( CategoryAccessType.ADMIN_BROWSE ),
ContentIndexQuery.CategoryAccessTypeFilterPolicy.AND );
contentResultSet = contentService.queryContent( query );
assertEquals( "europe_user should have access", 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "world_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
query.setCategoryAccessTypeFilter( Lists.newArrayList( CategoryAccessType.ADMIN_BROWSE ),
ContentIndexQuery.CategoryAccessTypeFilterPolicy.AND );
contentResultSet = contentService.queryContent( query );
assertEquals( "world_user should have access", 1, contentResultSet.getKeys().size() );
query = new OpenContentQuery();
query.setUser( fixture.findUserByName( "no_access_user" ) );
query.setContentKeyFilter( Lists.newArrayList( contentKey ) );
query.setCategoryAccessTypeFilter( Lists.newArrayList( CategoryAccessType.ADMIN_BROWSE ),
ContentIndexQuery.CategoryAccessTypeFilterPolicy.AND );
contentResultSet = contentService.queryContent( query );
assertEquals( 0, contentResultSet.getKeys().size() );
}
protected 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;
}
protected GroupEntity createAndSaveGroup( String groupId, String userstoreName, GroupType groupType )
{
GroupEntity group = factory.createGroupInUserstore( groupId, groupType, userstoreName );
fixture.save( group );
return group;
}
protected 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();
}
protected void createAndStoreCategory( String categoryName )
{
createAndStoreCategory( categoryName, false );
}
protected void createAndStoreCategory( String categoryName, boolean autoApprove )
{
fixture.save(
factory.createCategory( categoryName, null, "Person", "UnitForPerson", User.ANONYMOUS_UID, User.ANONYMOUS_UID, autoApprove ) );
fixture.flushAndClearHibernateSession();
}
protected void createAndSaveContentAccess( ContentKey contentKey, String userUid, String accesses )
{
final UserEntity user = fixture.findUserByName( userUid );
fixture.save( factory.createContentAccess( contentKey, user, accesses ) );
fixture.flushAndClearHibernateSession();
}
protected void createAndSaveCategoryAccess( String categoryName, String userUid, String accesses )
{
final UserEntity user = fixture.findUserByName( userUid );
//final CategoryEntity category = fixture.findCategoryByName( categoryName );
//category.addAccessRight( factory.createCategoryAccess( categoryName, user, accesses ) );
fixture.save( factory.createCategoryAccess( categoryName, user, accesses ) );
fixture.flushAndClearHibernateSession();
}
protected void createAndSaveCategoryAccessForGroup( String categoryName, String groupName, String accesses )
{
final GroupEntity group = fixture.findGroupByName( groupName );
fixture.save( factory.createCategoryAccess( categoryName, group, accesses ) );
fixture.flushAndClearHibernateSession();
}
protected ContentAccessEntity createContentAccess( GroupEntity group, boolean read, boolean update )
{
ContentAccessEntity contentAccess = new ContentAccessEntity();
contentAccess.setGroup( group );
contentAccess.setReadAccess( read );
contentAccess.setUpdateAccess( update );
return contentAccess;
}
}