CCM NG/ccm-cms:

- ContentSectionManager#addContentTypeToSection: Create permissions allowing type use for all roles of the contentsection when adding a content type to a content section.
- ContentItemManager#createContentItem: Verify that current user is allowed to use the provided type when creating a content item.


git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4456 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-11-25 08:56:29 +00:00
parent b39aa8152f
commit 45c8296282
2 changed files with 105 additions and 94 deletions

View File

@ -68,6 +68,9 @@ import java.util.UUID;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import org.libreccm.security.PermissionChecker;
import org.libreccm.security.PermissionManager;
import org.librecms.contentsection.privileges.TypePrivileges;
/** /**
* Manager class providing several methods to manipulate {@link ContentItem}s. * Manager class providing several methods to manipulate {@link ContentItem}s.
@ -112,6 +115,9 @@ public class ContentItemManager {
@Inject @Inject
private AssetManager assetManager; private AssetManager assetManager;
@Inject
private PermissionChecker permissionChecker;
/** /**
* Creates a new content item in the provided content section and folder * Creates a new content item in the provided content section and folder
@ -198,6 +204,10 @@ public class ContentItemManager {
type.getName())); type.getName()));
} }
//Check if the current user is allowed to use the content type
permissionChecker.checkPermission(TypePrivileges.USE_TYPE,
contentType.get());
if (name == null || name.trim().isEmpty()) { if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The name of a content item can't be blank."); "The name of a content item can't be blank.");

View File

@ -51,6 +51,7 @@ import org.librecms.contentsection.privileges.ItemPrivileges;
import org.librecms.lifecycle.LifecycleDefinition; import org.librecms.lifecycle.LifecycleDefinition;
import java.util.Optional; import java.util.Optional;
import org.librecms.contentsection.privileges.TypePrivileges;
import static org.librecms.contentsection.ContentSection.*; import static org.librecms.contentsection.ContentSection.*;
@ -97,11 +98,11 @@ public class ContentSectionManager {
public ContentSection createContentSection(final String name) { public ContentSection createContentSection(final String name) {
if (name == null || name.isEmpty()) { if (name == null || name.isEmpty()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The name of a ContentSection can't be blank."); "The name of a ContentSection can't be blank.");
} }
final KernelConfig kernelConfig = confManager.findConfiguration( final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class); KernelConfig.class);
final Locale defautLocale = kernelConfig.getDefaultLocale(); final Locale defautLocale = kernelConfig.getDefaultLocale();
final ContentSection section = new ContentSection(); final ContentSection section = new ContentSection();
@ -250,21 +251,21 @@ public class ContentSectionManager {
* {@link CmsConstants#AdminPrivileges.ADMINISTER_ROLES} for the provided * {@link CmsConstants#AdminPrivileges.ADMINISTER_ROLES} for the provided
* content section. * content section.
* *
* @param section The {@link ContentSection} to which the role is added. * @param section The {@link ContentSection} to which the role is added.
* @param roleName The name of the new role. * @param roleName The name of the new role.
* @param privileges The privileges of the new role. * @param privileges The privileges of the new role.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addRoleToContentSection( public void addRoleToContentSection(
@RequiresPrivilege(AdminPrivileges.ADMINISTER_ROLES) @RequiresPrivilege(AdminPrivileges.ADMINISTER_ROLES)
final ContentSection section, final ContentSection section,
final String roleName, final String roleName,
final String... privileges) { final String... privileges) {
if (section == null) { if (section == null) {
throw new IllegalArgumentException("Can't add a role to " throw new IllegalArgumentException("Can't add a role to "
+ "section null."); + "section null.");
} }
if (roleName == null || roleName.trim().isEmpty()) { if (roleName == null || roleName.trim().isEmpty()) {
@ -289,24 +290,24 @@ public class ContentSectionManager {
* requires {@link CmsConstants#AdminPrivileges.ADMINISTER_ROLES} for the * requires {@link CmsConstants#AdminPrivileges.ADMINISTER_ROLES} for the
* provided content section. * provided content section.
* *
* @param role The role to add. * @param role The role to add.
* @param section The section the role is associated with. * @param section The section the role is associated with.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addRoleToContentSection( public void addRoleToContentSection(
final Role role, final Role role,
@RequiresPrivilege(AdminPrivileges.ADMINISTER_ROLES) @RequiresPrivilege(AdminPrivileges.ADMINISTER_ROLES)
final ContentSection section) { final ContentSection section) {
if (section == null) { if (section == null) {
throw new IllegalArgumentException("Can't add a role to " throw new IllegalArgumentException("Can't add a role to "
+ "section null."); + "section null.");
} }
if (role == null) { if (role == null) {
throw new IllegalArgumentException("Can't add role null to a " throw new IllegalArgumentException("Can't add role null to a "
+ "content section."); + "content section.");
} }
section.addRole(role); section.addRole(role);
@ -322,18 +323,18 @@ public class ContentSectionManager {
* content section. * content section.
* *
* @param contentSection The section from which the role is removed. * @param contentSection The section from which the role is removed.
* @param role The role to remove from the content section. * @param role The role to remove from the content section.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeRoleFromContentSection( public void removeRoleFromContentSection(
@RequiresPrivilege(AdminPrivileges.ADMINISTER_ROLES) @RequiresPrivilege(AdminPrivileges.ADMINISTER_ROLES)
final ContentSection contentSection, final ContentSection contentSection,
final Role role) { final Role role) {
if (contentSection == null) { if (contentSection == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't remove role from ContentSection null"); "Can't remove role from ContentSection null");
} }
if (role == null) { if (role == null) {
@ -344,8 +345,8 @@ public class ContentSectionManager {
sectionRepo.save(contentSection); sectionRepo.save(contentSection);
final TypedQuery<Permission> query = entityManager final TypedQuery<Permission> query = entityManager
.createNamedQuery("ContentSection.findPermissions", .createNamedQuery("ContentSection.findPermissions",
Permission.class); Permission.class);
query.setParameter("section", contentSection); query.setParameter("section", contentSection);
query.setParameter("rootDocumentsFolder", query.setParameter("rootDocumentsFolder",
contentSection.getRootDocumentsFolder()); contentSection.getRootDocumentsFolder());
@ -361,14 +362,14 @@ public class ContentSectionManager {
* provided content section. * provided content section.
* *
* @param definition The lifecycle definition to add. * @param definition The lifecycle definition to add.
* @param section The section to which the definition is added. * @param section The section to which the definition is added.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addLifecycleDefinitionToContentSection( public void addLifecycleDefinitionToContentSection(
final LifecycleDefinition definition, final LifecycleDefinition definition,
@RequiresPrivilege(AdminPrivileges.ADMINISTER_LIFECYLES) @RequiresPrivilege(AdminPrivileges.ADMINISTER_LIFECYLES)
final ContentSection section) { final ContentSection section) {
section.addLifecycleDefinition(definition); section.addLifecycleDefinition(definition);
sectionRepo.save(section); sectionRepo.save(section);
@ -380,14 +381,14 @@ public class ContentSectionManager {
* the provided content section. * the provided content section.
* *
* @param definition The definition to remove. * @param definition The definition to remove.
* @param section The section from which the definition is removed. * @param section The section from which the definition is removed.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeLifecycleDefinitionFromContentSection( public void removeLifecycleDefinitionFromContentSection(
final LifecycleDefinition definition, final LifecycleDefinition definition,
@RequiresPrivilege(AdminPrivileges.ADMINISTER_LIFECYLES) @RequiresPrivilege(AdminPrivileges.ADMINISTER_LIFECYLES)
final ContentSection section) { final ContentSection section) {
section.removeLifecycleDefinition(definition); section.removeLifecycleDefinition(definition);
sectionRepo.save(section); sectionRepo.save(section);
@ -399,14 +400,14 @@ public class ContentSectionManager {
* content section. * content section.
* *
* @param template The template to add. * @param template The template to add.
* @param section The content section to which the template is added. * @param section The content section to which the template is added.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void addWorkflowTemplateToContentSection( public void addWorkflowTemplateToContentSection(
final WorkflowTemplate template, final WorkflowTemplate template,
@RequiresPrivilege(AdminPrivileges.ADMINISTER_WORKFLOW) @RequiresPrivilege(AdminPrivileges.ADMINISTER_WORKFLOW)
final ContentSection section) { final ContentSection section) {
section.addWorkflowTemplate(template); section.addWorkflowTemplate(template);
sectionRepo.save(section); sectionRepo.save(section);
@ -418,14 +419,14 @@ public class ContentSectionManager {
* provided content section. * provided content section.
* *
* @param template The template to remove. * @param template The template to remove.
* @param section The section from which the template is removed. * @param section The section from which the template is removed.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeWorkflowTemplateFromContentSection( public void removeWorkflowTemplateFromContentSection(
final WorkflowTemplate template, final WorkflowTemplate template,
@RequiresPrivilege(AdminPrivileges.ADMINISTER_WORKFLOW) @RequiresPrivilege(AdminPrivileges.ADMINISTER_WORKFLOW)
final ContentSection section) { final ContentSection section) {
section.removeWorkflowTemplate(template); section.removeWorkflowTemplate(template);
sectionRepo.save(section); sectionRepo.save(section);
@ -435,7 +436,7 @@ public class ContentSectionManager {
* Retrieves the {@link ItemResolver} for the provided content section. * Retrieves the {@link ItemResolver} for the provided content section.
* *
* @param section The section for which the {@link ItemResolver} is * @param section The section for which the {@link ItemResolver} is
* retrieved. * retrieved.
* *
* @return The {@link ItemResolver} for the provided content section. * @return The {@link ItemResolver} for the provided content section.
*/ */
@ -443,12 +444,12 @@ public class ContentSectionManager {
try { try {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final Class<ItemResolver> itemResolverClazz final Class<ItemResolver> itemResolverClazz
= (Class<ItemResolver>) Class. = (Class<ItemResolver>) Class.
forName(section.getItemResolverClass()); forName(section.getItemResolverClass());
return itemResolverClazz.newInstance(); return itemResolverClazz.newInstance();
} catch (ClassNotFoundException } catch (ClassNotFoundException
| IllegalAccessException | IllegalAccessException
| InstantiationException ex) { | InstantiationException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }
@ -459,75 +460,72 @@ public class ContentSectionManager {
* {@link CmsConstants#AdminPrivileges.ADMINISTER_CONTENT_TYPES} for the * {@link CmsConstants#AdminPrivileges.ADMINISTER_CONTENT_TYPES} for the
* provided content section. * provided content section.
* *
* @param type The type to add (a subclass of * @param type The type to add (a subclass of {@link ContentItem}.
* {@link ContentItem}. * @param section The section to which the type is added.
* @param section The section to which the type is added.
* @param defaultLifecycle The default lifecycle for items of the provided * @param defaultLifecycle The default lifecycle for items of the provided
* type in the provided content section. The * type in the provided content section. The lifecycle must be part of the
* lifecycle must be part of the provided section. * provided section. Otherwise an {@link IllegalArgumentException} is
* Otherwise an {@link IllegalArgumentException} is * thrown.
* thrown. * @param defaultWorkflow The default workflow for items of the provided
* @param defaultWorkflow The default workflow for items of the provided * type in the provided content section. The workflow must be part of the
* type in the provided content section. The * provided section. Otherwise an {@link IllegalArgumentException} is
* workflow must be part of the provided section. * thrown.
* Otherwise an {@link IllegalArgumentException} is
* thrown.
* *
* @return The new {@link ContentType} instance. * @return The new {@link ContentType} instance.
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public ContentType addContentTypeToSection( public ContentType addContentTypeToSection(
final Class<? extends ContentItem> type, final Class<? extends ContentItem> type,
@RequiresPrivilege(AdminPrivileges.ADMINISTER_CONTENT_TYPES) @RequiresPrivilege(AdminPrivileges.ADMINISTER_CONTENT_TYPES)
final ContentSection section, final ContentSection section,
final LifecycleDefinition defaultLifecycle, final LifecycleDefinition defaultLifecycle,
final WorkflowTemplate defaultWorkflow) { final WorkflowTemplate defaultWorkflow) {
if (type == null) { if (type == null) {
throw new IllegalArgumentException("Can't add null as content type " throw new IllegalArgumentException("Can't add null as content type "
+ "to a content section."); + "to a content section.");
} }
if (section == null) { if (section == null) {
throw new IllegalArgumentException("Can't add a content type" throw new IllegalArgumentException("Can't add a content type"
+ "to section null."); + "to section null.");
} }
if (defaultLifecycle == null) { if (defaultLifecycle == null) {
throw new IllegalArgumentException("Can't create a content type " throw new IllegalArgumentException("Can't create a content type "
+ "without a default lifecycle."); + "without a default lifecycle.");
} }
if (defaultWorkflow == null) { if (defaultWorkflow == null) {
throw new IllegalArgumentException("Can't create a content type " throw new IllegalArgumentException("Can't create a content type "
+ "without a default workflow."); + "without a default workflow.");
} }
if (!section.getLifecycleDefinitions().contains(defaultLifecycle)) { if (!section.getLifecycleDefinitions().contains(defaultLifecycle)) {
final KernelConfig kernelConfig = confManager.findConfiguration( final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class); KernelConfig.class);
final Locale defaultLocale = kernelConfig.getDefaultLocale(); final Locale defaultLocale = kernelConfig.getDefaultLocale();
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"The provided default lifecycle %d\"%s\" is not part of the" "The provided default lifecycle %d\"%s\" is not part of the"
+ "provided content section %d\"%s\".", + "provided content section %d\"%s\".",
defaultLifecycle.getDefinitionId(), defaultLifecycle.getDefinitionId(),
defaultLifecycle.getLabel().getValue(defaultLocale), defaultLifecycle.getLabel().getValue(defaultLocale),
section.getObjectId(), section.getObjectId(),
section.getDisplayName())); section.getDisplayName()));
} }
if (!section.getWorkflowTemplates().contains(defaultWorkflow)) { if (!section.getWorkflowTemplates().contains(defaultWorkflow)) {
final KernelConfig kernelConfig = confManager.findConfiguration( final KernelConfig kernelConfig = confManager.findConfiguration(
KernelConfig.class); KernelConfig.class);
final Locale defaultLocale = kernelConfig.getDefaultLocale(); final Locale defaultLocale = kernelConfig.getDefaultLocale();
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"The provided default workflow %d\"%s\" is not part of the" "The provided default workflow %d\"%s\" is not part of the"
+ "provided content section %d\"%s\".", + "provided content section %d\"%s\".",
defaultWorkflow.getWorkflowId(), defaultWorkflow.getWorkflowId(),
defaultWorkflow.getName().getValue(defaultLocale), defaultWorkflow.getName().getValue(defaultLocale),
section.getObjectId(), section.getObjectId(),
section.getDisplayName())); section.getDisplayName()));
} }
if (hasContentType(type, section)) { if (hasContentType(type, section)) {
@ -544,6 +542,10 @@ public class ContentSectionManager {
section.addContentType(contentType); section.addContentType(contentType);
section.getRoles().stream()
.forEach(role -> permissionManager.grantPrivilege(
TypePrivileges.USE_TYPE, role, contentType));
sectionRepo.save(section); sectionRepo.save(section);
typeRepo.save(contentType); typeRepo.save(contentType);
@ -554,11 +556,11 @@ public class ContentSectionManager {
* Checks if a content section has a {@link ContentType} for a specific * Checks if a content section has a {@link ContentType} for a specific
* subclass {@link ContentItem}. * subclass {@link ContentItem}.
* *
* @param type The type to check for. * @param type The type to check for.
* @param section The section to check for the {@link ContentType}. * @param section The section to check for the {@link ContentType}.
* *
* @return {@code true} if the section has a {@link ContentType} for * @return {@code true} if the section has a {@link ContentType} for
* {@code type}, {@code false} if not. * {@code type}, {@code false} if not.
*/ */
public boolean hasContentType(final Class<? extends ContentItem> type, public boolean hasContentType(final Class<? extends ContentItem> type,
final ContentSection section) { final ContentSection section) {
@ -572,7 +574,7 @@ public class ContentSectionManager {
} }
final Optional<ContentType> result = typeRepo final Optional<ContentType> result = typeRepo
.findByContentSectionAndClass(section, type); .findByContentSectionAndClass(section, type);
return result.isPresent(); return result.isPresent();
} }
@ -583,21 +585,20 @@ public class ContentSectionManager {
* {@link CmsConstants#AdminPrivileges.ADMINISTER_CONTENT_TYPES} for the * {@link CmsConstants#AdminPrivileges.ADMINISTER_CONTENT_TYPES} for the
* provided content section. * provided content section.
* *
* @param type The type to remove from the section. * @param type The type to remove from the section.
* @param section The section from which the type is removed. * @param section The section from which the type is removed.
* *
* @throws IllegalArgumentException if the provided {@link ContentType} is * @throws IllegalArgumentException if the provided {@link ContentType} is
* in use or the parameters or otherwise * in use or the parameters or otherwise illegal.
* illegal.
* @see * @see
* ContentTypeRepository#delete(org.librecms.contentsection.ContentType) * ContentTypeRepository#delete(org.librecms.contentsection.ContentType)
*/ */
@AuthorizationRequired @AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public void removeContentTypeFromSection( public void removeContentTypeFromSection(
final Class<? extends ContentItem> type, final Class<? extends ContentItem> type,
@RequiresPrivilege(AdminPrivileges.ADMINISTER_CONTENT_TYPES) @RequiresPrivilege(AdminPrivileges.ADMINISTER_CONTENT_TYPES)
final ContentSection section) { final ContentSection section) {
if (type == null) { if (type == null) {
throw new IllegalArgumentException("Can't remove content type null."); throw new IllegalArgumentException("Can't remove content type null.");
@ -605,11 +606,11 @@ public class ContentSectionManager {
if (section == null) { if (section == null) {
throw new IllegalArgumentException("Can't remove a content type " throw new IllegalArgumentException("Can't remove a content type "
+ "from section null."); + "from section null.");
} }
final Optional<ContentType> contentType = typeRepo final Optional<ContentType> contentType = typeRepo
.findByContentSectionAndClass(section, type); .findByContentSectionAndClass(section, type);
if (!contentType.isPresent()) { if (!contentType.isPresent()) {
return; return;
@ -617,12 +618,12 @@ public class ContentSectionManager {
if (typeRepo.isContentTypeInUse(contentType.get())) { if (typeRepo.isContentTypeInUse(contentType.get())) {
throw new IllegalArgumentException(String.format( throw new IllegalArgumentException(String.format(
"ContentType %d:\"%s\" is used by content section %d:\"%s\" and " "ContentType %d:\"%s\" is used by content section %d:\"%s\" and "
+ "can't be deleted.", + "can't be deleted.",
contentType.get().getObjectId(), contentType.get().getObjectId(),
contentType.get().getDisplayName(), contentType.get().getDisplayName(),
section.getObjectId(), section.getObjectId(),
section.getDisplayName())); section.getDisplayName()));
} }
typeRepo.delete(contentType.get()); typeRepo.delete(contentType.get());