package org.mitre.rhex;
import edu.umd.cs.findbugs.annotations.NonNull;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPut;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.mitre.test.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URI;
/**
* Test for document PUT operation
*
* <pre>
* 6.5 baseURL/sectionpath/documentname
*
* 6.5.2 PUT
*
* This operation is used to update a document by replacing it. The PUT operation
* MUST NOT be used to create a new document; new documents MUST be created by
* POSTing to the section. If the client attempts to create a new document this
* way [via PUT], the server MUST return a 404.
*
* The content MUST conform to the media type identified by the document metadata
* or the section content type. For media type application/xml, the document MUST
* also conform to the XML schema that corresponds to the content type identified
* by the document metadata or the section.
*
* If the parameter is incorrect or the content cannot be validated against
* the correct media type or the XML schema identified by the content type
* of this section, the server MUST return a status code of 400.
*
* If the request is successful, the [updated] section document MUST show up in the
* document feed for the section. The server returns a 200.
*
* Status Code: 200, [400], 404
* </pre>
*
* @author Jason Mathews, MITRE Corp.
* Date: 2/20/12 10:45 AM
*/
public class DocumentPutBadContent extends DocumentUpdate {
@NonNull
public String getId() {
return "6.5.2.5";
}
@Override
public boolean isRequired() {
return true;
}
@NonNull
public String getName() {
return "If the PUT parameter is incorrect or the content cannot be validated, server MUST return a 400";
}
/*
@NonNull
public List<Class<? extends TestUnit>> getDependencyClasses() {
return Collections.<Class<? extends TestUnit>> singletonList(DocumentPutPreTest.class); // 6.5.2.0
}
*/
protected String getContent(DocumentPutPreTest baseTest)
throws IOException, JDOMException
{
// bogus XML document should generate 400 errors
return "<bogus></bogus>";
}
/*
protected HttpPut createRequest(URI baseURL, String xmlContent) {
HttpPut request = new HttpPut(baseURL);
StringEntity entity = new StringEntity("plain text", ContentType.TEXT_PLAIN);
// StringEntity entity = new StringEntity(xmlContent, ContentType.APPLICATION_XML);
request.setEntity(entity);
return request;
}
*/
protected boolean validateContent(Context context, HttpPut request, HttpResponse response, DocumentPutPreTest baseTest, URI baseURL)
throws JDOMException, IOException, TestException
{
int code = response.getStatusLine().getStatusCode();
if (code != 400 || log.isDebugEnabled()) {
dumpResponse(request, response, code == 200);
if (code == 200) verifyContents(context, baseTest, baseURL);
}
// check return code
assertEquals(400, code);
return true;
}
private void verifyContents(Context context, DocumentPutPreTest baseTest, URI baseURL) {
try {
// verify document is unchanged since update should fail in first place
Document doc = getXmlDocument(context, baseURL);
if (doc == null) {
addLogWarning("Failed to retrieve document");
return;
}
Element rootElement = doc.getRootElement();
if (rootElement == null) {
addLogWarning("Retrieve document has empty root element");
return;
}
String rootElementName = rootElement.getName();
if ("bogus".equals(rootElementName)) {
addLogWarning("Server updated with invalid document contents");
} else {
// compare against original XML document
Document baseDoc = baseTest.getDocument();
if (baseDoc == null) {
addLogWarning("Cannot verify update");
return; // cannot compare
}
Element baseRootElement = doc.getRootElement();
if (baseRootElement == null) {
log.debug("Original document has empty root element. Cannot verify update");
return;
}
if (rootElementName.equals(baseRootElement.getName()))
log.debug("document root element unchanged"); // this is expected result
else
addLogWarning(String.format("Updated document root element %s does match expected element: %s",
rootElementName, baseRootElement.getName()));
Namespace ns = baseRootElement.getNamespace();
if (ns != null && !ns.equals(rootElement.getNamespace())) {
addLogWarning(String.format("Updated document namespace does not match: expected %s, actual=%s",
ns, rootElement.getNamespace()));
}
}
} catch (IOException e) {
log.warn("Failed to verify document", e);
} catch (JDOMException e) {
log.warn("Failed to parse updated document", e);
}
}
}