/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.tem.document.authorization; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.module.tem.TemConstants; import org.kuali.kfs.module.tem.businessobject.TemProfile; import org.kuali.kfs.sys.document.authorization.FinancialSystemMaintenanceDocumentAuthorizerBase; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.kns.document.MaintenanceDocument; import org.kuali.rice.kns.document.authorization.DocumentAuthorizer; import org.kuali.rice.kns.document.authorization.MaintenanceDocumentAuthorizer; import org.kuali.rice.krad.bo.BusinessObject; import org.kuali.rice.krad.document.Document; /** * This authorizer needs to override the canCreate and canMaintain methods...which are final on the base MaintDocAuthorizer class that every other authorizer simply extends. Therefore, * this uses an "assistant" authorizer to defer most of its calls to (rootDocumentAuthorizer) and overrides the logic for canCreate and canMaintain to perform the very special logic for TemProfiles. * It's acknowledged that this whole thing is going to be harder to customize than the regular authorizer. */ public class TemProfileAuthorizer implements MaintenanceDocumentAuthorizer, DocumentAuthorizer { protected TemProfileAuthorizerAssistant rootDocumentAuthorizer; /** * Not overridden; we'll just rely on the Create / Maintain Document check for this one * @see org.kuali.rice.krad.maintenance.MaintenanceDocumentAuthorizer#canCreate(java.lang.Class, org.kuali.rice.kim.api.identity.Person) */ @Override public boolean canCreate(Class boClass, Person user) { return getRootDocumentAuthorizer().canCreate(boClass, user); } /** * Overridden to verify that the user has KFS-TEM Edit Own Tem Profile permission before maintaining their own record, and that the user * @see org.kuali.rice.krad.maintenance.MaintenanceDocumentAuthorizer#canMaintain(java.lang.Object, org.kuali.rice.kim.api.identity.Person) */ @Override public boolean canMaintain(Object dataObject, Person user) { boolean result = getRootDocumentAuthorizer().canMaintain(dataObject, user); TemProfile profile = null; if (dataObject instanceof TemProfile) { profile = (TemProfile)dataObject; } else if (dataObject instanceof MaintenanceDocument) { profile = (TemProfile)((MaintenanceDocument)dataObject).getNewMaintainableObject().getBusinessObject(); } result &= ((doesProfileMatchUser(profile, user) && canEditOwnProfile((BusinessObject)dataObject, user)) || canEditAllProfiles((BusinessObject)dataObject, user)); return result; } /** * Overridden to check that the user has the normal Create / Maintain permission and also, if it's their own profile, the ability to edit their own profile; if it's not their own profile, * it checks if they can edit anyone's profile * @see org.kuali.rice.krad.maintenance.MaintenanceDocumentAuthorizer#canCreateOrMaintain(org.kuali.rice.krad.maintenance.MaintenanceDocument, org.kuali.rice.kim.api.identity.Person) */ @Override public boolean canCreateOrMaintain(org.kuali.rice.krad.maintenance.MaintenanceDocument maintenanceDocument, Person user) { boolean result = getRootDocumentAuthorizer().canCreateOrMaintain(maintenanceDocument, user); final TemProfile profile = (TemProfile)maintenanceDocument.getNewMaintainableObject().getDataObject(); result &= ((doesProfileMatchUser(profile, user) && canEditOwnProfile(maintenanceDocument, user)) || canEditAllProfiles(maintenanceDocument, user)); return result; } /** * Determines if the given profile matches the given user * @param profile the profile to check * @return true if the profile is for the current user, false otherwise */ protected boolean doesProfileMatchUser(TemProfile profile, Person user) { if (profile != null && !StringUtils.isBlank(profile.getPrincipalId())) { final String userPrincipalId = (user == null) ? null : user.getPrincipalId(); return StringUtils.equals(profile.getPrincipalId(), userPrincipalId); } return false; // no principal id? then they couldn't log in and therefore they can't be the current user } /** * Determines if the given user is allowed to create or maintain their own profile * @param profileOrDoc the maintenance document maintaining the profile to check, or the profile itself * @param user the user asking for permission * @return true if the user has permission, false otherwise */ public boolean canEditOwnProfile(BusinessObject profileOrDoc, Person user) { Map<String, String> roleQualifications = new HashMap<String, String>(); if (profileOrDoc != null) { getRootDocumentAuthorizer().addRoleQualification(profileOrDoc, roleQualifications); } return this.isAuthorized(profileOrDoc, TemConstants.NAMESPACE, TemConstants.Permission.EDIT_OWN_PROFILE, user.getPrincipalId(), Collections.<String,String>emptyMap(), roleQualifications); } /** * Determines if the given user is allowed to maintain a profile for any user or customer * @param profileOrDoc the maintenance document maintaining the profile to check, or the profile itself * @param user the user asking for permission * @return true if the user has permission, false otherwise */ public boolean canEditAllProfiles(BusinessObject profileOrDoc, Person user) { Map<String, String> roleQualifications = new HashMap<String, String>(); if (profileOrDoc != null) { getRootDocumentAuthorizer().addRoleQualification(profileOrDoc, roleQualifications); } return this.isAuthorized(profileOrDoc, TemConstants.NAMESPACE, TemConstants.Permission.EDIT_ANY_PROFILE, user.getPrincipalId(), Collections.<String,String>emptyMap(), roleQualifications); } /** * Determines if the given user is allowed to create a profile for any user or customer * @param profileOrDoc the maintenance document maintaining the profile to check, or the profile itself * @param user the user asking for permission * @return true if the user has permission, false otherwise */ public boolean canCreateAnyProfile(BusinessObject profileOrDoc, Person user) { Map<String, String> roleQualifications = new HashMap<String, String>(); if (profileOrDoc != null) { getRootDocumentAuthorizer().addRoleQualification(profileOrDoc, roleQualifications); } return this.isAuthorized(profileOrDoc, TemConstants.NAMESPACE, TemConstants.Permission.CREATE_ANY_PROFILE, user.getPrincipalId(), Collections.<String,String>emptyMap(), roleQualifications); } @Override public boolean canCopy(Document document, Person user) { return getRootDocumentAuthorizer().canCopy(document, user); } @Override public boolean isAuthorized(Object dataObject, String namespaceCode, String permissionName, String principalId) { return getRootDocumentAuthorizer().isAuthorized(dataObject, namespaceCode, permissionName, principalId); } @Override public boolean isAuthorizedByTemplate(Object dataObject, String namespaceCode, String permissionTemplateName, String principalId) { return getRootDocumentAuthorizer().isAuthorizedByTemplate(dataObject, namespaceCode, permissionTemplateName, principalId); } @Override public boolean isAuthorized(Object dataObject, String namespaceCode, String permissionName, String principalId, Map<String, String> additionalPermissionDetails, Map<String, String> additionalRoleQualifiers) { return getRootDocumentAuthorizer().isAuthorized(dataObject, namespaceCode, permissionName, principalId, additionalPermissionDetails, additionalRoleQualifiers); } @Override public Set<String> getSecurePotentiallyHiddenSectionIds() { return getRootDocumentAuthorizer().getSecurePotentiallyHiddenSectionIds(); } @Override public boolean isAuthorized(BusinessObject businessObject, String namespaceCode, String permissionName, String principalId) { return getRootDocumentAuthorizer().isAuthorized(businessObject, namespaceCode, permissionName, principalId); } @Override public boolean isAuthorizedByTemplate(BusinessObject businessObject, String namespaceCode, String permissionTemplateName, String principalId) { return getRootDocumentAuthorizer().isAuthorizedByTemplate(businessObject, namespaceCode, permissionTemplateName, principalId); } @Override public boolean isAuthorized(BusinessObject businessObject, String namespaceCode, String permissionName, String principalId, Map<String, String> additionalPermissionDetails, Map<String, String> additionalRoleQualifiers) { return getRootDocumentAuthorizer().isAuthorized(businessObject, namespaceCode, permissionName, principalId, additionalPermissionDetails, additionalRoleQualifiers); } @Override public boolean isAuthorizedByTemplate(Object dataObject, String namespaceCode, String permissionTemplateName, String principalId, Map<String, String> additionalPermissionDetails, Map<String, String> additionalRoleQualifiers) { return getRootDocumentAuthorizer().isAuthorizedByTemplate(dataObject, namespaceCode, permissionTemplateName, principalId, additionalPermissionDetails, additionalRoleQualifiers); } @Override public Map<String, String> getCollectionItemRoleQualifications(BusinessObject collectionItemBusinessObject) { return getRootDocumentAuthorizer().getCollectionItemRoleQualifications(collectionItemBusinessObject); } @Override public Map<String, String> getCollectionItemPermissionDetails(BusinessObject collectionItemBusinessObject) { return getRootDocumentAuthorizer().getCollectionItemPermissionDetails(collectionItemBusinessObject); } @Override public boolean canInitiate(String documentTypeName, Person user) { return getRootDocumentAuthorizer().canInitiate(documentTypeName, user); } @Override public boolean canOpen(Document document, Person user) { return getRootDocumentAuthorizer().canOpen(document, user); } @Override public boolean canEdit(Document document, Person user) { return getRootDocumentAuthorizer().canEdit(document, user); } @Override public boolean canAnnotate(Document document, Person user) { return getRootDocumentAuthorizer().canAnnotate(document, user); } @Override public boolean canReload(Document document, Person user) { return getRootDocumentAuthorizer().canReload(document, user); } @Override public boolean canClose(Document document, Person user) { return getRootDocumentAuthorizer().canClose(document, user); } @Override public boolean canSave(Document document, Person user) { return getRootDocumentAuthorizer().canSave(document, user); } @Override public boolean canRoute(Document document, Person user) { return getRootDocumentAuthorizer().canRoute(document, user); } @Override public boolean canCancel(Document document, Person user) { return getRootDocumentAuthorizer().canCancel(document, user); } @Override public boolean canPerformRouteReport(Document document, Person user) { return getRootDocumentAuthorizer().canPerformRouteReport(document, user); } @Override public boolean canBlanketApprove(Document document, Person user) { return getRootDocumentAuthorizer().canBlanketApprove(document, user); } @Override public boolean canApprove(Document document, Person user) { return getRootDocumentAuthorizer().canApprove(document, user); } @Override public boolean canDisapprove(Document document, Person user) { return getRootDocumentAuthorizer().canDisapprove(document, user); } @Override public boolean canSendNoteFyi(Document document, Person user) { return getRootDocumentAuthorizer().canSendNoteFyi(document, user); } @Override public boolean canEditDocumentOverview(Document document, Person user) { return getRootDocumentAuthorizer().canEditDocumentOverview(document, user); } @Override public boolean canFyi(Document document, Person user) { return getRootDocumentAuthorizer().canFyi(document, user); } @Override public boolean canAcknowledge(Document document, Person user) { return getRootDocumentAuthorizer().canAcknowledge(document, user); } @Override public boolean canReceiveAdHoc(Document document, Person user, String actionRequestCode) { return getRootDocumentAuthorizer().canReceiveAdHoc(document, user, actionRequestCode); } @Override public boolean canAddNoteAttachment(Document document, String attachmentTypeCode, Person user) { return getRootDocumentAuthorizer().canAddNoteAttachment(document, attachmentTypeCode, user); } @Override public boolean canDeleteNoteAttachment(Document document, String attachmentTypeCode, String authorUniversalIdentifier, Person user) { return getRootDocumentAuthorizer().canDeleteNoteAttachment(document, attachmentTypeCode, authorUniversalIdentifier, user); } @Override public boolean canViewNoteAttachment(Document document, String attachmentTypeCode, String authorUniversalIdentifier, Person user) { return getRootDocumentAuthorizer().canViewNoteAttachment(document, attachmentTypeCode, authorUniversalIdentifier, user); } @Override public boolean canSendAdHocRequests(Document document, String actionRequestCd, Person user) { return getRootDocumentAuthorizer().canSendAdHocRequests(document, actionRequestCd, user); } @Override public boolean canSendAnyTypeAdHocRequests(Document document, Person user) { return getRootDocumentAuthorizer().canSendAnyTypeAdHocRequests(document, user); } @Override public boolean canTakeRequestedAction(Document document, String actionRequestCode, Person user) { return getRootDocumentAuthorizer().canTakeRequestedAction(document, actionRequestCode, user); } @Override public boolean canRecall(Document document, Person user) { return getRootDocumentAuthorizer().canRecall(document, user); } @Override public Set<String> getSecurePotentiallyReadOnlySectionIds() { return getRootDocumentAuthorizer().getSecurePotentiallyReadOnlySectionIds(); } @Override public Set<String> getDocumentActions(Document document, Person user, Set<String> documentActions) { return getRootDocumentAuthorizer().getDocumentActions(document, user, documentActions); } @Override public boolean canViewNoteAttachment(Document document, String attachmentTypeCode, Person user) { return getRootDocumentAuthorizer().canViewNoteAttachment(document, attachmentTypeCode, user); } /** * This is what actually uses the TemProfileAuthorizerAssistant to use as the logic we defer calls to * @return a document authorizer composed in, to defer to when we can */ protected TemProfileAuthorizerAssistant getRootDocumentAuthorizer() { try { if (rootDocumentAuthorizer == null) { rootDocumentAuthorizer = TemProfileAuthorizerAssistant.class.newInstance(); } } catch (InstantiationException ie) { throw new RuntimeException("Could not instantiate instance of "+FinancialSystemMaintenanceDocumentAuthorizerBase.class.getName(), ie); } catch (IllegalAccessException iae) { throw new RuntimeException("Access issues while instantiating instance of "+FinancialSystemMaintenanceDocumentAuthorizerBase.class.getName(), iae); } return rootDocumentAuthorizer; } }