Skip to content

How to setup access_policy.rb when roles are not part of a user model? #51

@marekdlugos

Description

@marekdlugos

I'm pretty new to Rails, however, I work on the app where I have this trio: users, wikis, wiki_users. Many users can be assigned to many wikis and vice versa.

I struggle with connecting my access_policy.rb file with Rails. How could I let the gem know that it should look for user, assigned to a specific wiki with a specific role on that specific wiki?

# wiki_user.rb
  belongs_to :user
  belongs_to :wiki

  enum role: { owner: 1, administrator: 2, moderator: 3, contributor: 4, reader: 5 }
# user.rb
...
  has_many :wiki_users, dependent: :destroy
  has_many :wikis, through: :wiki_users
...
  def wiki_user_role(role)
    wiki = Wiki.find_by_subdomain request.subdomain
    wiki.users.include?(self) && wiki.wiki_users.find_by_user_id(self.id).role == role
  end
# project.rb
...
  has_many :wiki_users, dependent: :destroy
  has_many :users, through: :wiki_users
...

My project_users table contains columns id (of the relationship), user_id, project_id, and role. My access_policy.rb file looks like this so far, with some effort to make it work in role :reader block. However, it all feels just like a workaround and I am wondering whether this scenario can't be handeled in easier manner?

  def configure

    # ROLES
    # Owner — a person who handles payments, e.g. owner of the company
    # Administrator — administrator who does not care ab payments only ab the wiki itself
    # Moderator — can create and edit other people articles
    # Contributor — can only create and edit his own articles
    # Reader (guest) — only the permission to read

    role :owner, proc { |user| user.present? } do
      can [:edit, :update, :destroy], Article
      can [:edit, :update, :destroy], Comment
      can [:edit, :update, :destroy], User
      can [:edit, :update, :destroy], Wiki

    end

    role :administrator, proc { |user| user.present? } do
      can [:edit, :update, :destroy], Article
      can [:edit, :update, :destroy], Comment
      can [:edit, :update, :destroy], User

    end

    role :moderator, proc { |user| user.present? } do
      can [:edit, :update, :destroy], Article
      can [:edit, :update, :destroy], Comment

    end

    role :contributor, proc { |user| user.present? } do
      can [:edit, :create, :destroy], Article do |article, user|
        article.user_id == user.id
      end

      can [:edit, :create, :destroy], Comment do |comment, user|
        comment.user_id == user.id
      end
    end

    role :reader, proc { |user| user.present? && user.wiki_user_role("reader") } do
      can :read, Article do |article, user|
        article.wiki.users.include? user
      end

      can :read, User do |selected_user_and_wiki, user|
        selected_user = selected_user_and_wiki.first
        wiki = selected_user_and_wiki.second

        wiki.users.include?(selected_user) && wiki.users.include?(user)
      end

      can [:edit, :destroy], User do |edited_user, user|
        edited_user == user
      end
    end

  end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions