DEV Community


Posted on

How to use casbin authorization in your rust web-app [Part - 2]

This is the second part of the blog about casbin.
Here we will discuss about the casbin model that we shall use in our project application.

Here is the link of a sample policy file.

p, user_role_post_publish, post_publish_group, (POST)|(GET)
p, user_role_user, user_group, (DELETE)|(POST)
p, admin_role_user_manage, user_manage_group, (GET)|(DELETE)
p, admin_role_post_manage, post_manage_group, (GET)|(DELETE)

g2, /api/post, post_publish_group
g2, /api/admin/posts, post_manage_group
g2, /api/user/logout, user_group
g2, /api/user, user_group
g2, /api/admin/users, user_manage_group
g2, /api/admin/post/:id, post_manage_group
g2, /api/admin/user/:id, user_manage_group
g3, /api/post/:id, publicAction
g3, /api/posts, publicAction
g3, /api/auth/login, publicAction
g3, /api/auth/signup, publicAction

g, admin, admin_role_user_manage
g, admin, admin_role_post_manage
g, admin, user_role_post_publish
g, admin, user_role_user
Enter fullscreen mode Exit fullscreen mode

Let's try to understand this -
p here represents policy. Policies generally have 3 parts -
subject, object and action. Here they can be understood as user role, path and request method.
Furthermore, we can assign a group to our object or as used here, path.
For example,
The first line of the file is

p, user_role_post_publish, post_publish_group, (POST)|(GET)
Enter fullscreen mode Exit fullscreen mode

This is a policy where all users that have the role user_role_post_publish can make a POST and GET request on the subject post_publish_group, which is a group. post_publish_group has the /api/post path, as mentioned in the file -

g2, /api/post, post_publish_group
Enter fullscreen mode Exit fullscreen mode

Similarly, when we write

p, user_role_user, user_group, (DELETE)|(POST)
Enter fullscreen mode Exit fullscreen mode

It simply means that users with user_role_user role can make DELETE and POST requests on url paths in the user_group group. These url paths are /api/user/logout and /api/user.

publicAction is a group which has paths which are accessible to every user regardless of role.

A group can have multiple url paths, an url path cannot belong to more than one group.

Next, the .conf file -

r = sub, obj, act

p = sub, obj, act

g = _, _
g2 = _, _
g3 = _, _
g4 = _, _

e = some(where (p.eft == allow))

m = g(r.sub, p.sub) && g2(r.obj, p.obj) && regexMatch(r.act, p.act) || g3(r.obj, "publicAction") || r.sub == "root"
Enter fullscreen mode Exit fullscreen mode

As mentioned in the first blog, request_definition is the syntax of our request. First we have the subject, sub, then we have the object, obj, and then the action, act.
In our example, sub is the role, obj is the url path/group of url paths, and act is a HTTP method.
policy_definition should match with the request_definition for things to not break.(think of this as a schema)
Now we have role_definition, from where casbin reads what each role has access to(for example, let's say some employee role has access to /api/tasks/:userId/today).

In policy_effect here, e = some(where (p.eft == allow)) translates to - if the matching strategy result p.eft has the result of (some) allow, then the final result is true.

In matchers, we are checking if the request and policy components are equal. We are using regexMatch to check actions because here they are HTTP methods.
For example the final result is true when the request subject, r.sub is equal to root, in which case it has all the permissions. This entire expression m = g(r.sub, p.sub) && g2(r.obj, p.obj) && regexMatch(r.act, p.act) || g3(r.obj, "publicAction") || r.sub == "root" means, that if the requested parameters match with those in the policy, i.e., sub, obj and act, return the policy result ,p.eft, which is again rechecked in policy_effect.

That is all for this blog. Hope the concepts are explained well enough.
In the next blog, i.e., we will use this model in our actix-web app.
Comments below are always welcome.

And don't forget to star our repositories on Github.

Top comments (0)