Permission checking and continuation functions on API using :<|>
I'm trying to make various bits of cool Servant features work together, but I'm hitting a wall.
I need to implement a cookie-based authentication with various permissions stored on the cookie.
I use a AuthHandler from `Servant.Server.Experimental.Auth`. I know about Servant-Auth, and I realize that the Experimental.Auth package is... experimental, but I'm a bit constrained by the Stack LTS we're using (8.22, which mean we use servant-0.9.1.1.). I'd like to know if there's a solution before trying to upgrade things.
The underlying authHandler function will return a custom type that will reflect permissions and information stored on the cookie. So basically, my authentication combinators, in itself, will only check if the cookie is valid or not; permission management is left to the routes implementation.
However, I want the permission checking functions to be abstract enough to be reused in various APIs.
So, imagine that we have a function like
onlyRealm ::(MonadErrorServantErr m,MonadIO m)=>Realm->MyCookie-> m a -> m a
It is basically a function that will check the the cookie has been issued with the proper realm, and execute the last parameter as a continuation if so; if not, we will throw a 403.
This works very well with simple APIs. However, it cannot compile on complex cases like this mock API:
type API =CookieProtected:>"route":>(GetAPI:<|>PutAndDeleteAPI) type GetAPI=Capture"stuff" T.Text:>Capture"stuff2" T.Text:>Get'[JSON] BusinessObject
This doesn't compile : the "go" function does not match the type constraint requested by my limitToRealm (I don't really understand why, I admit).
I know that a potential solution would be to make the permission checks as the authHandler level, but I might want to make various different checks later and this would make compositions rather difficult. So what I really want is a way of writing an abstract function able to prevent going on in the route. How can I write a simple continuation function for this kind of APIs ?