Mercurial > hg > soundsoftware-site
comparison app/models/.svn/text-base/issue.rb.svn-base @ 119:8661b858af72
* Update to Redmine trunk rev 4705
author | Chris Cannam |
---|---|
date | Thu, 13 Jan 2011 14:12:06 +0000 |
parents | 94944d00e43c |
children | 07fa8a8b56a8 |
comparison
equal
deleted
inserted
replaced
39:150ceac17a8d | 119:8661b858af72 |
---|---|
14 # You should have received a copy of the GNU General Public License | 14 # You should have received a copy of the GNU General Public License |
15 # along with this program; if not, write to the Free Software | 15 # along with this program; if not, write to the Free Software |
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | 17 |
18 class Issue < ActiveRecord::Base | 18 class Issue < ActiveRecord::Base |
19 include Redmine::SafeAttributes | |
20 | |
19 belongs_to :project | 21 belongs_to :project |
20 belongs_to :tracker | 22 belongs_to :tracker |
21 belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id' | 23 belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id' |
22 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' | 24 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' |
23 belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id' | 25 belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id' |
66 named_scope :with_limit, lambda { |limit| { :limit => limit} } | 68 named_scope :with_limit, lambda { |limit| { :limit => limit} } |
67 named_scope :on_active_project, :include => [:status, :project, :tracker], | 69 named_scope :on_active_project, :include => [:status, :project, :tracker], |
68 :conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"] | 70 :conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"] |
69 named_scope :for_gantt, lambda { | 71 named_scope :for_gantt, lambda { |
70 { | 72 { |
71 :include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version], | 73 :include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version] |
72 :order => "#{Issue.table_name}.due_date ASC, #{Issue.table_name}.start_date ASC, #{Issue.table_name}.id ASC" | |
73 } | 74 } |
74 } | 75 } |
75 | 76 |
76 named_scope :without_version, lambda { | 77 named_scope :without_version, lambda { |
77 { | 78 { |
213 | 214 |
214 def estimated_hours=(h) | 215 def estimated_hours=(h) |
215 write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h) | 216 write_attribute :estimated_hours, (h.is_a?(String) ? h.to_hours : h) |
216 end | 217 end |
217 | 218 |
218 SAFE_ATTRIBUTES = %w( | 219 safe_attributes 'tracker_id', |
219 tracker_id | 220 'status_id', |
220 status_id | 221 'parent_issue_id', |
221 parent_issue_id | 222 'category_id', |
222 category_id | 223 'assigned_to_id', |
223 assigned_to_id | 224 'priority_id', |
224 priority_id | 225 'fixed_version_id', |
225 fixed_version_id | 226 'subject', |
226 subject | 227 'description', |
227 description | 228 'start_date', |
228 start_date | 229 'due_date', |
229 due_date | 230 'done_ratio', |
230 done_ratio | 231 'estimated_hours', |
231 estimated_hours | 232 'custom_field_values', |
232 custom_field_values | 233 'custom_fields', |
233 lock_version | 234 'lock_version', |
234 ) unless const_defined?(:SAFE_ATTRIBUTES) | 235 :if => lambda {|issue, user| issue.new_record? || user.allowed_to?(:edit_issues, issue.project) } |
235 | 236 |
236 SAFE_ATTRIBUTES_ON_TRANSITION = %w( | 237 safe_attributes 'status_id', |
237 status_id | 238 'assigned_to_id', |
238 assigned_to_id | 239 'fixed_version_id', |
239 fixed_version_id | 240 'done_ratio', |
240 done_ratio | 241 :if => lambda {|issue, user| issue.new_statuses_allowed_to(user).any? } |
241 ) unless const_defined?(:SAFE_ATTRIBUTES_ON_TRANSITION) | |
242 | 242 |
243 # Safely sets attributes | 243 # Safely sets attributes |
244 # Should be called from controllers instead of #attributes= | 244 # Should be called from controllers instead of #attributes= |
245 # attr_accessible is too rough because we still want things like | 245 # attr_accessible is too rough because we still want things like |
246 # Issue.new(:project => foo) to work | 246 # Issue.new(:project => foo) to work |
247 # TODO: move workflow/permission checks from controllers to here | 247 # TODO: move workflow/permission checks from controllers to here |
248 def safe_attributes=(attrs, user=User.current) | 248 def safe_attributes=(attrs, user=User.current) |
249 return unless attrs.is_a?(Hash) | 249 return unless attrs.is_a?(Hash) |
250 | 250 |
251 # User can change issue attributes only if he has :edit permission or if a workflow transition is allowed | 251 # User can change issue attributes only if he has :edit permission or if a workflow transition is allowed |
252 if new_record? || user.allowed_to?(:edit_issues, project) | 252 attrs = delete_unsafe_attributes(attrs, user) |
253 attrs = attrs.reject {|k,v| !SAFE_ATTRIBUTES.include?(k)} | 253 return if attrs.empty? |
254 elsif new_statuses_allowed_to(user).any? | |
255 attrs = attrs.reject {|k,v| !SAFE_ATTRIBUTES_ON_TRANSITION.include?(k)} | |
256 else | |
257 return | |
258 end | |
259 | 254 |
260 # Tracker must be set before since new_statuses_allowed_to depends on it. | 255 # Tracker must be set before since new_statuses_allowed_to depends on it. |
261 if t = attrs.delete('tracker_id') | 256 if t = attrs.delete('tracker_id') |
262 self.tracker_id = t | 257 self.tracker_id = t |
263 end | 258 end |
274 | 269 |
275 if attrs.has_key?('parent_issue_id') | 270 if attrs.has_key?('parent_issue_id') |
276 if !user.allowed_to?(:manage_subtasks, project) | 271 if !user.allowed_to?(:manage_subtasks, project) |
277 attrs.delete('parent_issue_id') | 272 attrs.delete('parent_issue_id') |
278 elsif !attrs['parent_issue_id'].blank? | 273 elsif !attrs['parent_issue_id'].blank? |
279 attrs.delete('parent_issue_id') unless Issue.visible(user).exists?(attrs['parent_issue_id']) | 274 attrs.delete('parent_issue_id') unless Issue.visible(user).exists?(attrs['parent_issue_id'].to_i) |
280 end | 275 end |
281 end | 276 end |
282 | 277 |
283 self.attributes = attrs | 278 self.attributes = attrs |
284 end | 279 end |