lib/alchemy/permissions.rb
# frozen_string_literal: true
module Alchemy
# ## Alchemy's permissions
#
# These are CanCan abilities, but to prevent any naming collusions we named it permissions.
#
# Alchemy user rules are modules that can be included in your app's/engine's Ability class.
#
# ### Example:
#
# # app/models/ability.rb
# class Ability
# include CanCan::Ability
# include Alchemy::Permissions::EditorUser
#
# def initialize(user)
# return if user.nil?
# @user ||= user
# if @user.has_role?(:demo)
# alchemy_editor_rules # alchemy editor roles
# # your own rules
# end
# end
# end
#
class Permissions
include CanCan::Ability
def initialize(user)
set_action_aliases
@user ||= user
@user ? user_role_rules : alchemy_guest_user_rules
end
module GuestUser
def alchemy_guest_user_rules
can([:show, :download], Alchemy::Attachment) { |a| !a.restricted? }
can :read, Alchemy::Element, Alchemy::Element.published.not_restricted do |e|
e.public? && !e.restricted?
end
can :read, Alchemy::Page, Alchemy::Page.published.not_restricted.from_current_site do |p|
p.public? && !p.restricted? && p.site == Alchemy::Current.site
end
end
end
# == Member rules
#
# Includes guest users rules
#
module MemberUser
include Alchemy::Permissions::GuestUser
def alchemy_member_rules
alchemy_guest_user_rules
# Resources
can [:show, :download], Alchemy::Attachment
can :read, Alchemy::Element, Alchemy::Element.published do |e|
e.public?
end
can :read, Alchemy::Page, Alchemy::Page.published.from_current_site do |p|
p.public? && p.site == Alchemy::Current.site
end
end
end
# == Author rules
#
# Includes member users rules
#
module AuthorUser
include Alchemy::Permissions::MemberUser
def alchemy_author_rules
alchemy_member_rules
# Navigation
can :index, [
:alchemy_admin_attachments,
:alchemy_admin_dashboard,
:alchemy_admin_layoutpages,
:alchemy_admin_nodes,
:alchemy_admin_pages,
:alchemy_admin_pictures,
:alchemy_admin_tags,
:alchemy_admin_users
]
# Controller actions
can :leave, :alchemy_admin
can [:info, :help], :alchemy_admin_dashboard
can :manage, :alchemy_admin_clipboard
can :edit, :alchemy_admin_layoutpages
can :tree, :alchemy_admin_pages
# Resources
can [:read, :download], Alchemy::Attachment
can :manage, Alchemy::Element
can :manage, Alchemy::Ingredient
can [:crop], Alchemy::Ingredients::Picture
can :manage, Alchemy::LegacyPageUrl
can :manage, Alchemy::Node
can [:read, :url], Alchemy::Picture
can [:read, :autocomplete], Alchemy::Tag
can :edit_content, Alchemy::Page, Alchemy::Page.all do |page|
page.editable_by?(@user)
end
end
end
# == Editor rules
#
# Includes author rules
#
module EditorUser
include Alchemy::Permissions::AuthorUser
def alchemy_editor_rules
alchemy_author_rules
# Navigation
can :index, [
:alchemy_admin_languages,
:alchemy_admin_users
]
# Resources
can [
:copy,
:copy_language_tree,
:flush,
:order,
:switch_language
], Alchemy::Page
# Resources which may be locked via template permissions
#
# # config/alchemy/page_layouts.yml
# - name: contact
# editable_by:
# - freelancer
# - admin
#
can([
:create,
:destroy
], Alchemy::Page) { |p| p.editable_by?(@user) }
can(:publish, Alchemy::Page) do |page|
page.language.public? && page.editable_by?(@user)
end
can :manage, Alchemy::Picture
can :manage, Alchemy::PictureDescription
can :manage, Alchemy::Attachment
can :manage, Alchemy::Tag
can :index, Alchemy::Language
can :switch, Alchemy::Language
end
end
# == Admin rules
#
# Includes editor rules
#
module AdminUser
include Alchemy::Permissions::EditorUser
def alchemy_admin_rules
alchemy_editor_rules
# Navigation
can :index, [:alchemy_admin_sites, :alchemy_admin_styleguide]
# Controller actions
can [:info, :update_check], :alchemy_admin_dashboard
# Resources
can :manage, Alchemy::Language
can :manage, Alchemy::Site
end
end
private
def user_role_rules
return alchemy_guest_user_rules if @user.alchemy_roles.blank?
@user.alchemy_roles.each do |role|
exec_role_rules(role)
end
end
def exec_role_rules(role)
meth = :"alchemy_#{role}_rules"
send(meth) if respond_to?(meth)
end
def set_action_aliases
alias_action :configure,
:fold,
:info,
:link,
:read,
:update,
:unlock,
:visit,
:tree,
to: :edit_content
end
# Include the role specific permissions.
include GuestUser
include MemberUser
include AuthorUser
include EditorUser
include AdminUser
end
end