Skip to content

Instantly share code, notes, and snippets.

@RStankov
Last active December 31, 2015 15:09
Show Gist options
  • Save RStankov/8005445 to your computer and use it in GitHub Desktop.
Save RStankov/8005445 to your computer and use it in GitHub Desktop.
Concept for access control
class Ability
Error = Class.new(StandardError)
AccessDenied = Class.new(Error)
NotImplemented = Class.new(Error)
def initialize(user)
@user = user
end
def ensure_can(action, subject)
# TODO use the action
raise AccessDenied.new unless can_access? subject
end
private
def can_access?(subject)
return false unless subject
method = "can_access_#{subject.class.name.underscore}?"
raise NotImplemented.new("Implement rules for #{subject.class.name}") unless respond_to? method, true
send method, subject
end
def can_access_photo?(photo)
photo.owner == @user || can_access_album?(photo.album)
end
def can_access_album?(album)
album.creator = @user || can_access_account?(album.account)
end
def can_access_account?(account)
account.member? @user
end
end
class AccessiblePhotos
def initialize(user, ability = nil)
@user = user
@ability = ability || Ability.new(user)
end
def find(id)
find_photo :view, id
end
def create(attributes)
CreatePhoto.call user, attributes
end
def update(id, attributes)
photo = find_photo :update, :id
photo.update attributes
photo
end
def destroy(id)
photo = find_photo :delete, :id
photo.destroy
photo
end
private
def find_photo(action, id)
photo = Photo.find id
@ability.ensure_can action, record
photo
end
end
class PhotosController < ApplicationController
def create
@photo = photos.create photo_params
respond_with @photo
end
def show
@photo = photos.find photo_id
respond_with @photo
end
def update
@photo = photos.update photo_id, photo_params
respond_with @photo
end
def destroy
@photo = photos.destroy photo_id
respond_with @photo
end
private
def photos
AccessiblePhotos.new current_user
end
def photo_id
params[:id]
end
def photo_params
params.permit :name # ,...
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment