/* 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.accounts.guarantees; import java.math.BigDecimal; import java.util.Collection; import java.util.Collections; import java.util.List; import nl.strohalm.cyclos.access.AdminMemberPermission; import nl.strohalm.cyclos.access.AdminSystemPermission; import nl.strohalm.cyclos.access.MemberPermission; import nl.strohalm.cyclos.access.OperatorPermission; import nl.strohalm.cyclos.entities.Relationship; import nl.strohalm.cyclos.entities.accounts.AccountOwner; import nl.strohalm.cyclos.entities.accounts.guarantees.Certification; import nl.strohalm.cyclos.entities.accounts.guarantees.Guarantee; import nl.strohalm.cyclos.entities.accounts.guarantees.Guarantee.Status; import nl.strohalm.cyclos.entities.accounts.guarantees.GuaranteeQuery; import nl.strohalm.cyclos.entities.accounts.guarantees.GuaranteeType; import nl.strohalm.cyclos.entities.accounts.guarantees.GuaranteeType.Model; import nl.strohalm.cyclos.entities.accounts.transactions.Transfer; import nl.strohalm.cyclos.entities.groups.Group; import nl.strohalm.cyclos.entities.groups.MemberGroup; import nl.strohalm.cyclos.entities.members.Member; import nl.strohalm.cyclos.exceptions.PermissionDeniedException; import nl.strohalm.cyclos.services.BaseServiceSecurity; import nl.strohalm.cyclos.utils.access.LoggedUser; import nl.strohalm.cyclos.utils.query.PageParameters; /** * Security implementation for {@link GuaranteeService} * * @author jcomas */ public class GuaranteeServiceSecurity extends BaseServiceSecurity implements GuaranteeService { private GuaranteeServiceLocal guaranteeService; @Override public Guarantee acceptGuarantee(Guarantee guarantee, final boolean automaticLoanAuthorization) { guarantee = fetchService.fetch(guarantee, Guarantee.Relationships.BUYER, Guarantee.Relationships.ISSUER); boolean hasPermission = permissionService.permission(guarantee.getBuyer()) .admin(AdminMemberPermission.GUARANTEES_ACCEPT_GUARANTEES_AS_MEMBER) .hasPermission(); if (!hasPermission) { hasPermission = permissionService.permission(guarantee.getIssuer()) .member(MemberPermission.GUARANTEES_ISSUE_GUARANTEES) .operator(OperatorPermission.GUARANTEES_ISSUE_GUARANTEES) .hasPermission(); } if (!hasPermission) { throw new PermissionDeniedException(); } return guaranteeService.acceptGuarantee(guarantee, automaticLoanAuthorization && hasPermission(AdminSystemPermission.PAYMENTS_AUTHORIZE)); } @Override public BigDecimal calculateFee(final GuaranteeFeeCalculationDTO dto) { checkHasUser(); return guaranteeService.calculateFee(dto); } @Override public boolean canChangeStatus(final Guarantee guarantee, final Status newStatus) { checkHasUser(); return guaranteeService.canChangeStatus(guarantee, newStatus); } @Override public boolean canRemoveGuarantee(final Guarantee guarantee) { checkHasUser(); return guaranteeService.canRemoveGuarantee(guarantee); } @Override public Guarantee changeStatus(final Long guaranteeId, final Status newStatus) { Guarantee guarantee = guaranteeService.load(guaranteeId, Guarantee.Relationships.BUYER, Guarantee.Relationships.ISSUER); switch (newStatus) { case CANCELLED: case REJECTED: if (newStatus == Status.CANCELLED || LoggedUser.isAdministrator()) { permissionService.permission(guarantee.getBuyer()) .admin(AdminMemberPermission.GUARANTEES_CANCEL_GUARANTEES_AS_MEMBER) .check(); break; } // fall down for an Issuer rejecting a guarantee default: permissionService.permission(guarantee.getIssuer()) .member(MemberPermission.GUARANTEES_ISSUE_GUARANTEES) .operator(OperatorPermission.GUARANTEES_ISSUE_GUARANTEES) .check(); } return guaranteeService.changeStatus(guaranteeId, newStatus); } @Override public Collection<? extends MemberGroup> getBuyers() { permissionService.permission() .admin(AdminMemberPermission.GUARANTEES_VIEW_PAYMENT_OBLIGATIONS, AdminMemberPermission.GUARANTEES_VIEW_CERTIFICATIONS, AdminMemberPermission.GUARANTEES_VIEW_GUARANTEES) .member(MemberPermission.GUARANTEES_ISSUE_GUARANTEES, MemberPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS) .operator(OperatorPermission.GUARANTEES_ISSUE_GUARANTEES, OperatorPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS) .check(); return guaranteeService.getBuyers(); } @Override public List<Guarantee> getGuarantees(final Certification certification, final PageParameters pageParameters, final List<Status> statusList) { permissionService.permission() .admin(AdminMemberPermission.GUARANTEES_VIEW_CERTIFICATIONS) .member(MemberPermission.GUARANTEES_ISSUE_CERTIFICATIONS, MemberPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS) .operator(OperatorPermission.GUARANTEES_ISSUE_CERTIFICATIONS, OperatorPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS) .check(); return guaranteeService.getGuarantees(certification, pageParameters, statusList); } @Override public Collection<? extends MemberGroup> getIssuers() { permissionService.permission() .admin(AdminMemberPermission.GUARANTEES_VIEW_PAYMENT_OBLIGATIONS, AdminMemberPermission.GUARANTEES_VIEW_CERTIFICATIONS, AdminMemberPermission.GUARANTEES_VIEW_GUARANTEES) .member() .operator() .check(); return guaranteeService.getIssuers(); } @Override public Collection<? extends MemberGroup> getIssuers(final GuaranteeType guaranteeType) { permissionService.permission() .admin(AdminMemberPermission.GUARANTEES_REGISTER_GUARANTEES) .check(); return guaranteeService.getIssuers(guaranteeType); } @Override public Collection<Model> getRelatedGuaranteeModels() { permissionService.permission() .member() .operator() .check(); return guaranteeService.getRelatedGuaranteeModels(); } @Override public Collection<? extends MemberGroup> getSellers() { permissionService.permission() .admin(AdminMemberPermission.GUARANTEES_VIEW_PAYMENT_OBLIGATIONS, AdminMemberPermission.GUARANTEES_VIEW_CERTIFICATIONS, AdminMemberPermission.GUARANTEES_VIEW_GUARANTEES) .member(MemberPermission.GUARANTEES_ISSUE_GUARANTEES, MemberPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS) .operator(OperatorPermission.GUARANTEES_ISSUE_GUARANTEES, OperatorPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS) .check(); return guaranteeService.getSellers(); } @Override public boolean isBuyer() { checkHasUser(); return guaranteeService.isBuyer(); } @Override public boolean isIssuer() { checkHasUser(); return guaranteeService.isIssuer(); } @Override public boolean isSeller() { checkHasUser(); return guaranteeService.isSeller(); } @Override public Guarantee load(final Long id, final Relationship... fetch) { Guarantee guarantee = guaranteeService.load(id, fetch); checkView(guarantee); return guarantee; } @Override public Guarantee loadFromTransfer(final Transfer transfer) { Guarantee guarantee = guaranteeService.loadFromTransfer(transfer); if (guarantee != null && !canView(guarantee)) { guarantee = null; } return guarantee; } @Override public Guarantee registerGuarantee(final Guarantee guarantee) { permissionService.permission(guarantee.getBuyer()) .admin(AdminMemberPermission.GUARANTEES_REGISTER_GUARANTEES) .check(); if (guarantee.getIssuer() != null) { permissionService.checkManages(guarantee.getIssuer()); } if (guarantee.getSeller() != null) { permissionService.checkManages(guarantee.getSeller()); } // Ensure a logged user don't update a guarantee. if (!guarantee.isTransient()) { throw new PermissionDeniedException(); } return guaranteeService.registerGuarantee(guarantee); } @Override public int remove(final Long guaranteeId) { Guarantee guarantee = guaranteeService.load(guaranteeId, Guarantee.Relationships.BUYER); if (canRemoveGuarantee(guarantee)) { return guaranteeService.remove(guaranteeId); } else { throw new PermissionDeniedException(); } } @Override public Guarantee requestGuarantee(final PaymentObligationPackDTO pack) { permissionService.permission() .member(MemberPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS) .operator(OperatorPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS) .check(); return guaranteeService.requestGuarantee(pack); } @Override public List<Guarantee> search(final GuaranteeQuery queryParameters) { final boolean isIssuer = isIssuer(); final boolean isBuyer = isBuyer(); final boolean isSeller = isSeller(); if (isIssuer) { final Group group = fetchService.fetch(LoggedUser.group(), Group.Relationships.GUARANTEE_TYPES); if (group.getGuaranteeTypes().isEmpty()) { // has no permission to any guarantee type return Collections.emptyList(); } else { // check valid guarantee type selection if (queryParameters.getGuaranteeType() == null) { // all allowed GT queryParameters.setAllowedGuaranteeTypes(group.getGuaranteeTypes()); } else if (!group.getGuaranteeTypes().contains(queryParameters.getGuaranteeType())) { throw new IllegalArgumentException("Guarantee type not allowed to filter: " + queryParameters.getGuaranteeType()); } } queryParameters.setIssuer((Member) LoggedUser.accountOwner()); } if (isBuyer && isSeller) { queryParameters.setLoggedMember((Member) LoggedUser.accountOwner()); } else if (isBuyer) { queryParameters.setBuyer((Member) LoggedUser.accountOwner()); } else if (isSeller) { queryParameters.setLoggedMember((Member) LoggedUser.accountOwner()); } // if hasn't got any role then we must set the logged user as the buyer (to get guarantees whose model is with buyer only) boolean hasAdminViewPermission = hasPermission(AdminMemberPermission.GUARANTEES_VIEW_GUARANTEES); final boolean hasNoRole = !isBuyer && !isIssuer && !isSeller && !hasAdminViewPermission; if (hasNoRole) { queryParameters.setBuyer((Member) LoggedUser.accountOwner()); } else if (hasAdminViewPermission) { // the logged user is an admin with view permissions queryParameters.setManagedMemberGroups(permissionService.getManagedMemberGroups()); } return guaranteeService.search(queryParameters); } public void setGuaranteeServiceLocal(final GuaranteeServiceLocal guaranteeService) { this.guaranteeService = guaranteeService; } @Override public void validate(final Guarantee guarantee, final boolean isAuthorization) { guaranteeService.validate(guarantee, isAuthorization); } private boolean canView(final Guarantee guarantee) { // we have a permission to define a member as a guarantee's issuer then // if the logged user is the guarantee's issuer and he doesn't have permission we must reject him // we must use the account owner to support operators too AccountOwner owner = LoggedUser.accountOwner(); if (guarantee.getIssuer().equals(owner) && !permissionService.hasPermission(MemberPermission.GUARANTEES_ISSUE_GUARANTEES, OperatorPermission.GUARANTEES_ISSUE_GUARANTEES)) { return false; } else if (guarantee.getIssuer().equals(owner)) { return true; } boolean manages = false; if (guarantee.getGuaranteeType().getModel() == GuaranteeType.Model.WITH_BUYER_ONLY) { manages = permissionService.manages(guarantee.getBuyer()); } else { manages = permissionService.manages(guarantee.getBuyer()) || permissionService.manages(guarantee.getSeller()); } if (!manages) { return false; } else { return permissionService.permission() .admin(AdminMemberPermission.GUARANTEES_VIEW_GUARANTEES) .member() .operator() .hasPermission(); } } private void checkView(final Guarantee guarantee) { if (!canView(guarantee)) { throw new PermissionDeniedException(); } } }