Skip to content

Commit 7f0713b

Browse files
committed
Add bean validation annotation tests
1 parent e7c61c4 commit 7f0713b

File tree

1 file changed

+398
-0
lines changed

1 file changed

+398
-0
lines changed
Lines changed: 398 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,398 @@
1+
package org.owasp.esapi.reference.validation.annotations;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.owasp.esapi.PropNames.DISABLE_INTRUSION_DETECTION;
5+
6+
import java.nio.charset.StandardCharsets;
7+
import java.text.DateFormat;
8+
import java.util.Date;
9+
import java.util.Locale;
10+
import java.util.Set;
11+
12+
import javax.servlet.http.HttpServletRequest;
13+
import javax.validation.ConstraintViolation;
14+
import javax.validation.Validation;
15+
import javax.validation.Validator;
16+
17+
import org.junit.After;
18+
import org.junit.Assume;
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
import org.owasp.esapi.ESAPI;
22+
import org.owasp.esapi.SecurityConfiguration;
23+
import org.owasp.esapi.SecurityConfigurationWrapper;
24+
import org.owasp.esapi.http.MockHttpServletRequest;
25+
26+
public class ValidationAnnotationsTest {
27+
private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win");
28+
private static final String WINDOWS_ROOT = "C:\\";
29+
private static final String UNIX_ROOT = "/";
30+
31+
private static class ConfOverride extends SecurityConfigurationWrapper {
32+
ConfOverride(SecurityConfiguration orig) {
33+
super(orig);
34+
}
35+
36+
@Override
37+
public Boolean getBooleanProp(String propName) {
38+
if (DISABLE_INTRUSION_DETECTION.equals(propName)) {
39+
return Boolean.TRUE;
40+
}
41+
return super.getBooleanProp(propName);
42+
}
43+
}
44+
45+
private Validator validator;
46+
47+
@Before
48+
public void setUp() {
49+
ESAPI.override(new ConfOverride(ESAPI.securityConfiguration()));
50+
validator = Validation.buildDefaultValidatorFactory().getValidator();
51+
}
52+
53+
@After
54+
public void tearDown() {
55+
ESAPI.override(null);
56+
}
57+
58+
@Test
59+
public void testValidCreditCard() {
60+
CreditCardBean bean = new CreditCardBean("1234 9876 0000 0008");
61+
assertViolations(bean, 0);
62+
bean.number = "4417 1234 5678 9112";
63+
assertViolations(bean, 1);
64+
}
65+
66+
@Test
67+
public void testValidDate() {
68+
String validDate = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US).format(new Date(0));
69+
DateBean bean = new DateBean(validDate);
70+
assertViolations(bean, 0);
71+
bean.value = "not-a-date";
72+
assertViolations(bean, 1);
73+
}
74+
75+
@Test
76+
public void testValidDirectoryPath() {
77+
if (IS_WINDOWS) {
78+
Assume.assumeTrue(isSystemDriveC());
79+
DirectoryPathWindowsBean bean = new DirectoryPathWindowsBean(WINDOWS_ROOT);
80+
assertViolations(bean, 0);
81+
bean.path = WINDOWS_ROOT + "does-not-exist";
82+
assertViolations(bean, 1);
83+
} else {
84+
DirectoryPathUnixBean bean = new DirectoryPathUnixBean(UNIX_ROOT);
85+
assertViolations(bean, 0);
86+
bean.path = UNIX_ROOT + "does-not-exist";
87+
assertViolations(bean, 1);
88+
}
89+
}
90+
91+
@Test
92+
public void testValidDouble() {
93+
DoubleBean bean = new DoubleBean("1.0");
94+
assertViolations(bean, 0);
95+
bean.value = "ridiculous";
96+
assertViolations(bean, 1);
97+
}
98+
99+
@Test
100+
public void testValidFileContent() {
101+
FileContentBean bean = new FileContentBean("12345".getBytes(StandardCharsets.UTF_8));
102+
assertViolations(bean, 0);
103+
bean.content = "123456".getBytes(StandardCharsets.UTF_8);
104+
assertViolations(bean, 1);
105+
}
106+
107+
@Test
108+
public void testValidFileName() {
109+
FileNameBean bean = new FileNameBean("test.txt");
110+
assertViolations(bean, 0);
111+
bean.name = "test.exe";
112+
assertViolations(bean, 1);
113+
}
114+
115+
@Test
116+
public void testValidFileUpload() {
117+
if (IS_WINDOWS) {
118+
Assume.assumeTrue(isSystemDriveC());
119+
FileUploadWindowsBean bean = new FileUploadWindowsBean("12345".getBytes(StandardCharsets.UTF_8));
120+
assertViolations(bean, 0);
121+
bean.content = "123456".getBytes(StandardCharsets.UTF_8);
122+
assertViolations(bean, 1);
123+
} else {
124+
FileUploadUnixBean bean = new FileUploadUnixBean("12345".getBytes(StandardCharsets.UTF_8));
125+
assertViolations(bean, 0);
126+
bean.content = "123456".getBytes(StandardCharsets.UTF_8);
127+
assertViolations(bean, 1);
128+
}
129+
}
130+
131+
@Test
132+
public void testValidInteger() {
133+
IntegerBean bean = new IntegerBean("5");
134+
assertViolations(bean, 0);
135+
bean.value = "20";
136+
assertViolations(bean, 1);
137+
}
138+
139+
@Test
140+
public void testValidListItem() {
141+
ListItemBean bean = new ListItemBean("red");
142+
assertViolations(bean, 0);
143+
bean.value = "blue";
144+
assertViolations(bean, 1);
145+
}
146+
147+
@Test
148+
public void testValidNumber() {
149+
NumberBean bean = new NumberBean("10");
150+
assertViolations(bean, 0);
151+
bean.value = "1000";
152+
assertViolations(bean, 1);
153+
}
154+
155+
@Test
156+
public void testValidPrintableChars() {
157+
PrintableCharsBean bean = new PrintableCharsBean("Hello".toCharArray());
158+
assertViolations(bean, 0);
159+
bean.value = "Hi\n".toCharArray();
160+
assertViolations(bean, 1);
161+
}
162+
163+
@Test
164+
public void testValidPrintableString() {
165+
PrintableStringBean bean = new PrintableStringBean("Hello");
166+
assertViolations(bean, 0);
167+
bean.value = "Hi\n";
168+
assertViolations(bean, 1);
169+
}
170+
171+
@Test
172+
public void testValidRedirectLocation() {
173+
RedirectBean bean = new RedirectBean("/test/ok");
174+
assertViolations(bean, 0);
175+
bean.value = "http://example.com";
176+
assertViolations(bean, 1);
177+
}
178+
179+
@Test
180+
public void testValidSafeHTML() {
181+
SafeHtmlBean bean = new SafeHtmlBean("<b>Jeff</b>");
182+
assertViolations(bean, 0);
183+
bean.value = "Test. <script>alert(document.cookie)</script>";
184+
assertViolations(bean, 1);
185+
}
186+
187+
@Test
188+
public void testValidURI() {
189+
UriBean bean = new UriBean("http://example.com");
190+
assertViolations(bean, 0);
191+
bean.value = "javascript:alert(1)";
192+
assertViolations(bean, 1);
193+
}
194+
195+
@Test
196+
public void testValidHTTPRequestParameterSet() {
197+
MockHttpServletRequest validRequest = new MockHttpServletRequest();
198+
validRequest.addParameter("required", "value");
199+
validRequest.addParameter("optional", "value");
200+
HttpRequestBean bean = new HttpRequestBean(validRequest);
201+
assertViolations(bean, 0);
202+
203+
MockHttpServletRequest invalidRequest = new MockHttpServletRequest();
204+
bean.request = invalidRequest;
205+
assertViolations(bean, 1);
206+
}
207+
208+
private boolean isSystemDriveC() {
209+
String systemDrive = System.getenv("SystemDrive");
210+
return systemDrive == null || "C:".equalsIgnoreCase(systemDrive);
211+
}
212+
213+
private <T> void assertViolations(T bean, int expected) {
214+
Set<ConstraintViolation<T>> violations = validator.validate(bean);
215+
assertEquals(expected, violations.size());
216+
}
217+
218+
private static class CreditCardBean {
219+
@ValidCreditCard(context = "cc", allowNull = false)
220+
private String number;
221+
222+
CreditCardBean(String number) {
223+
this.number = number;
224+
}
225+
}
226+
227+
private static class DateBean {
228+
@ValidDate(context = "date", dateStyle = DateFormat.SHORT, locale = "en-US", allowNull = false)
229+
private String value;
230+
231+
DateBean(String value) {
232+
this.value = value;
233+
}
234+
}
235+
236+
private static class DirectoryPathWindowsBean {
237+
@ValidDirectoryPath(context = "dir", parent = WINDOWS_ROOT, allowNull = false)
238+
private String path;
239+
240+
DirectoryPathWindowsBean(String path) {
241+
this.path = path;
242+
}
243+
}
244+
245+
private static class DirectoryPathUnixBean {
246+
@ValidDirectoryPath(context = "dir", parent = UNIX_ROOT, allowNull = false)
247+
private String path;
248+
249+
DirectoryPathUnixBean(String path) {
250+
this.path = path;
251+
}
252+
}
253+
254+
private static class DoubleBean {
255+
@ValidDouble(context = "double", minValue = 0, maxValue = 20, allowNull = false)
256+
private String value;
257+
258+
DoubleBean(String value) {
259+
this.value = value;
260+
}
261+
}
262+
263+
private static class FileContentBean {
264+
@ValidFileContent(context = "content", maxBytes = 5, allowNull = false)
265+
private byte[] content;
266+
267+
FileContentBean(byte[] content) {
268+
this.content = content;
269+
}
270+
}
271+
272+
private static class FileNameBean {
273+
@ValidFileName(context = "filename", allowedExtensions = {".txt"}, allowNull = false)
274+
private String name;
275+
276+
FileNameBean(String name) {
277+
this.name = name;
278+
}
279+
}
280+
281+
private static class FileUploadWindowsBean {
282+
@ValidFileUpload(
283+
context = "upload",
284+
directoryPath = WINDOWS_ROOT,
285+
fileName = "test.txt",
286+
parent = WINDOWS_ROOT,
287+
maxBytes = 5,
288+
allowNull = false
289+
)
290+
private byte[] content;
291+
292+
FileUploadWindowsBean(byte[] content) {
293+
this.content = content;
294+
}
295+
}
296+
297+
private static class FileUploadUnixBean {
298+
@ValidFileUpload(
299+
context = "upload",
300+
directoryPath = UNIX_ROOT,
301+
fileName = "test.txt",
302+
parent = UNIX_ROOT,
303+
maxBytes = 5,
304+
allowNull = false
305+
)
306+
private byte[] content;
307+
308+
FileUploadUnixBean(byte[] content) {
309+
this.content = content;
310+
}
311+
}
312+
313+
private static class IntegerBean {
314+
@ValidInteger(context = "int", minValue = 0, maxValue = 10, allowNull = false)
315+
private String value;
316+
317+
IntegerBean(String value) {
318+
this.value = value;
319+
}
320+
}
321+
322+
private static class ListItemBean {
323+
@ValidListItem(context = "item", list = {"red", "green"}, allowNull = false)
324+
private String value;
325+
326+
ListItemBean(String value) {
327+
this.value = value;
328+
}
329+
}
330+
331+
private static class NumberBean {
332+
@ValidNumber(context = "num", minValue = 1, maxValue = 100, allowNull = false)
333+
private String value;
334+
335+
NumberBean(String value) {
336+
this.value = value;
337+
}
338+
}
339+
340+
private static class PrintableCharsBean {
341+
@ValidPrintable(context = "print", maxLength = 10, allowNull = false)
342+
private char[] value;
343+
344+
PrintableCharsBean(char[] value) {
345+
this.value = value;
346+
}
347+
}
348+
349+
private static class PrintableStringBean {
350+
@ValidPrintable(context = "print", maxLength = 10, allowNull = false)
351+
private String value;
352+
353+
PrintableStringBean(String value) {
354+
this.value = value;
355+
}
356+
}
357+
358+
private static class RedirectBean {
359+
@ValidRedirectLocation(context = "redirect", allowNull = false)
360+
private String value;
361+
362+
RedirectBean(String value) {
363+
this.value = value;
364+
}
365+
}
366+
367+
private static class SafeHtmlBean {
368+
@ValidSafeHTML(context = "safehtml", maxLength = 200, allowNull = false)
369+
private String value;
370+
371+
SafeHtmlBean(String value) {
372+
this.value = value;
373+
}
374+
}
375+
376+
private static class UriBean {
377+
@ValidURI(context = "uri", allowNull = false)
378+
private String value;
379+
380+
UriBean(String value) {
381+
this.value = value;
382+
}
383+
}
384+
385+
private static class HttpRequestBean {
386+
@ValidHTTPRequestParameterSet(
387+
context = "params",
388+
requiredNames = {"required"},
389+
optionalNames = {"optional"},
390+
allowNull = false
391+
)
392+
private HttpServletRequest request;
393+
394+
HttpRequestBean(HttpServletRequest request) {
395+
this.request = request;
396+
}
397+
}
398+
}

0 commit comments

Comments
 (0)