| 
									
										
										
										
											2007-03-12 17:59:02 +00:00
										 |  |  | # redMine - project management software | 
					
						
							|  |  |  | # Copyright (C) 2006  Jean-Philippe Lang | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							|  |  |  | #  | 
					
						
							|  |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							|  |  |  | #  | 
					
						
							|  |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Role < ActiveRecord::Base | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   # Built-in roles | 
					
						
							|  |  |  |   BUILTIN_NON_MEMBER = 1
 | 
					
						
							|  |  |  |   BUILTIN_ANONYMOUS  = 2
 | 
					
						
							| 
									
										
										
										
											2008-09-13 16:31:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-17 14:35:00 +00:00
										 |  |  |   named_scope :givable, { :conditions => "builtin = 0", :order => 'position' } | 
					
						
							| 
									
										
										
										
											2008-09-13 16:31:11 +00:00
										 |  |  |   named_scope :builtin, lambda { |*args| | 
					
						
							|  |  |  |     compare = 'not' if args.first == true | 
					
						
							|  |  |  |     { :conditions => "#{compare} builtin = 0" } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |    | 
					
						
							|  |  |  |   before_destroy :check_deletable | 
					
						
							| 
									
										
										
										
											2008-03-15 08:27:38 +00:00
										 |  |  |   has_many :workflows, :dependent => :delete_all do | 
					
						
							| 
									
										
										
										
											2009-12-12 10:06:07 +00:00
										 |  |  |     def copy(source_role) | 
					
						
							|  |  |  |       Workflow.copy(nil, source_role, nil, proxy_owner) | 
					
						
							| 
									
										
										
										
											2008-03-15 08:27:38 +00:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2009-05-10 10:54:31 +00:00
										 |  |  |   has_many :member_roles, :dependent => :destroy | 
					
						
							|  |  |  |   has_many :members, :through => :member_roles | 
					
						
							| 
									
										
										
										
											2007-03-12 17:59:02 +00:00
										 |  |  |   acts_as_list | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2008-09-13 16:31:11 +00:00
										 |  |  |   serialize :permissions, Array | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   attr_protected :builtin | 
					
						
							| 
									
										
										
										
											2007-03-12 17:59:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   validates_presence_of :name | 
					
						
							|  |  |  |   validates_uniqueness_of :name | 
					
						
							| 
									
										
										
										
											2007-07-16 17:16:49 +00:00
										 |  |  |   validates_length_of :name, :maximum => 30
 | 
					
						
							| 
									
										
										
										
											2007-03-12 17:59:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   def permissions | 
					
						
							|  |  |  |     read_attribute(:permissions) || [] | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   def permissions=(perms) | 
					
						
							| 
									
										
										
										
											2008-09-13 16:31:11 +00:00
										 |  |  |     perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |     write_attribute(:permissions, perms) | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2008-09-13 16:31:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def add_permission!(*perms) | 
					
						
							|  |  |  |     self.permissions = [] unless permissions.is_a?(Array) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     permissions_will_change! | 
					
						
							|  |  |  |     perms.each do |p| | 
					
						
							|  |  |  |       p = p.to_sym | 
					
						
							|  |  |  |       permissions << p unless permissions.include?(p) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     save! | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def remove_permission!(*perms) | 
					
						
							|  |  |  |     return unless permissions.is_a?(Array) | 
					
						
							|  |  |  |     permissions_will_change! | 
					
						
							|  |  |  |     perms.each { |p| permissions.delete(p.to_sym) } | 
					
						
							|  |  |  |     save! | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2008-09-13 16:45:01 +00:00
										 |  |  |   # Returns true if the role has the given permission | 
					
						
							|  |  |  |   def has_permission?(perm) | 
					
						
							|  |  |  |     !permissions.nil? && permissions.include?(perm.to_sym) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:54 +00:00
										 |  |  |   def <=>(role) | 
					
						
							| 
									
										
										
										
											2009-05-10 10:54:31 +00:00
										 |  |  |     role ? position <=> role.position : -1
 | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   def to_s | 
					
						
							|  |  |  |     name | 
					
						
							| 
									
										
										
										
											2007-04-08 17:44:54 +00:00
										 |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   # Return true if the role is a builtin role | 
					
						
							|  |  |  |   def builtin? | 
					
						
							|  |  |  |     self.builtin != 0
 | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   # Return true if the role is a project member role | 
					
						
							|  |  |  |   def member? | 
					
						
							|  |  |  |     !self.builtin? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   # Return true if role is allowed to do the specified action | 
					
						
							|  |  |  |   # action can be: | 
					
						
							|  |  |  |   # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') | 
					
						
							|  |  |  |   # * a permission Symbol (eg. :edit_project) | 
					
						
							|  |  |  |   def allowed_to?(action) | 
					
						
							|  |  |  |     if action.is_a? Hash | 
					
						
							|  |  |  |       allowed_actions.include? "#{action[:controller]}/#{action[:action]}" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       allowed_permissions.include? action | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   # Return all the permissions that can be given to the role | 
					
						
							|  |  |  |   def setable_permissions | 
					
						
							|  |  |  |     setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions | 
					
						
							|  |  |  |     setable_permissions -= Redmine::AccessControl.members_only_permissions if self.builtin == BUILTIN_NON_MEMBER | 
					
						
							|  |  |  |     setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if self.builtin == BUILTIN_ANONYMOUS | 
					
						
							|  |  |  |     setable_permissions | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Find all the roles that can be given to a project member | 
					
						
							|  |  |  |   def self.find_all_givable | 
					
						
							|  |  |  |     find(:all, :conditions => {:builtin => 0}, :order => 'position') | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-03 17:47:47 +00:00
										 |  |  |   # Return the builtin 'non member' role.  If the role doesn't exist, | 
					
						
							|  |  |  |   # it will be created on the fly. | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   def self.non_member | 
					
						
							| 
									
										
										
										
											2010-02-03 17:47:47 +00:00
										 |  |  |     non_member_role = find(:first, :conditions => {:builtin => BUILTIN_NON_MEMBER}) | 
					
						
							|  |  |  |     if non_member_role.nil? | 
					
						
							|  |  |  |       non_member_role = create(:name => 'Non member', :position => 0) do |role| | 
					
						
							|  |  |  |         role.builtin = BUILTIN_NON_MEMBER | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       raise 'Unable to create the non-member role.' if non_member_role.new_record? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     non_member_role | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-03 17:47:47 +00:00
										 |  |  |   # Return the builtin 'anonymous' role.  If the role doesn't exist, | 
					
						
							|  |  |  |   # it will be created on the fly. | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   def self.anonymous | 
					
						
							| 
									
										
										
										
											2010-02-03 17:47:47 +00:00
										 |  |  |     anonymous_role = find(:first, :conditions => {:builtin => BUILTIN_ANONYMOUS}) | 
					
						
							|  |  |  |     if anonymous_role.nil? | 
					
						
							|  |  |  |       anonymous_role = create(:name => 'Anonymous', :position => 0) do |role| | 
					
						
							|  |  |  |         role.builtin = BUILTIN_ANONYMOUS | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       raise 'Unable to create the anonymous role.' if anonymous_role.new_record? | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     anonymous_role | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2007-03-12 17:59:02 +00:00
										 |  |  | private | 
					
						
							| 
									
										
										
										
											2007-08-29 16:52:35 +00:00
										 |  |  |   def allowed_permissions | 
					
						
							|  |  |  |     @allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name} | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def allowed_actions | 
					
						
							|  |  |  |     @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |   def check_deletable | 
					
						
							|  |  |  |     raise "Can't delete role" if members.any? | 
					
						
							|  |  |  |     raise "Can't delete builtin role" if builtin? | 
					
						
							| 
									
										
										
										
											2006-06-28 18:11:03 +00:00
										 |  |  |   end | 
					
						
							|  |  |  | end |