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);
}
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);
}
}
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;
}
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);
}
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;
}
Aggregations