Chris@1494: # Redmine - project management software Chris@1494: # Copyright (C) 2006-2014 Jean-Philippe Lang Chris@1494: # Chris@1494: # This program is free software; you can redistribute it and/or Chris@1494: # modify it under the terms of the GNU General Public License Chris@1494: # as published by the Free Software Foundation; either version 2 Chris@1494: # of the License, or (at your option) any later version. Chris@1494: # Chris@1494: # This program is distributed in the hope that it will be useful, Chris@1494: # but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@1494: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@1494: # GNU General Public License for more details. Chris@1494: # Chris@1494: # You should have received a copy of the GNU General Public License Chris@1494: # along with this program; if not, write to the Free Software Chris@1494: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Chris@1494: Chris@1494: module Redmine Chris@1494: module AccessControl Chris@1494: Chris@1494: class << self Chris@1494: def map Chris@1494: mapper = Mapper.new Chris@1494: yield mapper Chris@1494: @permissions ||= [] Chris@1494: @permissions += mapper.mapped_permissions Chris@1494: end Chris@1494: Chris@1494: def permissions Chris@1494: @permissions Chris@1494: end Chris@1494: Chris@1494: # Returns the permission of given name or nil if it wasn't found Chris@1494: # Argument should be a symbol Chris@1494: def permission(name) Chris@1494: permissions.detect {|p| p.name == name} Chris@1494: end Chris@1494: Chris@1494: # Returns the actions that are allowed by the permission of given name Chris@1494: def allowed_actions(permission_name) Chris@1494: perm = permission(permission_name) Chris@1494: perm ? perm.actions : [] Chris@1494: end Chris@1494: Chris@1494: def public_permissions Chris@1494: @public_permissions ||= @permissions.select {|p| p.public?} Chris@1494: end Chris@1494: Chris@1494: def members_only_permissions Chris@1494: @members_only_permissions ||= @permissions.select {|p| p.require_member?} Chris@1494: end Chris@1494: Chris@1494: def loggedin_only_permissions Chris@1494: @loggedin_only_permissions ||= @permissions.select {|p| p.require_loggedin?} Chris@1494: end Chris@1494: Chris@1494: def read_action?(action) Chris@1494: if action.is_a?(Symbol) Chris@1494: perm = permission(action) Chris@1494: !perm.nil? && perm.read? Chris@1494: else Chris@1494: s = "#{action[:controller]}/#{action[:action]}" Chris@1494: permissions.detect {|p| p.actions.include?(s) && !p.read?}.nil? Chris@1494: end Chris@1494: end Chris@1494: Chris@1494: def available_project_modules Chris@1494: @available_project_modules ||= @permissions.collect(&:project_module).uniq.compact Chris@1494: end Chris@1494: Chris@1494: def modules_permissions(modules) Chris@1494: @permissions.select {|p| p.project_module.nil? || modules.include?(p.project_module.to_s)} Chris@1494: end Chris@1494: end Chris@1494: Chris@1494: class Mapper Chris@1494: def initialize Chris@1494: @project_module = nil Chris@1494: end Chris@1494: Chris@1494: def permission(name, hash, options={}) Chris@1494: @permissions ||= [] Chris@1494: options.merge!(:project_module => @project_module) Chris@1494: @permissions << Permission.new(name, hash, options) Chris@1494: end Chris@1494: Chris@1494: def project_module(name, options={}) Chris@1494: @project_module = name Chris@1494: yield self Chris@1494: @project_module = nil Chris@1494: end Chris@1494: Chris@1494: def mapped_permissions Chris@1494: @permissions Chris@1494: end Chris@1494: end Chris@1494: Chris@1494: class Permission Chris@1494: attr_reader :name, :actions, :project_module Chris@1494: Chris@1494: def initialize(name, hash, options) Chris@1494: @name = name Chris@1494: @actions = [] Chris@1494: @public = options[:public] || false Chris@1494: @require = options[:require] Chris@1494: @read = options[:read] || false Chris@1494: @project_module = options[:project_module] Chris@1494: hash.each do |controller, actions| Chris@1494: if actions.is_a? Array Chris@1494: @actions << actions.collect {|action| "#{controller}/#{action}"} Chris@1494: else Chris@1494: @actions << "#{controller}/#{actions}" Chris@1494: end Chris@1494: end Chris@1494: @actions.flatten! Chris@1494: end Chris@1494: Chris@1494: def public? Chris@1494: @public Chris@1494: end Chris@1494: Chris@1494: def require_member? Chris@1494: @require && @require == :member Chris@1494: end Chris@1494: Chris@1494: def require_loggedin? Chris@1494: @require && (@require == :member || @require == :loggedin) Chris@1494: end Chris@1494: Chris@1494: def read? Chris@1494: @read Chris@1494: end Chris@1494: end Chris@1494: end Chris@1494: end