Application logic versus authorization

I use cancan

gem in Rails, but it's probably more general than this.

Short introduction. In cancan

you define authorization as follows:

can :read, Post
can :manage, Post if user.is_admin?
can :manage, Post do |post| post.author == user end

      

This means that anyone can read Post

s, but only the author and administrators can control (edit / destroy) them.

Now I would like to change my application logic so that you cannot delete the post if it has any comments (unless you are an administrator). It's still easy with cancan

(added at the end of the previous snippet):

cannot :destroy, Post do |post| post.comments.count > 0 && !user.is_admin? end

      

And that means I can use the following pseudocode in the view (HTML template):

<h1><%=post.title%></h1>
<p><%=post.text%></p>
<%=link_to 'Edit', edit_post_path(post) if can? :edit, post%>
<%=link_to 'Delete', delete_post_path(post) if can? :destroy, post%>

      

My only question is, is it smart to mix permissions with application logic? It seems messy, but on the other hand, I need to break DRY and replace it with double checks everywhere in the application (frontend, API, etc.).

<h1><%=post.title%></h1>
<p><%=post.text%></p>
<%=link_to 'Edit', edit_post_path(post) if post.can_be_edited? && can? :edit, post%>
<%=link_to 'Delete', delete_post_path(post) if post.can_be_destroyed? && can? :destroy, post %>

      

+3


source to share


2 answers


I don't see any problem setting checks for authorization behavior in the place you suggested. As you mentioned, the alternative is worse. It also means that someone can easily look in one place to see the authorization diagram for Post

, which is highly desirable. The alternative (having checks in multiple places) is much more difficult to maintain and justify, not to mention that changes need to be edited in multiple places, and it is just a "gentleman's convention" for a developer to edit them all at the same time, which keeps them in sync.



+1


source


In addition to tmruss's comment , I would like to add that what you are trying to do with cancan

is called external authorization. This is a great approach. You should always strive to separate your authorization logic from your business logic.

The most important thing at the end is that you do the checks in the appropriate places. If you do not know what these relevant places are, then you need to go back to the drawing board of the application to determine all the entry points. These entry points are where you want to apply fine-grained authorization / cancan

.



See XACML Reference Architecture for a formal architectural overview.

0


source







All Articles