diff options
| author | Randy Morgan <[email protected]> | 2012-05-19 13:30:26 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2012-05-19 13:30:26 +0900 |
| commit | 0aede23fd2d8649bce223b36c28e5c77bf3749c4 (patch) | |
| tree | 043c7851d8a776f19778f05c55e3c7ab9732f361 /lib | |
| parent | 5101c6f96ff1ec34ccbf8006f6e192fd45005602 (diff) | |
| download | caxlsx-0aede23fd2d8649bce223b36c28e5c77bf3749c4.tar.gz caxlsx-0aede23fd2d8649bce223b36c28e5c77bf3749c4.zip | |
first run at sheet_protection to provide password protection locking for sheets.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/axlsx/workbook/workbook.rb | 1 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/sheet_protection.rb | 182 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/worksheet.rb | 10 |
3 files changed, 192 insertions, 1 deletions
diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index fc9fbc51..fe3128c9 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -16,6 +16,7 @@ require 'axlsx/workbook/worksheet/row.rb' require 'axlsx/workbook/worksheet/col.rb' require 'axlsx/workbook/worksheet/comments.rb' require 'axlsx/workbook/worksheet/comment.rb' +require 'axlsx/workbook/worksheet/sheet_protection.rb' require 'axlsx/workbook/worksheet/worksheet.rb' require 'axlsx/workbook/shared_strings_table.rb' require 'axlsx/workbook/worksheet/table.rb' diff --git a/lib/axlsx/workbook/worksheet/sheet_protection.rb b/lib/axlsx/workbook/worksheet/sheet_protection.rb new file mode 100644 index 00000000..66687f75 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/sheet_protection.rb @@ -0,0 +1,182 @@ +# encoding: UTF-8 +module Axlsx + + # The SheetProtection object manages worksheet protection options per sheet. + class SheetProtection + + # Specifies the specific cryptographic hashing algorithm which shall be used along + # with the salt attribute and input password in order to compute the hash value. + # This value is automatically set to 'SHA-1' when password= is called. + # @note only SHA-1 is supported. + # @return [String] + attr_reader :algorithm_name + + + # If 1 or true then AutoFilters should not be allowed to operate when the sheet is protected. + # If 0 or false then AutoFilters should be allowed to operate when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :auto_filter + + # If 1 or true then deleting columns should not be allowed when the sheet is protected. + # If 0 or false then deleting columns should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :delete_columns + + # If 1 or true then deleting rows should not be allowed when the sheet is protected. + # If 0 or false then deleting rows should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :delete_rows + + # If 1 or true then formatting cells should not be allowed when the sheet is protected. + # If 0 or false then formatting cells should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :format_cells + + # If 1 or true then formatting columns should not be allowed when the sheet is protected. + # If 0 or false then formatting columns should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :format_columns + + # If 1 or true then formatting rows should not be allowed when the sheet is protected. + # If 0 or false then formatting rows should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :format_rows + + # Specifies the hash value for the password required to edit this worksheet. + # @return [String] + attr_reader :hash_value + + # If 1 or true then inserting columns should not be allowed when the sheet is protected. + # If 0 or false then inserting columns should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :insert_columns + + # If 1 or true then inserting hyperlinks should not be allowed when the sheet is protected. + # If 0 or false then inserting hyperlinks should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :insert_hyperlinks + + # If 1 or true then inserting rows should not be allowed when the sheet is protected. + # If 0 or false then inserting rows should be allowed when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :insert_rows + + # If 1 or true then editing of objects should not be allowed when the sheet is protected. + # If 0 or false then objects are allowed to be edited when the sheet is protected. + # @return [Boolean] + # @default false + attr_reader :objects + + # If 1 or true then PivotTables should not be allowed to operate when the sheet is protected. + # If 0 or false then PivotTables should be allowed to operate when the sheet is protected. + # @return [Boolean] + # @default true + attr_reader :pivot_tables + + # Specifies the salt which was prepended to the user-supplied password before it was hashed using the hashing algorithm + # @return [String] + attr_reader :salt_value + + # If 1 or true then Scenarios should not be edited when the sheet is protected. + # If 0 or false then Scenarios are allowed to be edited when the sheet is protected. + # @return [Boolean] + # default false + attr_reader :scenarios + + # If 1 or true then selection of locked cells should not be allowed when the sheet is protected. + # If 0 or false then selection of locked cells should be allowed when the sheet is protected. + # @return [Boolean] + # default false + attr_reader :select_locked_cells + + # If 1 or true then selection of unlocked cells should not be allowed when the sheet is protected. + # If 0 or false then selection of unlocked cells should be allowed when the sheet is protected. + # @return [Boolean] + # default false + attr_reader :select_unlocked_cells + + # If 1 or true then the sheet is protected. + # If 0 or false then the sheet is not protected. + # @return [Boolean] + # default false + attr_reader :sheet + + # If 1 or true then sorting should not be allowed when the sheet is protected. + # If 0 or false then sorting should be allowed when the sheet is protected. + # @return [Boolean] + # default true + attr_reader :sort + + # Specifies the number of times the hashing function shall be iteratively run + # @return [Integer] + # @default 10000 + attr_reader :spin_count + + # Creates a new SheetProtection instance + # @option options [Boolean] sheet @see SheetProtection#sheet + # @option options [Boolean] objects @see SheetProtection#objects + # @option options [Boolean] scenarios @see SheetProtection#scenarios + # @option options [Boolean] format_cells @see SheetProtection#objects + # @option options [Boolean] format_columns @see SheetProtection#format_columns + # @option options [Boolean] format_rows @see SheetProtection#format_rows + # @option options [Boolean] insert_columns @see SheetProtection#insert_columns + # @option options [Boolean] insert_rows @see SheetProtection#insert_rows + # @option options [Boolean] insert_hyperlinks @see SheetProtection#insert_hyperlinks + # @option options [Boolean] delete_columns @see SheetProtection#delete_columns + # @option options [Boolean] delete_rows @see SheetProtection#delete_rows + # @option options [Boolean] select_locked_cells @see SheetProtection#select_locked_cells + # @option options [Boolean] sort @see SheetProtection#sort + # @option options [Boolean] auto_filter @see SheetProtection#auto_filter + # @option options [Boolean] pivot_tables @see SheetProtection#pivot_tables + # @option options [Boolean] select_unlocked_cells @see SheetProtection#select_unlocked_cells + # @option options [String] password. The password required for unlocking. @see SheetProtection#password= + # @option options [Boolean] objects @see SheetProtection#objects + def initialize(options={}) + @sheet = @objects = @scenarios = @select_locked_cells = @select_unlocked_cells = false + @format_cells = @format_rows = @format_columns = @insert_columns = @insert_rows = @insert_hyperlinks = @delete_columns = @delete_rows = @sort = @auto_filter = @pivot_tables = true + options.each do |o| + self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}=" + end + end + + [:sheet, :objects, :scenarios, :select_locked_cells, :sort, + :select_unlocked_cells, :format_cells, :format_rows, :format_columns, + :insert_columns, :insert_rows, :insert_hyperlinks, :delete_columns, + :delete_rows, :auto_filter, :pivot_tables].each do |f_name| + define_method "#{f_name.to_s}=".to_sym do |v| + Axlsx::validate_boolean(v) + instance_variable_set "@#{f_name.to_s}".to_sym, v + end + end + + def password=(v) + @algorithm_name = v == nil ? nil : 'SHA-1' + @salt_value = @spin_count = @hash_value = v if v == nil + return if v == nil + require 'digest/sha1' + @spin_count = 10000 + @salt_value = Digest::SHA1.hexdigest(rand(36**8).to_s(36)) + + salty = @salt_value + v.to_s + @hash_value = Digest::SHA1.hexdigest(salty) + @spin_count.times do |count| + @hash_value = Digest::SHA1.hexdigest(@hash_value) + count.to_s + end + end + + def to_xml_string(str = '') + str << '<sheetProtection ' + str << instance_values.map{ |k,v| k.gsub(/_(.)/){ $1.upcase } << %{="#{v}"} }.join(' ') + str << '/>' + end + end +end diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 57d96861..43275ba0 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -8,6 +8,13 @@ module Axlsx # @return [String] attr_reader :name + # The sheet protection object for this workbook + # @return [SheetProtection] + # @see SheetProtection + def sheet_protection + @sheet_protection ||= SheetProtection.new + end + # The workbook that owns this worksheet # @return [Workbook] attr_reader :workbook @@ -151,7 +158,7 @@ module Axlsx self.workbook = wb @workbook.worksheets << self @page_marging = @page_setup = @print_options = nil - @drawing = @page_margins = @auto_filter = nil + @drawing = @page_margins = @auto_filter = @sheet_protection = nil @merged_cells = [] @auto_fit_data = [] @conditional_formattings = [] @@ -482,6 +489,7 @@ module Axlsx @rows.each_with_index { |row, index| row.to_xml_string(index, str) } str.concat '</sheetData>' str.concat "<autoFilter ref='%s'></autoFilter>" % @auto_filter if @auto_filter + @sheet_protection.to_xml_string(str) if @sheet_protection str.concat "<mergeCells count='%s'>%s</mergeCells>" % [@merged_cells.size, @merged_cells.reduce('') { |memo, obj| memo += "<mergeCell ref='%s'></mergeCell>" % obj } ] unless @merged_cells.empty? print_options.to_xml_string(str) if @print_options page_margins.to_xml_string(str) if @page_margins |
