Search in sources :

Example 1 with Subject

use of org.exist.security.Subject in project exist by eXist-db.

the class SystemImport method setAdminCredentials.

private void setAdminCredentials(final DBBroker broker, final String newCredentials) throws ConfigurationException, PermissionDeniedException {
    final Subject subject = broker.getCurrentSubject();
    subject.setPassword(newCredentials);
    subject.save(broker);
}
Also used : Subject(org.exist.security.Subject)

Example 2 with Subject

use of org.exist.security.Subject in project exist by eXist-db.

the class RESTServer method doPost.

/**
 * Handles POST requests. If the path leads to a binary resource with
 * mime-type "application/xquery", that resource will be read and executed
 * by the XQuery engine. Otherwise, the request content is loaded and parsed
 * as XML. It may either contain an XUpdate or a query request.
 *
 * @param broker the database broker
 * @param transaction the database transaction
 * @param request the request
 * @param response the response
 * @param path the path of the request
 *
 * @throws BadRequestException if a bad request is made
 * @throws PermissionDeniedException if the request has insufficient permissions
 * @throws NotFoundException if the request resource cannot be found
 * @throws IOException if an I/O error occurs
 */
public void doPost(final DBBroker broker, final Txn transaction, final HttpServletRequest request, final HttpServletResponse response, final String path) throws BadRequestException, PermissionDeniedException, IOException, NotFoundException {
    // if required, set character encoding
    if (request.getCharacterEncoding() == null) {
        request.setCharacterEncoding(formEncoding);
    }
    final Properties outputProperties = new Properties(defaultOutputKeysProperties);
    final XmldbURI pathUri = XmldbURI.createInternal(path);
    LockedDocument lockedDocument = null;
    DocumentImpl resource = null;
    final String encoding = outputProperties.getProperty(OutputKeys.ENCODING);
    String mimeType = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
    try {
        // check if path leads to an XQuery resource.
        // if yes, the resource is loaded and the XQuery executed.
        final String xquery_mime_type = MimeType.XQUERY_TYPE.getName();
        final String xproc_mime_type = MimeType.XPROC_TYPE.getName();
        lockedDocument = broker.getXMLResource(pathUri, LockMode.READ_LOCK);
        resource = lockedDocument == null ? null : lockedDocument.getDocument();
        XmldbURI servletPath = pathUri;
        // xquery resource
        while (null == resource) {
            // traverse up the path looking for xquery objects
            servletPath = servletPath.removeLastSegment();
            if (servletPath == XmldbURI.EMPTY_URI) {
                break;
            }
            lockedDocument = broker.getXMLResource(servletPath, LockMode.READ_LOCK);
            resource = lockedDocument == null ? null : lockedDocument.getDocument();
            if (null != resource && (resource.getResourceType() == DocumentImpl.BINARY_FILE && xquery_mime_type.equals(resource.getMimeType()) || resource.getResourceType() == DocumentImpl.XML_FILE && xproc_mime_type.equals(resource.getMimeType()))) {
                // found a binary file with mime-type xquery or XML file with mime-type xproc
                break;
            } else if (null != resource) {
                // not an xquery or xproc resource. This means we have a path
                // that cannot contain an xquery or xproc object even if we keep
                // moving up the path, so bail out now
                lockedDocument.close();
                lockedDocument = null;
                resource = null;
                break;
            }
        }
        // either xquery binary file or xproc xml file
        if (resource != null) {
            if (resource.getResourceType() == DocumentImpl.BINARY_FILE && xquery_mime_type.equals(resource.getMimeType()) || resource.getResourceType() == DocumentImpl.XML_FILE && xproc_mime_type.equals(resource.getMimeType())) {
                // found an XQuery resource, fixup request values
                final String pathInfo = pathUri.trimFromBeginning(servletPath).toString();
                try {
                    if (xquery_mime_type.equals(resource.getMimeType())) {
                        // Execute the XQuery
                        executeXQuery(broker, transaction, resource, request, response, outputProperties, servletPath.toString(), pathInfo);
                    } else {
                        // Execute the XProc
                        executeXProc(broker, transaction, resource, request, response, outputProperties, servletPath.toString(), pathInfo);
                    }
                } catch (final XPathException e) {
                    if (MimeType.XML_TYPE.getName().equals(mimeType)) {
                        writeXPathException(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                    } else {
                        writeXPathExceptionHtml(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                    }
                }
                return;
            }
        }
    } finally {
        if (lockedDocument != null) {
            lockedDocument.close();
        }
    }
    // check the content type to see if its XML or a parameter string
    String requestType = request.getContentType();
    if (requestType != null) {
        final int semicolon = requestType.indexOf(';');
        if (semicolon > 0) {
            requestType = requestType.substring(0, semicolon).trim();
        }
    }
    // content type != application/x-www-form-urlencoded
    if (requestType == null || !requestType.equals(MimeType.URL_ENCODED_TYPE.getName())) {
        // third, normal POST: read the request content and check if
        // it is an XUpdate or a query request.
        int howmany = 10;
        int start = 1;
        boolean typed = false;
        ElementImpl variables = null;
        boolean enclose = true;
        boolean cache = false;
        String query = null;
        try {
            final String content = getRequestContent(request);
            final NamespaceExtractor nsExtractor = new NamespaceExtractor();
            final ElementImpl root = parseXML(broker.getBrokerPool(), content, nsExtractor);
            final String rootNS = root.getNamespaceURI();
            if (rootNS != null && rootNS.equals(Namespaces.EXIST_NS)) {
                if (Query.xmlKey().equals(root.getLocalName())) {
                    // process <query>xpathQuery</query>
                    String option = root.getAttribute(Start.xmlKey());
                    if (option != null) {
                        try {
                            start = Integer.parseInt(option);
                        } catch (final NumberFormatException e) {
                        // 
                        }
                    }
                    option = root.getAttribute(Max.xmlKey());
                    if (option != null) {
                        try {
                            howmany = Integer.parseInt(option);
                        } catch (final NumberFormatException e) {
                        // 
                        }
                    }
                    option = root.getAttribute(Enclose.xmlKey());
                    if (option != null) {
                        if ("no".equals(option)) {
                            enclose = false;
                        }
                    } else {
                        option = root.getAttribute(Wrap.xmlKey());
                        if (option != null) {
                            if ("no".equals(option)) {
                                enclose = false;
                            }
                        }
                    }
                    option = root.getAttribute(Method.xmlKey());
                    if ((option != null) && (!option.isEmpty())) {
                        outputProperties.setProperty(SERIALIZATION_METHOD_PROPERTY, option);
                    }
                    option = root.getAttribute(Typed.xmlKey());
                    if (option != null) {
                        if ("yes".equals(option)) {
                            typed = true;
                        }
                    }
                    option = root.getAttribute(Mime.xmlKey());
                    if ((option != null) && (!option.isEmpty())) {
                        mimeType = option;
                    }
                    if ((option = root.getAttribute(Cache.xmlKey())) != null) {
                        cache = "yes".equals(option);
                    }
                    if ((option = root.getAttribute(Session.xmlKey())) != null && option.length() > 0) {
                        outputProperties.setProperty(Serializer.PROPERTY_SESSION_ID, option);
                    }
                    final NodeList children = root.getChildNodes();
                    for (int i = 0; i < children.getLength(); i++) {
                        final Node child = children.item(i);
                        if (child.getNodeType() == Node.ELEMENT_NODE && child.getNamespaceURI().equals(Namespaces.EXIST_NS)) {
                            if (Text.xmlKey().equals(child.getLocalName())) {
                                final StringBuilder buf = new StringBuilder();
                                Node next = child.getFirstChild();
                                while (next != null) {
                                    if (next.getNodeType() == Node.TEXT_NODE || next.getNodeType() == Node.CDATA_SECTION_NODE) {
                                        buf.append(next.getNodeValue());
                                    }
                                    next = next.getNextSibling();
                                }
                                query = buf.toString();
                            } else if (Variables.xmlKey().equals(child.getLocalName())) {
                                variables = (ElementImpl) child;
                            } else if (Properties.xmlKey().equals(child.getLocalName())) {
                                Node node = child.getFirstChild();
                                while (node != null) {
                                    if (node.getNodeType() == Node.ELEMENT_NODE && node.getNamespaceURI().equals(Namespaces.EXIST_NS) && Property.xmlKey().equals(node.getLocalName())) {
                                        final Element property = (Element) node;
                                        final String key = property.getAttribute("name");
                                        final String value = property.getAttribute("value");
                                        LOG.debug("{} = {}", key, value);
                                        if (key != null && value != null) {
                                            outputProperties.setProperty(key, value);
                                        }
                                    }
                                    node = node.getNextSibling();
                                }
                            }
                        }
                    }
                }
                // execute query
                if (query != null) {
                    try {
                        search(broker, transaction, query, path, nsExtractor.getNamespaces(), variables, howmany, start, typed, outputProperties, enclose, cache, request, response);
                    } catch (final XPathException e) {
                        if (MimeType.XML_TYPE.getName().equals(mimeType)) {
                            writeXPathException(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                        } else {
                            writeXPathExceptionHtml(response, HttpServletResponse.SC_BAD_REQUEST, encoding, null, path, e);
                        }
                    }
                } else {
                    throw new BadRequestException("No query specified");
                }
            } else if (rootNS != null && rootNS.equals(XUpdateProcessor.XUPDATE_NS)) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Got xupdate request: {}", content);
                }
                if (xupdateSubmission == EXistServlet.FeatureEnabled.FALSE) {
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    return;
                } else if (xupdateSubmission == EXistServlet.FeatureEnabled.AUTHENTICATED_USERS_ONLY) {
                    final Subject currentSubject = broker.getCurrentSubject();
                    if (!currentSubject.isAuthenticated() || currentSubject.getId() == RealmImpl.GUEST_GROUP_ID) {
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                        return;
                    }
                }
                final MutableDocumentSet docs = new DefaultDocumentSet();
                final boolean isCollection;
                try (final Collection collection = broker.openCollection(pathUri, LockMode.READ_LOCK)) {
                    if (collection != null) {
                        isCollection = true;
                        collection.allDocs(broker, docs, true);
                    } else {
                        isCollection = false;
                    }
                }
                if (!isCollection) {
                    final DocumentImpl xupdateDoc = broker.getResource(pathUri, Permission.READ);
                    if (xupdateDoc != null) {
                        docs.add(xupdateDoc);
                    } else {
                        broker.getAllXMLResources(docs);
                    }
                }
                final XUpdateProcessor processor = new XUpdateProcessor(broker, docs);
                long mods = 0;
                try (final Reader reader = new StringReader(content)) {
                    final Modification[] modifications = processor.parse(new InputSource(reader));
                    for (Modification modification : modifications) {
                        mods += modification.process(transaction);
                        broker.flush();
                    }
                }
                // FD : Returns an XML doc
                writeXUpdateResult(response, encoding, mods);
            // END FD
            } else {
                throw new BadRequestException("Unknown XML root element: " + root.getNodeName());
            }
        } catch (final SAXException e) {
            Exception cause = e;
            if (e.getException() != null) {
                cause = e.getException();
            }
            LOG.debug("SAX exception while parsing request: {}", cause.getMessage(), cause);
            throw new BadRequestException("SAX exception while parsing request: " + cause.getMessage());
        } catch (final ParserConfigurationException e) {
            throw new BadRequestException("Parser exception while parsing request: " + e.getMessage());
        } catch (final XPathException e) {
            throw new BadRequestException("Query exception while parsing request: " + e.getMessage());
        } catch (final IOException e) {
            throw new BadRequestException("IO exception while parsing request: " + e.getMessage());
        } catch (final EXistException e) {
            throw new BadRequestException(e.getMessage());
        } catch (final LockException e) {
            throw new PermissionDeniedException(e.getMessage());
        }
    // content type = application/x-www-form-urlencoded
    } else {
        doGet(broker, transaction, request, response, path);
    }
}
Also used : XUpdateProcessor(org.exist.xupdate.XUpdateProcessor) Modification(org.exist.xupdate.Modification) InputSource(org.xml.sax.InputSource) JSONNode(org.exist.util.serializer.json.JSONNode) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) XMLReader(org.xml.sax.XMLReader) Properties(java.util.Properties) SAXException(org.xml.sax.SAXException) ElementImpl(org.exist.dom.memtree.ElementImpl) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) XmldbURI(org.exist.xmldb.XmldbURI) NodeList(org.w3c.dom.NodeList) EXistException(org.exist.EXistException) Subject(org.exist.security.Subject) PermissionDeniedException(org.exist.security.PermissionDeniedException) XMLStreamException(javax.xml.stream.XMLStreamException) SAXException(org.xml.sax.SAXException) TriggerException(org.exist.collections.triggers.TriggerException) EXistException(org.exist.EXistException) TransformerConfigurationException(javax.xml.transform.TransformerConfigurationException) SAXParseException(org.xml.sax.SAXParseException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) Collection(org.exist.collections.Collection) PermissionDeniedException(org.exist.security.PermissionDeniedException)

Example 3 with Subject

use of org.exist.security.Subject in project exist by eXist-db.

the class BasicAuthenticator method authenticate.

@Override
public Subject authenticate(HttpServletRequest request, HttpServletResponse response, boolean sendChallenge) throws IOException {
    String credentials = request.getHeader("Authorization");
    String username = null;
    String password = null;
    try {
        if (credentials != null && credentials.startsWith("Basic")) {
            final byte[] c = Base64.decodeBase64(credentials.substring("Basic ".length()));
            final String s = new String(c, UTF_8);
            // LOG.debug("BASIC auth credentials: "+s);
            final int p = s.indexOf(':');
            username = p < 0 ? s : s.substring(0, p);
            password = p < 0 ? null : s.substring(p + 1);
        }
    } catch (final IllegalArgumentException iae) {
        LOG.warn("Invalid BASIC authentication header received: {}", iae.getMessage(), iae);
        credentials = null;
    }
    // get the user from the session if possible
    final HttpSession session = request.getSession(false);
    Subject user = null;
    if (session != null) {
        user = (Subject) session.getAttribute(XQueryContext.HTTP_SESSIONVAR_XMLDB_USER);
        if (user != null && (username == null || user.getName().equals(username))) {
            return user;
        }
    }
    if (user != null) {
        session.removeAttribute(XQueryContext.HTTP_SESSIONVAR_XMLDB_USER);
    }
    // get the credentials
    if (credentials == null) {
        // LOG.debug("Sending BASIC auth challenge.");
        if (sendChallenge) {
            sendChallenge(request, response);
        }
        return null;
    }
    // authenticate the credentials
    final SecurityManager secman = pool.getSecurityManager();
    try {
        user = secman.authenticate(username, password);
    } catch (final AuthenticationException e) {
        // if authentication failed then send a challenge request again
        if (sendChallenge) {
            sendChallenge(request, response);
        }
        return null;
    }
    // store the user in the session
    if (session != null) {
        session.setAttribute(XQueryContext.HTTP_SESSIONVAR_XMLDB_USER, user);
    }
    // return the authenticated user
    return user;
}
Also used : SecurityManager(org.exist.security.SecurityManager) AuthenticationException(org.exist.security.AuthenticationException) HttpSession(javax.servlet.http.HttpSession) Subject(org.exist.security.Subject)

Example 4 with Subject

use of org.exist.security.Subject in project exist by eXist-db.

the class AbstractExistHttpServlet method authenticate.

protected Subject authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException {
    if (isInternalOnly() && request.getAttribute(XQueryURLRewrite.RQ_ATTR) == null) {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
        return null;
    }
    Principal principal = HttpAccount.getUserFromServletRequest(request);
    if (principal != null) {
        return (Subject) principal;
    }
    // Try to validate the principal if passed from the Servlet engine
    principal = request.getUserPrincipal();
    if (principal != null) {
        if (XmldbPrincipal.class.isAssignableFrom(principal.getClass())) {
            final String username = ((XmldbPrincipal) principal).getName();
            final String password = ((XmldbPrincipal) principal).getPassword();
            getLog().info("Validating Principle: {}", username);
            try {
                return getPool().getSecurityManager().authenticate(username, password);
            } catch (final AuthenticationException e) {
                getLog().info(e.getMessage());
            }
        }
        if (principal instanceof Subject) {
            return (Subject) principal;
        }
    }
    // Secondly try basic authentication
    final String auth = request.getHeader("Authorization");
    if (auth == null && getDefaultUser() != null) {
        return getDefaultUser();
    }
    return getAuthenticator().authenticate(request, response, true);
}
Also used : XmldbPrincipal(org.exist.security.XmldbPrincipal) AuthenticationException(org.exist.security.AuthenticationException) Principal(java.security.Principal) XmldbPrincipal(org.exist.security.XmldbPrincipal) Subject(org.exist.security.Subject)

Example 5 with Subject

use of org.exist.security.Subject in project exist by eXist-db.

the class TestCase method getResource.

public Resource getResource(Object r) throws XMLDBException {
    LocalCollection collection = null;
    Subject user = null;
    LocalXMLResource res = null;
    final BrokerPool pool = existEmbeddedServer.getBrokerPool();
    if (r instanceof NodeProxy) {
        NodeProxy p = (NodeProxy) r;
        res = new LocalXMLResource(user, pool, collection, p);
    } else if (r instanceof Node) {
        res = new LocalXMLResource(user, pool, collection, XmldbURI.EMPTY_URI);
        res.setContentAsDOM((Node) r);
    } else if (r instanceof AtomicValue) {
        res = new LocalXMLResource(user, pool, collection, XmldbURI.EMPTY_URI);
        res.setContent(r);
    } else if (r instanceof LocalXMLResource)
        res = (LocalXMLResource) r;
    else
        throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "unknown object " + r.getClass());
    try {
        Field field = res.getClass().getDeclaredField("outputProperties");
        field.setAccessible(true);
        field.set(res, new Properties(defaultProperties));
    } catch (Exception e) {
    }
    return res;
}
Also used : Field(java.lang.reflect.Field) LocalXMLResource(org.exist.xmldb.LocalXMLResource) LocalCollection(org.exist.xmldb.LocalCollection) Node(org.w3c.dom.Node) XMLDBException(org.xmldb.api.base.XMLDBException) AtomicValue(org.exist.xquery.value.AtomicValue) Properties(java.util.Properties) NodeProxy(org.exist.dom.persistent.NodeProxy) Subject(org.exist.security.Subject) BrokerPool(org.exist.storage.BrokerPool) XMLDBException(org.xmldb.api.base.XMLDBException) IOException(java.io.IOException) SAXException(org.xml.sax.SAXException)

Aggregations

Subject (org.exist.security.Subject)66 DBBroker (org.exist.storage.DBBroker)22 Test (org.junit.Test)18 EXistException (org.exist.EXistException)17 XmldbURI (org.exist.xmldb.XmldbURI)15 AuthenticationException (org.exist.security.AuthenticationException)14 PermissionDeniedException (org.exist.security.PermissionDeniedException)13 Collection (org.exist.collections.Collection)12 SecurityManager (org.exist.security.SecurityManager)12 Permission (org.exist.security.Permission)10 ServletException (javax.servlet.ServletException)9 BrokerPool (org.exist.storage.BrokerPool)9 Txn (org.exist.storage.txn.Txn)9 Sequence (org.exist.xquery.value.Sequence)9 Properties (java.util.Properties)8 Descriptor (org.exist.http.Descriptor)8 XPathException (org.exist.xquery.XPathException)8 IOException (java.io.IOException)6 SAXException (org.xml.sax.SAXException)5 BadRequestException (org.exist.http.BadRequestException)4