@@ -74,8 +74,7 class ProjectsController < ApplicationController | |||||
74 | @project = Project.new |
|
74 | @project = Project.new | |
75 | @project.safe_attributes = params[:project] |
|
75 | @project.safe_attributes = params[:project] | |
76 |
|
76 | |||
77 |
if |
|
77 | if @project.save | |
78 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') |
|
|||
79 | unless User.current.admin? |
|
78 | unless User.current.admin? | |
80 | @project.add_default_member(User.current) |
|
79 | @project.add_default_member(User.current) | |
81 | end |
|
80 | end | |
@@ -110,8 +109,7 class ProjectsController < ApplicationController | |||||
110 | Mailer.with_deliveries(params[:notifications] == '1') do |
|
109 | Mailer.with_deliveries(params[:notifications] == '1') do | |
111 | @project = Project.new |
|
110 | @project = Project.new | |
112 | @project.safe_attributes = params[:project] |
|
111 | @project.safe_attributes = params[:project] | |
113 |
if |
|
112 | if @project.copy(@source_project, :only => params[:only]) | |
114 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') |
|
|||
115 | flash[:notice] = l(:notice_successful_create) |
|
113 | flash[:notice] = l(:notice_successful_create) | |
116 | redirect_to settings_project_path(@project) |
|
114 | redirect_to settings_project_path(@project) | |
117 | elsif !@project.new_record? |
|
115 | elsif !@project.new_record? | |
@@ -170,8 +168,7 class ProjectsController < ApplicationController | |||||
170 |
|
168 | |||
171 | def update |
|
169 | def update | |
172 | @project.safe_attributes = params[:project] |
|
170 | @project.safe_attributes = params[:project] | |
173 |
if |
|
171 | if @project.save | |
174 | @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') |
|
|||
175 | respond_to do |format| |
|
172 | respond_to do |format| | |
176 | format.html { |
|
173 | format.html { | |
177 | flash[:notice] = l(:notice_successful_update) |
|
174 | flash[:notice] = l(:notice_successful_update) | |
@@ -233,21 +230,4 class ProjectsController < ApplicationController | |||||
233 | # hide project in layout |
|
230 | # hide project in layout | |
234 | @project = nil |
|
231 | @project = nil | |
235 | end |
|
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 | end |
|
233 | end |
@@ -80,9 +80,11 class Project < ActiveRecord::Base | |||||
80 | validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? } |
|
80 | validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? } | |
81 | # reserved words |
|
81 | # reserved words | |
82 | validates_exclusion_of :identifier, :in => %w( new ) |
|
82 | validates_exclusion_of :identifier, :in => %w( new ) | |
|
83 | validate :validate_parent | |||
83 |
|
84 | |||
84 | after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?} |
|
85 | after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?} | |
85 | after_save :remove_inherited_member_roles, :add_inherited_member_roles, :if => Proc.new {|project| project.parent_id_changed?} |
|
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 | before_destroy :delete_all_members |
|
88 | before_destroy :delete_all_members | |
87 |
|
89 | |||
88 | scope :has_module, lambda {|mod| |
|
90 | scope :has_module, lambda {|mod| | |
@@ -366,11 +368,11 class Project < ActiveRecord::Base | |||||
366 |
|
368 | |||
367 | # Returns an array of projects the project can be moved to |
|
369 | # Returns an array of projects the project can be moved to | |
368 | # by the current user |
|
370 | # by the current user | |
369 | def allowed_parents |
|
371 | def allowed_parents(user=User.current) | |
370 | return @allowed_parents if @allowed_parents |
|
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 | @allowed_parents = @allowed_parents - self_and_descendants |
|
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 | @allowed_parents << nil |
|
376 | @allowed_parents << nil | |
375 | end |
|
377 | end | |
376 | unless parent.nil? || @allowed_parents.empty? || @allowed_parents.include?(parent) |
|
378 | unless parent.nil? || @allowed_parents.empty? || @allowed_parents.include?(parent) | |
@@ -381,48 +383,20 class Project < ActiveRecord::Base | |||||
381 |
|
383 | |||
382 | # Sets the parent of the project with authorization check |
|
384 | # Sets the parent of the project with authorization check | |
383 | def set_allowed_parent!(p) |
|
385 | def set_allowed_parent!(p) | |
384 |
|
|
386 | p = p.id if p.is_a?(Project) | |
385 | if p.to_s.blank? |
|
387 | send :safe_attributes, {:project_id => p} | |
386 | p = nil |
|
388 | save | |
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) |
|
|||
400 | end |
|
389 | end | |
401 |
|
390 | |||
402 | # Sets the parent of the project |
|
391 | # Sets the parent of the project | |
403 | # Argument can be either a Project, a String, a Fixnum or nil |
|
392 | # Argument can be either a Project, a String, a Fixnum or nil | |
404 | def set_parent!(p) |
|
393 | def set_parent!(p) | |
405 |
|
|
394 | if p.is_a?(Project) | |
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)) |
|
|||
417 | self.parent = p |
|
395 | self.parent = p | |
418 | save |
|
|||
419 | p.reload if p |
|
|||
420 | Issue.update_versions_from_hierarchy_change(self) |
|
|||
421 | true |
|
|||
422 | else |
|
396 | else | |
423 | # Can not move to the given target |
|
397 | self.parent_id = p | |
424 | false |
|
|||
425 | end |
|
398 | end | |
|
399 | save | |||
426 | end |
|
400 | end | |
427 |
|
401 | |||
428 | # Returns an array of the trackers used by the project and its active sub projects |
|
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 | 'custom_field_values', |
|
662 | 'custom_field_values', | |
689 | 'custom_fields', |
|
663 | 'custom_fields', | |
690 | 'tracker_ids', |
|
664 | 'tracker_ids', | |
691 | 'issue_custom_field_ids' |
|
665 | 'issue_custom_field_ids', | |
|
666 | 'parent_id' | |||
692 |
|
667 | |||
693 | safe_attributes 'enabled_module_names', |
|
668 | safe_attributes 'enabled_module_names', | |
694 | :if => lambda {|project, user| project.new_record? || user.allowed_to?(:select_project_modules, project) } |
|
669 | :if => lambda {|project, user| project.new_record? || user.allowed_to?(:select_project_modules, project) } | |
@@ -696,6 +671,23 class Project < ActiveRecord::Base | |||||
696 | safe_attributes 'inherit_members', |
|
671 | safe_attributes 'inherit_members', | |
697 | :if => lambda {|project, user| project.parent.nil? || project.parent.visible?(user)} |
|
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 | # Returns an auto-generated project identifier based on the last identifier used |
|
691 | # Returns an auto-generated project identifier based on the last identifier used | |
700 | def self.next_identifier |
|
692 | def self.next_identifier | |
701 | p = Project.order('id DESC').first |
|
693 | p = Project.order('id DESC').first | |
@@ -797,6 +789,20 class Project < ActiveRecord::Base | |||||
797 | end |
|
789 | end | |
798 | end |
|
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 | # Copies wiki from +project+ |
|
806 | # Copies wiki from +project+ | |
801 | def copy_wiki(project) |
|
807 | def copy_wiki(project) | |
802 | # Check that the source project has a wiki first |
|
808 | # Check that the source project has a wiki first |
@@ -40,8 +40,10 module ObjectHelpers | |||||
40 | end |
|
40 | end | |
41 |
|
41 | |||
42 | def Project.generate_with_parent!(parent, attributes={}) |
|
42 | def Project.generate_with_parent!(parent, attributes={}) | |
43 | project = Project.generate!(attributes) |
|
43 | project = Project.generate!(attributes) do |p| | |
44 |
p |
|
44 | p.parent = parent | |
|
45 | end | |||
|
46 | parent.reload if parent | |||
45 | project |
|
47 | project | |
46 | end |
|
48 | end | |
47 |
|
49 |
General Comments 0
You need to be logged in to leave comments.
Login now