Basic Authentication in DukeScript

I’m currently writing a little NetBeans Plugin with DukeScript. The Plugin allows you to show, filter and sort the issues of a Bitbucket project inside NetBeans. For this I need to make authenticated calls to the Bitbucket API. Here’s how I do that.

In DukeScript we’re using @OnReceive to connect to a REST endpoint. Here’s the example from the @OnReceive Javadoc:

 @Model(className="MyModel", properties={
   @Property(name = "people", type=Person.class, array=true)
 })
 class MyModelImpl {
   @Model(className="Person", properties={
     @Property(name = "firstName", type=String.class),
     @Property(name = "lastName", type=String.class)
   })
   static class PersonImpl {
     @ComputedProperty
     static String fullName(String firstName, String lastName) {
       return firstName + " " + lastName;
     }
   }

   @OnReceive(url = "{protocol}://your.server.com/person/{name}")
   static void getANewPerson(MyModel m, Person p) {
     System.out.println("Adding " + p.getFullName() + '!');
     m.getPeople().add(p);
   }

   // the above will generate method getANewPerson in class MyModel.
   // with protocol and name arguments
   // which asynchronously contacts the server and in case of success calls
   // your @OnReceive with parsed in data

   @Function
   static void requestSmith(MyModel m) {
     m.getANewPerson("http", "Smith");
   }
 }

If the REST-Endpoint requires basic authentication, we’ll need to somehow get hold of a username and password. Let’s assume we get them from a form and store them in the viewmodel:

 @Model(className="MyModel", properties={
   @Property(name = "people", type=Person.class, array=true),
// adding two new Properties:
   @Property(name = "username", type=String.class),
   @Property(name = "password", type=String.class)
 })
 class MyModelImpl {
   //...
 }

We’ll use the HTTP-Authorization-header to authenticate. For this, we need to encode username and password in a String. I’ve written a little function for that:

public class Authenticator {

    @JavaScriptBody(args = {"username", "password"}, body = "return btoa(username+':'+password)")
    public static native String getAuthenticationString(String username, String password);
}

Now we add the Authorization Header to the call by declaring it in the Annotation:

   @OnReceive(url = "{protocol}://your.server.com/person/{name}", 
   // headers can be added declaratively
   // For the dynamic part "{auth}" we'll get a new parameter in the generated method.
   headers = {"Authorization: Basic {auth}"})
   static void getANewPerson(MyModel m, Person p) {
     System.out.println("Adding " + p.getFullName() + '!');
     m.getPeople().add(p);
   }

The generated method will now have an additional parameter, so the call changes to:

   @Function
   static void requestSmith(MyModel m) {
     m.getANewPerson("http", "Smith", Authenticator.getAuthenticationString(m.username, m.password));
   }

That’s how you add basic authentication to DukeScript.