@@ -74,8 +74,7 class ProjectsController < ApplicationController | |||
|
74 | 74 | @project = Project.new |
|
75 | 75 | @project.safe_attributes = params[:project] |
|
76 | 76 | |
|
77 |
if |
|
|
78 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') | |
|
77 | if @project.save | |
|
79 | 78 | unless User.current.admin? |
|
80 | 79 | @project.add_default_member(User.current) |
|
81 | 80 | end |
@@ -110,8 +109,7 class ProjectsController < ApplicationController | |||
|
110 | 109 | Mailer.with_deliveries(params[:notifications] == '1') do |
|
111 | 110 | @project = Project.new |
|
112 | 111 | @project.safe_attributes = params[:project] |
|
113 |
if |
|
|
114 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') | |
|
112 | if @project.copy(@source_project, :only => params[:only]) | |
|
115 | 113 | flash[:notice] = l(:notice_successful_create) |
|
116 | 114 | redirect_to settings_project_path(@project) |
|
117 | 115 | elsif !@project.new_record? |
@@ -170,8 +168,7 class ProjectsController < ApplicationController | |||
|
170 | 168 | |
|
171 | 169 | def update |
|
172 | 170 | @project.safe_attributes = params[:project] |
|
173 |
if |
|
|
174 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') | |
|
171 | if @project.save | |
|
175 | 172 | respond_to do |format| |
|
176 | 173 | format.html { |
|
177 | 174 | flash[:notice] = l(:notice_successful_update) |
@@ -233,21 +230,4 class ProjectsController < ApplicationController | |||
|
233 | 230 | # hide project in layout |
|
234 | 231 | @project = nil |
|
235 | 232 | end |
|
236 | ||
|
237 | private | |
|
238 | ||
|
239 | # Validates parent_id param according to user's permissions | |
|
240 | # TODO: move it to Project model in a validation that depends on User.current | |
|
241 | def validate_parent_id | |
|
242 | return true if User.current.admin? | |
|
243 | parent_id = params[:project] && params[:project][:parent_id] | |
|
244 | if parent_id || @project.new_record? | |
|
245 | parent = parent_id.blank? ? nil : Project.find_by_id(parent_id.to_i) | |
|
246 | unless @project.allowed_parents.include?(parent) | |
|
247 | @project.errors.add :parent_id, :invalid | |
|
248 | return false | |
|
249 | end | |
|
250 | end | |
|
251 | true | |
|
252 | end | |
|
253 | 233 | end |
@@ -80,9 +80,11 class Project < ActiveRecord::Base | |||
|
80 | 80 | validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? } |
|
81 | 81 | # reserved words |
|
82 | 82 | validates_exclusion_of :identifier, :in => %w( new ) |
|
83 | validate :validate_parent | |
|
83 | 84 | |
|
84 | 85 | after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?} |
|
85 | 86 | after_save :remove_inherited_member_roles, :add_inherited_member_roles, :if => Proc.new {|project| project.parent_id_changed?} |
|
87 | after_update :update_versions_from_hierarchy_change, :if => Proc.new {|project| project.parent_id_changed?} | |
|
86 | 88 | before_destroy :delete_all_members |
|
87 | 89 | |
|
88 | 90 | scope :has_module, lambda {|mod| |
@@ -366,11 +368,11 class Project < ActiveRecord::Base | |||
|
366 | 368 | |
|
367 | 369 | # Returns an array of projects the project can be moved to |
|
368 | 370 | # by the current user |
|
369 | def allowed_parents | |
|
371 | def allowed_parents(user=User.current) | |
|
370 | 372 | return @allowed_parents if @allowed_parents |
|
371 |
@allowed_parents = Project.allowed_to( |
|
|
373 | @allowed_parents = Project.allowed_to(user, :add_subprojects).to_a | |
|
372 | 374 | @allowed_parents = @allowed_parents - self_and_descendants |
|
373 |
if |
|
|
375 | if user.allowed_to?(:add_project, nil, :global => true) || (!new_record? && parent.nil?) | |
|
374 | 376 | @allowed_parents << nil |
|
375 | 377 | end |
|
376 | 378 | unless parent.nil? || @allowed_parents.empty? || @allowed_parents.include?(parent) |
@@ -381,48 +383,20 class Project < ActiveRecord::Base | |||
|
381 | 383 | |
|
382 | 384 | # Sets the parent of the project with authorization check |
|
383 | 385 | def set_allowed_parent!(p) |
|
384 |
|
|
|
385 | if p.to_s.blank? | |
|
386 | p = nil | |
|
387 | else | |
|
388 | p = Project.find_by_id(p) | |
|
389 | return false unless p | |
|
390 | end | |
|
391 | end | |
|
392 | if p.nil? | |
|
393 | if !new_record? && allowed_parents.empty? | |
|
394 | return false | |
|
395 | end | |
|
396 | elsif !allowed_parents.include?(p) | |
|
397 | return false | |
|
398 | end | |
|
399 | set_parent!(p) | |
|
386 | p = p.id if p.is_a?(Project) | |
|
387 | send :safe_attributes, {:project_id => p} | |
|
388 | save | |
|
400 | 389 | end |
|
401 | 390 | |
|
402 | 391 | # Sets the parent of the project |
|
403 | 392 | # Argument can be either a Project, a String, a Fixnum or nil |
|
404 | 393 | def set_parent!(p) |
|
405 |
|
|
|
406 | if p.to_s.blank? | |
|
407 | p = nil | |
|
408 | else | |
|
409 | p = Project.find_by_id(p) | |
|
410 | return false unless p | |
|
411 | end | |
|
412 | end | |
|
413 | if p == parent && !p.nil? | |
|
414 | # Nothing to do | |
|
415 | true | |
|
416 | elsif p.nil? || (p.active? && move_possible?(p)) | |
|
394 | if p.is_a?(Project) | |
|
417 | 395 | self.parent = p |
|
418 | save | |
|
419 | p.reload if p | |
|
420 | Issue.update_versions_from_hierarchy_change(self) | |
|
421 | true | |
|
422 | 396 | else |
|
423 | # Can not move to the given target | |
|
424 | false | |
|
397 | self.parent_id = p | |
|
425 | 398 | end |
|
399 | save | |
|
426 | 400 | end |
|
427 | 401 | |
|
428 | 402 | # Returns an array of the trackers used by the project and its active sub projects |
@@ -688,7 +662,8 class Project < ActiveRecord::Base | |||
|
688 | 662 | 'custom_field_values', |
|
689 | 663 | 'custom_fields', |
|
690 | 664 | 'tracker_ids', |
|
691 | 'issue_custom_field_ids' | |
|
665 | 'issue_custom_field_ids', | |
|
666 | 'parent_id' | |
|
692 | 667 | |
|
693 | 668 | safe_attributes 'enabled_module_names', |
|
694 | 669 | :if => lambda {|project, user| project.new_record? || user.allowed_to?(:select_project_modules, project) } |
@@ -696,6 +671,23 class Project < ActiveRecord::Base | |||
|
696 | 671 | safe_attributes 'inherit_members', |
|
697 | 672 | :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)} |
|
698 | 673 | |
|
674 | def safe_attributes=(attrs, user=User.current) | |
|
675 | return unless attrs.is_a?(Hash) | |
|
676 | attrs = attrs.deep_dup | |
|
677 | ||
|
678 | @unallowed_parent_id = nil | |
|
679 | parent_id_param = attrs['parent_id'].to_s | |
|
680 | if parent_id_param.blank? || parent_id_param != parent_id.to_s | |
|
681 | p = parent_id_param.present? ? Project.find_by_id(parent_id_param) : nil | |
|
682 | unless allowed_parents(user).include?(p) | |
|
683 | attrs.delete('parent_id') | |
|
684 | @unallowed_parent_id = true | |
|
685 | end | |
|
686 | end | |
|
687 | ||
|
688 | super(attrs, user) | |
|
689 | end | |
|
690 | ||
|
699 | 691 | # Returns an auto-generated project identifier based on the last identifier used |
|
700 | 692 | def self.next_identifier |
|
701 | 693 | p = Project.order('id DESC').first |
@@ -797,6 +789,20 class Project < ActiveRecord::Base | |||
|
797 | 789 | end |
|
798 | 790 | end |
|
799 | 791 | |
|
792 | def update_versions_from_hierarchy_change | |
|
793 | Issue.update_versions_from_hierarchy_change(self) | |
|
794 | end | |
|
795 | ||
|
796 | def validate_parent | |
|
797 | if @unallowed_parent_id | |
|
798 | errors.add(:parent_id, :invalid) | |
|
799 | elsif parent_id_changed? | |
|
800 | unless parent.nil? || (parent.active? && move_possible?(parent)) | |
|
801 | errors.add(:parent_id, :invalid) | |
|
802 | end | |
|
803 | end | |
|
804 | end | |
|
805 | ||
|
800 | 806 | # Copies wiki from +project+ |
|
801 | 807 | def copy_wiki(project) |
|
802 | 808 | # Check that the source project has a wiki first |
@@ -40,8 +40,10 module ObjectHelpers | |||
|
40 | 40 | end |
|
41 | 41 | |
|
42 | 42 | def Project.generate_with_parent!(parent, attributes={}) |
|
43 | project = Project.generate!(attributes) | |
|
44 |
p |
|
|
43 | project = Project.generate!(attributes) do |p| | |
|
44 | p.parent = parent | |
|
45 | end | |
|
46 | parent.reload if parent | |
|
45 | 47 | project |
|
46 | 48 | end |
|
47 | 49 |
General Comments 0
You need to be logged in to leave comments.
Login now