Package org.apache.wink.server.internal.providers.entity

Source Code of org.apache.wink.server.internal.providers.entity.JAXBElementProviderTest

/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*   http://www.apache.org/licenses/LICENSE-2.0
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*******************************************************************************/
package org.apache.wink.server.internal.providers.entity;

import java.io.ByteArrayInputStream;
import java.lang.reflect.Type;
import java.util.StringTokenizer;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;

import org.apache.wink.common.annotations.Asset;
import org.apache.wink.common.internal.providers.entity.xml.JAXBElementXmlProvider;
import org.apache.wink.common.internal.providers.entity.xml.JAXBXmlProvider;
import org.apache.wink.common.model.atom.AtomFeed;
import org.apache.wink.common.model.atom.ObjectFactory;
import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
import org.apache.wink.test.mock.MockRequestConstructor;
import org.apache.wink.test.mock.TestUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;

public class JAXBElementProviderTest extends MockServletInvocationTest {

    private static final String SOURCE_REQUEST              =
                                                                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><feed xmlns:ns2=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns=\"http://www.w3.org/2005/Atom\" ><id>ID</id></feed>";

    private static final byte[] SOURCE_REQUEST_BYTES        = SOURCE_REQUEST.getBytes();
    private static final String SOURCE_RESPONSE             =
                                                                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><feed xmlns:ns2=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns=\"http://www.w3.org/2005/Atom\"><id>ID</id></feed>";

    private static final String JAXBXmlRootElement_REQUEST  =
                                                                "<JAXBXmlRootElement><id>ID</id><name>NAME</name></JAXBXmlRootElement>";
    private static final byte[] JAXBXmlRootElement_BYTES    = JAXBXmlRootElement_REQUEST.getBytes();
    private static final String JAXBXmlRootElement_RESPONSE =
                                                                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<JAXBXmlRootElement>"
                                                                    + "<id>ID</id>"
                                                                    + "<name>NAME</name>"
                                                                    + "</JAXBXmlRootElement>";

    private static final String JAXBXmlType_REQUEST         =
                                                                "<JAXBXmlType><id>ID</id><name>NAME</name></JAXBXmlType>";
    private static final byte[] JAXBXmlType_REQUEST_BYTES   = JAXBXmlType_REQUEST.getBytes();
    private static final String JAXBXmlType_RESPONSE        =
                                                                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<JAXBXmlType>"
                                                                    + "<id>ID</id>"
                                                                    + "<name>NAME</name>"
                                                                    + "</JAXBXmlType>";

    JAXBElement<AtomFeed>       atomfeed;

    @Override
    protected Class<?>[] getClasses() {
        return new Class<?>[] {Resource.class};
    }

    @Path("jaxbresource")
    public static class Resource {

        @POST
        @Path("jaxbelement")
        public JAXBElement<AtomFeed> createWraped(JAXBElement<AtomFeed> feed) {
            AtomFeed atomFeed = new AtomFeed();
            atomFeed.setId(feed.getValue().getId());
            JAXBElement<AtomFeed> wrapedFeed = new ObjectFactory().createFeed(atomFeed);
            return wrapedFeed;
        }

        @POST
        @Path("xmlrootwithfactory")
        public AtomFeed createBare(AtomFeed feed) {
            AtomFeed atomFeed = new AtomFeed();
            atomFeed.setId(feed.getId());
            return atomFeed;
        }

        @POST
        @Path("xmltype")
        public JAXBElement<JAXBXmlType> createxmltype(JAXBXmlType resource) {
            JAXBXmlType s = new JAXBXmlType();
            s.setId(resource.getId());
            s.setName(resource.getName());
            JAXBElement<JAXBXmlType> element =
                new JAXBElement<JAXBXmlType>(new QName("JAXBXmlType"), JAXBXmlType.class, resource);
            return element;
        }

        @POST
        @Path("xmlrootnofactory")
        public JAXBXmlRootElement createXmlRoot(JAXBXmlRootElement resource) {
            JAXBXmlRootElement s = new JAXBXmlRootElement();
            s.setId(resource.getId());
            s.setName(resource.getName());
            return s;
        }

        @GET
        @Path("xmltypenofactory")
        public JAXBXmlType getXmltypeNoFactory() {
            JAXBXmlType s = new JAXBXmlType();
            s.setId("ID");
            s.setName("NAME");
            return s;
        }

        @POST
        @Path("xmlasset")
        public TestAsset getAsset(TestAsset asset) {
            return asset;
        }
    }

    @Asset
    public static class TestAsset {

        JAXBXmlType xml;

        @Produces(MediaType.TEXT_XML)
        public JAXBXmlType getJAXB() {
            return xml;
        }

        @Consumes(MediaType.TEXT_XML)
        public void setJAXB(JAXBXmlType jaxbObject) {
            xml = jaxbObject;
        }
    }

    public void testJAXBElementProviderReaderWriter() throws SecurityException,
        NoSuchFieldException {

        JAXBElementXmlProvider provider = new JAXBElementXmlProvider();
        AtomFeed af = new AtomFeed();
        org.apache.wink.common.model.atom.ObjectFactory objectFactory =
            new org.apache.wink.common.model.atom.ObjectFactory();
        JAXBElement<AtomFeed> feed = objectFactory.createFeed(af);
        Type genericType =
            JAXBElementProviderTest.class.getDeclaredField("atomfeed").getGenericType();

        assertTrue(provider.isWriteable(feed.getClass(), genericType, null, new MediaType("text",
                                                                                          "xml")));
        assertTrue(provider.isWriteable(feed.getClass(),
                                        genericType,
                                        null,
                                        new MediaType("application", "xml")));
        assertTrue(provider.isWriteable(feed.getClass(),
                                        genericType,
                                        null,
                                        new MediaType("application", "atom+xml")));
        assertTrue(provider.isWriteable(feed.getClass(),
                                        genericType,
                                        null,
                                        new MediaType("application", "atomsvc+xml")));
        assertFalse(provider
            .isWriteable(feed.getClass(), genericType, null, new MediaType("text", "plain")));

        assertTrue(provider.isReadable(feed.getClass(), genericType, null, new MediaType("text",
                                                                                         "xml")));
        assertTrue(provider.isReadable(feed.getClass(),
                                       genericType,
                                       null,
                                       new MediaType("application", "xml")));
        assertTrue(provider.isReadable(feed.getClass(),
                                       genericType,
                                       null,
                                       new MediaType("application", "atom+xml")));
        assertTrue(provider.isReadable(feed.getClass(),
                                       genericType,
                                       null,
                                       new MediaType("application", "atomsvc+xml")));
        assertFalse(provider.isReadable(feed.getClass(), genericType, null, new MediaType("text",
                                                                                          "plain")));
    }

    @SuppressWarnings("unchecked")
    public void testJAXBElementProviderInvocation() throws Exception {
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/jaxbelement",
                                                        "text/xml",
                                                        "text/xml",
                                                        SOURCE_REQUEST_BYTES);
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(200, invoke.getStatus());

        JAXBContext context = JAXBContext.newInstance(AtomFeed.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        JAXBElement<AtomFeed> expectedResponse =
            (JAXBElement<AtomFeed>)unmarshaller.unmarshal(new ByteArrayInputStream(SOURCE_RESPONSE
                .getBytes()));
        JAXBElement<AtomFeed> response =
            (JAXBElement<AtomFeed>)unmarshaller.unmarshal(new ByteArrayInputStream(invoke
                .getContentAsByteArray()));
        assertEquals(expectedResponse.getValue().getId(), response.getValue().getId());
    }
   
    @SuppressWarnings("unchecked")
    public void testJAXBElementProviderInvocationDTD() throws Exception {
        String classpath = System.getProperty("java.class.path");
        StringTokenizer tokenizer = new StringTokenizer(classpath, System.getProperty("path.separator"));
        String path = null;
        while (tokenizer.hasMoreTokens()) {
            path = tokenizer.nextToken();
            if (path.endsWith("test-classes")) {
                break;
            }
        }
       
        /*
         * the addition of the DOCTYPE tests a well-known XML parser exploit in which arbitrary server
         * filesystem files can be read.  See JAXBElementXmlProvider.readFrom
         *
         */

        final String LOCALSOURCE = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
        "<!DOCTYPE data [<!ENTITY file SYSTEM \""+ path +"/etc/JAXBElementProviderTest.txt\">]>" +
        "<feed xmlns:ns2=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns=\"http://www.w3.org/2005/Atom\"><id>&file;</id></feed>";

        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/jaxbelement",
                                                        "text/xml",
                                                        "text/xml",
                                                        LOCALSOURCE.getBytes());
       
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(400, invoke.getStatus())// 400 means the unmarshaller could not unmarshal the xml
       
        // let's make sure our test string is unmarshallable, just for a good sanity check
        JAXBContext testcontext = JAXBContext.newInstance(AtomFeed.class);
        Unmarshaller testunmarshaller = testcontext.createUnmarshaller();
        JAXBElement<AtomFeed> testresponse =
            (JAXBElement<AtomFeed>)testunmarshaller.unmarshal(new ByteArrayInputStream(LOCALSOURCE.getBytes()));
        assertEquals("we could not unmarshal the test xml", "YOU SHOULD NOT BE ABLE TO SEE THIS", testresponse.getValue().getId().trim());
       
    }
   
    @SuppressWarnings("unchecked")
    public void testJAXBElementProviderInvocationDTDWithCharset() throws Exception {
        String classpath = System.getProperty("java.class.path");
        StringTokenizer tokenizer = new StringTokenizer(classpath, System.getProperty("path.separator"));
        String path = null;
        while (tokenizer.hasMoreTokens()) {
            path = tokenizer.nextToken();
            if (path.endsWith("test-classes")) {
                break;
            }
        }
       
        /*
         * the addition of the DOCTYPE tests a well-known XML parser exploit in which arbitrary server
         * filesystem files can be read.  See JAXBElementXmlProvider.readFrom
         *
         */

        final String LOCALSOURCE = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
        "<!DOCTYPE data [<!ENTITY file SYSTEM \""+ path +"/etc/JAXBElementProviderTest.txt\">]>" +
        "<feed xmlns:ns2=\"http://a9.com/-/spec/opensearch/1.1/\" xmlns=\"http://www.w3.org/2005/Atom\"><id>&file;</id></feed>";

        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/jaxbelement",
                                                        "text/xml",
                                                        "text/xml;charset=UTF-8",
                                                        LOCALSOURCE.getBytes());
       
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(400, invoke.getStatus())// 400 means the unmarshaller could not unmarshal the xml, this is good
       
        // let's make sure our test string is unmarshallable, just for a good sanity check
        JAXBContext testcontext = JAXBContext.newInstance(AtomFeed.class);
        Unmarshaller testunmarshaller = testcontext.createUnmarshaller();
        JAXBElement<AtomFeed> testresponse =
            (JAXBElement<AtomFeed>)testunmarshaller.unmarshal(new ByteArrayInputStream(LOCALSOURCE.getBytes()));
        assertEquals("we could not unmarshal the test xml", "YOU SHOULD NOT BE ABLE TO SEE THIS", testresponse.getValue().getId().trim());
       
    }

    @SuppressWarnings("unchecked")
    public void testJAXBXmlElementProviderInvocation() throws Exception {
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/xmlrootwithfactory",
                                                        "text/xml",
                                                        "text/xml",
                                                        SOURCE_REQUEST_BYTES);
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(200, invoke.getStatus());

        JAXBContext context = JAXBContext.newInstance(AtomFeed.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        JAXBElement<AtomFeed> expectedResponse =
            (JAXBElement<AtomFeed>)unmarshaller.unmarshal(new ByteArrayInputStream(SOURCE_RESPONSE
                .getBytes()));
        JAXBElement<AtomFeed> response =
            (JAXBElement<AtomFeed>)unmarshaller.unmarshal(new ByteArrayInputStream(invoke
                .getContentAsByteArray()));
        assertEquals(expectedResponse.getValue().getId(), response.getValue().getId());
    }

    public void testJAXBXmlElementProviderInvocationXmltypeNoFactory() throws Exception {
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("GET",
                                                        "/jaxbresource/xmltypenofactory",
                                                        "text/xml",
                                                        "text/xml",
                                                        null);
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(200, invoke.getStatus());
        String msg =
            TestUtils.diffIgnoreUpdateWithAttributeQualifier(JAXBXmlType_RESPONSE, invoke
                .getContentAsString());
        assertNull(msg, msg);
    }

    public void testJAXBXmlElementProviderInvocationXmltype() throws Exception {
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/xmltype",
                                                        "text/xml",
                                                        "text/xml",
                                                        JAXBXmlType_REQUEST_BYTES);
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(200, invoke.getStatus());
        String msg =
            TestUtils.diffIgnoreUpdateWithAttributeQualifier(JAXBXmlType_RESPONSE, invoke
                .getContentAsString());
        assertNull(msg, msg);
    }

    public void testJAXBXmlElementProviderInvocationXmlRoot() throws Exception {
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/xmlrootnofactory",
                                                        "text/xml",
                                                        "text/xml",
                                                        JAXBXmlRootElement_BYTES);
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(200, invoke.getStatus());
        String msg =
            TestUtils.diffIgnoreUpdateWithAttributeQualifier(JAXBXmlRootElement_RESPONSE, invoke
                .getContentAsString());
        assertNull(msg, msg);

        request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/xmlrootnofactory",
                                                        "text/xml",
                                                        "text/xml",
                                                        "<BadRequest/>".getBytes());
        invoke = invoke(request);
        assertEquals(400, invoke.getStatus());
    }

    public void testJAXBXmlElementProviderInvocationXmlAsset() throws Exception {
        MockHttpServletRequest request =
            MockRequestConstructor.constructMockRequest("POST",
                                                        "/jaxbresource/xmlasset",
                                                        "text/xml",
                                                        "text/xml",
                                                        JAXBXmlType_REQUEST_BYTES);
        MockHttpServletResponse invoke = invoke(request);
        assertEquals(200, invoke.getStatus());
        String msg =
            TestUtils.diffIgnoreUpdateWithAttributeQualifier(JAXBXmlType_RESPONSE, invoke
                .getContentAsString());
        assertNull(msg, msg);
    }

    public void testJAXBXmlElementProviderReaderWriter() throws SecurityException,
        NoSuchFieldException {
        JAXBXmlProvider provider = new JAXBXmlProvider();
        AtomFeed af = new AtomFeed();

        assertTrue(provider.isWriteable(af.getClass(), null, null, new MediaType("text", "xml")));
        assertTrue(provider.isWriteable(af.getClass(), null, null, new MediaType("application",
                                                                                 "xml")));
        assertTrue(provider.isWriteable(af.getClass(), null, null, new MediaType("application",
                                                                                 "atom+xml")));
        assertTrue(provider.isWriteable(af.getClass(), null, null, new MediaType("application",
                                                                                 "atomsvc+xml")));
        assertFalse(provider.isWriteable(af.getClass(), null, null, new MediaType("text", "plain")));

        assertTrue(provider.isReadable(af.getClass(), null, null, new MediaType("text", "xml")));
        assertTrue(provider.isReadable(af.getClass(), null, null, new MediaType("application",
                                                                                "xml")));
        assertTrue(provider.isReadable(af.getClass(), null, null, new MediaType("application",
                                                                                "atom+xml")));
        assertTrue(provider.isReadable(af.getClass(), null, null, new MediaType("application",
                                                                                "atomsvc+xml")));
        assertFalse(provider.isReadable(af.getClass(), null, null, new MediaType("text", "plain")));
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "JAXBXmlType", propOrder = {"id", "name"})
    public static class JAXBXmlType {

        @XmlElement(required = true)
        private String id;
        @XmlElement(required = true)
        private String name;

        public JAXBXmlType() {
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getId() {
            return id;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

    }

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "JAXBXmlRootElement", propOrder = {"id", "name"})
    @XmlRootElement(name = "JAXBXmlRootElement")
    public static class JAXBXmlRootElement {

        @XmlElement(required = true)
        private String id;
        @XmlElement(required = true)
        private String name;

        public JAXBXmlRootElement() {
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getId() {
            return id;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

    }

}
TOP

Related Classes of org.apache.wink.server.internal.providers.entity.JAXBElementProviderTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.