Search in sources :

Example 1 with ManifestAccessControl

use of org.alfresco.repo.transfer.manifest.ManifestAccessControl in project alfresco-repository by Alfresco.

the class RepoPrimaryManifestProcessorImpl method update.

/**
 * @param node TransferManifestNormalNode
 * @param resolvedNodes ResolvedParentChildPair
 * @param primaryParentAssoc ChildAssociationRef
 */
private void update(TransferManifestNormalNode node, ResolvedParentChildPair resolvedNodes, ChildAssociationRef primaryParentAssoc) {
    NodeRef nodeToUpdate = resolvedNodes.resolvedChild;
    /**
     * Check that if the destination is "from" the transferring repo if it is "from" another repo then ignore
     */
    if (nodeService.hasAspect(nodeToUpdate, TransferModel.ASPECT_TRANSFERRED)) {
        String fromRepository = (String) nodeService.getProperty(nodeToUpdate, TransferModel.PROP_FROM_REPOSITORY_ID);
        String transferringRepo = header.getRepositoryId();
        if (fromRepository != null && transferringRepo != null) {
            if (!fromRepository.equalsIgnoreCase(transferringRepo)) {
                logComment("Not updating local node (not from the transferring repository): " + node.getNodeRef());
                return;
            }
        }
    } else {
        logComment("Not updating local node - node is local to this repository): " + node.getNodeRef());
        // Not a transferred node.
        return;
    }
    QName parentAssocType = primaryParentAssoc.getTypeQName();
    QName parentAssocName = primaryParentAssoc.getQName();
    NodeRef parentNodeRef = resolvedNodes.resolvedParent;
    if (parentNodeRef == null) {
        // We can't find the node's parent.
        // We'll store the node in a temporary location and record it for
        // later processing
        ChildAssociationRef tempLocation = getTemporaryLocation(node.getNodeRef());
        parentNodeRef = tempLocation.getParentRef();
        parentAssocType = tempLocation.getTypeQName();
        parentAssocName = tempLocation.getQName();
        storeOrphanNode(primaryParentAssoc);
    }
    // First of all, do we need to move the node? If any aspect of the
    // primary parent association has changed
    // then the answer is "yes"
    ChildAssociationRef currentParent = nodeService.getPrimaryParent(nodeToUpdate);
    if (!currentParent.getParentRef().equals(parentNodeRef) || !currentParent.getTypeQName().equals(parentAssocType) || !currentParent.getQName().equals(parentAssocName)) {
        /**
         * Yes, the parent assoc has changed so we need to move the node
         */
        if (nodeService.hasAspect(currentParent.getParentRef(), TransferModel.ASPECT_ALIEN)) {
            // old parent node ref may be alien so treat as a delete
            alienProcessor.beforeDeleteAlien(currentParent.getChildRef(), null);
        }
        // Yes, we need to move the node
        ChildAssociationRef newNode = nodeService.moveNode(nodeToUpdate, parentNodeRef, parentAssocType, parentAssocName);
        logMoved(node.getNodeRef(), nodeToUpdate, node.getParentPath().toString(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString());
        logSummaryMoved(node.getNodeRef(), nodeToUpdate, node.getParentPath().toString(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString());
        /**
         * are we adding an alien node here? The transfer service has policies disabled
         * so have to call the consequence of the policy directly.
         */
        if (nodeService.hasAspect(newNode.getChildRef(), TransferModel.ASPECT_ALIEN)) {
            alienProcessor.afterMoveAlien(newNode);
        } else {
            /**
             * are we adding an alien node here? The transfer service has policies disabled
             * so have to call the consequence of the policy directly.
             */
            if (nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN)) {
                alienProcessor.onCreateChild(newNode, header.getRepositoryId(), true);
            }
        }
    }
    log.info("Resolved parent node to " + parentNodeRef);
    if (updateNeeded(node, nodeToUpdate)) {
        logUpdated(node.getNodeRef(), nodeToUpdate, nodeService.getPath(nodeToUpdate).toString());
        // We need to process content properties separately.
        // First, create a shallow copy of the supplied property map...
        Map<QName, Serializable> props = new HashMap<QName, Serializable>(node.getProperties());
        Map<QName, Serializable> existingProps = nodeService.getProperties(nodeToUpdate);
        processCategories(props, node.getManifestCategories());
        // inject transferred properties/aspect here
        injectTransferred(props);
        // Remove the invadedBy property since that is used by the transfer service
        // and is local to this repository.
        props.remove(TransferModel.PROP_INVADED_BY);
        // Do we need to worry about locking this updated ?
        if (header.isReadOnly()) {
            props.put(ContentModel.PROP_LOCK_OWNER, AuthenticationUtil.getAdminUserName());
            props.put(ContentModel.PROP_LOCK_TYPE, LockType.NODE_LOCK.toString());
            props.put(ContentModel.PROP_EXPIRY_DATE, null);
            log.debug("updated node needs to be locked");
        }
        // Split out the content properties and sanitise the others
        Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, existingProps);
        // If there was already a value for invadedBy then leave it alone rather than replacing it.
        if (existingProps.containsKey(TransferModel.PROP_INVADED_BY)) {
            props.put(TransferModel.PROP_INVADED_BY, existingProps.get(TransferModel.PROP_INVADED_BY));
        }
        // Update the non-content properties
        nodeService.setProperties(nodeToUpdate, props);
        // Deal with the content properties
        boolean contentUpdated = writeContent(nodeToUpdate, contentProps);
        if (contentUpdated) {
            logSummaryUpdated(node.getNodeRef(), nodeToUpdate, nodeService.getPath(nodeToUpdate).toString());
        }
        // Change the type of the content
        if (!nodeService.getType(nodeToUpdate).equals(node.getType())) {
            // The type has changed, check the dictionary to contain the model for that type
            TypeDefinition newTypeDef = dictionaryService.getType(node.getType());
            if (newTypeDef == null) {
                log.warn("Failed to update the type: " + node.getType() + " for node: " + nodeToUpdate + ", as there is no type definition for it");
            } else {
                // Check the default properties
                Map<QName, PropertyDefinition> typeProperties = newTypeDef.getProperties();
                // Search if all the properties are in place
                boolean fail = false;
                for (QName key : typeProperties.keySet()) {
                    PropertyDefinition propDef = typeProperties.get(key);
                    if (!props.containsKey(key) && propDef.isMandatory()) {
                        log.warn("Failed to update the type: " + node.getType() + " for node: " + nodeToUpdate + ", as the mandatory property '" + propDef.getName() + "' was not transferred.");
                        fail = true;
                        break;
                    }
                }
                if (!fail) {
                    // Set the new type
                    nodeService.setType(nodeToUpdate, node.getType());
                }
            }
        }
        // Blend the aspects together
        Set<QName> suppliedAspects = new HashSet<QName>(node.getAspects());
        Set<QName> existingAspects = nodeService.getAspects(nodeToUpdate);
        Set<QName> aspectsToRemove = new HashSet<QName>(existingAspects);
        // Add mandatory aspects to the supplied aspects (eg. should not explicitly remove auditable aspect from a folder - see also DMDeploymentTarget for similar)
        List<AspectDefinition> aspectDefs = dictionaryService.getType(nodeService.getType(nodeToUpdate)).getDefaultAspects(true);
        for (AspectDefinition aspectDef : aspectDefs) {
            suppliedAspects.add(aspectDef.getName());
        }
        if (header.isReadOnly()) {
            suppliedAspects.add(ContentModel.ASPECT_LOCKABLE);
        }
        aspectsToRemove.removeAll(suppliedAspects);
        /**
         * Don't remove the aspects that the transfer service uses itself.
         */
        aspectsToRemove.remove(TransferModel.ASPECT_TRANSFERRED);
        aspectsToRemove.remove(TransferModel.ASPECT_ALIEN);
        suppliedAspects.removeAll(existingAspects);
        // and suppliedAspects contains the set of aspects to add
        for (QName aspect : suppliedAspects) {
            nodeService.addAspect(nodeToUpdate, aspect, null);
        }
        for (QName aspect : aspectsToRemove) {
            nodeService.removeAspect(nodeToUpdate, aspect);
        }
        // Check the ACL of this updated node
        ManifestAccessControl acl = node.getAccessControl();
        if (acl != null) {
            boolean existInherit = permissionService.getInheritParentPermissions(nodeToUpdate);
            if (existInherit != acl.isInherited()) {
                log.debug("changed inherit permissions flag");
                permissionService.setInheritParentPermissions(nodeToUpdate, acl.isInherited());
            }
            Set<AccessPermission> existingPermissions = permissionService.getAllSetPermissions(nodeToUpdate);
            List<ManifestPermission> newPermissions = acl.getPermissions();
            if (existingPermissions.size() > 0 || newPermissions != null) {
                // Yes we have explicit permissions on this node.
                log.debug("have to check permissions");
                Set<ManifestPermission> work = new HashSet<ManifestPermission>();
                for (AccessPermission permission : existingPermissions) {
                    if (permission.isSetDirectly()) {
                        ManifestPermission p = new ManifestPermission();
                        p.setAuthority(permission.getAuthority());
                        p.setPermission(permission.getPermission());
                        p.setStatus(permission.getAccessStatus().toString());
                        work.add(p);
                    }
                }
                // Do we need to check whether to add any permissions ?
                if (newPermissions != null) {
                    // Do we need to add any permissions ?
                    for (ManifestPermission permission : acl.getPermissions()) {
                        if (!work.contains(permission)) {
                            log.debug("setting permission on node:" + permission);
                            AccessStatus status = AccessStatus.valueOf(permission.getStatus());
                            permissionService.setPermission(nodeToUpdate, permission.getAuthority(), permission.getPermission(), status == AccessStatus.ALLOWED);
                        }
                    }
                    // Remove permissions from "work" that should be there
                    work.removeAll(newPermissions);
                }
                // Do we need to remove any permissions
                for (ManifestPermission permission : work) {
                    log.debug("removing permission on node:" + permission);
                    permissionService.deletePermission(nodeToUpdate, permission.getAuthority(), permission.getPermission());
                }
            }
        }
    }
}
Also used : ManifestPermission(org.alfresco.repo.transfer.manifest.ManifestPermission) Serializable(java.io.Serializable) HashMap(java.util.HashMap) QName(org.alfresco.service.namespace.QName) ManifestAccessControl(org.alfresco.repo.transfer.manifest.ManifestAccessControl) AccessPermission(org.alfresco.service.cmr.security.AccessPermission) AspectDefinition(org.alfresco.service.cmr.dictionary.AspectDefinition) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) PropertyDefinition(org.alfresco.service.cmr.dictionary.PropertyDefinition) TypeDefinition(org.alfresco.service.cmr.dictionary.TypeDefinition) DataTypeDefinition(org.alfresco.service.cmr.dictionary.DataTypeDefinition) AccessStatus(org.alfresco.service.cmr.security.AccessStatus) NodeRef(org.alfresco.service.cmr.repository.NodeRef) HashSet(java.util.HashSet)

Example 2 with ManifestAccessControl

use of org.alfresco.repo.transfer.manifest.ManifestAccessControl in project alfresco-repository by Alfresco.

the class RepoPrimaryManifestProcessorImpl method create.

/**
 * Create new node.
 *
 * @param node TransferManifestNormalNode
 * @param resolvedNodes ResolvedParentChildPair
 * @param primaryParentAssoc ChildAssociationRef
 */
private void create(TransferManifestNormalNode node, ResolvedParentChildPair resolvedNodes, ChildAssociationRef primaryParentAssoc) {
    log.info("Creating new node with noderef " + node.getNodeRef());
    QName parentAssocType = primaryParentAssoc.getTypeQName();
    QName parentAssocName = primaryParentAssoc.getQName();
    NodeRef parentNodeRef = resolvedNodes.resolvedParent;
    if (parentNodeRef == null) {
        if (log.isDebugEnabled()) {
            log.debug("Unable to resolve parent for inbound noderef " + node.getNodeRef() + ".\n  Supplied parent noderef is " + primaryParentAssoc.getParentRef() + ".\n  Supplied parent path is " + node.getParentPath().toString());
        }
        // We can't find the node's parent.
        // We'll store the node in a temporary location and record it for
        // later processing
        ChildAssociationRef tempLocation = getTemporaryLocation(node.getNodeRef());
        parentNodeRef = tempLocation.getParentRef();
        parentAssocType = tempLocation.getTypeQName();
        parentAssocName = tempLocation.getQName();
        log.info("Recording orphaned transfer node: " + node.getNodeRef());
        logComment("Unable to resolve parent for new incoming node. Storing it in temp folder: " + node.getNodeRef());
        storeOrphanNode(primaryParentAssoc);
    }
    // We now know that this is a new node, and we have found the
    // appropriate parent node in the
    // local repository.
    log.info("Resolved parent node to " + parentNodeRef);
    // We need to process content properties separately.
    // First, create a shallow copy of the supplied property map...
    Map<QName, Serializable> props = new HashMap<QName, Serializable>(node.getProperties());
    processCategories(props, node.getManifestCategories());
    injectTransferred(props);
    // Split out the content properties and sanitise the others
    Map<QName, Serializable> contentProps = processProperties(null, props, null);
    // Remove the invadedBy property since that is used by the transfer service
    // and is local to this repository.
    props.remove(TransferModel.PROP_INVADED_BY);
    // Do we need to worry about locking this new node ?
    if (header.isReadOnly()) {
        log.debug("new node needs to be locked");
        props.put(ContentModel.PROP_LOCK_OWNER, AuthenticationUtil.getAdminUserName());
        props.put(ContentModel.PROP_LOCK_TYPE, LockType.NODE_LOCK.toString());
        props.put(ContentModel.PROP_EXPIRY_DATE, null);
    }
    // Create the corresponding node...
    ChildAssociationRef newNode = nodeService.createNode(parentNodeRef, parentAssocType, parentAssocName, node.getType(), props);
    if (log.isDebugEnabled()) {
        log.debug("Created new node (" + newNode.getChildRef() + ") parented by node " + newNode.getParentRef());
    }
    logCreated(node.getNodeRef(), newNode.getChildRef(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString(), false);
    logSummaryCreated(node.getNodeRef(), newNode.getChildRef(), newNode.getParentRef(), nodeService.getPath(newNode.getChildRef()).toString(), false);
    // Deal with the content properties
    writeContent(newNode.getChildRef(), contentProps);
    // Apply any aspects that are needed but haven't automatically been
    // applied
    Set<QName> aspects = new HashSet<QName>(node.getAspects());
    aspects.removeAll(nodeService.getAspects(newNode.getChildRef()));
    for (QName aspect : aspects) {
        nodeService.addAspect(newNode.getChildRef(), aspect, null);
    }
    ManifestAccessControl acl = node.getAccessControl();
    // Apply new ACL to this node
    if (acl != null) {
        permissionService.setInheritParentPermissions(newNode.getChildRef(), acl.isInherited());
        if (acl.getPermissions() != null) {
            for (ManifestPermission permission : acl.getPermissions()) {
                log.debug("setting permission on node");
                AccessStatus status = AccessStatus.valueOf(permission.getStatus());
                // The node has its own access control list
                permissionService.setPermission(newNode.getChildRef(), permission.getAuthority(), permission.getPermission(), status == AccessStatus.ALLOWED);
            }
        }
    }
    /**
     * are we adding an alien node here? The transfer service has policies disabled
     * so have to call the consequence of the policy directly.
     */
    if (nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN)) {
        alienProcessor.onCreateChild(newNode, header.getRepositoryId(), true);
    }
    // Is the node that we've just added the parent of any orphans that
    // we've found earlier?
    checkOrphans(newNode.getChildRef());
}
Also used : NodeRef(org.alfresco.service.cmr.repository.NodeRef) ManifestPermission(org.alfresco.repo.transfer.manifest.ManifestPermission) Serializable(java.io.Serializable) HashMap(java.util.HashMap) QName(org.alfresco.service.namespace.QName) ManifestAccessControl(org.alfresco.repo.transfer.manifest.ManifestAccessControl) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) HashSet(java.util.HashSet) AccessStatus(org.alfresco.service.cmr.security.AccessStatus)

Aggregations

Serializable (java.io.Serializable)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 ManifestAccessControl (org.alfresco.repo.transfer.manifest.ManifestAccessControl)2 ManifestPermission (org.alfresco.repo.transfer.manifest.ManifestPermission)2 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)2 NodeRef (org.alfresco.service.cmr.repository.NodeRef)2 AccessStatus (org.alfresco.service.cmr.security.AccessStatus)2 QName (org.alfresco.service.namespace.QName)2 AspectDefinition (org.alfresco.service.cmr.dictionary.AspectDefinition)1 DataTypeDefinition (org.alfresco.service.cmr.dictionary.DataTypeDefinition)1 PropertyDefinition (org.alfresco.service.cmr.dictionary.PropertyDefinition)1 TypeDefinition (org.alfresco.service.cmr.dictionary.TypeDefinition)1 AccessPermission (org.alfresco.service.cmr.security.AccessPermission)1