Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do (role-based) access control in Yesod?

I'm wondering what the best approach for adding roles to users / permissions to Handlers or resources in Yesod is. Does anyone have prior art for this kind of thing? Are there any approaches that leverage the type-system to help prevent slip-ups (and also keep database queries to check for ownership etc to a minimum)?

EDIT: Sorry for missing this before-hand - I do notice that there's actually a section, which I somehow missed at first glance (I think because there's no mention of access/roles/permissions), on Authorization in the Yesod book. This appears to do access control at the router level with a write flag for PUT/POST. It doesn't seem terribly sophisticated by itself, but it looks just fine for building abstractions on top...

like image 897
Rehno Lindeque Avatar asked Mar 09 '14 15:03

Rehno Lindeque


People also ask

How do I set up role based access control?

Under Access Settings, click New. Under New Setting, use the drop-down list under Select role to choose a role for this user. Click New again to add additional access scopes, or click OK to finish.

How user's access can be restricted using role-based login?

By adding a user to a role group, the user has access to all the roles in that group. If they are removed, access becomes restricted. Users may also be assigned to multiple groups in the event they need temporary access to certain data or programs and then removed once the project is complete.

What is role-based access an example of?

One role-based access control example is a set of permissions that allow users to read, edit, or delete articles in a writing application. There are two roles, a Writer and a Reader, and their respective permission levels are presented in this truth table. Using this table, you can assign permissions to each user.


1 Answers

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?)

like image 152
Rehno Lindeque Avatar answered Sep 30 '22 08:09

Rehno Lindeque