This is an automated email from the ASF dual-hosted git repository. nmalin pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push: new 5b1552c Improved: Convert ContentPermissionServices.xml mini lang to groovy (OFBIZ-11446) 5b1552c is described below commit 5b1552cfefd7ce318505bb081d1ce69ed9817ba9 Author: Wiebke Pätzold <wiebke.paetz...@ecomify.de> AuthorDate: Fri Jun 26 16:19:52 2020 +0200 Improved: Convert ContentPermissionServices.xml mini lang to groovy (OFBIZ-11446) Also change the reference in DataResourcePermissionServices.xml for checkOwnership --- .../permission/ContentPermissionServices.groovy | 590 +++++++++++++++ .../permission/ContentPermissionServices.xml | 821 --------------------- .../permission/DataResourcePermissionServices.xml | 3 +- applications/content/servicedef/services.xml | 21 +- 4 files changed, 607 insertions(+), 828 deletions(-) diff --git a/applications/content/groovyScripts/permission/ContentPermissionServices.groovy b/applications/content/groovyScripts/permission/ContentPermissionServices.groovy new file mode 100644 index 0000000..2d6376b --- /dev/null +++ b/applications/content/groovyScripts/permission/ContentPermissionServices.groovy @@ -0,0 +1,590 @@ +/* + * 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. + */ + +import org.apache.ofbiz.base.util.UtilProperties +import org.apache.ofbiz.entity.GenericValue + +/** + * Check user has Content Manager permission + * @return + */ +def contentManagerPermission() { + Map result = success() + parameters.primaryPermission = "CONTENTMGR" + Map resultService = run service: "genericBasePermissionCheck", with: parameters + result.hasPermission = resultService.hasPermission + return result +} + +/** + * Check user has Content Manager permission + * @return + */ +def contentManagerRolePermission() { + Map result = success() + parameters.primaryPermission = "CONTENTMGR" + parameters.altPermission = "CONTENTMGR_ROLE" + Map resultService = run service: "genericBasePermissionCheck", with: parameters + result.hasPermission = resultService.hasPermission + return result +} + +/** + * Generic service for Content Permissions + * @return + */ +def genericContentPermission() { + String statusId = parameters.statusId + String contentPurposeTypeId = parameters.contentPurposeTypeId + String contentId = parameters.contentId + String ownerContentId = parameters.ownerContentId + String contentOperationId = parameters.contentOperationId + String mainAction = parameters.mainAction + parameters.primaryPermission = "CONTENTMGR" + Map resultService = run service: "genericBasePermissionCheck", with: parameters + Boolean hasPermission = resultService.hasPermission + + // setting the roleEntity or this service + String roleEntityField = "contentId" + String roleEntity = "ContentRole" + // here we can use contentIdTo to check parent(s) ownership + if (!parameters.ownerContentId && parameters.contentIdFrom) { + ownerContentId = parameters.contentIdFrom + } + + // mainAction based call outs + if (!hasPermission) { + switch (parameters.mainAction) { + case "VIEW": + Map serviceVCP = viewContentPermission(hasPermission, contentId, contentOperationId, + contentPurposeTypeId, roleEntity, roleEntityField) + hasPermission = serviceVCP.hasPermission ?: false + break + case "CREATE": + contentOperationId = parameters.contentOperationId ?: "CONTENT_CREATE" + Map serviceCCP = createContentPermission(hasPermission, ownerContentId, contentOperationId, + statusId, contentPurposeTypeId, roleEntity, roleEntityField) + hasPermission = serviceCCP.hasPermission ?: false + break + case "UPDATE": + contentOperationId = parameters.contentOperationId ?: "CONTENT_UPDATE" + Map serviceUCP = updateContentPermission(hasPermission, contentId, ownerContentId, + contentOperationId, contentPurposeTypeId, roleEntity, roleEntityField) + hasPermission = serviceUCP.hasPermission ?: false + } // all other actions use main base check + } else { + logInfo("Admin permission found: ${parameters.primaryPermission}_${mainAction}") + } + logInfo("Permission service [${mainAction} / ${parameters.contentId}] completed; returning hasPermission = ${hasPermission}") + + return success(hasPermission: hasPermission) +} + + +/** + * Check user can view content + * @param hasPermission + * @param contentId + * @param contentOperationId + * @param contentPurposeTypeId + * @param roleEntity + * @param roleEntityField + * @return + */ +def viewContentPermission(Boolean hasPermission, String contentId, String contentOperationId, + String contentPurposeTypeId, String roleEntity, + String roleEntityField) { + + // if called directly check the main permission + if (!hasPermission) { + parameters.primaryPermission = "CONTENTMGR" + parameters.mainAction = "VIEW" + Map serviceResult = run service: "genericBasePermissionCheck", with: parameters + hasPermission = serviceResult.hasPermission + } + + // check content role permission + parameters.primaryPermission = "CONTENTMGR_ROLE" + Map serviceGBPC = run service: "genericBasePermissionCheck", with: parameters + hasPermission = serviceGBPC.hasPermission + + // must have the security permission to continue + if (hasPermission) { + // if no operation is passed; we use the CONTENT_VIEW operation + parameters.contentOperationId = parameters.contentOperationId ?: "CONTENT_VIEW" + + // contentId is required for update checking + contentId = contentId ?: parameters.contentId + if (!contentId) { + return error(UtilProperties.getMessage('ContentUiLabels', 'ContentViewPermissionError')) + } + + //check the operation security + contentOperationId = parameters.contentOperationId + String checkId = contentId + Map serviceCCOS = checkContentOperationSecurity(contentOperationId, contentPurposeTypeId, checkId, roleEntity, roleEntityField) + hasPermission = serviceCCOS.hasPermission + } + return success(hasPermission: hasPermission) +} + +/** + * Check user can create new content + * @param hasPermission + * @param ownerContentId + * @param contentOperationId + * @param statusId + * @param contentPurposeTypeId + * @param roleEntity + * @param roleEntityField + * @return + */ +def createContentPermission(Boolean hasPermission, String ownerContentId, String contentOperationId, + String statusId, String contentPurposeTypeId, + String roleEntity, String roleEntityField) { + + parameters.roleEntity = roleEntity + parameters.roleEntityField = roleEntityField + String checkId + + // if called directly check the main permission + if (!hasPermission) { + parameters.primaryPermission = "CONTENTMGR" + parameters.mainAction = "CREATE" + Map serviceResult = run service: "genericBasePermissionCheck", with: parameters + hasPermission = serviceResult.hasPermission + } + + // ownerContentId can be set from a calling method + ownerContentId = ownerContentId ?: parameters.ownerContentId + + // operation ID can be set from the calling method + contentOperationId = contentOperationId ?: parameters.contentOperationId + + // statusId can be set from the calling method + statusId = statusId ?: parameters.statusId + + // check role permission? + parameters.primaryPermission = "CONTENTMGR_ROLE" + Map serviceResultGBPC = run service: "genericBasePermissionCheck", with: parameters + hasPermission = serviceResultGBPC.hasPermission + + // must have the security permission to continue + if (hasPermission) { + logVerbose("Found necessary ROLE permission: ${parameters.primaryPermission}_${mainAction} :: ${contentOperationId}") + + // if an operation is passed, check the operation security + if (contentOperationId) { + checkId = ownerContentId + Map serviceResultCCOS = checkContentOperationSecurity(contentOperationId, contentPurposeTypeId, checkId, roleEntity, roleEntityField) + hasPermission = serviceResultCCOS.hasPermission + } + + // check if there was no operation; or if the operation check failed, we are okay to create unless we are creating against a parent; + // check parent ownership + if (!contentOperationId || hasPermission == false) { + if (ownerContentId) { + logVerbose("No operation found; but ownerContentId [${ownerContentId}] was; checking ownership") + checkId = ownerContentId + logVerbose("Checking Parent Ownership [${checkId}]") + parameters.checkId = checkId + Map serviceResultCO = run service: "checkOwnership", with: parameters + hasPermission = serviceResultCO.hasPermission ?: false + + if (!hasPermission) { + // no permission on this parent; check the parent's parent(s) + while (!hasPermission && checkId) { + // iterate until either we have permission or there are no more parents + GenericValue currentContent = from("Content").where(contentId: checkId).queryOne() + if (currentContent?.ownerContentId) { + checkId = currentContent.ownerContentId + logVerbose("Checking Parent(s) Ownership [${checkId}]") + parameters.checkId = checkId + Map serviceCO = run service: "checkOwnership", with: parameters + hasPermission = serviceCO.hasPermission ?: false + } else { + // no parent record found; time to stop recursion + checkId = null + } + } + } else { + logVerbose("Permission set to TRUE; granting access") + } + } + } + } + return success(hasPermission: hasPermission) +} + +/** + * Check user can update existing content + * @param hasPermission + * @param contentId + * @param ownerContentId + * @param contentOperationId + * @param contentPurposeTypeId + * @param roleEntity + * @param roleEntityField + * @return + */ +def updateContentPermission(Boolean hasPermission, String contentId, String ownerContentId, + String contentOperationId, String contentPurposeTypeId, + String roleEntity, String roleEntityField) { + String checkId + + // if called directly check the main permission + if (!hasPermission) { + parameters.primaryPermission = "CONTENTMGR" + parameters.mainAction = "UPDATE" + parameters.roleEntity = roleEntity + parameters.roleEntityField = roleEntityField + Map serviceResult = run service: "genericBasePermissionCheck", with: parameters + hasPermission = serviceResult.hasPermission + } + // contentId is required for update checking + contentId = contentId ?: parameters.contentId + if (!contentId) { + return error(label('ContentUiLabels', 'ContentSecurityUpdatePermission')) + } + + // ownerContentId can be set from a calling method + ownerContentId = ownerContentId ?: parameters.ownerContentId + + // operation ID can be set from the calling method + contentOperationId = contentOperationId ?: parameters.contentOperationId + + // check role permission + parameters.primaryPermission = "CONTENTMGR_ROLE" + Map resultService = run service: "genericBasePermissionCheck", with: parameters + hasPermission = resultService.hasPermission ?: false + + + // must have permission to continue + if (hasPermission) { + logVerbose("Found necessary ROLE permission: ${parameters.primaryPermission}_${mainAction}") + + // obtain the current content record + GenericValue thisContent = from("Content").where(contentId: contentId).cache().queryOne() + if (!thisContent) { + return error(label("ContentUiLabels", "ContentNoContentFound")) + } + + // check the operation + if (contentOperationId) { + logVerbose("Checking content operation for UPDATE: ${contentOperationId}") + checkId = contentId + Map serviceCCOS = checkContentOperationSecurity(contentOperationId, contentPurposeTypeId, checkId, roleEntity, roleEntityField) + hasPermission = serviceCCOS.hasPermission ?: false + } + + // check if there was no operation; or if the operation check failed + if (!contentOperationId || !hasPermission) { + // if no valid operation is passed; check ownership for permission + logVerbose("No valid operation for UPDATE; checking ownership instead!") + checkId = contentId + parameters.checkId = checkId + Map serviceCO = run service: "checkOwnership", with: parameters + hasPermission = serviceCO.hasPermission ?: false + + // we are okay to update; unless we are updating the owner content; verify ownership there + if (ownerContentId && thisContent.ownerContentId != ownerContentId) { + logVerbose("Updating content ownership; need to verify permision on parent(s)") + checkId = ownerContentId + parameters.checkId = checkId + Map serviceResultCO = run service: "checkOwnership", with: parameters + hasPermission = serviceResultCO.hasPermission ?: false + } + if (!hasPermission) { + // no permission on this parent; check the parent's parent(s) + while (!hasPermission && checkId) { + // iterate until either we have permission or there are no more parents + GenericValue currentContent = from("Content").where(contentId: checkId).cache().queryOne() + if (currentContent?.ownerContentId) { + checkId = currentContent.ownerContentId + parameters.checkId = checkId + Map serviceResCO = run service: "checkOwnership", with: parameters + hasPermission = serviceResCO.hasPermission ?: false + } else { + // no parent record found; time to stop recursion + checkId = null + } + } + } + } + } + return success(hasPermission: hasPermission) +} + +/** + * method to check operation security + * @param contentOperationId + * @param contentPurposeTypeId + * @param checkId + * @param roleEntity + * @param roleEntityField + * @return + */ +def checkContentOperationSecurity(String contentOperationId, String contentPurposeTypeId, String checkId, + String roleEntity, String roleEntityField) { + + roleEntityField = parameters.roleEntityField + roleEntity = parameters.roleEntity + List operations = [] + // resetting the permission flag + Boolean hasPermission = false + if (!contentOperationId) { + return error(label('ContentUiLabels', 'ContentRequiredField', [requiredField: contentOperationId])) + } + + contentPurposeTypeId = contentPurposeTypeId ?: parameters.contentPurposeTypeId + contentPurposeTypeId = contentPurposeTypeId ?: "_NA_" + + GenericValue checkContent = from("Content").where(contentId: checkId).cache().queryOne() + String statusId = checkContent?.statusId + + // If operation is CONTENT_CREATE and contentPurposeTypeId exists in parameters than obtain operations + // for that contentPurposeTypeId, else get the operations for checkContent + if (contentOperationId == "CONTENT_CREATE" && contentPurposeTypeId) { + // find defined purpose/operation mappings + operations = from("ContentPurposeOperation") + .where(contentPurposeTypeId: contentPurposeTypeId, contentOperationId: contentOperationId) + .cache() + .queryList() + } else { + // get all purposes for checkContent + List contentPurposes = findAllContentPurposes(checkId) + + // check the _NA_ purpose but only if no other purposes were found + if (contentPurposes) { + // find defined purpose/operation mappings + for (GenericValue currentPurpose : contentPurposes) { + List currentOperations = from("ContentPurposeOperation") + .where(contentPurposeTypeId: currentPurpose.contentPurposeTypeId, contentOperationId: contentOperationId) + .orderBy("contentPurposeTypeId") + .cache() + .queryList() + operations << currentOperations + } + } else { + operations = from("ContentPurposeOperation") + .where(contentPurposeTypeId: "_NA_", contentOperationId: contentOperationId) + .orderBy("contentPurposeTypeId") + .cache() + .queryList() + } + } + + // place holder for the content ID + String toCheckContentId = checkId + logVerbose("[${checkId}] Found Operations [${contentPurposeTypeId}/${contentOperationId}] :: ${operations}") + + if (!operations) { + // there are no ContentPurposeOperation entries for this operation/purpose; default is approve permission + logVerbose("No operations found; permission granted!") + hasPermission = true + } else { + // there are requirements to test + // get all possible partyIds for this user (including group memberships) + List partyIdList = findAllAssociatedPartyIds() + + // check each operation security + for (GenericValue operation : operations) { + if (!hasPermission) { + // reset the checkId if needed + if (!checkId && toCheckContentId) { + checkId = toCheckContentId + } + logVerbose("Testing [${checkId}] [${statusId}] OPERATION: ${operation}") + + // check statusId + if (operation.statusId == "_NA_" || (statusId && (operation.statusId == statusId))) { + logVerbose("Passed status check; now checking role(s)") + + // first check passed; now we test for the role membership(s) + for (String thisPartyId : partyIdList) { + if (!hasPermission) { + String checkRoleTypeId = operation.roleTypeId + String checkPartyId = thisPartyId + // reset the checkId if needed + if (!checkId && toCheckContentId) { + checkId = toCheckContentId + } + Map serviceCRS = checkRoleSecurity(roleEntity, roleEntityField, checkId, checkPartyId, checkRoleTypeId) + hasPermission = serviceCRS.hasPermission ?: false + + // check the parent(s) for permission + if (!hasPermission && checkId) { + logVerbose("Starting loop; checking operation: ${operation.contentOperationId}") + // iterate until either we have permission or there are no more parents + while (!hasPermission && checkId) { + GenericValue currentContent = from("Content").where(contentId: checkId).queryOne() + if (currentContent?.ownerContentId) { + checkId = currentContent.ownerContentId + Map serviceResultCRS = checkRoleSecurity(roleEntity, roleEntityField, checkId, checkPartyId, checkRoleTypeId) + hasPermission = serviceResultCRS.hasPermission ?: false + } else { + // no parent record found; time to stop recursion + checkId = null + } + } + } + } + } + } + } + } + } + return success(hasPermission: hasPermission) +} + +// method to check content ownership +/** + * Checks the (role) ownership of a record + * @return + */ +def checkOwnership() { + Map result = success() + String roleEntity = parameters.roleEntity + String roleEntityField = parameters.roleEntityField + String checkId = parameters.checkId + String checkPartyId + // resetting the permission flag + Boolean hasPermission = false + + if (!checkId) { + return error(label("ContentUiLabels", "ContentRequiredField", [requiredField: "checkId"])) + } + + // get all the associated parties (this user + all group memberships) + List partyIdList = findAllAssociatedPartyIds() + + // check to see if any of the parties are owner of the content + for (String thisPartyId : partyIdList) { + if (!hasPermission) { + logVerbose("Checking to see if party [${thisPartyId}] has ownership of ${checkId} :: ${hasPermission}") + checkPartyId = thisPartyId + Map serviceResult = checkRoleSecurity(roleEntity, roleEntityField, checkId, checkPartyId, "OWNER") + if (serviceResult.errorMessage != null) { + logError(serviceResult.errorMessage) + } else { + hasPermission = serviceResult.hasPermission + } + } else { + logVerbose("Field hasPermission is TRUE [${hasPermission}] did not test!") + } + } + return success(hasPermission: hasPermission) +} + +// method the check Content Role associations +/** + * Check users role associations with Content + * @param roleEntity + * @param roleEntityField + * @param checkId + * @param checkPartyId + * @param checkRoleTypeId + * @return + */ +def checkRoleSecurity(String roleEntity, String roleEntityField, String checkId, String checkPartyId, String checkRoleTypeId) { + Boolean hasPermission + List foundRoles + logVerbose("checkRoleSecurity: just reset hasPermission value to false!") + + List missingFields = [] + + if (!roleEntity) missingFields << "roleEntity" // roleEntity is required to determine which content role table to look: ContentRole, DataResourceRole, etc + if (!roleEntityField) missingFields << "roleEntityField" // roleEntityField is required to determine the pk field to check; contentId, dataResourceId, etc + if (!checkId) missingFields << "checkId" // setting the env field contentId is required for this simple method + if (!checkPartyId) missingFields << "checkPartyId" + if (missingFields) { + return error(label('ContentUiLabels', 'ContentRequiredField', [requiredField: missingFields])) + } + logVerbose("About to test of checkRoleTypeId is empty... ${checkRoleTypeId}") + + if (checkRoleTypeId && checkRoleTypeId == "_NA_") { + // _NA_ role means anyone (logged in) has permission + hasPermission = true + } else { + // not _NA_ so do the actual role check + if (checkRoleTypeId) { + logVerbose("Doing lookup [${roleEntity}] with roleTypeId : ${checkRoleTypeId}") + // looking up a specific role + hasPermission = from("${roleEntity}") + .where(["${roleEntityField}": checkId, + roleTypeId : checkRoleTypeId, + partyId : checkPartyId]) + .queryCount() > 0 + } else { + logVerbose("Doing lookup without roleTypeId") + // looking up any role + hasPermission = from("${roleEntity}") + .where(["${roleEntityField}": checkId, + partyId : checkPartyId]) + .queryCount() > 0 + + } + logVerbose("Checking for ContentRole: [party] - ${checkPartyId} [role] - ${checkRoleTypeId} [content] - ${checkId} :: ${foundRoles}") + } + return success(hasPermission: hasPermission) +} + +/** + * Find all content purposes for the specified content + * @param checkId + * @return + */ +def findAllContentPurposes(String checkId) { + if (!checkId) { + return error(label('ContentUiLabels', 'ContentRequiredField', [requiredField: "checkId"])) + } + return from("ContentPurpose") + .where(contentId: checkId) + .cache() + .queryList() +} + +/** + * Finds all associated party Ids for a use + * @return + */ +def findAllAssociatedPartyIds () { + Map serviceResult = run service: "getRelatedParties", with: [partyIdFrom : userLogin.partyId, + partyRelationshipTypeId: "GROUP_ROLLUP", + includeFromToSwitched : "Y"] + List partyIdList = serviceResult.relatedPartyIdList + + logVerbose("Got list of associated parties: ${partyIdList}") + return partyIdList +} + +/** + * Finds all associated parent content + * @return + */ +def findAllParentContent(String contentId) { + if (!contentId) { + return error(label('ContentUiLabels', 'ContentRequiredField', [requiredField: "contentId"])) + } + return success(contentAssocList: from("ContentAssoc") + .where(contentIdTo: contentId) + .filterByDate() + .cache() + .queryList()) +} diff --git a/applications/content/minilang/permission/ContentPermissionServices.xml b/applications/content/minilang/permission/ContentPermissionServices.xml deleted file mode 100644 index f06ebda..0000000 --- a/applications/content/minilang/permission/ContentPermissionServices.xml +++ /dev/null @@ -1,821 +0,0 @@ -<!-- - 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. - --> - -<simple-methods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns="http://ofbiz.apache.org/Simple-Method" xsi:schemaLocation="http://ofbiz.apache.org/Simple-Method http://ofbiz.apache.org/dtds/simple-methods.xsd"> - - <simple-method method-name="contentManagerPermission" short-description="Check user has Content Manager permission"> - <set field="primaryPermission" value="CONTENTMGR"/> - <call-simple-method method-name="genericBasePermissionCheck" xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - </simple-method> - <simple-method method-name="contentManagerRolePermission" short-description="Check user has Content Manager permission"> - <set field="primaryPermission" value="CONTENTMGR"/> - <set field="altPermission" value="CONTENTMGR_ROLE"/> - <call-simple-method method-name="genericBasePermissionCheck" xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - </simple-method> - - <simple-method method-name="genericContentPermission" short-description="Generic Service for Content Permissions"> - <set field="primaryPermission" value="CONTENTMGR"/> - <call-simple-method method-name="genericBasePermissionCheck" xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - - <!-- setting the roleEntity or this service --> - <set field="roleEntityField" value="contentId"/> - <set field="roleEntity" value="ContentRole"/> - <!-- here we can use contentIdTo to check parent(s) ownership --> - <if> - <condition> - <and> - <if-empty field="parameters.ownerContentId"/> - <not> - <if-empty field="parameters.contentIdFrom"/> - </not> - </and> - </condition> - <then> - <set field="ownerContentId" from-field="parameters.contentIdFrom"/> - </then> - </if> - - <!-- mainAction based call outs --> - <if> - <condition> - <not> - <if-compare field="hasPermission" value="true" type="Boolean" operator="equals"/> - </not> - </condition> - <then> - <if> - <!-- view content --> - <condition> - <if-compare field="parameters.mainAction" value="VIEW" operator="equals"/> - </condition> - <then> - <call-simple-method method-name="viewContentPermission"/> - </then> - <else-if> - <!-- create content --> - <condition> - <if-compare field="parameters.mainAction" value="CREATE" operator="equals"/> - </condition> - <then> - <!-- setup default operation --> - <if-empty field="parameters.contentOperationId"> - <set field="contentOperationId" value="CONTENT_CREATE"/> - </if-empty> - <call-simple-method method-name="createContentPermission"/> - </then> - </else-if> - <else-if> - <!-- update content --> - <condition> - <if-compare field="parameters.mainAction" value="UPDATE" operator="equals"/> - </condition> - <then> - <!-- setup default operation --> - <if-empty field="parameters.contentOperationId"> - <set field="contentOperationId" value="CONTENT_UPDATE"/> - </if-empty> - <call-simple-method method-name="updateContentPermission"/> - </then> - </else-if> - <!-- all other actions use main base check --> - </if> - </then> - <else> - <log level="info" message="Admin permission found: ${primaryPermission}_${mainAction}"/> - </else> - </if> - - <log level="info" message="Permission service [${mainAction} / ${parameters.contentId}] completed; returning hasPermission = ${hasPermission}"/> - <field-to-result field="hasPermission"/> - </simple-method> - - <simple-method method-name="viewContentPermission" short-description="Check user can view content"> - <!-- if called directly check the main permission --> - <if-empty field="hasPermission"> - <set field="primaryPermission" value="CONTENTMGR"/> - <set field="mainAction" value="VIEW"/> - <call-simple-method method-name="genericBasePermissionCheck" - xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - </if-empty> - - <!-- check content role permission --> - <set field="primaryPermission" value="CONTENTMGR_ROLE"/> - <call-simple-method method-name="genericBasePermissionCheck" - xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - - <!-- must have the security permission to continue --> - <if> - <condition> - <if-compare field="hasPermission" value="true" type="Boolean" operator="equals"/> - </condition> - <then> - <!-- if no operation is passed; we use the CONTENT_VIEW operation --> - <if-empty field="parameters.contentOperationId"> - <set field="parameters.contentOperationId" value="CONTENT_VIEW"/> - </if-empty> - - <!-- contentId is required for update checking --> - <if-empty field="contentId"> - <set field="contentId" from-field="parameters.contentId"/> - </if-empty> - <if-empty field="contentId"> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentViewPermissionError"/> - </add-error> - </if-empty> - <check-errors/> - - <!-- grab the current requested content record --> - <entity-one entity-name="Content" value-field="content"> - <field-map field-name="contentId" from-field="contentId"/> - </entity-one> - - <!-- check the operation security --> - <set field="contentOperationId" from-field="parameters.contentOperationId"/> - <set field="content" from-field="content"/> - <set field="checkId" from-field="contentId"/> - <call-simple-method method-name="checkContentOperationSecurity"/> - </then> - </if> - </simple-method> - - <simple-method method-name="createContentPermission" short-description="Check user can create new content"> - <!-- if called directly check the main permission --> - <if-empty field="hasPermission"> - <set field="primaryPermission" value="CONTENTMGR"/> - <set field="mainAction" value="CREATE"/> - <call-simple-method method-name="genericBasePermissionCheck" - xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - </if-empty> - - <!-- ownerContentId can be set from a calling method --> - <if-empty field="ownerContentId"> - <set field="ownerContentId" from-field="parameters.ownerContentId"/> - </if-empty> - - <!-- operation ID can be set from the calling method --> - <if-empty field="contentOperationId"> - <set field="contentOperationId" from-field="parameters.contentOperationId"/> - </if-empty> - - <!-- statusId can be set from the calling method --> - <if-empty field="statusId"> - <set field="statusId" from-field="parameters.statusId"/> - </if-empty> - - <!-- check role permission? --> - <set field="primaryPermission" value="CONTENTMGR_ROLE"/> - <call-simple-method method-name="genericBasePermissionCheck" - xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - - <!-- must have the security permission to continue --> - <if> - <condition> - <if-compare field="hasPermission" value="true" type="Boolean" operator="equals"/> - </condition> - <then> - <log level="verbose" message="Found necessary ROLE permission: ${primaryPermission}_${mainAction} :: ${contentOperationId}"/> - - <!-- if an operation is passed, check the operation security --> - <if> - <condition> - <not> - <if-empty field="contentOperationId"/> - </not> - </condition> - <then> - <set field="checkId" from-field="ownerContentId"/> - <call-simple-method method-name="checkContentOperationSecurity"/> - </then> - </if> - - <!-- check if there was no operation; or if the operation check failed, we are okay to create unless we are creating against a parent; check parent ownership --> - <if> - <condition> - <or> - <if-empty field="contentOperationId"/> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - </or> - </condition> - <then> - <if> - <condition> - <not> - <if-empty field="ownerContentId"/> - </not> - </condition> - <then> - <log level="verbose" message="No operation found; but ownerContentId [${ownerContentId}] was; checking ownership"/> - <set field="checkId" from-field="ownerContentId"/> - <log level="verbose" message="Checking Parent Ownership [${checkId}]"/> - <call-simple-method method-name="checkOwnership"/> - <if> - <condition> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - </condition> - <then> - <!-- no permission on this parent; check the parent's parent(s) --> - <while> - <condition> - <!-- iterate until either we have permission or there are no more parents --> - <and> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - <not> - <if-empty field="checkId"/> - </not> - </and> - </condition> - <then> - <entity-one entity-name="Content" value-field="currentContent"> - <field-map field-name="contentId" from-field="checkId"/> - </entity-one> - <if> - <condition> - <not> - <if-empty field="currentContent.ownerContentId"/> - </not> - </condition> - <then> - <set field="checkId" from-field="currentContent.ownerContentId"/> - <log level="verbose" message="Checking Parent(s) Ownership [${checkId}]"/> - <call-simple-method method-name="checkOwnership"/> - </then> - - <!-- no parent record found; time to stop recursion --> - <else> - <clear-field field="checkId"/> - </else> - </if> - </then> - </while> - </then> - <else> - <log level="verbose" message="Permission set to TRUE; granting access"/> - </else> - </if> - </then> - </if> - </then> - </if> - </then> - </if> - </simple-method> - - <simple-method method-name="updateContentPermission" short-description="Check user can update existing content"> - <!-- if called directly check the main permission --> - <if-empty field="hasPermission"> - <set field="primaryPermission" value="CONTENTMGR"/> - <set field="mainAction" value="UPDATE"/> - <call-simple-method method-name="genericBasePermissionCheck" - xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - </if-empty> - - <!-- contentId is required for update checking --> - <if-empty field="contentId"> - <set field="contentId" from-field="parameters.contentId"/> - </if-empty> - <if-empty field="contentId"> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentSecurityUpdatePermission"/> - </add-error> - </if-empty> - <check-errors/> - - <!-- ownerContentId can be set from a calling method --> - <if-empty field="ownerContentId"> - <set field="ownerContentId" from-field="parameters.ownerContentId"/> - </if-empty> - - <!-- operation ID can be set from the calling method --> - <if-empty field="contentOperationId"> - <set field="contentOperationId" from-field="parameters.contentOperationId"/> - </if-empty> - - <!-- check role permission --> - <set field="primaryPermission" value="CONTENTMGR_ROLE"/> - <call-simple-method method-name="genericBasePermissionCheck" - xml-resource="component://common/minilang/permission/CommonPermissionServices.xml"/> - - <!-- must have permission to continue --> - <if> - <condition> - <if-compare field="hasPermission" value="true" type="Boolean" operator="equals"/> - </condition> - <then> - <log level="verbose" message="Found necessary ROLE permission: ${primaryPermission}_${mainAction}"/> - - <!-- obtain the current content record --> - <entity-one entity-name="Content" value-field="thisContent"> - <field-map field-name="contentId"/> - </entity-one> - <if-empty field="thisContent"> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentNoContentFound"/> - </add-error> - <check-errors/> - </if-empty> - - <!-- check the operation --> - <if> - <condition> - <not> - <if-empty field="contentOperationId"/> - </not> - </condition> - <then> - <log level="verbose" message="Checking content operation for UPDATE: ${contentOperationId}"/> - <set field="checkId" from-field="contentId"/> - <call-simple-method method-name="checkContentOperationSecurity"/> - </then> - </if> - - <!-- check if there was no operation; or if the operation check failed --> - <if> - <condition> - <or> - <if-empty field="contentOperationId"/> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - </or> - </condition> - - <!-- if no valid operation is passed; check ownership for permission --> - <then> - <log level="verbose" message="No valid operation for UPDATE; checking ownership instead!"/> - <set field="checkId" from-field="contentId"/> - <call-simple-method method-name="checkOwnership"/> - - <!-- we are okay to update; unless we are updating the owner content; verify ownership there --> - <if> - <condition> - <and> - <not> - <if-empty field="ownerContentId"/> - </not> - <if-compare-field field="thisContent.ownerContentId" to-field="ownerContentId" operator="not-equals"/> - </and> - </condition> - <then> - <log level="verbose" message="Updating content ownership; need to verify permision on parent(s)"/> - <set field="checkId" from-field="ownerContentId"/> - <call-simple-method method-name="checkOwnership"/> - <if> - <condition> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - </condition> - <then> - <!-- no permission on this parent; check the parent's parent(s) --> - <while> - <condition> - <!-- iterate until either we have permission or there are no more parents --> - <and> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - <not> - <if-empty field="checkId"/> - </not> - </and> - </condition> - <then> - <entity-one entity-name="Content" value-field="currentContent"> - <field-map field-name="contentId" from-field="checkId"/> - </entity-one> - <if> - <condition> - <not> - <if-empty field="currentContent.ownerContentId"/> - </not> - </condition> - <then> - <set field="checkId" from-field="currentContent.ownerContentId"/> - <call-simple-method method-name="checkOwnership"/> - </then> - - <!-- no parent record found; time to stop recursion --> - <else> - <clear-field field="checkId"/> - </else> - </if> - </then> - </while> - </then> - </if> - </then> - </if> - </then> - </if> - </then> - </if> - </simple-method> - - - <!-- method to check operation security --> - <simple-method method-name="checkContentOperationSecurity" short-description="Checks for Operation defined security"> - <!-- resetting the permission flag --> - <set field="hasPermission" type="Boolean" value="false"/> - - <if-empty field="contentOperationId"> - <set field="requiredField" value="contentOperationId"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - - <if-empty field="contentPurposeTypeId"> - <set field="contentPurposeTypeId" from-field="parameters.contentPurposeTypeId"/> - </if-empty> - <if-empty field="contentPurposeTypeId"> - <set field="contentPurposeTypeId" value="_NA_"/> - </if-empty> - - <entity-one entity-name="Content" value-field="checkContent"> - <field-map field-name="contentId" from-field="checkId"/> - </entity-one> - <set field="statusId" from-field="checkContent.statusId"/> - - <!-- If operation is CONTENT_CREATE and contentPurposeTypeId exists in parameters than obtain operations - for that contentPurposeTypeId, else get the operations for checkContent --> - <if> - <condition> - <and> - <if-compare field="contentOperationId" operator="equals" value="CONTENT_CREATE"/> - <not> - <if-empty field="contentPurposeTypeId"/> - </not> - </and> - </condition> - <then> - <!-- find defined purpose/operation mappings --> - <entity-condition entity-name="ContentPurposeOperation" list="operations"> - <condition-list combine="and"> - <condition-expr field-name="contentPurposeTypeId" operator="equals" from-field="contentPurposeTypeId"/> - <condition-expr field-name="contentOperationId" operator="equals" from-field="contentOperationId"/> - </condition-list> - </entity-condition> - </then> - <else> - <!-- get all purposes for checkContent --> - <call-simple-method method-name="findAllContentPurposes"/> - - <!-- find defined purpose/operation mappings --> - <iterate list="contentPurposes" entry="currentPurpose"> - <entity-condition entity-name="ContentPurposeOperation" list="currentOperations"> - <condition-list combine="and"> - <condition-expr field-name="contentPurposeTypeId" operator="equals" from-field="currentPurpose.contentPurposeTypeId"/> - <condition-expr field-name="contentOperationId" operator="equals" from-field="contentOperationId"/> - </condition-list> - <order-by field-name="contentPurposeTypeId"/> - </entity-condition> - <list-to-list list="currentOperations" to-list="operations"/> - </iterate> - - <!-- check the _NA_ purpose but only if no other purposes were found --> - <if-empty field="contentPurposes"> - <entity-condition entity-name="ContentPurposeOperation" list="operations"> - <condition-list combine="and"> - <condition-expr field-name="contentPurposeTypeId" operator="equals" value="_NA_"/> - <condition-expr field-name="contentOperationId" operator="equals" from-field="contentOperationId"/> - </condition-list> - <order-by field-name="contentPurposeTypeId"/> - </entity-condition> - </if-empty> - </else> - </if> - - <!-- place holder for the content ID --> - <set field="toCheckContentId" from-field="checkId"/> - <log level="verbose" message="[${checkId}] Found Operations [${contentPurposeTypeId}/${contentOperationId}] :: ${operations}"/> - - <if> - <condition> - <if-empty field="operations"/> - </condition> - <!-- there are no ContentPurposeOperation entries for this operation/purpose; default is approve permission --> - <then> - <log level="verbose" message="No operations found; permission granted!"/> - <set field="hasPermission" type="Boolean" value="true"/> - </then> - <!-- there are requirements to test --> - <else> - <!-- get all possible partyIds for this user (including group memberships) --> - <call-simple-method method-name="findAllAssociatedPartyIds"/> - - <!-- check each operation security --> - <iterate list="operations" entry="operation"> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"> - <!-- reset the checkId if needed --> - <if> - <condition> - <and> - <if-empty field="checkId"/> - <not> - <if-empty field="toCheckContentId"/> - </not> - </and> - </condition> - <then> - <set field="checkId" from-field="toCheckContentId"/> - </then> - </if> - - <log level="verbose" message="Testing [${checkId}] [${statusId}] OPERATION: ${operation}"/> - - <!-- check statusId --> - <if> - <condition> - <or> - <if-compare field="operation.statusId" value="_NA_" operator="equals"/> - <and> - <not> - <if-empty field="statusId"/> - </not> - <if-compare-field field="operation.statusId" to-field="statusId" operator="equals"/> - </and> - </or> - </condition> - <then> - <log level="verbose" message="Passed status check; now checking role(s)"/> - - <!-- first check passed; now we test for the role membership(s) --> - <iterate list="partyIdList" entry="thisPartyId"> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"> - <set field="checkRoleTypeId" from-field="operation.roleTypeId"/> - <set field="checkPartyId" from-field="thisPartyId"/> - <!-- reset the checkId if needed --> - <if> - <condition> - <and> - <if-empty field="checkId"/> - <not> - <if-empty field="toCheckContentId"/> - </not> - </and> - </condition> - <then> - <set field="checkId" from-field="toCheckContentId"/> - </then> - </if> - <call-simple-method method-name="checkRoleSecurity"/> - - <!-- check the parent(s) for permission --> - <if> - <condition> - <and> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - <not> - <if-empty field="checkId"/> - </not> - </and> - </condition> - <then> - <log level="verbose" message="Starting loop; checking operation: ${operation.contentOperationId}"/> - <while> - <condition> - <!-- iterate until either we have permission or there are no more parents --> - <and> - <if-compare field="hasPermission" value="false" type="Boolean" operator="equals"/> - <not> - <if-empty field="checkId"/> - </not> - </and> - </condition> - <then> - <entity-one entity-name="Content" value-field="currentContent"> - <field-map field-name="contentId" from-field="checkId"/> - </entity-one> - <if> - <condition> - <not> - <if-empty field="currentContent.ownerContentId"/> - </not> - </condition> - <then> - <set field="checkId" from-field="currentContent.ownerContentId"/> - <call-simple-method method-name="checkRoleSecurity"/> - </then> - - <!-- no parent record found; time to stop recursion --> - <else> - <clear-field field="checkId"/> - </else> - </if> - </then> - </while> - </then> - </if> - </if-compare> - </iterate> - </then> - </if> - </if-compare> - </iterate> - </else> - </if> - </simple-method> - - <!-- method to check content ownership --> - <simple-method method-name="checkOwnership" short-description="Checks the (role) ownership of a record"> - <!-- resetting the permission flag --> - <set field="hasPermission" type="Boolean" value="false"/> - - <if-empty field="checkId"> - <set field="requiredField" value="checkId"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - <if-empty field="partyId"> - <set field="partyId" from-field="userLogin.partyId"/> - </if-empty> - <check-errors/> - - <!-- get all the associated parties (this user + all group memberships) --> - <call-simple-method method-name="findAllAssociatedPartyIds"/> - - <!-- ownership role --> - <set field="checkRoleTypeId" value="OWNER"/> - - <!-- check to see if any of the parties are owner of the content --> - <iterate list="partyIdList" entry="thisPartyId"> - <if> - <condition> - <not> - <if-compare field="hasPermission" value="true" operator="equals"/> - </not> - </condition> - <then> - <log level="verbose" message="Checking to see if party [${thisPartyId}] has ownership of ${checkId} :: ${hasPermission}"/> - <set field="checkPartyId" from-field="thisPartyId"/> - <call-simple-method method-name="checkRoleSecurity"/> - </then> - <else> - <log level="verbose" message="Field hasPermission is TRUE [${hasPermission}] did not test!"/> - </else> - </if> - </iterate> - </simple-method> - - <!-- method the check Content Role associations --> - <simple-method method-name="checkRoleSecurity" short-description="Check users role associations with Content"> - <!-- resetting the permission flag --> - <set field="hasPermission" type="Boolean" value="false"/> - <log level="verbose" message="checkRoleSecurity: just reset hasPermission value to false!"/> - - <!-- roleEntity is required to determine which content role table to look: ContentRole, DataResourceRole, etc --> - <if-empty field="roleEntity"> - <set field="requiredField" value="roleEntity"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - <!-- roleEntityField is required to determine the pk field to check; contentId, dataResourceId, etc --> - <if-empty field="roleEntityField"> - <set field="requiredField" value="roleEntityField"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - <!-- setting the env field contentId is required for this simple method --> - <if-empty field="checkId"> - <set field="requiredField" value="checkId"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - <!-- the party ID to check is required for this check --> - <if-empty field="checkPartyId"> - <set field="requiredField" value="checkPartyId"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - <check-errors/> - - <log level="verbose" message="About to test of checkRoleTypeId is empty... ${checkRoleTypeId}"/> - - <if> - <condition> - <and> - <not> - <if-empty field="checkRoleTypeId"/> - </not> - <if-compare field="checkRoleTypeId" value="_NA_" operator="equals"/> - </and> - </condition> - <then> - <!-- _NA_ role means anyone (logged in) has permission --> - <set field="hasPermission" type="Boolean" value="true"/> - </then> - - <!-- not _NA_ so do the actual role check --> - <else> - <if> - <condition> - <not> - <if-empty field="checkRoleTypeId"/> - </not> - </condition> - <then> - <log level="verbose" message="Doing lookup [${roleEntity}] with roleTypeId : ${checkRoleTypeId}"/> - <!-- looking up a specific role --> - <set field="lookup.${roleEntityField}" from-field="checkId"/> - <set field="lookup.roleTypeId" from-field="checkRoleTypeId"/> - <set field="lookup.partyId" from-field="checkPartyId"/> - <find-by-and entity-name="${roleEntity}" map="lookup" list="foundRoles"/> - <!-- - <entity-and entity-name="${roleEntity}" list="foundRoles"> - <field-map from-field="${roleEntityField}"/> - <field-map field-name="roleTypeId" from-field="checkRoleTypeId"/> - <field-map field-name="partyId" from-field="checkPartyId"/> - </entity-and> - --> - </then> - <else> - <log level="verbose" message="Doing lookup without roleTypeId"/> - <!-- looking up any role --> - <set field="lookup.${roleEntityField}" from-field="checkId"/> - <set field="lookup.partyId" from-field="checkPartyId"/> - <find-by-and entity-name="${roleEntity}" map="lookup" list="foundRoles"/> - <!-- - <entity-and entity-name="${roleEntity}" list="foundRoles"> - <field-map from-field="${roleEntityField}"/> - <field-map field-name="partyId" from-field="checkPartyId"/> - </entity-and> - --> - </else> - </if> - - <log level="verbose" message="Checking for ContentRole: [party] - ${checkPartyId} [role] - ${checkRoleTypeId} [content] - ${checkId} :: ${foundRoles}"/> - - <!-- the return should contain some entry if the user is a member --> - <if> - <condition> - <not> - <if-empty field="foundRoles"/> - </not> - </condition> - <then> - <set field="hasPermission" type="Boolean" value="true"/> - </then> - </if> - </else> - </if> - - </simple-method> - - <!-- method to get the content purposes --> - <simple-method method-name="findAllContentPurposes" short-description="Find all content purposes for the specified content"> - <if-empty field="checkId"> - <set field="requiredField" value="checkId"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - <check-errors/> - - <set field="purposeLookup.contentId" from-field="checkId"/> - <find-by-and entity-name="ContentPurpose" map="purposeLookup" list="contentPurposes"/> - </simple-method> - - <!-- method to get user's party associations --> - <simple-method method-name="findAllAssociatedPartyIds" short-description="Finds all associated party Ids for a user"> - <set field="lookupMap.partyIdFrom" from-field="userLogin.partyId"/> - <set field="lookupMap.partyRelationshipTypeId" value="GROUP_ROLLUP"/> - <set field="lookupMap.includeFromToSwitched" value="Y"/> - <call-service service-name="getRelatedParties" include-user-login="true" in-map-name="lookupMap"> - <result-to-field result-name="relatedPartyIdList" field="partyIdList"/> - </call-service> - <log level="verbose" message="Got list of associated parties: ${partyIdList}"/> - </simple-method> - - <!-- method to get content associations --> - <simple-method method-name="findAllParentContent" short-description="Finds all associated parent content"> - <if-empty field="contentId"> - <set field="requiredField" value="contentId"/> - <add-error> - <fail-property resource="ContentUiLabels" property="ContentRequiredField"/> - </add-error> - </if-empty> - <check-errors/> - - <entity-and entity-name="ContentAssoc" list="assocs" filter-by-date="true"> - <field-map field-name="contentIdTo" from-field="contentId"/> - </entity-and> - <field-to-result field="assocs" result-name="contentAssocList"/> - </simple-method> -</simple-methods> diff --git a/applications/content/minilang/permission/DataResourcePermissionServices.xml b/applications/content/minilang/permission/DataResourcePermissionServices.xml index 9d963c4..8363511 100644 --- a/applications/content/minilang/permission/DataResourcePermissionServices.xml +++ b/applications/content/minilang/permission/DataResourcePermissionServices.xml @@ -155,7 +155,8 @@ <!-- check ownership of this record --> <set field="checkId" from-field="dataResourceId"/> - <call-simple-method method-name="checkOwnership" xml-resource="component://content/minilang/permission/ContentPermissionServices.xml"/> + <call-simple-method method-name="checkOwnership" + xml-resource="component://content/groovyScripts/permission/ContentPermissionServices.groovy"/> </then> </if> </simple-method> diff --git a/applications/content/servicedef/services.xml b/applications/content/servicedef/services.xml index 5338abf..b53fcbb 100644 --- a/applications/content/servicedef/services.xml +++ b/applications/content/servicedef/services.xml @@ -909,16 +909,16 @@ </service> <!-- content permission services --> - <service name="contentManagerRolePermission" engine="simple" auth="true" - location="component://content/minilang/permission/ContentPermissionServices.xml" invoke="contentManagerRolePermission"> + <service name="contentManagerRolePermission" engine="groovy" auth="true" + location="component://content/groovyScripts/permission/ContentPermissionServices.groovy" invoke="contentManagerRolePermission"> <implements service="permissionInterface"/> </service> - <service name="contentManagerPermission" engine="simple" auth="true" - location="component://content/minilang/permission/ContentPermissionServices.xml" invoke="contentManagerPermission"> + <service name="contentManagerPermission" engine="groovy" auth="true" + location="component://content/groovyScripts/permission/ContentPermissionServices.groovy" invoke="contentManagerPermission"> <implements service="permissionInterface"/> </service> - <service name="genericContentPermission" engine="simple" auth="true" - location="component://content/minilang/permission/ContentPermissionServices.xml" invoke="genericContentPermission"> + <service name="genericContentPermission" engine="groovy" auth="true" + location="component://content/groovyScripts/permission/ContentPermissionServices.groovy" invoke="genericContentPermission"> <description>Generic Content Permission Service; Takes mainAction to determine the mode.</description> <implements service="permissionInterface"/> <attribute name="ownerContentId" type="String" mode="IN" optional="true"/> @@ -929,6 +929,15 @@ <attribute name="contentPurposeTypeId" type="String" mode="IN" optional="true"/> <attribute name="contentOperationId" type="String" mode="IN" optional="true"/> </service> + <service name="checkOwnership" engine="groovy" auth="true" + location="component://content/groovyScripts/permission/ContentPermissionServices.groovy" invoke="checkOwnership"> + <description>Generic DataResource Permission Service; Takes mainAction to determine the mode.</description> + <implements service="permissionInterface"/> + <attribute name="roleEntity" type="String" mode="IN" optional="true"/> + <attribute name="roleEntityField" type="String" mode="IN" optional="true"/> + <attribute name="checkId" type="String" mode="IN" optional="true"/> + </service> + <service name="genericDataResourcePermission" engine="simple" auth="true" location="component://content/minilang/permission/DataResourcePermissionServices.xml" invoke="genericDataResourcePermission"> <description>Generic DataResource Permission Service; Takes mainAction to determine the mode.</description>