blob: 7cef95f0ca3dea5c52dfce8745c053c5a35f398c [file] [log] [blame]
/*******************************************************************************
* 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;
}
}