Search in sources :

Example 1 with CmsLockException

use of org.opencms.lock.CmsLockException in project opencms-core by alkacon.

the class CmsDriverManager method deleteResource.

/**
 * Deletes a resource.<p>
 *
 * The <code>siblingMode</code> parameter controls how to handle siblings
 * during the delete operation.
 * Possible values for this parameter are:
 * <ul>
 * <li><code>{@link CmsResource#DELETE_REMOVE_SIBLINGS}</code></li>
 * <li><code>{@link CmsResource#DELETE_PRESERVE_SIBLINGS}</code></li>
 * </ul><p>
 *
 * @param dbc the current database context
 * @param resource the name of the resource to delete (full path)
 * @param siblingMode indicates how to handle siblings of the deleted resource
 *
 * @throws CmsException if something goes wrong
 *
 * @see CmsObject#deleteResource(String, CmsResource.CmsResourceDeleteMode)
 * @see I_CmsResourceType#deleteResource(CmsObject, CmsSecurityManager, CmsResource, CmsResource.CmsResourceDeleteMode)
 */
public void deleteResource(CmsDbContext dbc, CmsResource resource, CmsResource.CmsResourceDeleteMode siblingMode) throws CmsException {
    // upgrade a potential inherited, non-shared lock into a common lock
    CmsLock currentLock = getLock(dbc, resource);
    if (currentLock.getEditionLock().isDirectlyInherited()) {
        // upgrade the lock status if required
        lockResource(dbc, resource, CmsLockType.EXCLUSIVE);
    }
    // check if siblings of the resource exist and must be deleted as well
    if (resource.isFolder()) {
        // folder can have no siblings
        siblingMode = CmsResource.DELETE_PRESERVE_SIBLINGS;
    }
    // if selected, add all siblings of this resource to the list of resources to be deleted
    boolean allSiblingsRemoved;
    List<CmsResource> resources;
    if (siblingMode == CmsResource.DELETE_REMOVE_SIBLINGS) {
        resources = new ArrayList<CmsResource>(readSiblings(dbc, resource, CmsResourceFilter.ALL));
        allSiblingsRemoved = true;
        // ensure that the resource requested to be deleted is the last resource that gets actually deleted
        // to keep the shared locks of the siblings while those get deleted.
        resources.remove(resource);
        resources.add(resource);
    } else {
        // only delete the resource, no siblings
        resources = Collections.singletonList(resource);
        allSiblingsRemoved = false;
    }
    int size = resources.size();
    // if we have only one resource no further check is required
    if (size > 1) {
        CmsMultiException me = new CmsMultiException();
        // ensure that each sibling is unlocked or locked by the current user
        for (int i = 0; i < size; i++) {
            CmsResource currentResource = resources.get(i);
            currentLock = getLock(dbc, currentResource);
            if (!currentLock.getEditionLock().isUnlocked() && !currentLock.isOwnedBy(dbc.currentUser())) {
                // the resource is locked by a user different from the current user
                CmsRequestContext context = dbc.getRequestContext();
                me.addException(new CmsLockException(org.opencms.lock.Messages.get().container(org.opencms.lock.Messages.ERR_SIBLING_LOCKED_2, context.getSitePath(currentResource), context.getSitePath(resource))));
            }
        }
        if (!me.getExceptions().isEmpty()) {
            throw me;
        }
    }
    boolean removeAce = true;
    if (resource.isFolder()) {
        // check if the folder has any resources in it
        Iterator<CmsResource> childResources = getVfsDriver(dbc).readChildResources(dbc, dbc.currentProject(), resource, true, true).iterator();
        CmsUUID projectId = CmsProject.ONLINE_PROJECT_ID;
        if (dbc.currentProject().isOnlineProject()) {
            // HACK: to get an offline project id
            projectId = CmsUUID.getOpenCmsUUID();
        }
        // collect the names of the resources inside the folder, excluding the moved resources
        StringBuffer errorResNames = new StringBuffer(128);
        while (childResources.hasNext()) {
            CmsResource errorRes = childResources.next();
            if (errorRes.getState().isDeleted()) {
                continue;
            }
            // if deleting offline, or not moved, or just renamed inside the deleted folder
            // so, it may remain some orphan online entries for moved resources
            // which will be fixed during the publishing of the moved resources
            boolean error = !dbc.currentProject().isOnlineProject();
            if (!error) {
                try {
                    String originalPath = getVfsDriver(dbc).readResource(dbc, projectId, errorRes.getRootPath(), true).getRootPath();
                    error = originalPath.equals(errorRes.getRootPath()) || originalPath.startsWith(resource.getRootPath());
                } catch (CmsVfsResourceNotFoundException e) {
                // ignore
                }
            }
            if (error) {
                if (errorResNames.length() != 0) {
                    errorResNames.append(", ");
                }
                errorResNames.append("[" + dbc.removeSiteRoot(errorRes.getRootPath()) + "]");
            }
        }
        // the current implementation only deletes empty folders
        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(errorResNames.toString())) {
            throw new CmsVfsException(org.opencms.db.generic.Messages.get().container(org.opencms.db.generic.Messages.ERR_DELETE_NONEMTY_FOLDER_2, dbc.removeSiteRoot(resource.getRootPath()), errorResNames.toString()));
        }
    }
    // delete all collected resources
    for (int i = 0; i < size; i++) {
        CmsResource currentResource = resources.get(i);
        // is to be removed without write permissions, ie. while deleting a folder
        if (!currentResource.equals(resource) && (I_CmsPermissionHandler.PERM_ALLOWED != m_securityManager.hasPermissions(dbc, currentResource, CmsPermissionSet.ACCESS_WRITE, LockCheck.yes, CmsResourceFilter.ALL))) {
            // no write access to sibling - must keep ACE (see below)
            allSiblingsRemoved = false;
        } else {
            // write access to sibling granted
            boolean existsOnline = (getVfsDriver(dbc).validateStructureIdExists(dbc, CmsProject.ONLINE_PROJECT_ID, currentResource.getStructureId()) || !(currentResource.getState().equals(CmsResource.STATE_NEW)));
            if (!existsOnline) {
                // the resource does not exist online => remove the resource
                // this means the resource is "new" (blue) in the offline project
                // delete all properties of this resource
                deleteAllProperties(dbc, currentResource.getRootPath());
                if (currentResource.isFolder()) {
                    getVfsDriver(dbc).removeFolder(dbc, dbc.currentProject(), currentResource);
                } else {
                    // check labels
                    if (currentResource.isLabeled() && !labelResource(dbc, currentResource, null, 2)) {
                        // update the resource flags to "un label" the other siblings
                        int flags = currentResource.getFlags();
                        flags &= ~CmsResource.FLAG_LABELED;
                        currentResource.setFlags(flags);
                    }
                    getVfsDriver(dbc).removeFile(dbc, dbc.currentProject().getUuid(), currentResource);
                }
                // ensure an exclusive lock is removed in the lock manager for a deleted new resource,
                // otherwise it would "stick" in the lock manager, preventing other users from creating
                // a file with the same name (issue with temp files in editor)
                m_lockManager.removeDeletedResource(dbc, currentResource.getRootPath());
                // delete relations
                getVfsDriver(dbc).deleteRelations(dbc, dbc.currentProject().getUuid(), currentResource, CmsRelationFilter.TARGETS);
                getVfsDriver(dbc).deleteUrlNameMappingEntries(dbc, false, CmsUrlNameMappingFilter.ALL.filterStructureId(currentResource.getStructureId()));
                getVfsDriver(dbc).deleteAliases(dbc, dbc.currentProject(), new CmsAliasFilter(null, null, currentResource.getStructureId()));
                log(dbc, new CmsLogEntry(dbc, currentResource.getStructureId(), CmsLogEntryType.RESOURCE_NEW_DELETED, new String[] { currentResource.getRootPath() }), true);
            } else {
                // the resource exists online => mark the resource as deleted
                // structure record is removed during next publish
                // if one (or more) siblings are not removed, the ACE can not be removed
                removeAce = false;
                // set resource state to deleted
                currentResource.setState(CmsResource.STATE_DELETED);
                getVfsDriver(dbc).writeResourceState(dbc, dbc.currentProject(), currentResource, UPDATE_STRUCTURE, false);
                // update the project ID
                getVfsDriver(dbc).writeLastModifiedProjectId(dbc, dbc.currentProject(), dbc.currentProject().getUuid(), currentResource);
                // log it
                log(dbc, new CmsLogEntry(dbc, currentResource.getStructureId(), CmsLogEntryType.RESOURCE_DELETED, new String[] { currentResource.getRootPath() }), true);
            }
        }
    }
    if ((resource.getSiblingCount() <= 1) || allSiblingsRemoved) {
        if (removeAce) {
            // remove the access control entries
            getUserDriver(dbc).removeAccessControlEntries(dbc, dbc.currentProject(), resource.getResourceId());
        }
    }
    // flush all caches
    m_monitor.clearAccessControlListCache();
    m_monitor.flushCache(CmsMemoryMonitor.CacheType.PROPERTY, CmsMemoryMonitor.CacheType.PROPERTY_LIST, CmsMemoryMonitor.CacheType.PROJECT_RESOURCES);
    Map<String, Object> eventData = new HashMap<String, Object>();
    eventData.put(I_CmsEventListener.KEY_RESOURCES, resources);
    eventData.put(I_CmsEventListener.KEY_DBCONTEXT, dbc);
    OpenCms.fireCmsEvent(new CmsEvent(I_CmsEventListener.EVENT_RESOURCE_DELETED, eventData));
}
Also used : HashMap(java.util.HashMap) CmsEvent(org.opencms.main.CmsEvent) CmsLock(org.opencms.lock.CmsLock) CmsVfsResourceNotFoundException(org.opencms.file.CmsVfsResourceNotFoundException) CmsVfsException(org.opencms.file.CmsVfsException) CmsMultiException(org.opencms.main.CmsMultiException) CmsResource(org.opencms.file.CmsResource) I_CmsResource(org.opencms.file.I_CmsResource) CmsRequestContext(org.opencms.file.CmsRequestContext) CmsLockException(org.opencms.lock.CmsLockException) CmsLogEntry(org.opencms.db.log.CmsLogEntry) CmsUUID(org.opencms.util.CmsUUID) CmsObject(org.opencms.file.CmsObject)

Example 2 with CmsLockException

use of org.opencms.lock.CmsLockException in project opencms-core by alkacon.

the class CmsDriverManager method createResource.

/**
 * Creates a new resource with the provided content and properties.<p>
 *
 * The <code>content</code> parameter may be <code>null</code> if the resource id
 * already exists. If so, the created resource will be a sibling of the existing
 * resource, the existing content will remain unchanged.<p>
 *
 * This is used during file import for import of siblings as the
 * <code>manifest.xml</code> only contains one binary copy per file.<p>
 *
 * If the resource id exists but the <code>content</code> is not <code>null</code>,
 * the created resource will be made a sibling of the existing resource,
 * and both will share the new content.<p>
 *
 * @param dbc the current database context
 * @param resourcePath the name of the resource to create (full path)
 * @param resource the new resource to create
 * @param content the content for the new resource
 * @param properties the properties for the new resource
 * @param importCase if <code>true</code>, signals that this operation is done while
 *                      importing resource, causing different lock behavior and
 *                      potential "lost and found" usage
 *
 * @return the created resource
 *
 * @throws CmsException if something goes wrong
 */
public CmsResource createResource(CmsDbContext dbc, String resourcePath, CmsResource resource, byte[] content, List<CmsProperty> properties, boolean importCase) throws CmsException {
    CmsResource newResource = null;
    if (resource.isFolder()) {
        resourcePath = CmsFileUtil.addTrailingSeparator(resourcePath);
    }
    try {
        synchronized (this) {
            // need to provide the parent folder id for resource creation
            String parentFolderName = CmsResource.getParentFolder(resourcePath);
            CmsResource parentFolder = readFolder(dbc, parentFolderName, CmsResourceFilter.IGNORE_EXPIRATION);
            CmsLock parentLock = getLock(dbc, parentFolder);
            // it is not allowed to create a resource in a folder locked by other user
            if (!parentLock.isUnlocked() && !parentLock.isOwnedBy(dbc.currentUser())) {
                // one exception is if the admin user tries to create a temporary resource
                if (!CmsResource.getName(resourcePath).startsWith(TEMP_FILE_PREFIX) || !m_securityManager.hasRole(dbc, dbc.currentUser(), CmsRole.ROOT_ADMIN)) {
                    throw new CmsLockException(Messages.get().container(Messages.ERR_CREATE_RESOURCE_PARENT_LOCK_1, dbc.removeSiteRoot(resourcePath)));
                }
            }
            if (CmsResourceTypeJsp.isJsp(resource)) {
                // security check when trying to create a new jsp file
                m_securityManager.checkRoleForResource(dbc, CmsRole.VFS_MANAGER, parentFolder);
            }
            // check import configuration of "lost and found" folder
            boolean useLostAndFound = importCase && !OpenCms.getImportExportManager().overwriteCollidingResources();
            // check if the resource already exists by name
            CmsResource currentResourceByName = null;
            try {
                currentResourceByName = readResource(dbc, resourcePath, CmsResourceFilter.ALL);
            } catch (CmsVfsResourceNotFoundException e) {
            // if the resource does exist, we have to check the id later to decide what to do
            }
            // check if the resource already exists by id
            try {
                CmsResource currentResourceById = readResource(dbc, resource.getStructureId(), CmsResourceFilter.ALL);
                // it is not allowed to import resources when there is already a resource with the same id but different path
                if (!currentResourceById.getRootPath().equals(resourcePath)) {
                    throw new CmsVfsResourceAlreadyExistsException(Messages.get().container(Messages.ERR_RESOURCE_WITH_ID_ALREADY_EXISTS_3, dbc.removeSiteRoot(resourcePath), dbc.removeSiteRoot(currentResourceById.getRootPath()), currentResourceById.getStructureId()));
                }
            } catch (CmsVfsResourceNotFoundException e) {
            // if the resource does exist, we have to check the id later to decide what to do
            }
            // check the permissions
            if (currentResourceByName == null) {
                // resource does not exist - check parent folder
                m_securityManager.checkPermissions(dbc, parentFolder, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.IGNORE_EXPIRATION);
            } else {
                // resource already exists - check existing resource
                m_securityManager.checkPermissions(dbc, currentResourceByName, CmsPermissionSet.ACCESS_WRITE, !importCase, CmsResourceFilter.ALL);
            }
            // now look for the resource by name
            if (currentResourceByName != null) {
                boolean overwrite = true;
                if (currentResourceByName.getState().isDeleted()) {
                    if (!currentResourceByName.isFolder()) {
                        // if a non-folder resource was deleted it's treated like a new resource
                        overwrite = false;
                    }
                } else {
                    if (!importCase) {
                        // or if the resource has been deleted
                        throw new CmsVfsResourceAlreadyExistsException(org.opencms.db.generic.Messages.get().container(org.opencms.db.generic.Messages.ERR_RESOURCE_WITH_NAME_ALREADY_EXISTS_1, dbc.removeSiteRoot(resource.getRootPath())));
                    }
                    // the resource already exists
                    if (!resource.isFolder() && useLostAndFound && (!currentResourceByName.getResourceId().equals(resource.getResourceId()))) {
                        // semantic change: the current resource is moved to L&F and the imported resource will overwrite the old one
                        // will leave the resource with state deleted,
                        // but it does not matter, since the state will be set later again
                        moveToLostAndFound(dbc, currentResourceByName, false);
                    }
                }
                if (!overwrite) {
                    // lock the resource, will throw an exception if not lockable
                    lockResource(dbc, currentResourceByName, CmsLockType.EXCLUSIVE);
                    // trigger createResource instead of writeResource
                    currentResourceByName = null;
                }
            }
            // if null, create new resource, if not null write resource
            CmsResource overwrittenResource = currentResourceByName;
            // extract the name (without path)
            String targetName = CmsResource.getName(resourcePath);
            int contentLength;
            // modify target name and content length in case of folder creation
            if (resource.isFolder()) {
                // folders never have any content
                contentLength = -1;
                // must cut of trailing '/' for folder creation (or name check fails)
                if (CmsResource.isFolder(targetName)) {
                    targetName = targetName.substring(0, targetName.length() - 1);
                }
            } else {
                // otherwise ensure content and content length are set correctly
                if (content != null) {
                    // if a content is provided, in each case the length is the length of this content
                    contentLength = content.length;
                } else if (overwrittenResource != null) {
                    // we have no content, but an already existing resource - length remains unchanged
                    contentLength = overwrittenResource.getLength();
                } else {
                    // we have no content - length is used as set in the resource
                    contentLength = resource.getLength();
                }
            }
            // check if the target name is valid (forbidden chars etc.),
            // if not throw an exception
            // must do this here since targetName is modified in folder case (see above)
            CmsResource.checkResourceName(targetName);
            // set structure and resource ids as given
            CmsUUID structureId = resource.getStructureId();
            CmsUUID resourceId = resource.getResourceId();
            // decide which structure id to use
            if (overwrittenResource != null) {
                // resource exists, re-use existing ids
                structureId = overwrittenResource.getStructureId();
            }
            if (structureId.isNullUUID()) {
                // need a new structure id
                structureId = new CmsUUID();
            }
            // decide which resource id to use
            if (overwrittenResource != null) {
                // if we are overwriting we have to assure the resource id is the same
                resourceId = overwrittenResource.getResourceId();
            }
            if (resourceId.isNullUUID()) {
                // need a new resource id
                resourceId = new CmsUUID();
            }
            try {
                // check online resource
                CmsResource onlineResource = getVfsDriver(dbc).readResource(dbc, CmsProject.ONLINE_PROJECT_ID, resourcePath, true);
                // only allow to overwrite with different id if importing (createResource will set the right id)
                try {
                    CmsResource offlineResource = getVfsDriver(dbc).readResource(dbc, dbc.currentProject().getUuid(), onlineResource.getStructureId(), true);
                    if (!offlineResource.getRootPath().equals(onlineResource.getRootPath())) {
                        throw new CmsVfsOnlineResourceAlreadyExistsException(Messages.get().container(Messages.ERR_ONLINE_RESOURCE_EXISTS_2, dbc.removeSiteRoot(resourcePath), dbc.removeSiteRoot(offlineResource.getRootPath())));
                    }
                } catch (CmsVfsResourceNotFoundException e) {
                    // but should never happen
                    if (LOG.isErrorEnabled()) {
                        LOG.error(e.getLocalizedMessage(), e);
                    }
                }
            } catch (CmsVfsResourceNotFoundException e) {
            // ok, there is no online entry to worry about
            }
            // now create a resource object with all informations
            newResource = new CmsResource(structureId, resourceId, resourcePath, resource.getTypeId(), resource.isFolder(), resource.getFlags(), dbc.currentProject().getUuid(), resource.getState(), resource.getDateCreated(), resource.getUserCreated(), resource.getDateLastModified(), resource.getUserLastModified(), resource.getDateReleased(), resource.getDateExpired(), 1, contentLength, resource.getDateContent(), // version number does not matter since it will be computed later
            resource.getVersion());
            // ensure date is updated only if required
            if (resource.isTouched()) {
                // this will trigger the internal "is touched" state on the new resource
                newResource.setDateLastModified(resource.getDateLastModified());
            }
            if (resource.isFile()) {
                // check if a sibling to the imported resource lies in a marked site
                if (labelResource(dbc, resource, resourcePath, 2)) {
                    int flags = resource.getFlags();
                    flags |= CmsResource.FLAG_LABELED;
                    resource.setFlags(flags);
                }
                // ensure siblings don't overwrite existing resource records
                if (content == null) {
                    newResource.setState(CmsResource.STATE_KEEP);
                }
            }
            // delete all relations for the resource, before writing the content
            getVfsDriver(dbc).deleteRelations(dbc, dbc.currentProject().getUuid(), newResource, CmsRelationFilter.TARGETS);
            if (overwrittenResource == null) {
                CmsLock lock = getLock(dbc, newResource);
                if (lock.getEditionLock().isExclusive()) {
                    unlockResource(dbc, newResource, true, false);
                }
                // resource does not exist.
                newResource = getVfsDriver(dbc).createResource(dbc, dbc.currentProject().getUuid(), newResource, content);
            } else {
                // resource already exists.
                // probably the resource is a merged page file that gets overwritten during import, or it gets
                // overwritten by a copy operation. if so, the structure & resource state are not modified to changed.
                int updateStates = (overwrittenResource.getState().isNew() ? CmsDriverManager.NOTHING_CHANGED : CmsDriverManager.UPDATE_ALL);
                getVfsDriver(dbc).writeResource(dbc, dbc.currentProject().getUuid(), newResource, updateStates);
                if ((content != null) && resource.isFile()) {
                    // also update file content if required
                    getVfsDriver(dbc).writeContent(dbc, newResource.getResourceId(), content);
                }
            }
            // write the properties (internal operation, no events or duplicate permission checks)
            writePropertyObjects(dbc, newResource, properties, false);
            // lock the created resource
            try {
                // if it is locked by another user (copied or moved resource) this lock should be preserved and
                // the exception is OK: locks on created resources are a slave feature to original locks
                lockResource(dbc, newResource, CmsLockType.EXCLUSIVE);
            } catch (CmsLockException cle) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug(Messages.get().getBundle().key(Messages.ERR_CREATE_RESOURCE_LOCK_1, new Object[] { dbc.removeSiteRoot(newResource.getRootPath()) }));
                }
            }
            if (!importCase) {
                log(dbc, new CmsLogEntry(dbc, newResource.getStructureId(), CmsLogEntryType.RESOURCE_CREATED, new String[] { resource.getRootPath() }), false);
            } else {
                log(dbc, new CmsLogEntry(dbc, newResource.getStructureId(), CmsLogEntryType.RESOURCE_IMPORTED, new String[] { resource.getRootPath() }), false);
            }
        }
    } finally {
        // clear the internal caches
        m_monitor.clearAccessControlListCache();
        m_monitor.flushCache(CmsMemoryMonitor.CacheType.PROPERTY, CmsMemoryMonitor.CacheType.PROPERTY_LIST);
        if (newResource != null) {
            // fire an event that a new resource has been created
            OpenCms.fireCmsEvent(new CmsEvent(I_CmsEventListener.EVENT_RESOURCE_CREATED, Collections.<String, Object>singletonMap(I_CmsEventListener.KEY_RESOURCE, newResource)));
        }
    }
    return newResource;
}
Also used : CmsEvent(org.opencms.main.CmsEvent) CmsLock(org.opencms.lock.CmsLock) CmsVfsResourceNotFoundException(org.opencms.file.CmsVfsResourceNotFoundException) CmsResource(org.opencms.file.CmsResource) I_CmsResource(org.opencms.file.I_CmsResource) CmsLockException(org.opencms.lock.CmsLockException) CmsLogEntry(org.opencms.db.log.CmsLogEntry) CmsUUID(org.opencms.util.CmsUUID) CmsObject(org.opencms.file.CmsObject) CmsVfsResourceAlreadyExistsException(org.opencms.file.CmsVfsResourceAlreadyExistsException)

Example 3 with CmsLockException

use of org.opencms.lock.CmsLockException in project opencms-core by alkacon.

the class CmsDriverManager method changeLock.

/**
 * Changes the lock of a resource to the current user,
 * that is "steals" the lock from another user.<p>
 *
 * @param dbc the current database context
 * @param resource the resource to change the lock for
 * @param lockType the new lock type to set
 *
 * @throws CmsException if something goes wrong
 * @throws CmsSecurityException if something goes wrong
 *
 * @see CmsObject#changeLock(String)
 * @see I_CmsResourceType#changeLock(CmsObject, CmsSecurityManager, CmsResource)
 *
 * @see CmsSecurityManager#hasPermissions(CmsRequestContext, CmsResource, CmsPermissionSet, boolean, CmsResourceFilter)
 */
public void changeLock(CmsDbContext dbc, CmsResource resource, CmsLockType lockType) throws CmsException, CmsSecurityException {
    // get the current lock
    CmsLock currentLock = getLock(dbc, resource);
    // check if the resource is locked at all
    if (currentLock.getEditionLock().isUnlocked() && currentLock.getSystemLock().isUnlocked()) {
        throw new CmsLockException(Messages.get().container(Messages.ERR_CHANGE_LOCK_UNLOCKED_RESOURCE_1, dbc.getRequestContext().getSitePath(resource)));
    } else if ((lockType == CmsLockType.EXCLUSIVE) && currentLock.isExclusiveOwnedInProjectBy(dbc.currentUser(), dbc.currentProject())) {
        // the current lock requires no change
        return;
    }
    // duplicate logic from CmsSecurityManager#hasPermissions() because lock state can't be ignored
    // if another user has locked the file, the current user can never get WRITE permissions with the default check
    int denied = 0;
    // check if the current user is vfs manager
    boolean canIgnorePermissions = m_securityManager.hasRoleForResource(dbc, dbc.currentUser(), CmsRole.VFS_MANAGER, resource);
    // write is only allowed for developers
    if (!canIgnorePermissions && (CmsResourceTypeJsp.isJsp(resource))) {
        if (!m_securityManager.hasRoleForResource(dbc, dbc.currentUser(), CmsRole.VFS_MANAGER, resource)) {
            denied |= CmsPermissionSet.PERMISSION_WRITE;
        }
    }
    CmsPermissionSetCustom permissions;
    if (canIgnorePermissions) {
        // if the current user is administrator, anything is allowed
        permissions = new CmsPermissionSetCustom(~0);
    } else {
        // otherwise, get the permissions from the access control list
        permissions = getPermissions(dbc, resource, dbc.currentUser());
    }
    // revoke the denied permissions
    permissions.denyPermissions(denied);
    // now check if write permission is granted
    if ((CmsPermissionSet.ACCESS_WRITE.getPermissions() & permissions.getPermissions()) != CmsPermissionSet.ACCESS_WRITE.getPermissions()) {
        // check failed, throw exception
        m_securityManager.checkPermissions(dbc.getRequestContext(), resource, CmsPermissionSet.ACCESS_WRITE, I_CmsPermissionHandler.PERM_DENIED);
    }
    // if we got here write permission is granted on the target
    // remove the old lock
    m_lockManager.removeResource(dbc, resource, true, lockType.isSystem());
    // apply the new lock
    lockResource(dbc, resource, lockType);
}
Also used : CmsLockException(org.opencms.lock.CmsLockException) CmsPermissionSetCustom(org.opencms.security.CmsPermissionSetCustom) CmsLock(org.opencms.lock.CmsLock)

Example 4 with CmsLockException

use of org.opencms.lock.CmsLockException in project opencms-core by alkacon.

the class TestLock method testLockRequired.

/**
 * Ensures that a lock is required for all write/control operations.<p>
 *
 * @throws Throwable if something goes wrong
 */
public void testLockRequired() throws Throwable {
    CmsObject cms = getCmsObject();
    echo("Testing if a lock is required for write/control operations");
    String source = "/index.html";
    storeResources(cms, source);
    long timestamp = System.currentTimeMillis();
    // make sure source is not locked
    assertLock(cms, source, CmsLockType.UNLOCKED);
    CmsFile file = cms.readFile(source);
    boolean needLock;
    needLock = false;
    try {
        cms.setDateLastModified(source, timestamp, false);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Touch operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.deleteResource(source, CmsResource.DELETE_PRESERVE_SIBLINGS);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Delete operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.writeFile(file);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Write operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.moveResource(source, "index_dest.html");
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Move operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.writePropertyObject(source, new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, "New title", null));
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Write property operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        List properties = new ArrayList();
        properties.add(new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, "New title 2", null));
        cms.writePropertyObjects(source, properties);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Write property list operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.chflags(source, 1234);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Change flags operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.chtype(source, CmsResourceTypePlain.getStaticTypeId());
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Change type operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.replaceResource(source, CmsResourceTypePlain.getStaticTypeId(), "Kaputt".getBytes(), null);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Replace operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        CmsPermissionSet permissions = new CmsPermissionSet(CmsPermissionSet.PERMISSION_WRITE, CmsPermissionSet.PERMISSION_READ);
        cms.chacc(source, I_CmsPrincipal.PRINCIPAL_GROUP, OpenCms.getDefaultUsers().getGroupAdministrators(), permissions.getAllowedPermissions(), permissions.getDeniedPermissions(), CmsAccessControlEntry.ACCESS_FLAGS_OVERWRITE);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Change permissions operation on resource permitted without a lock on the current user!");
    }
    needLock = false;
    try {
        cms.undeleteResource(source, true);
    } catch (CmsLockException e) {
        // must throw a security exception because resource is not locked
        needLock = true;
    }
    if (!needLock) {
        fail("Unlock operation on resource permitted without a lock on the current user!");
    }
    // make sure original resource is unchanged
    assertFilter(cms, source, OpenCmsTestResourceFilter.FILTER_EQUAL);
    // now perform a delete operation with lock
    cms.lockResource(source);
    cms.deleteResource(source, CmsResource.DELETE_PRESERVE_SIBLINGS);
    // now undelete the resource
    cms.lockResource(source);
    cms.undoChanges(source, CmsResource.UNDO_CONTENT_RECURSIVE);
    cms.unlockResource(source);
    // make sure original resource is still unchanged
    assertFilter(cms, source, OpenCmsTestResourceFilter.FILTER_UNDOCHANGES_ALL);
}
Also used : CmsLockException(org.opencms.lock.CmsLockException) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) CmsPermissionSet(org.opencms.security.CmsPermissionSet)

Example 5 with CmsLockException

use of org.opencms.lock.CmsLockException in project opencms-core by alkacon.

the class CmsUploadBean method createSingleResource.

/**
 * Creates a single resource and returns the new resource.<p>
 *
 * @param cms the CMS context to use
 * @param fileName the name of the resource to create
 * @param targetFolder the folder to store the new resource
 * @param content the content of the resource to create
 *
 * @return the new resource
 *
 * @throws CmsException if something goes wrong
 * @throws CmsLoaderException if something goes wrong
 * @throws CmsDbSqlException if something goes wrong
 */
@SuppressWarnings("deprecation")
private CmsResource createSingleResource(CmsObject cms, String fileName, String targetFolder, byte[] content) throws CmsException, CmsLoaderException, CmsDbSqlException {
    String newResname = getNewResourceName(cms, fileName, targetFolder);
    CmsResource createdResource = null;
    // determine Title property value to set on new resource
    String title = fileName;
    if (title.lastIndexOf('.') != -1) {
        title = title.substring(0, title.lastIndexOf('.'));
    }
    // fileName really shouldn't contain the full path, but for some reason it does sometimes when the client is
    // running on IE7, so we eliminate anything before and including the last slash or backslash in the title
    // before setting it as a property.
    int backslashIndex = title.lastIndexOf('\\');
    if (backslashIndex != -1) {
        title = title.substring(backslashIndex + 1);
    }
    int slashIndex = title.lastIndexOf('/');
    if (slashIndex != -1) {
        title = title.substring(slashIndex + 1);
    }
    List<CmsProperty> properties = new ArrayList<CmsProperty>(1);
    CmsProperty titleProp = new CmsProperty();
    titleProp.setName(CmsPropertyDefinition.PROPERTY_TITLE);
    if (OpenCms.getWorkplaceManager().isDefaultPropertiesOnStructure()) {
        titleProp.setStructureValue(title);
    } else {
        titleProp.setResourceValue(title);
    }
    properties.add(titleProp);
    int plainId = OpenCms.getResourceManager().getResourceType(CmsResourceTypePlain.getStaticTypeName()).getTypeId();
    if (!cms.existsResource(newResname, CmsResourceFilter.IGNORE_EXPIRATION)) {
        try {
            // create the resource
            int resTypeId = OpenCms.getResourceManager().getDefaultTypeForName(newResname).getTypeId();
            createdResource = cms.createResource(newResname, resTypeId, content, properties);
            try {
                cms.unlockResource(newResname);
            } catch (CmsLockException e) {
                LOG.info("Couldn't unlock uploaded file", e);
            }
        } catch (CmsSecurityException e) {
            // in case of not enough permissions, try to create a plain text file
            createdResource = cms.createResource(newResname, plainId, content, properties);
            cms.unlockResource(newResname);
        } catch (CmsDbSqlException sqlExc) {
            // SQL error, probably the file is too large for the database settings, delete file
            cms.lockResource(newResname);
            cms.deleteResource(newResname, CmsResource.DELETE_PRESERVE_SIBLINGS);
            throw sqlExc;
        } catch (OutOfMemoryError e) {
            // the file is to large try to clear up
            cms.lockResource(newResname);
            cms.deleteResource(newResname, CmsResource.DELETE_PRESERVE_SIBLINGS);
            throw e;
        }
    } else {
        // if the resource already exists, replace it
        CmsResource res = cms.readResource(newResname, CmsResourceFilter.ALL);
        boolean wasLocked = false;
        try {
            if (!cms.getLock(res).isOwnedBy(cms.getRequestContext().getCurrentUser())) {
                cms.lockResource(res);
                wasLocked = true;
            }
            CmsFile file = cms.readFile(res);
            byte[] contents = file.getContents();
            try {
                cms.replaceResource(newResname, res.getTypeId(), content, null);
                createdResource = res;
            } catch (CmsDbSqlException sqlExc) {
                // SQL error, probably the file is too large for the database settings, restore content
                file.setContents(contents);
                cms.writeFile(file);
                throw sqlExc;
            } catch (OutOfMemoryError e) {
                // the file is to large try to clear up
                file.setContents(contents);
                cms.writeFile(file);
                throw e;
            }
        } finally {
            if (wasLocked) {
                cms.unlockResource(res);
            }
        }
    }
    return createdResource;
}
Also used : ArrayList(java.util.ArrayList) CmsFile(org.opencms.file.CmsFile) CmsSecurityException(org.opencms.security.CmsSecurityException) CmsResource(org.opencms.file.CmsResource) CmsDbSqlException(org.opencms.db.CmsDbSqlException) CmsLockException(org.opencms.lock.CmsLockException) CmsProperty(org.opencms.file.CmsProperty)

Aggregations

CmsLockException (org.opencms.lock.CmsLockException)22 CmsResource (org.opencms.file.CmsResource)16 CmsObject (org.opencms.file.CmsObject)12 CmsException (org.opencms.main.CmsException)8 ArrayList (java.util.ArrayList)7 CmsUUID (org.opencms.util.CmsUUID)7 CmsLockActionRecord (org.opencms.lock.CmsLockActionRecord)6 CmsProperty (org.opencms.file.CmsProperty)4 CmsLock (org.opencms.lock.CmsLock)4 HashSet (java.util.HashSet)3 CmsVfsResourceNotFoundException (org.opencms.file.CmsVfsResourceNotFoundException)3 List (java.util.List)2 CmsExportPoint (org.opencms.db.CmsExportPoint)2 CmsLogEntry (org.opencms.db.log.CmsLogEntry)2 CmsVfsException (org.opencms.file.CmsVfsException)2 CmsVfsResourceAlreadyExistsException (org.opencms.file.CmsVfsResourceAlreadyExistsException)2 I_CmsResource (org.opencms.file.I_CmsResource)2 CmsMessageContainer (org.opencms.i18n.CmsMessageContainer)2 CmsEvent (org.opencms.main.CmsEvent)2 IOException (java.io.IOException)1