Kuali Rice Development
  1. Kuali Rice Development
  2. KULRICE-8610

Make it so that the role qualifiers built in the DocumentTypePermissionService can be configurable by client apps.

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.1.3
    • Fix Version/s: 2.1.3
    • Component/s: Development
    • Security Level: Public (Public: Anyone can view)
    • Labels:
      None
    • Similar issues:
      KULRICE-6749Configure rice sample app as a client app running against a standalone server
      KULRICE-6399Make configuring the reloading data dictionary easier for client app developers
      KULRICE-133make it so the bus registry can be configured as a url
      KULRICE-10632Test env for client app using standalone
      KULRICE-129make it so bam can be applied in service configuration so it can be ran service by service
      KULRICE-8689Unable to programmatically re-resolve workflow on qualified roles from embedded KEW clients
      KULRICE-12814Clean up datasource configuration
      KULRICE-793Document built in roles and built in nodes
      KULRICE-3989UIDocumentService.loadRoleMemberQualifiers - is there a way to load qualifiers not associated with the role type
      KULRICE-9286KualiInquirableTest fails in CI with An inquiry URL to AccountManager should be built
    • Rice Module:
      KNS
    • Application Requirement:
      KC
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required

      Description

      This relates to KULRICE-8490. In that jira, we addressed the issue by adding the same kind of parameter check that is used in the canRoute and canSave methods. This works in KC but only because it bypasses all KIM permissions checks. The ideal situation would be where we can configure these from the KC end either by overriding some methods in the service or by spring injection. The details of the implementation can be discussed further.

        Issue Links

          Activity

          Hide
          Gayathri Athreya added a comment -

          Claus, I assigned it to you because we discussed this and you worked on KULRICE-8490. If it needs to go through the DM, that is obviously fine as well.

          Show
          Gayathri Athreya added a comment - Claus, I assigned it to you because we discussed this and you worked on KULRICE-8490 . If it needs to go through the DM, that is obviously fine as well.
          Hide
          Gayathri Athreya added a comment - - edited

          It was determined that the current solution of checking the useKimPermission parameter does not work for KC

          public boolean canRecall(String principalId, String documentId, DocumentType documentType, List<String> routeNodeNames, String documentStatus, String appDocStatus, String initiatorPrincipalId) {
                  validatePrincipalId(principalId);
                  validateDocumentType(documentType);
                  validateRouteNodeNames(routeNodeNames);
                  validateDocumentStatus(documentStatus);
                  // no need to validate appdocstatus, this is a free-form application defined value
          
                  // add appDocStatus to the details
                  List<Map<String, String>> permissionDetailList = buildDocumentTypePermissionDetails(documentType, routeNodeNames, documentStatus);
                  if (!StringUtils.isBlank(appDocStatus)) {
                      for (Map<String, String> details: permissionDetailList) {
                          details.put(KewApiConstants.APP_DOC_STATUS_DETAIL, appDocStatus);
                      }
                  }
          
                  boolean foundAtLeastOnePermission = false;
                  boolean authorizedByPermission = false;
                  boolean principalIsInitiator = StringUtils.equals(initiatorPrincipalId, principalId);
          
                  // loop over permission details, only one of them needs to be authorized
                  for (Map<String, String> permissionDetails : permissionDetailList) {
                      Map<String, String> roleQualifiers = buildDocumentIdRoleDocumentTypeDocumentStatusQualifiers(documentType, documentStatus, documentId, permissionDetails.get(KewApiConstants.ROUTE_NODE_NAME_DETAIL));
                      if (useKimPermission(KewApiConstants.KEW_NAMESPACE, KewApiConstants.RECALL_PERMISSION, permissionDetails)) {
                          if (getPermissionService().isPermissionDefinedByTemplate(KewApiConstants.KEW_NAMESPACE, KewApiConstants.RECALL_PERMISSION, permissionDetails)) {
                              foundAtLeastOnePermission = true;
                              if (getPermissionService().isAuthorizedByTemplate(principalId, KewApiConstants.KEW_NAMESPACE,
                                      KewApiConstants.RECALL_PERMISSION, permissionDetails, roleQualifiers)) {
                                  authorizedByPermission = true;
                                  break;
                              }
                          }
                      }
                  }
          
                  // alternative could be to only authorize initiator if the permission is omitted
                  // (i.e. exclude initiator if the initiator does not have the recall permission)
                  return authorizedByPermission;
              }
          

          The above useKimPermissions check was added to bypass KIM authorization but turns out it will never return true for us because of the following:
          authorizedByPermission is set to false initially and when the useKimPermission is false (it is false in KC because we set the KIM_PRIORITY_ON_DOC_TYP_PERMS_IND parameter to N), it never gets set to true which means it is always going to return false for us.
          Also, using a document policy of InitiatorCanRecall will also not work because the document can be recalled by non-initiators.

          Show
          Gayathri Athreya added a comment - - edited It was determined that the current solution of checking the useKimPermission parameter does not work for KC public boolean canRecall( String principalId, String documentId, DocumentType documentType, List< String > routeNodeNames, String documentStatus, String appDocStatus, String initiatorPrincipalId) { validatePrincipalId(principalId); validateDocumentType(documentType); validateRouteNodeNames(routeNodeNames); validateDocumentStatus(documentStatus); // no need to validate appdocstatus, this is a free-form application defined value // add appDocStatus to the details List<Map< String , String >> permissionDetailList = buildDocumentTypePermissionDetails(documentType, routeNodeNames, documentStatus); if (!StringUtils.isBlank(appDocStatus)) { for (Map< String , String > details: permissionDetailList) { details.put(KewApiConstants.APP_DOC_STATUS_DETAIL, appDocStatus); } } boolean foundAtLeastOnePermission = false ; boolean authorizedByPermission = false ; boolean principalIsInitiator = StringUtils.equals(initiatorPrincipalId, principalId); // loop over permission details, only one of them needs to be authorized for (Map< String , String > permissionDetails : permissionDetailList) { Map< String , String > roleQualifiers = buildDocumentIdRoleDocumentTypeDocumentStatusQualifiers(documentType, documentStatus, documentId, permissionDetails.get(KewApiConstants.ROUTE_NODE_NAME_DETAIL)); if (useKimPermission(KewApiConstants.KEW_NAMESPACE, KewApiConstants.RECALL_PERMISSION, permissionDetails)) { if (getPermissionService().isPermissionDefinedByTemplate(KewApiConstants.KEW_NAMESPACE, KewApiConstants.RECALL_PERMISSION, permissionDetails)) { foundAtLeastOnePermission = true ; if (getPermissionService().isAuthorizedByTemplate(principalId, KewApiConstants.KEW_NAMESPACE, KewApiConstants.RECALL_PERMISSION, permissionDetails, roleQualifiers)) { authorizedByPermission = true ; break ; } } } } // alternative could be to only authorize initiator if the permission is omitted // (i.e. exclude initiator if the initiator does not have the recall permission) return authorizedByPermission; } The above useKimPermissions check was added to bypass KIM authorization but turns out it will never return true for us because of the following: authorizedByPermission is set to false initially and when the useKimPermission is false (it is false in KC because we set the KIM_PRIORITY_ON_DOC_TYP_PERMS_IND parameter to N), it never gets set to true which means it is always going to return false for us. Also, using a document policy of InitiatorCanRecall will also not work because the document can be recalled by non-initiators.
          Hide
          Aaron Hamid (Inactive) added a comment -

          work has been completed and ready to commit once database change goes in.

          however, after reviewing the KNS/KRAD DocumentAuthorizer I'm wondering if anybody can comment on the relationship of that mechanism to this new one. there seems to be quite an overlap. the KNS/KRAD DocumentAuthorizer framework provides for custom details and qualifiers via getPermissionDetailValues and getRoleQualification, and mostly performs direct KIM permission checks itself. should one delegate to the other?

          Show
          Aaron Hamid (Inactive) added a comment - work has been completed and ready to commit once database change goes in. however, after reviewing the KNS/KRAD DocumentAuthorizer I'm wondering if anybody can comment on the relationship of that mechanism to this new one. there seems to be quite an overlap. the KNS/KRAD DocumentAuthorizer framework provides for custom details and qualifiers via getPermissionDetailValues and getRoleQualification , and mostly performs direct KIM permission checks itself. should one delegate to the other?
          Hide
          Gayathri Athreya added a comment -

          This worked smoothly for us. Thanks a lot Aaron

          Show
          Gayathri Athreya added a comment - This worked smoothly for us. Thanks a lot Aaron

            People

            • Assignee:
              Aaron Hamid (Inactive)
              Reporter:
              Gayathri Athreya
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 2 days, 1 hour
                2d 1h

                  Structure Helper Panel