Skip to content

Instantly share code, notes, and snippets.

@saurabhnanda
Last active July 3, 2019 04:10
Show Gist options
  • Select an option

  • Save saurabhnanda/b783c4a99d56c527613cf6cb3febce4c to your computer and use it in GitHub Desktop.

Select an option

Save saurabhnanda/b783c4a99d56c527613cf6cb3febce4c to your computer and use it in GitHub Desktop.

@K.A.Buhr, wow! Thank you for such a detailed reply. You are correct that this is an XY problem, and you've pretty-much nailed the actual problem that I'm trying to solve. Another important piece of context is that, at some point these type-level permissions will have to be "reified" at the value-level. This is because the final check is against the permissions granted to the currently signed-in user, which are stored in the DB.

Taking this into account, I'm planning to have two "general" functions, say:

requiredPermission :: (RequiredPermission p ps) => Proxy p -> AppM ps () 

optionalPermission :: (OptionalPermission p ps) => Proxy p -> AppM ps ()

Here's the difference:

  • requiredPermission will simply add the permission to the type-level list and it will be verified when runAppM is called. If the current user does not have ALL the required permissions, then runAppM will immediately throw a 401 error to the UI.
  • On the other hand, optionalPermission will extract the user from the Reader environment, check the permission, and return a True / False. runAppM will do nothing with OptionalPermissions. These will be for cases where the absence of a permission should NOT fail the entire action, but skip a specific step in the action.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment