Monthly Archives: November 2016

Wrapping Text and Making Memes

Play with the meme generator here.

The project I’m moving to on Monday is written using a different tech stack than what I’ve done previously. Instead of a web service in Spark or Play, this is a world-facing web app written in Spring Boot. I’m decently comfortable with Spring for dependency injection, so jumping in isn’t too terribly weird. I chopped up their tutorials on form submission and handling uploads and built a feature-poor meme generator.

Captioning images on the server side is a task for ImageMagick, or at least it used to be. I found Im4Java, a Java wrapper last updated in 2012, and hacked together a service method to write some text on the image:

It’s not my favorite code I’ve ever written. The wrapper library is fighting an uphill battle because you’re literally just putting a string together and then executing it as a system command, and that makes it difficult to get useful feedback. You have to call those property methods on the operation object in the correct order, since they’re just concatenating the string together. It’s frustrating. But it kinda sorta worked, and the rest of the application did some file storage and form handling stuff, and it served the purpose of “play with Spring Boot.”

Unfortunately, I didn’t have the means to compute how big the text was going to end up being on the resulting image.

download

When I showed this to my friend Chase Maier, he pointed out that this is a much easier task using an HTML5 Canvas – splat the image onto the canvas, draw your text, and do whatever you want with it. Now, “play with canvas again” doesn’t count for the “play with Spring Boot” part, but we’ll still be able to do our persistence in Spring Boot later.

The full source is here, but let’s focus on the js method that’s doing the equivalent of my java code above:

It’s not that the equivalent js code is much more compact than the Java code was – the important thing is that it’s easier for me to measure the width of the lines for the sake of wrapping:

The results are much prettier:

download-1

Fractal Simplex Noise for Procedural Terrain Generation

Noise is great for procedural generation. Rather than just turning a pixel on or off in a vacuum, we apply a random gradient function over the entire output space, and so each pixel is close to its neighbors. If we interpret the output of Perlin noise as being a brightness value for each pixel, for instance, we get something like this, depending on the scale of our function:

perlinnoise2d1x2x

Like a freeze frame of the static you’d get on an old tube TV tuned to a channel that didn’t exist, kind of.

We can re-scale the noise function’s input so that the gradient bounces back and forth more or less quickly between values. Simplex noise at a very small scale looks like this:

static

Now, neither of the above are particularly believable terrain, at least not on their own. In the past, I’d tried generating terrain by taking relatively course noise, and summing it with some deterministic function, like the distance from the center of the output space, or the distance from the edges. That worked okay, but resulted in very circular or very square islands, with a high peak in the center.

A better approach, at least for rapid development, is to re-scale our noise function so that we have relatively course noise responsible for the general outline of the world, and finer and finer noise functions added to it to create some excitement around the edges.

We can supply whatever value we’d like for the number of iterations – I think 5 is about right, but if you want your terrain to be more chaotic and for your daring adventurer to have less walking between mountains or bodies of water, you can reduce it.

The ‘tectonics’ function is my name for actually grabbing the noise for this iteration and adding the value to a given pixel:

That “maxElevationBeforeRescaling” variable is determined based on how many iterations we’re going to perform:

Running the code above (with the height and width supplied, and something to paint in an html5 canvas) we can get some pretty clouds:

clouds

That’s much nicer than the original static. WIth colors, we can make it clear:

And ultimately we get a pretty convincing distinction between land and water:

islands

You can hit kaiserleib.github.io/islands and refresh to get different coastlines, or view the complete source at github.com/kaiserleib/islands.

The thing that’s most impressive to me about this approach is how compact it is, given how nice the output is. With 50 or so lines of code (assuming we take the Simplex noise function as a given) we get a reasonably believable world, complete with elevation data. The generation process doesn’t mesh at all with real geology, but it’s compatible with algorithms for rainfall and erosion and biome placement and you can get a realistic-looking world out of it.

Now, it’s not terribly runtime-efficient. You have to compute Simplex noise five times for each pixel, which adds up fast. But it’s a comprehensible approach.

Selectively Disable-able Java CSRF Filters in Play! 2.5

I’ve written a little bit about CSRF (Cross-Site Request Forgery) protection before. Play provides strong CSRF protection out of the box, which is one of the things I like about the framework. To enable across-the-board CSRF protection, you create the following file, at app/filters/Filters.java:

Then enable the CSRF filter in application.conf:

And add a dependency for filters to build.sbt:

This will apply Play’s default, strong CSRF protection to every request which contains any cookies in the header.

In some cases, though, it’s important to be able to let cross-site requests happen for some (but not all) requests. In this case, ‘forgery’ is a misnomer, because we want the user to be able to make a request from our world-facing app, hit a microservice (for, say, authentication), and see results rather than being unceremoniously kicked out by an error message.

The most straightforward way to do that is with a blacklist: instead of you add an @RequireCSRFCheck annotation to all the form post methods which require CSRF filtering, and an @AddCSRFToken annotation to the action methods which generate those forms. This is tedious if you have many methods which require CSRF filtering and few that don’t. It’s also error-prone, and any oversight results in your security failing open rather than closed, which is not what we want.

Fortunately, although it’s not quite as straightforward, we do still have the ability to selectively disable a global CSRF filter, with just a little work. Moreover, we can do it in Java!

Steve Chaloner provides an excellent answer on StackOverflow detailing how to decorate Play’s routes file with comments to disable CSRF on a per-action basis. At SoFi, we like annotations, so we did it a little bit differently.

First, define an annotation:

We’ll use this annotation on any action method we don’t want to protect against CSRF.

Having defined the annotation, we then define a custom CSRF filter, which will replace the CSRFFilter in Filters.java. Save it as app/filters/AnnotationDisablableCSRFFilter.java:

The important distinction between my solution here and Steve’s solution from the stackoverflow answer is that we’re grabbing the class and method to which the request was made, then inspecting it for the presence of our @DisableCSRFCheck annotation.

Having implemented our custom filter, we then update the constructor of Filters.java, replacing the default CSRFFilter with our AnnotationDisablableCSRFFilter:

Whereupon we can go through and apply the @DisableCSRFCheck annotation to the action methods we wish to open to cross-site requests.