Role based access control as a logic program
Inspired by this article
# remotes::install_github("dirkschumacher/logician")
# a role based access control
library(logician)
role_database <- logician_database(
role(user),
role(moderator),
role(admin),
# Role A inherits from B
inherits_role(admin, moderator),
inherits_role(moderator, user),
# role action ressource
# e.g. user can store results
permission(user, see, results),
permission(moderator, delete, results),
permission(admin, delete, users),
permission(admin, add, users),
permission(admin, edit, users),
# this is the main rule for inference
# can Role do Action on Ressource?
can(Role, Action, Resource) := permission(Role, Action, Resource),
can(Role, Action, Resource) := inherits_role(Role, R) &&
can(R, Action, Resource)
)
# we check if the moderator role can see results (a property of the user role)
iter <- logician_query(role_database, can(moderator, see, results))
iter$next_value()
#> TRUE
# what roles can delete results?
iter <- logician_query(role_database, can(Role, delete, results))
iter$next_value()
#> TRUE
#> Role = moderator.
iter$next_value()
#> TRUE
#> Role = admin.
# and what can admin's do?
iter <- logician_query(role_database, can(admin, Action, Resource))
iter$next_value()
#> TRUE
#> Action = delete;
#> Resource = users.
iter$next_value()
#> TRUE
#> Action = add;
#> Resource = users.
iter$next_value()
#> TRUE
#> Action = edit;
#> Resource = users.
iter$next_value()
#> TRUE
#> Action = delete;
#> Resource = results.
iter$next_value()
#> TRUE
#> Action = see;
#> Resource = results.
iter$next_value()
#> FALSE