PreProcessor#

com.palmyralabs.palmyra.handlers.PreProcessor

Mixin shared by all mutating handlers (CreateHandler, UpdateHandler, SaveHandler, DeleteHandler). Centralizes validation and ACL.

Note: This interface should not be implemented by application developers. Implement one of the child interfaces (CreateHandler, UpdateHandler, SaveHandler, DeleteHandler) instead.

Methods#

Method Signature
validate void validate(Tuple tuple, HandlerContext ctx) — throw to reject
preProcessRaw Tuple preProcessRaw(Tuple tuple, HandlerContext ctx) — runs before preProcess
preProcess Tuple preProcess(Tuple tuple, HandlerContext ctx)
aclCheck (abstract) int aclCheck(Tuple tuple, HandlerContext ctx) — return -1 to forbid
getAcl int getAcl(Tuple tuple, HandlerContext ctx) — throws EndPointForbiddenException when the mask is -1

Example#

@Component
@CrudMapping(value = "/v1/admin/user", type = User.class)
public class UserCreateHandler implements CreateHandler { // composes PreProcessor

    @Autowired
    private UserProvider userProvider;

    @Override
    public void validate(Tuple tuple, HandlerContext ctx) {
        if (tuple.get("loginName") == null) {
            throw new ValidationException("loginName is required");
        }
    }

    @Override
    public Tuple preProcessRaw(Tuple tuple, HandlerContext ctx) {
        // normalize raw input before validation / ACL
        String login = (String) tuple.get("loginName");
        if (login != null) tuple.set("loginName", login.trim().toLowerCase());
        return tuple;
    }

    @Override
    public Tuple preProcess(Tuple tuple, HandlerContext ctx) {
        tuple.set("status", "PENDING");
        return tuple;
    }

    @Override
    public int aclCheck(Tuple tuple, HandlerContext ctx) {
        return userProvider.hasRole("USER_CREATE") ? 0 : -1;
    }

    @Override
    public int getAcl(Tuple tuple, HandlerContext ctx) {
        // delegate to the default implementation, which throws when mask == -1
        return PreProcessor.super.getAcl(tuple, ctx);
    }
}