Skip to content

Instantly share code, notes, and snippets.

@the-teacher
Created November 29, 2019 19:45
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save the-teacher/05a7f85237c756c4560017d31491597e to your computer and use it in GitHub Desktop.
roles-post-1
class PostsController < ApplicationController
def index
# ...
end
def show
# ...
end
def create
# ...
end
def update
@post = @current_user.posts.find(params[:id])
@post.update!(post_params)
redirect_to @post
end
private
def post_params
params.require(:post).permit(:title, :content)
end
end
@the-teacher
Copy link
Author

class PostsController < ApplicationController
  def index
    # ...
  end

  def show
    # ...
  end
  
  def create
    # ...
  end

  def update
    @post = Post.find(params[:id])
    @post.update!(post_params)
    redirect_to @post
  end

  private

  def post_params
    params.require(:post).permit(:title, :content)
  end
end

@the-teacher
Copy link
Author

+------------------+
+ User             +
+------------------+
+                  +
+ id: 1            +
+ full_name: Admin +
+                  +
+------------------+

+------------------+
+ User             +
+------------------+
+                  +
+ id: 2            +
+ full_name: Alex  +
+                  +
+------------------+

+------------------+
+ User             +
+------------------+
+                  +
+ id: 3            +
+ full_name: Bob   +
+                  +
+------------------+

+-------------------+
+ Post              +
+-------------------+
+                   +
+ id: 1             +
+ user_id: 2 (Alex) +
+ Title: Post 1     +
+                   +
+-------------------+

+-------------------+
+ Post              +
+-------------------+
+                   +
+ id: 2             +
+ user_id: 2 (Alex) +
+ Title: Post 2     +
+                   +
+-------------------+

+-------------------+
+ Post              +
+-------------------+
+                   +
+ id: 3             +
+ user_id: 3 (Bob) +
+ Title: Post 3     +
+                   +
+-------------------+

@the-teacher
Copy link
Author

the-teacher commented Nov 30, 2019

class ACL
  ALEX_PERMISSIONS = {
     index: true,
     show: true,
     create: true,
     edit: true,
     update: true,
     delete: false
  }

  BOB_PERMISSIONS = {
    index: true,
    show: true,
    create: true,
    edit: true,
    update: true,
    delete: true
  }

  def self.check_permission?(user, action)
   puts ALEX_PERMISSIONS
  end
end

@the-teacher
Copy link
Author

class PostsController < ApplicationController
  before_filter :check_permissions, only: [:create, :edit, :update, :delete]

  before_filter :find_post, only: [:edit, :update, :delete]
  before_filter :check_ownership, only: [:edit, :update, :delete]
  
  def index
    # ...
  end

  def show
    # ...
  end
  
  def create
    # ...
  end

  def update
    @post.update!(post_params)
    redirect_to @post
  end

  private

  def post_params
    params.require(:post).permit(:title, :content)
  end

  def find_post
    @post = Post.find(params[:id])
  end

  def check_permissions
    has_access = ACL.check_permission(@current_user, self.action_name)

    unless has_access
      redirect_to root_path, alert: "Lack of permissions"
    end
  end

  def check_ownership
    @current_user.owner?(@post)
    redirect_to root_path, alert: "Not an owner"
  end
end

@the-teacher
Copy link
Author

class ACL
  REGULAR_USERS = [1]
  ADVANCED_USERS = [2]
  
  REGULAR_PERMISSIONS = {
     index: true,
     show: true,
     create: true,
     edit: true,
     update: true,
     delete: false
  }

  ADVANCED_PERMISSIONS = {
    index: true,
    show: true,
    create: true,
    edit: true,
    update: true,
    delete: true
  }

  DEFAULT_PERMISSIONS = {
    index: true,
    show: true
  }

  def self.check_permission?(user, action)
    return true if user.admin?

    if REGULAR_USERS.include?(user.id)
      return REGULAR_PERMISSIONS[action]
    end

    if ADVANCED_USERS.include?(user.id)
      return ADVANCED_PERMISSIONS[action]
    end
    
    return DEFAULT_PERMISSIONS[action]
  end
end

@the-teacher
Copy link
Author

class ACL
  REGULAR_USERS = [1] # Alex
  ADVANCED_USERS = [2] # Bob
  
  REGULAR_PERMISSIONS = {
     index: true,
     show: true,
     create: true,
     edit: true,
     update: true,
     delete: false
  }

  ADVANCED_PERMISSIONS = {
    posts_index: true,
    posts_show: true,
    posts_create: true,
    posts_edit: true,
    posts_update: true,
    posts_delete: true,

    users_index: true,
    users_show: true,
    users_create: true,
    users_edit: true,
    users_update: true,
    users_delete: false
  }

  DEFAULT_PERMISSIONS = {
    index: true,
    show: true
  }

  def self.check_permission?(user, where, what)
    return true if user.admin?

    action = [where, what].join('_')

    if REGULAR_USERS.include?(user.id)
      return REGULAR_PERMISSIONS[action]
    end

    if ADVANCED_USERS.include?(user.id)
      return ADVANCED_PERMISSIONS[action]
    end
    
    return DEFAULT_PERMISSIONS[action]
  end
end

@the-teacher
Copy link
Author

@the-teacher
Copy link
Author

module Post
  class AuthorAbilities
    include Kan::Abilities

    role(:author) do |user, post|
      user.id == post.author_id
    end

    register(:read, :edit) { |_, _| true }
    register(:delete) { |_, _| false }
  end

  class AdminAbilities
    include Kan::Abilities

    role(:admin) do |user, _|
      user.admin?
    end

    register(:read, :edit, :delete) { |_, _| true }
  end
end

class UserPolicy
  attr_reader :current_user, :model

  def initialize(current_user, model)
    @current_user = current_user
    @user = model
  end

  def index?
    @current_user.admin?
  end

  def show?
    @current_user.admin? or @current_user == @user
  end

  def update?
    @current_user.admin?
  end

  def destroy?
    return false if @current_user == @user
    @current_user.admin?
  end
end

require 'cancancan'

class Ability
  include CanCan::Ability

  def initialize(user)
    send("#{user.role}_abilities", user)
  end

  def admin_abilities(user)
    can :manage, :all
  end

  def member_abilities(user)
    can :read, :all
    can :manage, Article, { author_id: user.id }
    can [:read, :update], User, { id: user.id }
  end

  def visitor_abilities(user)
    can :read, :all
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment