/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.services.elements; import java.util.Collections; import java.util.List; import nl.strohalm.cyclos.access.AdminMemberPermission; import nl.strohalm.cyclos.access.BrokerPermission; import nl.strohalm.cyclos.access.MemberPermission; import nl.strohalm.cyclos.access.OperatorPermission; import nl.strohalm.cyclos.entities.Relationship; import nl.strohalm.cyclos.entities.members.Member; import nl.strohalm.cyclos.entities.members.messages.Message; import nl.strohalm.cyclos.entities.members.messages.MessageQuery; import nl.strohalm.cyclos.exceptions.PermissionDeniedException; import nl.strohalm.cyclos.services.BaseServiceSecurity; import nl.strohalm.cyclos.utils.access.LoggedUser; import nl.strohalm.cyclos.utils.validation.ValidationException; /** * Security implementation for {@link MessageService} * * @author jcomas */ public class MessageServiceSecurity extends BaseServiceSecurity implements MessageService { private MessageServiceLocal messageService; private MessageCategoryServiceLocal messageCategoryService; @Override public boolean canManage(final Message message) { return messageService.canManage(message); } @Override public boolean canSendToAdmin() { return messageService.canSendToAdmin(); } @Override public boolean canSendToMember(final Member member) { return messageService.canSendToMember(member); } @Override public Message load(final Long id, final Relationship... fetch) { Message message = messageService.load(id, fetch); checkView(message); return message; } @Override public void performAction(final MessageAction action, final Long... ids) { for (Long id : ids) { Message message = messageService.load(id); checkManage(message); } messageService.performAction(action, ids); } @Override public Message read(final Long id, final Relationship... fetch) { Message message = messageService.read(id, fetch); checkView(message); return message; } @Override public List<Message> search(final MessageQuery query) { if (!applyQueryRestrictions(query)) { return Collections.emptyList(); } return messageService.search(query); } @Override public Message send(final SendMessageDTO message) { checkSend(message); return messageService.send(message); } public void setMessageCategoryServiceLocal(final MessageCategoryServiceLocal messageCategoryService) { this.messageCategoryService = messageCategoryService; } public void setMessageServiceLocal(final MessageServiceLocal messageService) { this.messageService = messageService; } @Override public void validate(final SendMessageDTO message) throws ValidationException { // Nothing to check messageService.validate(message); } private boolean applyQueryRestrictions(final MessageQuery query) { if (!permissionService.permission() .admin(AdminMemberPermission.MESSAGES_VIEW) .member(MemberPermission.MESSAGES_VIEW) .operator(OperatorPermission.MESSAGES_VIEW).hasPermission()) { return false; } query.setGetter(LoggedUser.element()); return true; } private void checkManage(final Message message) { if (!canManage(message)) { throw new PermissionDeniedException(); } } private void checkSend(final SendMessageDTO message) { if (message instanceof SendMessageToGroupDTO) { permissionService.permission().admin(AdminMemberPermission.MESSAGES_SEND_TO_GROUP).check(); // Check if the to groups are visible to the logged user. if (!permissionService.getVisibleMemberGroups().containsAll(((SendMessageToGroupDTO) message).getToGroups())) { throw new PermissionDeniedException(); } } else if (message instanceof SendMessageFromBrokerToMembersDTO) { permissionService.permission().broker(BrokerPermission.MESSAGES_SEND_TO_MEMBERS).check(); } else if (message instanceof SendMessageToAdminDTO) { if (!canSendToAdmin()) { throw new PermissionDeniedException(); } } else if (message instanceof SendDirectMessageToMemberDTO) { if (!canSendToMember(((SendDirectMessageToMemberDTO) message).getToMember())) { throw new PermissionDeniedException(); } } else { throw new IllegalArgumentException("Unexpected message class received " + message.getClass().getName()); } // Check if the category is visible to the logged user. if (message.getCategory() != null && !messageCategoryService.canView(message.getCategory())) { throw new PermissionDeniedException(); } // If it's in reply to another message, check that the reply message is visible to the logged user. if (message.getInReplyTo() != null) { checkView(message.getInReplyTo()); } } private void checkView(final Message message) { permissionService.permission() .admin(AdminMemberPermission.MESSAGES_VIEW) .member(MemberPermission.MESSAGES_VIEW) .operator(OperatorPermission.MESSAGES_VIEW).check(); if (messageService.checkMessageOwner(message) == null) { throw new PermissionDeniedException(); } } }