1

My current goal is to remove all valuable business code from the client side and put it on the server. But I'm struggling to hide the following logic, which involves AutoIt. Do you know a solution?

I don't understand if it's possible to pass AutoIt's control object to a REST resource, in order to verify some condition on the server side and then return true/false. I understand POJO's can be passed, but controls?? For example, my client code has this method which returns true if the current active window contains certain "Secret Text" inside.

...
  AutoItX control;

  private boolean foundCorrectInnerText() {
     return control.winGetText("Secret Title").contains("Secret Text");
  }
...

I want to hide the title string "Secret Title" from ever being known to the user, along with "Secret Text". How am I suppose to protect this logic?

Since the AutoIt method winGetText returns a boolean, I'm thinking the best way would be to convert the control object to a JSON string via org.codehaus.jackson.map.ObjectMapper and then perform the verification server-side, returning merely true or false. If only POJO can be passed via JSON, then how else do I protect such an important line of code? Here's a mockup:

Demo Client:

        ObjectMapper mapper = new ObjectMapper();
        AutoItX control = new AutoItX();  
        try {
            String jsonInString = mapper.writeValueAsString(control); // Really dumb?
            ResteasyClient client = new ResteasyClientBuilder().build();
            client.register(new CustomRestHeaderFilter("Content-Type", "application/json"));
            ResteasyWebTarget target = client.target("http://localhost:8080/MyApp/rest/autoit/control");
            Response response = target.request().post(Entity.json(jsonInString));
            String value = response.readEntity(String.class);
            response.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

ServerSide.java:

@Path("autoit")
public class ServerDemo {

    @POST
    @Path("control")
    @Produces("application/json")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response buildSendString(AutoIt control) {
    AutoItX control;
    String WindowTitle = "[REGEXPTITLE:(?i)(Notepad\\b.*)]";
        boolean titleFound = false;
        logger.info("HERE1");
        control = new ObjectMapper().readValue(jsonString, AutoItX.class);
        logger.info("HERE2");
        titleFound = control.winExists(WindowTitle);
        return Response.status(200).entity(titleFound).build();
  }
}

Update

I've updated my ServerSide.java code above. It returns "false" even though it should return true. So I looked into my server's log and it gives the following error. Notice how it prints "HERE1" but doesn't reach "HERE2" because of this line control = new ObjectMapper().readValue(jsonString, AutoItX.class);.

The jsonString I reference in my client code prints this JSON: {"version":"3.3.14.2","admin":true,"error":0} which seems like a limited JSON object.

Some of the error is below, the full stack is here.

15:56:53,867 INFO [com.serv.rest.ServerSide] (default task-1) HERE1

15:56:54,150 ERROR [stderr] (default task-1) com.fasterxml.jackson.databind.exc. UnrecognizedPropertyException: Unrecognized field "version" (class com.myproject.AutoItX), not marked as ignorable (0 known properties: ])

15:56:54,166 ERROR [stderr] (default task-1) at [Source: {"version":"3.3.14.2","admin":true,"error":0}; line: 1, column: 13] (through reference chain: com.myproject.AutoItX["version"])

15:56:54,166 ERROR [stderr] (default task-1) at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62)

15:56:54,166 ERROR [stderr] (default task-1) at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:851)

15:56:54,166 ERROR [stderr] (default task-1) at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1085)

15:56:54,166 ERROR [stderr] (default task-1) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1389)

Notice the line: UnrecognizedPropertyException: Unrecognized field "version" (class com.myproject.AutoItX), not marked as ignorable (0 known properties: ]). Is this an indication of it's serializability?

IanSky
  • 31
  • 6
  • You need to include AutoItX.java code and make sure it's serializable – jlewkovich Jan 29 '17 at 16:28
  • @JLewkovich How do I make sure it's serializable? Is there a certain technique? I thought that's what I was doing with `ObjectMapper`, however the above example returns an empty `Response`. Can you elaborate or provide a tutorial? Thank you – IanSky Jan 29 '17 at 17:52
  • We need to see the AutoItX class first, please provide source code. – jlewkovich Jan 29 '17 at 18:11
  • @JLewkovich, you can view the exact class [here](https://github.com/accessrichard/autoitx4java/blob/master/src/autoitx4java/AutoItX.java). _Note:_ I named the AutoItX object as "control" in my question – IanSky Jan 29 '17 at 18:39
  • You say example above returns empty response, can you inspect the contents of `control` at run time to ensure it's not blank or null. If it's non-null, you're able to post its contents in your question, that would help. – jlewkovich Jan 29 '17 at 19:03
  • @JLewkovich my application server is providing an error on this line `control = new ObjectMapper().readValue(jsonString, AutoItX.class);`, so I don't see how I can inspect the `control` object since it's not instantiated yet. I've updated the server-side code in my question, explaining the error I get - despite receiving "false" from my `POST` request. Thoughts? – IanSky Jan 29 '17 at 20:15
  • @JLewkovich here's what my IDE looks like. [Screenshot](http://imgur.com/3x4B8RC) – IanSky Jan 29 '17 at 20:21
  • So it looks like you are trying to serialize an instance of AutoItX, which is not a POJO and by default not serializable. You will have to tag the class/attributes with jackson annotations in order to make that work, but assuming that AutoItX.java is not meant to be editable, you should instead create a wrapper class that can be used to pass needed data between the client/server. – jlewkovich Jan 29 '17 at 21:02
  • @JLewkovich the only solution I've found discussing passing complex objects via a wrapper is [here](http://stackoverflow.com/a/6292702/7419673), but this involves the `@FormParam` annotation. Is that what I need? A wrapper class seems to be used to wrap primitive data types ... but the `winExists` method in AutoItX.java looks like `public boolean winExists(String title) { Variant result = winVariant(title, "WinExists"); return oneToTrue(result.getInt()); }`. So how does this fit into a wrapper class? I'm stumped – IanSky Jan 29 '17 at 22:18

0 Answers0