We want to ad a request timestamp to some forms in Spring Boot. We need the timestamp in production and testing for various reasons.

public interface TimestampForm {

    ZonedDateTime getTimestamp();

    void setTimestamp(ZonedDateTime timestamp);
}

@Getter
@Setter
public class OrderForm implements TimestampForm {
   private customerId;
   private productId;
   private ZonedDateTime timestamp;
}

This field should be excluded by binding because the user should not be allowed to change it. On the other hand we want to override it for testing.

So this is what we have so far:

@ControllerAdvice
@RequiredArgsConstructor
public class TimestampControllerAdvice {

    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {
        // Don't allow user to override the value
        binder.setDisallowedFields("timestamp");
        var target = binder.getTarget();
        if (target instanceof TimestampForm) {
            var form = ((TimestampForm) binder.getTarget());
            form.setTimestamp(ZonedDateTime.now());
            if (!isProductionConfiguration()) {
                var header = request.getHeader("X-TIMESTAMP");
                if (header != null) {
                    var timestamp = ZonedDateTime.parse(header);
                    form.setTimestamp(timestamp);
                }
            }
        }
    }
}

This feels a little bit insecure. id I forget implements TimestampForm but not the field itself, the user could sent a timestamp and it gets binded to teh form.

We want the ability to always have ZonedDateTime.now() in production and the possibility to override it in development/testing. What is best practice for this szenario?

0

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.