| 
									
										
										
										
											2019-03-16 09:37:35 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							| 
									
										
										
										
											2019-03-15 01:32:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  | # Redmine - project management software | 
					
						
							| 
									
										
										
										
											2024-02-26 22:55:54 +00:00
										 |  |  | # Copyright (C) 2006-  Jean-Philippe Lang | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # 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. | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:44 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  | # 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. | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:44 +00:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  | # 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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Redmine | 
					
						
							|  |  |  |   module SafeAttributes | 
					
						
							|  |  |  |     def self.included(base) | 
					
						
							|  |  |  |       base.extend(ClassMethods) | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |     module ClassMethods | 
					
						
							|  |  |  |       # Declares safe attributes | 
					
						
							|  |  |  |       # An optional Proc can be given for conditional inclusion | 
					
						
							|  |  |  |       # | 
					
						
							|  |  |  |       # Example: | 
					
						
							|  |  |  |       #   safe_attributes 'title', 'pages' | 
					
						
							|  |  |  |       #   safe_attributes 'isbn', :if => {|book, user| book.author == user} | 
					
						
							|  |  |  |       def safe_attributes(*args) | 
					
						
							|  |  |  |         @safe_attributes ||= [] | 
					
						
							|  |  |  |         if args.empty? | 
					
						
							| 
									
										
										
										
											2012-06-19 19:47:54 +00:00
										 |  |  |           if superclass.include?(Redmine::SafeAttributes) | 
					
						
							| 
									
										
										
										
											2019-06-06 14:50:14 +00:00
										 |  |  |             @safe_attributes + superclass.safe_attributes | 
					
						
							| 
									
										
										
										
											2012-06-19 19:47:54 +00:00
										 |  |  |           else | 
					
						
							|  |  |  |             @safe_attributes | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |         else | 
					
						
							|  |  |  |           options = args.last.is_a?(Hash) ? args.pop : {} | 
					
						
							|  |  |  |           @safe_attributes << [args, options] | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |     # Returns an array that can be safely set by user or current user | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # Example: | 
					
						
							|  |  |  |     #   book.safe_attributes # => ['title', 'pages'] | 
					
						
							|  |  |  |     #   book.safe_attributes(book.author) # => ['title', 'pages', 'isbn'] | 
					
						
							| 
									
										
										
										
											2011-12-13 20:40:03 +00:00
										 |  |  |     def safe_attribute_names(user=nil) | 
					
						
							|  |  |  |       return @safe_attribute_names if @safe_attribute_names && user.nil? | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |       names = [] | 
					
						
							|  |  |  |       self.class.safe_attributes.collect do |attrs, options| | 
					
						
							| 
									
										
										
										
											2011-12-13 20:40:03 +00:00
										 |  |  |         if options[:if].nil? || options[:if].call(self, user || User.current) | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |           names += attrs.collect(&:to_s) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2011-12-13 20:40:03 +00:00
										 |  |  |       names.uniq! | 
					
						
							|  |  |  |       @safe_attribute_names = names if user.nil? | 
					
						
							|  |  |  |       names | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Returns true if attr can be set by user or the current user | 
					
						
							|  |  |  |     def safe_attribute?(attr, user=nil) | 
					
						
							|  |  |  |       safe_attribute_names(user).include?(attr.to_s) | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |     # Returns a hash with unsafe attributes removed | 
					
						
							|  |  |  |     # from the given attrs hash | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:44 +00:00
										 |  |  |     # | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |     # Example: | 
					
						
							|  |  |  |     #   book.delete_unsafe_attributes({'title' => 'My book', 'foo' => 'bar'}) | 
					
						
							|  |  |  |     #   # => {'title' => 'My book'} | 
					
						
							|  |  |  |     def delete_unsafe_attributes(attrs, user=User.current) | 
					
						
							|  |  |  |       safe = safe_attribute_names(user) | 
					
						
							| 
									
										
										
										
											2024-08-12 08:36:05 +00:00
										 |  |  |       attrs.dup.delete_if {|k, v| !safe.include?(k.to_s)} | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2011-09-20 02:44:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |     # Sets attributes from attrs that are safe | 
					
						
							|  |  |  |     # attrs is a Hash with string keys | 
					
						
							|  |  |  |     def safe_attributes=(attrs, user=User.current) | 
					
						
							| 
									
										
										
										
											2017-07-23 11:26:04 +00:00
										 |  |  |       if attrs.respond_to?(:to_unsafe_hash) | 
					
						
							|  |  |  |         attrs = attrs.to_unsafe_hash | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-12 13:11:53 +00:00
										 |  |  |       return unless attrs.is_a?(Hash) | 
					
						
							|  |  |  |       self.attributes = delete_unsafe_attributes(attrs, user) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |