How to Implement Complex Security Rules in Ruby on Rails

I have a system that I am creating that seems to require some complicated rules and instead of having a mess of rules through the system. I tried to centralize the process. (This may not be the smartest idea I had)

My most (perhaps least) brilliant idea was to use a separate class to validate any objects before storing them in the database against a list of allowed values ​​in different fields. It is extremely tightly coupled with the structure of the database, but is fairly easy to test and easy to maintain.

Examples of rules:

  • Moderators can post comments with moderator status, but not administrator status.
    • Comments.status can only be normal or moderated (admin is reserved for admins)
  • Users cannot change the value of the moderator when commenting
    • Comments.status can only be normal, Comments .display can only be normal
  • Only moderators can suspend user accounts
    • list of numerous fields
  • Only moderators can modify other user accounts
    • restriction on which fields with logic determine whether the current user belongs to a row
  • Only users with a paid account can do X, Y and Z.

The problem I am facing is where I can put this logic. It's too hard to check the rails. Some of these rules are difficult or impossible to implement if I just look at the user's registered status. The current solution is to create a security class that will accept the database object and user and allow or deny the action.

If I follow this course, the implementation is nasty. Right now I'm looking at something like this

#For every field on an object passed to Security::allow?(user, object), call this private method
def allow_helper?(user, object, field) 
    perm = permissions[user.rank][object.class.name][field] 
    if perm.is_a? Array
          perm.include? object.send(field)
    else
          perm

      

This will quickly become a maintenance nightmare. There must be an alternative to this nightmare that I dreamed of. I stopped before I coded this.

+1


a source to share


1 answer


Why don't you create a model Permissions

and then just see if user.permissions.find(:permission_name_here)

when designing validations and views?



0


a source







All Articles