1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.swid.swidval.controller;
28
29 import gov.nist.secauto.decima.core.assessment.AssessmentException;
30 import gov.nist.secauto.decima.core.assessment.AssessmentExecutor;
31 import gov.nist.secauto.decima.core.assessment.result.AssessmentResultBuilder;
32 import gov.nist.secauto.decima.core.assessment.result.AssessmentResults;
33 import gov.nist.secauto.decima.core.assessment.result.ResultStatus;
34 import gov.nist.secauto.decima.core.document.DocumentException;
35 import gov.nist.secauto.decima.xml.assessment.result.ReportGenerator;
36 import gov.nist.secauto.decima.xml.assessment.result.XMLResultBuilder;
37 import gov.nist.secauto.decima.xml.assessment.schematron.SchematronAssessment;
38 import gov.nist.secauto.decima.xml.document.JDOMDocument;
39 import gov.nist.secauto.decima.xml.document.XMLDocument;
40 import gov.nist.secauto.swid.swidval.SWIDAssessmentResultBuilderFactory;
41 import gov.nist.secauto.swid.swidval.SWIDRequirementsManager;
42 import gov.nist.secauto.swid.swidval.SWIDTagCharacteristics;
43 import gov.nist.secauto.swid.swidval.TagType;
44
45 import org.apache.logging.log4j.LogManager;
46 import org.apache.logging.log4j.Logger;
47 import org.jdom2.Document;
48 import org.jdom2.transform.JDOMSource;
49 import org.springframework.stereotype.Controller;
50 import org.springframework.web.bind.annotation.ExceptionHandler;
51 import org.springframework.web.bind.annotation.RequestMapping;
52 import org.springframework.web.bind.annotation.RequestMethod;
53 import org.springframework.web.bind.annotation.RequestParam;
54 import org.springframework.web.bind.annotation.RestController;
55 import org.springframework.web.multipart.MultipartFile;
56 import org.springframework.web.servlet.ModelAndView;
57
58 import java.io.IOException;
59 import java.io.InputStream;
60 import java.net.URI;
61 import java.net.URISyntaxException;
62 import java.util.HashMap;
63 import java.util.Map;
64
65 import javax.servlet.http.HttpServletRequest;
66 import javax.servlet.http.HttpServletResponse;
67 import javax.xml.transform.TransformerException;
68 import javax.xml.transform.stream.StreamResult;
69 import javax.xml.xpath.XPathExpressionException;
70 import javax.xml.xpath.XPathFactoryConfigurationException;
71
72 @RestController
73 @Controller
74 public class SWIDValController {
75 private static final Logger log = LogManager.getLogger(SchematronAssessment.class);
76
77 public static final String MODEL_KEY_ASSESSMENT_RESULT = "assessment";
78 public static final String MODEL_KEY_FILENAME = "filename";
79
80 private static final TagType TAG_TYPE_DEFAULT = TagType.PRIMARY;
81 private static final boolean TAG_AUTHORITATIVE_DEFAULT = true;
82
83 private final SWIDAssessmentManagerer/SWIDAssessmentManager.html#SWIDAssessmentManager">SWIDAssessmentManager manager = new SWIDAssessmentManager();
84
85
86 @RequestMapping(name = "/validate", method = RequestMethod.POST)
87 public void validate(HttpServletRequest requestEntity, HttpServletResponse response)
88 throws AssessmentException, DocumentException, IOException, TransformerException, URISyntaxException {
89
90 InputStream is = requestEntity.getInputStream();
91
92
93
94
95 JDOMDocument swidDocuemnt = new JDOMDocument(is, null);
96
97
98 SWIDTagCharacteristics swidTagCharacteristics = getSWIDTagCharacteristics(swidDocuemnt);
99
100 AssessmentResults results = performAssessment(swidDocuemnt, swidTagCharacteristics);
101
102 String accept = requestEntity.getHeader("Accept");
103 if (accept == null) {
104 accept = "application/xml";
105 }
106 XMLResultBuilder writer = new XMLResultBuilder();
107 if (accept.equals("application/xml")) {
108 writer.write(results, response.getOutputStream());
109 } else if (accept.equals("text/html")) {
110 Document document = writer.newDocument(results);
111 ReportGenerator reportGenerator = new ReportGenerator();
112 reportGenerator.setIgnoreNotTestedResults(true);
113 reportGenerator.setIgnoreOutOfScopeResults(true);
114 reportGenerator.setXslTemplateExtension(new URI("classpath:xsl/swid-result.xsl"));
115
116 reportGenerator.generate(new JDOMSource(document), new StreamResult(response.getOutputStream()));
117
118 }
119 }
120
121 @RequestMapping("/validate-form")
122 public ModelAndView validateForm(@RequestParam("file") MultipartFile file,
123 @RequestParam("tag-type") String tagTypeParam)
124 throws AssessmentException, UnrecognizedContentException, DocumentException, IOException {
125 if (file.isEmpty()) {
126 throw new UnrecognizedContentException("A valid SWID tag was not provided.");
127 }
128
129 InputStream is = file.getInputStream();
130
131
132
133
134 XMLDocument swidDocuemnt = new JDOMDocument(is, null);
135
136 SWIDTagCharacteristics swidTagCharacteristics = getSWIDTagCharacteristics(swidDocuemnt);
137 if (tagTypeParam != null) {
138 TagType tagType = TagType.lookup(tagTypeParam);
139 if (tagType != null) {
140
141 swidTagCharacteristics = new SWIDTagCharacteristics(tagType, swidTagCharacteristics.isAuthoritative());
142 }
143 }
144
145 AssessmentResults results = performAssessment(swidDocuemnt, swidTagCharacteristics);
146
147 if (!ResultStatus.PASS.equals(results.getBaseRequirementResult("GEN-1").getStatus())) {
148 throw new UnrecognizedContentException("The provided file was not a schema valid SWID tag.");
149 }
150
151 Map<String, Object> model = new HashMap<>();
152 model.put(MODEL_KEY_ASSESSMENT_RESULT, results);
153 model.put(MODEL_KEY_FILENAME, file.getOriginalFilename());
154 return new ModelAndView(new DecimaResultView(), model);
155 }
156
157 @ExceptionHandler(Exception.class)
158 public void handleError(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException {
159 log.error("Requested URL '" + request.getRequestURL() + "' raised an exception:", ex);
160
161 response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage());
162
163
164
165
166
167
168 }
169
170 private SWIDTagCharacteristics getSWIDTagCharacteristics(XMLDocument swidDocuemnt) {
171 SWIDTagCharacteristics characteristics;
172 try {
173 characteristics = SWIDTagCharacteristics.getSWIDTagCharacteristics(swidDocuemnt);
174 log.debug("Based on the tag contents, the tag appears to be {} {} tag",
175 characteristics.isAuthoritative() ? "an authoritative" : "a non-authoritative",
176 characteristics.getTagType().getName());
177 } catch (XPathExpressionException | XPathFactoryConfigurationException ex) {
178 log.debug("Unable to determine the type and authoritativeness of the tag", ex);
179 characteristics = new SWIDTagCharacteristics(TAG_TYPE_DEFAULT, TAG_AUTHORITATIVE_DEFAULT);
180 }
181 return characteristics;
182 }
183
184 private AssessmentResults performAssessment(XMLDocument swidDocuemnt, SWIDTagCharacteristics swidTagCharacteristics)
185 throws AssessmentException {
186
187 AssessmentExecutor<XMLDocument> executor
188 = manager.getAssessmentExecutor(swidTagCharacteristics.getTagType(), swidTagCharacteristics.isAuthoritative());
189 AssessmentResultBuilder assessmentResultBuilder = SWIDAssessmentResultBuilderFactory
190 .newAssessmentResultBuilder(swidTagCharacteristics.getTagType(), swidTagCharacteristics.isAuthoritative());
191
192
193 executor.execute(swidDocuemnt, assessmentResultBuilder);
194
195
196 return assessmentResultBuilder.end().build(SWIDRequirementsManager.getInstance());
197 }
198 }