Search in sources :

Example 1 with LockedDocument

use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.

the class SystemImportHandler method restoreResourceEntry.

private DeferredPermission restoreResourceEntry(final Attributes atts) throws SAXException {
    @Nullable final String skip = atts.getValue("skip");
    // Don't process entries which should be skipped
    if (skip != null && !"no".equals(skip)) {
        return new SkippedEntryDeferredPermission();
    }
    @Nullable final String name = atts.getValue("name");
    if (name == null) {
        throw new SAXException("Resource requires a name attribute");
    }
    final boolean xmlType = Optional.ofNullable(atts.getValue("type")).filter(s -> s.equals("XMLResource")).isPresent();
    final String owner = getAttr(atts, "owner", SecurityManager.SYSTEM);
    final String group = getAttr(atts, "group", SecurityManager.DBA_GROUP);
    final String perms = getAttr(atts, "mode", "644");
    final String filename = getAttr(atts, "filename", name);
    @Nullable final String mimeTypeStr = atts.getValue("mimetype");
    @Nullable final String dateCreatedStr = atts.getValue("created");
    @Nullable final String dateModifiedStr = atts.getValue("modified");
    @Nullable final String publicId = atts.getValue("publicid");
    @Nullable final String systemId = atts.getValue("systemid");
    @Nullable final String nameDocType = atts.getValue("namedoctype");
    MimeType mimeType = null;
    if (mimeTypeStr != null) {
        mimeType = MimeTable.getInstance().getContentType(mimeTypeStr);
    }
    if (mimeType == null) {
        mimeType = xmlType ? MimeType.XML_TYPE : MimeType.BINARY_TYPE;
    }
    Date dateCreated = null;
    if (dateCreatedStr != null) {
        try {
            dateCreated = new DateTimeValue(dateCreatedStr).getDate();
        } catch (final XPathException xpe) {
            listener.warn("Illegal creation date. Ignoring date...");
        }
    }
    Date dateModified = null;
    if (dateModifiedStr != null) {
        try {
            dateModified = new DateTimeValue(dateModifiedStr).getDate();
        } catch (final XPathException xpe) {
            listener.warn("Illegal modification date. Ignoring date...");
        }
    }
    final DocumentType docType;
    if (publicId != null || systemId != null) {
        docType = new DocumentTypeImpl(nameDocType, publicId, systemId);
    } else {
        docType = null;
    }
    final XmldbURI docUri;
    if (version >= STRICT_URI_VERSION) {
        docUri = XmldbURI.create(name);
    } else {
        try {
            docUri = URIUtils.encodeXmldbUriFor(name);
        } catch (final URISyntaxException e) {
            final String msg = "Could not parse document name into a URI: " + e.getMessage();
            listener.error(msg);
            LOG.error(msg, e);
            return new SkippedEntryDeferredPermission();
        }
    }
    try (final EXistInputSource is = descriptor.getInputSource(filename)) {
        if (is == null) {
            final String msg = "Failed to restore resource '" + name + "'\nfrom file '" + descriptor.getSymbolicPath(name, false) + "'.\nReason: Unable to obtain its EXistInputSource";
            listener.warn(msg);
            throw new RuntimeException(msg);
        }
        try (final Txn transaction = beginTransaction()) {
            broker.storeDocument(transaction, docUri, is, mimeType, dateCreated, dateModified, null, docType, null, currentCollection);
            try (final LockedDocument doc = currentCollection.getDocumentWithLock(broker, docUri, Lock.LockMode.READ_LOCK)) {
                rh.startDocumentRestore(doc.getDocument(), atts);
            }
            transaction.commit();
            final DeferredPermission deferredPermission;
            if (name.startsWith(XmldbURI.SYSTEM_COLLECTION)) {
                // prevents restore of a backup from changing system collection resource ownership
                deferredPermission = new ResourceDeferredPermission(listener, currentCollection.getURI().append(name), SecurityManager.SYSTEM, SecurityManager.DBA_GROUP, Integer.parseInt(perms, 8));
            } else {
                deferredPermission = new ResourceDeferredPermission(listener, currentCollection.getURI().append(name), owner, group, Integer.parseInt(perms, 8));
            }
            try (final LockedDocument doc = currentCollection.getDocumentWithLock(broker, docUri, Lock.LockMode.READ_LOCK)) {
                rh.endDocumentRestore(doc.getDocument());
            }
            listener.restoredResource(name);
            return deferredPermission;
        } catch (final Exception e) {
            throw new IOException(e);
        }
    } catch (final Exception e) {
        listener.warn("Failed to restore resource '" + name + "'\nfrom file '" + descriptor.getSymbolicPath(name, false) + "'.\nReason: " + e.getMessage());
        LOG.error(e.getMessage(), e);
        return new SkippedEntryDeferredPermission();
    }
}
Also used : URIUtils(org.exist.xquery.util.URIUtils) Tuple2(com.evolvedbinary.j8fu.tuple.Tuple2) Txn(org.exist.storage.txn.Txn) java.util(java.util) ACE_TARGET(org.exist.security.ACLPermission.ACE_TARGET) URISyntaxException(java.net.URISyntaxException) SAXParserFactory(javax.xml.parsers.SAXParserFactory) Tuple(com.evolvedbinary.j8fu.tuple.Tuple.Tuple) XMLReader(org.xml.sax.XMLReader) Namespaces(org.exist.Namespaces) Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI) Attributes(org.xml.sax.Attributes) DocumentImpl(org.exist.dom.persistent.DocumentImpl) DateTimeValue(org.exist.xquery.value.DateTimeValue) Lock(org.exist.storage.lock.Lock) Permission(org.exist.security.Permission) Nullable(javax.annotation.Nullable) RestoreListener(org.exist.backup.restore.listener.RestoreListener) LockedDocument(org.exist.dom.persistent.LockedDocument) UTF_8(java.nio.charset.StandardCharsets.UTF_8) IOException(java.io.IOException) TransactionException(org.exist.storage.txn.TransactionException) DocumentType(org.w3c.dom.DocumentType) DefaultHandler(org.xml.sax.helpers.DefaultHandler) SecurityManager(org.exist.security.SecurityManager) SAXParseException(org.xml.sax.SAXParseException) Logger(org.apache.logging.log4j.Logger) BackupDescriptor(org.exist.backup.BackupDescriptor) ACE_ACCESS_TYPE(org.exist.security.ACLPermission.ACE_ACCESS_TYPE) DBBroker(org.exist.storage.DBBroker) SAXException(org.xml.sax.SAXException) org.exist.util(org.exist.util) DocumentTypeImpl(org.exist.dom.persistent.DocumentTypeImpl) LogManager(org.apache.logging.log4j.LogManager) XPathException(org.exist.xquery.XPathException) DateTimeValue(org.exist.xquery.value.DateTimeValue) XPathException(org.exist.xquery.XPathException) DocumentTypeImpl(org.exist.dom.persistent.DocumentTypeImpl) DocumentType(org.w3c.dom.DocumentType) URISyntaxException(java.net.URISyntaxException) Txn(org.exist.storage.txn.Txn) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) TransactionException(org.exist.storage.txn.TransactionException) SAXParseException(org.xml.sax.SAXParseException) SAXException(org.xml.sax.SAXException) XPathException(org.exist.xquery.XPathException) SAXException(org.xml.sax.SAXException) LockedDocument(org.exist.dom.persistent.LockedDocument) Nullable(javax.annotation.Nullable) XmldbURI(org.exist.xmldb.XmldbURI)

Example 2 with LockedDocument

use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.

the class ResourceDeferredPermission method apply.

@Override
public void apply(final DBBroker broker, final Txn transaction) {
    try (final LockedDocument lockedDoc = broker.getXMLResource(getTarget(), Lock.LockMode.WRITE_LOCK)) {
        final DocumentImpl doc = lockedDoc.getDocument();
        final Permission permission = doc.getPermissions();
        PermissionFactory.chown(broker, permission, Optional.ofNullable(getOwner()), Optional.ofNullable(getGroup()));
        PermissionFactory.chmod(broker, permission, Optional.of(getMode()), Optional.ofNullable(permission instanceof ACLPermission ? getAces() : null));
        broker.storeXMLResource(transaction, doc);
    } catch (final PermissionDeniedException e) {
        final String msg = "ERROR: Failed to set permissions on Document '" + getTarget() + "'.";
        LOG.error(msg, e);
        getListener().warn(msg);
    }
}
Also used : ACLPermission(org.exist.security.ACLPermission) LockedDocument(org.exist.dom.persistent.LockedDocument) ACLPermission(org.exist.security.ACLPermission) Permission(org.exist.security.Permission) PermissionDeniedException(org.exist.security.PermissionDeniedException) DocumentImpl(org.exist.dom.persistent.DocumentImpl)

Example 3 with LockedDocument

use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.

the class XQueryURLRewrite method getSource.

private SourceInfo getSource(final DBBroker broker, final String moduleLoadPath) throws ServletException {
    final SourceInfo sourceInfo;
    if (query.startsWith(XmldbURI.XMLDB_URI_PREFIX)) {
        // Is the module source stored in the database?
        try {
            final XmldbURI locationUri = XmldbURI.xmldbUriFor(query);
            try (final LockedDocument lockedSourceDoc = broker.getXMLResource(locationUri.toCollectionPathURI(), LockMode.READ_LOCK)) {
                if (lockedSourceDoc == null) {
                    throw new ServletException("XQuery resource: " + query + " not found in database");
                }
                final DocumentImpl sourceDoc = lockedSourceDoc.getDocument();
                if (sourceDoc.getResourceType() != DocumentImpl.BINARY_FILE || !"application/xquery".equals(sourceDoc.getMimeType())) {
                    throw new ServletException("XQuery resource: " + query + " is not an XQuery or " + "declares a wrong mime-type");
                }
                sourceInfo = new SourceInfo(new DBSource(broker, (BinaryDocument) sourceDoc, true), locationUri.toString());
            } catch (final PermissionDeniedException e) {
                throw new ServletException("permission denied to read module source from " + query);
            }
        } catch (final URISyntaxException e) {
            throw new ServletException(e.getMessage(), e);
        }
    } else {
        try {
            sourceInfo = new SourceInfo(SourceFactory.getSource(broker, moduleLoadPath, query, true), moduleLoadPath);
        } catch (final IOException e) {
            throw new ServletException("IO error while reading XQuery source: " + query);
        } catch (final PermissionDeniedException e) {
            throw new ServletException("Permission denied while reading XQuery source: " + query);
        }
    }
    return sourceInfo;
}
Also used : LockedDocument(org.exist.dom.persistent.LockedDocument) DBSource(org.exist.source.DBSource) PermissionDeniedException(org.exist.security.PermissionDeniedException) URISyntaxException(java.net.URISyntaxException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) XmldbURI(org.exist.xmldb.XmldbURI)

Example 4 with LockedDocument

use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.

the class BinaryDoc method eval.

@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
    final Sequence emptyParamReturnValue = (isCalledAs(FS_BINARY_DOC_NAME) || isCalledAs(FS_BINARY_DOC_CONTENT_DIGEST_NAME)) ? Sequence.EMPTY_SEQUENCE : BooleanValue.FALSE;
    if (args[0].isEmpty()) {
        return emptyParamReturnValue;
    }
    final String path = args[0].getStringValue();
    try (final LockedDocument lockedDoc = context.getBroker().getXMLResource(XmldbURI.xmldbUriFor(path), LockMode.READ_LOCK)) {
        if (lockedDoc == null) {
            return emptyParamReturnValue;
        }
        final DocumentImpl doc = lockedDoc.getDocument();
        if (doc.getResourceType() != DocumentImpl.BINARY_FILE) {
            return emptyParamReturnValue;
        } else if (isCalledAs(FS_BINARY_DOC_NAME)) {
            try (final Txn transaction = context.getBroker().continueOrBeginTransaction()) {
                final BinaryDocument bin = (BinaryDocument) doc;
                final InputStream is = context.getBroker().getBinaryResource(transaction, bin);
                final Base64BinaryDocument b64doc = Base64BinaryDocument.getInstance(context, is);
                b64doc.setUrl(path);
                transaction.commit();
                return b64doc;
            }
        } else if (isCalledAs(FS_BINARY_DOC_CONTENT_DIGEST_NAME)) {
            final String algorithm = args[1].getStringValue();
            final DigestType digestType;
            try {
                digestType = DigestType.forCommonName(algorithm);
            } catch (final IllegalArgumentException e) {
                throw new XPathException(this, "Invalid algorithm: " + algorithm, e);
            }
            try (final Txn transaction = context.getBroker().getBrokerPool().getTransactionManager().beginTransaction()) {
                final BinaryDocument bin = (BinaryDocument) doc;
                final MessageDigest messageDigest = context.getBroker().getBinaryResourceContentDigest(transaction, bin, digestType);
                final InputStream is = new UnsynchronizedByteArrayInputStream(messageDigest.getValue());
                final Sequence result = BinaryValueFromInputStream.getInstance(context, new HexBinaryValueType(), is);
                transaction.commit();
                return result;
            }
        } else {
            return BooleanValue.TRUE;
        }
    } catch (final URISyntaxException e) {
        logger.error("Invalid resource URI", e);
        throw new XPathException(this, "Invalid resource uri", e);
    } catch (final PermissionDeniedException e) {
        logger.error("{}: permission denied to read resource", path, e);
        throw new XPathException(this, path + ": permission denied to read resource");
    } catch (final IOException | TransactionException e) {
        logger.error("{}: I/O error while reading resource", path, e);
        throw new XPathException(this, path + ": I/O error while reading resource", e);
    }
}
Also used : XPathException(org.exist.xquery.XPathException) UnsynchronizedByteArrayInputStream(org.apache.commons.io.input.UnsynchronizedByteArrayInputStream) InputStream(java.io.InputStream) Txn(org.exist.storage.txn.Txn) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) BinaryDocument(org.exist.dom.persistent.BinaryDocument) TransactionException(org.exist.storage.txn.TransactionException) DigestType(org.exist.util.crypto.digest.DigestType) LockedDocument(org.exist.dom.persistent.LockedDocument) UnsynchronizedByteArrayInputStream(org.apache.commons.io.input.UnsynchronizedByteArrayInputStream) PermissionDeniedException(org.exist.security.PermissionDeniedException) MessageDigest(org.exist.util.crypto.digest.MessageDigest)

Example 5 with LockedDocument

use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.

the class XMLDBGetMimeType method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    final String path = new AnyURIValue(args[0].itemAt(0).getStringValue()).toString();
    if (path.matches("^[a-z]+://.*")) {
        // external
        final MimeTable mimeTable = MimeTable.getInstance();
        final MimeType mimeType = mimeTable.getContentTypeFor(path);
        if (mimeType != null) {
            return new StringValue(mimeType.getName());
        }
    } else {
        // database
        try {
            XmldbURI pathUri = XmldbURI.xmldbUriFor(path);
            // relative collection Path: add the current base URI
            pathUri = context.getBaseURI().toXmldbURI().resolveCollectionPath(pathUri);
            // try to open the document and acquire a lock
            try (final LockedDocument lockedDoc = context.getBroker().getXMLResource(pathUri, LockMode.READ_LOCK)) {
                if (lockedDoc != null) {
                    return new StringValue(lockedDoc.getDocument().getMimeType());
                }
            }
        } catch (final Exception e) {
            logger.error(e.getMessage());
            throw new XPathException(this, e);
        }
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : MimeTable(org.exist.util.MimeTable) XPathException(org.exist.xquery.XPathException) AnyURIValue(org.exist.xquery.value.AnyURIValue) LockedDocument(org.exist.dom.persistent.LockedDocument) StringValue(org.exist.xquery.value.StringValue) MimeType(org.exist.util.MimeType) XmldbURI(org.exist.xmldb.XmldbURI) XPathException(org.exist.xquery.XPathException)

Aggregations

LockedDocument (org.exist.dom.persistent.LockedDocument)91 DocumentImpl (org.exist.dom.persistent.DocumentImpl)40 XmldbURI (org.exist.xmldb.XmldbURI)39 DBBroker (org.exist.storage.DBBroker)36 PermissionDeniedException (org.exist.security.PermissionDeniedException)30 Collection (org.exist.collections.Collection)28 Txn (org.exist.storage.txn.Txn)27 BrokerPool (org.exist.storage.BrokerPool)21 EXistException (org.exist.EXistException)20 Test (org.junit.Test)20 IOException (java.io.IOException)18 BinaryDocument (org.exist.dom.persistent.BinaryDocument)18 Serializer (org.exist.storage.serializers.Serializer)15 XPathException (org.exist.xquery.XPathException)14 URISyntaxException (java.net.URISyntaxException)13 InputStream (java.io.InputStream)11 LockException (org.exist.util.LockException)11 Tuple2 (com.evolvedbinary.j8fu.tuple.Tuple2)9 Lock (org.exist.storage.lock.Lock)9 TransactionManager (org.exist.storage.txn.TransactionManager)9