In the time since posting this I have found this very helpful blog post Abstracting permissions with Yesod by Felipe Lessa. It builds on top of the existing isAuthorized
function, demonstrating a simple strategy for adding roles to users and access permissions to resources.
Basically it defines
isAuthorizedTo :: Maybe (UserId, User) -> [Permission] -> YesodDB sub Blog AuthResult
permissionsRequiredFor :: Route Blog -> Bool -> [Permission]
in order to get something like this:
isAuthorized route isWrite = do
mauth <- maybeAuth
runDB $ mauth `isAuthorizedTo` permissionsRequiredFor route isWrite
where permissionsRequiredFor
returns a list of some user defined Permission
data type like this:
data Permission = Post -- Permission to create blog posts
| CommentOn EntryId -- Permission to comment on a particular blog entry
| View EntryId -- Permission to view a particular blog entry
This is simple and practical, thank you Felipe. (It might be nice if someone tries to capture this kind of thing in library form and publish to Hackage in order to find & drop access control into your app as quickly as possible! Alternatively perhaps in the Yesod scaffold?)