Skip to content

Commit 55a60ed

Browse files
committed
sha256 support
1 parent d2b5129 commit 55a60ed

5 files changed

Lines changed: 62 additions & 3 deletions

File tree

src/main/java/com/yetanalytics/xapi/model/Attachment.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
1010
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
1111
import com.yetanalytics.xapi.model.deserializers.MimeTypeDeserializer;
12+
import com.yetanalytics.xapi.validation.Sha256Sum;
1213

1314
import jakarta.activation.MimeType;
1415

@@ -35,8 +36,8 @@ public class Attachment implements JSONObject {
3536
@NotNull
3637
private Integer length;
3738

38-
// TODO: Validate that sha2 is a SHA256, 64-char hex string
3939
@NotNull
40+
@Sha256Sum
4041
private String sha2;
4142

4243
private URI fileUrl;

src/main/java/com/yetanalytics/xapi/util/HashUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44

55
public final class HashUtils {
66
private static final Pattern SHA1_HEX_PATTERN = Pattern.compile("^[0-9a-fA-F]{40}$");
7+
private static final Pattern SHA256_HEX_PATTERN = Pattern.compile("^[0-9a-fA-F]{64}$");
78

89
private HashUtils() {}
910

1011
public static boolean isSha1Hex(String value) {
1112
return value != null && SHA1_HEX_PATTERN.matcher(value).matches();
1213
}
14+
15+
public static boolean isSha256Hex(String value) {
16+
return value != null && SHA256_HEX_PATTERN.matcher(value).matches();
17+
}
1318
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.yetanalytics.xapi.validation;
2+
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.ElementType;
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.RetentionPolicy;
7+
import java.lang.annotation.Target;
8+
9+
import jakarta.validation.Constraint;
10+
import jakarta.validation.Payload;
11+
12+
@Documented
13+
@Constraint(validatedBy = Sha256SumValidator.class)
14+
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_USE })
15+
@Retention(RetentionPolicy.RUNTIME)
16+
public @interface Sha256Sum {
17+
String message() default "must be a 64-character SHA-256 hex string";
18+
19+
Class<?>[] groups() default {};
20+
21+
Class<? extends Payload>[] payload() default {};
22+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.yetanalytics.xapi.validation;
2+
3+
import com.yetanalytics.xapi.util.HashUtils;
4+
5+
import jakarta.validation.ConstraintValidator;
6+
import jakarta.validation.ConstraintValidatorContext;
7+
8+
public class Sha256SumValidator implements ConstraintValidator<Sha256Sum, String> {
9+
10+
@Override
11+
public boolean isValid(String value, ConstraintValidatorContext context) {
12+
return value == null || HashUtils.isSha256Hex(value);
13+
}
14+
}

src/test/java/com/yetanalytics/model/AttachmentTest.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ public void init() {
2525
attachment = new Attachment();
2626
}
2727

28-
@Test
29-
public void testAttachment() throws URISyntaxException, MimeTypeParseException {
28+
private void populateValidAttachment() throws URISyntaxException, MimeTypeParseException {
3029
LangMap display = new LangMap(new HashMap<>());
3130
display.put("en-US", "Display");
3231

@@ -45,10 +44,28 @@ public void testAttachment() throws URISyntaxException, MimeTypeParseException {
4544
attachment.setLength(length);
4645
attachment.setSha2(sha2);
4746
attachment.setFileUrl(fileUrl);
47+
}
4848

49+
@Test
50+
public void testAttachment() throws URISyntaxException, MimeTypeParseException {
51+
populateValidAttachment();
4952
ValidationUtils.assertValid(validator, attachment);
5053
}
5154

55+
@Test
56+
public void testInvalidSha2Length() throws URISyntaxException, MimeTypeParseException {
57+
populateValidAttachment();
58+
attachment.setSha2("426cf3a8b2864dd91201b989ba5728181da52bfff9a0489670e54cd8ec8b3a5");
59+
ValidationUtils.assertInvalid(validator, attachment);
60+
}
61+
62+
@Test
63+
public void testInvalidSha2Hex() throws URISyntaxException, MimeTypeParseException {
64+
populateValidAttachment();
65+
attachment.setSha2("z26cf3a8b2864dd91201b989ba5728181da52bfff9a0489670e54cd8ec8b3a50");
66+
ValidationUtils.assertInvalid(validator, attachment);
67+
}
68+
5269
@Test
5370
public void testEmptyAttachment() {
5471
// One error for empty attachment, one error each for null properties

0 commit comments

Comments
 (0)