Building a Blog in Haskell with Yesod–Authorization

Posted on August 5, 2019 by Riccardo.

Building a Blog in Haskell with Yesod (Series)

Building a Blog in Haskell with Yesod–The Basic Structure Building a Blog in Haskell with Yesod–Using a Database Building a Blog in Haskell with Yesod–Authentication Building a Blog in Haskell with Yesod–Authorization Building a Blog in Haskell with Yesod–Returning JSON Building a Blog in Haskell with Yesod–JSON API Building a Blog in Haskell with Yesod–Giving Back

This is a series about Yesod: a Haskell web framework that follows a similar philosophy to Rails. In fact, it is strongly opinionated and provides a lot of functionality out of the box.

A good read about Yesod is available online for free: Developing web applications with Haskell and Yesod. That’s why this series will be a commentary of the commits from a repo we will use to develop a super simple blog.

In other words, this won’t be good material to learn how to use Yesod. However, it will hopefully give an overview of how the framework works.

Who’s the Author?

Up until now, the logged-in user didn’t have any relationships with the posts. Commit b9ed6789ed578e4349f9fc0eee670e2df87434be adds a userId to Post and makes sure it gets filled with the id of the authenticated user.

Authorize Deletions

In a multi-author blog, only the owner should be allowed to delete a post. Commit db722e785cc09ad5642486df17c770e85899648c takes care of that. The important bit is the following

isAuthorized (PostR postId) _ = isOwner postId

Delete Button

Since only the owner can delete a post, it makes sense to reflect that in the UI. Commit 2378194354b6e0e92fb1c83ac5feb97aac8d219b does exactly that:

$if userId == (postUserId $ entityVal post)

Show me the Author!

The last thing to do is to show the author names alongside their blogposts. Given our database schema (config/models.persistentmodels)

    ident Text
    password Text Maybe
    title Text
    text Textarea
    userId UserId

we need to perform a join between user and post.

Unfortunately, the default database library for Yesod, Persistent, doesn’t support joins in a type-safe way. In fact, the only way would be to use rawSql.

Luckily, we can easily add Esqueleto which builds on top of Persistent and is capable of performing type-safe joins: 78ef59c6e6718dbce83ea2802cb70335bb4cca33

Screenshot or didn’t Happen!

Here we can see that the delete button is shown only to the owner of the post and that the author names is displayed together with title and text:

Screenshot of the blog with two posts where the current user can only delete their post

Support my work by tweeting this article! 🙏