##// END OF EJS Templates
Use safe_attributes....
Jean-Philippe Lang -
r15287:dca56a0350c3
parent child
Show More
@@ -1,107 +1,110
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class TrackersController < ApplicationController
19 19 layout 'admin'
20 20
21 21 before_action :require_admin, :except => :index
22 22 before_action :require_admin_or_api_request, :only => :index
23 23 accept_api_auth :index
24 24
25 25 def index
26 26 @trackers = Tracker.sorted.to_a
27 27 respond_to do |format|
28 28 format.html { render :layout => false if request.xhr? }
29 29 format.api
30 30 end
31 31 end
32 32
33 33 def new
34 @tracker ||= Tracker.new(params[:tracker])
34 @tracker ||= Tracker.new
35 @tracker.safe_attributes = params[:tracker]
35 36 @trackers = Tracker.sorted.to_a
36 37 @projects = Project.all
37 38 end
38 39
39 40 def create
40 @tracker = Tracker.new(params[:tracker])
41 @tracker = Tracker.new
42 @tracker.safe_attributes = params[:tracker]
41 43 if @tracker.save
42 44 # workflow copy
43 45 if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
44 46 @tracker.workflow_rules.copy(copy_from)
45 47 end
46 48 flash[:notice] = l(:notice_successful_create)
47 49 redirect_to trackers_path
48 50 return
49 51 end
50 52 new
51 53 render :action => 'new'
52 54 end
53 55
54 56 def edit
55 57 @tracker ||= Tracker.find(params[:id])
56 58 @projects = Project.all
57 59 end
58 60
59 61 def update
60 62 @tracker = Tracker.find(params[:id])
61 if @tracker.update_attributes(params[:tracker])
63 @tracker.safe_attributes = params[:tracker]
64 if @tracker.save
62 65 respond_to do |format|
63 66 format.html {
64 67 flash[:notice] = l(:notice_successful_update)
65 68 redirect_to trackers_path(:page => params[:page])
66 69 }
67 70 format.js { render :nothing => true }
68 71 end
69 72 else
70 73 respond_to do |format|
71 74 format.html {
72 75 edit
73 76 render :action => 'edit'
74 77 }
75 78 format.js { render :nothing => true, :status => 422 }
76 79 end
77 80 end
78 81 end
79 82
80 83 def destroy
81 84 @tracker = Tracker.find(params[:id])
82 85 unless @tracker.issues.empty?
83 86 flash[:error] = l(:error_can_not_delete_tracker)
84 87 else
85 88 @tracker.destroy
86 89 end
87 90 redirect_to trackers_path
88 91 end
89 92
90 93 def fields
91 94 if request.post? && params[:trackers]
92 95 params[:trackers].each do |tracker_id, tracker_params|
93 96 tracker = Tracker.find_by_id(tracker_id)
94 97 if tracker
95 98 tracker.core_fields = tracker_params[:core_fields]
96 99 tracker.custom_field_ids = tracker_params[:custom_field_ids]
97 100 tracker.save
98 101 end
99 102 end
100 103 flash[:notice] = l(:notice_successful_update)
101 104 redirect_to fields_trackers_path
102 105 return
103 106 end
104 107 @trackers = Tracker.sorted.to_a
105 108 @custom_fields = IssueCustomField.all.sort
106 109 end
107 110 end
@@ -1,137 +1,146
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Tracker < ActiveRecord::Base
19 include Redmine::SafeAttributes
19 20
20 21 CORE_FIELDS_UNDISABLABLE = %w(project_id tracker_id subject description priority_id is_private).freeze
21 22 # Fields that can be disabled
22 23 # Other (future) fields should be appended, not inserted!
23 24 CORE_FIELDS = %w(assigned_to_id category_id fixed_version_id parent_issue_id start_date due_date estimated_hours done_ratio).freeze
24 25 CORE_FIELDS_ALL = (CORE_FIELDS_UNDISABLABLE + CORE_FIELDS).freeze
25 26
26 27 before_destroy :check_integrity
27 28 belongs_to :default_status, :class_name => 'IssueStatus'
28 29 has_many :issues
29 30 has_many :workflow_rules, :dependent => :delete_all do
30 31 def copy(source_tracker)
31 32 WorkflowRule.copy(source_tracker, nil, proxy_association.owner, nil)
32 33 end
33 34 end
34 35
35 36 has_and_belongs_to_many :projects
36 37 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_trackers#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
37 38 acts_as_positioned
38 39
39 40 attr_protected :fields_bits
40 41
41 42 validates_presence_of :default_status
42 43 validates_presence_of :name
43 44 validates_uniqueness_of :name
44 45 validates_length_of :name, :maximum => 30
45 46
46 47 scope :sorted, lambda { order(:position) }
47 48 scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)}
48 49
49 50 # Returns the trackers that are visible by the user.
50 51 #
51 52 # Examples:
52 53 # project.trackers.visible(user)
53 54 # => returns the trackers that are visible by the user in project
54 55 #
55 56 # Tracker.visible(user)
56 57 # => returns the trackers that are visible by the user in at least on project
57 58 scope :visible, lambda {|*args|
58 59 user = args.shift || User.current
59 60 condition = Project.allowed_to_condition(user, :view_issues) do |role, user|
60 61 unless role.permissions_all_trackers?(:view_issues)
61 62 tracker_ids = role.permissions_tracker_ids(:view_issues)
62 63 if tracker_ids.any?
63 64 "#{Tracker.table_name}.id IN (#{tracker_ids.join(',')})"
64 65 else
65 66 '1=0'
66 67 end
67 68 end
68 69 end
69 70 joins(:projects).where(condition).distinct
70 71 }
71 72
73 safe_attributes 'name',
74 'default_status_id',
75 'is_in_roadmap',
76 'core_fields',
77 'position',
78 'custom_field_ids',
79 'project_ids'
80
72 81 def to_s; name end
73 82
74 83 def <=>(tracker)
75 84 position <=> tracker.position
76 85 end
77 86
78 87 # Returns an array of IssueStatus that are used
79 88 # in the tracker's workflows
80 89 def issue_statuses
81 90 @issue_statuses ||= IssueStatus.where(:id => issue_status_ids).to_a.sort
82 91 end
83 92
84 93 def issue_status_ids
85 94 if new_record?
86 95 []
87 96 else
88 97 @issue_status_ids ||= WorkflowTransition.where(:tracker_id => id).distinct.pluck(:old_status_id, :new_status_id).flatten.uniq
89 98 end
90 99 end
91 100
92 101 def disabled_core_fields
93 102 i = -1
94 103 @disabled_core_fields ||= CORE_FIELDS.select { i += 1; (fields_bits || 0) & (2 ** i) != 0}
95 104 end
96 105
97 106 def core_fields
98 107 CORE_FIELDS - disabled_core_fields
99 108 end
100 109
101 110 def core_fields=(fields)
102 111 raise ArgumentError.new("Tracker.core_fields takes an array") unless fields.is_a?(Array)
103 112
104 113 bits = 0
105 114 CORE_FIELDS.each_with_index do |field, i|
106 115 unless fields.include?(field)
107 116 bits |= 2 ** i
108 117 end
109 118 end
110 119 self.fields_bits = bits
111 120 @disabled_core_fields = nil
112 121 core_fields
113 122 end
114 123
115 124 # Returns the fields that are disabled for all the given trackers
116 125 def self.disabled_core_fields(trackers)
117 126 if trackers.present?
118 127 trackers.map(&:disabled_core_fields).reduce(:&)
119 128 else
120 129 []
121 130 end
122 131 end
123 132
124 133 # Returns the fields that are enabled for one tracker at least
125 134 def self.core_fields(trackers)
126 135 if trackers.present?
127 136 trackers.uniq.map(&:core_fields).reduce(:|)
128 137 else
129 138 CORE_FIELDS.dup
130 139 end
131 140 end
132 141
133 142 private
134 143 def check_integrity
135 144 raise Exception.new("Cannot delete tracker") if Issue.where(:tracker_id => self.id).any?
136 145 end
137 146 end
General Comments 0
You need to be logged in to leave comments. Login now