Search in sources :

Example 11 with LockInfo

use of org.olat.core.util.vfs.lock.LockInfo in project OpenOLAT by OpenOLAT.

the class WebdavStatus method doLock.

/**
 * LOCK Method.
 */
public void doLock(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    if (isLocked(req)) {
        resp.sendError(WebdavStatus.SC_LOCKED);
        return;
    }
    final String path = getRelativePath(req);
    final WebResourceRoot resources = getResources(req);
    if (!resources.canWrite(path)) {
        resp.sendError(WebdavStatus.SC_FORBIDDEN);
        return;
    }
    UserSession usess = webDAVManager.getUserSession(req);
    LockInfo lock = new LockInfo(usess.getIdentity().getKey(), true, false);
    // Parsing lock request
    // Parsing depth header
    String depthStr = req.getHeader("Depth");
    if (depthStr == null) {
        lock.setDepth(maxDepth);
    } else {
        if (depthStr.equals("0")) {
            lock.setDepth(0);
        } else {
            lock.setDepth(maxDepth);
        }
    }
    if (log.isDebug()) {
        log.debug("Lock the ressource: " + path + " with depth:" + lock.getDepth());
    }
    // Parsing timeout header
    int lockDuration = DEFAULT_TIMEOUT;
    String lockDurationStr = req.getHeader("Timeout");
    if (lockDurationStr == null) {
        lockDuration = DEFAULT_TIMEOUT;
    } else {
        int commaPos = lockDurationStr.indexOf(",");
        // If multiple timeouts, just use the first
        if (commaPos != -1) {
            lockDurationStr = lockDurationStr.substring(0, commaPos);
        }
        if (lockDurationStr.startsWith("Second-")) {
            lockDuration = (new Integer(lockDurationStr.substring(7))).intValue();
        } else {
            if (lockDurationStr.equalsIgnoreCase("infinity")) {
                lockDuration = MAX_TIMEOUT;
            } else {
                try {
                    lockDuration = (new Integer(lockDurationStr)).intValue();
                } catch (NumberFormatException e) {
                    lockDuration = MAX_TIMEOUT;
                }
            }
        }
        if (lockDuration == 0) {
            lockDuration = DEFAULT_TIMEOUT;
        }
        if (lockDuration > MAX_TIMEOUT) {
            lockDuration = MAX_TIMEOUT;
        }
    }
    lock.setExpiresAt(System.currentTimeMillis() + (lockDuration * 1000));
    int lockRequestType = LOCK_CREATION;
    Node lockInfoNode = null;
    DocumentBuilder documentBuilder = getDocumentBuilder(req);
    try {
        Document document = documentBuilder.parse(new InputSource(req.getInputStream()));
        // Get the root element of the document
        Element rootElement = document.getDocumentElement();
        lockInfoNode = rootElement;
    } catch (IOException e) {
        lockRequestType = LOCK_REFRESH;
    } catch (SAXException e) {
        lockRequestType = LOCK_REFRESH;
    }
    if (lockInfoNode != null) {
        // Reading lock information
        NodeList childList = lockInfoNode.getChildNodes();
        StringWriter strWriter = null;
        DOMWriter domWriter = null;
        Node lockScopeNode = null;
        Node lockTypeNode = null;
        Node lockOwnerNode = null;
        for (int i = 0; i < childList.getLength(); i++) {
            Node currentNode = childList.item(i);
            switch(currentNode.getNodeType()) {
                case Node.TEXT_NODE:
                    break;
                case Node.ELEMENT_NODE:
                    String nodeName = currentNode.getNodeName();
                    if (nodeName.endsWith("lockscope")) {
                        lockScopeNode = currentNode;
                    }
                    if (nodeName.endsWith("locktype")) {
                        lockTypeNode = currentNode;
                    }
                    if (nodeName.endsWith("owner")) {
                        lockOwnerNode = currentNode;
                    }
                    break;
            }
        }
        if (lockScopeNode != null) {
            childList = lockScopeNode.getChildNodes();
            for (int i = 0; i < childList.getLength(); i++) {
                Node currentNode = childList.item(i);
                switch(currentNode.getNodeType()) {
                    case Node.TEXT_NODE:
                        break;
                    case Node.ELEMENT_NODE:
                        String tempScope = currentNode.getNodeName();
                        if (tempScope.indexOf(':') != -1) {
                            lock.setScope(tempScope.substring(tempScope.indexOf(':') + 1));
                        } else {
                            lock.setScope(tempScope);
                        }
                        break;
                }
            }
            if (lock.getScope() == null) {
                // Bad request
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
            }
        } else {
            // Bad request
            resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
        }
        if (lockTypeNode != null) {
            childList = lockTypeNode.getChildNodes();
            for (int i = 0; i < childList.getLength(); i++) {
                Node currentNode = childList.item(i);
                switch(currentNode.getNodeType()) {
                    case Node.TEXT_NODE:
                        break;
                    case Node.ELEMENT_NODE:
                        String tempType = currentNode.getNodeName();
                        if (tempType.indexOf(':') != -1) {
                            lock.setType(tempType.substring(tempType.indexOf(':') + 1));
                        } else {
                            lock.setType(tempType);
                        }
                        break;
                }
            }
            if (lock.getType() == null) {
                // Bad request
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
            }
        } else {
            // Bad request
            resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
        }
        if (lockOwnerNode != null) {
            childList = lockOwnerNode.getChildNodes();
            for (int i = 0; i < childList.getLength(); i++) {
                Node currentNode = childList.item(i);
                switch(currentNode.getNodeType()) {
                    case Node.TEXT_NODE:
                        lock.setOwner(lock.getOwner() + currentNode.getNodeValue());
                        break;
                    case Node.ELEMENT_NODE:
                        strWriter = new StringWriter();
                        domWriter = new DOMWriter(strWriter, true);
                        domWriter.print(currentNode);
                        lock.setOwner(lock.getOwner() + strWriter.toString());
                        break;
                }
            }
            if (lock.getOwner() == null) {
                // Bad request
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
            }
        } else {
            lock.setOwner("");
        }
    }
    final WebResource resource = resources.getResource(path);
    lock.setWebResource(resource);
    Iterator<LockInfo> locksList = null;
    if (lockRequestType == LOCK_CREATION) {
        // Generating lock id
        String lockToken = lockManager.generateLockToken(lock, usess.getIdentity().getKey());
        if (resource.isDirectory() && lock.getDepth() == maxDepth) {
            // Locking a collection (and all its member resources)
            // Checking if a child resource of this collection is
            // already locked
            Vector<String> lockPaths = new Vector<String>();
            locksList = lockManager.getCollectionLocks();
            while (locksList.hasNext()) {
                LockInfo currentLock = locksList.next();
                if (currentLock.hasExpired()) {
                    WebResource currentLockedResource = resources.getResource(currentLock.getWebPath());
                    lockManager.removeResourceLock(currentLockedResource);
                    continue;
                }
                if ((currentLock.getWebPath().startsWith(lock.getWebPath())) && ((currentLock.isExclusive()) || (lock.isExclusive()))) {
                    // A child collection of this collection is locked
                    lockPaths.addElement(currentLock.getWebPath());
                }
            }
            locksList = lockManager.getResourceLocks();
            while (locksList.hasNext()) {
                LockInfo currentLock = locksList.next();
                if (currentLock.hasExpired()) {
                    WebResource currentLockedResource = resources.getResource(currentLock.getWebPath());
                    lockManager.removeResourceLock(currentLockedResource);
                    continue;
                }
                if ((currentLock.getWebPath().startsWith(lock.getWebPath())) && ((currentLock.isExclusive()) || (lock.isExclusive()))) {
                    // A child resource of this collection is locked
                    lockPaths.addElement(currentLock.getWebPath());
                }
            }
            if (!lockPaths.isEmpty()) {
                // One of the child paths was locked
                // We generate a multistatus error report
                Enumeration<String> lockPathsList = lockPaths.elements();
                resp.setStatus(WebdavStatus.SC_CONFLICT);
                XMLWriter generatedXML = new XMLWriter();
                generatedXML.writeXMLHeader();
                generatedXML.writeElement("D", DEFAULT_NAMESPACE, "multistatus", XMLWriter.OPENING);
                while (lockPathsList.hasMoreElements()) {
                    generatedXML.writeElement("D", "response", XMLWriter.OPENING);
                    generatedXML.writeElement("D", "href", XMLWriter.OPENING);
                    generatedXML.writeText(lockPathsList.nextElement());
                    generatedXML.writeElement("D", "href", XMLWriter.CLOSING);
                    generatedXML.writeElement("D", "status", XMLWriter.OPENING);
                    generatedXML.writeText("HTTP/1.1 " + WebdavStatus.SC_LOCKED + " " + WebdavStatus.getStatusText(WebdavStatus.SC_LOCKED));
                    generatedXML.writeElement("D", "status", XMLWriter.CLOSING);
                    generatedXML.writeElement("D", "response", XMLWriter.CLOSING);
                }
                generatedXML.writeElement("D", "multistatus", XMLWriter.CLOSING);
                Writer writer = resp.getWriter();
                writer.write(generatedXML.toString());
                writer.close();
                return;
            }
            boolean addLock = true;
            // Checking if there is already a shared lock on this path
            locksList = lockManager.getCollectionLocks();
            while (locksList.hasNext()) {
                LockInfo currentLock = locksList.next();
                if (currentLock.getWebPath().equals(lock.getWebPath())) {
                    if (currentLock.isExclusive()) {
                        resp.sendError(WebdavStatus.SC_LOCKED);
                        return;
                    } else {
                        if (lock.isExclusive()) {
                            resp.sendError(WebdavStatus.SC_LOCKED);
                            return;
                        }
                    }
                    currentLock.addToken(lockToken);
                    lock = currentLock;
                    addLock = false;
                }
            }
            if (addLock) {
                lock.addToken(lockToken);
                lockManager.addCollectionLock(lock);
            }
        } else {
            // Locking a single resource
            // Retrieving an already existing lock on that resource
            WebResource lockedResource = resources.getResource(lock.getWebPath());
            LockInfo presentLock = lockManager.getResourceLock(lockedResource);
            if (presentLock != null) {
                if ((presentLock.isExclusive()) || (lock.isExclusive())) {
                    // If either lock is exclusive, the lock can't be
                    // granted
                    resp.sendError(WebdavStatus.SC_PRECONDITION_FAILED);
                    return;
                } else {
                    presentLock.setWebDAVLock(true);
                    presentLock.addToken(lockToken);
                    lock = presentLock;
                }
            } else {
                lock.addToken(lockToken);
                lockManager.putResourceLock(lockedResource, lock);
                // Checking if a resource exists at this path
                if (!resource.exists()) {
                    // "Creating" a lock-null resource
                    int slash = lock.getWebPath().lastIndexOf('/');
                    String parentPath = lock.getWebPath().substring(0, slash);
                    WebResource parentResource = resources.getResource(parentPath);
                    Vector<String> lockNulls = lockManager.getLockNullResource(parentResource);
                    if (lockNulls == null) {
                        lockNulls = new Vector<String>();
                        lockManager.putLockNullResource(parentPath, lockNulls);
                    }
                    lockNulls.addElement(lock.getWebPath());
                }
                // Add the Lock-Token header as by RFC 2518 8.10.1
                // - only do this for newly created locks
                resp.addHeader("Lock-Token", "<opaquelocktoken:" + lockToken + ">");
            }
        }
    }
    if (lockRequestType == LOCK_REFRESH) {
        String ifHeader = req.getHeader("If");
        if (ifHeader == null)
            ifHeader = "";
        // Checking resource locks
        LockInfo toRenew = lockManager.getResourceLock(resource);
        if (toRenew != null) {
            // At least one of the tokens of the locks must have been given
            Iterator<String> tokenList = toRenew.tokens();
            while (tokenList.hasNext()) {
                String token = tokenList.next();
                if (ifHeader.indexOf(token) != -1) {
                    toRenew.setExpiresAt(lock.getExpiresAt());
                    toRenew.setWebDAVLock(true);
                    lock = toRenew;
                }
            }
        }
        // Checking inheritable collection locks
        Iterator<LockInfo> collectionLocksList = lockManager.getCollectionLocks();
        while (collectionLocksList.hasNext()) {
            toRenew = collectionLocksList.next();
            if (path.equals(toRenew.getWebPath())) {
                Iterator<String> tokenList = toRenew.tokens();
                while (tokenList.hasNext()) {
                    String token = tokenList.next();
                    if (ifHeader.indexOf(token) != -1) {
                        toRenew.setExpiresAt(lock.getExpiresAt());
                        lock = toRenew;
                    }
                }
            }
        }
    }
    // Set the status, then generate the XML response containing
    // the lock information
    XMLWriter generatedXML = new XMLWriter();
    generatedXML.writeXMLHeader();
    generatedXML.writeElement("D", DEFAULT_NAMESPACE, "prop", XMLWriter.OPENING);
    generatedXML.writeElement("D", "lockdiscovery", XMLWriter.OPENING);
    lock.toXML(generatedXML);
    generatedXML.writeElement("D", "lockdiscovery", XMLWriter.CLOSING);
    generatedXML.writeElement("D", "prop", XMLWriter.CLOSING);
    resp.setStatus(WebdavStatus.SC_OK);
    resp.setContentType("text/xml; charset=UTF-8");
    Writer writer = resp.getWriter();
    writer.write(generatedXML.toString());
    writer.close();
}
Also used : InputSource(org.xml.sax.InputSource) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) Document(org.w3c.dom.Document) SAXException(org.xml.sax.SAXException) StringWriter(java.io.StringWriter) UserSession(org.olat.core.util.UserSession) Vector(java.util.Vector) NodeList(org.w3c.dom.NodeList) IOException(java.io.IOException) DocumentBuilder(javax.xml.parsers.DocumentBuilder) LockInfo(org.olat.core.util.vfs.lock.LockInfo) PrintWriter(java.io.PrintWriter) Writer(java.io.Writer) StringWriter(java.io.StringWriter)

Example 12 with LockInfo

use of org.olat.core.util.vfs.lock.LockInfo in project OpenOLAT by OpenOLAT.

the class MetaInfoController method initForm.

@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
    setFormTitle("mf.metadata.title");
    setFormContextHelp("Folders#_metadata");
    // filename
    uifactory.addStaticTextElement("mf.filename", item.getName(), formLayout);
    MetaInfo meta = item == null ? null : CoreSpringFactory.getImpl(MetaInfoFactory.class).createMetaInfoFor((OlatRelPathImpl) item);
    // title
    String titleVal = StringHelper.escapeHtml(meta != null ? meta.getTitle() : null);
    uifactory.addStaticTextElement("mf.title", titleVal, formLayout);
    // comment/description
    String commentVal = StringHelper.xssScan(meta != null ? meta.getComment() : null);
    uifactory.addStaticTextElement("mf.comment", commentVal, formLayout);
    // license
    if (licenseModule.isEnabled(licenseHandler)) {
        MetaInfoFactory metaInfoFactory = CoreSpringFactory.getImpl(MetaInfoFactory.class);
        License license = metaInfoFactory.getOrCreateLicense(meta, getIdentity());
        boolean isNoLicense = !licenseService.isNoLicense(license.getLicenseType());
        boolean isFreetext = licenseService.isFreetext(license.getLicenseType());
        licenseEl = uifactory.addStaticTextElement("mf.license", LicenseUIFactory.translate(license.getLicenseType(), getLocale()), formLayout);
        if (isNoLicense) {
            licensorEl = uifactory.addStaticTextElement("mf.licensor", license.getLicensor(), formLayout);
        }
        if (isFreetext) {
            licenseFreetextEl = uifactory.addStaticTextElement("mf.freetext", LicenseUIFactory.getFormattedLicenseText(license), formLayout);
        }
        ;
        // creator
        String creatorVal = StringHelper.escapeHtml(meta != null ? meta.getCreator() : null);
        creator = uifactory.addStaticTextElement("mf.creator", creatorVal, formLayout);
        // publisher
        String publisherVal = StringHelper.escapeHtml(meta != null ? meta.getPublisher() : null);
        publisher = uifactory.addStaticTextElement("mf.publisher", publisherVal, formLayout);
        // source/origin
        String sourceVal = StringHelper.escapeHtml(meta != null ? meta.getSource() : null);
        sourceEl = uifactory.addStaticTextElement("mf.source", sourceVal, formLayout);
        // city
        String cityVal = StringHelper.escapeHtml(meta != null ? meta.getCity() : null);
        city = uifactory.addStaticTextElement("mf.city", cityVal, formLayout);
        String[] pubDate = (meta != null ? meta.getPublicationDate() : new String[] { "", "" });
        String publicationDate = new StringBuilder().append(translate("mf.month")).append(pubDate[0]).append(", ").append(translate("mf.year")).append(pubDate[1]).toString();
        publicationDateEl = uifactory.addStaticTextElement("mf.publishDate", publicationDate, formLayout);
        // number of pages
        String pageVal = StringHelper.escapeHtml(meta != null ? meta.getPages() : null);
        pages = uifactory.addStaticTextElement("mf.pages", pageVal, formLayout);
        // language
        String langVal = StringHelper.escapeHtml(meta != null ? meta.getLanguage() : null);
        language = uifactory.addStaticTextElement("mf.language", langVal, formLayout);
        // url/link
        String urlVal = StringHelper.escapeHtml(meta != null ? meta.getUrl() : null);
        url = uifactory.addStaticTextElement("mf.url", urlVal, formLayout);
    }
    /* static fields */
    String sizeText, typeText;
    if (item instanceof VFSLeaf) {
        sizeText = Formatter.formatBytes(((VFSLeaf) item).getSize());
        typeText = FolderHelper.extractFileType(item.getName(), getLocale());
    } else {
        sizeText = "-";
        typeText = translate("mf.type.directory");
    }
    // Targets to hide
    metaFields = new HashSet<>();
    metaFields.add(creator);
    metaFields.add(publisher);
    metaFields.add(sourceEl);
    metaFields.add(city);
    metaFields.add(publicationDateEl);
    metaFields.add(pages);
    metaFields.add(language);
    metaFields.add(url);
    if (licenseEl != null) {
        metaFields.add(licenseEl);
    }
    if (licensorEl != null) {
        metaFields.add(licensorEl);
    }
    if (licenseFreetextEl != null) {
        metaFields.add(licenseFreetextEl);
    }
    if (!hasMetadata(meta)) {
        moreMetaDataLink = uifactory.addFormLink("mf.more.meta.link", formLayout, Link.LINK_CUSTOM_CSS);
        setMetaFieldsVisible(false);
    }
    if (meta != null && !meta.isDirectory()) {
        LockInfo lock = vfsLockManager.getLock(item);
        // locked
        String lockedTitle = getTranslator().translate("mf.locked");
        String unlockedTitle = getTranslator().translate("mf.unlocked");
        locked = uifactory.addRadiosHorizontal("locked", "mf.locked", formLayout, new String[] { "lock", "unlock" }, new String[] { lockedTitle, unlockedTitle });
        if (vfsLockManager.isLocked(item)) {
            locked.select("lock", true);
        } else {
            locked.select("unlock", true);
        }
        locked.setEnabled(false);
        // locked by
        String lockedDetails = "";
        if (lock != null) {
            String user = userManager.getUserDisplayName(lock.getLockedBy());
            user = StringHelper.escapeHtml(user);
            String date = "";
            if (lock.getCreationDate() != null) {
                date = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()).format(lock.getCreationDate());
            }
            lockedDetails = getTranslator().translate("mf.locked.description", new String[] { user, date });
            if (lock.isWebDAVLock()) {
                lockedDetails += " (WebDAV)";
            }
        } else {
            lockedDetails = getTranslator().translate("mf.unlocked.description");
        }
        uifactory.addStaticTextElement("mf.lockedBy", lockedDetails, formLayout);
        // username
        String author = StringHelper.escapeHtml(meta.getHTMLFormattedAuthor());
        uifactory.addStaticTextElement("mf.author", author, formLayout);
        // filesize
        uifactory.addStaticTextElement("mf.size", StringHelper.escapeHtml(sizeText), formLayout);
        // last modified date
        String lastModified = StringHelper.formatLocaleDate(meta.getLastModified(), getLocale());
        uifactory.addStaticTextElement("mf.lastModified", lastModified, formLayout);
        // file type
        uifactory.addStaticTextElement("mf.type", StringHelper.escapeHtml(typeText), formLayout);
        String downloads = String.valueOf(meta.getDownloadCount());
        uifactory.addStaticTextElement("mf.downloads", downloads, formLayout);
    } else {
        setMetaFieldsVisible(false);
        if (moreMetaDataLink != null) {
            moreMetaDataLink.setVisible(false);
        }
    }
    boolean xssErrors = false;
    if (item != null) {
        xssErrors = StringHelper.xssScanForErrors(item.getName());
    }
    if (StringHelper.containsNonWhitespace(resourceUrl) && !xssErrors) {
        String externalUrlPage = velocity_root + "/external_url.html";
        FormLayoutContainer extUrlCont = FormLayoutContainer.createCustomFormLayout("external.url", getTranslator(), externalUrlPage);
        extUrlCont.setLabel("external.url", null);
        extUrlCont.contextPut("resourceUrl", resourceUrl);
        extUrlCont.setRootForm(mainForm);
        formLayout.add(extUrlCont);
    }
    // cancel buttons
    final FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator());
    formLayout.add(buttonLayout);
    uifactory.addFormCancelButton("cancel", buttonLayout, ureq, getWindowControl());
}
Also used : VFSLeaf(org.olat.core.util.vfs.VFSLeaf) OlatRelPathImpl(org.olat.core.util.vfs.OlatRelPathImpl) License(org.olat.core.commons.services.license.License) FormLayoutContainer(org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer) LockInfo(org.olat.core.util.vfs.lock.LockInfo)

Example 13 with LockInfo

use of org.olat.core.util.vfs.lock.LockInfo in project openolat by klemens.

the class WebDAVCommandsTest method testLock_guilike_lockedWithWebdAV.

/**
 * @throws IOException
 * @throws URISyntaxException
 */
@Test
public void testLock_guilike_lockedWithWebdAV() throws IOException, URISyntaxException {
    // create a user
    Identity user = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-2c-" + UUID.randomUUID().toString());
    // create a file
    String publicPath = FolderConfig.getUserHomes() + "/" + user.getName() + "/public";
    VFSContainer vfsPublic = new OlatRootFolderImpl(publicPath, null);
    VFSItem item = createFile(vfsPublic, "test.txt");
    // lock the item with WebDAV
    WebDAVConnection conn = new WebDAVConnection();
    conn.setCredentials(user.getName(), "A6B7C8");
    // author check file
    URI textUri = conn.getBaseURI().path("webdav").path("home").path("public").path("test.txt").build();
    String textPropfind = conn.propfind(textUri, 0);
    log.info(textPropfind);
    // author lock the file
    String lockToken = conn.lock(textUri, UUID.randomUUID().toString());
    Assert.assertNotNull(lockToken);
    // check vfs lock
    Roles adminRoles = new Roles(true, false, false, false, false, false, false);
    boolean lockedForMe = lockManager.isLockedForMe(item, user, adminRoles);
    Assert.assertTrue(lockedForMe);
    LockInfo lock = lockManager.getLock(item);
    Assert.assertNotNull(lock);
    Assert.assertNotNull(lock.getScope());
    Assert.assertNotNull(lock.getType());
    Assert.assertNotNull(lock.getOwner());
    Assert.assertTrue(lock.getOwner().length() > 0);
    Assert.assertFalse(lock.isVfsLock());
    Assert.assertTrue(lock.isWebDAVLock());
    Assert.assertEquals(user.getKey(), lock.getLockedBy());
    Assert.assertEquals(1, lock.getTokensSize());
    // try to unlock which should not be possible
    boolean unlocked = lockManager.unlock(item, user, adminRoles);
    Assert.assertFalse(unlocked);
    // check that nothing changed
    LockInfo lockAfterUnlock = lockManager.getLock(item);
    Assert.assertNotNull(lockAfterUnlock);
    Assert.assertNotNull(lockAfterUnlock.getScope());
    Assert.assertNotNull(lockAfterUnlock.getType());
    Assert.assertNotNull(lockAfterUnlock.getOwner());
    Assert.assertTrue(lockAfterUnlock.getOwner().length() > 0);
    Assert.assertFalse(lockAfterUnlock.isVfsLock());
    Assert.assertTrue(lockAfterUnlock.isWebDAVLock());
    Assert.assertEquals(user.getKey(), lockAfterUnlock.getLockedBy());
    Assert.assertEquals(1, lock.getTokensSize());
    IOUtils.closeQuietly(conn);
}
Also used : OlatRootFolderImpl(org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl) VFSContainer(org.olat.core.util.vfs.VFSContainer) VFSItem(org.olat.core.util.vfs.VFSItem) GroupRoles(org.olat.basesecurity.GroupRoles) Roles(org.olat.core.id.Roles) LockInfo(org.olat.core.util.vfs.lock.LockInfo) Identity(org.olat.core.id.Identity) URI(java.net.URI) Test(org.junit.Test) CoursePublishTest(org.olat.restapi.CoursePublishTest)

Example 14 with LockInfo

use of org.olat.core.util.vfs.lock.LockInfo in project openolat by klemens.

the class WebDAVCommandsTest method testLock_propfind_lockedInOpenOLAT.

/**
 * @throws IOException
 * @throws URISyntaxException
 */
@Test
public void testLock_propfind_lockedInOpenOLAT() throws IOException, URISyntaxException {
    // create a user
    Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-4-" + UUID.randomUUID().toString());
    Identity assistant = JunitTestHelper.createAndPersistIdentityAsAuthor("webdav-5-" + UUID.randomUUID().toString());
    RepositoryEntry re = deployTestCourse(author, assistant);
    ICourse course = CourseFactory.loadCourse(re.getOlatResource());
    Assert.assertNotNull(course);
    // the assistant lock the file as in OpenOLAT GUI
    VFSContainer folderContainer = course.getCourseFolderContainer();
    createFile(folderContainer, "tolock.txt");
    VFSItem itemToLock = folderContainer.resolve("tolock.txt");
    Assert.assertNotNull(itemToLock);
    boolean locked = lockManager.lock(itemToLock, assistant, new Roles(false, false, false, true, false, false, false));
    Assert.assertTrue(locked);
    // author make a propfind in the locked resource
    WebDAVConnection conn = new WebDAVConnection();
    conn.setCredentials(author.getName(), "A6B7C8");
    URI toLockUri = conn.getBaseURI().path("webdav").path("coursefolders").path("_other").path("Kurs").path("tolock.txt").build();
    String propfindXml = conn.propfind(toLockUri, 2);
    // not really a test
    Assert.assertTrue(propfindXml.indexOf("<D:lockscope><D:exclusive/></D:lockscope>") > 0);
    Assert.assertTrue(propfindXml.indexOf("/Identity/" + assistant.getKey() + "</D:owner>") > 0);
    Assert.assertTrue(propfindXml.indexOf("<D:locktoken><D:href>opaquelocktoken:") > 0);
    LockInfo lock = lockManager.getLock(itemToLock);
    Assert.assertNotNull(lock);
    Assert.assertNotNull(lock.getScope());
    Assert.assertNotNull(lock.getType());
    Assert.assertNotNull(lock.getOwner());
    Assert.assertTrue(lock.getOwner().length() > 0);
    Assert.assertTrue(lock.isVfsLock());
    Assert.assertFalse(lock.isWebDAVLock());
    Assert.assertEquals(assistant.getKey(), lock.getLockedBy());
    Assert.assertEquals(1, lock.getTokensSize());
    IOUtils.closeQuietly(conn);
}
Also used : VFSContainer(org.olat.core.util.vfs.VFSContainer) VFSItem(org.olat.core.util.vfs.VFSItem) ICourse(org.olat.course.ICourse) GroupRoles(org.olat.basesecurity.GroupRoles) Roles(org.olat.core.id.Roles) LockInfo(org.olat.core.util.vfs.lock.LockInfo) RepositoryEntry(org.olat.repository.RepositoryEntry) Identity(org.olat.core.id.Identity) URI(java.net.URI) Test(org.junit.Test) CoursePublishTest(org.olat.restapi.CoursePublishTest)

Example 15 with LockInfo

use of org.olat.core.util.vfs.lock.LockInfo in project openolat by klemens.

the class ListRenderer method appendRenderedFile.

// getRenderedDirectoryContent
/**
 * Render a single file or folder.
 *
 * @param	f			The file or folder to render
 * @param	sb		StringOutput to append generated html code
 */
private void appendRenderedFile(FolderComponent fc, VFSItem child, String currentContainerPath, StringOutput sb, URLBuilder ubu, Translator translator, boolean iframePostEnabled, boolean canContainerVersion, int pos) {
    // assume full access unless security callback tells us something different.
    boolean canWrite = child.getParentContainer().canWrite() == VFSConstants.YES;
    // special case: virtual folders are always read only. parent of child =! the current container
    canWrite = canWrite && !(fc.getCurrentContainer() instanceof VirtualContainer);
    boolean isAbstract = (child instanceof AbstractVirtualContainer);
    Versions versions = null;
    if (canContainerVersion && child instanceof Versionable) {
        Versionable versionable = (Versionable) child;
        if (versionable.getVersions().isVersioned()) {
            versions = versionable.getVersions();
        }
    }
    boolean canVersion = versions != null && !versions.getRevisions().isEmpty();
    boolean canAddToEPortfolio = FolderConfig.isEPortfolioAddEnabled();
    VFSLeaf leaf = null;
    if (child instanceof VFSLeaf) {
        leaf = (VFSLeaf) child;
    }
    // if not a leaf, it must be a container...
    boolean isContainer = (leaf == null);
    MetaInfo metaInfo = null;
    if (child instanceof MetaTagged) {
        metaInfo = ((MetaTagged) child).getMetaInfo();
    }
    boolean lockedForUser = lockManager.isLockedForMe(child, fc.getIdentityEnvironnement().getIdentity(), fc.getIdentityEnvironnement().getRoles());
    String name = child.getName();
    boolean xssErrors = StringHelper.xssScanForErrors(name);
    String pathAndName;
    if (xssErrors) {
        pathAndName = null;
    } else {
        pathAndName = currentContainerPath;
        if (pathAndName.length() > 0 && !pathAndName.endsWith("/")) {
            pathAndName += "/";
        }
        pathAndName += name;
    }
    // tr begin
    sb.append("<tr><td>").append("<input type=\"checkbox\" name=\"").append(FileSelection.FORM_ID).append("\" value=\"");
    if (xssErrors) {
        sb.append(StringHelper.escapeHtml(name)).append("\" disabled=\"disabled\"");
    } else {
        sb.append(name).append("\" ");
    }
    sb.append("/> ");
    // browse link pre
    if (xssErrors) {
        sb.append("<i class='o_icon o_icon-fw o_icon_banned'> </i> ");
        sb.append(StringHelper.escapeHtml(name));
        log.error("XSS Scan found something suspicious in: " + child);
    } else {
        sb.append("<a id='o_sel_doc_").append(pos).append("'");
        if (isContainer) {
            // for directories... normal module URIs
            // needs encoding, not done in buildHrefAndOnclick!
            // FIXME: SR: refactor encode: move to ubu.buildHrefAndOnclick
            String pathAndNameEncoded = ubu.encodeUrl(pathAndName);
            ubu.buildHrefAndOnclick(sb, pathAndNameEncoded, iframePostEnabled, false, true);
        } else {
            // for files, add PARAM_SERV command
            sb.append(" href=\"");
            ubu.buildURI(sb, new String[] { PARAM_SERV }, new String[] { "x" }, pathAndName, AJAXFlags.MODE_NORMAL);
            sb.append("\"");
            boolean download = FolderManager.isDownloadForcedFileType(name);
            if (download) {
                sb.append(" download=\"").append(StringHelper.escapeHtml(name)).append("\"");
            } else {
                sb.append(" target=\"_blank\"");
            }
        }
        sb.append(">");
        // icon css
        sb.append("<i class=\"o_icon o_icon-fw ");
        if (isContainer)
            sb.append(CSSHelper.CSS_CLASS_FILETYPE_FOLDER);
        else
            sb.append(CSSHelper.createFiletypeIconCssClassFor(name));
        sb.append("\"></i> ");
        // name
        if (isAbstract)
            sb.append("<i>");
        sb.append(StringHelper.escapeHtml(name));
        if (isAbstract)
            sb.append("</i>");
        sb.append("</a>");
    }
    // file metadata as tooltip
    if (metaInfo != null) {
        boolean hasMeta = false;
        sb.append("<div id='o_sel_doc_tooltip_").append(pos).append("' class='o_bc_meta' style='display:none;'>");
        if (StringHelper.containsNonWhitespace(metaInfo.getTitle())) {
            String title = StringHelper.escapeHtml(metaInfo.getTitle());
            sb.append("<h5>").append(Formatter.escapeDoubleQuotes(title)).append("</h5>");
            hasMeta = true;
        }
        if (StringHelper.containsNonWhitespace(metaInfo.getComment())) {
            sb.append("<div class=\"o_comment\">");
            String comment = StringHelper.escapeHtml(metaInfo.getComment());
            sb.append(Formatter.escapeDoubleQuotes(comment));
            sb.append("</div>");
            hasMeta = true;
        }
        // boolean hasThumbnail = false;
        if (metaInfo.isThumbnailAvailable() && !xssErrors) {
            sb.append("<div class='o_thumbnail' style='background-image:url(");
            ubu.buildURI(sb, new String[] { PARAM_SERV_THUMBNAIL }, new String[] { "x" }, pathAndName, AJAXFlags.MODE_NORMAL);
            sb.append("); background-repeat:no-repeat; background-position:50% 50%;'></div>");
            hasMeta = true;
        // hasThumbnail = true;
        }
        // first try author info from metadata (creator)
        // boolean hasMetaAuthor = false;
        String author = metaInfo.getCreator();
        // fallback use file author (uploader)
        if (StringHelper.containsNonWhitespace(author)) {
        // hasMetaAuthor = true;
        } else {
            author = metaInfo.getAuthor();
            if (!"-".equals(author)) {
                author = UserManager.getInstance().getUserDisplayName(author);
            } else {
                author = null;
            }
        }
        author = StringHelper.escapeHtml(author);
        if (StringHelper.containsNonWhitespace(author)) {
            sb.append("<p class=\"o_author\">").append(Formatter.escapeDoubleQuotes(translator.translate("mf.author")));
            sb.append(": ").append(Formatter.escapeDoubleQuotes(author)).append("</p>");
            hasMeta = true;
        }
        sb.append("</div>");
        if (hasMeta) {
            // render tooltip only when it contains something
            sb.append("<script type='text/javascript'>").append("/* <![CDATA[ */").append("jQuery(function() {\n").append("  jQuery('#o_sel_doc_").append(pos).append("').tooltip({\n").append("	   html: true,\n").append("	   container: 'body',\n").append("    title: function(){ return jQuery('#o_sel_doc_tooltip_").append(pos).append("').html(); }\n").append("  });\n").append("  jQuery('#o_sel_doc_").append(pos).append("').on('click', function(){\n").append("	   jQuery('#o_sel_doc_").append(pos).append("').tooltip('hide');\n").append("  });\n").append("});").append("/* ]]> */").append("</script>");
        }
    }
    sb.append("</td><td>");
    // filesize
    if (!isContainer) {
        // append filesize
        sb.append("<span class='text-muted small'>");
        sb.append(Formatter.formatBytes(leaf.getSize()));
        sb.append("</span>");
    }
    sb.append("</td><td>");
    // last modified
    long lastModified = child.getLastModified();
    sb.append("<span class='text-muted small'>");
    if (lastModified != VFSConstants.UNDEFINED)
        sb.append(DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, translator.getLocale()).format(new Date(lastModified)));
    else
        sb.append("-");
    sb.append("</span></td><td>");
    // license
    if (licensesEnabled) {
        MetaInfoFactory metaInfoFactory = CoreSpringFactory.getImpl(MetaInfoFactory.class);
        License license = metaInfoFactory.getLicense(metaInfo);
        LicenseRenderer licenseRenderer = new LicenseRenderer(translator.getLocale());
        licenseRenderer.render(sb, license, true);
        sb.append("</td><td>");
    }
    if (canContainerVersion) {
        if (canVersion)
            if (versions != null) {
                sb.append("<span class='text-muted small'>");
                sb.append(versions.getRevisionNr());
                sb.append("</span>");
            }
        sb.append("</td><td>");
    }
    // locked
    boolean locked = lockManager.isLocked(child);
    if (locked) {
        LockInfo lock = lockManager.getLock(child);
        sb.append("<i class=\"o_icon o_icon_locked\" title=\"");
        if (lock != null && lock.getLockedBy() != null) {
            String fullname = userManager.getUserDisplayName(lock.getLockedBy());
            String date = "";
            if (lock.getCreationDate() != null) {
                date = fc.getDateTimeFormat().format(lock.getCreationDate());
            }
            String msg = translator.translate("Locked", new String[] { fullname, date });
            if (lock.isWebDAVLock()) {
                msg += " (WebDAV)";
            }
            sb.append(msg);
        }
        sb.append("\">&#160;</i>");
    }
    sb.append("</td><td>");
    // Info link
    if (canWrite) {
        int actionCount = 0;
        if (canVersion) {
            actionCount++;
        }
        String nameLowerCase = name.toLowerCase();
        // OO-57 only display edit link if it's not a folder
        boolean isLeaf = (child instanceof VFSLeaf);
        boolean isEditable = (isLeaf && !lockedForUser && !xssErrors && (nameLowerCase.endsWith(".html") || nameLowerCase.endsWith(".htm") || nameLowerCase.endsWith(".txt") || nameLowerCase.endsWith(".css") || nameLowerCase.endsWith(".csv	")));
        if (isEditable)
            actionCount++;
        boolean canEP = canAddToEPortfolio && !isContainer;
        if (canEP)
            actionCount++;
        boolean canMetaData = canMetaInfo(child);
        if (canMetaData)
            actionCount++;
        if (actionCount == 1 && canMetaData) {
            // when only one action is available, don't render menu
            sb.append("<a ");
            ubu.buildHrefAndOnclick(sb, null, iframePostEnabled, false, false, new NameValuePair(PARAM_EDTID, pos)).append(" title=\"").append(StringHelper.escapeHtml(translator.translate("mf.edit"))).append("\"><i class=\"o_icon o_icon-fw o_icon_edit_metadata\"></i></a>");
        } else if (actionCount > 1) {
            // add actions to menu if multiple actions available
            sb.append("<a id='o_sel_actions_").append(pos).append("' href='javascript:;'><i class='o_icon o_icon-lg o_icon_actions'></i></a>").append("<div id='o_sel_actions_pop_").append(pos).append("' style='display:none;'><ul class='list-unstyled'>");
            // meta edit action (rename etc)
            if (canMetaData) {
                // Metadata edit link... also handles rename for non-OlatRelPathImpls
                sb.append("<li><a ");
                ubu.buildHrefAndOnclick(sb, null, iframePostEnabled, false, false, new NameValuePair(PARAM_EDTID, pos)).append("><i class=\"o_icon o_icon-fw o_icon_edit_metadata\"></i> ").append(StringHelper.escapeHtml(translator.translate("mf.edit"))).append("</a></li>");
            }
            // content edit action
            if (isEditable) {
                sb.append("<li><a ");
                ubu.buildHrefAndOnclick(sb, null, iframePostEnabled, false, false, new NameValuePair(PARAM_CONTENTEDITID, pos)).append("><i class=\"o_icon o_icon-fw o_icon_edit_file\"></i> ").append(StringHelper.escapeHtml(translator.translate("editor"))).append("</a></li>");
            }
            // versions action
            if (canVersion) {
                // Versions link
                sb.append("<li><a ");
                ubu.buildHrefAndOnclick(sb, null, iframePostEnabled, false, false, new NameValuePair(PARAM_VERID, pos)).append("><i class=\"o_icon o_icon-fw o_icon_version\"></i> ").append(StringHelper.escapeHtml(translator.translate("versions"))).append("</a></li>");
            }
            // get a link for adding a file to ePortfolio, if file-owner is the current user
            if (canEP) {
                if (metaInfo != null) {
                    Identity author = metaInfo.getAuthorIdentity();
                    if (author != null && fc.getIdentityEnvironnement().getIdentity().getKey().equals(author.getKey())) {
                        sb.append("<li><a ");
                        ubu.buildHrefAndOnclick(sb, null, iframePostEnabled, false, false, new NameValuePair(PARAM_EPORT, pos)).append("><i class=\"o_icon o_icon-fw o_icon_eportfolio_add\"></i> ").append(StringHelper.escapeHtml(translator.translate("eportfolio"))).append("</a></li>");
                    }
                }
            }
            sb.append("</ul></div>").append("<script type='text/javascript'>").append("/* <![CDATA[ */").append("jQuery(function() {\n").append("  o_popover('o_sel_actions_").append(pos).append("','o_sel_actions_pop_").append(pos).append("','left');\n").append("});").append("/* ]]> */").append("</script>");
        }
    }
    sb.append("</td></tr>");
}
Also used : VFSLeaf(org.olat.core.util.vfs.VFSLeaf) NameValuePair(org.olat.core.gui.components.form.flexible.impl.NameValuePair) AbstractVirtualContainer(org.olat.core.util.vfs.AbstractVirtualContainer) MetaInfo(org.olat.core.commons.modules.bc.meta.MetaInfo) MetaTagged(org.olat.core.commons.modules.bc.meta.tagged.MetaTagged) License(org.olat.core.commons.services.license.License) MetaInfoFactory(org.olat.core.commons.modules.bc.meta.MetaInfoFactory) Date(java.util.Date) Versionable(org.olat.core.util.vfs.version.Versionable) Versions(org.olat.core.util.vfs.version.Versions) LockInfo(org.olat.core.util.vfs.lock.LockInfo) Identity(org.olat.core.id.Identity) AbstractVirtualContainer(org.olat.core.util.vfs.AbstractVirtualContainer) VirtualContainer(org.olat.core.util.vfs.VirtualContainer) LicenseRenderer(org.olat.core.commons.services.license.ui.LicenseRenderer)

Aggregations

LockInfo (org.olat.core.util.vfs.lock.LockInfo)18 License (org.olat.core.commons.services.license.License)6 Identity (org.olat.core.id.Identity)6 VFSLeaf (org.olat.core.util.vfs.VFSLeaf)6 URI (java.net.URI)4 Vector (java.util.Vector)4 Test (org.junit.Test)4 GroupRoles (org.olat.basesecurity.GroupRoles)4 FormLayoutContainer (org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer)4 Roles (org.olat.core.id.Roles)4 OlatRelPathImpl (org.olat.core.util.vfs.OlatRelPathImpl)4 VFSContainer (org.olat.core.util.vfs.VFSContainer)4 VFSItem (org.olat.core.util.vfs.VFSItem)4 CoursePublishTest (org.olat.restapi.CoursePublishTest)4 IOException (java.io.IOException)2 PrintWriter (java.io.PrintWriter)2 StringWriter (java.io.StringWriter)2 Writer (java.io.Writer)2 Date (java.util.Date)2 DocumentBuilder (javax.xml.parsers.DocumentBuilder)2