/******************************************************************************* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *******************************************************************************/ package org.apache.ofbiz.content.content; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.StringUtil; import org.apache.ofbiz.base.util.UtilGenerics; import org.apache.ofbiz.base.util.UtilMisc; import org.apache.ofbiz.base.util.UtilProperties; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.entity.Delegator; import org.apache.ofbiz.entity.GenericEntityException; import org.apache.ofbiz.entity.GenericValue; import org.apache.ofbiz.entity.util.EntityQuery; import org.apache.ofbiz.entityext.permission.EntityPermissionChecker; import org.apache.ofbiz.security.Security; import org.apache.ofbiz.service.DispatchContext; import org.apache.ofbiz.service.GenericServiceException; import org.apache.ofbiz.service.LocalDispatcher; import org.apache.ofbiz.service.ModelService; import org.apache.ofbiz.service.ServiceUtil; /** * ContentPermissionServices Class * * Services for granting operation permissions on Content entities in a data-driven manner. */ public class ContentPermissionServices { public static final String module = ContentPermissionServices.class.getName(); public static final String resource = "ContentUiLabels"; public ContentPermissionServices() {} /** * checkContentPermission * *@param dctx The DispatchContext that this service is operating in *@param context Map containing the input parameters *@return Map with the result of the service, the output parameters * * This service goes thru a series of test to determine if the user has * authority to performed anyone of the passed in target operations. * * It expects a Content entity in "currentContent" * It expects a list of contentOperationIds in "targetOperationList" rather * than a scalar because it is thought that sometimes more than one operation * would fit the situation. * Similarly, it expects a list of contentPurposeTypeIds in "contentPurposeList". * Again, normally there will just be one, but it is possible that a Content * entity could have multiple purposes associated with it. * The userLogin GenericValue is also required. * A list of roleTypeIds is also possible. * * The basic sequence of testing events is: * First the ContentPurposeOperation table is checked to see if there are any * entries with matching purposes (and operations) with no roleTypeId (ie. _NA_). * This is done because it would be the most common scenario and is quick to check. * * Secondly, the CONTENTMGR permission is checked. * * Thirdly, the ContentPurposeOperation table is rechecked to see if there are * any conditions with roleTypeIds that match associated ContentRoles tied to the * user. * If a Party of "PARTY_GROUP" type is found, the PartyRelationship table is checked * to see if the current user is linked to that group. * * If no match is found to this point and the current Content entity has a value for * ownerContentId, then the last step is recusively applied, using the ContentRoles * associated with the ownerContent entity. */ public static Map<String, Object> checkContentPermission(DispatchContext dctx, Map<String, ? extends Object> context) { Debug.logWarning(new Exception(), "This service has been depricated in favor of [genericContentPermission]", module); Security security = dctx.getSecurity(); Delegator delegator = dctx.getDelegator(); //TODO this parameters is still not used but this service need to be replaced by genericContentPermission // String statusId = (String) context.get("statusId"); //TODO this parameters is still not used but this service need to be replaced by genericContentPermission // String privilegeEnumId = (String) context.get("privilegeEnumId"); GenericValue content = (GenericValue) context.get("currentContent"); Boolean bDisplayFailCond = (Boolean)context.get("displayFailCond"); boolean displayFailCond = false; if (bDisplayFailCond != null && bDisplayFailCond.booleanValue()) { displayFailCond = true; } Debug.logInfo("displayFailCond(0):" + displayFailCond, ""); Boolean bDisplayPassCond = (Boolean)context.get("displayPassCond"); boolean displayPassCond = false; if (bDisplayPassCond != null && bDisplayPassCond.booleanValue()) { displayPassCond = true; } Debug.logInfo("displayPassCond(0):" + displayPassCond, ""); Map<String, Object> results = new HashMap<String, Object>(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String partyId = (String) context.get("partyId"); if (UtilValidate.isEmpty(partyId)) { String passedUserLoginId = (String)context.get("userLoginId"); if (UtilValidate.isNotEmpty(passedUserLoginId)) { try { userLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", passedUserLoginId).cache().queryOne(); if (userLogin != null) { partyId = userLogin.getString("partyId"); } } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } } } if (UtilValidate.isEmpty(partyId) && userLogin != null) { partyId = userLogin.getString("partyId"); } // Do entity permission check. This will pass users with administrative permissions. boolean passed = false; // I realized, belatedly, that I wanted to be able to pass parameters in as // strings so this service could be used in an action event directly, // so I had to write this code to handle both list and strings List<String> passedPurposes = UtilGenerics.checkList(context.get("contentPurposeList")); String contentPurposeString = (String) context.get("contentPurposeString"); if (UtilValidate.isNotEmpty(contentPurposeString)) { List<String> purposesFromString = StringUtil.split(contentPurposeString, "|"); if (passedPurposes == null) { passedPurposes = new LinkedList<String>(); } passedPurposes.addAll(purposesFromString); } EntityPermissionChecker.StdAuxiliaryValueGetter auxGetter = new EntityPermissionChecker.StdAuxiliaryValueGetter("ContentPurpose", "contentPurposeTypeId", "contentId"); // Sometimes permissions need to be checked before an entity is created, so // there needs to be a method for setting a purpose list auxGetter.setList(passedPurposes); List<String> targetOperations = UtilGenerics.checkList(context.get("targetOperationList")); String targetOperationString = (String) context.get("targetOperationString"); if (UtilValidate.isNotEmpty(targetOperationString)) { List<String> operationsFromString = StringUtil.split(targetOperationString, "|"); if (targetOperations == null) { targetOperations = new LinkedList<String>(); } targetOperations.addAll(operationsFromString); } EntityPermissionChecker.StdPermissionConditionGetter permCondGetter = new EntityPermissionChecker.StdPermissionConditionGetter("ContentPurposeOperation", "contentOperationId", "roleTypeId", "statusId", "contentPurposeTypeId", "privilegeEnumId"); permCondGetter.setOperationList(targetOperations); EntityPermissionChecker.StdRelatedRoleGetter roleGetter = new EntityPermissionChecker.StdRelatedRoleGetter("Content", "roleTypeId", "contentId", "partyId", "ownerContentId", "ContentRole"); List<String> passedRoles = UtilGenerics.checkList(context.get("roleTypeList")); if (passedRoles == null) passedRoles = new LinkedList<String>(); String roleTypeString = (String) context.get("roleTypeString"); if (UtilValidate.isNotEmpty(roleTypeString)) { List<String> rolesFromString = StringUtil.split(roleTypeString, "|"); passedRoles.addAll(rolesFromString); } roleGetter.setList(passedRoles); String entityAction = (String) context.get("entityOperation"); if (entityAction == null) entityAction = "_ADMIN"; if (userLogin != null && entityAction != null) { passed = security.hasEntityPermission("CONTENTMGR", entityAction, userLogin); } StringBuilder errBuf = new StringBuilder(); String permissionStatus = null; List<Object> entityIds = new LinkedList<Object>(); if (passed) { results.put("permissionStatus", "granted"); permissionStatus = "granted"; if (displayPassCond) { errBuf.append("\n hasEntityPermission(" + entityAction + "): PASSED"); } } else { if (displayFailCond) { errBuf.append("\n hasEntityPermission(" + entityAction + "): FAILED"); } if (content != null) entityIds.add(content); String quickCheckContentId = (String) context.get("quickCheckContentId"); if (UtilValidate.isNotEmpty(quickCheckContentId)) { List<String> quickList = StringUtil.split(quickCheckContentId, "|"); if (UtilValidate.isNotEmpty(quickList)) entityIds.addAll(quickList); } try { boolean check = EntityPermissionChecker.checkPermissionMethod(delegator, partyId, "Content", entityIds, auxGetter, roleGetter, permCondGetter); if (check) { results.put("permissionStatus", "granted"); } else { results.put("permissionStatus", "rejected"); } } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } permissionStatus = (String)results.get("permissionStatus"); errBuf.append("\n permissionStatus:"); errBuf.append(permissionStatus); } if ((permissionStatus.equals("granted") && displayPassCond) || (permissionStatus.equals("rejected") && displayFailCond)) { // Don't show this if passed on 'hasEntityPermission' if (displayFailCond || displayPassCond) { if (!passed) { errBuf.append("\n targetOperations:"); errBuf.append(targetOperations); String errMsg = permCondGetter.dumpAsText(); errBuf.append("\n"); errBuf.append(errMsg); errBuf.append("\n partyId:"); errBuf.append(partyId); errBuf.append("\n entityIds:"); errBuf.append(entityIds); if (auxGetter != null) { errBuf.append("\n auxList:"); errBuf.append(auxGetter.getList()); } if (roleGetter != null) { errBuf.append("\n roleList:"); errBuf.append(roleGetter.getList()); } } } } Debug.logInfo("displayPass/FailCond(0), errBuf:" + errBuf.toString(), ""); results.put(ModelService.ERROR_MESSAGE, errBuf.toString()); return results; } public static Map<String, Object> checkAssocPermission(DispatchContext dctx, Map<String, ? extends Object> context) { Map<String, Object> results = new HashMap<String, Object>(); // Security security = dctx.getSecurity(); Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); Boolean bDisplayFailCond = (Boolean)context.get("displayFailCond"); String contentIdFrom = (String) context.get("contentIdFrom"); String contentIdTo = (String) context.get("contentIdTo"); GenericValue userLogin = (GenericValue) context.get("userLogin"); String entityAction = (String) context.get("entityOperation"); Locale locale = (Locale) context.get("locale"); if (entityAction == null) entityAction = "_ADMIN"; String permissionStatus = null; GenericValue contentTo = null; GenericValue contentFrom = null; try { contentTo = EntityQuery.use(delegator).from("Content").where("contentId", contentIdTo).cache().queryOne(); contentFrom = EntityQuery.use(delegator).from("Content").where("contentId", contentIdFrom).cache().queryOne(); } catch (GenericEntityException e) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ContentContentToOrFromErrorRetriving", locale)); } if (contentTo == null || contentFrom == null) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ContentContentToOrFromIsNull", UtilMisc.toMap("contentTo", contentTo, "contentFrom", contentFrom), locale)); } Map<String, Object> permResults = new HashMap<String, Object>(); // Use the purposes from the from entity for both cases. List<String> relatedPurposes = EntityPermissionChecker.getRelatedPurposes(contentFrom, null); List<String> relatedPurposesTo = EntityPermissionChecker.getRelatedPurposes(contentTo, relatedPurposes); Map<String, Object> serviceInMap = new HashMap<String, Object>(); serviceInMap.put("userLogin", userLogin); serviceInMap.put("targetOperationList", UtilMisc.toList("CONTENT_LINK_TO")); serviceInMap.put("contentPurposeList", relatedPurposesTo); serviceInMap.put("currentContent", contentTo); serviceInMap.put("displayFailCond", bDisplayFailCond); try { permResults = dispatcher.runSync("checkContentPermission", serviceInMap); } catch (GenericServiceException e) { Debug.logError(e, "Problem checking permissions", "ContentServices"); } permissionStatus = (String)permResults.get("permissionStatus"); if (permissionStatus == null || !permissionStatus.equals("granted")) { if (bDisplayFailCond != null && bDisplayFailCond.booleanValue()) { String errMsg = (String)permResults.get(ModelService.ERROR_MESSAGE); results.put(ModelService.ERROR_MESSAGE, errMsg); } return results; } serviceInMap.put("currentContent", contentFrom); serviceInMap.put("targetOperationList", UtilMisc.toList("CONTENT_LINK_FROM")); serviceInMap.put("contentPurposeList", relatedPurposes); try { permResults = dispatcher.runSync("checkContentPermission", serviceInMap); } catch (GenericServiceException e) { Debug.logError(e, "Problem checking permissions", "ContentServices"); } permissionStatus = (String)permResults.get("permissionStatus"); if (permissionStatus != null && permissionStatus.equals("granted")) { results.put("permissionStatus", "granted"); } else { if (bDisplayFailCond != null && bDisplayFailCond.booleanValue()) { String errMsg = (String)permResults.get(ModelService.ERROR_MESSAGE); results.put(ModelService.ERROR_MESSAGE, errMsg); } } return results; } }