Topalov Alex 2015
Author could create post
Author could create posts
... of blogs
Authors could create posts
... of their blogs
... if the blog is active
Authors could create posts
... of their blogs
... if the blog is active
... but only on workdays
Authors could create posts
... of their blogs
... if the blog is active
... but only on workdays
... and when the author has a confirmed contract
Authors could create posts
... of their blogs
... if the blog is active
... but only on workdays
... and when the author has a confirmed contract
... or when they're acting as a proxy for a sick colleague
1. Restrict access to a resource. A user may only see her own posts 2.One resource, different restrictions A user may edit her posts if they aren't published yet 3. User roles/rights. What posts a user may see depends on his role/right 4. Sensitive attributes Authors may edit a post, but only admins may change its state 5. Restricting attributes/values Authors may change the state of a post, but only admins may set it to 'published' 6. Restricting what may be associated Users with locked accounts may not be assigned as post authors 7. Authorized values that depend on other fields A user may change the state of all posts, but only publish posts by their subordinates.
class Post < ActiveRecord::Base
belongs_to :author
validate :author_is_admin
private
def author_is_admin
unless author.admin?
errors.add(:author_id, 'must be an admin')
end
end
end
class PostsController < ApplicationController
def update
post = Post.find(params[:id])
if post.author != current_user
raise "Trying to edit unauthorized post!"
end
if params[:post][:edited]
raise "Trying to set unauthorized value!"
end
post.update_attributes(params[:post])
end
end
class User
has_many :departments
has_many :autorizations, as: :autorizable
has_many :rights, through: :rights
def assign_new_department(department)
autorizations << *department.autorizations
end
end
class Autorization
belongs_to :autorizable, polymorphic: true
has_many :rights
# Fields of content.
# autorizable_id - either User ID or Department ID
# autorizable_type - either user or department
# right_id - ID of applicable right
# meta - JSON object of options:
# scope: Scope of an object (published, all, posts etc)
# allowed_attributes: Attributes that allowed for right entity
end
Each object that should have autorization have their own Policy class that contain all specific logic about autorization
class PostController
def index
@posts = PostPolicy.new(current_user, :read).posts
end
def show
@post = PostPolicy.new(current_user, :read).posts.where(id: params[:id]).first
end
def new
@post = PostPolicy.new(current_user, :create, {author_id: params[:author_id]}).build_post
end
def create
@post = PostPolicy.new(current_user, :create, params[:post]).build_post
if @post.save
return redirect_to post_path(@post)
else
render :new
end
end
end
class PostPolicy
def initialize(user, action, options = {})
@user = user
@action = action
@right = user.rights.where(action: action, entity: 'Product')
@autorization = user.autorizations.where(right_id: @right.id)
end
def build_product
return unless @right
Product.new(sanitized_params)
end
def products
return unless @right
begginging_of_association_tree
end
def sanitazed_params
options[:params].slice(@autorization.meta(:permitted_params))
end
private
def begginging_of_association_tree
Product.public_send(@autorization.meta(:scope))
end
end
1. https://github.com/elabs/pundit
2. https://github.com/makandra/consul
3. https://github.com/makandra/assignable_values